import * as http from 'http'; import * as url from 'url'; import * as path from 'path'; import { chromium } from 'playwright'; import { locks } from 'web-locks'; import crypto from 'crypto'; import fs from 'fs'; import { setTimeout } from 'timers/promises'; // npm i playwright // npm i web-locks // nohup cloudflared tunnel --url http://localhost:8080 --no-autoupdate & (or setsid) // setsid node playwright.mjs (nohup doesnt work) // curl 'https://gowah44030-playwright.hf.space/.. globalThis.state = Object.assign(globalThis.state||{}, { browser: null, context: null, }); async function text_from_url(url, cookie) { let { browser, context } = globalThis.state; if (!browser) { await locks.request('playwright_browser', async lock => { browser = globalThis.state.browser = await chromium.launch(); context = globalThis.state.context = await browser.newContext({ javaScriptEnabled: false }/*devices['iPhone 11']*/); }); } const page = await context.newPage(); if (cookie) { if (cookie.endsWith(';')) cookie = cookie.slice(0, -1); let cookies = cookie.split(';'); cookies = cookies.map(it=>{ let [name, value] = it.split('='); return {name: name.trim(), value: value.trim(), url}; }); context.addCookies(cookies); } await context.route("**/*.{png,jpg,jpeg,css,js}", route => route.abort()); await page.goto(url); let text; let i = 0; while (true) { let new_text = await page.evaluate(() => document.body.innerText); if (i > 5 || new_text?.length > 200) { text = new_text; break; } i++; await new Promise(resolve=>setTimeout(resolve, 1000)); } await page.close(); //await context.close(); // await browser.close(); return text; } async function screenshot(url, cookie, js_enabled) { let { browser, context } = globalThis.state; if (!browser) { await locks.request('playwright_browser', async lock => { browser = globalThis.state.browser = await chromium.launch(); context = globalThis.state.context = await browser.newContext({ javaScriptEnabled: js_enabled }/*devices['iPhone 11']*/); }); } const page = await context.newPage(); if (cookie) { if (cookie.endsWith(';')) cookie = cookie.slice(0, -1); let cookies = cookie.split(';'); cookies = cookies.map(it=>{ let [name, value] = it.split('='); return {name: name.trim(), value: value.trim(), url}; }); context.addCookies(cookies); } //await context.route("**/*.{png,jpg,jpeg,css,js}", route => route.abort()); await page.goto(url); await setTimeout(2000); // let id = crypto.randomUUID(); // let path = `/code/${id}.png`; // await page.screenshot({ path, fullPage: true }); const buffer = await page.screenshot({fullPage: true}); await page.close(); //await context.close(); // await browser.close(); return buffer; } const server = http.createServer(async function(req, res) { const {query, pathname} = url.parse(req.url, true); res.setHeader('Access-Control-Allow-Origin', '*') let _url = query.url; let cookie = query.cookie; try { if (pathname == '/text') { let text = await text_from_url(_url, cookie); res.end(text); } else if (pathname == '/screenshot') { let buffer = await screenshot(_url, cookie, true); res.writeHead(200,{'Content-type':'image/png'}); res.end(buffer); // const readStream = fs.createReadStream(path); // res.writeHead(200,{'Content-type':'image/png'}); // readStream.pipe(res); // res.end(); } else { res.end('hello'); } } catch (e) { res.end(e.toString()); } }); server.listen(7860);