var serve = require("koa-static"); const { v4: uuid } = require("uuid"); 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) => { ctx.body = /* HTML */ `


`; }); router.get("/preview", 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);
console.log("server started");