/*
Dateiverwaltung - File management in your browser
Copyright (C) 2017 Ulrich Hilger, http://uhilger.de
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
package de.uhilger.filecms.api;
import de.uhilger.wbx.Bild;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
/**
* Die Klasse HtmlExportService stellt Methoden bereit, mit denen
* .htmi-Dateien der WebBox zusammen mit Bildern und Stylesheets als
* Ordner exportierten werden koennen, aus denen heraus die Inhalte
* als HTML-Seiten im Browser zu oeffnen sind.
*/
public class HtmlExportService extends Api {
private static final Logger logger = Logger.getLogger(HtmlExportService.class.getName());
/**
* Den Inhalt eines Ordners als HTML exportieren
*
* Annahme hierbei ist, dass der Ordner, auf den im Parameter relPath
* verwiesen wird eine oder mehrere .htmi-Dateien enthaelt. Optional
* koennen Bilder im Ordner oder seinen Unterordnern enthalten sein, die
* dann in derselben Struktur im Ausgabeordner landen.
*
* Es werden nur .htmi-Dateien exortiert, die im mit relPath bezeichneten
* Ordner liegen. Eventuell in darin befindlichen Unterordnern befindliche
* .htmi-Dateien werden nicht exportiert.
*
* Es sollen keine komplexen Webseiten-Strukturen mit dieser Methode
* erzeugt werden sondern einfache Dokumente mit einer oder wenigen
* einzelnen Dateien.
*
* Die Ausgabe erfolgt in den Ordner, in dem der mit relPath bezeichnete
* Ordner liegt, also in dessen Eltern-Ordner. Der ausgegebene Ordner heisst
* genauso wir der mit relPath bezeichnete Ordner und wird mit der
* Ergaenzung _html versehen.
*
* @param relPath
* @return 'ok' oder Fehlermeldung
*/
public String exportHtml(String relPath) {
String result = null;
File dir = getTargetDir(relPath);
File parentDir = dir.getParentFile();
File outDir = new File(parentDir, dir.getName() + "_html/");
File[] files = dir.listFiles(new HtmiFileFilter());
for(int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
try {
FileUtils.copyDirectoryToDirectory(files[i], outDir);
} catch (IOException ex) {
result = ex.getLocalizedMessage();
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
} else {
BufferedReader br = null;
try {
File out = new File(outDir, stripExt(files[i].getName()) + ".html");
if(!out.exists()) {
logger.fine(out.getAbsolutePath() + " existiert nicht, erzeuge Datei..");
out.getParentFile().mkdirs();
out.createNewFile();
}
PrintWriter w = new PrintWriter(out);
printHeader(w);
br = new BufferedReader(new FileReader(files[i]));
String line = br.readLine();
while(line != null) {
w.print(line.replace("htmi", "html"));
w.print("\r\n");
line = br.readLine();
}
printFooter(w);
w.flush();
w.close();
br.close();
} catch (FileNotFoundException ex) {
result = ex.getLocalizedMessage();
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
} catch (IOException ex) {
result = ex.getLocalizedMessage();
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
} finally {
try {
if(br != null) {
br.close();
}
} catch (IOException ex) {
result = ex.getLocalizedMessage();
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
}
}
}
File catalinaBase = new File(getCatalinaBase(getServletContext()));
File bsDir = new File(catalinaBase, "webapps/jslib/bootstrap/css/");
try {
FileUtils.copyFile(new File(bsDir, "bootstrap.min.css"), new File(outDir, "bootstrap.min.css"), true);
File stile = new File(dir, "stile.css");
if(stile.exists()) {
FileUtils.copyFile(stile, new File(outDir, "stile.css"), true);
}
buildThumbnailImages(outDir, new Bild());
File lbDir = new File(catalinaBase, "webapps/jslib/lightbox/");
FileUtils.copyDirectoryToDirectory(lbDir, outDir);
File jqDir = new File(catalinaBase, "webapps/jslib/jquery/");
FileUtils.copyDirectoryToDirectory(jqDir, outDir);
File lbimgDir = new File(catalinaBase, "webapps/jslib/lightbox/img");
FileUtils.copyDirectoryToDirectory(lbimgDir, outDir);
result = "Export nach HTML ausgefuehrt.";
} catch (IOException ex) {
result = ex.getLocalizedMessage();
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
return result;
}
/**
* Minituransichten der Bilddateien erzeugen, die beim HTML-Export
* entstanden sind.
*
* Die Methode erstellt fuer alle Dateien mit Endung png oder jpg
* eine weitere Bilddatei mit Namen [Name]_tn.[Endung]. Also z.B.
* bild_tn.jpg fuer die Datei bild.jpg
*/
private void buildThumbnailImages(File dir, Bild bild) {
logger.fine("Minituransichten dir: " + dir.getAbsolutePath());
File[] files = dir.listFiles(new ImageFileFilter());
if(files != null) {
for(int i = 0; i < files.length; i++) {
if(files[i].isDirectory()) {
buildThumbnailImages(files[i], bild);
} else {
String absPath = files[i].getAbsolutePath();
logger.fine("Miniaturansicht fuer Bild " + absPath);
String fname = files[i].getName();
logger.fine("fname: " + fname);
int dotPos = fname.lastIndexOf(".");
logger.fine("dotPos: " + dotPos);
StringBuffer tnFileName = new StringBuffer();
if(dotPos > -1) {
String fname_no_ext = fname.substring(0, dotPos);
logger.fine("fname_no_ext: " + fname_no_ext);
String fext = fname.substring(dotPos);
logger.fine("fext: " + fext);
tnFileName.append(fname_no_ext);
tnFileName.append("_tn");
//tnFileName.append(".");
tnFileName.append(fext);
} else {
tnFileName.append(fname);
tnFileName.append("_tn");
}
String outFileName = new File(dir, tnFileName.toString()).getAbsolutePath();
logger.fine("outFileName: " + outFileName);
try {
Thumbnails.of(absPath)
.size(bild.getVariantenGroesse(Bild.WINZIG), bild.getVariantenGroesse(Bild.WINZIG))
.keepAspectRatio(true)
.toFile(outFileName);
} catch (IOException ex) {
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
/*
Image image = Toolkit.getDefaultToolkit().getImage(absPath);
MediaTracker mediaTracker = new MediaTracker(new Container());
mediaTracker.addImage(image, 0);
try {
mediaTracker.waitForID(0);
if (!mediaTracker.isErrorAny()) {
bild.writeImageFile(image, bild.getVariantenGroesse(Bild.WINZIG), bild.getMimeType(files[i]), outFileName);
} else {
logger.fine("Fehler: Miniaturansicht konnte nicht erzeugt werden");
}
} catch (InterruptedException | IOException ex) {
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
*/
}
}
} else {
logger.fine("files ist null");
}
}
private String stripExt(String name) {
int dotpos = name.indexOf(".");
if(dotpos > -1) {
name = name.substring(0, dotpos);
}
return name;
}
public class HtmiFileFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
boolean doAccept = false;
if(pathname.getName().endsWith(".htmi") || pathname.isDirectory()) {
doAccept = true;
}
return doAccept;
}
}
public class ImageFileFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
boolean doAccept = false;
String lcName = pathname.getName().toLowerCase();
if( lcName.endsWith(".jpg") ||
lcName.endsWith(".jpeg") ||
lcName.endsWith(".png") ||
pathname.isDirectory()) {
if(!lcName.contains("_tn")) {
doAccept = true;
}
}
return doAccept;
}
}
private void printHeader(PrintWriter out) throws IOException {
out.print("