From 6a36db2e7a88bb97d2034c71594f58b4a2f59a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=88=9A=28noham=29=C2=B2?= <100566912+NohamR@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:02:39 +0200 Subject: [PATCH] Add better logging system --- package-lock.json | 242 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 13 ++- src/browser.js | 9 +- src/cli.js | 4 + src/config.js | 3 +- src/index.js | 15 +-- src/logger.js | 22 +++++ src/pdf.js | 7 +- src/reader.js | 11 ++- 9 files changed, 304 insertions(+), 22 deletions(-) create mode 100644 src/logger.js diff --git a/package-lock.json b/package-lock.json index 12cd711..021b493 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,8 @@ "version": "1.0.0", "dependencies": { "commander": "^15.0.0", + "pino": "^10.3.1", + "pino-pretty": "^13.1.3", "puppeteer": "^24.0.0" } }, @@ -35,6 +37,12 @@ "node": ">=6.9.0" } }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, "node_modules/@puppeteer/browsers": { "version": "2.13.2", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", @@ -133,6 +141,15 @@ "node": ">=4" } }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/b4a": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", @@ -311,6 +328,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, "node_modules/commander": { "version": "15.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", @@ -355,6 +378,15 @@ "node": ">= 14" } }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -515,12 +547,24 @@ "@types/yauzl": "^2.9.1" } }, + "node_modules/fast-copy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-4.0.3.tgz", + "integrity": "sha512-58apWr0GUiDFM8+3afrO6eYwJBn9ZAhDOzG3L+/9llab/haCARS2UIfffmOurYLwbgDRs8n0rfr6qAAPEAuAQw==", + "license": "MIT" + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -568,6 +612,12 @@ "node": ">= 14" } }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "license": "MIT" + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -634,6 +684,15 @@ "node": ">=8" } }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -683,6 +742,15 @@ "node": ">=12" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", @@ -704,6 +772,15 @@ "node": ">= 0.4.0" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -787,6 +864,83 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, + "node_modules/pino": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-10.3.1.tgz", + "integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^3.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^4.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-3.0.0.tgz", + "integrity": "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.3.tgz", + "integrity": "sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^4.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^3.0.0", + "pump": "^3.0.0", + "secure-json-parse": "^4.0.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^5.0.2" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "license": "MIT" + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -870,6 +1024,21 @@ "node": ">=18" } }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -888,6 +1057,31 @@ "node": ">=4" } }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/semver": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", @@ -938,6 +1132,15 @@ "node": ">= 14" } }, + "node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -948,6 +1151,15 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/streamx": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.0.tgz", @@ -985,6 +1197,18 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", + "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tar-fs": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", @@ -1029,6 +1253,24 @@ "b4a": "^1.6.4" } }, + "node_modules/thread-stream": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.2.0.tgz", + "integrity": "sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==", + "license": "MIT", + "dependencies": { + "real-require": "^1.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/thread-stream/node_modules/real-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-1.0.0.tgz", + "integrity": "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==", + "license": "MIT" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", diff --git a/package.json b/package.json index bcdf39b..72f2614 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,20 @@ "test": "node src/test/test.js" }, "standard": { - "globals": ["chrome", "Readability", "indexedDB", "getComputedStyle"], - "ignore": ["extension/"] + "globals": [ + "chrome", + "Readability", + "indexedDB", + "getComputedStyle" + ], + "ignore": [ + "extension/" + ] }, "dependencies": { "commander": "^15.0.0", + "pino": "^10.3.1", + "pino-pretty": "^13.1.3", "puppeteer": "^24.0.0" } } diff --git a/src/browser.js b/src/browser.js index be19dff..3e43da8 100644 --- a/src/browser.js +++ b/src/browser.js @@ -1,6 +1,7 @@ import fs from 'node:fs' import path from 'node:path' import puppeteer from 'puppeteer' +import logger from './logger.js' const EXTENSION_DIR = path.resolve('./extension/reader-view') const MANIFEST_PATH = path.join(EXTENSION_DIR, 'manifest.json') @@ -8,7 +9,7 @@ const READABILITY_PATH = path.join(EXTENSION_DIR, 'data/inject/Readability.js') export function checkExtension () { if (!fs.existsSync(MANIFEST_PATH)) { - console.error( + logger.error( `Extension not found at: ${EXTENSION_DIR}\n` + 'Please extract the extension first:\n' + ' mkdir -p extension/reader-view\n' + @@ -17,7 +18,7 @@ export function checkExtension () { process.exit(1) } if (!fs.existsSync(READABILITY_PATH)) { - console.error( + logger.error( `Readability.js not found at: ${READABILITY_PATH}\n` + 'The extension may be incomplete. Please re-extract it.' ) @@ -34,7 +35,7 @@ export function getExtensionDir () { } export async function launchBrowser () { - console.log(`Launching browser with extension: ${EXTENSION_DIR}`) + logger.debug(`Launching browser with extension: ${EXTENSION_DIR}`) const browser = await puppeteer.launch({ headless: true, ignoreDefaultArgs: [ @@ -67,6 +68,6 @@ export async function discoverExtensionId (browser) { if (!extId) { throw new Error('Could not discover Reader View extension ID') } - console.log(`Discovered extension ID: ${extId}`) + logger.debug(`Discovered extension ID: ${extId}`) return extId } diff --git a/src/cli.js b/src/cli.js index 1c2b10f..95bc0c7 100644 --- a/src/cli.js +++ b/src/cli.js @@ -27,6 +27,10 @@ program '-o, --output ', 'output file path (default: ./output/.pdf)' ) + .option( + '-l, --log-level <level>', + 'logging level (fatal, error, warn, info, debug)' + ) .addHelpText( 'after', ` diff --git a/src/config.js b/src/config.js index 0403c53..8ff6756 100644 --- a/src/config.js +++ b/src/config.js @@ -1,12 +1,13 @@ import fs from 'node:fs' import path from 'node:path' +import logger from './logger.js' export function loadPreferences (prefsPath) { if (!prefsPath || !fs.existsSync(prefsPath)) return {} try { return JSON.parse(fs.readFileSync(prefsPath, 'utf-8')) } catch (e) { - console.warn(`Warning: could not parse preferences file: ${prefsPath}`) + logger.warn(`Warning: could not parse preferences file: ${prefsPath}`) return {} } } diff --git a/src/index.js b/src/index.js index 7aba9fd..f3e081f 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ import process from 'node:process' import path from 'node:path' import { parseArgs, VALID_THEMES } from './cli.js' import { loadPreferences, readCustomCss } from './config.js' +import logger from './logger.js' import { checkExtension, launchBrowser, @@ -37,20 +38,20 @@ async function main () { const theme = opts.theme || preferences.mode || 'light' if (!VALID_THEMES.includes(theme)) { - console.error( + logger.error( `Invalid theme "${theme}". Valid themes: ${VALID_THEMES.join(', ')}` ) process.exit(1) } preferences.mode = theme - console.log(`Theme: ${theme}`) + logger.info(`Theme: ${theme}`) let customCss = null if (opts.css) { customCss = readCustomCss(path.resolve(opts.css)) if (customCss !== null) { preferences['user-css'] = customCss - console.log(`Custom CSS loaded: ${path.resolve(opts.css)}`) + logger.info(`Custom CSS loaded: ${path.resolve(opts.css)}`) } } @@ -59,7 +60,7 @@ async function main () { try { const extId = await discoverExtensionId(browser) - console.log(`Fetching article: ${url}`) + logger.info(`Fetching article: ${url}`) const articlePage = await browser.newPage() await articlePage.goto(url, { waitUntil: 'networkidle0', timeout: 30000 }) const article = await extractArticle(articlePage, getReadabilityPath()) @@ -83,7 +84,7 @@ async function main () { '?id=1', `&url=${encodeURIComponent(url)}` ].join('') - console.log(`Opening Reader View: ${readerUrl}`) + logger.debug(`Opening Reader View: ${readerUrl}`) const readerPage = await browser.newPage() await readerPage.goto(readerUrl, { waitUntil: 'load', timeout: 30000 }) @@ -109,11 +110,11 @@ async function main () { await pdfPage.close() } finally { await browser.close() - console.log('Browser closed.') + logger.info('Browser closed.') } } main().catch((err) => { - console.error('Fatal error:', err) + logger.error(err) process.exit(1) }) diff --git a/src/logger.js b/src/logger.js new file mode 100644 index 0000000..b40f93f --- /dev/null +++ b/src/logger.js @@ -0,0 +1,22 @@ +import pino from 'pino' + +function resolveLevel () { + if (process.env.LOG_LEVEL) return process.env.LOG_LEVEL + const idx = process.argv.indexOf('--log-level') + if (idx !== -1 && process.argv[idx + 1]) return process.argv[idx + 1] + return 'info' +} + +const logger = pino({ + level: resolveLevel(), + transport: { + target: 'pino-pretty', + options: { + colorize: true, + translateTime: 'HH:MM:ss', + ignore: 'pid,hostname' + } + } +}) + +export default logger diff --git a/src/pdf.js b/src/pdf.js index 26182e6..3fc407e 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -1,10 +1,11 @@ import fs from 'node:fs' import path from 'node:path' +import logger from './logger.js' const HIGHLIGHT_CSS = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">' const HIGHLIGHT_JS = - '<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"><script><script>hljs.highlightAll();<script>' + '<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"><\/script><script>hljs.highlightAll();<\/script>' export function getOutputFilename (title, outputDir) { const safe = title @@ -42,7 +43,7 @@ export function enhanceHtml (html, customCss) { export async function generatePdf (page, html, outputPath) { await page.setContent(html, { waitUntil: 'networkidle0' }) - console.log(`Generating PDF: ${outputPath}`) + logger.info(`Generating PDF: ${outputPath}`) await page.pdf({ path: outputPath, format: 'A4', @@ -54,5 +55,5 @@ export async function generatePdf (page, html, outputPath) { right: '0mm' } }) - console.log(`PDF saved: ${outputPath}`) + logger.info(`PDF saved: ${outputPath}`) } diff --git a/src/reader.js b/src/reader.js index 7be945a..ead25ab 100644 --- a/src/reader.js +++ b/src/reader.js @@ -1,4 +1,5 @@ import fs from 'node:fs' +import logger from './logger.js' export async function extractArticle (page, readabilityPath) { const readabilitySource = fs.readFileSync(readabilityPath, 'utf-8') @@ -51,7 +52,7 @@ export async function extractArticle (page, readabilityPath) { if (!article) { throw new Error('Failed to extract article content with Readability') } - console.log( + logger.info( `Extracted article: ${article.title} (${article.length} chars, reading ${article.readingTimeMinsFast}-${article.readingTimeMinsSlow} min` + (article.published_time ? `, ${article.published_time}` : '') + ')' @@ -90,7 +91,7 @@ export async function storeArticle (extPage, extId, articleId, article) { }, { id: articleId, article } ) - console.log('Article stored in extension IndexedDB') + logger.debug('Article stored in extension IndexedDB') } export async function setExtensionPreferences (page, extId, prefs) { @@ -105,11 +106,11 @@ export async function setExtensionPreferences (page, extId, prefs) { }) }) }, prefs) - console.log(`Extension preferences set: ${Object.keys(prefs).length} key(s)`) + logger.debug(`Extension preferences set: ${Object.keys(prefs).length} key(s)`) } export async function waitForReaderView (page) { - console.log('Waiting for Reader View to render article...') + logger.debug('Waiting for Reader View to render article...') await page.waitForFunction( () => { const title = document.title @@ -126,7 +127,7 @@ export async function waitForReaderView (page) { }, { timeout: 60000 } ) - console.log('Article rendered.') + logger.info('Article rendered.') } export async function extractRenderedContent (page, baseUrl) {