OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * This Source Code is subject to the terms of the Mozilla Public License |
| 3 * version 2.0 (the "License"). You can obtain a copy of the License at |
| 4 * http://mozilla.org/MPL/2.0/. |
| 5 */ |
| 6 |
| 7 /* |
| 8 * crawler_ui.js |
| 9 */ |
| 10 /** |
| 11 * @fileOverview These functions implement the user interface behaviors of the t
op-level control dialog. |
| 12 */ |
| 13 |
| 14 const Cu = Components.utils; |
| 15 const Cc = Components.classes; |
| 16 const Ci = Components.interfaces; |
| 17 |
| 18 Cu.import( "resource://gre/modules/Services.jsm" ); |
| 19 Cu.import( "resource://gre/modules/FileUtils.jsm" ); |
| 20 |
| 21 function require( module ) |
| 22 { |
| 23 let result = {}; |
| 24 result.wrappedJSObject = result; |
| 25 Services.obs.notifyObservers( result, "abpcrawler-require", module ); |
| 26 if ( !("exports" in result) ) |
| 27 { |
| 28 Cu.reportError( "crawler_ui require: 'exports' missing from module \"" +
module + "\"" ); |
| 29 } |
| 30 return result.exports; |
| 31 } |
| 32 let {Storage} = require( "storage" ); |
| 33 let {Instruction, Instruction_Set, Input_String, Input_File} = require( "instruc
tion" ); |
| 34 let {Long_Task} = require( "task" ); |
| 35 let {Crawler} = require( "crawler" ); |
| 36 let {Logger} = require( "logger" ); |
| 37 |
| 38 //------------------------------------------------------- |
| 39 // New code |
| 40 //------------------------------------------------------- |
| 41 |
| 42 var current_crawler = null; |
| 43 var current_crawl = null; |
| 44 var preference_service, preference_branch; |
| 45 var go_button; |
| 46 var base_name, base_name_initial_value; |
| 47 var number_of_tabs; |
| 48 var input_file, input_file_initial_value; |
| 49 var output_directory, output_directory_initial_value; |
| 50 |
| 51 function loader() |
| 52 { |
| 53 go_button = document.getElementById( "crawl_go" ); |
| 54 preference_service = Cc["@mozilla.org/preferences-service;1"].getService( Ci
.nsIPrefService ); |
| 55 preference_branch = preference_service.getBranch( "extensions.abpcrawler." )
; |
| 56 |
| 57 /* |
| 58 * Set up the output directory values and preferences. |
| 59 */ |
| 60 input_file = document.getElementById( "input_file" ); |
| 61 base_name = document.getElementById( "base_name" ); |
| 62 output_directory = document.getElementById( "output_directory" ); |
| 63 |
| 64 if ( preference_branch.prefHasUserValue( "input_file" ) ) |
| 65 { |
| 66 input_file_initial_value = preference_branch.getCharPref( "input_file" )
; |
| 67 input_file.value = input_file_initial_value; |
| 68 } |
| 69 base_name_initial_value = base_name.value; |
| 70 if ( preference_branch.prefHasUserValue( "base_name" ) ) |
| 71 { |
| 72 base_name_initial_value = preference_branch.getCharPref( "base_name" ); |
| 73 base_name.value = base_name_initial_value; |
| 74 } |
| 75 else |
| 76 { |
| 77 base_name_initial_value = base_name.value; |
| 78 } |
| 79 if ( preference_branch.prefHasUserValue( "output_directory" ) ) |
| 80 { |
| 81 output_directory_initial_value = preference_branch.getCharPref( "output_
directory" ); |
| 82 output_directory.value = output_directory_initial_value; |
| 83 } |
| 84 else |
| 85 { |
| 86 output_directory_initial_value = ""; |
| 87 var dir = FileUtils.getDir( "Home", [] ); |
| 88 output_directory.value = dir.path; |
| 89 } |
| 90 |
| 91 document.getElementById( "input_file_icon" ).addEventListener( "click", icon
_input_click ); |
| 92 document.getElementById( "output_directory_icon" ).addEventListener( "click"
, icon_output_click ); |
| 93 } |
| 94 |
| 95 function unloader() |
| 96 { |
| 97 if ( current_crawler ) |
| 98 { |
| 99 current_crawler.close(); |
| 100 current_crawler = null; |
| 101 } |
| 102 if ( current_crawl ) |
| 103 { |
| 104 current_crawl.close(); |
| 105 current_crawl = null; |
| 106 } |
| 107 } |
| 108 |
| 109 function icon_input_click() |
| 110 { |
| 111 var fp = Cc["@mozilla.org/filepicker;1"].createInstance( Ci.nsIFilePicker ); |
| 112 fp.init( window, "Select an Input File", Ci.nsIFilePicker.modeOpen ); |
| 113 if ( input_file.value != "" && input_file.value != null ) |
| 114 { |
| 115 var f = new FileUtils.File( input_file.value ); |
| 116 if ( f.exists() ) |
| 117 { |
| 118 if ( f.isFile() ) |
| 119 { |
| 120 f = f.parent; |
| 121 } |
| 122 if ( f.isDirectory() ) |
| 123 { |
| 124 fp.displayDirectory = f; |
| 125 } |
| 126 } |
| 127 } |
| 128 var result = fp.show(); |
| 129 switch ( result ) |
| 130 { |
| 131 case Ci.nsIFilePicker.returnOK: |
| 132 f = fp.file; |
| 133 if ( f.isFile() ) |
| 134 { |
| 135 input_file.value = fp.file.path; |
| 136 } |
| 137 break; |
| 138 case Ci.nsIFilePicker.returnCancel: |
| 139 break; |
| 140 case Ci.nsIFilePicker.returnReplace: |
| 141 break; |
| 142 default: |
| 143 break; |
| 144 } |
| 145 } |
| 146 |
| 147 function icon_output_click() |
| 148 { |
| 149 var fp = Cc["@mozilla.org/filepicker;1"].createInstance( Ci.nsIFilePicker ); |
| 150 fp.init( window, "Select an Output Folder", Ci.nsIFilePicker.modeGetFolder )
; |
| 151 var result = fp.show(); |
| 152 switch ( result ) |
| 153 { |
| 154 case Ci.nsIFilePicker.returnOK: |
| 155 output_directory.value = fp.file.path; |
| 156 break; |
| 157 case Ci.nsIFilePicker.returnCancel: |
| 158 break; |
| 159 case Ci.nsIFilePicker.returnReplace: |
| 160 break; |
| 161 default: |
| 162 break; |
| 163 } |
| 164 } |
| 165 |
| 166 function leave_open() |
| 167 { |
| 168 return document.getElementById( "leave_open" ).checked; |
| 169 } |
| 170 |
| 171 function start_crawl() |
| 172 { |
| 173 var log = crawler_ui_log; |
| 174 log( "Start crawl", false ); |
| 175 |
| 176 /* |
| 177 * Save preferences automatically when we start a crawl. |
| 178 */ |
| 179 var saving_input = ( input_file_initial_value != input_file.value ); |
| 180 var saving_basename = ( base_name_initial_value != base_name.value ); |
| 181 var saving_dir = ( output_directory.value != output_directory_initial_value
); |
| 182 if ( saving_input ) |
| 183 { |
| 184 preference_branch.setCharPref( "input_file", input_file.value ); |
| 185 } |
| 186 if ( saving_basename ) |
| 187 { |
| 188 preference_branch.setCharPref( "base_name", base_name.value ); |
| 189 } |
| 190 if ( saving_dir ) |
| 191 { |
| 192 preference_branch.setCharPref( "output_directory", output_directory.valu
e ); |
| 193 } |
| 194 if ( saving_input || saving_basename || saving_dir ) |
| 195 { |
| 196 preference_service.savePrefFile( null ); |
| 197 /* |
| 198 * Recalculate initial values only when saving. |
| 199 */ |
| 200 input_file_initial_value = input_file.value; |
| 201 base_name_initial_value = base_name.value; |
| 202 output_directory_initial_value = output_directory.value; |
| 203 } |
| 204 var log_window = new Crawl_Display(); |
| 205 var log_to_textbox = new Storage.Display_Log( log_window ); |
| 206 |
| 207 /* |
| 208 * Input |
| 209 */ |
| 210 var instructions; |
| 211 var si = document.getElementById( "instructions_tabbox" ).selectedIndex; |
| 212 switch ( si ) |
| 213 { |
| 214 case 0: |
| 215 log_window.log( "Server input not supported at present. Aborted." ); |
| 216 return false; |
| 217 case 1: |
| 218 var f = new FileUtils.File( input_file.value ); |
| 219 if ( !f.exists() ) |
| 220 { |
| 221 log_window.log( "Input file does not exist. name = " + f.path ); |
| 222 return false; |
| 223 } |
| 224 if ( !f.isFile() ) |
| 225 { |
| 226 log_window.log( "Input does not name a file. name = " + f.path )
; |
| 227 return false; |
| 228 } |
| 229 instructions = new Instruction_Set.Parsed( new Input_File( f ) ); |
| 230 break; |
| 231 case 2: |
| 232 var fixed_source = "" |
| 233 + "name: Fixed internal development test\n" |
| 234 + "target:\n" |
| 235 + " - yahoo.com\n" |
| 236 + " - ksl.com\n" |
| 237 + ""; |
| 238 instructions = new Instruction_Set.Parsed( new Input_String( fixed_s
ource ) ); |
| 239 break; |
| 240 default: |
| 241 log_window.log( "WTF? Unknown input tab. Aborted. si=" + si ); |
| 242 return false; |
| 243 } |
| 244 // Assert 'instructions' contains a valid 'Instruction_Set' object |
| 245 |
| 246 /* |
| 247 * Tab configuration |
| 248 */ |
| 249 number_of_tabs = document.getElementById( "number_of_tabs" ); |
| 250 // preference initialization goes here. |
| 251 |
| 252 /* |
| 253 * Encoding |
| 254 */ |
| 255 var encoding = null, suffix = ""; |
| 256 switch ( document.getElementById( "format" ).selectedIndex ) |
| 257 { |
| 258 case 0: |
| 259 encoding = "JSON"; |
| 260 suffix = ".json"; |
| 261 break; |
| 262 case 1: |
| 263 encoding = "YAML"; |
| 264 suffix = ".yaml"; |
| 265 break; |
| 266 default: |
| 267 log_window.log( "Unknown output encoding. Aborted." ); |
| 268 return false; |
| 269 } |
| 270 |
| 271 /* |
| 272 * Output |
| 273 */ |
| 274 var outputs = [ |
| 275 { storage: log_to_textbox, encode: "YAML" } |
| 276 ]; |
| 277 si = document.getElementById( "storage_tabbox" ).selectedIndex; |
| 278 switch ( si ) |
| 279 { |
| 280 case 0: |
| 281 log_window.log( "Server storage not supported at present. Aborted."
); |
| 282 return false; |
| 283 case 1: |
| 284 var file = Cc["@mozilla.org/file/local;1"].createInstance( Ci.nsILoc
alFile ); |
| 285 file.initWithPath( output_directory.value ); |
| 286 file.append( base_name.value + filename_timestamp() + suffix ); |
| 287 log_window.log( "Computed file name = " + file.path ); |
| 288 outputs.push( { storage: new Storage.Local_File( file ), encode: enc
oding } ); |
| 289 break; |
| 290 case 2: |
| 291 /* |
| 292 * This is in at present to ensure that the JSON encoder does not un
expectedly throw. We can take it out |
| 293 * when we're assured that it doesn't. |
| 294 */ |
| 295 outputs.push( { storage: new Storage.Bit_Bucket(), encode: "JSON" }
); |
| 296 break; |
| 297 default: |
| 298 log_window.log( "WTF? Unknown storage tab. Aborted. si=" + si ); |
| 299 return false; |
| 300 } |
| 301 |
| 302 let mainWindow = window.opener; |
| 303 if ( !mainWindow || mainWindow.closed ) |
| 304 { |
| 305 log_window.log( "Unable to find the main window, aborting." ); |
| 306 return false; |
| 307 } |
| 308 current_crawler = new Crawler( |
| 309 instructions, outputs, log_window, mainWindow, |
| 310 leave_open(), number_of_tabs.value, new Progress( instructions.size ) |
| 311 ); |
| 312 current_crawl = new Long_Task( current_crawler ); |
| 313 current_crawl.run(); |
| 314 return true; |
| 315 } |
| 316 |
| 317 /** |
| 318 * Constructor for a display object for the crawler. |
| 319 */ |
| 320 function Crawl_Display() |
| 321 { |
| 322 this.display_log = document.getElementById( "display_log" ); |
| 323 this.log_box = document.getElementById( "log_box" ); |
| 324 } |
| 325 |
| 326 Crawl_Display.prototype.log = function( message ) |
| 327 { |
| 328 this.log_box.value += message + "\n"; |
| 329 }; |
| 330 |
| 331 Crawl_Display.prototype.write = function( message ) |
| 332 { |
| 333 if ( this.display_log.checked ) |
| 334 this.log_box.value += message; |
| 335 }; |
| 336 |
| 337 crawler_ui_log = (new Logger( "crawler_ui" )).make_log(); |
| 338 |
| 339 function filename_timestamp() |
| 340 { |
| 341 var s = Logger.timestamp(); |
| 342 return "_" + s.substr( 0, 10 ) + "_" + s.substr( 11, 2 ) + "-" + s.substr( 1
4, 2 ) + "-" + s.substr( 17, 2 ); |
| 343 } |
| 344 |
| 345 var Progress = function( n_instructions ) |
| 346 { |
| 347 this.total = n_instructions; |
| 348 this.progress_message = document.getElementById( "progress" ); |
| 349 document.getElementById( "progress_label" ).value = "Active/Completed/Total"
; |
| 350 }; |
| 351 |
| 352 Progress.prototype.notice = function( x ) |
| 353 { |
| 354 this.progress_message.value = x.active + "/" + x.completed + "/" + this.tota
l; |
| 355 }; |
OLD | NEW |