patreon-dl 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -267,6 +267,11 @@ Note the URL shown in the output. Open this URL in a web browser to begin viewin
267
267
 
268
268
  ## Changelog
269
269
 
270
+ v3.2.1
271
+ - Fix log file path sometimes not sanitized properly on Windows
272
+ - API: add support for passing request options to `getCampaign()`
273
+ - CLI: add support for using request options from conf file when running with `--list-tiers` / `--list-tiers-uid`
274
+
270
275
  v3.2.0
271
276
  - Fix:
272
277
  - "Initial data not found" error in `patreon.com/cw` pages ([#85](https://github.com/patrickkfkan/patreon-dl/issues/85)) and custom-domain pages
@@ -25,7 +25,8 @@ export type CLIOptionParserEntry = ({
25
25
  key: string;
26
26
  value?: string;
27
27
  };
28
- export declare function getCLIOptions(): CLIOptions;
28
+ export declare function getCLIOptions(skipTargetURLs: true): Omit<CLIOptions, 'targetURLs'>;
29
+ export declare function getCLIOptions(skipTargetURLs?: false): CLIOptions;
29
30
  export declare function getCLILoggerOptions(commandLineOptions?: CommandLineParseResult, configFileOptions?: ReturnType<typeof ConfigFileParser['parse']> | null): {
30
31
  consoleLogger: {
31
32
  enabled: boolean | undefined;
@@ -5,24 +5,25 @@ import CommandLineParser from './CommandLineParser.js';
5
5
  import ConfigFileParser from './ConfigFileParser.js';
6
6
  import path from 'path';
7
7
  import ObjectHelper from '../utils/ObjectHelper.js';
8
- export function getCLIOptions() {
8
+ export function getCLIOptions(skipTargetURLs = false) {
9
9
  const commandLineOptions = CommandLineParser.parse();
10
10
  const configFileOptions = commandLineOptions.configFile?.value ? ConfigFileParser.parse(commandLineOptions.configFile.value) : null;
11
- let targetURLs;
12
- const targetURLValue = CLIOptionValidator.validateRequired(pickDefined(commandLineOptions.targetURLs, configFileOptions?.targetURLs), 'No target URL specified');
13
- const targetsFile = path.resolve(targetURLValue);
14
- if (fs.existsSync(targetsFile)) {
15
- targetURLs = readTargetsFile(targetsFile);
16
- }
17
- else {
18
- targetURLs = CLIOptionValidator
19
- .validateTargetURLs(targetURLValue)
20
- .map((url) => ({ url }));
11
+ let targetURLs = [];
12
+ if (!skipTargetURLs) {
13
+ const targetURLValue = CLIOptionValidator.validateRequired(pickDefined(commandLineOptions.targetURLs, configFileOptions?.targetURLs), 'No target URL specified');
14
+ const targetsFile = path.resolve(targetURLValue);
15
+ if (fs.existsSync(targetsFile)) {
16
+ targetURLs = readTargetsFile(targetsFile);
17
+ }
18
+ else {
19
+ targetURLs = CLIOptionValidator
20
+ .validateTargetURLs(targetURLValue)
21
+ .map((url) => ({ url }));
22
+ }
21
23
  }
22
24
  const { consoleLogger, fileLoggers } = getCLILoggerOptions(commandLineOptions, configFileOptions);
23
25
  const proxy = getProxyOptions(configFileOptions);
24
26
  const options = {
25
- targetURLs,
26
27
  cookie: CLIOptionValidator.validateString(pickDefined(commandLineOptions.cookie, configFileOptions?.cookie)),
27
28
  useStatusCache: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.useStatusCache, configFileOptions?.useStatusCache)),
28
29
  stopOn: CLIOptionValidator.validateString(pickDefined(commandLineOptions.stopOn, configFileOptions?.stopOn), 'never', 'postPreviouslyDownloaded', 'postPublishDateOutOfRange'),
@@ -54,7 +55,13 @@ export function getCLIOptions() {
54
55
  consoleLogger,
55
56
  fileLoggers
56
57
  };
57
- return options;
58
+ if (skipTargetURLs) {
59
+ return options;
60
+ }
61
+ return {
62
+ targetURLs,
63
+ ...options
64
+ };
58
65
  }
59
66
  export function getCLILoggerOptions(commandLineOptions, configFileOptions) {
60
67
  if (!commandLineOptions) {
@@ -1 +1 @@
1
- {"version":3,"file":"CLIOptions.js","sourceRoot":"","sources":["../../src/cli/CLIOptions.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport { type DownloaderIncludeOptions, type DownloaderOptions } from '../downloaders/DownloaderOptions.js';\nimport { type DeepPartial, type RecursivePropsTo, pickDefined } from '../utils/Misc.js';\nimport { type ConsoleLoggerOptions } from '../utils/logging/ConsoleLogger.js';\nimport { type FileLoggerType, type FileLoggerOptions } from '../utils/logging/FileLogger.js';\nimport CLIOptionValidator from './CLIOptionValidator.js';\nimport CommandLineParser, { type CommandLineParseResult } from './CommandLineParser.js';\nimport ConfigFileParser, { type ConfigFileParseResult } from './ConfigFileParser.js';\nimport path from 'path';\nimport ObjectHelper from '../utils/ObjectHelper.js';\n\nexport interface CLITargetURLEntry {\n url: string;\n // Target-specific 'include' options\n include?: DownloaderIncludeOptions;\n}\n\nexport interface CLIOptions extends Omit<DownloaderOptions, 'logger'> {\n targetURLs: CLITargetURLEntry[];\n noPrompt: boolean;\n consoleLogger: ConsoleLoggerOptions;\n fileLoggers?: Omit<FileLoggerOptions<FileLoggerType.Downloader>, 'init'>[];\n}\n\nexport type CLIOptionParserEntry = ({\n src: 'cli'\n} | {\n src: 'cfg',\n section: string\n} | {\n src: 'tgt',\n line: number\n}) & {\n key: string;\n value?: string;\n}\n\nexport function getCLIOptions(): CLIOptions {\n const commandLineOptions = CommandLineParser.parse();\n\n const configFileOptions = commandLineOptions.configFile?.value ? ConfigFileParser.parse(commandLineOptions.configFile.value) : null;\n\n let targetURLs: CLITargetURLEntry[];\n const targetURLValue = CLIOptionValidator.validateRequired(pickDefined(commandLineOptions.targetURLs, configFileOptions?.targetURLs), 'No target URL specified');\n const targetsFile = path.resolve(targetURLValue);\n if (fs.existsSync(targetsFile)) {\n targetURLs = readTargetsFile(targetsFile);\n }\n else {\n targetURLs = CLIOptionValidator\n .validateTargetURLs(targetURLValue)\n .map((url) => ({ url }));\n }\n\n const { consoleLogger, fileLoggers } = getCLILoggerOptions(commandLineOptions, configFileOptions);\n const proxy = getProxyOptions(configFileOptions);\n\n const options: CLIOptions = {\n targetURLs,\n cookie: CLIOptionValidator.validateString(pickDefined(commandLineOptions.cookie, configFileOptions?.cookie)),\n useStatusCache: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.useStatusCache, configFileOptions?.useStatusCache)),\n stopOn: CLIOptionValidator.validateString(pickDefined(commandLineOptions.stopOn, configFileOptions?.stopOn), 'never', 'postPreviouslyDownloaded', 'postPublishDateOutOfRange'),\n pathToFFmpeg: CLIOptionValidator.validateString(pickDefined(commandLineOptions.pathToFFmpeg, configFileOptions?.pathToFFmpeg)),\n outDir: CLIOptionValidator.validateString(pickDefined(commandLineOptions.outDir, configFileOptions?.outDir)),\n dirNameFormat: {\n campaign: CLIOptionValidator.validateString(pickDefined(commandLineOptions.dirNameFormat?.campaign, configFileOptions?.dirNameFormat?.campaign)),\n content: CLIOptionValidator.validateString(pickDefined(commandLineOptions.dirNameFormat?.content, configFileOptions?.dirNameFormat?.content))\n },\n filenameFormat: {\n media: CLIOptionValidator.validateString(pickDefined(commandLineOptions.filenameFormat?.media, configFileOptions?.filenameFormat?.media))\n },\n include: getCLIIncludeOptions(commandLineOptions, configFileOptions),\n request: {\n maxRetries: CLIOptionValidator.validateNumber(pickDefined(commandLineOptions?.request?.maxRetries, configFileOptions?.request?.maxRetries)),\n maxConcurrent: CLIOptionValidator.validateNumber(pickDefined(commandLineOptions?.request?.maxConcurrent, configFileOptions?.request?.maxConcurrent)),\n minTime: CLIOptionValidator.validateNumber(pickDefined(commandLineOptions?.request?.minTime, configFileOptions?.request?.minTime)),\n proxy,\n userAgent: CLIOptionValidator.validateString(pickDefined(commandLineOptions?.request?.userAgent, configFileOptions?.request?.userAgent))\n },\n fileExistsAction: {\n content: CLIOptionValidator.validateString(pickDefined(commandLineOptions.fileExistsAction?.content, configFileOptions?.fileExistsAction?.content), 'overwrite', 'skip', 'saveAsCopy', 'saveAsCopyIfNewer'),\n info: CLIOptionValidator.validateString(pickDefined(commandLineOptions.fileExistsAction?.info, configFileOptions?.fileExistsAction?.info), 'overwrite', 'skip', 'saveAsCopy', 'saveAsCopyIfNewer'),\n infoAPI: CLIOptionValidator.validateString(pickDefined(commandLineOptions.fileExistsAction?.infoAPI, configFileOptions?.fileExistsAction?.infoAPI), 'overwrite', 'skip', 'saveAsCopy', 'saveAsCopyIfNewer')\n },\n embedDownloaders: getEmbedDownloaderOptions(configFileOptions),\n noPrompt: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.noPrompt, configFileOptions?.noPrompt)) || false,\n dryRun: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.dryRun, configFileOptions?.dryRun)) || false,\n consoleLogger,\n fileLoggers\n };\n\n return options;\n}\n\nexport function getCLILoggerOptions(commandLineOptions?: CommandLineParseResult, configFileOptions?: ReturnType<typeof ConfigFileParser['parse']> | null) {\n if (!commandLineOptions) {\n commandLineOptions = CommandLineParser.parse();\n }\n const consoleLogger = {\n enabled: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.enabled, configFileOptions?.consoleLogger?.enabled)),\n logLevel: CLIOptionValidator.validateString(pickDefined(commandLineOptions.consoleLogger?.logLevel, configFileOptions?.consoleLogger?.logLevel), 'info', 'debug', 'warn', 'error'),\n include: {\n dateTime: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.dateTime, configFileOptions?.consoleLogger?.include?.dateTime)),\n level: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.level, configFileOptions?.consoleLogger?.include?.level)),\n originator: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.originator, configFileOptions?.consoleLogger?.include?.originator)),\n errorStack: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.errorStack, configFileOptions?.consoleLogger?.include?.errorStack))\n },\n dateTimeFormat: CLIOptionValidator.validateString(pickDefined(commandLineOptions.consoleLogger?.dateTimeFormat, configFileOptions?.consoleLogger?.dateTimeFormat)),\n color: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.color, configFileOptions?.consoleLogger?.color))\n };\n let fileLoggers;\n if (configFileOptions?.fileLoggers) {\n fileLoggers = configFileOptions.fileLoggers.map((logger): Omit<FileLoggerOptions<FileLoggerType.Downloader>, 'init'> => ({\n enabled: CLIOptionValidator.validateBoolean(logger.enabled),\n logDir: CLIOptionValidator.validateString(logger.logDir),\n logFilename: CLIOptionValidator.validateString(logger.logFilename),\n fileExistsAction: CLIOptionValidator.validateString(logger.fileExistsAction, 'append', 'overwrite'),\n logLevel: CLIOptionValidator.validateString(logger.logLevel, 'info', 'debug', 'warn', 'error'),\n include: {\n dateTime: CLIOptionValidator.validateBoolean(logger.include?.dateTime),\n level: CLIOptionValidator.validateBoolean(logger.include?.level),\n originator: CLIOptionValidator.validateBoolean(logger.include?.originator),\n errorStack: CLIOptionValidator.validateBoolean(logger.include?.errorStack)\n },\n dateTimeFormat: CLIOptionValidator.validateString(logger.dateTimeFormat),\n color: CLIOptionValidator.validateBoolean(logger.color)\n }));\n }\n return {\n consoleLogger,\n fileLoggers\n };\n}\n\nfunction getCLIIncludeOptions(commandLineOptions: CommandLineParseResult, configFileOptions?: ConfigFileParseResult | null) {\n if (!commandLineOptions) {\n commandLineOptions = CommandLineParser.parse();\n }\n return {\n lockedContent: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.lockedContent, configFileOptions?.include?.lockedContent)),\n postsWithMediaType: CLIOptionValidator.validateIncludeContentWithMediaType(pickDefined(commandLineOptions.include?.postsWithMediaType, configFileOptions?.include?.postsWithMediaType)),\n postsInTier: CLIOptionValidator.validateIncludeContentInTier(pickDefined(commandLineOptions.include?.postsInTier, configFileOptions?.include?.postsInTier)),\n postsPublished: {\n after: CLIOptionValidator.validateDateTime(pickDefined(commandLineOptions.include?.postsPublished?.after, configFileOptions?.include?.postsPublished?.after)) || null,\n before: CLIOptionValidator.validateDateTime(pickDefined(commandLineOptions.include?.postsPublished?.before, configFileOptions?.include?.postsPublished?.before)) || null,\n },\n campaignInfo: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.campaignInfo, configFileOptions?.include?.campaignInfo)),\n contentInfo: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.contentInfo, configFileOptions?.include?.contentInfo)),\n previewMedia: CLIOptionValidator.validateIncludePreviewMedia(pickDefined(commandLineOptions.include?.previewMedia, configFileOptions?.include?.previewMedia)),\n contentMedia: CLIOptionValidator.validateIncludeContentMedia(pickDefined(commandLineOptions.include?.contentMedia, configFileOptions?.include?.contentMedia)),\n allMediaVariants: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.allMediaVariants, configFileOptions?.include?.allMediaVariants)),\n mediaByFilename: {\n images: CLIOptionValidator.validateString(pickDefined(commandLineOptions.include?.mediaByFilename?.images, configFileOptions?.include?.mediaByFilename?.images)) || null,\n audio: CLIOptionValidator.validateString(pickDefined(commandLineOptions.include?.mediaByFilename?.audio, configFileOptions?.include?.mediaByFilename?.audio)) || null,\n attachments: CLIOptionValidator.validateString(pickDefined(commandLineOptions.include?.mediaByFilename?.attachments, configFileOptions?.include?.mediaByFilename?.attachments)) || null\n },\n comments: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.comments, configFileOptions?.include?.comments))\n };\n}\n\nfunction getEmbedDownloaderOptions(configFileOptions?: ConfigFileParseResult | null) {\n if (configFileOptions?.embedDownloaders) {\n return configFileOptions?.embedDownloaders.map((dl) => ({\n provider: CLIOptionValidator.validateRequired(dl.provider),\n exec: CLIOptionValidator.validateRequired(dl.exec)\n }));\n }\n return undefined;\n}\n\nfunction getProxyOptions(configFileOptions?: ConfigFileParseResult | null) {\n if (configFileOptions?.request?.proxy && configFileOptions.request.proxy.url?.value?.trim()) {\n return {\n url: CLIOptionValidator.validateProxyURL(configFileOptions.request.proxy.url),\n rejectUnauthorizedTLS: CLIOptionValidator.validateBoolean(configFileOptions.request.proxy.rejectUnauthorizedTLS)\n };\n }\n return null;\n}\n\nfunction readTargetsFile(file: string) {\n const includeKeys = {\n lockedContent: 'include.locked.content',\n postsWithMediaType: 'include.posts.with.media.type',\n postsInTier: 'include.posts.in.tier',\n postsPublishedAfter: 'include.posts.published.after',\n postsPublishedBefore: 'include.posts.published.before',\n campaignInfo: 'include.campaign.info',\n contentInfo: 'include.content.info',\n previewMedia: 'include.preview.media',\n contentMedia: 'include.content.media',\n allMediaVariants: 'include.all.media.variants',\n imagesByFilename: 'include.images.by.filename',\n audioByFilename: 'include.audio.by.filename',\n attachmentsByFilename: 'include.attachments.by.filename',\n comments: 'include.comments'\n };\n\n const lines = fs.readFileSync(file)\n .toString('utf-8')\n // Replace Windows line breaks with Unix ones and then split\n .replace(/\\r\\n/g, '\\n').split('\\n')\n .map((line) => line.trim());\n\n const currentTargets: { url: string; include?: RecursivePropsTo<DeepPartial<DownloaderIncludeOptions>, CLIOptionParserEntry>; }[] = [];\n for (let ln = 0; ln < lines.length; ln++) {\n const line = lines[ln];\n if (line === '' || line.startsWith('#')) {\n continue;\n }\n try {\n const match = Object.entries(includeKeys).find((e) => line.startsWith(e[1]));\n if (match) {\n const [ optName, matchKey ] = match;\n const eq = line.indexOf('=');\n const propValue = (eq >= matchKey.length ? line.substring(eq + 1) : '').trim();\n if (propValue) {\n const target = currentTargets.at(-1);\n if (target) {\n const entry: CLIOptionParserEntry = {\n key: matchKey,\n line: ln,\n src: 'tgt',\n value: propValue\n };\n if (!target.include) {\n target.include = {};\n }\n if (matchKey === includeKeys.postsPublishedAfter || matchKey === includeKeys.postsPublishedBefore) {\n if (!target.include.postsPublished) {\n target.include.postsPublished = {};\n }\n if (matchKey === includeKeys.postsPublishedAfter) {\n target.include.postsPublished.after = entry;\n }\n else {\n target.include.postsPublished.before = entry;\n }\n }\n else if (matchKey === includeKeys.imagesByFilename || matchKey === includeKeys.audioByFilename ||\n matchKey === includeKeys.attachmentsByFilename) {\n if (!target.include.mediaByFilename) {\n target.include.mediaByFilename = {};\n }\n switch (matchKey) {\n case includeKeys.imagesByFilename:\n target.include.mediaByFilename.images = entry;\n break;\n case includeKeys.audioByFilename:\n target.include.mediaByFilename.audio = entry;\n break;\n case includeKeys.attachmentsByFilename:\n target.include.mediaByFilename.attachments = entry;\n break;\n }\n }\n else {\n target.include[optName as keyof DownloaderIncludeOptions] = entry;\n }\n }\n }\n }\n else {\n const url = CLIOptionValidator.validateTargetURL(line);\n currentTargets.push({ url });\n }\n }\n catch (error: any) {\n const errMsg = error instanceof Error ? error.message : error;\n throw Error(`Error parsing targets file (line ${ln})${errMsg ? `: ${errMsg}` : ''}`);\n }\n }\n\n const result: CLITargetURLEntry[] = [];\n for (const target of currentTargets) {\n const v: CLITargetURLEntry = { url: target.url };\n if (target.include) {\n const includeOpts = ObjectHelper.clean(getCLIIncludeOptions(target), {\n deep: true, cleanNulls: true, cleanEmptyObjects: true\n });\n if (Object.entries(includeOpts).length > 0) {\n v.include = includeOpts;\n }\n }\n result.push(v);\n }\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"CLIOptions.js","sourceRoot":"","sources":["../../src/cli/CLIOptions.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport { type DownloaderIncludeOptions, type DownloaderOptions } from '../downloaders/DownloaderOptions.js';\nimport { type DeepPartial, type RecursivePropsTo, pickDefined } from '../utils/Misc.js';\nimport { type ConsoleLoggerOptions } from '../utils/logging/ConsoleLogger.js';\nimport { type FileLoggerType, type FileLoggerOptions } from '../utils/logging/FileLogger.js';\nimport CLIOptionValidator from './CLIOptionValidator.js';\nimport CommandLineParser, { type CommandLineParseResult } from './CommandLineParser.js';\nimport ConfigFileParser, { type ConfigFileParseResult } from './ConfigFileParser.js';\nimport path from 'path';\nimport ObjectHelper from '../utils/ObjectHelper.js';\n\nexport interface CLITargetURLEntry {\n url: string;\n // Target-specific 'include' options\n include?: DownloaderIncludeOptions;\n}\n\nexport interface CLIOptions extends Omit<DownloaderOptions, 'logger'> {\n targetURLs: CLITargetURLEntry[];\n noPrompt: boolean;\n consoleLogger: ConsoleLoggerOptions;\n fileLoggers?: Omit<FileLoggerOptions<FileLoggerType.Downloader>, 'init'>[];\n}\n\nexport type CLIOptionParserEntry = ({\n src: 'cli'\n} | {\n src: 'cfg',\n section: string\n} | {\n src: 'tgt',\n line: number\n}) & {\n key: string;\n value?: string;\n}\n\nexport function getCLIOptions(skipTargetURLs: true): Omit<CLIOptions, 'targetURLs'>;\nexport function getCLIOptions(skipTargetURLs?: false): CLIOptions;\nexport function getCLIOptions(skipTargetURLs = false): CLIOptions | Omit<CLIOptions, 'targetURLs'> {\n const commandLineOptions = CommandLineParser.parse();\n\n const configFileOptions = commandLineOptions.configFile?.value ? ConfigFileParser.parse(commandLineOptions.configFile.value) : null;\n\n let targetURLs: CLITargetURLEntry[] = [];\n if (!skipTargetURLs) {\n const targetURLValue = CLIOptionValidator.validateRequired(pickDefined(commandLineOptions.targetURLs, configFileOptions?.targetURLs), 'No target URL specified');\n const targetsFile = path.resolve(targetURLValue);\n if (fs.existsSync(targetsFile)) {\n targetURLs = readTargetsFile(targetsFile);\n }\n else {\n targetURLs = CLIOptionValidator\n .validateTargetURLs(targetURLValue)\n .map((url) => ({ url }));\n }\n }\n\n const { consoleLogger, fileLoggers } = getCLILoggerOptions(commandLineOptions, configFileOptions);\n const proxy = getProxyOptions(configFileOptions);\n\n const options = {\n cookie: CLIOptionValidator.validateString(pickDefined(commandLineOptions.cookie, configFileOptions?.cookie)),\n useStatusCache: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.useStatusCache, configFileOptions?.useStatusCache)),\n stopOn: CLIOptionValidator.validateString(pickDefined(commandLineOptions.stopOn, configFileOptions?.stopOn), 'never', 'postPreviouslyDownloaded', 'postPublishDateOutOfRange'),\n pathToFFmpeg: CLIOptionValidator.validateString(pickDefined(commandLineOptions.pathToFFmpeg, configFileOptions?.pathToFFmpeg)),\n outDir: CLIOptionValidator.validateString(pickDefined(commandLineOptions.outDir, configFileOptions?.outDir)),\n dirNameFormat: {\n campaign: CLIOptionValidator.validateString(pickDefined(commandLineOptions.dirNameFormat?.campaign, configFileOptions?.dirNameFormat?.campaign)),\n content: CLIOptionValidator.validateString(pickDefined(commandLineOptions.dirNameFormat?.content, configFileOptions?.dirNameFormat?.content))\n },\n filenameFormat: {\n media: CLIOptionValidator.validateString(pickDefined(commandLineOptions.filenameFormat?.media, configFileOptions?.filenameFormat?.media))\n },\n include: getCLIIncludeOptions(commandLineOptions, configFileOptions),\n request: {\n maxRetries: CLIOptionValidator.validateNumber(pickDefined(commandLineOptions?.request?.maxRetries, configFileOptions?.request?.maxRetries)),\n maxConcurrent: CLIOptionValidator.validateNumber(pickDefined(commandLineOptions?.request?.maxConcurrent, configFileOptions?.request?.maxConcurrent)),\n minTime: CLIOptionValidator.validateNumber(pickDefined(commandLineOptions?.request?.minTime, configFileOptions?.request?.minTime)),\n proxy,\n userAgent: CLIOptionValidator.validateString(pickDefined(commandLineOptions?.request?.userAgent, configFileOptions?.request?.userAgent))\n },\n fileExistsAction: {\n content: CLIOptionValidator.validateString(pickDefined(commandLineOptions.fileExistsAction?.content, configFileOptions?.fileExistsAction?.content), 'overwrite', 'skip', 'saveAsCopy', 'saveAsCopyIfNewer'),\n info: CLIOptionValidator.validateString(pickDefined(commandLineOptions.fileExistsAction?.info, configFileOptions?.fileExistsAction?.info), 'overwrite', 'skip', 'saveAsCopy', 'saveAsCopyIfNewer'),\n infoAPI: CLIOptionValidator.validateString(pickDefined(commandLineOptions.fileExistsAction?.infoAPI, configFileOptions?.fileExistsAction?.infoAPI), 'overwrite', 'skip', 'saveAsCopy', 'saveAsCopyIfNewer')\n },\n embedDownloaders: getEmbedDownloaderOptions(configFileOptions),\n noPrompt: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.noPrompt, configFileOptions?.noPrompt)) || false,\n dryRun: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.dryRun, configFileOptions?.dryRun)) || false,\n consoleLogger,\n fileLoggers\n } satisfies Omit<CLIOptions, 'targetURLs'>;\n\n if (skipTargetURLs) {\n return options;\n }\n\n return {\n targetURLs,\n ...options\n } satisfies CLIOptions;\n}\n\nexport function getCLILoggerOptions(commandLineOptions?: CommandLineParseResult, configFileOptions?: ReturnType<typeof ConfigFileParser['parse']> | null) {\n if (!commandLineOptions) {\n commandLineOptions = CommandLineParser.parse();\n }\n const consoleLogger = {\n enabled: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.enabled, configFileOptions?.consoleLogger?.enabled)),\n logLevel: CLIOptionValidator.validateString(pickDefined(commandLineOptions.consoleLogger?.logLevel, configFileOptions?.consoleLogger?.logLevel), 'info', 'debug', 'warn', 'error'),\n include: {\n dateTime: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.dateTime, configFileOptions?.consoleLogger?.include?.dateTime)),\n level: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.level, configFileOptions?.consoleLogger?.include?.level)),\n originator: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.originator, configFileOptions?.consoleLogger?.include?.originator)),\n errorStack: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.include?.errorStack, configFileOptions?.consoleLogger?.include?.errorStack))\n },\n dateTimeFormat: CLIOptionValidator.validateString(pickDefined(commandLineOptions.consoleLogger?.dateTimeFormat, configFileOptions?.consoleLogger?.dateTimeFormat)),\n color: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.consoleLogger?.color, configFileOptions?.consoleLogger?.color))\n };\n let fileLoggers;\n if (configFileOptions?.fileLoggers) {\n fileLoggers = configFileOptions.fileLoggers.map((logger): Omit<FileLoggerOptions<FileLoggerType.Downloader>, 'init'> => ({\n enabled: CLIOptionValidator.validateBoolean(logger.enabled),\n logDir: CLIOptionValidator.validateString(logger.logDir),\n logFilename: CLIOptionValidator.validateString(logger.logFilename),\n fileExistsAction: CLIOptionValidator.validateString(logger.fileExistsAction, 'append', 'overwrite'),\n logLevel: CLIOptionValidator.validateString(logger.logLevel, 'info', 'debug', 'warn', 'error'),\n include: {\n dateTime: CLIOptionValidator.validateBoolean(logger.include?.dateTime),\n level: CLIOptionValidator.validateBoolean(logger.include?.level),\n originator: CLIOptionValidator.validateBoolean(logger.include?.originator),\n errorStack: CLIOptionValidator.validateBoolean(logger.include?.errorStack)\n },\n dateTimeFormat: CLIOptionValidator.validateString(logger.dateTimeFormat),\n color: CLIOptionValidator.validateBoolean(logger.color)\n }));\n }\n return {\n consoleLogger,\n fileLoggers\n };\n}\n\nfunction getCLIIncludeOptions(commandLineOptions: CommandLineParseResult, configFileOptions?: ConfigFileParseResult | null) {\n if (!commandLineOptions) {\n commandLineOptions = CommandLineParser.parse();\n }\n return {\n lockedContent: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.lockedContent, configFileOptions?.include?.lockedContent)),\n postsWithMediaType: CLIOptionValidator.validateIncludeContentWithMediaType(pickDefined(commandLineOptions.include?.postsWithMediaType, configFileOptions?.include?.postsWithMediaType)),\n postsInTier: CLIOptionValidator.validateIncludeContentInTier(pickDefined(commandLineOptions.include?.postsInTier, configFileOptions?.include?.postsInTier)),\n postsPublished: {\n after: CLIOptionValidator.validateDateTime(pickDefined(commandLineOptions.include?.postsPublished?.after, configFileOptions?.include?.postsPublished?.after)) || null,\n before: CLIOptionValidator.validateDateTime(pickDefined(commandLineOptions.include?.postsPublished?.before, configFileOptions?.include?.postsPublished?.before)) || null,\n },\n campaignInfo: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.campaignInfo, configFileOptions?.include?.campaignInfo)),\n contentInfo: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.contentInfo, configFileOptions?.include?.contentInfo)),\n previewMedia: CLIOptionValidator.validateIncludePreviewMedia(pickDefined(commandLineOptions.include?.previewMedia, configFileOptions?.include?.previewMedia)),\n contentMedia: CLIOptionValidator.validateIncludeContentMedia(pickDefined(commandLineOptions.include?.contentMedia, configFileOptions?.include?.contentMedia)),\n allMediaVariants: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.allMediaVariants, configFileOptions?.include?.allMediaVariants)),\n mediaByFilename: {\n images: CLIOptionValidator.validateString(pickDefined(commandLineOptions.include?.mediaByFilename?.images, configFileOptions?.include?.mediaByFilename?.images)) || null,\n audio: CLIOptionValidator.validateString(pickDefined(commandLineOptions.include?.mediaByFilename?.audio, configFileOptions?.include?.mediaByFilename?.audio)) || null,\n attachments: CLIOptionValidator.validateString(pickDefined(commandLineOptions.include?.mediaByFilename?.attachments, configFileOptions?.include?.mediaByFilename?.attachments)) || null\n },\n comments: CLIOptionValidator.validateBoolean(pickDefined(commandLineOptions.include?.comments, configFileOptions?.include?.comments))\n };\n}\n\nfunction getEmbedDownloaderOptions(configFileOptions?: ConfigFileParseResult | null) {\n if (configFileOptions?.embedDownloaders) {\n return configFileOptions?.embedDownloaders.map((dl) => ({\n provider: CLIOptionValidator.validateRequired(dl.provider),\n exec: CLIOptionValidator.validateRequired(dl.exec)\n }));\n }\n return undefined;\n}\n\nfunction getProxyOptions(configFileOptions?: ConfigFileParseResult | null) {\n if (configFileOptions?.request?.proxy && configFileOptions.request.proxy.url?.value?.trim()) {\n return {\n url: CLIOptionValidator.validateProxyURL(configFileOptions.request.proxy.url),\n rejectUnauthorizedTLS: CLIOptionValidator.validateBoolean(configFileOptions.request.proxy.rejectUnauthorizedTLS)\n };\n }\n return null;\n}\n\nfunction readTargetsFile(file: string) {\n const includeKeys = {\n lockedContent: 'include.locked.content',\n postsWithMediaType: 'include.posts.with.media.type',\n postsInTier: 'include.posts.in.tier',\n postsPublishedAfter: 'include.posts.published.after',\n postsPublishedBefore: 'include.posts.published.before',\n campaignInfo: 'include.campaign.info',\n contentInfo: 'include.content.info',\n previewMedia: 'include.preview.media',\n contentMedia: 'include.content.media',\n allMediaVariants: 'include.all.media.variants',\n imagesByFilename: 'include.images.by.filename',\n audioByFilename: 'include.audio.by.filename',\n attachmentsByFilename: 'include.attachments.by.filename',\n comments: 'include.comments'\n };\n\n const lines = fs.readFileSync(file)\n .toString('utf-8')\n // Replace Windows line breaks with Unix ones and then split\n .replace(/\\r\\n/g, '\\n').split('\\n')\n .map((line) => line.trim());\n\n const currentTargets: { url: string; include?: RecursivePropsTo<DeepPartial<DownloaderIncludeOptions>, CLIOptionParserEntry>; }[] = [];\n for (let ln = 0; ln < lines.length; ln++) {\n const line = lines[ln];\n if (line === '' || line.startsWith('#')) {\n continue;\n }\n try {\n const match = Object.entries(includeKeys).find((e) => line.startsWith(e[1]));\n if (match) {\n const [ optName, matchKey ] = match;\n const eq = line.indexOf('=');\n const propValue = (eq >= matchKey.length ? line.substring(eq + 1) : '').trim();\n if (propValue) {\n const target = currentTargets.at(-1);\n if (target) {\n const entry: CLIOptionParserEntry = {\n key: matchKey,\n line: ln,\n src: 'tgt',\n value: propValue\n };\n if (!target.include) {\n target.include = {};\n }\n if (matchKey === includeKeys.postsPublishedAfter || matchKey === includeKeys.postsPublishedBefore) {\n if (!target.include.postsPublished) {\n target.include.postsPublished = {};\n }\n if (matchKey === includeKeys.postsPublishedAfter) {\n target.include.postsPublished.after = entry;\n }\n else {\n target.include.postsPublished.before = entry;\n }\n }\n else if (matchKey === includeKeys.imagesByFilename || matchKey === includeKeys.audioByFilename ||\n matchKey === includeKeys.attachmentsByFilename) {\n if (!target.include.mediaByFilename) {\n target.include.mediaByFilename = {};\n }\n switch (matchKey) {\n case includeKeys.imagesByFilename:\n target.include.mediaByFilename.images = entry;\n break;\n case includeKeys.audioByFilename:\n target.include.mediaByFilename.audio = entry;\n break;\n case includeKeys.attachmentsByFilename:\n target.include.mediaByFilename.attachments = entry;\n break;\n }\n }\n else {\n target.include[optName as keyof DownloaderIncludeOptions] = entry;\n }\n }\n }\n }\n else {\n const url = CLIOptionValidator.validateTargetURL(line);\n currentTargets.push({ url });\n }\n }\n catch (error: any) {\n const errMsg = error instanceof Error ? error.message : error;\n throw Error(`Error parsing targets file (line ${ln})${errMsg ? `: ${errMsg}` : ''}`);\n }\n }\n\n const result: CLITargetURLEntry[] = [];\n for (const target of currentTargets) {\n const v: CLITargetURLEntry = { url: target.url };\n if (target.include) {\n const includeOpts = ObjectHelper.clean(getCLIIncludeOptions(target), {\n deep: true, cleanNulls: true, cleanEmptyObjects: true\n });\n if (Object.entries(includeOpts).length > 0) {\n v.include = includeOpts;\n }\n }\n result.push(v);\n }\n\n return result;\n}\n"]}
package/dist/cli/index.js CHANGED
@@ -16,7 +16,7 @@ import path from 'path';
16
16
  import fs from 'fs';
17
17
  import Downloader from '../downloaders/Downloader.js';
18
18
  import ConsoleLogger from '../utils/logging/ConsoleLogger.js';
19
- import { getCLILoggerOptions, getCLIOptions } from './CLIOptions.js';
19
+ import { getCLIOptions } from './CLIOptions.js';
20
20
  import CommandLineParser from './CommandLineParser.js';
21
21
  import { commonLog } from '../utils/logging/Logger.js';
22
22
  import FileLogger, { FileLoggerType } from '../utils/logging/FileLogger.js';
@@ -68,12 +68,15 @@ class PatreonDownloaderCLI {
68
68
  if (listTiersTargets) {
69
69
  const { byVanity: vanities, byUserId: userIds } = listTiersTargets;
70
70
  let hasError = false;
71
- const { consoleLogger: consoleLoggerOptions } = getCLILoggerOptions();
72
- const consoleLogger = new ConsoleLogger(consoleLoggerOptions);
71
+ const options = getCLIOptions(true);
72
+ const consoleLogger = new ConsoleLogger(options.consoleLogger);
73
73
  const __doList = async (targets, targetType) => {
74
74
  for (const target of targets) {
75
75
  try {
76
- const campaign = await Downloader.getCampaign(targetType === 'vanity' ? target : { userId: target }, undefined, consoleLogger);
76
+ const campaign = await Downloader.getCampaign(targetType === 'vanity' ? target : { userId: target }, undefined, {
77
+ ...options,
78
+ logger: consoleLogger
79
+ });
77
80
  if (campaign) {
78
81
  const p = targetType === 'userId' ? 'user #' : '';
79
82
  console.log(`*** Tiers for ${p}${target} ***${EOL}`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { EOL } from 'os';\nimport PromptSync from 'prompt-sync';\nimport path from 'path';\nimport fs from 'fs';\nimport Downloader, { type DownloaderConfig } from '../downloaders/Downloader.js';\nimport ConsoleLogger from '../utils/logging/ConsoleLogger.js';\nimport { type CLIOptions, type CLITargetURLEntry, getCLILoggerOptions, getCLIOptions } from './CLIOptions.js';\nimport CommandLineParser from './CommandLineParser.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { commonLog } from '../utils/logging/Logger.js';\nimport FileLogger, { FileLoggerType, type DownloaderFileLoggerInit } from '../utils/logging/FileLogger.js';\nimport ChainLogger from '../utils/logging/ChainLogger.js';\nimport { type PackageInfo, getPackageInfo } from '../utils/PackageInfo.js';\nimport envPaths from 'env-paths';\nimport YouTubeConfigurator from './helper/YouTubeConfigurator.js';\nimport { type DownloaderIncludeOptions } from '../downloaders/DownloaderOptions.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport copy from 'fast-copy';\nimport cliTruncate from 'cli-truncate';\nimport type deepFreeze from 'deep-freeze';\nimport { type DeepPartial } from '../utils/Misc.js';\nimport { createProxyAgent } from '../utils/Proxy.js';\nimport { type Product } from '../entities/Product.js';\nimport { type Post } from '../entities/Post.js';\n\nconst YT_CREDENTIALS_FILENAME = 'youtube-credentials.json';\n\nexport default class PatreonDownloaderCLI {\n\n #logger: Logger | null;\n #packageInfo: PackageInfo;\n #globalConfPath: string;\n // Keep track of file loggers created, so that we force 'append' mode if\n // Multiple target URLs share the same log file.\n #fileLoggers: FileLogger[];\n\n constructor() {\n this.#logger = null;\n this.#fileLoggers = [];\n this.#packageInfo = getPackageInfo();\n this.#globalConfPath = envPaths(\n this.#packageInfo.name || 'patreon-dl', { suffix: '' }).config;\n }\n\n async start() {\n if (CommandLineParser.showUsage()) {\n return this.exit(0);\n }\n\n if (this.#packageInfo.banner) {\n console.log(`${EOL}${this.#packageInfo.banner}${EOL}`);\n }\n\n const __printOptionError = (error: any) => {\n console.error(\n 'Error processing options: ',\n error instanceof Error ? error.message : error,\n EOL,\n 'See usage with \\'-h\\' option.');\n return this.exit(1);\n };\n\n const ytCredsPath = this.#getYouTubeCredentialsPath();\n if (CommandLineParser.configureYouTube()) {\n return this.exit(await YouTubeConfigurator.start(ytCredsPath));\n }\n\n let listTiersTargets;\n try {\n listTiersTargets = CommandLineParser.listTiers();\n }\n catch (error) {\n return __printOptionError(error);\n }\n if (listTiersTargets) {\n const { byVanity: vanities, byUserId: userIds } = listTiersTargets;\n let hasError = false;\n const { consoleLogger: consoleLoggerOptions } = getCLILoggerOptions();\n const consoleLogger = new ConsoleLogger(consoleLoggerOptions);\n\n const __doList = async (targets: string[], targetType: 'vanity' | 'userId') => {\n for (const target of targets) {\n try {\n const campaign = await Downloader.getCampaign(\n targetType === 'vanity' ? target : { userId: target },\n undefined,\n consoleLogger\n );\n if (campaign) {\n const p = targetType === 'userId' ? 'user #' : '';\n console.log(`*** Tiers for ${p}${target} ***${EOL}`);\n const idColWidth = campaign.rewards.reduce<number>((len, reward) => {\n return Math.max(len, reward.id.length);\n }, 0);\n const gap = ' ';\n console.log(`ID${gap}${' '.repeat(idColWidth - 2)}Title`);\n console.log('-'.repeat(idColWidth) + gap + '-'.repeat('title'.length));\n campaign.rewards.forEach((reward) => {\n console.log(`${reward.id}${' '.repeat(idColWidth - reward.id.length)}${gap}${reward.title || 'Public'}`);\n });\n console.log(EOL);\n }\n else {\n commonLog(consoleLogger, 'error', null, 'Failed to obtain campaign info');\n throw Error();\n }\n }\n catch (_error: unknown) {\n console.error(`${EOL}Error fetching tier data for \"${target}\"${EOL}${EOL}`);\n hasError = true;\n }\n }\n };\n\n await __doList(vanities, 'vanity');\n await __doList(userIds, 'userId');\n\n return this.exit(hasError ? 1 : 0);\n }\n\n let options;\n try {\n options = getCLIOptions();\n }\n catch (error) {\n return __printOptionError(error);\n }\n\n const targetsWithError: string[] = [];\n const targetEndMessages: { url: string; message: string; }[] = [];\n for (let i = 0; i < options.targetURLs.length; i++) {\n const { hasError, aborted, endMessage } = await this.#createAndStartDownloader(options.targetURLs, i, options);\n if (aborted) {\n return this.exit(1);\n }\n const targetURL = options.targetURLs[i].url;\n if (hasError) {\n targetsWithError.push(targetURL);\n }\n targetEndMessages[i] = { url: targetURL, message: endMessage };\n }\n if (options.targetURLs.length > 0) {\n // Print summary\n console.log('');\n const heading = `Total ${options.targetURLs.length} targets processed`;\n console.log(heading);\n console.log('-'.repeat(heading.length));\n console.log('');\n targetEndMessages.forEach(({ url, message }, i) => {\n const s = `${i}: ${url}`;\n console.log(s);\n console.log(message);\n console.log('');\n });\n }\n if (targetsWithError.length > 0) {\n if (options.targetURLs.length > 0) {\n console.warn('There were errors processing the following URLs:', JSON.stringify(targetsWithError, null, 2));\n }\n return this.exit(1);\n }\n return this.exit(0);\n }\n\n #getYouTubeCredentialsPath() {\n return path.resolve(this.#globalConfPath, YT_CREDENTIALS_FILENAME);\n }\n\n #getApplicableIncludeOptions(local?: DownloaderIncludeOptions, global?: DownloaderIncludeOptions) {\n if (!local) {\n return global;\n }\n if (!global) {\n return local;\n }\n const result: DownloaderIncludeOptions = { ...global };\n for (const [ k, v ] of Object.entries(local)) {\n if (v !== undefined) {\n result[k as keyof DownloaderIncludeOptions] = v;\n }\n }\n return result;\n }\n\n #getDisplayConfig(config: DeepPartial<DownloaderConfig<any>> | deepFreeze.DeepReadonly<DownloaderConfig<any>>) {\n const displayConfig = copy(config) as any;\n if (config.include?.postsPublished?.after) {\n displayConfig.include.postsPublished.after = config.include.postsPublished.after.toString();\n }\n if (config.include?.postsPublished?.before) {\n displayConfig.include.postsPublished.before = config.include.postsPublished.before.toString();\n }\n if (config.cookie) {\n displayConfig.cookie = cliTruncate(displayConfig.cookie, 20, { position: 'middle', space: true });\n }\n if (config.include?.mediaByFilename) {\n for (const [k, v] of Object.entries(config.include.mediaByFilename)) {\n if (v) {\n if (v.startsWith('!')) {\n const stripped = v.substring(1);\n if (!stripped) {\n delete displayConfig.include.mediaByFilename[k];\n }\n else {\n displayConfig.include.mediaByFilename[k] = {\n pattern: v.substring(1),\n 'case-sensitive': false\n };\n }\n }\n else {\n displayConfig.include.mediaByFilename[k] = {\n pattern: v,\n 'case-sensitive': true\n };\n }\n }\n }\n }\n return ObjectHelper.clean(displayConfig, {\n deep: true, cleanNulls: true, cleanEmptyObjects: true\n });\n }\n\n async #createAndStartDownloader(targetURLs: CLITargetURLEntry[], index: number, options: CLIOptions) {\n const { url: targetURL } = targetURLs[index];\n const includeOpts = this.#getApplicableIncludeOptions(targetURLs[index].include, options.include);\n\n // Create loggers\n const { chainLogger: logger, consoleLogger, fileLoggers } = this.#createLoggers(targetURL, options);\n this.#logger = logger;\n\n // Create downloader\n let downloader: Downloader<any>;\n const ytCredsPath = this.#getYouTubeCredentialsPath();\n try {\n downloader = await Downloader.getInstance(targetURL, {\n ...options,\n include: includeOpts,\n pathToYouTubeCredentials: fs.existsSync(ytCredsPath) ? ytCredsPath : null,\n logger: this.#logger\n });\n }\n catch (error) {\n commonLog(logger, 'error', null, 'Failed to get downloader instance:', error);\n return { hasError: true, endMessage: 'Downloader init error' };\n }\n\n if (!downloader) {\n commonLog(logger, 'error', null, 'Failed to get downloader instance (unknown reason)');\n return { hasError: true, endMessage: 'Downloader init error' };\n }\n\n const downloaderName = downloader.name;\n const __logBegin = () => {\n commonLog(logger, 'info', null, `*** BEGIN target URL: ${targetURL} ***`, EOL);\n };\n\n const __checkProxy = () => {\n const proxyAgentInfo = createProxyAgent(options);\n if (proxyAgentInfo) {\n if (proxyAgentInfo.protocol !== 'http') {\n commonLog(logger, 'warn', null,\n `${proxyAgentInfo.protocol.toUpperCase()} proxy specified in config. Note that some operations use FFmpeg to download video streams. Since FFmpeg only supports HTTP proxy, these operations will ignore the specified proxy options.`, EOL);\n }\n }\n }\n\n if (!options.noPrompt) {\n\n const __printLoggerConfigs = () => {\n if (!consoleLogger.getConfig().enabled) {\n console.log('Console logging disabled', EOL);\n }\n\n const enabledFileLoggers = fileLoggers.filter((logger) => logger.getConfig().enabled);\n if (enabledFileLoggers.length > 0) {\n console.log('Log files');\n console.log('---------');\n for (const fl of enabledFileLoggers) {\n const flConf = fl.getConfig();\n console.log(`- ${flConf.logLevel}: ${flConf.logFilePath}`);\n }\n console.log(EOL);\n }\n };\n\n const __printDownloaderCreated = () => {\n commonLog(logger, 'info', null, `Created ${downloaderName} instance with config: `, this.#getDisplayConfig(downloader.getConfig()), EOL);\n };\n\n let promptConfirm = true;\n let postConfirm: (() => void) | null = null;\n\n if (targetURLs.length === 1) {\n __printLoggerConfigs();\n __printDownloaderCreated();\n __checkProxy();\n }\n else if (index === 0) {\n postConfirm = () => {\n __logBegin();\n __printLoggerConfigs();\n __printDownloaderCreated();\n };\n const displayConfSrc = await Downloader.getInstance(targetURL, {\n ...options,\n pathToYouTubeCredentials: fs.existsSync(ytCredsPath) ? ytCredsPath : null\n });\n const conf = {...displayConfSrc.getConfig()} as Partial<DownloaderConfig<Post>> & Partial<DownloaderConfig<Product>>;\n delete conf.targetURL;\n delete conf.type;\n delete conf.postFetch;\n delete conf.productId;\n delete conf.outDir;\n const heading = 'Target URLs';\n console.log(`${EOL}${heading}`);\n console.log('-'.repeat(heading.length), EOL);\n const hasTargetSpecificSettings = !!targetURLs.find((target) => target.include);\n targetURLs.forEach((target, i) => {\n console.log(`${i}: ${target.url}`);\n if (hasTargetSpecificSettings) {\n console.log('');\n }\n if (target.include) {\n console.log('include:', this.#getDisplayConfig({include: target.include}).include);\n console.log('');\n }\n });\n const heading2 = 'Common settings';\n console.log(`${EOL}${heading2}`);\n console.log('-'.repeat(heading2.length));\n console.log(this.#getDisplayConfig(conf), EOL);\n if (targetURLs.find((target) => target.include)) {\n console.log('Target-specific settings may override common settings', EOL);\n }\n __checkProxy();\n }\n else {\n __logBegin();\n __printLoggerConfigs();\n __printDownloaderCreated();\n promptConfirm = false;\n }\n if (promptConfirm && !this.#confirmProceed()) {\n console.log('Abort');\n return { aborted: true, endMessage: 'Aborted' };\n }\n if (postConfirm) {\n postConfirm();\n }\n }\n else {\n __logBegin();\n commonLog(logger, 'debug', null, `Created ${downloaderName} instance with config: `, downloader.getConfig());\n if (index === 0) {\n __checkProxy();\n }\n }\n\n let hasDownloaderError = false;\n let isAborted = false;\n let endMessage = '';\n downloader.on('end', ({ aborted, error, message }) => {\n if (aborted) {\n commonLog(logger, 'info', null, `${downloaderName} aborted`);\n isAborted = true;\n }\n else if (!error) {\n commonLog(logger, 'info', null, `${downloaderName} end`);\n }\n else {\n commonLog(logger, 'warn', null, `${downloaderName} end with error`);\n hasDownloaderError = true;\n }\n endMessage = message;\n });\n\n try {\n const abortController = new AbortController();\n const abortHandler = () => {\n abortController.abort();\n };\n process.on('SIGINT', abortHandler);\n await downloader.start({ signal: abortController.signal });\n await logger.end();\n process.off('SIGINT', abortHandler);\n return { hasError: hasDownloaderError, aborted: isAborted, endMessage };\n }\n catch (error) {\n commonLog(logger, 'error', null, `Uncaught ${downloaderName} error:`, error);\n return { hasError: true, aborted: isAborted, endMessage: 'Uncaught error' };\n }\n }\n\n #confirmProceed(prompt?: PromptSync.Prompt): boolean {\n if (!prompt) {\n prompt = PromptSync({ sigint: true });\n }\n const confirmProceed = prompt('Proceed (Y/n)? ');\n if (!confirmProceed.trim() || confirmProceed.trim().toLowerCase() === 'y') {\n return true;\n }\n else if (confirmProceed.trim().toLowerCase() === 'n') {\n return false;\n }\n\n return this.#confirmProceed(prompt);\n }\n\n #createLoggers(targetURL: string, options: CLIOptions) {\n // Create file loggers\n const fileLoggerInit: DownloaderFileLoggerInit = {\n targetURL,\n outDir: options.outDir,\n date: new Date()\n };\n const fileLoggers = options.fileLoggers?.reduce<FileLogger[]>((result, fileLoggerOptions) => {\n try {\n const fullOptions = {\n init: fileLoggerInit,\n ...fileLoggerOptions\n };\n const { filePath } = FileLogger.getPathInfo(FileLoggerType.Downloader, fullOptions);\n const existingFileLogger = this.#fileLoggers.find((logger) => logger.getConfig().logFilePath === filePath);\n const fl = existingFileLogger || new FileLogger(fullOptions);\n result.push(fl);\n }\n catch (error) {\n console.warn('Failed to create file logger: ', error instanceof Error ? error.message : error);\n }\n return result;\n }, []) || [];\n\n // Create console logger\n const consoleLogger = new ConsoleLogger(options.consoleLogger);\n\n // Chain logger\n const chainLogger = new ChainLogger([\n consoleLogger,\n ...fileLoggers\n ]);\n\n return {\n chainLogger,\n consoleLogger,\n fileLoggers\n };\n }\n\n async exit(code?: number) {\n if (this.#logger) {\n await this.#logger.end();\n }\n process.exit(code);\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { EOL } from 'os';\nimport PromptSync from 'prompt-sync';\nimport path from 'path';\nimport fs from 'fs';\nimport Downloader, { type DownloaderConfig } from '../downloaders/Downloader.js';\nimport ConsoleLogger from '../utils/logging/ConsoleLogger.js';\nimport { type CLIOptions, type CLITargetURLEntry, getCLIOptions } from './CLIOptions.js';\nimport CommandLineParser from './CommandLineParser.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { commonLog } from '../utils/logging/Logger.js';\nimport FileLogger, { FileLoggerType, type DownloaderFileLoggerInit } from '../utils/logging/FileLogger.js';\nimport ChainLogger from '../utils/logging/ChainLogger.js';\nimport { type PackageInfo, getPackageInfo } from '../utils/PackageInfo.js';\nimport envPaths from 'env-paths';\nimport YouTubeConfigurator from './helper/YouTubeConfigurator.js';\nimport { type DownloaderIncludeOptions } from '../downloaders/DownloaderOptions.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport copy from 'fast-copy';\nimport cliTruncate from 'cli-truncate';\nimport type deepFreeze from 'deep-freeze';\nimport { type DeepPartial } from '../utils/Misc.js';\nimport { createProxyAgent } from '../utils/Proxy.js';\nimport { type Product } from '../entities/Product.js';\nimport { type Post } from '../entities/Post.js';\n\nconst YT_CREDENTIALS_FILENAME = 'youtube-credentials.json';\n\nexport default class PatreonDownloaderCLI {\n\n #logger: Logger | null;\n #packageInfo: PackageInfo;\n #globalConfPath: string;\n // Keep track of file loggers created, so that we force 'append' mode if\n // Multiple target URLs share the same log file.\n #fileLoggers: FileLogger[];\n\n constructor() {\n this.#logger = null;\n this.#fileLoggers = [];\n this.#packageInfo = getPackageInfo();\n this.#globalConfPath = envPaths(\n this.#packageInfo.name || 'patreon-dl', { suffix: '' }).config;\n }\n\n async start() {\n if (CommandLineParser.showUsage()) {\n return this.exit(0);\n }\n\n if (this.#packageInfo.banner) {\n console.log(`${EOL}${this.#packageInfo.banner}${EOL}`);\n }\n\n const __printOptionError = (error: any) => {\n console.error(\n 'Error processing options: ',\n error instanceof Error ? error.message : error,\n EOL,\n 'See usage with \\'-h\\' option.');\n return this.exit(1);\n };\n\n const ytCredsPath = this.#getYouTubeCredentialsPath();\n if (CommandLineParser.configureYouTube()) {\n return this.exit(await YouTubeConfigurator.start(ytCredsPath));\n }\n\n let listTiersTargets;\n try {\n listTiersTargets = CommandLineParser.listTiers();\n }\n catch (error) {\n return __printOptionError(error);\n }\n if (listTiersTargets) {\n const { byVanity: vanities, byUserId: userIds } = listTiersTargets;\n let hasError = false;\n const options = getCLIOptions(true);\n const consoleLogger = new ConsoleLogger(options.consoleLogger);\n\n const __doList = async (targets: string[], targetType: 'vanity' | 'userId') => {\n for (const target of targets) {\n try {\n const campaign = await Downloader.getCampaign(\n targetType === 'vanity' ? target : { userId: target },\n undefined,\n {\n ...options,\n logger: consoleLogger\n }\n );\n if (campaign) {\n const p = targetType === 'userId' ? 'user #' : '';\n console.log(`*** Tiers for ${p}${target} ***${EOL}`);\n const idColWidth = campaign.rewards.reduce<number>((len, reward) => {\n return Math.max(len, reward.id.length);\n }, 0);\n const gap = ' ';\n console.log(`ID${gap}${' '.repeat(idColWidth - 2)}Title`);\n console.log('-'.repeat(idColWidth) + gap + '-'.repeat('title'.length));\n campaign.rewards.forEach((reward) => {\n console.log(`${reward.id}${' '.repeat(idColWidth - reward.id.length)}${gap}${reward.title || 'Public'}`);\n });\n console.log(EOL);\n }\n else {\n commonLog(consoleLogger, 'error', null, 'Failed to obtain campaign info');\n throw Error();\n }\n }\n catch (_error: unknown) {\n console.error(`${EOL}Error fetching tier data for \"${target}\"${EOL}${EOL}`);\n hasError = true;\n }\n }\n };\n\n await __doList(vanities, 'vanity');\n await __doList(userIds, 'userId');\n\n return this.exit(hasError ? 1 : 0);\n }\n\n let options;\n try {\n options = getCLIOptions();\n }\n catch (error) {\n return __printOptionError(error);\n }\n\n const targetsWithError: string[] = [];\n const targetEndMessages: { url: string; message: string; }[] = [];\n for (let i = 0; i < options.targetURLs.length; i++) {\n const { hasError, aborted, endMessage } = await this.#createAndStartDownloader(options.targetURLs, i, options);\n if (aborted) {\n return this.exit(1);\n }\n const targetURL = options.targetURLs[i].url;\n if (hasError) {\n targetsWithError.push(targetURL);\n }\n targetEndMessages[i] = { url: targetURL, message: endMessage };\n }\n if (options.targetURLs.length > 0) {\n // Print summary\n console.log('');\n const heading = `Total ${options.targetURLs.length} targets processed`;\n console.log(heading);\n console.log('-'.repeat(heading.length));\n console.log('');\n targetEndMessages.forEach(({ url, message }, i) => {\n const s = `${i}: ${url}`;\n console.log(s);\n console.log(message);\n console.log('');\n });\n }\n if (targetsWithError.length > 0) {\n if (options.targetURLs.length > 0) {\n console.warn('There were errors processing the following URLs:', JSON.stringify(targetsWithError, null, 2));\n }\n return this.exit(1);\n }\n return this.exit(0);\n }\n\n #getYouTubeCredentialsPath() {\n return path.resolve(this.#globalConfPath, YT_CREDENTIALS_FILENAME);\n }\n\n #getApplicableIncludeOptions(local?: DownloaderIncludeOptions, global?: DownloaderIncludeOptions) {\n if (!local) {\n return global;\n }\n if (!global) {\n return local;\n }\n const result: DownloaderIncludeOptions = { ...global };\n for (const [ k, v ] of Object.entries(local)) {\n if (v !== undefined) {\n result[k as keyof DownloaderIncludeOptions] = v;\n }\n }\n return result;\n }\n\n #getDisplayConfig(config: DeepPartial<DownloaderConfig<any>> | deepFreeze.DeepReadonly<DownloaderConfig<any>>) {\n const displayConfig = copy(config) as any;\n if (config.include?.postsPublished?.after) {\n displayConfig.include.postsPublished.after = config.include.postsPublished.after.toString();\n }\n if (config.include?.postsPublished?.before) {\n displayConfig.include.postsPublished.before = config.include.postsPublished.before.toString();\n }\n if (config.cookie) {\n displayConfig.cookie = cliTruncate(displayConfig.cookie, 20, { position: 'middle', space: true });\n }\n if (config.include?.mediaByFilename) {\n for (const [k, v] of Object.entries(config.include.mediaByFilename)) {\n if (v) {\n if (v.startsWith('!')) {\n const stripped = v.substring(1);\n if (!stripped) {\n delete displayConfig.include.mediaByFilename[k];\n }\n else {\n displayConfig.include.mediaByFilename[k] = {\n pattern: v.substring(1),\n 'case-sensitive': false\n };\n }\n }\n else {\n displayConfig.include.mediaByFilename[k] = {\n pattern: v,\n 'case-sensitive': true\n };\n }\n }\n }\n }\n return ObjectHelper.clean(displayConfig, {\n deep: true, cleanNulls: true, cleanEmptyObjects: true\n });\n }\n\n async #createAndStartDownloader(targetURLs: CLITargetURLEntry[], index: number, options: CLIOptions) {\n const { url: targetURL } = targetURLs[index];\n const includeOpts = this.#getApplicableIncludeOptions(targetURLs[index].include, options.include);\n\n // Create loggers\n const { chainLogger: logger, consoleLogger, fileLoggers } = this.#createLoggers(targetURL, options);\n this.#logger = logger;\n\n // Create downloader\n let downloader: Downloader<any>;\n const ytCredsPath = this.#getYouTubeCredentialsPath();\n try {\n downloader = await Downloader.getInstance(targetURL, {\n ...options,\n include: includeOpts,\n pathToYouTubeCredentials: fs.existsSync(ytCredsPath) ? ytCredsPath : null,\n logger: this.#logger\n });\n }\n catch (error) {\n commonLog(logger, 'error', null, 'Failed to get downloader instance:', error);\n return { hasError: true, endMessage: 'Downloader init error' };\n }\n\n if (!downloader) {\n commonLog(logger, 'error', null, 'Failed to get downloader instance (unknown reason)');\n return { hasError: true, endMessage: 'Downloader init error' };\n }\n\n const downloaderName = downloader.name;\n const __logBegin = () => {\n commonLog(logger, 'info', null, `*** BEGIN target URL: ${targetURL} ***`, EOL);\n };\n\n const __checkProxy = () => {\n const proxyAgentInfo = createProxyAgent(options);\n if (proxyAgentInfo) {\n if (proxyAgentInfo.protocol !== 'http') {\n commonLog(logger, 'warn', null,\n `${proxyAgentInfo.protocol.toUpperCase()} proxy specified in config. Note that some operations use FFmpeg to download video streams. Since FFmpeg only supports HTTP proxy, these operations will ignore the specified proxy options.`, EOL);\n }\n }\n }\n\n if (!options.noPrompt) {\n\n const __printLoggerConfigs = () => {\n if (!consoleLogger.getConfig().enabled) {\n console.log('Console logging disabled', EOL);\n }\n\n const enabledFileLoggers = fileLoggers.filter((logger) => logger.getConfig().enabled);\n if (enabledFileLoggers.length > 0) {\n console.log('Log files');\n console.log('---------');\n for (const fl of enabledFileLoggers) {\n const flConf = fl.getConfig();\n console.log(`- ${flConf.logLevel}: ${flConf.logFilePath}`);\n }\n console.log(EOL);\n }\n };\n\n const __printDownloaderCreated = () => {\n commonLog(logger, 'info', null, `Created ${downloaderName} instance with config: `, this.#getDisplayConfig(downloader.getConfig()), EOL);\n };\n\n let promptConfirm = true;\n let postConfirm: (() => void) | null = null;\n\n if (targetURLs.length === 1) {\n __printLoggerConfigs();\n __printDownloaderCreated();\n __checkProxy();\n }\n else if (index === 0) {\n postConfirm = () => {\n __logBegin();\n __printLoggerConfigs();\n __printDownloaderCreated();\n };\n const displayConfSrc = await Downloader.getInstance(targetURL, {\n ...options,\n pathToYouTubeCredentials: fs.existsSync(ytCredsPath) ? ytCredsPath : null\n });\n const conf = {...displayConfSrc.getConfig()} as Partial<DownloaderConfig<Post>> & Partial<DownloaderConfig<Product>>;\n delete conf.targetURL;\n delete conf.type;\n delete conf.postFetch;\n delete conf.productId;\n delete conf.outDir;\n const heading = 'Target URLs';\n console.log(`${EOL}${heading}`);\n console.log('-'.repeat(heading.length), EOL);\n const hasTargetSpecificSettings = !!targetURLs.find((target) => target.include);\n targetURLs.forEach((target, i) => {\n console.log(`${i}: ${target.url}`);\n if (hasTargetSpecificSettings) {\n console.log('');\n }\n if (target.include) {\n console.log('include:', this.#getDisplayConfig({include: target.include}).include);\n console.log('');\n }\n });\n const heading2 = 'Common settings';\n console.log(`${EOL}${heading2}`);\n console.log('-'.repeat(heading2.length));\n console.log(this.#getDisplayConfig(conf), EOL);\n if (targetURLs.find((target) => target.include)) {\n console.log('Target-specific settings may override common settings', EOL);\n }\n __checkProxy();\n }\n else {\n __logBegin();\n __printLoggerConfigs();\n __printDownloaderCreated();\n promptConfirm = false;\n }\n if (promptConfirm && !this.#confirmProceed()) {\n console.log('Abort');\n return { aborted: true, endMessage: 'Aborted' };\n }\n if (postConfirm) {\n postConfirm();\n }\n }\n else {\n __logBegin();\n commonLog(logger, 'debug', null, `Created ${downloaderName} instance with config: `, downloader.getConfig());\n if (index === 0) {\n __checkProxy();\n }\n }\n\n let hasDownloaderError = false;\n let isAborted = false;\n let endMessage = '';\n downloader.on('end', ({ aborted, error, message }) => {\n if (aborted) {\n commonLog(logger, 'info', null, `${downloaderName} aborted`);\n isAborted = true;\n }\n else if (!error) {\n commonLog(logger, 'info', null, `${downloaderName} end`);\n }\n else {\n commonLog(logger, 'warn', null, `${downloaderName} end with error`);\n hasDownloaderError = true;\n }\n endMessage = message;\n });\n\n try {\n const abortController = new AbortController();\n const abortHandler = () => {\n abortController.abort();\n };\n process.on('SIGINT', abortHandler);\n await downloader.start({ signal: abortController.signal });\n await logger.end();\n process.off('SIGINT', abortHandler);\n return { hasError: hasDownloaderError, aborted: isAborted, endMessage };\n }\n catch (error) {\n commonLog(logger, 'error', null, `Uncaught ${downloaderName} error:`, error);\n return { hasError: true, aborted: isAborted, endMessage: 'Uncaught error' };\n }\n }\n\n #confirmProceed(prompt?: PromptSync.Prompt): boolean {\n if (!prompt) {\n prompt = PromptSync({ sigint: true });\n }\n const confirmProceed = prompt('Proceed (Y/n)? ');\n if (!confirmProceed.trim() || confirmProceed.trim().toLowerCase() === 'y') {\n return true;\n }\n else if (confirmProceed.trim().toLowerCase() === 'n') {\n return false;\n }\n\n return this.#confirmProceed(prompt);\n }\n\n #createLoggers(targetURL: string, options: CLIOptions) {\n // Create file loggers\n const fileLoggerInit: DownloaderFileLoggerInit = {\n targetURL,\n outDir: options.outDir,\n date: new Date()\n };\n const fileLoggers = options.fileLoggers?.reduce<FileLogger[]>((result, fileLoggerOptions) => {\n try {\n const fullOptions = {\n init: fileLoggerInit,\n ...fileLoggerOptions\n };\n const { filePath } = FileLogger.getPathInfo(FileLoggerType.Downloader, fullOptions);\n const existingFileLogger = this.#fileLoggers.find((logger) => logger.getConfig().logFilePath === filePath);\n const fl = existingFileLogger || new FileLogger(fullOptions);\n result.push(fl);\n }\n catch (error) {\n console.warn('Failed to create file logger: ', error instanceof Error ? error.message : error);\n }\n return result;\n }, []) || [];\n\n // Create console logger\n const consoleLogger = new ConsoleLogger(options.consoleLogger);\n\n // Chain logger\n const chainLogger = new ChainLogger([\n consoleLogger,\n ...fileLoggers\n ]);\n\n return {\n chainLogger,\n consoleLogger,\n fileLoggers\n };\n }\n\n async exit(code?: number) {\n if (this.#logger) {\n await this.#logger.end();\n }\n process.exit(code);\n }\n}\n"]}
@@ -5,7 +5,7 @@ import { type DownloaderBootstrapData, type DownloaderType } from './Bootstrap.j
5
5
  import { type DownloaderInit, type DownloaderOptions, type FileExistsAction } from './DownloaderOptions.js';
6
6
  import { type DownloaderEvent, type DownloaderEventPayloadOf } from './DownloaderEvent.js';
7
7
  import { type LogLevel } from '../utils/logging/Logger.js';
8
- import type Logger from '../utils/logging/Logger.js';
8
+ import Logger from '../utils/logging/Logger.js';
9
9
  import { type Campaign } from '../entities/Campaign.js';
10
10
  import FSHelper, { type WriteTextFileResult } from '../utils/FSHelper.js';
11
11
  import DownloadTaskBatch from './task/DownloadTaskBatch.js';
@@ -58,7 +58,7 @@ export default abstract class Downloader<T extends DownloaderType> extends Event
58
58
  }>;
59
59
  abstract start(params: DownloaderStartParams): Promise<void>;
60
60
  static getInstance(url: string, options?: DownloaderOptions): Promise<import("./PostDownloader.js").default | import("./ProductDownloader.js").default>;
61
- static getCampaign(params: GetCampaignParams, signal?: AbortSignal, logger?: Logger | null): Promise<Campaign | null>;
61
+ static getCampaign(params: GetCampaignParams, signal?: AbortSignal, options?: Logger | null | Pick<DownloaderOptions, 'cookie' | 'request' | 'logger'>): Promise<Campaign | null>;
62
62
  protected saveCampaignInfo(campaign: Campaign | null, signal?: AbortSignal): Promise<void>;
63
63
  protected log(level: LogLevel, ...msg: any[]): void;
64
64
  getConfig(): deepFreeze.DeepReadonly<DownloaderConfig<T>>;
@@ -16,6 +16,7 @@ import deepFreeze from 'deep-freeze';
16
16
  import Fetcher from '../utils/Fetcher.js';
17
17
  import Bootstrap from './Bootstrap.js';
18
18
  import { getDownloaderInit } from './DownloaderOptions.js';
19
+ import Logger from '../utils/logging/Logger.js';
19
20
  import { commonLog } from '../utils/logging/Logger.js';
20
21
  import FSHelper from '../utils/FSHelper.js';
21
22
  import DownloadTaskBatch from './task/DownloadTaskBatch.js';
@@ -221,7 +222,7 @@ class Downloader extends EventEmitter {
221
222
  }
222
223
  }
223
224
  }
224
- static async getCampaign(params, signal, logger) {
225
+ static async getCampaign(params, signal, options) {
225
226
  // Backwards compatibility - if 'params' is string type, then it is vanity
226
227
  let url;
227
228
  if (typeof params === 'string') {
@@ -234,12 +235,12 @@ class Downloader extends EventEmitter {
234
235
  // Sole purpose of passing 'dummy' vanity is to create the PostDownloader instance
235
236
  url = URLHelper.constructUserPostsURL({ vanity: 'dummy' });
236
237
  }
237
- const downloader = await this.getInstance(url, { logger });
238
+ const downloader = await this.getInstance(url, options instanceof Logger ? { logger: options } : (options || undefined));
238
239
  const PostDownloader = (await import('./PostDownloader.js')).default;
239
240
  if (downloader instanceof PostDownloader) {
240
241
  if (typeof params === 'object' && params.campaignId) {
241
242
  const { json } = await downloader.fetchCampaign(params.campaignId, signal);
242
- const parser = new PostParser(logger);
243
+ const parser = new PostParser(options instanceof Logger ? options : options?.logger);
243
244
  return parser.parseCampaignAPIResponse(json);
244
245
  }
245
246
  return downloader.__getCampaign(signal);
@@ -1 +1 @@
1
- {"version":3,"file":"Downloader.js","sourceRoot":"","sources":["../../src/downloaders/Downloader.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport { EventEmitter } from 'events';\nimport deepFreeze from 'deep-freeze';\nimport Fetcher from '../utils/Fetcher.js';\nimport Bootstrap, { type DownloaderBootstrapData, type DownloaderType } from './Bootstrap.js';\nimport { type DownloaderInit, type DownloaderOptions, type FileExistsAction, getDownloaderInit } from './DownloaderOptions.js';\nimport { type DownloaderEvent, type DownloaderEventPayloadOf } from './DownloaderEvent.js';\nimport {type LogLevel} from '../utils/logging/Logger.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { commonLog } from '../utils/logging/Logger.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport FSHelper, { type WriteTextFileResult } from '../utils/FSHelper.js';\nimport DownloadTaskBatch from './task/DownloadTaskBatch.js';\nimport { type IDownloadTask } from './task/DownloadTask.js';\nimport DownloadTaskFactory from './task/DownloadTaskFactory.js';\nimport FilenameFormatHelper from '../utils/FilenameFormatHelper.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { generateCampaignSummary } from './templates/CampaignInfo.js';\nimport path from 'path';\nimport URLHelper from '../utils/URLHelper.js';\nimport ffmpeg from 'fluent-ffmpeg';\nimport InnertubeLoader from '../utils/yt/InnertubeLoader.js';\nimport FFmpegDownloadTaskBase from './task/FFmpegDownloadTaskBase.js';\nimport ExternalDownloaderTask from './task/ExternalDownloaderTask.js';\nimport DB, { type DBInstance } from '../browse/db/index.js';\nimport PostParser from '../parsers/PostParser.js';\n\nexport type DownloaderConfig<T extends DownloaderType> =\n DownloaderInit &\n DownloaderBootstrapData<T>;\n\nexport interface DownloaderStartParams {\n signal?: AbortSignal;\n}\n\nexport type GetCampaignParams = \n string |\n { userId: string; vanity?: never, campaignId?: never; } |\n { userId?: never; vanity: string, campaignId?: never; } |\n { vanity?: never; userId?: never; campaignId: string; };\n\ninterface CreateDownloadTaskParams {\n target: Downloadable[];\n targetName: string;\n dirs: {\n campaign: string | null;\n main: string;\n thumbnails: string | null;\n };\n fileExistsAction: FileExistsAction;\n isAttachment?: boolean;\n}\n\nexport default abstract class Downloader<T extends DownloaderType> extends EventEmitter {\n\n abstract name: string;\n\n protected fetcher: Fetcher;\n protected fsHelper: FSHelper;\n protected config: DownloaderConfig<T>;\n protected logger?: Logger | null;\n protected db: () => Promise<DBInstance>;\n #dbPromise: Promise<DBInstance> | null;\n\n #hasEmittedEndEventOnAbort: boolean;\n\n constructor(config: DownloaderConfig<T>, db: () => Promise<DBInstance>, logger?: Logger | null) {\n super();\n\n this.config = config;\n this.fetcher = new Fetcher(this.config, logger);\n this.fsHelper = new FSHelper(this.config, logger);\n this.#dbPromise = null;\n this.db = async () => {\n if (!this.#dbPromise) {\n this.#dbPromise = db();\n }\n return this.#dbPromise;\n }\n this.logger = logger;\n\n if (this.config.pathToFFmpeg) {\n ffmpeg.setFfmpegPath(this.config.pathToFFmpeg);\n }\n\n InnertubeLoader.setLogger(this.logger);\n if (this.config.pathToYouTubeCredentials) {\n InnertubeLoader.setCredentialsFile(this.config.pathToYouTubeCredentials);\n }\n\n this.#hasEmittedEndEventOnAbort = false;\n }\n\n protected createDownloadTaskBatch(\n name: string,\n signal?: AbortSignal,\n ...createTasks: Array<CreateDownloadTaskParams | null>\n ): Promise<{ batch: DownloadTaskBatch; errorCount: number; }> {\n\n const __getDownloadIdString = (task: IDownloadTask, batch: DownloadTaskBatch) => {\n let result = `#${batch.id}.${task.id}`;\n if (task.retryCount > 0) {\n result += `-r${task.retryCount}`;\n }\n return result;\n };\n\n const batch = new DownloadTaskBatch({\n name,\n fetcher: this.fetcher,\n limiter: this.config.request,\n logger: this.logger\n });\n\n batch.on('taskStart', ({task}) => {\n const retryOrBeginStr = task.retryCount > 0 ? 'retry' : 'begin';\n const isExternal = task instanceof ExternalDownloaderTask;\n const destStr = isExternal ? ' -> Unknown destination (external process)' : task.resolvedDestFilename ? ` -> ${task.resolvedDestFilename}` : '';\n this.log('info', `Download ${retryOrBeginStr} (${__getDownloadIdString(task, batch)}): [type: ${task.srcEntity.type}; ID: #${task.srcEntity.id}]${destStr}`);\n if (task instanceof FFmpegDownloadTaskBase) {\n const retryOrBeginStr = task.retryCount > 0 ? 'Retry' : 'Begin';\n this.log('info', `${retryOrBeginStr} FFmpeg task (${__getDownloadIdString(task, batch)}): ${task.commandLine}`);\n }\n });\n\n batch.on('taskComplete', ({task}) => {\n const isExternal = task instanceof ExternalDownloaderTask;\n const destStr = isExternal ? ': Unknown destination (external process)' : task.resolvedDestPath ? `: \"${task.resolvedDestPath}\"` : '';\n this.log('info', `Download complete (${__getDownloadIdString(task, batch)})${destStr}`);\n });\n\n batch.on('taskError', ({error, willRetry}) => {\n const { task, cause, message } = error;\n const retryStr = willRetry ? '- will retry' : '';\n this.log('error', `Download error (${__getDownloadIdString(task, batch)}):`, cause || message, `(${task.src})`, retryStr);\n });\n\n batch.on('taskAbort', ({task}) => {\n this.log('warn', `Download aborted (${__getDownloadIdString(task, batch)})`);\n });\n\n batch.on('taskSkip', ({task, reason}) => {\n this.log('warn', `Download skipped (${__getDownloadIdString(task, batch)}): ${reason.message}`);\n });\n\n batch.on('taskSpawn', ({origin, spawn}) => {\n this.log('info', `Download spawned: #${batch.id}.${origin.id} -> #${batch.id}.${spawn.id}`);\n });\n\n /**\n * Uncomment this block to log download progress\n\n batch.on('taskProgress', ({task, progress}) => {\n if (progress) {\n if (progress.length) {\n this.log('info', `Download progress (${__getDownloadIdString(task, batch)}): ${progress.lengthDownloaded} / ${progress.length} ${progress.lengthUnit}s / ${progress.percent}% (${progress.speed} kB/s)`,);\n }\n else {\n this.log('info', `Download progress (${__getDownloadIdString(task, batch)}): ${progress.lengthDownloaded} / ? ${progress.lengthUnit}s (${progress.speed} kB/s)`,);\n }\n }\n else {\n this.log('warn', `Download progress not available (${__getDownloadIdString(task, batch)})`);\n }\n });\n\n */\n\n batch.on('complete', () => {\n const total = batch.getTasks().length;\n const completed = batch.getTasks('completed').length;\n const error = batch.getTasks('error').length;\n const aborted = batch.getTasks('aborted').length;\n const skipped = batch.getTasks('skipped').length;\n const counts = [\n `${total} downloads`,\n `${completed} completed`,\n `${error} errors`,\n `${skipped} skipped`,\n `${aborted} aborted`\n ].join('; ');\n this.log('info', `Download batch complete (#${batch.id}): ${counts}`);\n });\n\n return this.addToDownloadTaskBatch(batch, signal, ...createTasks);\n }\n\n protected async addToDownloadTaskBatch(\n batch: DownloadTaskBatch,\n signal?: AbortSignal,\n ...createTasks: Array<CreateDownloadTaskParams | null>\n ) {\n let failedCreateTaskCount = 0;\n for (const task of createTasks) {\n if (!task) {\n continue;\n }\n const { target, targetName, dirs } = task;\n this.log('info', `Create download tasks for ${targetName}`);\n if (task.target.length === 0) {\n this.log('warn', `No items in ${targetName}`);\n continue;\n }\n let ensureDirs: string[] = [];\n for (const tt of target) {\n try {\n const tasks = await DownloadTaskFactory.createFromDownloadable({\n config: this.config,\n dirs,\n item: tt,\n fetcher: this.fetcher,\n fileExistsAction: task.fileExistsAction,\n isAttachment: task.isAttachment,\n limiter: batch.limiter,\n signal,\n logger: this.logger\n });\n\n if (signal?.aborted) {\n return { batch, errorCount: failedCreateTaskCount };\n }\n\n // Filter out tasks that are DOA (errors that occurred in DownloadTask.create())\n for (const task of tasks) {\n if (task.doa) {\n this.log('error', `Failed to create download task for item #${tt.id} in ${targetName}:`, task.doa.msg, task.doa.cause);\n failedCreateTaskCount++;\n }\n }\n const createdTasks = tasks.filter((task) => !task.doa);\n batch.addTasks(createdTasks);\n ensureDirs = createdTasks.reduce<string[]>((result, task) => {\n const dir = task.resolvedDestPath ? path.dirname(task.resolvedDestPath) : null;\n if (dir && !result.includes(dir)) {\n result.push(dir);\n }\n return result;\n }, ensureDirs);\n }\n catch (error) {\n if (signal?.aborted) {\n this.log('warn', 'Operation aborted');\n return { batch, errorCount: failedCreateTaskCount };\n }\n this.log('error', `Failed to create download task(s) for item #${tt.id} in ${targetName}:`, error);\n failedCreateTaskCount++;\n }\n }\n for (const dir of ensureDirs) {\n this.fsHelper.createDir(dir);\n }\n }\n if (failedCreateTaskCount > 0) {\n this.log('warn', `${failedCreateTaskCount} items could not be processed for downloading`);\n }\n return { batch, errorCount: failedCreateTaskCount };\n }\n\n abstract start(params: DownloaderStartParams): Promise<void>;\n\n static async getInstance(url: string, options?: DownloaderOptions) {\n const bootstrap = Bootstrap.getDownloaderBootstrapDataByURL(url);\n if (!bootstrap) {\n throw Error('Could not determine downloader type from URL');\n }\n this.#validateOptions(options);\n\n const config = {\n ...bootstrap,\n ...getDownloaderInit(options)\n };\n const logger = options?.logger;\n const fsHelper = new FSHelper(config, logger);\n const db = () => DB.getInstance(fsHelper.getDBFilePath(), config.dryRun, logger);\n \n switch (config.type) {\n case 'product': {\n const ProductDownloader = (await import('./ProductDownloader.js')).default;\n return new ProductDownloader(config, db, logger);\n }\n case 'post': {\n const PostDownloader = (await import('./PostDownloader.js')).default;\n return new PostDownloader(config, db, logger);\n }\n }\n }\n\n static async getCampaign(\n params: GetCampaignParams,\n signal?: AbortSignal,\n logger?: Logger | null\n ) {\n // Backwards compatibility - if 'params' is string type, then it is vanity\n let url: string;\n if (typeof params === 'string') {\n url = URLHelper.constructUserPostsURL({ vanity: params });\n }\n else if (params.userId || params.vanity) {\n url = URLHelper.constructUserPostsURL(params);\n }\n else {\n // Sole purpose of passing 'dummy' vanity is to create the PostDownloader instance\n url = URLHelper.constructUserPostsURL({ vanity: 'dummy' });\n }\n const downloader = await this.getInstance(url, { logger });\n const PostDownloader = (await import('./PostDownloader.js')).default;\n if (downloader instanceof PostDownloader) {\n if (typeof params === 'object' && params.campaignId) {\n const { json } = await downloader.fetchCampaign(params.campaignId, signal);\n const parser = new PostParser(logger);\n return parser.parseCampaignAPIResponse(json);\n }\n return downloader.__getCampaign(signal);\n }\n throw Error('Type mismatch: PostDownloader expected');\n }\n\n static #validateOptions(options?: DownloaderOptions) {\n if (!options) {\n return true;\n }\n\n // Check FFmpeg path exists\n if (options.pathToFFmpeg) {\n if (!fs.existsSync(options.pathToFFmpeg)) {\n throw Error(`Path to FFmpeg executable \"${options.pathToFFmpeg}\" does not exist`);\n }\n else if (!fs.lstatSync(options.pathToFFmpeg).isFile()) {\n throw Error(`Path to FFmpeg executable \"${options.pathToFFmpeg}\" does not point to a file`);\n }\n }\n\n // Check outDir is a directory\n if (options.outDir) {\n if (fs.existsSync(options.outDir) && !fs.lstatSync(options.outDir).isDirectory()) {\n throw Error(`\"${options.outDir}\" is not a directory`);\n }\n }\n\n // Check formats are valid\n const campaignDirNameFormat = options.dirNameFormat?.campaign;\n if (campaignDirNameFormat) {\n const validate = FilenameFormatHelper.validateCampaignDirNameFormat(campaignDirNameFormat);\n if (!validate.validateOK) {\n throw Error(`Campaign directory name format '${campaignDirNameFormat}' is invalid (matched against ${validate.regex})`);\n }\n }\n const contentDirNameFormat = options.dirNameFormat?.content;\n if (contentDirNameFormat) {\n const validate = FilenameFormatHelper.validateContentDirNameFormat(contentDirNameFormat);\n if (!validate.validateOK) {\n throw Error(`Content directory name format '${contentDirNameFormat}' is invalid (matched against ${validate.regex})`);\n }\n }\n const mediaFilenameFormat = options.filenameFormat?.media;\n if (mediaFilenameFormat) {\n const validate = FilenameFormatHelper.validateMediaFilenameFormat(mediaFilenameFormat);\n if (!validate.validateOK) {\n throw Error(`Media filename format '${mediaFilenameFormat}' is invalid (matched against ${validate.regex})`);\n }\n }\n\n return true;\n }\n\n protected saveCampaignInfo(campaign: Campaign | null, signal?: AbortSignal) {\n\n return new Promise<void>((resolve) => {\n void (async () => {\n const db = await this.db();\n if (!this.config.include.campaignInfo) {\n if (campaign) {\n await db.saveCampaign(campaign, new Date());\n }\n resolve();\n return;\n }\n \n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n \n let batch: DownloadTaskBatch | null = null;\n const abortHandler = () => {\n void (async () => {\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n \n if (!campaign) {\n this.log('warn', 'Skipped saving campaign info: target unavailable');\n resolve();\n return;\n }\n \n this.log('info', `Save campaign info #${campaign.id}`);\n this.emit('targetBegin', { target: campaign });\n this.emit('phaseBegin', { target: campaign, phase: 'saveInfo' });\n \n // Step 1: create campaign directories\n const campaignDirs = this.fsHelper.getCampaignDirs(campaign);\n this.log('debug', 'Campaign directories: ', campaignDirs);\n this.fsHelper.createDir(campaignDirs.root);\n this.fsHelper.createDir(campaignDirs.info);\n \n // Step 2: save summary and raw json\n const summary = generateCampaignSummary(campaign);\n const summaryFile = path.resolve(campaignDirs.info, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, campaign, 'campaign summary');\n \n // Campaign / creator raw data might not be complete. Fetch directly from API.\n // Strictly speaking, we should check for 'error' in results, but since it's not going to be fatal we'll just skip it.\n const { json: fetchedCampaignAPIData } = await this.fetchCampaign(campaign.id, signal);\n const { json: fetchedCreatorAPIData } = campaign.creator ? await this.fetchUser(campaign.creator.id, signal) : { json: null };\n \n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n \n const campaignRawFile = path.resolve(campaignDirs.info, 'campaign-api.json');\n const saveCampaignRawResult = await this.fsHelper.writeTextFile(\n campaignRawFile, fetchedCampaignAPIData || campaign.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCampaignRawResult, campaign, 'campaign API data');\n \n if (campaign.creator) {\n const creatorRawFile = path.resolve(campaignDirs.info, 'creator-api.json');\n const saveCreatorRawResult = await this.fsHelper.writeTextFile(\n creatorRawFile, fetchedCreatorAPIData || campaign.creator.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCreatorRawResult, campaign.creator, 'creator API data');\n }\n \n this.emit('phaseEnd', { target: campaign, phase: 'saveInfo' });\n \n // Step 3: download campaign media items\n this.emit('phaseBegin', { target: campaign, phase: 'saveMedia' });\n const campaignMedia: Downloadable[] = [\n campaign.avatarImage,\n campaign.coverPhoto\n ];\n if (campaign.creator) {\n campaignMedia.push(\n campaign.creator.image,\n campaign.creator.thumbnail\n );\n }\n for (const reward of campaign.rewards) {\n if (reward.image) {\n campaignMedia.push(reward.image);\n }\n }\n batch = (await this.createDownloadTaskBatch(\n `Campaign #${campaign.id} (${campaign.name})`,\n signal,\n {\n target: campaignMedia,\n targetName: `campaign #${campaign.id} -> images`,\n dirs: {\n campaign: campaignDirs.root,\n main: campaignDirs.info,\n thumbnails: null\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n )).batch;\n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n batch.prestart();\n this.emit('phaseBegin', { target: campaign, phase: 'batchDownload', batch });\n await batch.start();\n await batch.destroy();\n this.emit('phaseEnd', { target: campaign, phase: 'batchDownload' });\n this.emit('phaseEnd', { target: campaign, phase: 'saveMedia' });\n \n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n\n // Step 4: save to DB\n await db.saveCampaign(campaign, new Date());\n \n // Done\n this.log('info', 'Done saving campaign info');\n this.emit('targetEnd', { target: campaign, isSkipped: false });\n \n resolve();\n })();\n });\n\n }\n\n protected log(level: LogLevel, ...msg: any[]) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n\n getConfig() {\n return deepFreeze(this.config);\n }\n\n protected checkAbortSignal(signal: AbortSignal | undefined, resolve: () => void) {\n if (signal && signal.aborted) {\n if (!this.#hasEmittedEndEventOnAbort) {\n this.emit('end', { aborted: true, message: 'Download aborted' });\n this.#hasEmittedEndEventOnAbort = true;\n }\n resolve();\n return true;\n }\n return false;\n }\n\n protected logWriteTextFileResult(result: WriteTextFileResult, target: {id: string}, targetName: string) {\n switch (result.status) {\n case 'completed':\n this.log('info', `Saved ${targetName} to \"${result.filePath}\"`);\n break;\n case 'skipped':\n this.log('warn', `Skipped saving ${targetName} #${target.id}: ${result.message}`);\n break;\n case 'error':\n this.log('error', `Error saving ${targetName} #${target.id} to \"${result.filePath}\":`, result.error);\n }\n }\n\n protected async commonFetchAPI(url: string, signal?: AbortSignal) {\n let json, requestAPIError: any;\n try {\n json = (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal })).json;\n }\n catch (error) {\n if (signal?.aborted) {\n this.log('warn', 'API request aborted');\n }\n else {\n this.log('error', `Error requesting API URL \"${url}\": `, error);\n requestAPIError = error;\n }\n json = null;\n }\n return { json, error: requestAPIError };\n }\n\n protected fetchCampaign(campaignId: string, signal?: AbortSignal) {\n const url = URLHelper.constructCampaignAPIURL(campaignId);\n this.log('debug', `Fetch campaign data from API URL \"${url}\"`);\n return this.commonFetchAPI(url, signal);\n }\n\n protected fetchUser(userId: string, signal?: AbortSignal) {\n const url = URLHelper.constructUserAPIURL(userId);\n this.log('debug', `Fetch user data from API URL \"${url}\"`);\n return this.commonFetchAPI(url, signal);\n }\n\n on<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;\n on(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(event, listener);\n }\n\n once<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;\n once(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.once(event, listener);\n }\n\n off<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;\n off(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(event, listener);\n }\n\n emit<T extends DownloaderEvent>(event: T, args: DownloaderEventPayloadOf<T>): boolean;\n emit(event: string | symbol, ...args: any[]): boolean {\n return super.emit(event, ...args);\n }\n}\n"]}
1
+ {"version":3,"file":"Downloader.js","sourceRoot":"","sources":["../../src/downloaders/Downloader.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport { EventEmitter } from 'events';\nimport deepFreeze from 'deep-freeze';\nimport Fetcher from '../utils/Fetcher.js';\nimport Bootstrap, { type DownloaderBootstrapData, type DownloaderType } from './Bootstrap.js';\nimport { type DownloaderInit, type DownloaderOptions, type FileExistsAction, getDownloaderInit } from './DownloaderOptions.js';\nimport { type DownloaderEvent, type DownloaderEventPayloadOf } from './DownloaderEvent.js';\nimport {type LogLevel} from '../utils/logging/Logger.js';\nimport Logger from '../utils/logging/Logger.js';\nimport { commonLog } from '../utils/logging/Logger.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport FSHelper, { type WriteTextFileResult } from '../utils/FSHelper.js';\nimport DownloadTaskBatch from './task/DownloadTaskBatch.js';\nimport { type IDownloadTask } from './task/DownloadTask.js';\nimport DownloadTaskFactory from './task/DownloadTaskFactory.js';\nimport FilenameFormatHelper from '../utils/FilenameFormatHelper.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { generateCampaignSummary } from './templates/CampaignInfo.js';\nimport path from 'path';\nimport URLHelper from '../utils/URLHelper.js';\nimport ffmpeg from 'fluent-ffmpeg';\nimport InnertubeLoader from '../utils/yt/InnertubeLoader.js';\nimport FFmpegDownloadTaskBase from './task/FFmpegDownloadTaskBase.js';\nimport ExternalDownloaderTask from './task/ExternalDownloaderTask.js';\nimport DB, { type DBInstance } from '../browse/db/index.js';\nimport PostParser from '../parsers/PostParser.js';\n\nexport type DownloaderConfig<T extends DownloaderType> =\n DownloaderInit &\n DownloaderBootstrapData<T>;\n\nexport interface DownloaderStartParams {\n signal?: AbortSignal;\n}\n\nexport type GetCampaignParams = \n string |\n { userId: string; vanity?: never, campaignId?: never; } |\n { userId?: never; vanity: string, campaignId?: never; } |\n { vanity?: never; userId?: never; campaignId: string; };\n\ninterface CreateDownloadTaskParams {\n target: Downloadable[];\n targetName: string;\n dirs: {\n campaign: string | null;\n main: string;\n thumbnails: string | null;\n };\n fileExistsAction: FileExistsAction;\n isAttachment?: boolean;\n}\n\nexport default abstract class Downloader<T extends DownloaderType> extends EventEmitter {\n\n abstract name: string;\n\n protected fetcher: Fetcher;\n protected fsHelper: FSHelper;\n protected config: DownloaderConfig<T>;\n protected logger?: Logger | null;\n protected db: () => Promise<DBInstance>;\n #dbPromise: Promise<DBInstance> | null;\n\n #hasEmittedEndEventOnAbort: boolean;\n\n constructor(config: DownloaderConfig<T>, db: () => Promise<DBInstance>, logger?: Logger | null) {\n super();\n\n this.config = config;\n this.fetcher = new Fetcher(this.config, logger);\n this.fsHelper = new FSHelper(this.config, logger);\n this.#dbPromise = null;\n this.db = async () => {\n if (!this.#dbPromise) {\n this.#dbPromise = db();\n }\n return this.#dbPromise;\n }\n this.logger = logger;\n\n if (this.config.pathToFFmpeg) {\n ffmpeg.setFfmpegPath(this.config.pathToFFmpeg);\n }\n\n InnertubeLoader.setLogger(this.logger);\n if (this.config.pathToYouTubeCredentials) {\n InnertubeLoader.setCredentialsFile(this.config.pathToYouTubeCredentials);\n }\n\n this.#hasEmittedEndEventOnAbort = false;\n }\n\n protected createDownloadTaskBatch(\n name: string,\n signal?: AbortSignal,\n ...createTasks: Array<CreateDownloadTaskParams | null>\n ): Promise<{ batch: DownloadTaskBatch; errorCount: number; }> {\n\n const __getDownloadIdString = (task: IDownloadTask, batch: DownloadTaskBatch) => {\n let result = `#${batch.id}.${task.id}`;\n if (task.retryCount > 0) {\n result += `-r${task.retryCount}`;\n }\n return result;\n };\n\n const batch = new DownloadTaskBatch({\n name,\n fetcher: this.fetcher,\n limiter: this.config.request,\n logger: this.logger\n });\n\n batch.on('taskStart', ({task}) => {\n const retryOrBeginStr = task.retryCount > 0 ? 'retry' : 'begin';\n const isExternal = task instanceof ExternalDownloaderTask;\n const destStr = isExternal ? ' -> Unknown destination (external process)' : task.resolvedDestFilename ? ` -> ${task.resolvedDestFilename}` : '';\n this.log('info', `Download ${retryOrBeginStr} (${__getDownloadIdString(task, batch)}): [type: ${task.srcEntity.type}; ID: #${task.srcEntity.id}]${destStr}`);\n if (task instanceof FFmpegDownloadTaskBase) {\n const retryOrBeginStr = task.retryCount > 0 ? 'Retry' : 'Begin';\n this.log('info', `${retryOrBeginStr} FFmpeg task (${__getDownloadIdString(task, batch)}): ${task.commandLine}`);\n }\n });\n\n batch.on('taskComplete', ({task}) => {\n const isExternal = task instanceof ExternalDownloaderTask;\n const destStr = isExternal ? ': Unknown destination (external process)' : task.resolvedDestPath ? `: \"${task.resolvedDestPath}\"` : '';\n this.log('info', `Download complete (${__getDownloadIdString(task, batch)})${destStr}`);\n });\n\n batch.on('taskError', ({error, willRetry}) => {\n const { task, cause, message } = error;\n const retryStr = willRetry ? '- will retry' : '';\n this.log('error', `Download error (${__getDownloadIdString(task, batch)}):`, cause || message, `(${task.src})`, retryStr);\n });\n\n batch.on('taskAbort', ({task}) => {\n this.log('warn', `Download aborted (${__getDownloadIdString(task, batch)})`);\n });\n\n batch.on('taskSkip', ({task, reason}) => {\n this.log('warn', `Download skipped (${__getDownloadIdString(task, batch)}): ${reason.message}`);\n });\n\n batch.on('taskSpawn', ({origin, spawn}) => {\n this.log('info', `Download spawned: #${batch.id}.${origin.id} -> #${batch.id}.${spawn.id}`);\n });\n\n /**\n * Uncomment this block to log download progress\n\n batch.on('taskProgress', ({task, progress}) => {\n if (progress) {\n if (progress.length) {\n this.log('info', `Download progress (${__getDownloadIdString(task, batch)}): ${progress.lengthDownloaded} / ${progress.length} ${progress.lengthUnit}s / ${progress.percent}% (${progress.speed} kB/s)`,);\n }\n else {\n this.log('info', `Download progress (${__getDownloadIdString(task, batch)}): ${progress.lengthDownloaded} / ? ${progress.lengthUnit}s (${progress.speed} kB/s)`,);\n }\n }\n else {\n this.log('warn', `Download progress not available (${__getDownloadIdString(task, batch)})`);\n }\n });\n\n */\n\n batch.on('complete', () => {\n const total = batch.getTasks().length;\n const completed = batch.getTasks('completed').length;\n const error = batch.getTasks('error').length;\n const aborted = batch.getTasks('aborted').length;\n const skipped = batch.getTasks('skipped').length;\n const counts = [\n `${total} downloads`,\n `${completed} completed`,\n `${error} errors`,\n `${skipped} skipped`,\n `${aborted} aborted`\n ].join('; ');\n this.log('info', `Download batch complete (#${batch.id}): ${counts}`);\n });\n\n return this.addToDownloadTaskBatch(batch, signal, ...createTasks);\n }\n\n protected async addToDownloadTaskBatch(\n batch: DownloadTaskBatch,\n signal?: AbortSignal,\n ...createTasks: Array<CreateDownloadTaskParams | null>\n ) {\n let failedCreateTaskCount = 0;\n for (const task of createTasks) {\n if (!task) {\n continue;\n }\n const { target, targetName, dirs } = task;\n this.log('info', `Create download tasks for ${targetName}`);\n if (task.target.length === 0) {\n this.log('warn', `No items in ${targetName}`);\n continue;\n }\n let ensureDirs: string[] = [];\n for (const tt of target) {\n try {\n const tasks = await DownloadTaskFactory.createFromDownloadable({\n config: this.config,\n dirs,\n item: tt,\n fetcher: this.fetcher,\n fileExistsAction: task.fileExistsAction,\n isAttachment: task.isAttachment,\n limiter: batch.limiter,\n signal,\n logger: this.logger\n });\n\n if (signal?.aborted) {\n return { batch, errorCount: failedCreateTaskCount };\n }\n\n // Filter out tasks that are DOA (errors that occurred in DownloadTask.create())\n for (const task of tasks) {\n if (task.doa) {\n this.log('error', `Failed to create download task for item #${tt.id} in ${targetName}:`, task.doa.msg, task.doa.cause);\n failedCreateTaskCount++;\n }\n }\n const createdTasks = tasks.filter((task) => !task.doa);\n batch.addTasks(createdTasks);\n ensureDirs = createdTasks.reduce<string[]>((result, task) => {\n const dir = task.resolvedDestPath ? path.dirname(task.resolvedDestPath) : null;\n if (dir && !result.includes(dir)) {\n result.push(dir);\n }\n return result;\n }, ensureDirs);\n }\n catch (error) {\n if (signal?.aborted) {\n this.log('warn', 'Operation aborted');\n return { batch, errorCount: failedCreateTaskCount };\n }\n this.log('error', `Failed to create download task(s) for item #${tt.id} in ${targetName}:`, error);\n failedCreateTaskCount++;\n }\n }\n for (const dir of ensureDirs) {\n this.fsHelper.createDir(dir);\n }\n }\n if (failedCreateTaskCount > 0) {\n this.log('warn', `${failedCreateTaskCount} items could not be processed for downloading`);\n }\n return { batch, errorCount: failedCreateTaskCount };\n }\n\n abstract start(params: DownloaderStartParams): Promise<void>;\n\n static async getInstance(url: string, options?: DownloaderOptions) {\n const bootstrap = Bootstrap.getDownloaderBootstrapDataByURL(url);\n if (!bootstrap) {\n throw Error('Could not determine downloader type from URL');\n }\n this.#validateOptions(options);\n\n const config = {\n ...bootstrap,\n ...getDownloaderInit(options)\n };\n const logger = options?.logger;\n const fsHelper = new FSHelper(config, logger);\n const db = () => DB.getInstance(fsHelper.getDBFilePath(), config.dryRun, logger);\n \n switch (config.type) {\n case 'product': {\n const ProductDownloader = (await import('./ProductDownloader.js')).default;\n return new ProductDownloader(config, db, logger);\n }\n case 'post': {\n const PostDownloader = (await import('./PostDownloader.js')).default;\n return new PostDownloader(config, db, logger);\n }\n }\n }\n\n static async getCampaign(\n params: GetCampaignParams,\n signal?: AbortSignal,\n options?: Logger | null | Pick<DownloaderOptions, 'cookie' | 'request' | 'logger'>\n ) {\n // Backwards compatibility - if 'params' is string type, then it is vanity\n let url: string;\n if (typeof params === 'string') {\n url = URLHelper.constructUserPostsURL({ vanity: params });\n }\n else if (params.userId || params.vanity) {\n url = URLHelper.constructUserPostsURL(params);\n }\n else {\n // Sole purpose of passing 'dummy' vanity is to create the PostDownloader instance\n url = URLHelper.constructUserPostsURL({ vanity: 'dummy' });\n }\n const downloader = await this.getInstance(\n url,\n options instanceof Logger ? { logger: options } : (options || undefined)\n );\n const PostDownloader = (await import('./PostDownloader.js')).default;\n if (downloader instanceof PostDownloader) {\n if (typeof params === 'object' && params.campaignId) {\n const { json } = await downloader.fetchCampaign(params.campaignId, signal);\n const parser = new PostParser(options instanceof Logger ? options : options?.logger);\n return parser.parseCampaignAPIResponse(json);\n }\n return downloader.__getCampaign(signal);\n }\n throw Error('Type mismatch: PostDownloader expected');\n }\n\n static #validateOptions(options?: DownloaderOptions) {\n if (!options) {\n return true;\n }\n\n // Check FFmpeg path exists\n if (options.pathToFFmpeg) {\n if (!fs.existsSync(options.pathToFFmpeg)) {\n throw Error(`Path to FFmpeg executable \"${options.pathToFFmpeg}\" does not exist`);\n }\n else if (!fs.lstatSync(options.pathToFFmpeg).isFile()) {\n throw Error(`Path to FFmpeg executable \"${options.pathToFFmpeg}\" does not point to a file`);\n }\n }\n\n // Check outDir is a directory\n if (options.outDir) {\n if (fs.existsSync(options.outDir) && !fs.lstatSync(options.outDir).isDirectory()) {\n throw Error(`\"${options.outDir}\" is not a directory`);\n }\n }\n\n // Check formats are valid\n const campaignDirNameFormat = options.dirNameFormat?.campaign;\n if (campaignDirNameFormat) {\n const validate = FilenameFormatHelper.validateCampaignDirNameFormat(campaignDirNameFormat);\n if (!validate.validateOK) {\n throw Error(`Campaign directory name format '${campaignDirNameFormat}' is invalid (matched against ${validate.regex})`);\n }\n }\n const contentDirNameFormat = options.dirNameFormat?.content;\n if (contentDirNameFormat) {\n const validate = FilenameFormatHelper.validateContentDirNameFormat(contentDirNameFormat);\n if (!validate.validateOK) {\n throw Error(`Content directory name format '${contentDirNameFormat}' is invalid (matched against ${validate.regex})`);\n }\n }\n const mediaFilenameFormat = options.filenameFormat?.media;\n if (mediaFilenameFormat) {\n const validate = FilenameFormatHelper.validateMediaFilenameFormat(mediaFilenameFormat);\n if (!validate.validateOK) {\n throw Error(`Media filename format '${mediaFilenameFormat}' is invalid (matched against ${validate.regex})`);\n }\n }\n\n return true;\n }\n\n protected saveCampaignInfo(campaign: Campaign | null, signal?: AbortSignal) {\n\n return new Promise<void>((resolve) => {\n void (async () => {\n const db = await this.db();\n if (!this.config.include.campaignInfo) {\n if (campaign) {\n await db.saveCampaign(campaign, new Date());\n }\n resolve();\n return;\n }\n \n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n \n let batch: DownloadTaskBatch | null = null;\n const abortHandler = () => {\n void (async () => {\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n \n if (!campaign) {\n this.log('warn', 'Skipped saving campaign info: target unavailable');\n resolve();\n return;\n }\n \n this.log('info', `Save campaign info #${campaign.id}`);\n this.emit('targetBegin', { target: campaign });\n this.emit('phaseBegin', { target: campaign, phase: 'saveInfo' });\n \n // Step 1: create campaign directories\n const campaignDirs = this.fsHelper.getCampaignDirs(campaign);\n this.log('debug', 'Campaign directories: ', campaignDirs);\n this.fsHelper.createDir(campaignDirs.root);\n this.fsHelper.createDir(campaignDirs.info);\n \n // Step 2: save summary and raw json\n const summary = generateCampaignSummary(campaign);\n const summaryFile = path.resolve(campaignDirs.info, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, campaign, 'campaign summary');\n \n // Campaign / creator raw data might not be complete. Fetch directly from API.\n // Strictly speaking, we should check for 'error' in results, but since it's not going to be fatal we'll just skip it.\n const { json: fetchedCampaignAPIData } = await this.fetchCampaign(campaign.id, signal);\n const { json: fetchedCreatorAPIData } = campaign.creator ? await this.fetchUser(campaign.creator.id, signal) : { json: null };\n \n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n \n const campaignRawFile = path.resolve(campaignDirs.info, 'campaign-api.json');\n const saveCampaignRawResult = await this.fsHelper.writeTextFile(\n campaignRawFile, fetchedCampaignAPIData || campaign.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCampaignRawResult, campaign, 'campaign API data');\n \n if (campaign.creator) {\n const creatorRawFile = path.resolve(campaignDirs.info, 'creator-api.json');\n const saveCreatorRawResult = await this.fsHelper.writeTextFile(\n creatorRawFile, fetchedCreatorAPIData || campaign.creator.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCreatorRawResult, campaign.creator, 'creator API data');\n }\n \n this.emit('phaseEnd', { target: campaign, phase: 'saveInfo' });\n \n // Step 3: download campaign media items\n this.emit('phaseBegin', { target: campaign, phase: 'saveMedia' });\n const campaignMedia: Downloadable[] = [\n campaign.avatarImage,\n campaign.coverPhoto\n ];\n if (campaign.creator) {\n campaignMedia.push(\n campaign.creator.image,\n campaign.creator.thumbnail\n );\n }\n for (const reward of campaign.rewards) {\n if (reward.image) {\n campaignMedia.push(reward.image);\n }\n }\n batch = (await this.createDownloadTaskBatch(\n `Campaign #${campaign.id} (${campaign.name})`,\n signal,\n {\n target: campaignMedia,\n targetName: `campaign #${campaign.id} -> images`,\n dirs: {\n campaign: campaignDirs.root,\n main: campaignDirs.info,\n thumbnails: null\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n )).batch;\n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n batch.prestart();\n this.emit('phaseBegin', { target: campaign, phase: 'batchDownload', batch });\n await batch.start();\n await batch.destroy();\n this.emit('phaseEnd', { target: campaign, phase: 'batchDownload' });\n this.emit('phaseEnd', { target: campaign, phase: 'saveMedia' });\n \n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n if (this.checkAbortSignal(signal, resolve)) {\n return;\n }\n\n // Step 4: save to DB\n await db.saveCampaign(campaign, new Date());\n \n // Done\n this.log('info', 'Done saving campaign info');\n this.emit('targetEnd', { target: campaign, isSkipped: false });\n \n resolve();\n })();\n });\n\n }\n\n protected log(level: LogLevel, ...msg: any[]) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n\n getConfig() {\n return deepFreeze(this.config);\n }\n\n protected checkAbortSignal(signal: AbortSignal | undefined, resolve: () => void) {\n if (signal && signal.aborted) {\n if (!this.#hasEmittedEndEventOnAbort) {\n this.emit('end', { aborted: true, message: 'Download aborted' });\n this.#hasEmittedEndEventOnAbort = true;\n }\n resolve();\n return true;\n }\n return false;\n }\n\n protected logWriteTextFileResult(result: WriteTextFileResult, target: {id: string}, targetName: string) {\n switch (result.status) {\n case 'completed':\n this.log('info', `Saved ${targetName} to \"${result.filePath}\"`);\n break;\n case 'skipped':\n this.log('warn', `Skipped saving ${targetName} #${target.id}: ${result.message}`);\n break;\n case 'error':\n this.log('error', `Error saving ${targetName} #${target.id} to \"${result.filePath}\":`, result.error);\n }\n }\n\n protected async commonFetchAPI(url: string, signal?: AbortSignal) {\n let json, requestAPIError: any;\n try {\n json = (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal })).json;\n }\n catch (error) {\n if (signal?.aborted) {\n this.log('warn', 'API request aborted');\n }\n else {\n this.log('error', `Error requesting API URL \"${url}\": `, error);\n requestAPIError = error;\n }\n json = null;\n }\n return { json, error: requestAPIError };\n }\n\n protected fetchCampaign(campaignId: string, signal?: AbortSignal) {\n const url = URLHelper.constructCampaignAPIURL(campaignId);\n this.log('debug', `Fetch campaign data from API URL \"${url}\"`);\n return this.commonFetchAPI(url, signal);\n }\n\n protected fetchUser(userId: string, signal?: AbortSignal) {\n const url = URLHelper.constructUserAPIURL(userId);\n this.log('debug', `Fetch user data from API URL \"${url}\"`);\n return this.commonFetchAPI(url, signal);\n }\n\n on<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;\n on(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(event, listener);\n }\n\n once<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;\n once(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.once(event, listener);\n }\n\n off<T extends DownloaderEvent>(event: T, listener: (args: DownloaderEventPayloadOf<T>) => void): this;\n off(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(event, listener);\n }\n\n emit<T extends DownloaderEvent>(event: T, args: DownloaderEventPayloadOf<T>): boolean;\n emit(event: string | symbol, ...args: any[]): boolean {\n return super.emit(event, ...args);\n }\n}\n"]}
@@ -60,7 +60,6 @@ export default class FSHelper {
60
60
  filePath: string;
61
61
  preceding: string;
62
62
  };
63
- static sanitizeFilePath(filePath: string): string;
64
63
  static createFilename(parts: {
65
64
  name: string;
66
65
  suffix?: string;
@@ -166,16 +166,6 @@ export default class FSHelper {
166
166
  preceding: path.resolve(dir, currentLargestIncFilename)
167
167
  };
168
168
  }
169
- static sanitizeFilePath(filePath) {
170
- const splitted = filePath.split(path.sep);
171
- const sanitized = splitted.map((s) => {
172
- if (!s || s === '.') {
173
- return s;
174
- }
175
- return this.sanitizeFilename(s);
176
- });
177
- return sanitized.join(path.sep);
178
- }
179
169
  static createFilename(parts) {
180
170
  const { name, suffix = '', ext = '' } = parts;
181
171
  const sanitizedName = _sanitizeFilename(name);
@@ -1 +1 @@
1
- {"version":3,"file":"FSHelper.js","sourceRoot":"","sources":["../../src/utils/FSHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\nimport fse from 'fs-extra';\nimport makeDir from 'make-dir';\nimport _sanitizeFilename from 'sanitize-filename';\nimport escapeStringRegexp from 'escape-string-regexp';\nimport hasha from 'hasha';\nimport { type Product } from '../entities/Product.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type DownloaderConfig } from '../downloaders/Downloader.js';\nimport FilenameFormatHelper from './FilenameFormatHelper.js';\nimport { type Post } from '../entities/Post.js';\nimport { type FileExistsAction } from '../downloaders/DownloaderOptions.js';\nimport {type LogLevel} from './logging/Logger.js';\nimport type Logger from './logging/Logger.js';\nimport { commonLog } from './logging/Logger.js';\n\nconst CAMPAIGN_FIXED_DIR_NAMES = {\n INFO: 'campaign_info'\n};\n\nconst PRODUCT_FIXED_DIR_NAMES = {\n SHOP: 'shop',\n INFO: 'product_info',\n CONTENT_MEDIA: 'content_media',\n PREVIEW_MEDIA: 'preview_media',\n THUMBNAILS: '.thumbnails'\n};\n\nconst POST_FIXED_DIR_NAMES = {\n POSTS: 'posts',\n INFO: 'post_info',\n AUDIO: 'audio',\n VIDEO: 'video',\n IMAGES: 'images',\n AUDIO_PREVIEW: 'audio_preview',\n VIDEO_PREVIEW: 'video_preview',\n IMAGE_PREVIEWS: 'image_previews',\n ATTACHMENTS: 'attachments',\n EMBED: 'embed',\n THUMBNAILS: '.thumbnails'\n};\n\nexport interface PostDirectories {\n root: string;\n info: string;\n audio: string;\n video: string;\n images: string;\n audioPreview: string;\n videoPreview: string;\n imagePreviews: string;\n attachments: string;\n embed: string;\n thumbnails: string;\n statusCache: string;\n}\n\nconst INTERNAL_DATA_DIR_NAME = '.patreon-dl';\nconst DB_FILENAME = 'db.sqlite';\n\nexport type WriteTextFileResult = {\n status: 'completed';\n filePath: string;\n} | {\n status: 'skipped';\n message: string;\n} | {\n status: 'error';\n filePath: string;\n error: any\n};\n\nexport default class FSHelper {\n\n name = 'FSHelper';\n\n protected config: DownloaderConfig<any>;\n protected logger?: Logger | null;\n\n constructor(config: DownloaderConfig<any>, logger?: Logger | null) {\n this.config = config;\n this.logger = logger;\n }\n\n getDBFilePath() {\n const dbDir = this.createDir(path.resolve(this.config.outDir, INTERNAL_DATA_DIR_NAME));\n return path.resolve(dbDir, DB_FILENAME);\n }\n\n getCampaignDirs(campaign: Campaign) {\n const dirName = FilenameFormatHelper.getCampaignDirName(campaign, this.config.dirNameFormat.campaign);\n const root = path.resolve(this.config.outDir, dirName);\n return {\n root,\n info: path.resolve(root, CAMPAIGN_FIXED_DIR_NAMES.INFO)\n };\n }\n\n getPostDirs(post: Post): PostDirectories {\n const dirName = FilenameFormatHelper.getContentDirName(post, this.config.dirNameFormat.content);\n let postRootPath: string;\n let statusCachePath: string;\n if (post.campaign) {\n const campaignRootDir = this.getCampaignDirs(post.campaign).root;\n const postsDir = this.createDir(path.resolve(campaignRootDir, POST_FIXED_DIR_NAMES.POSTS));\n postRootPath = path.resolve(postsDir, dirName);\n statusCachePath = path.resolve(campaignRootDir, INTERNAL_DATA_DIR_NAME);\n }\n else {\n postRootPath = path.resolve(this.config.outDir, dirName);\n statusCachePath = path.resolve(postRootPath, INTERNAL_DATA_DIR_NAME);\n }\n return {\n root: postRootPath,\n info: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.INFO),\n audio: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.AUDIO),\n video: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.VIDEO),\n images: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.IMAGES),\n audioPreview: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.AUDIO_PREVIEW),\n videoPreview: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.VIDEO_PREVIEW),\n imagePreviews: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.IMAGE_PREVIEWS),\n attachments: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.ATTACHMENTS),\n embed: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.EMBED),\n thumbnails: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.THUMBNAILS),\n statusCache: statusCachePath\n };\n }\n\n getProductDirs(product: Product) {\n const dirName = FilenameFormatHelper.getContentDirName(product, this.config.dirNameFormat.content);\n let productRootPath: string;\n let statusCachePath: string;\n if (product.campaign) {\n const campaignRootDir = this.getCampaignDirs(product.campaign).root;\n const shopDir = this.createDir(path.resolve(campaignRootDir, PRODUCT_FIXED_DIR_NAMES.SHOP));\n productRootPath = path.resolve(shopDir, dirName);\n statusCachePath = path.resolve(campaignRootDir, INTERNAL_DATA_DIR_NAME);\n }\n else {\n productRootPath = path.resolve(this.config.outDir, dirName);\n statusCachePath = path.resolve(productRootPath, INTERNAL_DATA_DIR_NAME);\n }\n return {\n root: productRootPath,\n info: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.INFO),\n contentMedia: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.CONTENT_MEDIA),\n previewMedia: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.PREVIEW_MEDIA),\n thumbnails: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.THUMBNAILS),\n statusCache: statusCachePath\n };\n }\n\n createDir(dir: string, parents = true) {\n if (fse.existsSync(dir)) {\n if (!fse.lstatSync(dir).isDirectory()) {\n throw Error(`\"${dir}\" exists but is not a directory`);\n }\n return dir;\n }\n\n if (this.config.dryRun) {\n this.log('debug', `(dry-run) Create directory \"${dir}\"`);\n return dir;\n }\n\n return FSHelper.createDir(dir, parents);\n }\n\n static createDir(dir: string, parents = true) {\n if (!parents) {\n fse.mkdirSync(dir);\n return dir;\n }\n return makeDir.sync(dir);\n }\n\n checkFileExistsAndIncrement(file: string) {\n const { name, base, dir, ext } = path.parse(file);\n // Regex to match filename with increment: 'filename (number).ext'\n //Const regex = new RegExp(`^${escapeStringRegexp(name)} \\\\((\\\\d+?)\\\\)${escapeStringRegexp(ext)}$`, 'g');\n const regex = new RegExp(`(.+) \\\\((\\\\d+?)\\\\)${escapeStringRegexp(ext)}$`, 'g');\n let currentLargestInc = -1;\n let currentLargestIncFilename = base;\n const files = this.readdir(dir);\n for (const _file of files) {\n const match = regex.exec(_file);\n if (match && match[1] !== undefined) {\n const filename = match[0];\n const num = Number(match[1]);\n if (\n (filename === base ||\n (filename.length >= (255 - match[1].length - 1) && base.length >= 255 && base.startsWith(filename))) &&\n num > currentLargestInc\n ) {\n currentLargestInc = Number(match[1]);\n currentLargestIncFilename = _file;\n }\n }\n regex.lastIndex = 0;\n }\n\n if (currentLargestInc === -1) {\n if (!fse.existsSync(file)) {\n const fileParts = path.parse(file);\n return {\n filename: fileParts.base,\n filePath: path.resolve(file),\n preceding: null\n };\n }\n currentLargestInc = 0;\n }\n\n const _filename = FSHelper.createFilename({\n name,\n suffix: ` (${currentLargestInc + 1})`,\n ext\n });\n const _filePath = path.resolve(dir, _filename);\n\n return {\n filename: _filename,\n filePath: _filePath,\n preceding: path.resolve(dir, currentLargestIncFilename)\n };\n }\n\n static sanitizeFilePath(filePath: string) {\n const splitted = filePath.split(path.sep);\n const sanitized = splitted.map((s) => {\n if (!s || s === '.') {\n return s;\n }\n return this.sanitizeFilename(s);\n });\n return sanitized.join(path.sep);\n }\n\n static createFilename(parts: { name: string, suffix?: string, ext?: string }) {\n const { name, suffix = '', ext = '' } = parts;\n const sanitizedName = _sanitizeFilename(name);\n const sanitizedSuffix = _sanitizeFilename(suffix);\n const sanitizedExt = _sanitizeFilename(ext);\n const useName = sanitizedName.substring(0, 255 - sanitizedSuffix.length - sanitizedExt.length);\n return [ useName, sanitizedSuffix, sanitizedExt ].join('');\n }\n\n static createTmpFilePath(filePath: string, prefix = '') {\n const { dir, base } = path.parse(filePath);\n const tmpFilename = this.createFilename({ name: `${prefix ? `${prefix}-` : ''}${base}`, ext: '.part' });\n return path.resolve(dir, tmpFilename);\n }\n\n static sanitizeFilename(filename: string) {\n const { name, ext } = path.parse(filename);\n return this.createFilename({ name, ext });\n }\n\n async compareFiles(f1: string, f2: string) {\n if (this.config.dryRun) {\n this.log('debug', '(dry-run) Compare files: return true');\n return true;\n }\n const [ checksum1, checksum2 ] = await Promise.all([\n hasha.fromFile(f1, { algorithm: 'md5' }),\n hasha.fromFile(f2, { algorithm: 'md5' })\n ]);\n return checksum1 === checksum2;\n }\n\n async writeTextFile(file: string, data: string | object, fileExistsAction: FileExistsAction): Promise<WriteTextFileResult> {\n const resolvedFile = {\n original: file,\n final: file,\n incrementedFrom: null as string | null\n };\n try {\n if (fse.existsSync(file)) {\n if (fileExistsAction === 'skip') {\n return {\n status: 'skipped',\n message: `Destination file exists (${file})`\n };\n }\n if (fileExistsAction === 'saveAsCopy' || fileExistsAction === 'saveAsCopyIfNewer') {\n const checked = this.checkFileExistsAndIncrement(file);\n resolvedFile.final = checked.filePath;\n resolvedFile.incrementedFrom = checked.preceding;\n }\n }\n const tmpFile = FSHelper.createTmpFilePath(resolvedFile.final);\n if (typeof data === 'object') {\n this.writeJSON(tmpFile, data);\n }\n else {\n this.writeFile(tmpFile, data);\n }\n if (fileExistsAction === 'saveAsCopyIfNewer' &&\n resolvedFile.incrementedFrom && fse.existsSync(resolvedFile.incrementedFrom)) {\n\n const filesMatch = await this.compareFiles(tmpFile, resolvedFile.incrementedFrom);\n if (filesMatch) {\n this.unlink(tmpFile);\n return {\n status: 'skipped',\n message: `Destination file exists with same content (${resolvedFile.incrementedFrom})`\n };\n }\n }\n\n this.rename(tmpFile, resolvedFile.final);\n return {\n status: 'completed',\n filePath: resolvedFile.final\n };\n }\n catch (error) {\n return {\n status: 'error',\n filePath: resolvedFile.final,\n error\n };\n }\n }\n\n changeFilePathExtension(filePath: string, extension: `.${string}`) {\n const filePathParts = {\n ...path.parse(filePath),\n base: undefined,\n ext: extension\n };\n return path.format(filePathParts);\n }\n\n readdir(dir: string) {\n if (!this.config.dryRun || fse.existsSync(dir)) {\n return fse.readdirSync(dir);\n }\n return [];\n }\n\n writeFile(file: string, data: string) {\n if (!this.config.dryRun) {\n FSHelper.writeFile(file, data);\n }\n else {\n this.log('debug', `(dry-run) Write text \"${file}\"`);\n }\n }\n\n static writeFile(file: string, data: string) {\n fse.writeFileSync(file, data);\n }\n\n writeJSON(file: string, data: any) {\n if (!this.config.dryRun) {\n FSHelper.writeJSON(file, data);\n }\n else {\n this.log('debug', `(dry-run) Write JSON \"${file}\"`);\n }\n }\n\n static writeJSON(file: string, data: any) {\n fse.writeJsonSync(file, data, { spaces: 2 });\n }\n\n unlink(file: string) {\n if (!this.config.dryRun) {\n FSHelper.unlink(file);\n }\n else {\n this.log('debug', `(dry-run) Unlink \"${file}\"`);\n }\n }\n\n static unlink(file: string) {\n fse.unlinkSync(file);\n }\n\n rename(oldPath: string, newPath: string) {\n if (!this.config.dryRun) {\n FSHelper.rename(oldPath, newPath);\n }\n else {\n this.log('debug', `(dry-run) Rename \"${oldPath}\" -> \"${newPath}\"`);\n }\n }\n\n static rename(oldPath: string, newPath: string) {\n fse.renameSync(oldPath, newPath);\n }\n\n protected log(level: LogLevel, ...msg: Array<any>) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n}\n"]}
1
+ {"version":3,"file":"FSHelper.js","sourceRoot":"","sources":["../../src/utils/FSHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\nimport fse from 'fs-extra';\nimport makeDir from 'make-dir';\nimport _sanitizeFilename from 'sanitize-filename';\nimport escapeStringRegexp from 'escape-string-regexp';\nimport hasha from 'hasha';\nimport { type Product } from '../entities/Product.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type DownloaderConfig } from '../downloaders/Downloader.js';\nimport FilenameFormatHelper from './FilenameFormatHelper.js';\nimport { type Post } from '../entities/Post.js';\nimport { type FileExistsAction } from '../downloaders/DownloaderOptions.js';\nimport {type LogLevel} from './logging/Logger.js';\nimport type Logger from './logging/Logger.js';\nimport { commonLog } from './logging/Logger.js';\n\nconst CAMPAIGN_FIXED_DIR_NAMES = {\n INFO: 'campaign_info'\n};\n\nconst PRODUCT_FIXED_DIR_NAMES = {\n SHOP: 'shop',\n INFO: 'product_info',\n CONTENT_MEDIA: 'content_media',\n PREVIEW_MEDIA: 'preview_media',\n THUMBNAILS: '.thumbnails'\n};\n\nconst POST_FIXED_DIR_NAMES = {\n POSTS: 'posts',\n INFO: 'post_info',\n AUDIO: 'audio',\n VIDEO: 'video',\n IMAGES: 'images',\n AUDIO_PREVIEW: 'audio_preview',\n VIDEO_PREVIEW: 'video_preview',\n IMAGE_PREVIEWS: 'image_previews',\n ATTACHMENTS: 'attachments',\n EMBED: 'embed',\n THUMBNAILS: '.thumbnails'\n};\n\nexport interface PostDirectories {\n root: string;\n info: string;\n audio: string;\n video: string;\n images: string;\n audioPreview: string;\n videoPreview: string;\n imagePreviews: string;\n attachments: string;\n embed: string;\n thumbnails: string;\n statusCache: string;\n}\n\nconst INTERNAL_DATA_DIR_NAME = '.patreon-dl';\nconst DB_FILENAME = 'db.sqlite';\n\nexport type WriteTextFileResult = {\n status: 'completed';\n filePath: string;\n} | {\n status: 'skipped';\n message: string;\n} | {\n status: 'error';\n filePath: string;\n error: any\n};\n\nexport default class FSHelper {\n\n name = 'FSHelper';\n\n protected config: DownloaderConfig<any>;\n protected logger?: Logger | null;\n\n constructor(config: DownloaderConfig<any>, logger?: Logger | null) {\n this.config = config;\n this.logger = logger;\n }\n\n getDBFilePath() {\n const dbDir = this.createDir(path.resolve(this.config.outDir, INTERNAL_DATA_DIR_NAME));\n return path.resolve(dbDir, DB_FILENAME);\n }\n\n getCampaignDirs(campaign: Campaign) {\n const dirName = FilenameFormatHelper.getCampaignDirName(campaign, this.config.dirNameFormat.campaign);\n const root = path.resolve(this.config.outDir, dirName);\n return {\n root,\n info: path.resolve(root, CAMPAIGN_FIXED_DIR_NAMES.INFO)\n };\n }\n\n getPostDirs(post: Post): PostDirectories {\n const dirName = FilenameFormatHelper.getContentDirName(post, this.config.dirNameFormat.content);\n let postRootPath: string;\n let statusCachePath: string;\n if (post.campaign) {\n const campaignRootDir = this.getCampaignDirs(post.campaign).root;\n const postsDir = this.createDir(path.resolve(campaignRootDir, POST_FIXED_DIR_NAMES.POSTS));\n postRootPath = path.resolve(postsDir, dirName);\n statusCachePath = path.resolve(campaignRootDir, INTERNAL_DATA_DIR_NAME);\n }\n else {\n postRootPath = path.resolve(this.config.outDir, dirName);\n statusCachePath = path.resolve(postRootPath, INTERNAL_DATA_DIR_NAME);\n }\n return {\n root: postRootPath,\n info: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.INFO),\n audio: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.AUDIO),\n video: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.VIDEO),\n images: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.IMAGES),\n audioPreview: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.AUDIO_PREVIEW),\n videoPreview: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.VIDEO_PREVIEW),\n imagePreviews: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.IMAGE_PREVIEWS),\n attachments: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.ATTACHMENTS),\n embed: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.EMBED),\n thumbnails: path.resolve(postRootPath, POST_FIXED_DIR_NAMES.THUMBNAILS),\n statusCache: statusCachePath\n };\n }\n\n getProductDirs(product: Product) {\n const dirName = FilenameFormatHelper.getContentDirName(product, this.config.dirNameFormat.content);\n let productRootPath: string;\n let statusCachePath: string;\n if (product.campaign) {\n const campaignRootDir = this.getCampaignDirs(product.campaign).root;\n const shopDir = this.createDir(path.resolve(campaignRootDir, PRODUCT_FIXED_DIR_NAMES.SHOP));\n productRootPath = path.resolve(shopDir, dirName);\n statusCachePath = path.resolve(campaignRootDir, INTERNAL_DATA_DIR_NAME);\n }\n else {\n productRootPath = path.resolve(this.config.outDir, dirName);\n statusCachePath = path.resolve(productRootPath, INTERNAL_DATA_DIR_NAME);\n }\n return {\n root: productRootPath,\n info: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.INFO),\n contentMedia: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.CONTENT_MEDIA),\n previewMedia: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.PREVIEW_MEDIA),\n thumbnails: path.resolve(productRootPath, PRODUCT_FIXED_DIR_NAMES.THUMBNAILS),\n statusCache: statusCachePath\n };\n }\n\n createDir(dir: string, parents = true) {\n if (fse.existsSync(dir)) {\n if (!fse.lstatSync(dir).isDirectory()) {\n throw Error(`\"${dir}\" exists but is not a directory`);\n }\n return dir;\n }\n\n if (this.config.dryRun) {\n this.log('debug', `(dry-run) Create directory \"${dir}\"`);\n return dir;\n }\n\n return FSHelper.createDir(dir, parents);\n }\n\n static createDir(dir: string, parents = true) {\n if (!parents) {\n fse.mkdirSync(dir);\n return dir;\n }\n return makeDir.sync(dir);\n }\n\n checkFileExistsAndIncrement(file: string) {\n const { name, base, dir, ext } = path.parse(file);\n // Regex to match filename with increment: 'filename (number).ext'\n //Const regex = new RegExp(`^${escapeStringRegexp(name)} \\\\((\\\\d+?)\\\\)${escapeStringRegexp(ext)}$`, 'g');\n const regex = new RegExp(`(.+) \\\\((\\\\d+?)\\\\)${escapeStringRegexp(ext)}$`, 'g');\n let currentLargestInc = -1;\n let currentLargestIncFilename = base;\n const files = this.readdir(dir);\n for (const _file of files) {\n const match = regex.exec(_file);\n if (match && match[1] !== undefined) {\n const filename = match[0];\n const num = Number(match[1]);\n if (\n (filename === base ||\n (filename.length >= (255 - match[1].length - 1) && base.length >= 255 && base.startsWith(filename))) &&\n num > currentLargestInc\n ) {\n currentLargestInc = Number(match[1]);\n currentLargestIncFilename = _file;\n }\n }\n regex.lastIndex = 0;\n }\n\n if (currentLargestInc === -1) {\n if (!fse.existsSync(file)) {\n const fileParts = path.parse(file);\n return {\n filename: fileParts.base,\n filePath: path.resolve(file),\n preceding: null\n };\n }\n currentLargestInc = 0;\n }\n\n const _filename = FSHelper.createFilename({\n name,\n suffix: ` (${currentLargestInc + 1})`,\n ext\n });\n const _filePath = path.resolve(dir, _filename);\n\n return {\n filename: _filename,\n filePath: _filePath,\n preceding: path.resolve(dir, currentLargestIncFilename)\n };\n }\n\n static createFilename(parts: { name: string, suffix?: string, ext?: string }) {\n const { name, suffix = '', ext = '' } = parts;\n const sanitizedName = _sanitizeFilename(name);\n const sanitizedSuffix = _sanitizeFilename(suffix);\n const sanitizedExt = _sanitizeFilename(ext);\n const useName = sanitizedName.substring(0, 255 - sanitizedSuffix.length - sanitizedExt.length);\n return [ useName, sanitizedSuffix, sanitizedExt ].join('');\n }\n\n static createTmpFilePath(filePath: string, prefix = '') {\n const { dir, base } = path.parse(filePath);\n const tmpFilename = this.createFilename({ name: `${prefix ? `${prefix}-` : ''}${base}`, ext: '.part' });\n return path.resolve(dir, tmpFilename);\n }\n\n static sanitizeFilename(filename: string) {\n const { name, ext } = path.parse(filename);\n return this.createFilename({ name, ext });\n }\n\n async compareFiles(f1: string, f2: string) {\n if (this.config.dryRun) {\n this.log('debug', '(dry-run) Compare files: return true');\n return true;\n }\n const [ checksum1, checksum2 ] = await Promise.all([\n hasha.fromFile(f1, { algorithm: 'md5' }),\n hasha.fromFile(f2, { algorithm: 'md5' })\n ]);\n return checksum1 === checksum2;\n }\n\n async writeTextFile(file: string, data: string | object, fileExistsAction: FileExistsAction): Promise<WriteTextFileResult> {\n const resolvedFile = {\n original: file,\n final: file,\n incrementedFrom: null as string | null\n };\n try {\n if (fse.existsSync(file)) {\n if (fileExistsAction === 'skip') {\n return {\n status: 'skipped',\n message: `Destination file exists (${file})`\n };\n }\n if (fileExistsAction === 'saveAsCopy' || fileExistsAction === 'saveAsCopyIfNewer') {\n const checked = this.checkFileExistsAndIncrement(file);\n resolvedFile.final = checked.filePath;\n resolvedFile.incrementedFrom = checked.preceding;\n }\n }\n const tmpFile = FSHelper.createTmpFilePath(resolvedFile.final);\n if (typeof data === 'object') {\n this.writeJSON(tmpFile, data);\n }\n else {\n this.writeFile(tmpFile, data);\n }\n if (fileExistsAction === 'saveAsCopyIfNewer' &&\n resolvedFile.incrementedFrom && fse.existsSync(resolvedFile.incrementedFrom)) {\n\n const filesMatch = await this.compareFiles(tmpFile, resolvedFile.incrementedFrom);\n if (filesMatch) {\n this.unlink(tmpFile);\n return {\n status: 'skipped',\n message: `Destination file exists with same content (${resolvedFile.incrementedFrom})`\n };\n }\n }\n\n this.rename(tmpFile, resolvedFile.final);\n return {\n status: 'completed',\n filePath: resolvedFile.final\n };\n }\n catch (error) {\n return {\n status: 'error',\n filePath: resolvedFile.final,\n error\n };\n }\n }\n\n changeFilePathExtension(filePath: string, extension: `.${string}`) {\n const filePathParts = {\n ...path.parse(filePath),\n base: undefined,\n ext: extension\n };\n return path.format(filePathParts);\n }\n\n readdir(dir: string) {\n if (!this.config.dryRun || fse.existsSync(dir)) {\n return fse.readdirSync(dir);\n }\n return [];\n }\n\n writeFile(file: string, data: string) {\n if (!this.config.dryRun) {\n FSHelper.writeFile(file, data);\n }\n else {\n this.log('debug', `(dry-run) Write text \"${file}\"`);\n }\n }\n\n static writeFile(file: string, data: string) {\n fse.writeFileSync(file, data);\n }\n\n writeJSON(file: string, data: any) {\n if (!this.config.dryRun) {\n FSHelper.writeJSON(file, data);\n }\n else {\n this.log('debug', `(dry-run) Write JSON \"${file}\"`);\n }\n }\n\n static writeJSON(file: string, data: any) {\n fse.writeJsonSync(file, data, { spaces: 2 });\n }\n\n unlink(file: string) {\n if (!this.config.dryRun) {\n FSHelper.unlink(file);\n }\n else {\n this.log('debug', `(dry-run) Unlink \"${file}\"`);\n }\n }\n\n static unlink(file: string) {\n fse.unlinkSync(file);\n }\n\n rename(oldPath: string, newPath: string) {\n if (!this.config.dryRun) {\n FSHelper.rename(oldPath, newPath);\n }\n else {\n this.log('debug', `(dry-run) Rename \"${oldPath}\" -> \"${newPath}\"`);\n }\n }\n\n static rename(oldPath: string, newPath: string) {\n fse.renameSync(oldPath, newPath);\n }\n\n protected log(level: LogLevel, ...msg: Array<any>) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n}\n"]}
@@ -119,7 +119,7 @@ _a = FileLogger, _FileLogger_fileExistsAction = new WeakMap(), _FileLogger_strea
119
119
  }
120
120
  return dateTimeFields.reduce((result, field) => {
121
121
  if (!result[field.name]) {
122
- result[field.name] = dateFormat(date, field.pattern);
122
+ result[field.name] = FSHelper.sanitizeFilename(dateFormat(date, field.pattern));
123
123
  }
124
124
  return result;
125
125
  }, addTo);
@@ -146,7 +146,7 @@ _a = FileLogger, _FileLogger_fileExistsAction = new WeakMap(), _FileLogger_strea
146
146
  'log.level': logLevel,
147
147
  ...allDTValues
148
148
  };
149
- const logDir = path.resolve(process.cwd(), FSHelper.sanitizeFilePath(Formatter.format(dirNameFormat, logDirDict).result));
149
+ const logDir = path.resolve(process.cwd(), Formatter.format(dirNameFormat, logDirDict).result);
150
150
  const filename = FSHelper.sanitizeFilename(Formatter.format(filenameFormat, logFilenameDict).result);
151
151
  const filePath = path.resolve(logDir, filename);
152
152
  const created = date;
@@ -157,7 +157,7 @@ _a = FileLogger, _FileLogger_fileExistsAction = new WeakMap(), _FileLogger_strea
157
157
  created
158
158
  };
159
159
  }, _FileLogger_getPathInfoForServerType = function _FileLogger_getPathInfoForServerType(params) {
160
- const filePath = path.resolve(process.cwd(), FSHelper.sanitizeFilePath(params.logFilePath));
160
+ const filePath = path.resolve(process.cwd(), params.logFilePath);
161
161
  const { dir: logDir, base: filename } = path.parse(filePath);
162
162
  return {
163
163
  logDir,
@@ -1 +1 @@
1
- {"version":3,"file":"FileLogger.js","sourceRoot":"","sources":["../../../src/utils/logging/FileLogger.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport dateFormat from 'dateformat';\nimport { type LogLevel } from '../../utils/logging/Logger.js';\nimport { type DeepRequired, pickDefined } from '../Misc.js';\nimport ConsoleLogger, { type ConsoleLoggerOptions } from './ConsoleLogger.js';\nimport Formatter from '../Formatter.js';\nimport path from 'path';\nimport FSHelper from '../FSHelper.js';\nimport { EOL } from 'os';\nimport { getDefaultDownloaderOutDir } from '../../downloaders/DownloaderOptions.js';\n\nexport enum FileLoggerType {\n Downloader = 'downloader',\n Server = 'server'\n};\n\nexport type FileLoggerOptions<T extends FileLoggerType> =\n ConsoleLoggerOptions & \n ( T extends FileLoggerType.Downloader ? DownloaderFileLoggerOptions\n : T extends FileLoggerType.Server ? ServerFileLoggerOptions\n : never\n );\n\nexport interface DownloaderFileLoggerOptions {\n init: DownloaderFileLoggerInit;\n logDir?: string;\n logFilename?: string;\n fileExistsAction?: 'append' | 'overwrite';\n}\n\nexport interface ServerFileLoggerOptions {\n logFilePath: string;\n fileExistsAction?: 'append' | 'overwrite';\n}\n\nexport type FileLoggerConfig<T extends FileLoggerType> =\n DeepRequired<FileLoggerOptions<T>> & {\n logDir: string;\n logFilename: string;\n logFilePath: string;\n created: Date;\n };\n\nexport type FileLoggerGetPathInfoParams<T extends FileLoggerType> =\n T extends FileLoggerType.Downloader ? Pick<FileLoggerOptions<T>, 'init' | 'logDir' | 'logFilename' | 'logLevel'>\n : T extends FileLoggerType.Server ? Pick<FileLoggerOptions<T>, 'logFilePath'>\n : never;\n\nconst DEFAULT_DOWNLOADER_LOGGER_CONFIG: Omit<FileLoggerConfig<FileLoggerType.Downloader>, 'init' | 'created'> = {\n enabled: true,\n logDir: '{out.dir}/logs/{target.url.path}',\n logFilename: '{datetime.yyyymmdd}-{log.level}.log',\n fileExistsAction: 'append',\n logFilePath: '',\n logLevel: 'info',\n include: {\n dateTime: true,\n level: true,\n originator: true,\n errorStack: false\n },\n dateTimeFormat: 'mmm dd HH:MM:ss',\n color: false\n};\n\nconst DEFAULT_SERVER_LOGGER_FILE_EXISTS_ACTION = 'append';\n\nexport interface DownloaderFileLoggerInit {\n targetURL: string;\n outDir?: string;\n date?: Date;\n}\n\nexport default class FileLogger<T extends FileLoggerType = FileLoggerType.Downloader> extends ConsoleLogger {\n\n protected config: FileLoggerConfig<T>;\n #fileExistsAction: FileLoggerConfig<T>['fileExistsAction'];\n #stream: fs.WriteStream | null;\n #firstRun: boolean;\n\n constructor(options: FileLoggerOptions<T>) {\n super(options);\n \n const defaultFileExistsAction = this.#isDownloaderOptions(options) ?\n DEFAULT_DOWNLOADER_LOGGER_CONFIG.fileExistsAction\n : DEFAULT_SERVER_LOGGER_FILE_EXISTS_ACTION;\n this.#fileExistsAction = options?.fileExistsAction || defaultFileExistsAction;\n this.#stream = null;\n this.#firstRun = true;\n this.config.color = pickDefined(options?.color, DEFAULT_DOWNLOADER_LOGGER_CONFIG.color);\n\n const pathInfo = this.#isDownloaderOptions(options) ?\n FileLogger.#getPathInfoForDownloaderType(options)\n : FileLogger.#getPathInfoForServerType(options);\n\n this.config.logDir = pathInfo.logDir;\n this.config.logFilename = pathInfo.filename;\n this.config.logFilePath = pathInfo.filePath;\n this.config.created = pathInfo.created;\n }\n\n static getPathInfo<T extends FileLoggerType>(\n type: T,\n params: FileLoggerGetPathInfoParams<T>\n ) {\n switch (type) {\n case FileLoggerType.Downloader:\n return this.#getPathInfoForDownloaderType(params as FileLoggerGetPathInfoParams<FileLoggerType.Downloader>);\n case FileLoggerType.Server:\n return this.#getPathInfoForServerType(params as FileLoggerGetPathInfoParams<FileLoggerType.Server>);\n }\n return undefined as never;\n }\n\n static #getPathInfoForDownloaderType(params: FileLoggerGetPathInfoParams<FileLoggerType.Downloader>) {\n const defaultLogDir = DEFAULT_DOWNLOADER_LOGGER_CONFIG.logDir.replaceAll('/', path.sep);\n const {\n date = new Date(),\n outDir = getDefaultDownloaderOutDir(),\n targetURL\n } = params.init;\n const {\n logDir: dirNameFormat = defaultLogDir,\n logFilename: filenameFormat = DEFAULT_DOWNLOADER_LOGGER_CONFIG.logFilename,\n logLevel = DEFAULT_DOWNLOADER_LOGGER_CONFIG.logLevel } = params;\n\n const __getDateTimeFieldValues = (format: string, addTo: Record<string, string>) => {\n const dateTimeRegex = /{(datetime\\.(.+?))}/g;\n const dateTimeFields: { name: string; pattern: string; }[] = [];\n let m;\n while ((m = dateTimeRegex.exec(format)) !== null) {\n dateTimeFields.push({\n name: m[1],\n pattern: m[2]\n });\n }\n return dateTimeFields.reduce<Record<string, string>>((result, field) => {\n if (!result[field.name]) {\n result[field.name] = dateFormat(date, field.pattern);\n }\n return result;\n }, addTo);\n };\n\n // Prepare variables for generating log dir and filenames\n let urlPath = new URL(targetURL).pathname.trim();\n while (urlPath.startsWith('/')) {\n urlPath = urlPath.slice(1);\n }\n while (urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, urlPath.length - 1);\n }\n urlPath = FSHelper.sanitizeFilename(urlPath.replaceAll('/', '_'));\n\n const logDirDTValues = __getDateTimeFieldValues(dirNameFormat, {});\n const allDTValues = __getDateTimeFieldValues(filenameFormat, logDirDTValues);\n\n // Pass to Formatter and get log dir and filename\n const logDirDict = {\n 'out.dir': outDir,\n 'target.url.path': urlPath,\n ...allDTValues\n };\n\n const logFilenameDict = {\n 'target.url.path': urlPath,\n 'log.level': logLevel,\n ...allDTValues\n };\n\n const logDir = path.resolve(\n process.cwd(),\n FSHelper.sanitizeFilePath(Formatter.format(dirNameFormat, logDirDict).result)\n );\n const filename = FSHelper.sanitizeFilename(Formatter.format(filenameFormat, logFilenameDict).result);\n const filePath = path.resolve(logDir, filename);\n const created = date;\n\n return {\n logDir,\n filename,\n filePath,\n created\n };\n }\n\n static #getPathInfoForServerType(params: FileLoggerGetPathInfoParams<FileLoggerType.Server>) {\n const filePath = path.resolve(\n process.cwd(),\n FSHelper.sanitizeFilePath(params.logFilePath)\n );\n const { dir: logDir, base: filename } = path.parse(filePath);\n return {\n logDir,\n filename,\n filePath,\n created: new Date()\n };\n }\n\n #getStream() {\n if (this.#stream) {\n return this.#stream;\n }\n // Ensure log directory exists\n FSHelper.createDir(this.config.logDir);\n\n // Create write stream\n let flags: 'a' | 'w';\n if (fs.existsSync(this.config.logFilePath) && (!this.#firstRun || this.#fileExistsAction === 'append')) {\n flags = 'a';\n }\n else {\n flags = 'w';\n }\n this.#stream = fs.createWriteStream(this.config.logFilePath, { flags, encoding: 'utf-8', autoClose: false });\n if (this.#firstRun) {\n const initDateTimeStr = dateFormat(this.config.created, 'mmm dd yyyy HH:MM:ss').toUpperCase();\n this.#stream.write(`${EOL}*************** LOG BEGIN ${initDateTimeStr} ***************${EOL}`);\n this.#firstRun = false;\n }\n return this.#stream;\n }\n\n #isDownloaderOptions(options: FileLoggerOptions<FileLoggerType>): options is FileLoggerOptions<FileLoggerType.Downloader> {\n return Reflect.has(options, 'init');\n }\n\n getConfig() {\n return this.config;\n }\n\n static getDefaultConfig() {\n const config = {\n ...DEFAULT_DOWNLOADER_LOGGER_CONFIG\n };\n config.logDir = config.logDir.replaceAll('/', path.sep);\n return config;\n }\n\n protected toOutput(_level: LogLevel, msg: string[]) {\n const stream = this.#getStream();\n stream.write(msg.join(' '));\n stream.write(EOL);\n }\n\n end(): Promise<void> {\n return new Promise((resolve) => {\n if (this.#stream) {\n this.#stream.once('finish', () => {\n this.#stream = null;\n resolve();\n });\n this.#stream.end();\n }\n else {\n resolve();\n }\n });\n }\n}\n"]}
1
+ {"version":3,"file":"FileLogger.js","sourceRoot":"","sources":["../../../src/utils/logging/FileLogger.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport dateFormat from 'dateformat';\nimport { type LogLevel } from '../../utils/logging/Logger.js';\nimport { type DeepRequired, pickDefined } from '../Misc.js';\nimport ConsoleLogger, { type ConsoleLoggerOptions } from './ConsoleLogger.js';\nimport Formatter from '../Formatter.js';\nimport path from 'path';\nimport FSHelper from '../FSHelper.js';\nimport { EOL } from 'os';\nimport { getDefaultDownloaderOutDir } from '../../downloaders/DownloaderOptions.js';\n\nexport enum FileLoggerType {\n Downloader = 'downloader',\n Server = 'server'\n};\n\nexport type FileLoggerOptions<T extends FileLoggerType> =\n ConsoleLoggerOptions & \n ( T extends FileLoggerType.Downloader ? DownloaderFileLoggerOptions\n : T extends FileLoggerType.Server ? ServerFileLoggerOptions\n : never\n );\n\nexport interface DownloaderFileLoggerOptions {\n init: DownloaderFileLoggerInit;\n logDir?: string;\n logFilename?: string;\n fileExistsAction?: 'append' | 'overwrite';\n}\n\nexport interface ServerFileLoggerOptions {\n logFilePath: string;\n fileExistsAction?: 'append' | 'overwrite';\n}\n\nexport type FileLoggerConfig<T extends FileLoggerType> =\n DeepRequired<FileLoggerOptions<T>> & {\n logDir: string;\n logFilename: string;\n logFilePath: string;\n created: Date;\n };\n\nexport type FileLoggerGetPathInfoParams<T extends FileLoggerType> =\n T extends FileLoggerType.Downloader ? Pick<FileLoggerOptions<T>, 'init' | 'logDir' | 'logFilename' | 'logLevel'>\n : T extends FileLoggerType.Server ? Pick<FileLoggerOptions<T>, 'logFilePath'>\n : never;\n\nconst DEFAULT_DOWNLOADER_LOGGER_CONFIG: Omit<FileLoggerConfig<FileLoggerType.Downloader>, 'init' | 'created'> = {\n enabled: true,\n logDir: '{out.dir}/logs/{target.url.path}',\n logFilename: '{datetime.yyyymmdd}-{log.level}.log',\n fileExistsAction: 'append',\n logFilePath: '',\n logLevel: 'info',\n include: {\n dateTime: true,\n level: true,\n originator: true,\n errorStack: false\n },\n dateTimeFormat: 'mmm dd HH:MM:ss',\n color: false\n};\n\nconst DEFAULT_SERVER_LOGGER_FILE_EXISTS_ACTION = 'append';\n\nexport interface DownloaderFileLoggerInit {\n targetURL: string;\n outDir?: string;\n date?: Date;\n}\n\nexport default class FileLogger<T extends FileLoggerType = FileLoggerType.Downloader> extends ConsoleLogger {\n\n protected config: FileLoggerConfig<T>;\n #fileExistsAction: FileLoggerConfig<T>['fileExistsAction'];\n #stream: fs.WriteStream | null;\n #firstRun: boolean;\n\n constructor(options: FileLoggerOptions<T>) {\n super(options);\n \n const defaultFileExistsAction = this.#isDownloaderOptions(options) ?\n DEFAULT_DOWNLOADER_LOGGER_CONFIG.fileExistsAction\n : DEFAULT_SERVER_LOGGER_FILE_EXISTS_ACTION;\n this.#fileExistsAction = options?.fileExistsAction || defaultFileExistsAction;\n this.#stream = null;\n this.#firstRun = true;\n this.config.color = pickDefined(options?.color, DEFAULT_DOWNLOADER_LOGGER_CONFIG.color);\n\n const pathInfo = this.#isDownloaderOptions(options) ?\n FileLogger.#getPathInfoForDownloaderType(options)\n : FileLogger.#getPathInfoForServerType(options);\n\n this.config.logDir = pathInfo.logDir;\n this.config.logFilename = pathInfo.filename;\n this.config.logFilePath = pathInfo.filePath;\n this.config.created = pathInfo.created;\n }\n\n static getPathInfo<T extends FileLoggerType>(\n type: T,\n params: FileLoggerGetPathInfoParams<T>\n ) {\n switch (type) {\n case FileLoggerType.Downloader:\n return this.#getPathInfoForDownloaderType(params as FileLoggerGetPathInfoParams<FileLoggerType.Downloader>);\n case FileLoggerType.Server:\n return this.#getPathInfoForServerType(params as FileLoggerGetPathInfoParams<FileLoggerType.Server>);\n }\n return undefined as never;\n }\n\n static #getPathInfoForDownloaderType(params: FileLoggerGetPathInfoParams<FileLoggerType.Downloader>) {\n const defaultLogDir = DEFAULT_DOWNLOADER_LOGGER_CONFIG.logDir.replaceAll('/', path.sep);\n const {\n date = new Date(),\n outDir = getDefaultDownloaderOutDir(),\n targetURL\n } = params.init;\n const {\n logDir: dirNameFormat = defaultLogDir,\n logFilename: filenameFormat = DEFAULT_DOWNLOADER_LOGGER_CONFIG.logFilename,\n logLevel = DEFAULT_DOWNLOADER_LOGGER_CONFIG.logLevel } = params;\n\n const __getDateTimeFieldValues = (format: string, addTo: Record<string, string>) => {\n const dateTimeRegex = /{(datetime\\.(.+?))}/g;\n const dateTimeFields: { name: string; pattern: string; }[] = [];\n let m;\n while ((m = dateTimeRegex.exec(format)) !== null) {\n dateTimeFields.push({\n name: m[1],\n pattern: m[2]\n });\n }\n return dateTimeFields.reduce<Record<string, string>>((result, field) => {\n if (!result[field.name]) {\n result[field.name] = FSHelper.sanitizeFilename(dateFormat(date, field.pattern));\n }\n return result;\n }, addTo);\n };\n\n // Prepare variables for generating log dir and filenames\n let urlPath = new URL(targetURL).pathname.trim();\n while (urlPath.startsWith('/')) {\n urlPath = urlPath.slice(1);\n }\n while (urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, urlPath.length - 1);\n }\n urlPath = FSHelper.sanitizeFilename(urlPath.replaceAll('/', '_'));\n\n const logDirDTValues = __getDateTimeFieldValues(dirNameFormat, {});\n const allDTValues = __getDateTimeFieldValues(filenameFormat, logDirDTValues);\n\n // Pass to Formatter and get log dir and filename\n const logDirDict = {\n 'out.dir': outDir,\n 'target.url.path': urlPath,\n ...allDTValues\n };\n\n const logFilenameDict = {\n 'target.url.path': urlPath,\n 'log.level': logLevel,\n ...allDTValues\n };\n\n const logDir = path.resolve(\n process.cwd(),\n Formatter.format(dirNameFormat, logDirDict).result\n );\n const filename = FSHelper.sanitizeFilename(Formatter.format(filenameFormat, logFilenameDict).result);\n const filePath = path.resolve(logDir, filename);\n const created = date;\n\n return {\n logDir,\n filename,\n filePath,\n created\n };\n }\n\n static #getPathInfoForServerType(params: FileLoggerGetPathInfoParams<FileLoggerType.Server>) {\n const filePath = path.resolve(\n process.cwd(),\n params.logFilePath\n );\n const { dir: logDir, base: filename } = path.parse(filePath);\n return {\n logDir,\n filename,\n filePath,\n created: new Date()\n };\n }\n\n #getStream() {\n if (this.#stream) {\n return this.#stream;\n }\n // Ensure log directory exists\n FSHelper.createDir(this.config.logDir);\n\n // Create write stream\n let flags: 'a' | 'w';\n if (fs.existsSync(this.config.logFilePath) && (!this.#firstRun || this.#fileExistsAction === 'append')) {\n flags = 'a';\n }\n else {\n flags = 'w';\n }\n this.#stream = fs.createWriteStream(this.config.logFilePath, { flags, encoding: 'utf-8', autoClose: false });\n if (this.#firstRun) {\n const initDateTimeStr = dateFormat(this.config.created, 'mmm dd yyyy HH:MM:ss').toUpperCase();\n this.#stream.write(`${EOL}*************** LOG BEGIN ${initDateTimeStr} ***************${EOL}`);\n this.#firstRun = false;\n }\n return this.#stream;\n }\n\n #isDownloaderOptions(options: FileLoggerOptions<FileLoggerType>): options is FileLoggerOptions<FileLoggerType.Downloader> {\n return Reflect.has(options, 'init');\n }\n\n getConfig() {\n return this.config;\n }\n\n static getDefaultConfig() {\n const config = {\n ...DEFAULT_DOWNLOADER_LOGGER_CONFIG\n };\n config.logDir = config.logDir.replaceAll('/', path.sep);\n return config;\n }\n\n protected toOutput(_level: LogLevel, msg: string[]) {\n const stream = this.#getStream();\n stream.write(msg.join(' '));\n stream.write(EOL);\n }\n\n end(): Promise<void> {\n return new Promise((resolve) => {\n if (this.#stream) {\n this.#stream.once('finish', () => {\n this.#stream = null;\n resolve();\n });\n this.#stream.end();\n }\n else {\n resolve();\n }\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patreon-dl",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "Patreon Downloader",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",