Spaces:
Sleeping
Sleeping
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); | |