| Index: chrome/content/crawler_ui.js |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/chrome/content/crawler_ui.js |
| @@ -0,0 +1,355 @@ |
| +/* |
| + * This Source Code is subject to the terms of the Mozilla Public License |
| + * version 2.0 (the "License"). You can obtain a copy of the License at |
| + * http://mozilla.org/MPL/2.0/. |
| + */ |
| + |
| +/* |
| + * crawler_ui.js |
| + */ |
| +/** |
| + * @fileOverview These functions implement the user interface behaviors of the top-level control dialog. |
| + */ |
| + |
| +const Cu = Components.utils; |
| +const Cc = Components.classes; |
| +const Ci = Components.interfaces; |
| + |
| +Cu.import( "resource://gre/modules/Services.jsm" ); |
| +Cu.import( "resource://gre/modules/FileUtils.jsm" ); |
| + |
| +function require( module ) |
| +{ |
| + let result = {}; |
| + result.wrappedJSObject = result; |
| + Services.obs.notifyObservers( result, "abpcrawler-require", module ); |
| + if ( !("exports" in result) ) |
| + { |
| + Cu.reportError( "crawler_ui require: 'exports' missing from module \"" + module + "\"" ); |
| + } |
| + return result.exports; |
| +} |
| +let {Storage} = require( "storage" ); |
| +let {Instruction, Instruction_Set, Input_String, Input_File} = require( "instruction" ); |
| +let {Long_Task} = require( "task" ); |
| +let {Crawler} = require( "crawler" ); |
| +let {Logger} = require( "logger" ); |
| + |
| +//------------------------------------------------------- |
| +// New code |
| +//------------------------------------------------------- |
| + |
| +var current_crawler = null; |
| +var current_crawl = null; |
| +var preference_service, preference_branch; |
| +var go_button; |
| +var base_name, base_name_initial_value; |
| +var number_of_tabs; |
| +var input_file, input_file_initial_value; |
| +var output_directory, output_directory_initial_value; |
| + |
| +function loader() |
| +{ |
| + go_button = document.getElementById( "crawl_go" ); |
| + preference_service = Cc["@mozilla.org/preferences-service;1"].getService( Ci.nsIPrefService ); |
| + preference_branch = preference_service.getBranch( "extensions.abpcrawler." ); |
| + |
| + /* |
| + * Set up the output directory values and preferences. |
| + */ |
| + input_file = document.getElementById( "input_file" ); |
| + base_name = document.getElementById( "base_name" ); |
| + output_directory = document.getElementById( "output_directory" ); |
| + |
| + if ( preference_branch.prefHasUserValue( "input_file" ) ) |
| + { |
| + input_file_initial_value = preference_branch.getCharPref( "input_file" ); |
| + input_file.value = input_file_initial_value; |
| + } |
| + base_name_initial_value = base_name.value; |
| + if ( preference_branch.prefHasUserValue( "base_name" ) ) |
| + { |
| + base_name_initial_value = preference_branch.getCharPref( "base_name" ); |
| + base_name.value = base_name_initial_value; |
| + } |
| + else |
| + { |
| + base_name_initial_value = base_name.value; |
| + } |
| + if ( preference_branch.prefHasUserValue( "output_directory" ) ) |
| + { |
| + output_directory_initial_value = preference_branch.getCharPref( "output_directory" ); |
| + output_directory.value = output_directory_initial_value; |
| + } |
| + else |
| + { |
| + output_directory_initial_value = ""; |
| + var dir = FileUtils.getDir( "Home", [] ); |
| + output_directory.value = dir.path; |
| + } |
| + |
| + document.getElementById( "input_file_icon" ).addEventListener( "click", icon_input_click ); |
| + document.getElementById( "output_directory_icon" ).addEventListener( "click", icon_output_click ); |
| +} |
| + |
| +function unloader() |
| +{ |
| + if ( current_crawler ) |
| + { |
| + current_crawler.close(); |
| + current_crawler = null; |
| + } |
| + if ( current_crawl ) |
| + { |
| + current_crawl.close(); |
| + current_crawl = null; |
| + } |
| +} |
| + |
| +function icon_input_click() |
| +{ |
| + var fp = Cc["@mozilla.org/filepicker;1"].createInstance( Ci.nsIFilePicker ); |
| + fp.init( window, "Select an Input File", Ci.nsIFilePicker.modeOpen ); |
| + if ( input_file.value != "" && input_file.value != null ) |
| + { |
| + var f = new FileUtils.File( input_file.value ); |
| + if ( f.exists() ) |
| + { |
| + if ( f.isFile() ) |
| + { |
| + f = f.parent; |
| + } |
| + if ( f.isDirectory() ) |
| + { |
| + fp.displayDirectory = f; |
| + } |
| + } |
| + } |
| + var result = fp.show(); |
| + switch ( result ) |
| + { |
| + case Ci.nsIFilePicker.returnOK: |
| + f = fp.file; |
| + if ( f.isFile() ) |
| + { |
| + input_file.value = fp.file.path; |
| + } |
| + break; |
| + case Ci.nsIFilePicker.returnCancel: |
| + break; |
| + case Ci.nsIFilePicker.returnReplace: |
| + break; |
| + default: |
| + break; |
| + } |
| +} |
| + |
| +function icon_output_click() |
| +{ |
| + var fp = Cc["@mozilla.org/filepicker;1"].createInstance( Ci.nsIFilePicker ); |
| + fp.init( window, "Select an Output Folder", Ci.nsIFilePicker.modeGetFolder ); |
| + var result = fp.show(); |
| + switch ( result ) |
| + { |
| + case Ci.nsIFilePicker.returnOK: |
| + output_directory.value = fp.file.path; |
| + break; |
| + case Ci.nsIFilePicker.returnCancel: |
| + break; |
| + case Ci.nsIFilePicker.returnReplace: |
| + break; |
| + default: |
| + break; |
| + } |
| +} |
| + |
| +function leave_open() |
| +{ |
| + return document.getElementById( "leave_open" ).checked; |
| +} |
| + |
| +function start_crawl() |
| +{ |
| + var log = crawler_ui_log; |
| + log( "Start crawl", false ); |
| + |
| + /* |
| + * Save preferences automatically when we start a crawl. |
| + */ |
| + var saving_input = ( input_file_initial_value != input_file.value ); |
| + var saving_basename = ( base_name_initial_value != base_name.value ); |
| + var saving_dir = ( output_directory.value != output_directory_initial_value ); |
| + if ( saving_input ) |
| + { |
| + preference_branch.setCharPref( "input_file", input_file.value ); |
| + } |
| + if ( saving_basename ) |
| + { |
| + preference_branch.setCharPref( "base_name", base_name.value ); |
| + } |
| + if ( saving_dir ) |
| + { |
| + preference_branch.setCharPref( "output_directory", output_directory.value ); |
| + } |
| + if ( saving_input || saving_basename || saving_dir ) |
| + { |
| + preference_service.savePrefFile( null ); |
| + /* |
| + * Recalculate initial values only when saving. |
| + */ |
| + input_file_initial_value = input_file.value; |
| + base_name_initial_value = base_name.value; |
| + output_directory_initial_value = output_directory.value; |
| + } |
| + var log_window = new Crawl_Display(); |
| + var log_to_textbox = new Storage.Display_Log( log_window ); |
| + |
| + /* |
| + * Input |
| + */ |
| + var instructions; |
| + var si = document.getElementById( "instructions_tabbox" ).selectedIndex; |
| + switch ( si ) |
| + { |
| + case 0: |
| + log_window.log( "Server input not supported at present. Aborted." ); |
| + return false; |
| + case 1: |
| + var f = new FileUtils.File( input_file.value ); |
| + if ( !f.exists() ) |
| + { |
| + log_window.log( "Input file does not exist. name = " + f.path ); |
| + return false; |
| + } |
| + if ( !f.isFile() ) |
| + { |
| + log_window.log( "Input does not name a file. name = " + f.path ); |
| + return false; |
| + } |
| + instructions = new Instruction_Set.Parsed( new Input_File( f ) ); |
| + break; |
| + case 2: |
| + var fixed_source = "" |
| + + "name: Fixed internal development test\n" |
| + + "target:\n" |
| + + " - yahoo.com\n" |
| + + " - ksl.com\n" |
| + + ""; |
| + instructions = new Instruction_Set.Parsed( new Input_String( fixed_source ) ); |
| + break; |
| + default: |
| + log_window.log( "WTF? Unknown input tab. Aborted. si=" + si ); |
| + return false; |
| + } |
| + // Assert 'instructions' contains a valid 'Instruction_Set' object |
| + |
| + /* |
| + * Tab configuration |
| + */ |
| + number_of_tabs = document.getElementById( "number_of_tabs" ); |
| + // preference initialization goes here. |
| + |
| + /* |
| + * Encoding |
| + */ |
| + var encoding = null, suffix = ""; |
| + switch ( document.getElementById( "format" ).selectedIndex ) |
| + { |
| + case 0: |
| + encoding = "JSON"; |
| + suffix = ".json"; |
| + break; |
| + case 1: |
| + encoding = "YAML"; |
| + suffix = ".yaml"; |
| + break; |
| + default: |
| + log_window.log( "Unknown output encoding. Aborted." ); |
| + return false; |
| + } |
| + |
| + /* |
| + * Output |
| + */ |
| + var outputs = [ |
| + { storage: log_to_textbox, encode: "YAML" } |
| + ]; |
| + si = document.getElementById( "storage_tabbox" ).selectedIndex; |
| + switch ( si ) |
| + { |
| + case 0: |
| + log_window.log( "Server storage not supported at present. Aborted." ); |
| + return false; |
| + case 1: |
| + var file = Cc["@mozilla.org/file/local;1"].createInstance( Ci.nsILocalFile ); |
| + file.initWithPath( output_directory.value ); |
| + file.append( base_name.value + filename_timestamp() + suffix ); |
| + log_window.log( "Computed file name = " + file.path ); |
| + outputs.push( { storage: new Storage.Local_File( file ), encode: encoding } ); |
| + break; |
| + case 2: |
| + /* |
| + * This is in at present to ensure that the JSON encoder does not unexpectedly throw. We can take it out |
| + * when we're assured that it doesn't. |
| + */ |
| + outputs.push( { storage: new Storage.Bit_Bucket(), encode: "JSON" } ); |
| + break; |
| + default: |
| + log_window.log( "WTF? Unknown storage tab. Aborted. si=" + si ); |
| + return false; |
| + } |
| + |
| + let mainWindow = window.opener; |
| + if ( !mainWindow || mainWindow.closed ) |
| + { |
| + log_window.log( "Unable to find the main window, aborting." ); |
| + return false; |
| + } |
| + current_crawler = new Crawler( |
| + instructions, outputs, log_window, mainWindow, |
| + leave_open(), number_of_tabs.value, new Progress( instructions.size ) |
| + ); |
| + current_crawl = new Long_Task( current_crawler ); |
| + current_crawl.run(); |
| + return true; |
| +} |
| + |
| +/** |
| + * Constructor for a display object for the crawler. |
| + */ |
| +function Crawl_Display() |
| +{ |
| + this.display_log = document.getElementById( "display_log" ); |
| + this.log_box = document.getElementById( "log_box" ); |
| +} |
| + |
| +Crawl_Display.prototype.log = function( message ) |
| +{ |
| + this.log_box.value += message + "\n"; |
| +}; |
| + |
| +Crawl_Display.prototype.write = function( message ) |
| +{ |
| + if ( this.display_log.checked ) |
| + this.log_box.value += message; |
| +}; |
| + |
| +crawler_ui_log = (new Logger( "crawler_ui" )).make_log(); |
| + |
| +function filename_timestamp() |
| +{ |
| + var s = Logger.timestamp(); |
| + return "_" + s.substr( 0, 10 ) + "_" + s.substr( 11, 2 ) + "-" + s.substr( 14, 2 ) + "-" + s.substr( 17, 2 ); |
| +} |
| + |
| +var Progress = function( n_instructions ) |
| +{ |
| + this.total = n_instructions; |
| + this.progress_message = document.getElementById( "progress" ); |
| + document.getElementById( "progress_label" ).value = "Active/Completed/Total"; |
| +}; |
| + |
| +Progress.prototype.notice = function( x ) |
| +{ |
| + this.progress_message.value = x.active + "/" + x.completed + "/" + this.total; |
| +}; |