save and load state
This commit is contained in:
		| @ -3,6 +3,7 @@ | ||||
| <link> | ||||
| <meta charset="utf-8"> | ||||
| <title>Data Extractor</title> | ||||
| <script charset="UTF-8" type="text/javascript" src="../scripts/shared/common.js"></script> | ||||
| <script charset="UTF-8" type="text/javascript" src="tip.js"></script> | ||||
|  | ||||
| <link rel="stylesheet" href="styles/bootstrap.min.css"> | ||||
| @ -32,7 +33,6 @@ | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="row"> | ||||
|  | ||||
|             <div class="col"> | ||||
|                 <h6>Quick Start</h6> | ||||
|             </div> | ||||
| @ -42,22 +42,33 @@ | ||||
|                 <div class="alert alert-success small"> | ||||
|                     <p> | ||||
|                         <b>Extract current page</b>: | ||||
|                         <br>new Extractor().task(".list-item", ["a.title", "p.content"]).start(); | ||||
|                         <br>> $(".list-item", ["a.title", "p.content"]); | ||||
|                     </p> | ||||
|                     <p> | ||||
|                         <b>Extract multiple pages (1-10, interval 1)</b>: | ||||
|                         <br>new Extractor().task(".list-item", ["a.title", "p.content"], | ||||
|                         "http://sample.com/?pn=${page}", 1, 10, 1).start(); | ||||
|                         <br>> job=new Extractor().task(".list-item", ["a.title", "p.content"], | ||||
|                         "http://sample.com/?pn=${page}", 1, 10, 1); | ||||
|                         <br>> job.start(); | ||||
|  | ||||
|                     </p> | ||||
|                     <p> | ||||
|                         <b>Full document:</b> | ||||
|                         <b>Full document at:</b> | ||||
|                         <br> | ||||
|                         <a href="#" id="link-document">https://git.jebbs.co/jebbs/data-extracter-extesion</a> | ||||
|                     </p> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="row"> | ||||
|             <div class="col"> | ||||
|                 <h6>Saved State</h6> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="row"> | ||||
|             <div class="col"> | ||||
|                <input type="file" name="state" id="state-input"> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
|  | ||||
							
								
								
									
										18
									
								
								popup/tip.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								popup/tip.js
									
									
									
									
									
								
							| @ -11,4 +11,22 @@ window.onload = function () { | ||||
|                 'url': `https://git.jebbs.co/jebbs/data-extracter-extesion` | ||||
|             }); | ||||
|         }) | ||||
|     document.querySelector('#state-input') | ||||
|         .addEventListener('change', function (...args) { | ||||
|             if (this.files.length == 1) { | ||||
|                 var reader = new FileReader(); | ||||
|                 let fileName = this.files[0].name; | ||||
|                 reader.readAsText(this.files[0], "UTF-8"); | ||||
|                 reader.onload = function (evt) { | ||||
|                     var fileString = evt.target.result; | ||||
|                     chrome.runtime.sendMessage({ | ||||
|                         action: ACTION_UPLOAD_STATE, | ||||
|                         state: fileString, | ||||
|                         name: fileName | ||||
|                     }, r => { | ||||
|                         if (r) console.log('State sent:', r); | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
| } | ||||
| @ -1,9 +1,31 @@ | ||||
| var __EXTRACTOR_STATE__ = ""; | ||||
|  | ||||
| class Extractor { | ||||
|     constructor(options) { | ||||
|         this._tasks = []; | ||||
|         this._running = false; | ||||
|         this._options = options; | ||||
|     } | ||||
|     /** | ||||
|      * Save current state, in case we restore it later. | ||||
|      */ | ||||
|     save() { | ||||
|         saveFile(JSON.stringify(this), 'application/json', 'state.json'); | ||||
|     } | ||||
|     /** | ||||
|      * Restore previous state by loading from saved state. | ||||
|      */ | ||||
|     load() { | ||||
|         if (!__EXTRACTOR_STATE__) { | ||||
|             console.log('No state found. \nPlease upload a saved state from the popup window first.'); | ||||
|             return; | ||||
|         } | ||||
|         let state = JSON.parse(__EXTRACTOR_STATE__); | ||||
|         __EXTRACTOR_STATE__ = ""; | ||||
|         this._options = state._options; | ||||
|         this._tasks = state._tasks.map(t => new Task(this._options, 'whaterver', ['whaterver']).load(t)); | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Add a task to Extractor. \n | ||||
|      * One Extractor could has multiple tasks, which orgnized in a task chian. | ||||
| @ -76,7 +98,7 @@ class Extractor { | ||||
|         }, Promise.resolve(undefined)).then( | ||||
|             () => { | ||||
|                 this._running = false; | ||||
|                 this.save(); | ||||
|                 this.export(); | ||||
|             } | ||||
|         ).catch(err => { | ||||
|             this._running = false; | ||||
| @ -84,10 +106,10 @@ class Extractor { | ||||
|         }); | ||||
|     } | ||||
|     /** | ||||
|      * Save result of a task | ||||
|      * export result of a task to CSV | ||||
|      * @param {number} taskid which task id to save, begins with 0 | ||||
|      */ | ||||
|     save(taskid) { | ||||
|     export(taskid) { | ||||
|         let id = this._checkTaskId(taskid, this._tasks.length - 1); | ||||
|         if (id < 0) return; | ||||
|         let results = this._tasks[id].results | ||||
|  | ||||
| @ -50,10 +50,18 @@ function sendMessage(tab, req, log, cond, interval, limit = 0) { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { | ||||
|     if (!message.action || !message.action.startsWith(EXT_NAME)) { | ||||
| chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { | ||||
|     if (!request.action || !request.action.startsWith(EXT_NAME)) { | ||||
|         return; | ||||
|     } | ||||
|     sendResponse("Calling from user pages is not allowed."); | ||||
|     return; | ||||
|     switch (request.action) { | ||||
|         case ACTION_UPLOAD_STATE: | ||||
|             sendResponse('recieved!'); | ||||
|             __EXTRACTOR_STATE__ = request.state; | ||||
|             console.log(`State (${request.name}) recieved. Use following to load it: \nsome_var = new Extractor().load()`); | ||||
|             break; | ||||
|         default: | ||||
|             sendResponse("Request not supported."); | ||||
|             break; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| @ -17,6 +17,15 @@ class Task { | ||||
|         this._fieldSelectors = args.shift(); | ||||
|         this._urls = parseUrls(...args); | ||||
|     } | ||||
|     load(state) { | ||||
|         this._itemsSelector = state._itemsSelector; | ||||
|         this._data = state._data; | ||||
|         this._data_keys = state._data_keys; | ||||
|         this._itemsSelector = state._itemsSelector; | ||||
|         this._fieldSelectors = state._fieldSelectors; | ||||
|         this._urls = state._urls; | ||||
|         return this; | ||||
|     } | ||||
|     get urls() { | ||||
|         return this._urls; | ||||
|     } | ||||
|  | ||||
| @ -1,12 +1,8 @@ | ||||
| const EXT_NAME = "DataExtracter"; | ||||
|  | ||||
| const URL_REG = getWebUrl(); | ||||
|  | ||||
| const ACTION_EXTRACT = `${EXT_NAME}:Extract`; | ||||
| const ACTION_GOTO_URL = `${EXT_NAME}:GoToTUL`; | ||||
| const ACTION_REPORT_IN = `${EXT_NAME}:ReportIn`; | ||||
| const ACTION_QUERY_URL = `${EXT_NAME}:QueryURL`; | ||||
| const ACTION_SCROLL_BOTTOM = `${EXT_NAME}:ScrollToBottom`; | ||||
|  | ||||
| const MSG_ELEMENT_NOT_FOUND = new ConstMessage(1, "No element found for at least one selector, maybe it's not loaded yet"); | ||||
| const MSG_URL_SKIPPED = new ConstMessage(100, "Skipped current URL"); | ||||
| const ACTION_UPLOAD_STATE = `${EXT_NAME}:UploadStateFile`; | ||||
|  | ||||
| @ -9,6 +9,10 @@ class ConstMessage { | ||||
|     } | ||||
| } | ||||
|  | ||||
| const URL_REG = getWebUrl(); | ||||
| const MSG_ELEMENT_NOT_FOUND = new ConstMessage(1, "No element found for at least one selector, maybe it's not loaded yet"); | ||||
| const MSG_URL_SKIPPED = new ConstMessage(100, "Skipped current URL"); | ||||
|  | ||||
| function saveFile(data, mimeType, fileName) { | ||||
|     fileName = fileName || document.title || "result"; | ||||
|     var blob; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user