package votorola.s.line; // Copyright 2012, Christian Weilbach. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.URISyntaxException; import java.sql.SQLException; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.script.ScriptException; import votorola.a.PageProperty; import votorola.a.PagePropertyReader; import votorola.a.VoteServer; import votorola.a.WikiCache; import votorola.a.diff.harvest.HarvestReporter; import votorola.a.diff.harvest.StateTable; import votorola.a.diff.harvest.cache.HarvestCache; import votorola.a.diff.harvest.kick.Kicker; import votorola.a.diff.harvest.kick.UpdateKick; import votorola.a.response.line.CommandLine; import votorola.g.logging.LoggerX; import votorola.g.option.GetoptX; import votorola.g.option.Option; /** * Main class of the executable voharvest - a tool to gather diff * messages from different remote web forums. See * {@linkplain votorola.a.diff.harvest.cache.HarvestCache Cache} for more * details. * * @see voharvest */ public final class VOHarvest { private static final Logger LOGGER = LoggerX.i(VOTrace.class); /** * Runs the tool from the command line. * * @param argv * command line argument array */ public static void main(final String[] argv) { LOGGER.info("voharvest is running with arguments " + Arrays.toString(argv)); try { new VOHarvest().run(argv); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Harvesting failed.", e); System.exit(1); } } private static enum Action { NONE, UPDATE, REMOVE }; private void run(final String[] argv) throws IOException, ScriptException, SQLException, URISyntaxException { final Map optionMap = CommandLine.compileBaseOptions(); GetoptX.parse("voharvest", argv, optionMap); final List realArgs = new LinkedList(); for(final String arg : Arrays.asList(argv)){ if(!arg.startsWith("-")){ realArgs.add(arg); } } int argCount = realArgs.size(); if (optionMap.get("help").hasOccured() || argCount == 0) { printHelp(); return; } // try to parse command Action action = Action.NONE; // first argument final String command = realArgs.remove(0); // remove command if (command.equals("update")) { action = Action.UPDATE; } else if (command.equals("remove")) { action = Action.REMOVE; } // setup verbosity boolean verbosity = false; if (optionMap.get("verbose").hasOccured()) { verbosity = true; } // setup cache for operation VoteServer.Run vsRun = null; vsRun = new VoteServer(System.getProperty("user.name")).new Run(false); HarvestCache.init(vsRun); final WikiCache wc = vsRun.voteServer().pollwiki().cache(); // execute action if (action.equals(Action.UPDATE)) { if (argCount < 2) { System.err .println("voharvest: wrong number of arguments\n" + "\"update\" needs to know one or more archive page(s) in the Pollwiki. \n" + "For example: \n" + "voharvest update 'Stuff:Votorola/mailing list' \n"); return; } // iterate over all arguments for (String arg : realArgs) { final Archive arch = getArchive(arg, wc); Kicker.i().broadcast( UpdateKick.create(arch.design, arch.url, createReporter(arg, verbosity))); } } else if (action.equals(Action.REMOVE)) { if (argCount != 2) { System.err .println("voharvest: wrong number of arguments\n" + "You need to supply two arguments, " + "\"remove\" and the archive descriptor in the Pollwiki. \n" + "For example: \n" + "voharvest remove 'Stuff:Votorola/mailing list'"); return; } final Archive arch = getArchive(realArgs.get(0), wc); int removeCount = HarvestCache.i().getTable() .removeArchive(arch.url); if (verbosity) { System.out.println(removeCount + " messages removed."); } new StateTable(HarvestCache.i().getDatabase()) .removeArchive(arch.url); } } private void maybeExit() { if (openReports.isEmpty()) { System.exit(0); } } // ------------------- Archive --------------------- class Archive { Archive(final String design, final String url) { this.design = design; this.url = url; } public final String design; public final String url; } private HarvestReporter createReporter(final String _archive, final boolean _verbose) { final HarvestReporter reporter = new HarvestReporter() { final String archive = _archive; final boolean verbose = _verbose; @Override public PrintStream printStream() { if (verbose) { return System.out; } else { return new PrintStream(new OutputStream() { @Override public void write(int b) throws IOException { // nope } }); } } @Override public void proccessFinished() { openReports.remove(this); if(verbose){ System.out.println(archive + " update finished."); } maybeExit(); } }; openReports.add(reporter); return reporter; } private final List openReports = Collections .synchronizedList(new LinkedList()); private Archive getArchive(final String archivePage, final WikiCache wc) throws IOException { final PageProperty designP = new PageProperty("Archive design"); final PagePropertyReader designR = new PagePropertyReader(wc, archivePage, designP); final PageProperty urlP = new PageProperty("Archive URL"); final PagePropertyReader urlR = new PagePropertyReader(wc, archivePage, urlP); if (designR.hasNext()) { final String design = designR.read().getValue(); final String url = urlR.read().getValue(); return new Archive(design, url); } throw new IllegalArgumentException(archivePage + " does not resolve to a proper archive definition."); } private void printHelp() { System.err .print("Usage: voharvest update PAGE_NAME_OF_ARCHIVE_IN_POLLWIKI* [--verbose]\n" + " or voharvest remove PAGE_NAME_OF_ARCHIVE_IN_POLLWIKI [--verbose]\n"); } }