feat: invert logic (#141)

Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
This commit is contained in:
admon84
2020-09-22 21:33:36 -06:00
committed by GitHub
parent a70e63bb35
commit 6608a79769
16 changed files with 183 additions and 79 deletions
+87 -53
View File
@@ -1,8 +1,8 @@
import {Browser, Response} from 'puppeteer';
import {Browser, Page, Response} from 'puppeteer';
import {Link, Store} from './model';
import {closePage, delay, getSleepTime} from '../util';
import {Config} from '../config';
import {Logger} from '../logger';
import {Store} from './model';
import {includesLabels} from './includes-labels';
import open from 'open';
import {sendNotification} from '../notification';
@@ -57,58 +57,10 @@ async function lookup(browser: Browser, store: Store) {
page.setDefaultNavigationTimeout(Config.page.navigationTimeout);
await page.setUserAgent(Config.page.userAgent);
const graphicsCard = `${link.brand} ${link.model} ${link.series}`;
let response: Response | null;
try {
response = await page.goto(link.url, {waitUntil: 'networkidle0'});
} catch {
Logger.error(`✖ [${store.name}] ${graphicsCard} skipping; timed out`);
await closePage(page);
continue;
}
const bodyHandle = await page.$('body');
const textContent = await page.evaluate(body => body.textContent, bodyHandle);
Logger.debug(textContent);
if (includesLabels(textContent, store.labels.outOfStock)) {
Logger.info(`✖ [${store.name}] still out of stock: ${graphicsCard}`);
} else if (store.labels.bannedSeller && includesLabels(textContent, store.labels.bannedSeller)) {
Logger.warn(`✖ [${store.name}] banned seller detected: ${graphicsCard}. skipping...`);
} else if (store.labels.captcha && includesLabels(textContent, store.labels.captcha)) {
Logger.warn(`✖ [${store.name}] CAPTCHA from: ${graphicsCard}. Waiting for a bit with this store...`);
await delay(getSleepTime());
} else if (response && response.status() === 429) {
Logger.warn(`✖ [${store.name}] Rate limit exceeded: ${graphicsCard}`);
} else {
Logger.info(`🚀🚀🚀 [${store.name}] ${graphicsCard} IN STOCK 🚀🚀🚀`);
Logger.info(link.url);
if (Config.page.inStockWaitTime) {
inStock[store.name] = true;
setTimeout(() => {
inStock[store.name] = false;
}, 1000 * Config.page.inStockWaitTime);
}
if (Config.page.capture) {
Logger.debug(' saving screenshot');
link.screenshot = `success-${Date.now()}.png`;
await page.screenshot({path: link.screenshot});
}
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
if (Config.browser.open) {
if (link.openCartAction === undefined) {
await open(givenUrl);
} else {
link.openCartAction(browser);
}
}
sendNotification(givenUrl, link);
await lookupCard(browser, store, page, link);
} catch (error) {
Logger.error(`✖ [${store.name}] ${link.brand} ${link.model} - ${error.message as string}`);
}
await closePage(page);
@@ -116,6 +68,88 @@ async function lookup(browser: Browser, store: Store) {
/* eslint-enable no-await-in-loop */
}
async function lookupCard(browser: Browser, store: Store, page: Page, link: Link) {
const response: Response | null = await page.goto(link.url, {waitUntil: 'networkidle0'});
const graphicsCard = `${link.brand} ${link.model}`;
if (await lookupCardInStock(store, page)) {
Logger.info(`🚀🚀🚀 [${store.name}] ${graphicsCard} IN STOCK 🚀🚀🚀`);
Logger.info(link.url);
if (Config.page.inStockWaitTime) {
inStock[store.name] = true;
setTimeout(() => {
inStock[store.name] = false;
}, 1000 * Config.page.inStockWaitTime);
}
if (Config.page.capture) {
Logger.debug(' saving screenshot');
link.screenshot = `success-${Date.now()}.png`;
await page.screenshot({path: link.screenshot});
}
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
if (Config.browser.open) {
if (link.openCartAction === undefined) {
await open(givenUrl);
} else {
link.openCartAction(browser);
}
}
sendNotification(givenUrl, link);
return;
}
if (await lookupPageHasCaptcha(store, page)) {
Logger.warn(`✖ [${store.name}] CAPTCHA from: ${graphicsCard}. Waiting for a bit with this store...`);
await delay(getSleepTime());
return;
}
if (response && response.status() === 429) {
Logger.warn(`✖ [${store.name}] Rate limit exceeded: ${graphicsCard}`);
return;
}
Logger.info(`✖ [${store.name}] still out of stock: ${graphicsCard}`);
}
async function lookupCardInStock(store: Store, page: Page) {
const stockHandle = await page.$(store.labels.inStock.container);
const visible = await page.evaluate(element => element && element.offsetWidth > 0 && element.offsetHeight > 0, stockHandle);
if (!visible) {
return false;
}
const stockContent = await page.evaluate(element => element.outerHTML, stockHandle);
Logger.debug(stockContent);
if (includesLabels(stockContent, store.labels.inStock.text)) {
return true;
}
return false;
}
async function lookupPageHasCaptcha(store: Store, page: Page) {
if (!store.labels.captcha) {
return false;
}
const captchaHandle = await page.$(store.labels.captcha.container);
const captchaContent = await page.evaluate(element => element.textContent, captchaHandle);
if (includesLabels(captchaContent, store.labels.captcha.text)) {
return true;
}
return false;
}
export async function tryLookupAndLoop(browser: Browser, store: Store) {
Logger.debug(`[${store.name}] Starting lookup...`);
try {