diff --git a/source/plugins/screenshot/README.md b/source/plugins/screenshot/README.md new file mode 100644 index 00000000..fcbf2cf2 --- /dev/null +++ b/source/plugins/screenshot/README.md @@ -0,0 +1,26 @@ +### 📸 Website screenshot + +The *screenshot* plugin lets you take a screenshot from any website. +It can be restricted with a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) or you can take a full page. + + + +
+ + +
+ +#### ℹ️ Examples workflows + +[➡️ Available options for this plugin](metadata.yml) + +```yaml +- uses: lowlighter/metrics@latest + with: + # ... other options + plugin_screenshot: yes + plugin_screenshot_title: XKCD of the day # Section title + plugin_screenshot_url: https://xkcd.com # Website url + plugin_screenshot_selector: "#comic img" # CSS selector to take into screenshot + plugin_screenshot_background: no # Remove page background +``` \ No newline at end of file diff --git a/source/plugins/screenshot/index.mjs b/source/plugins/screenshot/index.mjs new file mode 100644 index 00000000..1dc3d904 --- /dev/null +++ b/source/plugins/screenshot/index.mjs @@ -0,0 +1,42 @@ +//Setup + export default async function({login, q, imports, data, account}, {enabled = false} = {}) { + //Plugin execution + try { + //Check if plugin is enabled and requirements are met + if ((!enabled)||(!q.screenshot)) + return null + + //Load inputs + let {url, selector, title, background} = imports.metadata.plugins.screenshot.inputs({data, account, q}) + if (!url) + throw {error:{message:"An url is required"}} + + //Start puppeteer and navigate to page + console.debug(`metrics/compute/${login}/plugins > screenshot > starting browser`) + const browser = await imports.puppeteer.launch() + console.debug(`metrics/compute/${login}/plugins > screenshot > started ${await browser.version()}`) + const page = await browser.newPage() + await page.setViewport({width:600, height:600}) + console.debug(`metrics/compute/${login}/plugins > screenshot > loading ${url}`) + await page.goto(url) + + //Screenshot + await page.waitForSelector(selector) + const clip = await page.evaluate(selector => { + const {x, y, width, height} = document.querySelector(selector).getBoundingClientRect() + return {x, y, width, height} + }, selector) + const [buffer] = await imports.record({page, ...clip, frames:1, background}) + const screenshot = await (await imports.jimp.read(Buffer.from(buffer.split(",").pop(), "base64"))).resize(454, imports.jimp.AUTO) + await browser.close() + + //Results + return {image:await screenshot.getBase64Async("image/png"), title, height:screenshot.bitmap.height, width:screenshot.bitmap.width} + } + //Handle errors + catch (error) { + if (error.error?.message) + throw error + throw {title:"Screenshot error", error:{message:"An error occured", instance:error}} + } + } \ No newline at end of file diff --git a/source/plugins/screenshot/metadata.yml b/source/plugins/screenshot/metadata.yml new file mode 100644 index 00000000..9763fd4f --- /dev/null +++ b/source/plugins/screenshot/metadata.yml @@ -0,0 +1,39 @@ +name: "📸 Website screenshot" +cost: N/A +categorie: other +index: 2 +supports: + - user + - organization + - repository +inputs: + + # Enable or disable plugin + plugin_screenshot: + description: Display a screenshot of any website + type: boolean + default: no + + # Screenshot title caption + plugin_screenshot_title: + description: Screenshot title caption + type: string + default: Screenshot + + # Website to take screenshot + plugin_screenshot_url: + description: Website to take screenshot + type: string + default: "" + + # Selector to take in screenshot + plugin_screenshot_selector: + description: Selector to take in screenshot + type: string + default: body + + # Display or remove default page background + plugin_screenshot_background: + description: Display or remove default page background + type: boolean + default: yes \ No newline at end of file diff --git a/source/plugins/screenshot/tests.yml b/source/plugins/screenshot/tests.yml new file mode 100644 index 00000000..ebc27bd4 --- /dev/null +++ b/source/plugins/screenshot/tests.yml @@ -0,0 +1,12 @@ +- name: Screenshot plugin (default) + uses: lowlighter/metrics@latest + with: + token: NOT_NEEDED + plugin_screenshot: yes + plugin_screenshot_url: https://github.com + plugin_screenshot_title: Test + plugin_screenshot_selector: body + plugin_screenshot_background: no + timeout: 1800000 + modes: + - action \ No newline at end of file diff --git a/source/templates/classic/partials/_.json b/source/templates/classic/partials/_.json index 3fa4541d..98fdc4d0 100644 --- a/source/templates/classic/partials/_.json +++ b/source/templates/classic/partials/_.json @@ -26,5 +26,6 @@ "skyline", "stackoverflow", "stock", - "achievements" + "achievements", + "screenshot" ] \ No newline at end of file diff --git a/source/templates/classic/partials/screenshot.ejs b/source/templates/classic/partials/screenshot.ejs new file mode 100644 index 00000000..4b3b31bb --- /dev/null +++ b/source/templates/classic/partials/screenshot.ejs @@ -0,0 +1,20 @@ +<% if (plugins.screenshot) { %> +
+

+ + <%= plugins.screenshot.title %> +

+
+
+ <% if (plugins.screenshot.error) { %> +
+ + <%= plugins.screenshot.error.message %> +
+ <% } else { %> + + <% } %> +
+
+
+<% } %> diff --git a/source/templates/classic/style.css b/source/templates/classic/style.css index 2f2560a1..32c88587 100644 --- a/source/templates/classic/style.css +++ b/source/templates/classic/style.css @@ -932,6 +932,12 @@ stroke: rgba(127, 127, 127, 0.4) !important; } +/* Autosize */ + .autosize { + width: auto; + height: auto; + } + /* Fade animation */ .af { opacity: 0;