Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/command_line.js

Issue 10233013: Crawler, second version (Closed)
Patch Set: Created April 12, 2013, 1:38 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/client.js ('k') | lib/counter_task.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/command_line.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/lib/command_line.js
@@ -0,0 +1,134 @@
+/*
+ * A bootstrapped extension must load its own command-line handler, because it won't load from chrome.manifest. See
+ * https://developer.mozilla.org/en-US/docs/Chrome_Registration and its section "Instructions supported in bootstrapped
+ * add-ons". This is only barely mentioned in
+ * https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions, and only in passing at that. The upshot
+ * is that you have to replicate what would otherwise happen in chrome.manifest.
+ *
+ * A command line handler must implement the interface nsICommandLineHandler and, in order to hook into the command line
+ * system, must register itself in the category "command-line-handler". See
+ * https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsICommandLineHandler
+ * The value of the category entry is a service contract ID, which is used to construct an instance of the handler.
+ *
+ * The way to construct an instance given a contract ID is to implement nsIFactory and, in order that hook into the
+ * instantiation system, must register itself with the component registrar. The component registrar is also the
+ * component manager, but through the interface nsIComponentRegistrar, which is not the default interface.
+ */
+
+Cu.import( "resource://gre/modules/XPCOMUtils.jsm" );
+
+let { Bootstrap_XPCOM } = require( "bootstrap_xpcom" );
+
+//-----------------------------------------------------------------------------------------
+// Command_Line
+//-----------------------------------------------------------------------------------------
+
+/**
+ * The command line handler singleton.
+ *
+ * This object supplies its own factory to XPCOM, so there's no need for a constructor function; instead, the factory
+ * function simply returns 'this' (essentially, though it passes it through QueryInterface first).
+ */
+var Command_Line = new Bootstrap_XPCOM.Singleton_class(
+ "ABP Crawler - Command Line Handler",
+ Components.ID( "{771575E6-62FE-48CB-BC24-EAEFDDC1CA1D}" ),
+ "@adblockplus.org/abpcrawler/command-line;1",
+ [ Ci.nsICommandLineHandler ],
+ [
+ {
+ category: "command-line-handler",
+ // The entry starts with "k" so that it has slightly higher priority than ordinary command line handlers.
+ entry: "k-abpcrawler"
+ }
+ ] );
+
+Command_Line.helpInfo = "" +
+ // - - - - - - - - - - - - - - | wrap here
+ "AdBlock Plus Crawler\n" +
+ " -abpcrawler Start a crawl. Must specify both an input and\n" +
+ " an output.\n" +
+ " -input_file <path> Use <path> as input file from which to compile\n" +
+ " instructions for the crawl.\n" +
+ " -output_dir <path> Use <path> as output directory to contain a\n" +
+ " file of crawl results.\n" +
+ " -output_base <name> Use <name> as the base name for a file of crawl\n" +
+ " results. Optional. Default='crawl_results'.\n" +
+ " -max_tabs <N> Maximum number of tabs for simultananeous\n" +
+ " loading of target sites.\n";
+
+/**
+ * Set a startup hook to run
+ * @param f
+ */
+Command_Line.set_startup_hook = function( f )
+{
+ this._startup_hook = f;
+};
+
+/**
+ * The actual handler.
+ *
+ * @param {nsICommandLine} ff_command_line
+ * The Firefox command line
+ */
+Command_Line.handle = function( ff_command_line )
+{
+ dump( "Command line handler: abpcrawler\n" );
+
+ if ( !ff_command_line.handleFlag( "abpcrawler", false ) )
+ {
+ /*
+ * There's no '--abpcrawler' option on the command line. As a result we don't try to interpret any other
+ * command line flags.
+ */
+ return;
+ }
+ var flags = this.flags = { abpcrawler: true };
+ /*
+ * The '--abpcrawler' argument indicates that this invocation is designated as a crawl session. As a result,
+ * we don't perform the default action, which is opening the start page in the browser for interactive use.
+ */
+ ff_command_line.preventDefault = true;
+
+ let x = ff_command_line.handleFlagWithParam( "input_file", false );
+ if ( x ) flags.input_file = x;
+ x = ff_command_line.handleFlagWithParam( "output_dir", false );
+ if ( x ) flags.output_dir = x;
+ x = ff_command_line.handleFlagWithParam( "output_base", false );
+ if ( x ) flags.output_base = x;
+ x = ff_command_line.handleFlagWithParam( "max_tabs", false );
+ if ( x ) flags.max_tabs = x;
+
+ /*
+ * Some experimentation revealed that this command line handler runs _after_ observer notifications for topic
+ * 'final-ui-startup'. (This seems like a design failure, since it ought to happen after the add-on has an opportunity
+ * to initialize itself at 'profile-after-change' but before anything else. Whatever.) As a result, we call a startup
+ * hook here.
+ */
+ if ( this._startup_hook )
+ {
+ try
+ {
+ this._startup_hook();
+ }
+ catch ( e )
+ {
+ dump( "Command_Line/handle/startup hook: Unexpected exception"
+ + (("message" in e) ? ": " + e.message : "") + ".\n" );
+ }
+ }
+};
+
+exports.Command_Line = Command_Line;
+try
+{
+ /*
+ * We must call init() after handle() is defined, so that if the category manager triggers an immediate event
+ * that we have already initialized fully.
+ */
+ Command_Line.init();
+}
+catch ( e )
+{
+ dump( "command_line.js: Unexpected exception during init(): " + e.message );
+}
« no previous file with comments | « lib/client.js ('k') | lib/counter_task.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld