-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathindex.ts
128 lines (107 loc) · 3.08 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import * as Process from 'process';
import {config} from './config'; // Needs to be loaded first
import {startAPIServer, stopAPIServer} from './web';
import Puppeteer, {Browser} from 'puppeteer';
import {getSleepTime} from './util';
import {logger} from './logger';
import {storeList} from './store/model';
import {tryLookupAndLoop} from './store';
let browser: Browser | undefined;
async function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* Schedules a restart of the bot
*/
async function restartMain() {
if (config.restartTime > 0) {
await sleep(config.restartTime);
await stop();
loopMain();
}
}
/**
* Starts the bot.
*/
async function main() {
browser = await launchBrowser();
for (const store of storeList.values()) {
logger.debug('store links', {meta: {links: store.links}});
if (store.setupAction !== undefined) {
store.setupAction(browser);
}
setTimeout(tryLookupAndLoop, getSleepTime(store), browser, store);
}
await startAPIServer();
}
async function stop() {
await stopAPIServer();
if (browser) {
// Use temporary swap variable to avoid any race condition
const browserTemporary = browser;
browser = undefined;
await browserTemporary.close();
}
}
async function stopAndExit() {
await stop();
Process.exit(0);
}
/**
* Will continually run until user interferes.
*/
async function loopMain() {
try {
restartMain();
await main();
} catch (error: unknown) {
logger.error(
'✖ something bad happened, resetting streetmerchant in 5 seconds',
error
);
setTimeout(loopMain, 5000);
}
}
export async function launchBrowser(): Promise<Browser> {
const args: string[] = [];
// Skip Chromium Linux Sandbox
// https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
if (config.browser.isTrusted) {
args.push('--no-sandbox');
args.push('--disable-setuid-sandbox');
}
// https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#tips
// https://stackoverflow.com/questions/48230901/docker-alpine-with-node-js-and-chromium-headless-puppeter-failed-to-launch-c
if (config.docker) {
args.push('--disable-dev-shm-usage');
args.push('--no-sandbox');
args.push('--disable-setuid-sandbox');
args.push('--headless');
args.push('--disable-gpu');
config.browser.open = false;
}
// Add the address of the proxy server if defined
if (config.proxy.address) {
args.push(
`--proxy-server=${config.proxy.protocol}://${config.proxy.address}:${config.proxy.port}`
);
}
if (args.length > 0) {
logger.info('ℹ puppeteer config: ', args);
}
await stop();
const browser = await Puppeteer.launch({
args,
defaultViewport: {
height: config.page.height,
width: config.page.width,
},
headless: config.browser.isHeadless,
});
config.browser.userAgent = await browser.userAgent();
return browser;
}
void loopMain();
process.on('SIGINT', stopAndExit);
process.on('SIGQUIT', stopAndExit);
process.on('SIGTERM', stopAndExit);