yekonga-server
Version:
Yekonga Server
210 lines (180 loc) • 7.23 kB
JavaScript
const { spawnSync } = require('node:child_process');
const { parentPort, workerData } = require('node:worker_threads');
const fs = require('fs');
const path = require('path');
const webBrowser = require('puppeteer');
const modifyString = require('./utils/string.js/lib/string');
async function processPDF() {
var result = null;
var chromeTmpDataDir = null;
try {
const dataJson = (typeof workerData == 'string')? JSON.stringify(workerData): workerData;
var { html, filepath, options, queueId } = dataJson || {};
if(!options) options = {};
const type = (options.type)? options.type.toLowerCase(): 'pdf';
const width = (options.width)? options.width: null;
const height = (options.height)? options.height: null;
const viewport = (options.viewport)? options.viewport: null;
const scale = (options.scale)? options.scale: null;
const format = (options.format)? options.format: 'A4';
const landscape = (typeof options.orientation == 'string' && options.orientation.toLowerCase() == 'landscape')? true: false;
const margin = (options.margin)
? options.margin
: { top: '0px', right: '0px', bottom: '0px', left: '0px' };
const mainOptions = {
path: filepath,
landscape: landscape,
margin: margin,
printBackground: true,
format: (width && height)? null: format,
width: width,
height: height,
timeout: 0,
}
if(options.displayHeaderFooter) {
mainOptions.displayHeaderFooter = options.displayHeaderFooter;
}
if(options.headerTemplate) {
mainOptions.headerTemplate = options.headerTemplate;
if(!options.margin || (options.margin && !options.margin.top)) {
mainOptions.margin.top = '120px';
}
}
if(options.footerTemplate) {
mainOptions.footerTemplate = options.footerTemplate;
if(!options.margin || (options.margin && !options.margin.bottom)) {
mainOptions.margin.bottom = '100px';
}
}
var browser = null;
try {
browser = await getBrowser();
try {
let chromeSpawnArgs = browser.process().spawnargs;
for (let i = 0; i < chromeSpawnArgs.length; i++) {
if (chromeSpawnArgs[i].indexOf("--user-data-dir=") === 0) {
chromeTmpDataDir = chromeSpawnArgs[i].replace("--user-data-dir=", "");
}
}
} catch (error) {
}
try {
const page = await browser.newPage();
await page.setDefaultTimeout(120000);
await page.setDefaultNavigationTimeout(120000);
if(viewport) {
await page.setViewport(viewport);
}
await page.emulateMediaType('screen');
if(Array.isArray(html)) {
for (let i = 0; i < html.length; i++) {
await createFolder(path.dirname(filepath[i]))
await generatePdf(html[i], page, {path: filepath[i], options, type, mainOptions })
}
} else {
await createFolder(path.dirname(filepath))
await generatePdf(html, page, {path:filepath, options, type, mainOptions })
}
await page.close();
await browser.close();
browser = null;
} catch (error) {
console.error('PDF ERROR 1', error);
parentPort.postMessage(error);
}
} catch (error) {
console.error('PDF ERROR 2', error);
parentPort.postMessage(error);
} finally {
if(browser) {
await browser.close();
}
}
result = { filepath }
} catch (error) {
console.debug('error', error);
parentPort.postMessage(error);
process.exit(1);
}
try {
if (chromeTmpDataDir !== null) {
spawnSync('rm', ['-rf', chromeTmpDataDir]);
}
} catch (error) {
}
parentPort.postMessage(result);
process.exit(0);
}
async function getBrowser() {
return await webBrowser.launch({
args: [
'--disable-setuid-sandbox',
'--disable-gpu',
'--disable-dev-shm-usage',
'--disable-setuid-sandbox',
'--disable-features=IsolateOrigins',
'--disable-site-isolation-trials',
'--disable-web-security',
'--disable-dev-profile',
'--no-first-run',
'--no-sandbox',
'--no-zygote',
'--deterministic-fetch',
'--single-process',
],
headless: true,
timeout: 120000,
});
}
async function generatePdf(html, page, {path, type, options, mainOptions, clear = false}) {
// console.debug("===== 0")
// await page.waitForNetworkIdle({ idleTime: 1000 });
await page.setContent(html, { waitUntil: 'networkidle2', timeout: 120000 });
// console.debug("===== 1")
const scale = (options.scale)? options.scale: 1;
// console.debug("===== 2")
if(['jpg', 'jpeg', 'png', 'webp', 'image'].includes(type)) {
// console.debug("===== 3")
mainOptions.fullPage = true;
mainOptions.captureBeyondViewport = false;
mainOptions.type = 'png';
// console.debug("===== 4")
if(['png', 'webp'].includes(type)) {
mainOptions.type = type;
} else if(['jpg', 'jpeg'].includes(type)) {
mainOptions.type = 'jpeg';
}
// console.debug("===== 5")
if(mainOptions.width && mainOptions.height) {
var _width = Math.round(parseInt(mainOptions.width) * ((scale)? scale: 1));
var _height = Math.round(parseInt(mainOptions.height) * ((scale)? scale: 1));
// console.debug("===== 6")
await page.setViewport({
width: _width,
height: _height,
// height: await page.evaluate(() => parseInt(`${document.body.clientHeight}`)),
});
}
// console.debug("===== 7")
await page.screenshot({...mainOptions, path});
// console.debug("===== 8")
} else {
await page.pdf({...mainOptions, path});
// console.debug("===== 9")
}
}
function createFolder(file) {
if (file && !fs.existsSync(file)) {
var dir_array = modifyString(file).replaceAll('\\', '/').splitLeft('/').filter((e) => (e != ''));
var dirname = (process.platform == 'win32') ? '' : '/';
for (var i = 0; i < dir_array.length; i++) {
dirname = path.join(dirname, dir_array[i], (i) ? '' : '/');
// console.debug(dirname);
if (!fs.existsSync(dirname)) {
fs.mkdirSync(dirname);
}
}
}
return;
}
processPDF();