diff --git a/Dockerfile b/Dockerfile index bd737ae..d5f53da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,13 +45,12 @@ RUN apt-get update \ /var/lib/apt/lists/* \ /var/tmp/* -RUN useradd -ms /bin/bash fgc - # RUN node --version # RUN npm --version -RUN ln -s /usr/share/novnc/vnc_auto.html /usr/share/novnc/index.html -RUN pip install apprise +RUN useradd -ms /bin/bash fgc \ + && ln -s /usr/share/novnc/vnc_auto.html /usr/share/novnc/index.html \ + && pip install apprise WORKDIR /fgc COPY package*.json ./ @@ -71,8 +70,7 @@ COPY test ./test COPY docker-entrypoint.sh ./ # Shell scripts need Linux line endings. On Windows, git might be configured to check out dos/CRLF line endings, so we convert them for those people in case they want to build the image. They could also use --config core.autocrlf=input -RUN dos2unix ./*.sh && chmod +x ./*.sh -RUN chown -R fgc:fgc /fgc +RUN dos2unix ./*.sh && chmod +x ./*.sh && chown -R fgc:fgc /fgc COPY docker-entrypoint.sh /usr/local/bin/ ARG COMMIT="" diff --git a/aliexpress.js b/aliexpress.js index f10dc46..a28cf8a 100644 --- a/aliexpress.js +++ b/aliexpress.js @@ -14,7 +14,6 @@ const { fingerprint, headers } = new FingerprintGenerator().getFingerprint({ const context = await firefox.launchPersistentContext(cfg.dir.browser, { headless: cfg.headless, - // viewport: { width: cfg.width, height: cfg.height }, locale: 'en-US', // ignore OS locale to be sure to have english text for locators -> done via /en in URL recordVideo: cfg.record ? { dir: 'data/record/', size: { width: cfg.width, height: cfg.height } } : undefined, // will record a .webm video for each page navigated; without size, video would be scaled down to fit 800x800 recordHar: cfg.record ? { path: `data/record/aliexpress-${filenamify(datetime())}.har` } : undefined, // will record a HAR file with network requests and responses; can be imported in Chrome devtools @@ -29,7 +28,6 @@ const context = await firefox.launchPersistentContext(cfg.dir.browser, { }, }); handleSIGINT(context); -// await stealth(context); await new FingerprintInjector().attachFingerprintToPlaywright(context, { fingerprint, headers }); context.setDefaultTimeout(cfg.debug ? 0 : cfg.timeout); @@ -41,10 +39,7 @@ const auth = async url => { await page.goto(url, { waitUntil: 'domcontentloaded' }); // redirects to https://login.aliexpress.com/?return_url=https%3A%2F%2Fwww.aliexpress.com%2Fp%2Fcoin-pc-index%2Findex.html await Promise.any([page.waitForURL(url => url.includes('login.aliexpress.com')).then(async () => { - // manual login console.error('Not logged in! Will wait for 120s for you to login...'); - // await page.waitForTimeout(120*1000); - // or try automated page.locator('span:has-text("Switch account")').click().catch(() => {}); // sometimes no longer logged in, but previous user/email is pre-selected -> in this case we want to go back to the classic login const login = page.locator('.login-container'); const email = cfg.ae_email || await prompt({ message: 'Enter email' }); @@ -60,12 +55,8 @@ const auth = async url => { const error = login.locator('.error-text'); error.waitFor().then(async () => console.error('Login error:', await error.innerText())); await page.waitForURL(url); - // await page.addLocatorHandler(page.getByRole('button', { name: 'Accept cookies' }), btn => btn.click()); page.getByRole('button', { name: 'Accept cookies' }).click().then(() => console.log('Accepted cookies')).catch(() => { }); }), page.locator('#nav-user-account').waitFor()]).catch(() => {}); - - // await page.locator('#nav-user-account').hover(); - // console.log('Logged in as:', await page.locator('.welcome-name').innerText()); }; // copied URLs from AliExpress app on tablet which has menu for the used webview @@ -82,7 +73,6 @@ const urls = { /* eslint-disable no-unused-vars */ const coins = async () => { - // await auth(urls.coins); await Promise.any([page.locator('.checkin-button').click(), page.locator('.addcoin').waitFor()]); console.log('Coins:', await page.locator('.mycoin-content-right-money').innerText()); console.log('Streak:', await page.locator('.title-box').innerText()); @@ -107,20 +97,13 @@ const merge = async () => { /* eslint-enable no-unused-vars */ try { - // await coins(); await [ - // coins, - // grow, - // gogo, - // euro, merge, ].reduce((a, f) => a.then(async () => { await auth(urls[f.name]); await f(); console.log(); }), Promise.resolve()); - - // await page.pause(); } catch (error) { process.exitCode ||= 1; console.error('--- Exception:'); diff --git a/epic-games.js b/epic-games.js index 4db1e75..b12b35a 100644 --- a/epic-games.js +++ b/epic-games.js @@ -1,8 +1,8 @@ import { firefox } from 'playwright-firefox'; // stealth plugin needs no outdated playwright-extra import { authenticator } from 'otplib'; import chalk from 'chalk'; -import path from 'path'; -import { existsSync, writeFileSync, appendFileSync } from 'fs'; +import path from 'node:path'; +import { existsSync, writeFileSync, appendFileSync } from 'node:fs'; import { resolve, jsonDb, datetime, stealth, filenamify, prompt, notify, html_game_list, handleSIGINT } from './src/util.js'; import { cfg } from './src/config.js'; diff --git a/src/migrate.js b/src/migrate.js index b2db945..80abc9d 100644 --- a/src/migrate.js +++ b/src/migrate.js @@ -1,4 +1,4 @@ -import { existsSync } from 'fs'; +import { existsSync } from 'node:fs'; import { Low } from 'lowdb'; import { JSONFile } from 'lowdb/node'; import { datetime } from './util.js'; diff --git a/src/version.js b/src/version.js index b5cf838..5f61351 100644 --- a/src/version.js +++ b/src/version.js @@ -1,6 +1,4 @@ -// check if running the latest version - -import { log } from 'console'; +import { log } from 'node:console'; import { execFile } from 'node:child_process'; const gitBin = process.env.GIT_BIN || '/usr/bin/git'; @@ -20,10 +18,7 @@ const runGit = (...args) => new Promise((resolve, reject) => { }); }); -// const git_main = () => readFileSync('.git/refs/heads/main').toString().trim(); - let sha, date; -// if (existsSync('/.dockerenv')) { // did not work if (process.env.NOVNC_PORT) { log('Running inside Docker.'); ['COMMIT', 'BRANCH', 'NOW'].forEach(v => log(` ${v}:`, process.env[v])); @@ -33,22 +28,13 @@ if (process.env.NOVNC_PORT) { log('Not running inside Docker.'); sha = await runGit('rev-parse', 'HEAD'); date = await runGit('show', '-s', '--format=%cD'); // same as format as `date -R` (RFC2822) - // date = await execp('git show -s --format=%ch'); // %ch is same as --date=human (short/relative) } -const gh = await (await fetch('https://api.github.com/repos/vogler/free-games-claimer/commits/main', { - // headers: { accept: 'application/vnd.github.VERSION.sha' } -})).json(); -// log(gh); +const gh = await (await fetch('https://api.github.com/repos/vogler/free-games-claimer/commits/main')).json(); log('Local commit:', sha, new Date(date)); log('Online commit:', gh.sha, new Date(gh.commit.committer.date)); -// git describe --all --long --dirty -// --> heads/main-0-gdee47d2-dirty -// git describe --tags --long --dirty -// --> v1.7-35-gdee47d2-dirty - if (sha == gh.sha) { log('Running the latest version!'); } else { diff --git a/test/notify.js b/test/notify.js index 6d89086..b97994d 100644 --- a/test/notify.js +++ b/test/notify.js @@ -6,33 +6,38 @@ const URL_CLAIM = 'https://gaming.amazon.com/home'; // dummy URL console.debug('NOTIFY:', cfg.notify); -if (true) { - const notify_games = [ - // { title: 'Kerbal Space Program', status: 'claimed', url: URL_CLAIM }, - // { title: "Shadow Tactics - Aiko's Choice", status: 'claimed', url: URL_CLAIM }, - { title: 'Epistory - Typing Chronicles', status: 'claimed', url: URL_CLAIM }, - ]; - await notify(`epic-games:
${html_game_list(notify_games)}`); -} +const scenarios = [ + { + enabled: process.env.TEST_NOTIFY_EPIC === '1', + title: 'epic-games', + games: [ + { title: 'Epistory - Typing Chronicles', status: 'claimed', url: URL_CLAIM }, + ], + }, + { + enabled: process.env.TEST_NOTIFY_PG === '1', + delayMs: 1000, + title: 'prime-gaming', + games: [ + { title: 'Faraway 2: Jungle Escape', status: 'claimed', url: URL_CLAIM }, + { title: 'Chicken Police - Paint it RED!', status: 'claimed', url: URL_CLAIM }, + { title: 'Lawn Mowing Simulator', status: 'claimed', url: URL_CLAIM }, + { title: 'Breathedge', status: 'claimed', url: URL_CLAIM }, + { title: 'The Evil Within 2', status: `redeem H97S6FB38FA6D09DEA on gog.com`, url: URL_CLAIM }, + { title: 'Beat Cop', status: `redeem BMKM8558EC55F7B38F on gog.com`, url: URL_CLAIM }, + { title: 'Dishonored 2', status: `redeem NNEK0987AB20DFBF8F on gog.com`, url: URL_CLAIM }, + ], + }, + { + enabled: process.env.TEST_NOTIFY_GOG === '1', + delayMs: 1000, + title: 'gog', + games: [{ title: 'Haven Park', status: 'claimed', url: URL_CLAIM }], + }, +]; -if (false) { - await delay(1000); - const notify_games = [ - { title: 'Faraway 2: Jungle Escape', status: 'claimed', url: URL_CLAIM }, - { title: 'Chicken Police - Paint it RED!', status: 'claimed', url: URL_CLAIM }, - { title: 'Lawn Mowing Simulator', status: 'claimed', url: URL_CLAIM }, - { title: 'Breathedge', status: 'claimed', url: URL_CLAIM }, - { title: 'The Evil Within 2', status: `redeem H97S6FB38FA6D09DEA on gog.com`, url: URL_CLAIM }, - { title: 'Beat Cop', status: `redeem BMKM8558EC55F7B38F on gog.com`, url: URL_CLAIM }, - { title: 'Dishonored 2', status: `redeem NNEK0987AB20DFBF8F on gog.com`, url: URL_CLAIM }, - ]; - notify(`prime-gaming:
${html_game_list(notify_games)}`); -} - -if (false) { - await delay(1000); - const notify_games = [ - { title: 'Haven Park', status: 'claimed', url: URL_CLAIM }, - ]; - notify(`gog:
${html_game_list(notify_games)}`); +for (const scenario of scenarios) { + if (!scenario.enabled) continue; + if (scenario.delayMs) await delay(scenario.delayMs); + await notify(`${scenario.title}:
${html_game_list(scenario.games)}`); } diff --git a/unrealengine.js b/unrealengine.js index 2bb8ee9..4f4de4b 100644 --- a/unrealengine.js +++ b/unrealengine.js @@ -3,8 +3,8 @@ import { firefox } from 'playwright-firefox'; // stealth plugin needs no outdated playwright-extra import { authenticator } from 'otplib'; -import path from 'path'; -import { writeFileSync } from 'fs'; +import path from 'node:path'; +import { writeFileSync } from 'node:fs'; import { resolve, jsonDb, datetime, stealth, filenamify, prompt, notify, html_game_list, handleSIGINT } from './src/util.js'; import { cfg } from './src/config.js';