/**
* GeoDress - A program for reverse geocoding
* Copyright (C) 2010 Stefan T.
*
* See COPYING for Details.
*
* 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, 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package geodress.ui.command_line;
import geodress.main.InfoConstants;
import geodress.main.Logging;
import geodress.model.PictureBox;
import geodress.model.reader.GoogleMapsReader;
import geodress.model.writer.ExifToolWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
/**
* This class is used for command-line interface of GeoDress.
*
* @author Stefan T.
*/
public class GeoDressCli {
/** Logger object */
private static Logger logger;
/** CLI options */
public static Options cliOptions;
/** the option value for writing addresses to description (default) */
private final static String WRITE_TO_DESCRIPTION = "description";
/** the option value for writing addresses to comment */
private final static String WRITE_TO_COMMENT = "comment";
/* initialize the CLI options */
static {
logger = Logging.getLogger(GeoDressCli.class.getName());
cliOptions = new Options();
cliOptions.addOption(new Option("h", "help", false,
"show command-line help"));
cliOptions.addOption(new Option("v", "version", false,
"show version of GeoDress"));
cliOptions.addOption(new Option("l", "license", false,
"show license of GeoDress"));
cliOptions.addOption(new Option("d", "directory", true,
"specify the directory with JPEG pictures"));
cliOptions.addOption(new Option("k", "googlekey", true,
"use an individual Google Maps API key"));
cliOptions.addOption(new Option("e", "export", true,
"export picture data to text file before exit "
+ "(an existing file will be overwritten)"));
cliOptions.addOption(new Option("a", "addresses", false,
"catch addresses from Google Maps (needs -d)"));
Option writeOption = new Option(
"w",
"write",
true,
"write the caught addresses to the picture files, you can use '"
+ WRITE_TO_DESCRIPTION
+ "' (default) or '"
+ WRITE_TO_COMMENT
+ "' to specify the field that should be written to (needs -da)");
writeOption.setOptionalArg(true);
cliOptions.addOption(writeOption);
cliOptions
.addOption(new Option(
"p",
"exiftoolpath",
true,
"path to ExifTool executable (if not set, try to find it by environment variable)"));
cliOptions.addOption(new Option("b", "nobackup", false,
"do not backup all picture files before writing"));
}
/**
* Starts the command-line interface.
*
* @param args
* the command line options
*/
public GeoDressCli(String[] args) {
/* show license */
System.out.println(InfoConstants.SHORT_LICENSE);
CommandLineParser parser = new PosixParser();
try {
/* parse */
CommandLine line = parser.parse(cliOptions, args);
/* show help */
if (line.hasOption("h")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("geodress [OPTION]", cliOptions);
System.exit(0);
}
/* show version */
if (line.hasOption("v")) {
System.out.println(InfoConstants.VERSION_DETAILS);
System.exit(0);
}
/* show license */
if (line.hasOption("l")) {
System.out.println(InfoConstants.LICENSE);
System.exit(0);
}
/* initialization */
PictureBox pictureBox = null;
/* get picture folder */
File dir;
if (line.hasOption("d")) {
dir = new File(line.getOptionValue("d"));
/* load picture folder */
try {
logger.log(Level.FINE, "directory: "
+ dir.getCanonicalPath());
pictureBox = new PictureBox(dir);
} catch (FileNotFoundException fnfe) {
logger.log(Level.WARNING, fnfe.getMessage(), fnfe);
System.out.println("The directory " + dir.getAbsolutePath()
+ " doesn't exist.");
System.exit(0);
} catch (IOException ioe) {
logger.log(Level.WARNING,
"error while loading files from directory", ioe);
}
/* print only pictures */
if (!line.hasOption("a")) {
System.out.println(pictureBox
.getPicturesAsString(PictureBox.FORMAT_TXT));
}
/* catch address and print them */
if (line.hasOption("a")) {
try {
if (line.hasOption("k")) {
logger.log(Level.FINE,
"an individual Google Maps API key is used: "
+ line.getOptionValue("k"));
System.out
.println("An individual Google Maps API key is used: "
+ line.getOptionValue("k") + ".");
pictureBox.catchAddresses(new GoogleMapsReader(line
.getOptionValue("k")), new ProgressCli(
"Catch addresses from Google Maps"));
} else {
pictureBox
.catchAddresses(
new GoogleMapsReader(),
new ProgressCli(
"Catch addresses from Google Maps"));
}
/* print pictures */
System.out.println(pictureBox
.getPicturesAsString(PictureBox.FORMAT_TXT));
} catch (UnknownHostException uhe) {
logger.log(Level.WARNING, uhe.getMessage(), uhe);
System.out
.println("An error occured while connecting to Google Maps "
+ "(maybe there is no Internet connection).");
}
/* write caught addresses to picture files */
if (line.hasOption("w")) {
logger.log(Level.FINE,
"write caught addresses (field '"
+ line.getOptionValue("w") + "')");
ExifToolWriter writer = new ExifToolWriter();
if (line.hasOption("b")) {
writer.setBackupMode(false);
}
if (line.hasOption("p")) {
System.out.println("Setting "
+ line.getOptionValue("p")
+ " as path to ExifTool...");
try {
writer
.setExifToolPath(line
.getOptionValue("p"));
} catch (IOException ioe) {
System.out
.println("An error occured while setting the ExifToolPath: "
+ ioe.getMessage());
}
}
/* find out field */
int field = InfoConstants.IMAGE_DESCRIPTION;
if (line.getOptionValue("w").contains(WRITE_TO_COMMENT)) {
field = InfoConstants.USER_COMMENT;
}
/* write data */
pictureBox.writeAddresses(writer, field,
new ProgressCli(
"Writing addresses to picture files"));
}
}
/* export to text file */
if (line.hasOption("e")) {
File exportFile = new File(line.getOptionValue("e"));
logger.log(Level.FINE, "Picture data will be exported to "
+ exportFile.getName() + ".");
System.out.println("Picture data will be exported to "
+ exportFile.getName() + ".");
try {
pictureBox.saveToFile(exportFile,
PictureBox.FORMAT_TXT_OS);
} catch (IOException ioe) {
logger
.log(
Level.WARNING,
"error while exporting picture data to text file",
ioe);
}
}
}
} catch (ParseException pe) {
showParseError(pe);
}
}
/**
* Shows a error message if the command line options could not be parsed.
*
* @param pe
* the parse error exception
*/
public static void showParseError(ParseException pe) {
logger.log(Level.WARNING, "command line options could not be parsed",
pe);
System.out.println(pe.getLocalizedMessage() + "\n"
+ "Use geodress -h to get a usage summary.");
}
}