var serve = require("koa-static");
const Koa = require("koa");
const Router = require("@koa/router");
const mount = require("koa-mount");
const qs = require("qs");
const { Readable } = require("stream");
const { spawn } = require("child_process");
const { requests } = require("./memory");
const ScreenshotRequest = require("./request");
const DOCKER_ARGS = require("./docker-args");
const router = new Router();
// response
const app = new Koa();
const static = new Koa();
static.use(serve("./static"));
app.use(mount("/static", static));
function attach(docker_id, output_stream) {
// to prevent browser timeout
const interval = setInterval(() => output_stream.push(""), 500);
const task = spawn("docker", ["logs", "-f", docker_id]);
task.stdout.on("data", (d) => {
output_stream.push(d);
console.log("DATA!", d.toString());
});
task.stderr.on("data", (d) => {
/* output_stream.push(d); */
console.log("STDERR!", d.toString());
});
task.stdout.on("error", (d) => {
output_stream.push(d);
});
task.on("close", () => {
output_stream.push("");
output_stream.push(/* HTML */ ``);
clearInterval(interval);
output_stream.push(null);
});
}
router.get("/", async (ctx) => {
const s = new Readable({ read() {} });
// stream data
ctx.response.set("content-type", "txt/html");
ctx.type = "html"; // <-- THIS is the important step!
ctx.body = s;
ctx.body.push("");
const id = uuid();
ctx.body.push(
`
`
);
ctx.body.push(/* HTML */ ``);
const params = qs.parse(ctx.querystring);
s.push(`Got request to screenshot ${params.url}
`); let docker_id = ""; if (!params.url) { ctx.body = "specify url!"; return; } const starter = spawn( "docker", [ ...DOCKER_ARGS, `{"url": "${params.url}", "third_party_domains": ["hotjar.com", "cookielaw.org", "facebook.com", "gemius.pl"]}`, id, ], { cwd: process.cwd() } ); starter.stdout.on("data", (data) => { docker_id += data.toString().replace(/\n/g, ""); }); starter.on("close", () => { ctx.body.push("spawned " + docker_id); attach(docker_id, ctx.body); }); }); router.post("/api/requests", async (ctx) => { const params = qs.parse(ctx.querystring); if (!params.url) { ctx.body = "Specify url"; ctx.status = 422; return; } if (!params.domains) { ctx.body = "Specify domains"; ctx.status = 422; return; } if (!Array.isArray(params.domains)) { ctx.body = "'domains' should be an array of strings"; ctx.status = 422; return; } const request = new ScreenshotRequest(params.url, params.domains); ctx.status = 303; ctx.redirect(`/api/requests/${request.id}`); }); router.get("/api/requests/:id", async (ctx) => { const request = requests[ctx.params.id]; if (!request) { ctx.status = 404; return; } ctx.body = await request.getJSON(); }); app.use(router.routes()).use(router.allowedMethods()); app.listen(3000);