/*
GNU General Public License
CacheWolf is a software for PocketPC, Win and Linux that
enables paperless caching.
It supports the sites geocaching.com and opencaching.de
Copyright (C) 2006 CacheWolf development team
See http://www.cachewolf.de/ for more information.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package CacheWolf.exp;
import CacheWolf.MainForm;
import CacheWolf.Preferences;
import CacheWolf.controls.InfoBox;
import CacheWolf.database.CacheDB;
import CacheWolf.database.CacheHolder;
import CacheWolf.database.CacheHolderDetail;
import CacheWolf.utils.Common;
import CacheWolf.utils.Files;
import CacheWolf.utils.MyLocale;
import HTML.Template;
import com.stevesoft.ewe_pat.Regex;
import ewe.filechooser.FileChooser;
import ewe.filechooser.FileChooserBase;
import ewe.io.BufferedWriter;
import ewe.io.File;
import ewe.io.FileBase;
import ewe.io.FileWriter;
import ewe.io.IOException;
import ewe.io.PrintWriter;
import ewe.sys.Convert;
import ewe.sys.Handle;
import ewe.ui.FormBase;
import ewe.ui.ProgressBarForm;
import ewe.util.Comparer;
import ewe.util.Hashtable;
import ewe.util.Vector;
/**
* Class to export cache information to individual HTML files.<br>
* It uses the HTML package to parse template files. This makes the export very flexible; enabling the user to customise the HTML files according to thier liking.
*/
public class HTMLExporter {
// TODO Exportanzahl anpassen: Bug: 7351
CacheDB cacheDB;
String[] template_init_index = { "filename", FileBase.getProgramDirectory() + FileBase.separator + FileBase.separator + "indextpl.html", "case_sensitive", "true", "max_includes", "5"
//,"debug", "true"
};
String[] template_init_page = { "filename", FileBase.getProgramDirectory() + FileBase.separator + FileBase.separator + "pagetpl.html", "case_sensitive", "true", "loop_context_vars", "true", "max_includes", "5" };
public final static String expName = "HTML";
public HTMLExporter() {
cacheDB = MainForm.profile.cacheDB;
}
public void doIt() {
CacheHolderDetail det;
CacheHolder ch;
ProgressBarForm pbf = new ProgressBarForm();
Handle h = new Handle();
int exportErrors = 0;
FileChooser fc = new FileChooser(FileChooserBase.DIRECTORY_SELECT, Preferences.itself().getExportPath(expName));
fc.setTitle("Select target directory:");
String targetDir;
if (fc.execute() != FormBase.IDCANCEL) {
targetDir = fc.getChosen() + "/";
Preferences.itself().setExportPref(expName, targetDir);
Vector cache_index = new Vector();
Vector cacheImg = new Vector();
Vector logImg = new Vector();
Vector mapImg = new Vector();
Vector usrImg = new Vector();
Vector logIcons = new Vector(15);
String icon;
Hashtable varParams;
Hashtable logImgParams;
Hashtable usrImgParams;
Hashtable mapImgParams;
//Generate index page
int counter = cacheDB.countVisible();
pbf.showMainTask = false;
pbf.setTask(h, "Exporting ...");
pbf.exec();
String decSep = "."; // myFilter.decSep
Regex dec = new Regex("[,.]", decSep);
TemplateTable tt = new TemplateTable();
for (int i = 0; i < counter; i++) {
h.progress = (float) (i + 1) / (float) counter;
h.changed();
ch = cacheDB.get(i);
if (ch.isVisible()) {
if (ch.isIncomplete()) {
exportErrors++;
Preferences.itself().log("HTMLExport: skipping export of incomplete waypoint " + ch.getCode());
continue;
}
det = ch.getDetails();
tt.set(ch);
varParams = tt.toHashtable(dec, null, 0, 30, -1, true, null, false, 2, expName);
cache_index.add(varParams);
//We can generate the individual page here!
try {
Template page_tpl = new Template(template_init_page);
page_tpl.setParams(varParams);
if (det != null) {
// Add the icon to list of icons to copy to dest directory
for (int j = 0; j < det.CacheLogs.size() - 1; j++) {
icon = det.CacheLogs.getLog(j).getIcon();
if (logIcons.find(icon) < 0) {
logIcons.add(icon);
}
}
// Log images
logImg.clear();
for (int j = 0; j < det.logImages.size(); j++) {
logImgParams = new Hashtable();
String logImgFile = det.logImages.get(j).getFilename();
logImgParams.put("FILE", logImgFile);
logImgParams.put("TEXT", det.logImages.get(j).getTitle());
if (Files.copy(MainForm.profile.dataDir + logImgFile, targetDir + logImgFile))
logImg.add(logImgParams);
else {
Preferences.itself().log("[HTMLExporter:Files]" + logImgFile + " " + ch.getCode());
exportErrors++;
}
}
page_tpl.setParam("logImg", logImg);
// User images
usrImg.clear();
for (int j = 0; j < det.userImages.size(); j++) {
usrImgParams = new Hashtable();
String usrImgFile = det.userImages.get(j).getFilename();
usrImgParams.put("FILE", usrImgFile);
usrImgParams.put("TEXT", det.userImages.get(j).getTitle());
if (Files.copy(MainForm.profile.dataDir + usrImgFile, targetDir + usrImgFile))
usrImg.add(usrImgParams);
else {
Preferences.itself().log("[HTMLExporter:Files]" + usrImgFile + " " + ch.getCode());
exportErrors++;
}
}
page_tpl.setParam("userImg", usrImg);
// Map images
mapImg.clear();
mapImgParams = new Hashtable();
String mapImgFile = ch.getCode() + "_map.gif";
// check if map file exists
File test = new File(MainForm.profile.dataDir + mapImgFile);
if (test.exists()) {
mapImgParams.put("FILE", mapImgFile);
mapImgParams.put("TEXT", mapImgFile);
if (Files.copy(MainForm.profile.dataDir + mapImgFile, targetDir + mapImgFile))
mapImg.add(mapImgParams);
else {
Preferences.itself().log("[HTMLExporter:Files]" + mapImgFile + " " + ch.getCode());
exportErrors++;
}
mapImgParams = new Hashtable();
mapImgFile = ch.getCode() + "_map_2.gif";
mapImgParams.put("FILE", mapImgFile);
mapImgParams.put("TEXT", mapImgFile);
if (Files.copy(MainForm.profile.dataDir + mapImgFile, targetDir + mapImgFile))
mapImg.add(mapImgParams);
else {
Preferences.itself().log("[HTMLExporter:Files]" + mapImgFile + " " + ch.getCode());
exportErrors++;
}
page_tpl.setParam("mapImg", mapImg);
}
} else {
page_tpl.setParam("DESCRIPTION", "");
page_tpl.setParam("LOGS", "");
page_tpl.setParam("NOTES", "");
page_tpl.setParam("cacheImg", cacheImg);
page_tpl.setParam("logImg", ""); // ???
page_tpl.setParam("userImg", ""); // ???
page_tpl.setParam("mapImg", ""); // ???
Preferences.itself().log("[HTMLExporter:DoIt]Error " + ch.getCode());
exportErrors++;
}
PrintWriter pagefile = new PrintWriter(new BufferedWriter(new FileWriter(targetDir + ch.getCode() + ".html")));
pagefile.print(page_tpl.output());
pagefile.close();
} catch (IllegalArgumentException e) {
Preferences.itself().log("[HTMLExporter:DoIt]" + ch.getCode() + " is incomplete reason: ", e, true);
exportErrors++;
ch.setIncomplete(true);
} catch (Exception e) {
exportErrors++;
Preferences.itself().log("[HTMLExporter:DoIt]" + ch.getCode(), e, true);
}
}//if is black, filtered
}
// Copy the log-icons to the destination directory
for (int j = 0; j < logIcons.size(); j++) {
icon = (String) logIcons.elementAt(j);
if (!Files.copy(FileBase.getProgramDirectory() + "/" + icon, targetDir + icon)) {
Preferences.itself().log("[HTMLExporter:Files]" + icon, null);
exportErrors++;
}
}
if (!Files.copy(FileBase.getProgramDirectory() + "/recommendedlog.gif", targetDir + "recommendedlog.gif")) {
Preferences.itself().log("[HTMLExporter:Files]recommendedlog.gif", null);
exportErrors++;
}
try {
Template tpl = new Template(template_init_index);
tpl.setParam("cache_index", cache_index);
PrintWriter detfile;
detfile = new PrintWriter(new BufferedWriter(new FileWriter(targetDir + "/index.html")));
detfile.print(tpl.output());
detfile.close();
// sort by waypoint
sortAndPrintIndex(tpl, cache_index, targetDir + "/index_wp.html", "WAYPOINT");
// sort by name
sortAndPrintIndex(tpl, cache_index, targetDir + "/index_alpha.html", "NAME", false);
// sort by type
sortAndPrintIndex(tpl, cache_index, targetDir + "/index_type.html", "TYPE", true);
// sort by size
sortAndPrintIndex(tpl, cache_index, targetDir + "/index_size.html", "SIZE", true);
// sort by distance
sortAndPrintIndex(tpl, cache_index, targetDir + "/index_dist.html", "DISTANCE", 10.0);
} catch (Exception e) {
Preferences.itself().log("[HTMLExporter:writeIndexFiles]Problem writing HTML files", e, true);
}//try
}//if
pbf.exit(0);
if (exportErrors > 0) {
new InfoBox(MyLocale.getMsg(5500, "Error"), exportErrors + " errors during export. See log for details.").wait(FormBase.OKB);
}
}
private void sortAndPrintIndex(Template tmpl, Vector list, String file, String field) {
PrintWriter detfile;
list.sort(new HTMLComparer(field), false);
try {
detfile = new PrintWriter(new BufferedWriter(new FileWriter(file)));
detfile.print(tmpl.output());
detfile.close();
} catch (IOException e) {
Preferences.itself().log("[HTMLExporter:sortAndPrintIndex]Problem writing HTML file:" + file, e, true);
}
}
private void sortAndPrintIndex(Template tmpl, Vector list, String file, String field, boolean fullCompare) {
Vector navi_index;
PrintWriter detfile;
list.sort(new HTMLComparer(field), false);
navi_index = addAnchorString(list, field, fullCompare);
if (navi_index != null) {
tmpl.setParam("navi_index", navi_index);
}
try {
detfile = new PrintWriter(new BufferedWriter(new FileWriter(file)));
detfile.print(tmpl.output());
detfile.close();
} catch (IOException e) {
Preferences.itself().log("[HTMLExporter:writeIndexFile]Problem writing HTML file:" + file, e, true);
}
}
private void sortAndPrintIndex(Template tmpl, Vector list, String file, String field, double diff) {
Vector navi_index;
PrintWriter detfile;
list.sort(new HTMLComparer(field), false);
navi_index = addAnchorString(list, field, diff);
if (navi_index != null) {
tmpl.setParam("navi_index", navi_index);
}
try {
detfile = new PrintWriter(new BufferedWriter(new FileWriter(file)));
detfile.print(tmpl.output());
detfile.close();
} catch (IOException e) {
Preferences.itself().log("[HTMLExporter:writeIndexFile]Problem writing HTML file:" + file, e, true);
}
}
private Vector addAnchorString(Vector list, String field, boolean fullCompare) {
Vector topIndex = new Vector();
Hashtable topIndexParms, currEntry;
String lastValue, currValue;
if (list.size() == 0)
return null;
currEntry = (Hashtable) list.get(0);
lastValue = (String) currEntry.get(field);
if (lastValue == null || lastValue.length() == 0)
lastValue = " ";
lastValue = lastValue.toUpperCase();
for (int i = 1; i < list.size(); i++) {
currEntry = (Hashtable) list.get(i);
currValue = (String) currEntry.get(field);
currValue = currValue.toUpperCase();
if (currValue == null || currValue.length() == 0)
continue;
try {
if (fullCompare) {
if (lastValue.compareTo(currValue) != 0) {
// Values for navigation line
topIndexParms = new Hashtable();
topIndexParms.put("HREF", Convert.toString(i));
topIndexParms.put("TEXT", currValue);
topIndex.add(topIndexParms);
// add anchor entry to list
currEntry.put("ANCHORNAME", Convert.toString(i));
currEntry.put("ANCHORTEXT", currValue);
} else {
// clear value from previous run
currEntry.put("ANCHORNAME", "");
currEntry.put("ANCHORTEXT", "");
}
} else {
if (lastValue.charAt(0) != currValue.charAt(0)) {
// Values for navigation line
topIndexParms = new Hashtable();
topIndexParms.put("HREF", Convert.toString(i));
topIndexParms.put("TEXT", currValue.charAt(0) + " ");
topIndex.add(topIndexParms);
// add anchor entry to list
currEntry.put("ANCHORNAME", Convert.toString(i));
currEntry.put("ANCHORTEXT", currValue.charAt(0) + " ");
} else {
// clear value from previous run
currEntry.put("ANCHORNAME", "");
currEntry.put("ANCHORTEXT", "");
}
}
list.set(i, currEntry);
lastValue = currValue;
} catch (Exception e) {
continue;
}
}
return topIndex;
}
private Vector addAnchorString(Vector list, String field, double diff) {
Vector topIndex = new Vector();
Hashtable topIndexParms, currEntry;
double lastValue, currValue;
if (list.size() == 0)
return null;
currEntry = (Hashtable) list.get(0);
lastValue = Common.parseDouble((String) currEntry.get(field)) + diff;
for (int i = 1; i < list.size(); i++) {
currEntry = (Hashtable) list.get(i);
currValue = Common.parseDouble((String) currEntry.get(field));
if (currValue >= lastValue) {
// Values for navigation line
topIndexParms = new Hashtable();
topIndexParms.put("HREF", Convert.toString(i));
topIndexParms.put("TEXT", Convert.toString(lastValue));
topIndex.add(topIndexParms);
// add anchor entry to list
currEntry.put("ANCHORNAME", Convert.toString(i));
currEntry.put("ANCHORTEXT", Convert.toString(lastValue));
lastValue = currValue + diff;
} else {
// clear value from previous run
currEntry.put("ANCHORNAME", "");
currEntry.put("ANCHORTEXT", "");
}
list.set(i, currEntry);
}
return topIndex;
}
/**
* @author Kalle Comparer for sorting the vector for the index.html file
*/
private class HTMLComparer implements Comparer {
String compareWhat;
public HTMLComparer(String what) {
this.compareWhat = what;
}
public int compare(Object o1, Object o2) {
Hashtable hash1 = (Hashtable) o1;
Hashtable hash2 = (Hashtable) o2;
String str1, str2;
double dbl1, dbl2;
str1 = hash1.get(compareWhat).toString().toLowerCase();
str2 = hash2.get(compareWhat).toString().toLowerCase();
if (this.compareWhat.equals("WAYPOINT")) {
str1 = hash1.get(compareWhat).toString().substring(2).toLowerCase();
str2 = hash2.get(compareWhat).toString().substring(2).toLowerCase();
}
if (this.compareWhat.equals("DISTANCE")) {
dbl1 = Common.parseDouble(str1.substring(0, str1.length() - 3));
dbl2 = Common.parseDouble(str2.substring(0, str2.length() - 3));
if (dbl1 > dbl2)
return 1;
if (dbl1 < dbl2)
return -1;
else
return 0;
} else {
return str1.compareTo(str2);
}
}
}
}