From 9311962475c631efaba86eeb234a95e70570812e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96nder=20Ceylan?= Date: Sun, 20 Oct 2019 00:35:34 +0200 Subject: [PATCH] feat(file): avoided saving a shell html file Due to issues on systems with ownership problems of the module, avoided saving a file in module folder #52 --- .npmignore | 1 - package.json | 2 ++ src/config/constants.ts | 9 ++++++- src/helpers/file.ts | 33 ++++++++++++++++------- src/helpers/url.ts | 58 ++++++++++++++++++++++------------------- src/puppets.ts | 20 ++++++++++++-- static/.gitkeep | 0 7 files changed, 83 insertions(+), 40 deletions(-) delete mode 100644 static/.gitkeep diff --git a/.npmignore b/.npmignore index abeb1a4c..c6d5129a 100644 --- a/.npmignore +++ b/.npmignore @@ -3,7 +3,6 @@ # Generated files static/* -!static/.gitkeep temp/* __snapshots__/* *.tgz diff --git a/package.json b/package.json index af636554..629de982 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "lodash.isequal": "4.5.0", "lodash.uniqwith": "4.5.0", "meow": "5.0.0", + "mime-types": "2.1.24", "puppeteer": "1.19.0", "slash": "3.0.0", "tslib": "1.10.0" @@ -65,6 +66,7 @@ "@types/lodash.isequal": "^4.5.5", "@types/lodash.uniqwith": "^4.5.6", "@types/meow": "^5.0.0", + "@types/mime-types": "^2.1.0", "@types/puppeteer": "^1.19.1", "@typescript-eslint/eslint-plugin": "^2.2.0", "@typescript-eslint/parser": "^2.2.0", diff --git a/src/config/constants.ts b/src/config/constants.ts index 68e9df7f..d849976e 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -82,10 +82,17 @@ export default { '--ignore-certificate-errors', '--ignore-certificate-errors-spki-list', '--disable-gpu', - '--disable-extensions', '--disable-default-apps', '--enable-features=NetworkService', '--disable-setuid-sandbox', + '--disable-features=TranslateUI', + '--disable-extensions', + '--disable-background-networking', + '--disable-sync', + '--metrics-recording-only', + '--disable-default-apps', + '--mute-audio', + '--no-first-run', ], EMULATED_USER_AGENT: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3641.0 Safari/537.36', diff --git a/src/helpers/file.ts b/src/helpers/file.ts index 057e62f1..871e2a85 100644 --- a/src/helpers/file.ts +++ b/src/helpers/file.ts @@ -1,6 +1,7 @@ import fs from 'fs'; import path from 'path'; import slash from 'slash'; +import { lookup } from 'mime-types'; import constants from '../config/constants'; import { Extension, Options } from '../models/options'; @@ -110,7 +111,7 @@ const makeDir = (folderPath: string): Promise => { const readFile = ( filePath: string, - options?: { encoding?: null; flag?: string } | undefined | null, + options?: { encoding?: 'base64' | null; flag?: string } | undefined | null, ): Promise => { return new Promise((resolve, reject): void => { fs.readFile(filePath, options, (err, data) => { @@ -123,6 +124,13 @@ const readFile = ( }); }; +const readFileSync = ( + filePath: string, + options?: { encoding?: 'base64' | null; flag?: string } | undefined | null, +): string => { + return fs.readFileSync(filePath, options) as string; +}; + const writeFile = (filePath: string, data: string): Promise => { return new Promise((resolve, reject): void => { fs.writeFile(filePath, data, (err: NodeJS.ErrnoException | null) => { @@ -150,27 +158,33 @@ const getRelativeImagePath = ( return convertBackslashPathToSlashPath(imagePath); }; -const saveHtmlShell = ( +const getImageBase64Url = (imagePath: string): string => { + return `data:${lookup(imagePath)};base64,${readFileSync(imagePath, { + encoding: 'base64', + })}`; +}; + +const getHtmlShell = ( imagePath: string, options: Options, isUrl: boolean, -): Promise => { - const imageUrl = isUrl ? imagePath : getFileUrlOfPath(imagePath); - const htmlContent = constants.SHELL_HTML_FOR_LOGO( +): string => { + const imageUrl = isUrl ? imagePath : getImageBase64Url(imagePath); + + return `${constants.SHELL_HTML_FOR_LOGO( imageUrl, options.background, options.padding, - ); - - return writeFile(getShellHtmlFilePath(), htmlContent); + )}`; }; export default { convertBackslashPathToSlashPath, getRelativeImagePath, - saveHtmlShell, + getHtmlShell, isHtmlFile, isImageFile, + getImageBase64Url, getShellHtmlFilePath, getImageSavePath, getFileUrlOfPath, @@ -179,6 +193,7 @@ export default { getAppDir, getExtension, readFile, + readFileSync, writeFile, makeDir, READ_ACCESS: fs.constants.R_OK, diff --git a/src/helpers/url.ts b/src/helpers/url.ts index 4fa19fca..697764b2 100644 --- a/src/helpers/url.ts +++ b/src/helpers/url.ts @@ -31,18 +31,6 @@ const getAddress = async ( ): Promise => { const logger = preLogger(getAddress.name, options); - const useShell = async (isSourceUrl = false): Promise => { - try { - await file.saveHtmlShell(source, options, isSourceUrl); - } catch (e) { - logger.error(e); - throw Error('Failed saving html shell'); - } - - logger.log('Providing shell html path as navigation address'); - return file.getFileUrlOfPath(file.getShellHtmlFilePath()); - }; - if (isUrl(source)) { if (!(await isUrlExists(source))) { throw Error( @@ -50,24 +38,10 @@ const getAddress = async ( ); } - if (file.isImageFile(source)) { - logger.log('Saving html shell with provided image url'); - return useShell(true); - } - logger.log('Providing url source as navigation address'); return source; } - if (!(await file.pathExists(source, file.READ_ACCESS))) { - throw Error(`Cannot find path ${source}. Please check if file exists`); - } - - if (file.isImageFile(source)) { - logger.log('Saving html shell with provided image source'); - return useShell(); - } - if (file.isHtmlFile(source)) { logger.log('Providing html file path as navigation address'); return file.getFileUrlOfPath(source); @@ -76,4 +50,34 @@ const getAddress = async ( return source; }; -export default { isUrl, isUrlExists, getAddress }; +const getShellHtml = async ( + source: string, + options: Options, +): Promise => { + const logger = preLogger(getShellHtml.name, options); + + const useShell = async (isSourceUrl = false): Promise => { + logger.log('Providing shell html as page content'); + return file.getHtmlShell(source, options, isSourceUrl); + }; + + if (isUrl(source)) { + if (!(await isUrlExists(source))) { + throw Error( + `Cannot resolve ${source}. Please check your internet connection`, + ); + } + + logger.log('Saving html shell with provided image url'); + return useShell(true); + } + + if (!(await file.pathExists(source, file.READ_ACCESS))) { + throw Error(`Cannot find path ${source}. Please check if file exists`); + } + + logger.log('Saving html shell with provided image source'); + return useShell(); +}; + +export default { isUrl, isUrlExists, getAddress, getShellHtml }; diff --git a/src/puppets.ts b/src/puppets.ts index 6b7a404b..dcbaa777 100644 --- a/src/puppets.ts +++ b/src/puppets.ts @@ -230,16 +230,26 @@ const getSplashScreenMetaData = async ( return splashScreenUniformMetaData; }; +const canNavigateTo = (source: string): boolean => + (url.isUrl(source) && !file.isImageFile(source)) || file.isHtmlFile(source); + const saveImages = async ( imageList: Image[], source: string, output: string, options: Options, ): Promise => { + let address: string; + let shellHtml: string; + const logger = preLogger(saveImages.name, options); logger.log('Initialising puppeteer to take screenshots', '🤖'); - const address = await url.getAddress(source, options); + if (canNavigateTo(source)) { + address = await url.getAddress(source, options); + } else { + shellHtml = await url.getShellHtml(source, options); + } return Promise.all( imageList.map(async ({ name, width, height, scaleFactor, orientation }) => { @@ -259,7 +269,13 @@ const saveImages = async ( try { const page = await browser.newPage(); - await page.goto(address); + + if (address) { + await page.goto(address); + } else { + await page.setContent(shellHtml); + } + await page.screenshot({ path, omitBackground: !options.opaque, diff --git a/static/.gitkeep b/static/.gitkeep deleted file mode 100644 index e69de29b..00000000