diff --git a/README.md b/README.md index 1572d90..03b2fb5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,19 @@ # motivational-picture-generator -A project to learn NodeJS, ExpressJS, and whatever else along the way. \ No newline at end of file +A project to learn NodeJS, ExpressJS, and whatever else along the way. + +**THIS IS ALL WORK IN PROGRESS AND SUBJECT TO CHANGE** + +To start server + +```bash +npm run dev +``` + +Make url request to `localhost:4000/submit/{}` + +Testing with + +```bash +ab -c 5 -t 15 http://localhost:4000/submit/\{\} +``` \ No newline at end of file diff --git a/image-generator.cjs b/image-generator.cjs new file mode 100644 index 0000000..eb27920 --- /dev/null +++ b/image-generator.cjs @@ -0,0 +1,41 @@ +const puppeteer = require("puppeteer"); +const { scrollPageToBottom } = require("puppeteer-autoscroll-down"); +const express = require("express"); + +const { parentPort, workerData } = require("worker_threads"); + +const folderToServe = + "/Users/tarasis/Programming/websites/rmcg.dev/www/FrontendMentor/newbie/social-links-profile/"; + +const dynamicPage = express(); +dynamicPage.use(express.static(folderToServe)); + +const dynamicServer = dynamicPage.listen(0, async () => { + const dynamicPort = dynamicServer.address().port; + console.log(`Dynamic server is running at http://localhost:${dynamicPort}`); + + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + await page.goto(`http://localhost:${dynamicPort}`); + + await page.waitForResponse((response) => response.status() === 200); + + await scrollPageToBottom(page); + + const screenshotBuffer = await page.screenshot({ fullPage: true }); + + // other option is just to save the file to disk + // await page.screenshot({ path: 'example.png' }); + // Close the browser + + await browser.close(); + console.log(`Closing dynamic server http://localhost:${dynamicPort}`); + + await dynamicServer.close(); + + parentPort.postMessage({ + type: "image", + data: screenshotBuffer, + port: dynamicPort, + }); +}); diff --git a/index.mjs b/index.mjs index 4961001..b161202 100644 --- a/index.mjs +++ b/index.mjs @@ -1,49 +1,61 @@ -import puppeteer from "puppeteer"; -import { scrollPageToBottom } from "puppeteer-autoscroll-down"; import express from "express"; import "dotenv/config"; -const folderToServe = "/Users/tarasis/Programming/websites/rmcg.dev/www/"; +import { Worker, isMainThread, parentPort, workerData } from "worker_threads"; + +import fs from "fs"; const port = process.env.PORT || 4000; const app = express(); -app.use(express.static(folderToServe)); -app.get("/screenshot", async (req, res) => { - const dynamicPage = express(); - dynamicPage.use(express.static(folderToServe)); +app.use(express.static("www")); - const dynamicServer = dynamicPage.listen(0, async () => { - const dynamicPort = dynamicServer.address().port; - console.log( - `Dynamic server is running at http://localhost:${dynamicPort}` - ); +app.get("/submit/:mpgParams", (req, res) => { + // console.log("🚀 ~ app.get ~ req:", req); + // Get any supplied parameters, this keeps it clean + // if I pass more parameters in the future + const mpgParams = req.query.mpgParams; + console.log("🚀 ~ app.get ~ mpgParams:", mpgParams); - const browser = await puppeteer.launch(); - const page = await browser.newPage(); - await page.goto(`http://localhost:${dynamicPort}`); + const worker = new Worker("./image-generator.cjs", { + workerData: { + mpgParams, + }, + }); - await page.waitForResponse((response) => response.status() === 200); + // nicer would be to return a link the user + // can click to download the image + // or better yet dynamically load it into the original page in an iframe or ssg thing + // but that might require moving project + // to a framework like react/astro + worker.on("message", (message) => { + if (message.type === "image") { + res.writeHead(200, { + "Content-Type": "image/png", + "Content-Length": message.data.length, + }); + res.end(message.data); - await scrollPageToBottom(page); + // save the image - temporary for now + // fs.writeFileSync( + // `received_image-${message.port}.png`, + // message.data + // ); + } + }); - const screenshotBuffer = await page.screenshot({ fullPage: true }); + worker.on("error", (err) => { + // Handle errors from the worker + console.error(err); + res.status(500).send("Internal Server Error"); + }); - // Respond with the image - res.writeHead(200, { - "Content-Type": "image/png", - "Content-Length": screenshotBuffer.length, - }); - res.end(screenshotBuffer); - // other option is just to save the file to disk - // await page.screenshot({ path: 'example.png' }); - // Close the browser - - await browser.close(); - console.log(`Closing dynamic server http://localhost:${dynamicPort}`); - - await dynamicServer.close(); + worker.on("exit", (code) => { + if (code !== 0) { + // Handle non-zero exit codes + console.error(new Error(`Worker stopped with exit code ${code}`)); + } }); }); diff --git a/package-lock.json b/package-lock.json index d4425c3..b3a696d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "dotenv": "^16.4.5", "express": "^4.18.3", "puppeteer": "^22.4.0", - "puppeteer-autoscroll-down": "^2.0.0" + "puppeteer-autoscroll-down": "^1.1.2" } }, "node_modules/@babel/code-frame": { @@ -1498,11 +1498,11 @@ } }, "node_modules/puppeteer-autoscroll-down": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/puppeteer-autoscroll-down/-/puppeteer-autoscroll-down-2.0.0.tgz", - "integrity": "sha512-Bo5ADSo1t5u36IxY4x/EgS6kNQqMXfTNRSh5CSR5bpoTTOpzE+HE0LZ5xIlqzAfpRjaPtsOd+2lRQiPeAKQlHA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/puppeteer-autoscroll-down/-/puppeteer-autoscroll-down-1.1.2.tgz", + "integrity": "sha512-SSzxBf6Iu2zn6NNqZO1XlU8cqbjVOzhlTh38xLU42srNZjrDXkIAhKandScM0ZwueVOtOs4xSY0FN2S6whlFSA==", "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/puppeteer-core": { diff --git a/package.json b/package.json index fbd18fd..83e7544 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,6 @@ "dotenv": "^16.4.5", "express": "^4.18.3", "puppeteer": "^22.4.0", - "puppeteer-autoscroll-down": "^2.0.0" + "puppeteer-autoscroll-down": "^1.1.2" } -} \ No newline at end of file +} diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..6fc447a --- /dev/null +++ b/www/index.html @@ -0,0 +1,14 @@ + + + + + + + Movitvational Picture Generator + + + +

Hello World

+ + + \ No newline at end of file