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

Unified Diff: lib/main.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/logger.js ('k') | lib/storage.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/main.js
===================================================================
--- a/lib/main.js
+++ b/lib/main.js
@@ -4,89 +4,277 @@
* http://mozilla.org/MPL/2.0/.
*/
-Cu.import("resource://gre/modules/Services.jsm");
+dump( "--------\n" );
-let {WindowObserver} = require("windowObserver");
+Cu.import( "resource://gre/modules/Services.jsm" );
+let {WindowObserver} = require( "windowObserver" );
+let { Application_Session } = require( "application" );
+let { Bootstrap_XPCOM } = require( "bootstrap_xpcom" );
+let { Command_Line } = require( "command_line" );
+dump( "main.js: all require() finished\n" );
+
+//-------------------------------------------------------
+// Main
+//-------------------------------------------------------
+
+var Main = new Bootstrap_XPCOM.Singleton_class(
+ "ABP Crawler - Main",
+ Components.ID( "{7beffb8d-13e4-472c-9623-e3f3d7f37383}" ),
+ "@adblockplus.org/abpcrawler/main;1",
+ [ Ci.nsIObserver ],
+ [] );
+
+Main.observe = function( subject, topic, data )
+{
+ dump( "Main.observe: topic = " + topic + ( data ? ", data = " + data : "" ) + "\n" );
+ switch ( topic )
+ {
+ case "profile-before-change":
+ this.remove_observation_topic( topic );
+ break;
+ }
+};
+
+/**
+ * Startup function.
+ *
+ * Strictly speaking this is only the startup function for automatic sessions at this time. The interactive version
+ * will already have initialized below.
+ */
+Main.startup = function()
+{
+ dump( "Main/startup: invoked.\n" );
+
+ if ( !( "flags" in Command_Line ) )
+ {
+ throw new Error( "No flags found in Command_Line.\n" );
+ }
+ var flags = Command_Line.flags;
+ if ( !( "abpcrawler" in flags ) || !flags.abpcrawler )
+ {
+ // No session for us.
+ return;
+ }
+ /*
+ * There was a command line argument that ordered an automatic run. Here we check the arguments for validity,
+ * create an Application_Session, and start it running.
+ */
+ var session = make_session( flags );
+ if ( !session )
+ {
+ // Error messages were already generated in make_session.
+ return;
+ }
+ if ( !session.window )
+ {
+ dump( "Main: session does not have a window. Aborted.\n" );
+ return;
+ }
+ this.session = session;
+ /*
+ * At this point we have a session and its window, but the window may not be initialized. So what we have to do is
+ * to wait for the window to show up.
+ */
+ this.ready_listener = this.ready.bind( this );
+ session.window.addEventListener( "load", this.ready_listener );
+ // This action should really have a timeout attached to it.
+ dump( "Main/startup: waiting for window load.\n");
+};
+
+/**
+ * Launch the session when we're fully ready and have a window object.
+ */
+Main.ready = function()
+{
+ if ( !this.session.window.gBrowser )
+ {
+ dump( "Main/ready: session window does not have a 'gBrowser' member.\n" );
+ this.session.window.close();
+ this.session.close();
+ return;
+ }
+ this.session.window.removeEventListener( "load", this.ready_listener );
+ this.ready_listener = null;
+
+ dump( "Main: running session.\n" );
+ try
+ {
+ this.session.run( this.done.bind( this ) );
+ }
+ catch ( e )
+ {
+ dump( "Main: unexpected error running session = " + e.message + "\n" );
+ this.done();
+ }
+};
+
+Main.done = function()
+{
+ if ( this.session )
+ {
+ /*
+ * We have responsibility for the window, since we created it.
+ */
+ if ( this.session.window )
+ {
+ this.session.window.close();
+ }
+ this.session.close();
+ }
+};
+
+/*
+ * Initialize the Main object. It's built individually, so this is code that would otherwise be in a constructor.
+ */
+try
+{
+ Main.init();
+ Main.add_observation_topic( "profile-before-change" );
+ Command_Line.set_startup_hook( Main.startup.bind( Main ) );
+}
+catch ( e )
+{
+ dump( "main.js: Unexpected exception in Main.init(): " + e.message );
+}
+
+//-------------------------------------------------------
+// Automatic
+//-------------------------------------------------------
+function make_session( flags )
+{
+ /*
+ * Check that the flags are syntactically correct.
+ */
+ if ( !( "input_file" in flags ) )
+ {
+ dump( "abpcrawler: Missing flag '-input_file'.\n" );
+ return null;
+ }
+ if ( !( "output_dir" in flags ) )
+ {
+ dump( "abpcrawler: Missing flag '-output_dir'.\n" );
+ return null;
+ }
+ /*
+ * Provide defaults for any absent flags.
+ */
+ var max_tabs = ( "max_tabs" in flags ) ? flags.max_tabs : 5;
+ var base_name = ( "output_base" in flags ) ? flags.output_base : "crawl_results";
+ /*
+ * At this point all the syntax of the arguments is valid. Now we create the actual resources used.
+ */
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService( Ci.nsIWindowWatcher );
+ var window = ww.openWindow( null, "chrome://browser/content/", "abpcrawler_main", null, null );
+ /*
+ * 5 minute timeout
+ */
+ var session = new Application_Session( window, false, max_tabs, 300000, null );
+ try
+ {
+ session.set_input_file( flags.input_file );
+ session.add_output_file( flags.output_dir, base_name, true, "JSON" );
+ }
+ catch ( e )
+ {
+ dump( "abpcrawler: " + e.message + "\n" );
+ return null;
+ }
+ return session;
+}
+
+//-------------------------------------------------------
+// Setup
+//-------------------------------------------------------
let knownWindowTypes =
{
"navigator:browser": true,
__proto__: null
};
-new WindowObserver({
- applyToWindow: function(window)
+/*
+ * We initialize the interactive version, which means hooking into the menu.
+ *
+ * At this time, we're doing this regardless of whether we actual need an interactive session. Later, we may initialize
+ * differently or not at all if we're only running an automatic session.
+ */
+new WindowObserver( {
+ applyToWindow: function( window )
{
- let type = window.document.documentElement.getAttribute("windowtype");
- if (!(type in knownWindowTypes))
+ let type = window.document.documentElement.getAttribute( "windowtype" );
+ if ( !(type in knownWindowTypes) )
return;
- window.addEventListener("popupshowing", popupShowingHandler, false);
- window.addEventListener("popuphidden", popupHiddenHandler, false);
+ window.addEventListener( "popupshowing", popupShowingHandler, false );
+ window.addEventListener( "popuphidden", popupHiddenHandler, false );
},
- removeFromWindow: function(window)
+ removeFromWindow: function( window )
{
- let type = window.document.documentElement.getAttribute("windowtype");
- if (!(type in knownWindowTypes))
+ let type = window.document.documentElement.getAttribute( "windowtype" );
+ if ( !(type in knownWindowTypes) )
return;
- window.removeEventListener("popupshowing", popupShowingHandler, false);
- window.removeEventListener("popuphidden", popupHiddenHandler, false);
+ window.removeEventListener( "popupshowing", popupShowingHandler, false );
+ window.removeEventListener( "popuphidden", popupHiddenHandler, false );
}
-});
+} );
+
+//-------------------------------------------------------
+// Interactive
+//-------------------------------------------------------
function getMenuItem()
{
// Randomize URI to work around bug 719376
- let stringBundle = Services.strings.createBundle("chrome://abpcrawler/locale/global.properties?" + Math.random());
- let result = [stringBundle.GetStringFromName("crawler.label")];
+ let stringBundle = Services.strings.createBundle( "chrome://abpcrawler/locale/global.properties?" + Math.random() );
+ let result = [stringBundle.GetStringFromName( "crawler.label" )];
getMenuItem = function() result;
return getMenuItem();
}
-function popupShowingHandler(event)
+function popupShowingHandler( event )
{
let popup = event.target;
- if (!/^(abp-(?:toolbar|status|menuitem)-)popup$/.test(popup.id))
+ if ( !/^(abp-(?:toolbar|status|menuitem)-)popup$/.test( popup.id ) )
return;
- popupHiddenHandler(event);
+ popupHiddenHandler( event );
let [label] = getMenuItem();
- let item = popup.ownerDocument.createElement("menuitem");
- item.setAttribute("label", label);
- item.setAttribute("class", "abpcrawler-item");
+ let item = popup.ownerDocument.createElement( "menuitem" );
+ item.setAttribute( "label", label );
+ item.setAttribute( "class", "abpcrawler-item" );
- item.addEventListener("command", popupCommandHandler, false);
+ item.addEventListener( "command", popupCommandHandler, false );
let insertBefore = null;
- for (let child = popup.firstChild; child; child = child.nextSibling)
- if (/-options$/.test(child.id))
+ for ( let child = popup.firstChild ; child ; child = child.nextSibling )
+ if ( /-options$/.test( child.id ) )
insertBefore = child;
- popup.insertBefore(item, insertBefore);
+ popup.insertBefore( item, insertBefore );
}
-function popupHiddenHandler(event)
+function popupHiddenHandler( event )
{
let popup = event.target;
- if (!/^(abp-(?:toolbar|status|menuitem)-)popup$/.test(popup.id))
+ if ( !/^(abp-(?:toolbar|status|menuitem)-)popup$/.test( popup.id ) )
return;
- let items = popup.getElementsByClassName("abpcrawler-item");
- while (items.length)
- items[0].parentNode.removeChild(items[0]);
+ let items = popup.getElementsByClassName( "abpcrawler-item" );
+ while ( items.length )
+ items[0].parentNode.removeChild( items[0] );
}
-function popupCommandHandler(event)
+function popupCommandHandler( event )
{
- if (!("@adblockplus.org/abp/public;1" in Cc))
+ if ( !("@adblockplus.org/abp/public;1" in Cc) )
return;
- let crawlerWnd = Services.wm.getMostRecentWindow("abpcrawler:crawl");
- if (crawlerWnd)
+ let crawlerWnd = Services.wm.getMostRecentWindow( "abpcrawler:crawl" );
+ if ( crawlerWnd )
crawlerWnd.focus();
else
- event.target.ownerDocument.defaultView.openDialog("chrome://abpcrawler/content/crawler.xul", "_blank", "chrome,centerscreen,resizable,dialog=no");
+ event.target.ownerDocument.defaultView.openDialog( "chrome://abpcrawler/content/crawler.xul", "_blank", "chrome,centerscreen,resizable,dialog=no" );
}
« no previous file with comments | « lib/logger.js ('k') | lib/storage.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld