Extractor.watch() improvements
- only watch current window - stop watch on window close - don't ask user to confirm when fails
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { Actions, Request } from "../common";
|
||||
import { sendMessage } from "./messaging";
|
||||
import { logger } from "./common";
|
||||
|
||||
/**
|
||||
* redirect tab to url.
|
||||
@ -41,7 +42,7 @@ export function redirectTab(tab: chrome.tabs.Tab, url: string) {
|
||||
* @param {Array<string>} fieldSelectors fields selectors for selecting fields (data columns) under each item
|
||||
* @returns {Promise<string[]>} a promise of extracted data
|
||||
*/
|
||||
export function extractTabData(tab, itemsSelector, fieldSelectors) {
|
||||
export function extractTabData(tab: chrome.tabs.Tab, itemsSelector: string, fieldSelectors: string[], askOnfail?: boolean) {
|
||||
let req = {
|
||||
action: Actions.EXTRACT,
|
||||
itemsSelector: itemsSelector,
|
||||
@ -49,7 +50,13 @@ export function extractTabData(tab, itemsSelector, fieldSelectors) {
|
||||
}
|
||||
let checker = (result, err, tryCount) => {
|
||||
if (!result || !result.length) {
|
||||
if (tryCount % 20 == 0 && confirm('No data found in current page. \n\nContinue to next page?')) {
|
||||
if (
|
||||
tryCount % 20 == 0 && (
|
||||
!askOnfail ||
|
||||
confirm('No data found in current page. \n\nContinue to next page?')
|
||||
)
|
||||
) {
|
||||
logger.warn(`Failed after ${tryCount} tries: ${tab.url}`)
|
||||
return [];
|
||||
} else {
|
||||
return undefined;
|
||||
@ -135,6 +142,25 @@ export async function findIncognitoWindow(): Promise<chrome.windows.Window> {
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCurrentWindow(): Promise<chrome.windows.Window> {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.windows.getCurrent(
|
||||
(windows: chrome.windows.Window) => {
|
||||
return resolve(windows);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export async function getWindowByID(id: number) {
|
||||
return new Promise<chrome.windows.Window>((resolve, reject) => {
|
||||
chrome.windows.get(id, function (window) {
|
||||
chrome.runtime.lastError;
|
||||
resolve(window);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function CreateIncognitoWindow() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.windows.create(
|
||||
|
||||
@ -31,7 +31,7 @@ export function sendMessage<T>(
|
||||
loop();
|
||||
|
||||
async function loop() {
|
||||
logger.debug("Request for", req.action);
|
||||
logger.debug("Request for", Actions[req.action]);
|
||||
let tabAvailable = await getTabByID(tab.id);
|
||||
if (!tabAvailable) {
|
||||
reject("Task interrupted due to the target tab is closed.");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { parseUrls } from "./tools";
|
||||
import { queryUrl, redirectTab, scrollToBottom, extractTabData } from "./actions";
|
||||
import { queryUrl, redirectTab, scrollToBottom, extractTabData, findIncognitoWindow, getCurrentWindow, getWindowByID } from "./actions";
|
||||
import { testArgs, signitures } from "./signiture";
|
||||
import { ExtractResult } from "./result";
|
||||
import { messageSubscribers, ActionSubscriber } from "./messaging";
|
||||
@ -14,6 +14,7 @@ export class Task {
|
||||
private _fieldSelectors: string[];
|
||||
private _urls: string[] = [];
|
||||
private _running = false;
|
||||
private _listeners: ActionSubscriber[] = [];
|
||||
|
||||
constructor(options: any, ...arg: any);
|
||||
constructor(options: any, itemsSelector: string, fieldSelectors: string[]);
|
||||
@ -56,15 +57,46 @@ export class Task {
|
||||
}
|
||||
stop() {
|
||||
this._running = false;
|
||||
messageSubscribers.removeListener(Actions.REPORT_NEW_PAGE, this.listener);
|
||||
let listener: ActionSubscriber;
|
||||
while (listener = this._listeners.pop()) {
|
||||
messageSubscribers.removeListener(Actions.REPORT_NEW_PAGE, listener);
|
||||
}
|
||||
}
|
||||
watch() {
|
||||
async watch() {
|
||||
if (this._running) {
|
||||
logger.info("The task is running. Please wait...");
|
||||
return;
|
||||
}
|
||||
this._running = true;
|
||||
messageSubscribers.addListener(Actions.REPORT_NEW_PAGE, this.listener);
|
||||
let window = await findIncognitoWindow() || await getCurrentWindow();
|
||||
if (!window) {
|
||||
logger.info("No window to watch...");
|
||||
return;
|
||||
}
|
||||
let listener: ActionSubscriber = async (request, sender, sendResponse) => {
|
||||
let findWindow = await getWindowByID(window.id);
|
||||
if (!findWindow) {
|
||||
// stop watch on window close.
|
||||
messageSubscribers.removeListener(Actions.REPORT_NEW_PAGE, listener);
|
||||
return;
|
||||
}
|
||||
// only watch current window.
|
||||
if (sender.tab.windowId != window.id) return;
|
||||
let pm = this.makeOptionalTasks(sender.tab);
|
||||
return pm.then(
|
||||
() => extractTabData(sender.tab, this._itemsSelector, this._fieldSelectors, false)
|
||||
).then(
|
||||
results => {
|
||||
if (results && results.length) {
|
||||
this.saveResult(results, sender.tab.url);
|
||||
}
|
||||
}
|
||||
).catch(
|
||||
e => logger.error(e)
|
||||
)
|
||||
}
|
||||
this._listeners.push(listener);
|
||||
messageSubscribers.addListener(Actions.REPORT_NEW_PAGE, listener);
|
||||
}
|
||||
async execute(tab: chrome.tabs.Tab, upstreamData?: ExtractResult): Promise<void> {
|
||||
if (!tab) return Promise.reject("No tab to execute the task.");
|
||||
@ -108,21 +140,6 @@ export class Task {
|
||||
}
|
||||
);
|
||||
}
|
||||
private listener: ActionSubscriber = (request, sender, sendResponse) => {
|
||||
sendResponse('recieved!');
|
||||
let pm = this.makeOptionalTasks(sender.tab);
|
||||
return pm.then(
|
||||
() => extractTabData(sender.tab, this._itemsSelector, this._fieldSelectors)
|
||||
).then(
|
||||
results => {
|
||||
if (results && results.length) {
|
||||
this.saveResult(results, sender.tab.url);
|
||||
}
|
||||
}
|
||||
).catch(
|
||||
e => logger.error(e)
|
||||
)
|
||||
}
|
||||
private makeOptionalTasks(tab: chrome.tabs.Tab): Promise<any> {
|
||||
let pm: Promise<any>;
|
||||
if (this._options["scrollToBottom"]) {
|
||||
|
||||
Reference in New Issue
Block a user