From c7f4fe7cc4e09868363864c67040dd54cc6257b2 Mon Sep 17 00:00:00 2001 From: jebbs Date: Sun, 12 Jan 2020 16:19:38 +0800 Subject: [PATCH] save and load state --- popup/tip.html | 21 ++++++++++++++++----- popup/tip.js | 18 ++++++++++++++++++ scripts/background/extractor.js | 28 +++++++++++++++++++++++++--- scripts/background/messaging.js | 16 ++++++++++++---- scripts/background/task.js | 9 +++++++++ scripts/shared/common.js | 6 +----- scripts/shared/tools.js | 4 ++++ 7 files changed, 85 insertions(+), 17 deletions(-) diff --git a/popup/tip.html b/popup/tip.html index 2ad5230..c4c3257 100644 --- a/popup/tip.html +++ b/popup/tip.html @@ -3,6 +3,7 @@ Data Extractor + @@ -32,7 +33,6 @@
-
Quick Start
@@ -42,22 +42,33 @@

Extract current page: -
new Extractor().task(".list-item", ["a.title", "p.content"]).start(); +
> $(".list-item", ["a.title", "p.content"]);

Extract multiple pages (1-10, interval 1): -
new Extractor().task(".list-item", ["a.title", "p.content"], - "http://sample.com/?pn=${page}", 1, 10, 1).start(); +
> job=new Extractor().task(".list-item", ["a.title", "p.content"], + "http://sample.com/?pn=${page}", 1, 10, 1); +
> job.start();

- Full document: + Full document at:
https://git.jebbs.co/jebbs/data-extracter-extesion

+
+
+
Saved State
+
+
+
+
+ +
+
diff --git a/popup/tip.js b/popup/tip.js index bdf79ab..147b1e1 100644 --- a/popup/tip.js +++ b/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); + }); + } + } + }); } \ No newline at end of file diff --git a/scripts/background/extractor.js b/scripts/background/extractor.js index cc15e3d..ab9866d 100644 --- a/scripts/background/extractor.js +++ b/scripts/background/extractor.js @@ -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 diff --git a/scripts/background/messaging.js b/scripts/background/messaging.js index 92fdf9d..66d9841 100644 --- a/scripts/background/messaging.js +++ b/scripts/background/messaging.js @@ -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; + } }); diff --git a/scripts/background/task.js b/scripts/background/task.js index 43cb2f9..2b61195 100644 --- a/scripts/background/task.js +++ b/scripts/background/task.js @@ -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; } diff --git a/scripts/shared/common.js b/scripts/shared/common.js index 3d53524..5a70c35 100644 --- a/scripts/shared/common.js +++ b/scripts/shared/common.js @@ -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`; diff --git a/scripts/shared/tools.js b/scripts/shared/tools.js index 640fb65..99d2470 100644 --- a/scripts/shared/tools.js +++ b/scripts/shared/tools.js @@ -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;