diff --git a/source/app/metrics/index.mjs b/source/app/metrics/index.mjs index b8ea12ad..c659d8bd 100644 --- a/source/app/metrics/index.mjs +++ b/source/app/metrics/index.mjs @@ -56,8 +56,8 @@ console.debug(`metrics/compute/${login} > render`) let rendered = await ejs.render(image, {...data, s:imports.s, f:imports.format, style, fonts}, {views, async:true}) if (q["config.twemoji"]) - rendered = await imports.svgemojis(rendered) - const {resized, mime} = await imports.svgresize(rendered, {paddings:q["config.padding"] || conf.settings.padding, convert}) + rendered = await imports.svg.twemojis(rendered) + const {resized, mime} = await imports.svg.resize(rendered, {paddings:q["config.padding"] || conf.settings.padding, convert}) rendered = resized //Additional SVG transformations diff --git a/source/app/metrics/utils.mjs b/source/app/metrics/utils.mjs index 662bb831..a09c0030 100644 --- a/source/app/metrics/utils.mjs +++ b/source/app/metrics/utils.mjs @@ -86,16 +86,6 @@ .replace(/'/g, u["'"] ? "'" : "'") } -/**Expand url */ - export async function urlexpand(url) { - try { - return (await axios.get(url)).request.res.responseUrl - } - catch { - return url - } - } - /**Run command */ export async function run(command, options, {prefixed = true} = {}) { const prefix = {win32:"wsl"}[process.platform] ?? "" @@ -128,63 +118,65 @@ return false } -/**Render svg */ - export async function svgresize(svg, {paddings, convert}) { - //Instantiate browser if needed - if (!svgresize.browser) { - svgresize.browser = await puppeteer.launch({headless:true, executablePath:process.env.PUPPETEER_BROWSER_PATH, args:["--no-sandbox", "--disable-extensions", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]}) - console.debug(`metrics/svgresize > started ${await svgresize.browser.version()}`) - } - //Format padding - const [pw = 1, ph] = (Array.isArray(paddings) ? paddings : `${paddings}`.split(",").map(x => x.trim())).map(padding => `${padding}`.substring(0, padding.length-1)).map(value => 1+Number(value)/100) - const padding = {width:pw, height:ph ?? pw} - console.debug(`metrics/svgresize > padding width*${padding.width}, height*${padding.height}`) - //Render through browser and resize height - const page = await svgresize.browser.newPage() - await page.setContent(svg, {waitUntil:["load", "domcontentloaded", "networkidle2"]}) - await page.addStyleTag({content:"body { margin: 0; padding: 0; }"}) - await wait(1) - let mime = "image/svg+xml" - let {resized, width, height} = await page.evaluate(async padding => { - //Disable animations - const animated = !document.querySelector("svg").classList.contains("no-animations") - if (animated) - document.querySelector("svg").classList.add("no-animations") - //Get bounds and resize - let {y:height, width} = document.querySelector("svg #metrics-end").getBoundingClientRect() - height = Math.ceil(height*padding.height) - width = Math.ceil(width*padding.width) - //Resize svg - document.querySelector("svg").setAttribute("height", height) - //Enable animations - if (animated) - document.querySelector("svg").classList.remove("no-animations") +/**SVG utils */ + export const svg = { + /**Render and resize svg */ + async resize(rendered, {paddings, convert}) { + //Instantiate browser if needed + if (!svg.resize.browser) { + svg.resize.browser = await puppeteer.launch({headless:true, executablePath:process.env.PUPPETEER_BROWSER_PATH, args:["--no-sandbox", "--disable-extensions", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]}) + console.debug(`metrics/svg/resize > started ${await svg.resize.browser.version()}`) + } + //Format padding + const [pw = 1, ph] = (Array.isArray(paddings) ? paddings : `${paddings}`.split(",").map(x => x.trim())).map(padding => `${padding}`.substring(0, padding.length-1)).map(value => 1+Number(value)/100) + const padding = {width:pw, height:ph ?? pw} + console.debug(`metrics/svg/resize > padding width*${padding.width}, height*${padding.height}`) + //Render through browser and resize height + const page = await svg.resize.browser.newPage() + await page.setContent(rendered, {waitUntil:["load", "domcontentloaded", "networkidle2"]}) + await page.addStyleTag({content:"body { margin: 0; padding: 0; }"}) + await wait(1) + let mime = "image/svg+xml" + let {resized, width, height} = await page.evaluate(async padding => { + //Disable animations + const animated = !document.querySelector("svg").classList.contains("no-animations") + if (animated) + document.querySelector("svg").classList.add("no-animations") + //Get bounds and resize + let {y:height, width} = document.querySelector("svg #metrics-end").getBoundingClientRect() + height = Math.ceil(height*padding.height) + width = Math.ceil(width*padding.width) + //Resize svg + document.querySelector("svg").setAttribute("height", height) + //Enable animations + if (animated) + document.querySelector("svg").classList.remove("no-animations") + //Result + return {resized:new XMLSerializer().serializeToString(document.querySelector("svg")), height, width} + }, padding) + //Convert if required + if (convert) { + console.debug(`metrics/svg/resize > convert to ${convert}`) + resized = await page.screenshot({type:convert, clip:{x:0, y:0, width, height}, omitBackground:true}) + mime = `image/${convert}` + } //Result - return {resized:new XMLSerializer().serializeToString(document.querySelector("svg")), height, width} - }, padding) - //Convert if required - if (convert) { - console.debug(`metrics/svgresize > convert to ${convert}`) - resized = await page.screenshot({type:convert, clip:{x:0, y:0, width, height}, omitBackground:true}) - mime = `image/${convert}` - } - //Result - await page.close() - return {resized, mime} - } - -/**Render twemojis */ - export async function svgemojis(svg) { - //Load emojis - const emojis = new Map() - for (const {text:emoji, url} of twemojis.parse(svg)) { - if (!emojis.has(emoji)) - emojis.set(emoji, (await axios.get(url)).data.replace(/^ processed ${i}/${frames} frames`) + console.debug(`metrics/record > processed ${i}/${frames} frames`) } - console.debug(`metrics/puppeteergif > processed ${frames}/${frames} frames`) + console.debug(`metrics/record > processed ${frames}/${frames} frames`) //Post-processing - console.debug("metrics/puppeteergif > applying post-processing") + console.debug("metrics/record > applying post-processing") return Promise.all(images.map(async buffer => (await jimp.read(buffer)).scale(scale).quality(quality).getBase64Async("image/png"))) } \ No newline at end of file diff --git a/source/plugins/skyline/index.mjs b/source/plugins/skyline/index.mjs index 920a8af3..6dfa4ee2 100644 --- a/source/plugins/skyline/index.mjs +++ b/source/plugins/skyline/index.mjs @@ -32,7 +32,7 @@ //Generate gif console.debug(`metrics/compute/${login}/plugins > skyline > generating frames`) - const framed = await imports.puppeteergif({page, width, height, frames, scale:quality}) + const framed = await imports.record({page, width, height, frames, scale:quality}) //Close puppeteer await browser.close()