patreon-dl 3.8.0 → 3.9.0

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.
Files changed (44) hide show
  1. package/README.md +9 -209
  2. package/dist/browse/db/CampaignDBMixin.d.ts +3 -3
  3. package/dist/browse/db/ContentDBMixin.d.ts +13 -13
  4. package/dist/browse/db/ContentDBMixin.js +1 -1
  5. package/dist/browse/db/ContentDBMixin.js.map +1 -1
  6. package/dist/browse/db/MediaDBMixin.js +1 -1
  7. package/dist/browse/db/MediaDBMixin.js.map +1 -1
  8. package/dist/browse/db/index.d.ts +16 -16
  9. package/dist/browse/server/handler/CampaignAPIRequesthandler.js +5 -0
  10. package/dist/browse/server/handler/CampaignAPIRequesthandler.js.map +1 -1
  11. package/dist/browse/web/assets/index-CtjPL2rI.js +218 -0
  12. package/dist/browse/web/index.html +1 -1
  13. package/dist/cli/CLIOptions.js +6 -2
  14. package/dist/cli/CLIOptions.js.map +1 -1
  15. package/dist/cli/ConfigFileParser.js +1 -1
  16. package/dist/cli/ConfigFileParser.js.map +1 -1
  17. package/dist/downloaders/Downloader.js +1 -1
  18. package/dist/downloaders/Downloader.js.map +1 -1
  19. package/dist/downloaders/PostDownloader.js +5 -5
  20. package/dist/downloaders/PostDownloader.js.map +1 -1
  21. package/dist/downloaders/PostsFetcher.js +3 -3
  22. package/dist/downloaders/PostsFetcher.js.map +1 -1
  23. package/dist/downloaders/task/DownloadTask.js +11 -1
  24. package/dist/downloaders/task/DownloadTask.js.map +1 -1
  25. package/dist/entities/MediaItem.d.ts +1 -0
  26. package/dist/entities/MediaItem.js.map +1 -1
  27. package/dist/parsers/PageParser.js +4 -1
  28. package/dist/parsers/PageParser.js.map +1 -1
  29. package/dist/parsers/PostParser.d.ts +4 -1
  30. package/dist/parsers/PostParser.js +82 -5
  31. package/dist/parsers/PostParser.js.map +1 -1
  32. package/dist/utils/Fetcher.d.ts +1 -0
  33. package/dist/utils/Fetcher.js +5 -0
  34. package/dist/utils/Fetcher.js.map +1 -1
  35. package/dist/utils/FilenameFormatHelper.d.ts +1 -1
  36. package/dist/utils/FilenameFormatHelper.js +4 -1
  37. package/dist/utils/FilenameFormatHelper.js.map +1 -1
  38. package/dist/utils/Formatter.d.ts +1 -1
  39. package/dist/utils/Formatter.js +1 -1
  40. package/dist/utils/Formatter.js.map +1 -1
  41. package/dist/utils/logging/FileLogger.js +1 -0
  42. package/dist/utils/logging/FileLogger.js.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/browse/web/assets/index-CtZbx-Du.js +0 -218
@@ -1 +1 @@
1
- {"version":3,"file":"PostDownloader.js","sourceRoot":"","sources":["../../src/downloaders/PostDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import URLHelper from '../utils/URLHelper.js';\nimport Downloader, { type DownloaderConfig, type DownloaderStartParams } from './Downloader.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { type Downloadable, isYouTubeEmbed } from '../entities/Downloadable.js';\nimport StatusCache, { type StatusCacheValidationScope } from './cache/StatusCache.js';\nimport { generatePostEmbedSummary, generatePostSummary } from './templates/PostInfo.js';\nimport path from 'path';\nimport { TargetSkipReason } from './DownloaderEvent.js';\nimport DownloadTaskFactory from './task/DownloadTaskFactory.js';\nimport PostsFetcher from './PostsFetcher.js';\nimport CommentParser from '../parsers/CommentParser.js';\nimport { type Comment, type CommentList, type CommentReply, type CommentReplyList } from '../entities/Comment.js';\nimport { generatePostCommentsSummary } from './templates/CommentInfo.js';\nimport { type PostDirectories } from '../utils/FSHelper.js';\nimport { type DBInstance } from '../browse/db/index.js';\nimport { type AttachmentMediaItem } from '../entities/MediaItem.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { type DeepRequired } from '../utils/Misc.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport type DownloadTaskBatch from './task/DownloadTaskBatch.js';\nimport { generateCollectionSummary } from './templates/CollectionInfo.js';\nimport { IncludeCriteriaHelper } from './IncludeCriteriaHelper.js';\n\nexport interface PostDownloaderContext {\n skipSaveCampaign?: boolean;\n keepLoggerOpen?: boolean;\n keepDBOpen?: boolean;\n}\n\nexport default class PostDownloader extends Downloader<Post> {\n\n static version = '1.1.1';\n\n name = 'PostDownloader';\n\n #startPromise: Promise<void> | null = null;\n #context: DeepRequired<PostDownloaderContext>;\n\n constructor(\n config: DownloaderConfig<Post>,\n db: () => Promise<DBInstance>,\n logger?: Logger | null,\n context?: PostDownloaderContext\n ) {\n super(config, db, logger);\n this.#context = {\n skipSaveCampaign: context?.skipSaveCampaign ?? false,\n keepLoggerOpen: context?.keepLoggerOpen ?? false,\n keepDBOpen: context?.keepDBOpen ?? false\n };\n }\n\n doStart(params?: DownloaderStartParams): Promise<void> {\n if (this.#startPromise) {\n throw Error('Downloader already running');\n }\n this.#startPromise = this.#doStart(params)\n .finally(() => {\n this.#startPromise = null;\n });\n return this.#startPromise;\n }\n\n async #doStart(params?: DownloaderStartParams): Promise<void> {\n try {\n const { signal } = params || {};\n const postFetch = this.config.postFetch;\n const db = await this.db();\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (postFetch.type === 'byUser') {\n this.log('info', `Targeting posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Targeting posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Targeting posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byURL') {\n this.log('info', `Targeting posts at '${postFetch.url}'`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Target post given by API data in \"${postFetch.filePath}\"`);\n }\n else { // Single\n this.log('info', `Targeting post #${postFetch.postId}`);\n }\n if (this.#isFetchingMultiplePosts(postFetch) && postFetch.filters) {\n const filterStr = Object.entries(postFetch.filters).map(([ key, value ]) => `${key}=${value}`).join('; ');\n if (filterStr) {\n this.log('info', `Filters: ${filterStr}`);\n }\n }\n\n // Step 1: Get posts (if by user) or target post\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n postsFetcher.on('statusChange', ({current}) => {\n if (current.status === 'running') {\n this.emit('fetchBegin', { targetType: postsFetcher.getTargetType() });\n }\n });\n postsFetcher.begin();\n\n // Step 2: download posts in each fetched list\n let downloaded = 0;\n let skippedUnviewable = 0;\n let skippedRedundant = 0;\n let skippedUnmetMediaTypeCriteria = 0;\n let skippedNotInTier = 0;\n let skippedPublishDateOutOfRange = 0;\n let campaignSaved = false;\n let stopConditionMet = false;\n const savedCollectionIds: string[] = [];\n const postsParser = new PostParser(this.logger);\n while (postsFetcher.hasNext()) {\n const { list, aborted, error } = await postsFetcher.next();\n if (!list || aborted) {\n break;\n }\n if (!list && error) {\n this.emit('end', { aborted: false, error, message: 'PostsFetcher error' });\n return;\n }\n if (!this.#context.skipSaveCampaign && !campaignSaved && list.items[0]?.campaign) {\n await this.saveCampaignInfo(list.items[0].campaign, signal);\n campaignSaved = true;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n for (const _post of list.items) {\n\n if (stopConditionMet) {\n break;\n }\n\n let post = _post;\n\n // Collections\n if (post.campaign && post.collections) {\n for (const collection of post.collections) {\n if (!savedCollectionIds.includes(collection.id)) {\n try {\n await this.#saveCollection(collection, post.campaign);\n savedCollectionIds.push(collection.id);\n }\n catch (error) {\n this.log('error', `Failed to save collection #${collection.id}:`, error);\n }\n }\n else {\n this.log('debug', `Collection #${collection.id} already processed`);\n }\n }\n }\n\n if (this.#isFetchingMultiplePosts(postFetch)) {\n // Refresh to ensure media links have not expired\n this.log('debug', `Refresh post #${_post.id}`);\n const postURL = URLHelper.constructPostsAPIURL({ postId: _post.id });\n const { json } = await this.commonFetchAPI(postURL, signal);\n let refreshed: Post | null = null;\n if (json) {\n refreshed = postsParser.parsePostsAPIResponse(json, postURL).items[0] || null;\n if (!refreshed) {\n this.log('warn', `Refreshed post #${_post.id} but got empty value - going to use existing data`);\n }\n else if (refreshed.id !== _post.id) {\n this.log('warn', `Refreshed post #${_post.id} but ID mismatch - going to use existing data`);\n refreshed = null;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return;\n }\n else {\n this.log('warn', `Failed to refresh post #${_post.id} - going to use existing data`);\n }\n if (refreshed) {\n this.log('debug', `Use refreshed post data #${refreshed.id}`);\n post = refreshed;\n }\n }\n\n this.emit('targetBegin', { target: post });\n\n // Step 4.1: post directories\n const postDirs = this.fsHelper.getPostDirs(post);\n this.log('debug', 'Post directories:', postDirs);\n\n // Step 4.2: Check with status cache\n const statusCache = StatusCache.getInstance(this.config, postDirs.statusCache, this.logger);\n const statusCacheValidation = statusCache.validate(post, postDirs.root, this.config)\n if (!statusCacheValidation.invalidated) {\n this.log('info', `Skipped downloading post #${post.id}: already downloaded and nothing has changed since last download`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.AlreadyDownloaded,\n skipMessage: 'Target already downloaded and nothing has changed since last download'\n });\n skippedRedundant++;\n if (this.config.stopOn === 'postPreviouslyDownloaded' || \n this.config.stopOn === 'previouslyDownloaded'\n ) {\n stopConditionMet = true;\n }\n continue;\n }\n \n switch ((await this.#doDownload(\n post,\n postDirs,\n statusCacheValidation.scope,\n statusCache,\n db,\n signal\n )).status) {\n case 'aborted':\n return;\n case 'downloaded':\n downloaded++;\n break;\n case 'skippedNotInTier':\n skippedNotInTier++;\n break;\n case 'skippedPublishDateOutOfRange':\n skippedPublishDateOutOfRange++;\n if (this.config.stopOn === 'postPublishDateOutOfRange' ||\n this.config.stopOn === 'publishDateOutOfRange'\n ) {\n stopConditionMet = true;\n }\n break;\n case 'skippedUnmetMediaTypeCriteria':\n skippedUnmetMediaTypeCriteria++;\n break;\n case 'skippedUnviewable':\n skippedUnviewable++;\n break;\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n if (stopConditionMet) {\n break;\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (stopConditionMet && this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', `Stop downloader: stop condition \"${this.config.stopOn}\" met`)\n }\n\n // Done\n if (postFetch.type === 'byUser') {\n this.log('info', `Done downloading posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Done downloading posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Done downloading posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byURL') {\n this.log('info', `Done downloading posts at '${postFetch.url}'`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Done downloading post given in \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', `Done downloading post #${postFetch.postId}`);\n }\n let endMessage = 'Done';\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const skippedStrParts: string[] = [];\n if (skippedUnviewable) {\n skippedStrParts.push(`${skippedUnviewable} unviewable`);\n }\n if (skippedRedundant) {\n skippedStrParts.push(`${skippedRedundant} redundant`);\n }\n if (skippedUnmetMediaTypeCriteria) {\n skippedStrParts.push(`${skippedUnmetMediaTypeCriteria} with unmet media type criteria`);\n }\n if (skippedNotInTier) {\n skippedStrParts.push(`${skippedNotInTier} not in tier`);\n }\n if (skippedPublishDateOutOfRange) {\n skippedStrParts.push(`${skippedPublishDateOutOfRange} with publish date out of range`);\n }\n const skippedStr = skippedStrParts.length > 0 ? ` (skipped: ${skippedStrParts.join(', ')})` : '';\n endMessage = `Total ${downloaded} / ${postsFetcher.getTotal()} posts processed${skippedStr}`;\n this.log('info', endMessage);\n }\n this.emit('end', { aborted: false, message: endMessage });\n }\n finally {\n if (!this.#context.keepDBOpen) {\n await this.closeDB();\n }\n if (this.logger && !this.#context.keepLoggerOpen) {\n await this.logger.end();\n }\n }\n }\n\n async #doDownload(\n post: Post,\n postDirs: PostDirectories,\n scope: StatusCacheValidationScope<Post>,\n statusCache: StatusCache,\n db: DBInstance,\n signal?: AbortSignal\n ): Promise<{status: 'skippedUnviewable' | 'skippedUnmetMediaTypeCriteria' | 'skippedNotInTier' | 'skippedPublishDateOutOfRange' | 'aborted' | 'downloaded' }> {\n this.log('info', `Download post #${post.id} (${post.title})`);\n\n const downloadPost = scope.includes('post');\n const downloadComments = scope.includes('comments');\n \n // Step 1: Check whether we should download post\n const criteriaHelper = new IncludeCriteriaHelper(this.logger);\n const criteriaCheck = criteriaHelper.checkPost(post, this.config);\n if (!criteriaCheck.ok) {\n switch (criteriaCheck.reason) {\n case 'unviewable': {\n this.log('warn', `Skipped downloading post #${post.id}: not viewable by current user`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.Inaccessible,\n skipMessage: 'Target is not viewable by current user'\n });\n return {\n status: 'skippedUnviewable'\n };\n }\n case 'unmetMediaTypeCriteria': {\n this.log('warn', `Skipped downloading post #${post.id}: unmet media type criteria`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.UnmetMediaTypeCriteria,\n skipMessage: 'Target does not meet media type criteria'\n });\n return {\n status: 'skippedUnmetMediaTypeCriteria'\n };\n }\n case 'notInTier': {\n this.log('warn', `Skipped downloading post #${post.id}: not in tier`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.NotInTier,\n skipMessage: 'Target not in tier'\n });\n return {\n status: 'skippedNotInTier'\n };\n }\n case 'publishDateOutOfRange': {\n this.log('warn', `Skipped downloading post #${post.id}: publish date out of range`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.PublishDateOutOfRange,\n skipMessage: 'Publish date out of range'\n });\n return {\n status: 'skippedPublishDateOutOfRange'\n };\n }\n }\n }\n\n if (!post.isViewable && this.config.include.lockedContent) {\n this.log('warn', `Post #${post.id} is not viewable by current user`);\n }\n\n if (!downloadPost && downloadComments) {\n this.log('info', `Previously downloaded post #${post.id} - refresh comments only`);\n }\n\n let hasDownloadPostError = false;\n if (downloadPost) {\n // Step 2: Save post info\n if (this.config.include.contentInfo) {\n this.log('info', `Save post info #${post.id}`);\n this.emit('phaseBegin', { target: post, phase: 'saveInfo' });\n this.fsHelper.createDir(postDirs.info);\n // Post raw data might not be complete or consistent with other posts in the collection.\n // 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: fetchedPostAPIData } = await this.commonFetchAPI(\n URLHelper.constructPostsAPIURL({\n postId: post.id,\n campaignId: post.campaign?.id\n }),\n signal\n );\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 3. Save summary and raw json\n const summary = generatePostSummary(post);\n const summaryFile = path.resolve(postDirs.info, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, post, 'post summary');\n\n const postRawFile = path.resolve(postDirs.info, 'post-api.json');\n const savePostRawResult = await this.fsHelper.writeTextFile(\n postRawFile, fetchedPostAPIData || post.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(savePostRawResult, post, 'post API data');\n this.emit('phaseEnd', { target: post, phase: 'saveInfo' });\n\n // (Downloading of info media items deferred to the next step)\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseBegin', { target: post, phase: 'saveMedia' });\n }\n\n // Step 4: save embed info\n if (post.embed && this.config.include.contentMedia) {\n this.log('info', `Save embed info of post #${post.id}`);\n this.fsHelper.createDir(postDirs.embed);\n const embedSummary = generatePostEmbedSummary(post.embed);\n let embedFilename;\n switch (post.embed.type) {\n case 'videoEmbed':\n embedFilename = 'embedded-video.txt';\n break;\n case 'linkEmbed':\n embedFilename = 'embedded-link.txt';\n break;\n default:\n embedFilename = 'embedded-unknown.txt';\n }\n const embedFile = path.resolve(postDirs.embed, embedFilename);\n const saveSummaryResult = await this.fsHelper.writeTextFile(embedFile, embedSummary, this.config.fileExistsAction.content);\n this.logWriteTextFileResult(saveSummaryResult, post, 'embed info');\n }\n\n // Step 5: create download tasks\n let createTaskErrorCount = 0;\n if (this.config.include.previewMedia ||\n this.config.include.contentMedia ||\n this.config.include.contentInfo) {\n\n const batchResult = await this.#createDownloadTaskBatchForPost(post, postDirs, signal);\n const { batch } = batchResult; \n createTaskErrorCount += batchResult.errorCount;\n\n const abortHandler = () => {\n void (async () => {\n this.log('info', 'Abort signal received');\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n\n try {\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n if (this.config.include.contentInfo) {\n const infoElements: Downloadable[] = [];\n if (post.coverImage) {\n infoElements.push(post.coverImage);\n }\n if (post.thumbnail) {\n infoElements.push(post.thumbnail);\n }\n if (infoElements.length > 0) {\n const { errorCount } = await this.addToDownloadTaskBatch(batch,\n signal,\n {\n target: infoElements,\n targetName: `post #${post.id} -> info elements`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.info,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n );\n createTaskErrorCount += errorCount;\n }\n }\n \n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n batch.prestart();\n this.log('info', `Download batch created (#${batch.id}): ${batch.getTasks('pending').length} downloads pending`);\n this.emit('phaseBegin', { target: post, phase: 'batchDownload', batch });\n \n await batch.start();\n\n hasDownloadPostError = batch.getTasks('error').length > 0 || createTaskErrorCount > 0;\n\n await batch.destroy();\n }\n finally {\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n }\n\n this.emit('phaseEnd', { target: post, phase: 'batchDownload'});\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseEnd', { target: post, phase: 'saveMedia' });\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 6: Fetch and save comments (only available if post is viewable)\n let comments: Comment[] | null = null;\n if (downloadComments && this.config.include.comments && post.isViewable) {\n if (post.commentCount > 0) {\n comments = await this.#fetchComments(post, signal);\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n if (comments.length > 0) {\n this.fsHelper.createDir(postDirs.info);\n const commentsFile = path.resolve(postDirs.info, 'comments.txt');\n const commentsSummary = generatePostCommentsSummary(comments);\n const saveCommentsResult = await this.fsHelper.writeTextFile(commentsFile, commentsSummary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveCommentsResult, post, `${comments.length} comments`);\n }\n else {\n this.log('warn', `Expecting ${post.commentCount} comments for post #${post.id} but got none`);\n }\n }\n else {\n this.log('info', `No comments available for post #${post.id}`)\n }\n }\n\n // Step 7: Update status cache\n statusCache.updateOnDownload(post, postDirs.root, hasDownloadPostError, this.config);\n\n // Step 8: Save to DB\n let skipDB = false;\n if (!post.isViewable) {\n // Skip if existing db record (if any) refers to viewable post\n const dbPost = db.getContent(post.id, 'post');\n skipDB = dbPost !== null && dbPost.isViewable;\n }\n if (!skipDB) {\n db.saveContent(post);\n if (comments) {\n db.savePostComments(post, comments);\n }\n }\n else {\n this.log('info', `Skip overwrite existing viewable post #${post.id} in DB with current unviewable version`);\n }\n\n this.emit('targetEnd', { target: post, isSkipped: false });\n\n return {\n status: 'downloaded'\n };\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' | 'byURL' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';\n }\n\n async __getCampaign(signal?: AbortSignal) {\n let url: string | null;\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n url = URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n break;\n case 'byUserId':\n url = URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n break;\n default:\n url = null;\n }\n if (!url) {\n throw Error('Internal error: invalid config');\n }\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n const { campaignId } = await postsFetcher.getInitialData(url);\n const postsParser = new PostParser(this.logger);\n const res = await this.fetchCampaign(campaignId);\n if (signal?.aborted) {\n throw new Error('Aborted');\n }\n if (res.error) {\n throw res.error;\n }\n return postsParser.parseCampaignAPIResponse(res.json);\n }\n\n async #createDownloadTaskBatchForPost(post: Post, postDirs: ReturnType<typeof this.fsHelper['getPostDirs']>, signal?: AbortSignal) {\n\n const incPreview = this.config.include.previewMedia;\n const incContent = this.config.include.contentMedia;\n\n const __incPreview = (mediaType: 'audio' | 'video' | 'image') => {\n if (typeof incPreview === 'boolean') {\n return incPreview;\n }\n return incPreview.includes(mediaType);\n };\n\n const __incContent = (mediaType: 'audio' | 'video' | 'image' | 'attachment') => {\n if (typeof incContent === 'boolean') {\n return incContent;\n }\n return incContent.includes(mediaType);\n };\n\n const __getEmbedTask = () => {\n if (!post.embed) {\n return null;\n }\n\n const hasEmbedDownloader = DownloadTaskFactory.findEmbedDownloader(this.config.embedDownloaders, post.embed.provider);\n const isDownloadableVideo = isYouTubeEmbed(post.embed) || (post.embed.type === 'videoEmbed' && hasEmbedDownloader);\n const isDownloadableOther = !isYouTubeEmbed(post.embed) && post.embed.type !== 'videoEmbed' && hasEmbedDownloader;\n \n if ((isDownloadableVideo && __incContent('video')) || isDownloadableOther) {\n const embedType = post.embed.type === 'videoEmbed' ? ' video' : post.embed.type === 'linkEmbed' ? ' link' : '';\n return {\n target: [ post.embed ],\n targetName: `post #${post.id} -> embedded ${post.embed.provider}${embedType}`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.embed,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n };\n }\n \n return null;\n }\n\n const campaignDir = post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null;\n\n await this.#processLinkedAttachments(post);\n const downloadableLinkedAttachments = post.linkedAttachments?.reduce<Downloadable<AttachmentMediaItem>[]>((result, att) => {\n if (att.downloadable) {\n result.push(att.downloadable);\n }\n return result;\n }, []) || [];\n\n const allAttachments = [...post.attachments, ...downloadableLinkedAttachments];\n\n const batchResult = this.createDownloadTaskBatch(\n `Post #${post.id} (${post.title})`,\n signal,\n\n __incPreview('audio') && post.audioPreview ? {\n target: [ post.audioPreview ],\n targetName: `post #${post.id} -> audio preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audioPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incPreview('video') && post.videoPreview ? {\n target: [ post.videoPreview ],\n targetName: `post #${post.id} -> video preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.videoPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable by current user, its images will be\n * blurry and we should categorize them as image previews.\n */\n __incPreview('image') && post.images.length > 0 && !post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> image previews`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.imagePreviews,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable, audio data should have no URL, so check and\n * skip if this is the case.\n */\n __incContent('audio') && post.audio && (post.isViewable || (post.audio.type === 'audio' && post.audio.url)) ? {\n target: [ post.audio ],\n targetName: `post #${post.id} -> audio`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audio,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('video') && post.video ? {\n target: [ post.video ],\n targetName: `post #${post.id} -> video`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.video,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('image') && post.images.length > 0 && post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> images`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.images,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('attachment') && allAttachments.length > 0 ? {\n target: allAttachments,\n targetName: `post #${post.id} -> attachments`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.attachments,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content,\n isAttachment: true\n } : null,\n\n __getEmbedTask()\n );\n\n return batchResult;\n }\n\n async #processLinkedAttachments(post: Post, signal?: AbortSignal) {\n if (!post.linkedAttachments || post.linkedAttachments.length === 0) {\n return;\n }\n this.log('debug', `Process linked attachments of post #${post.id}`);\n for (const la of post.linkedAttachments) {\n const laStr = `[#${post.id} -> #${la.mediaId}]`;\n // Only process linked attachment where its postId is not the same as current one being processed.\n // If same as current one, then linked attachment would already be in the current post data.\n if (la.postId === post.id) {\n this.log('debug', `Linked attachment ${laStr} has same parent post`);\n }\n else {\n const apiURL = URLHelper.constructPostsAPIURL({ postId: la.postId });\n let json;\n try {\n this.log('debug', `Linked attachment ${laStr} belongs to post #${la.postId}`);\n json = (await this.fetcher.get({\n url: apiURL,\n type: 'json',\n maxRetries: this.config.request.maxRetries,\n signal }\n )).json;\n }\n catch (error) {\n if (signal?.aborted) {\n throw error;\n }\n else {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: API request failed for \"${apiURL}\": `, error);\n }\n json = null;\n }\n if (json) {\n const parser = new PostParser();\n const parentPost = parser.parsePostsAPIResponse(json, apiURL).items[0];\n if (!parentPost) {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: post data not found in response of \"${apiURL}\"`);\n }\n else {\n if (!parentPost.isViewable) {\n this.log('warn', `Parent post #${la.postId} of linked attachment ${laStr} is not viewable by user`);\n }\n else {\n const attachment = parentPost.attachments.find((att) => att.id === la.mediaId);\n if (!attachment) {\n this.log('warn', `Attachment not found in parent post #${la.postId} of linked attachment ${laStr}`);\n }\n else {\n la.downloadable = attachment;\n this.log('debug', `Obtained attachment from parent post #${la.postId} of linked attachment ${laStr}`);\n }\n }\n }\n }\n }\n }\n }\n\n async #fetchComments(post: Post, signal?: AbortSignal, accumulated?: CommentList & { nextURL: string; }): Promise<Comment[]> {\n if (!post.commentCount) {\n this.log('debug', `Comment count is zero for post #${post.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let commentsURL;\n if (!accumulated) {\n this.log('info', `Fetch comments for post #${post.id}`);\n commentsURL = URLHelper.constructPostCommentsAPIURL({ postId: post.id });\n }\n else {\n this.log('debug', `Fetch next batch of comments for post #${post.id}`);\n commentsURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(commentsURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const comments = parser.parseCommentsAPIResponse(json, commentsURL);\n this.log('debug', `Fetched ${comments.items.length} comments for post #${post.id}`);\n if (comments.items.length > 0 && comments.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: comments.url,\n items: comments.items,\n nextURL: comments.nextURL,\n total: comments.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = comments.url;\n _acc.items.push(...comments.items);\n _acc.nextURL = comments.nextURL;\n }\n return this.#fetchComments(post, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...comments.items ] : comments.items;\n this.log('debug', `Total ${result.length} comments fetched for post #${post.id}`);\n for (const comment of result) {\n if (comment.replyCount > 0) {\n comment.replies = await this.#fetchCommentReplies(comment, signal);\n }\n }\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch comments for post #${post.id}`);\n return [];\n }\n }\n\n async #fetchCommentReplies(comment: Comment, signal?: AbortSignal, accumulated?: CommentReplyList & { nextURL: string; }): Promise<CommentReply[]> {\n if (!comment.replyCount) {\n this.log('debug', `Reply count is zero for comment #${comment.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let repliesURL;\n if (!accumulated) {\n this.log('debug', `Fetch replies to comment #${comment.id}`);\n repliesURL = URLHelper.constructPostCommentsAPIURL({ commentId: comment.id, replies: true });\n }\n else {\n this.log('debug', `Fetch next batch of replies to comment #${comment.id}`);\n repliesURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(repliesURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const replies = parser.parseCommentsAPIResponse(json, repliesURL, true);\n this.log('debug', `Fetched ${replies.items.length} replies to comment #${comment.id}`);\n if (replies.items.length > 0 && replies.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: replies.url,\n items: replies.items,\n nextURL: replies.nextURL,\n total: replies.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = replies.url;\n _acc.items.push(...replies.items);\n _acc.nextURL = replies.nextURL;\n }\n return this.#fetchCommentReplies(comment, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...replies.items ] : replies.items;\n this.log('debug', `Total ${result.length} replies fetched for comment #${comment.id}`);\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch replies to comment #${comment.id}`);\n return [];\n }\n }\n\n async #saveCollection(collection: Collection, campaign: Campaign, signal?: AbortSignal) {\n const db = await this.db();\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (!this.config.include.contentInfo) {\n db.saveCollection(collection, campaign);\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 this.log('info', `Save collection info #${collection.id}`);\n this.emit('targetBegin', { target: collection });\n this.emit('phaseBegin', { target: collection, phase: 'saveInfo' });\n\n // Step 1: create collection directories\n const collectionDirs = this.fsHelper.getCollectionsDir(campaign, collection);\n this.log('debug', 'Campaign directories: ', collectionDirs);\n this.fsHelper.createDir(collectionDirs.root);\n\n // Step 2: save summary and raw json\n const summary = generateCollectionSummary(collection);\n const summaryFile = path.resolve(collectionDirs.root, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, collection, 'collection summary');\n\n const collectionRawFile = path.resolve(collectionDirs.root, 'collection-api.json');\n const saveCollectionRawResult = await this.fsHelper.writeTextFile(\n collectionRawFile, collection.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCollectionRawResult, collection, 'collection API data');\n\n this.emit('phaseEnd', { target: collection, phase: 'saveInfo' });\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n // Step 3: download collection media items\n if (collection.thumbnail) {\n this.emit('phaseBegin', { target: collection, phase: 'saveMedia' });\n const collectionMedia: Downloadable[] = [\n collection.thumbnail\n ];\n batch = (await this.createDownloadTaskBatch(\n `Collection #${collection.id} (${collection.title})`,\n signal,\n {\n target: collectionMedia,\n targetName: `collection #${campaign.id} -> thumbnail`,\n src: collection,\n dirs: {\n campaign: this.fsHelper.getCampaignDirs(campaign).root,\n main: collectionDirs.root,\n thumbnails: null\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n )).batch;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n batch.prestart();\n this.emit('phaseBegin', { target: collection, phase: 'batchDownload', batch });\n await batch.start();\n await batch.destroy();\n this.emit('phaseEnd', { target: collection, phase: 'batchDownload' });\n this.emit('phaseEnd', { target: collection, phase: 'saveMedia' });\n\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n // Step 4: save to DB\n db.saveCollection(collection, campaign);\n\n // Done\n this.log('info', 'Done saving collection info');\n this.emit('targetEnd', { target: collection, isSkipped: false });\n }\n\n}\n"]}
1
+ {"version":3,"file":"PostDownloader.js","sourceRoot":"","sources":["../../src/downloaders/PostDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import URLHelper from '../utils/URLHelper.js';\nimport Downloader, { type DownloaderConfig, type DownloaderStartParams } from './Downloader.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type Collection, type Post } from '../entities/Post.js';\nimport { type Downloadable, isYouTubeEmbed } from '../entities/Downloadable.js';\nimport StatusCache, { type StatusCacheValidationScope } from './cache/StatusCache.js';\nimport { generatePostEmbedSummary, generatePostSummary } from './templates/PostInfo.js';\nimport path from 'path';\nimport { TargetSkipReason } from './DownloaderEvent.js';\nimport DownloadTaskFactory from './task/DownloadTaskFactory.js';\nimport PostsFetcher from './PostsFetcher.js';\nimport CommentParser from '../parsers/CommentParser.js';\nimport { type Comment, type CommentList, type CommentReply, type CommentReplyList } from '../entities/Comment.js';\nimport { generatePostCommentsSummary } from './templates/CommentInfo.js';\nimport { type PostDirectories } from '../utils/FSHelper.js';\nimport { type DBInstance } from '../browse/db/index.js';\nimport { type AttachmentMediaItem } from '../entities/MediaItem.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport { type DeepRequired } from '../utils/Misc.js';\nimport { type Campaign } from '../entities/Campaign.js';\nimport type DownloadTaskBatch from './task/DownloadTaskBatch.js';\nimport { generateCollectionSummary } from './templates/CollectionInfo.js';\nimport { IncludeCriteriaHelper } from './IncludeCriteriaHelper.js';\n\nexport interface PostDownloaderContext {\n skipSaveCampaign?: boolean;\n keepLoggerOpen?: boolean;\n keepDBOpen?: boolean;\n}\n\nexport default class PostDownloader extends Downloader<Post> {\n\n static version = '1.1.1';\n\n name = 'PostDownloader';\n\n #startPromise: Promise<void> | null = null;\n #context: DeepRequired<PostDownloaderContext>;\n\n constructor(\n config: DownloaderConfig<Post>,\n db: () => Promise<DBInstance>,\n logger?: Logger | null,\n context?: PostDownloaderContext\n ) {\n super(config, db, logger);\n this.#context = {\n skipSaveCampaign: context?.skipSaveCampaign ?? false,\n keepLoggerOpen: context?.keepLoggerOpen ?? false,\n keepDBOpen: context?.keepDBOpen ?? false\n };\n }\n\n doStart(params?: DownloaderStartParams): Promise<void> {\n if (this.#startPromise) {\n throw Error('Downloader already running');\n }\n this.#startPromise = this.#doStart(params)\n .finally(() => {\n this.#startPromise = null;\n });\n return this.#startPromise;\n }\n\n async #doStart(params?: DownloaderStartParams): Promise<void> {\n try {\n const { signal } = params || {};\n const postFetch = this.config.postFetch;\n const db = await this.db();\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (postFetch.type === 'byUser') {\n this.log('info', `Targeting posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Targeting posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Targeting posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byURL') {\n this.log('info', `Targeting posts at '${postFetch.url}'`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Target post given by API data in \"${postFetch.filePath}\"`);\n }\n else { // Single\n this.log('info', `Targeting post #${postFetch.postId}`);\n }\n if (this.#isFetchingMultiplePosts(postFetch) && postFetch.filters) {\n const filterStr = Object.entries(postFetch.filters).map(([ key, value ]) => `${key}=${value}`).join('; ');\n if (filterStr) {\n this.log('info', `Filters: ${filterStr}`);\n }\n }\n\n // Step 1: Get posts (if by user) or target post\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n postsFetcher.on('statusChange', ({current}) => {\n if (current.status === 'running') {\n this.emit('fetchBegin', { targetType: postsFetcher.getTargetType() });\n }\n });\n postsFetcher.begin();\n\n // Step 2: download posts in each fetched list\n let downloaded = 0;\n let skippedUnviewable = 0;\n let skippedRedundant = 0;\n let skippedUnmetMediaTypeCriteria = 0;\n let skippedNotInTier = 0;\n let skippedPublishDateOutOfRange = 0;\n let campaignSaved = false;\n let stopConditionMet = false;\n const savedCollectionIds: string[] = [];\n const postsParser = new PostParser(this.fetcher, this.logger);\n while (postsFetcher.hasNext()) {\n const { list, aborted, error } = await postsFetcher.next();\n if (!list || aborted) {\n break;\n }\n if (!list && error) {\n this.emit('end', { aborted: false, error, message: 'PostsFetcher error' });\n return;\n }\n if (!this.#context.skipSaveCampaign && !campaignSaved && list.items[0]?.campaign) {\n await this.saveCampaignInfo(list.items[0].campaign, signal);\n campaignSaved = true;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n for (const _post of list.items) {\n\n if (stopConditionMet) {\n break;\n }\n\n let post = _post;\n\n // Collections\n if (post.campaign && post.collections) {\n for (const collection of post.collections) {\n if (!savedCollectionIds.includes(collection.id)) {\n try {\n await this.#saveCollection(collection, post.campaign);\n savedCollectionIds.push(collection.id);\n }\n catch (error) {\n this.log('error', `Failed to save collection #${collection.id}:`, error);\n }\n }\n else {\n this.log('debug', `Collection #${collection.id} already processed`);\n }\n }\n }\n\n if (this.#isFetchingMultiplePosts(postFetch)) {\n // Refresh to ensure media links have not expired\n this.log('debug', `Refresh post #${_post.id}`);\n const postURL = URLHelper.constructPostsAPIURL({ postId: _post.id });\n const { json } = await this.commonFetchAPI(postURL, signal);\n let refreshed: Post | null = null;\n if (json) {\n refreshed = (await postsParser.parsePostsAPIResponse(json, postURL)).items[0] || null;\n if (!refreshed) {\n this.log('warn', `Refreshed post #${_post.id} but got empty value - going to use existing data`);\n }\n else if (refreshed.id !== _post.id) {\n this.log('warn', `Refreshed post #${_post.id} but ID mismatch - going to use existing data`);\n refreshed = null;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return;\n }\n else {\n this.log('warn', `Failed to refresh post #${_post.id} - going to use existing data`);\n }\n if (refreshed) {\n this.log('debug', `Use refreshed post data #${refreshed.id}`);\n post = refreshed;\n }\n }\n\n this.emit('targetBegin', { target: post });\n\n // Step 4.1: post directories\n const postDirs = this.fsHelper.getPostDirs(post);\n this.log('debug', 'Post directories:', postDirs);\n\n // Step 4.2: Check with status cache\n const statusCache = StatusCache.getInstance(this.config, postDirs.statusCache, this.logger);\n const statusCacheValidation = statusCache.validate(post, postDirs.root, this.config)\n if (!statusCacheValidation.invalidated) {\n this.log('info', `Skipped downloading post #${post.id}: already downloaded and nothing has changed since last download`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.AlreadyDownloaded,\n skipMessage: 'Target already downloaded and nothing has changed since last download'\n });\n skippedRedundant++;\n if (this.config.stopOn === 'postPreviouslyDownloaded' || \n this.config.stopOn === 'previouslyDownloaded'\n ) {\n stopConditionMet = true;\n }\n continue;\n }\n \n switch ((await this.#doDownload(\n post,\n postDirs,\n statusCacheValidation.scope,\n statusCache,\n db,\n signal\n )).status) {\n case 'aborted':\n return;\n case 'downloaded':\n downloaded++;\n break;\n case 'skippedNotInTier':\n skippedNotInTier++;\n break;\n case 'skippedPublishDateOutOfRange':\n skippedPublishDateOutOfRange++;\n if (this.config.stopOn === 'postPublishDateOutOfRange' ||\n this.config.stopOn === 'publishDateOutOfRange'\n ) {\n stopConditionMet = true;\n }\n break;\n case 'skippedUnmetMediaTypeCriteria':\n skippedUnmetMediaTypeCriteria++;\n break;\n case 'skippedUnviewable':\n skippedUnviewable++;\n break;\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n if (stopConditionMet) {\n break;\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (stopConditionMet && this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', `Stop downloader: stop condition \"${this.config.stopOn}\" met`)\n }\n\n // Done\n if (postFetch.type === 'byUser') {\n this.log('info', `Done downloading posts by '${postFetch.vanity}'`);\n }\n else if (postFetch.type === 'byUserId') {\n this.log('info', `Done downloading posts by user #${postFetch.userId}`);\n }\n else if (postFetch.type === 'byCollection') {\n this.log('info', `Done downloading posts in collection #${postFetch.collectionId}`);\n }\n else if (postFetch.type === 'byURL') {\n this.log('info', `Done downloading posts at '${postFetch.url}'`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Done downloading post given in \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', `Done downloading post #${postFetch.postId}`);\n }\n let endMessage = 'Done';\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const skippedStrParts: string[] = [];\n if (skippedUnviewable) {\n skippedStrParts.push(`${skippedUnviewable} unviewable`);\n }\n if (skippedRedundant) {\n skippedStrParts.push(`${skippedRedundant} redundant`);\n }\n if (skippedUnmetMediaTypeCriteria) {\n skippedStrParts.push(`${skippedUnmetMediaTypeCriteria} with unmet media type criteria`);\n }\n if (skippedNotInTier) {\n skippedStrParts.push(`${skippedNotInTier} not in tier`);\n }\n if (skippedPublishDateOutOfRange) {\n skippedStrParts.push(`${skippedPublishDateOutOfRange} with publish date out of range`);\n }\n const skippedStr = skippedStrParts.length > 0 ? ` (skipped: ${skippedStrParts.join(', ')})` : '';\n endMessage = `Total ${downloaded} / ${postsFetcher.getTotal()} posts processed${skippedStr}`;\n this.log('info', endMessage);\n }\n this.emit('end', { aborted: false, message: endMessage });\n }\n finally {\n if (!this.#context.keepDBOpen) {\n await this.closeDB();\n }\n if (this.logger && !this.#context.keepLoggerOpen) {\n await this.logger.end();\n }\n }\n }\n\n async #doDownload(\n post: Post,\n postDirs: PostDirectories,\n scope: StatusCacheValidationScope<Post>,\n statusCache: StatusCache,\n db: DBInstance,\n signal?: AbortSignal\n ): Promise<{status: 'skippedUnviewable' | 'skippedUnmetMediaTypeCriteria' | 'skippedNotInTier' | 'skippedPublishDateOutOfRange' | 'aborted' | 'downloaded' }> {\n this.log('info', `Download post #${post.id} (${post.title})`);\n\n const downloadPost = scope.includes('post');\n const downloadComments = scope.includes('comments');\n \n // Step 1: Check whether we should download post\n const criteriaHelper = new IncludeCriteriaHelper(this.logger);\n const criteriaCheck = criteriaHelper.checkPost(post, this.config);\n if (!criteriaCheck.ok) {\n switch (criteriaCheck.reason) {\n case 'unviewable': {\n this.log('warn', `Skipped downloading post #${post.id}: not viewable by current user`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.Inaccessible,\n skipMessage: 'Target is not viewable by current user'\n });\n return {\n status: 'skippedUnviewable'\n };\n }\n case 'unmetMediaTypeCriteria': {\n this.log('warn', `Skipped downloading post #${post.id}: unmet media type criteria`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.UnmetMediaTypeCriteria,\n skipMessage: 'Target does not meet media type criteria'\n });\n return {\n status: 'skippedUnmetMediaTypeCriteria'\n };\n }\n case 'notInTier': {\n this.log('warn', `Skipped downloading post #${post.id}: not in tier`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.NotInTier,\n skipMessage: 'Target not in tier'\n });\n return {\n status: 'skippedNotInTier'\n };\n }\n case 'publishDateOutOfRange': {\n this.log('warn', `Skipped downloading post #${post.id}: publish date out of range`);\n this.emit('targetEnd', {\n target: post,\n isSkipped: true,\n skipReason: TargetSkipReason.PublishDateOutOfRange,\n skipMessage: 'Publish date out of range'\n });\n return {\n status: 'skippedPublishDateOutOfRange'\n };\n }\n }\n }\n\n if (!post.isViewable && this.config.include.lockedContent) {\n this.log('warn', `Post #${post.id} is not viewable by current user`);\n }\n\n if (!downloadPost && downloadComments) {\n this.log('info', `Previously downloaded post #${post.id} - refresh comments only`);\n }\n\n let hasDownloadPostError = false;\n if (downloadPost) {\n // Step 2: Save post info\n if (this.config.include.contentInfo) {\n this.log('info', `Save post info #${post.id}`);\n this.emit('phaseBegin', { target: post, phase: 'saveInfo' });\n this.fsHelper.createDir(postDirs.info);\n // Post raw data might not be complete or consistent with other posts in the collection.\n // 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: fetchedPostAPIData } = await this.commonFetchAPI(\n URLHelper.constructPostsAPIURL({\n postId: post.id,\n campaignId: post.campaign?.id\n }),\n signal\n );\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 3. Save summary and raw json\n const summary = generatePostSummary(post);\n const summaryFile = path.resolve(postDirs.info, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, post, 'post summary');\n\n const postRawFile = path.resolve(postDirs.info, 'post-api.json');\n const savePostRawResult = await this.fsHelper.writeTextFile(\n postRawFile, fetchedPostAPIData || post.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(savePostRawResult, post, 'post API data');\n this.emit('phaseEnd', { target: post, phase: 'saveInfo' });\n\n // (Downloading of info media items deferred to the next step)\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseBegin', { target: post, phase: 'saveMedia' });\n }\n\n // Step 4: save embed info\n if (post.embed && this.config.include.contentMedia) {\n this.log('info', `Save embed info of post #${post.id}`);\n this.fsHelper.createDir(postDirs.embed);\n const embedSummary = generatePostEmbedSummary(post.embed);\n let embedFilename;\n switch (post.embed.type) {\n case 'videoEmbed':\n embedFilename = 'embedded-video.txt';\n break;\n case 'linkEmbed':\n embedFilename = 'embedded-link.txt';\n break;\n default:\n embedFilename = 'embedded-unknown.txt';\n }\n const embedFile = path.resolve(postDirs.embed, embedFilename);\n const saveSummaryResult = await this.fsHelper.writeTextFile(embedFile, embedSummary, this.config.fileExistsAction.content);\n this.logWriteTextFileResult(saveSummaryResult, post, 'embed info');\n }\n\n // Step 5: create download tasks\n let createTaskErrorCount = 0;\n if (this.config.include.previewMedia ||\n this.config.include.contentMedia ||\n this.config.include.contentInfo) {\n\n const batchResult = await this.#createDownloadTaskBatchForPost(post, postDirs, signal);\n const { batch } = batchResult; \n createTaskErrorCount += batchResult.errorCount;\n\n const abortHandler = () => {\n void (async () => {\n this.log('info', 'Abort signal received');\n if (batch) {\n await batch.abort();\n }\n })();\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, { once: true });\n }\n\n try {\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n if (this.config.include.contentInfo) {\n const infoElements: Downloadable[] = [];\n if (post.coverImage) {\n infoElements.push(post.coverImage);\n }\n if (post.thumbnail) {\n infoElements.push(post.thumbnail);\n }\n if (infoElements.length > 0) {\n const { errorCount } = await this.addToDownloadTaskBatch(batch,\n signal,\n {\n target: infoElements,\n targetName: `post #${post.id} -> info elements`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.info,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n );\n createTaskErrorCount += errorCount;\n }\n }\n \n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n \n batch.prestart();\n this.log('info', `Download batch created (#${batch.id}): ${batch.getTasks('pending').length} downloads pending`);\n this.emit('phaseBegin', { target: post, phase: 'batchDownload', batch });\n \n await batch.start();\n\n hasDownloadPostError = batch.getTasks('error').length > 0 || createTaskErrorCount > 0;\n\n await batch.destroy();\n }\n finally {\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n }\n\n this.emit('phaseEnd', { target: post, phase: 'batchDownload'});\n }\n\n if (this.config.include.previewMedia || this.config.include.contentMedia) {\n this.emit('phaseEnd', { target: post, phase: 'saveMedia' });\n }\n }\n\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n\n // Step 6: Fetch and save comments (only available if post is viewable)\n let comments: Comment[] | null = null;\n if (downloadComments && this.config.include.comments && post.isViewable) {\n if (post.commentCount > 0) {\n comments = await this.#fetchComments(post, signal);\n if (this.checkAbortSignal(signal)) {\n return {\n status: 'aborted'\n };\n }\n if (comments.length > 0) {\n this.fsHelper.createDir(postDirs.info);\n const commentsFile = path.resolve(postDirs.info, 'comments.txt');\n const commentsSummary = generatePostCommentsSummary(comments);\n const saveCommentsResult = await this.fsHelper.writeTextFile(commentsFile, commentsSummary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveCommentsResult, post, `${comments.length} comments`);\n }\n else {\n this.log('warn', `Expecting ${post.commentCount} comments for post #${post.id} but got none`);\n }\n }\n else {\n this.log('info', `No comments available for post #${post.id}`)\n }\n }\n\n // Step 7: Update status cache\n statusCache.updateOnDownload(post, postDirs.root, hasDownloadPostError, this.config);\n\n // Step 8: Save to DB\n let skipDB = false;\n if (!post.isViewable) {\n // Skip if existing db record (if any) refers to viewable post\n const dbPost = db.getContent(post.id, 'post');\n skipDB = dbPost !== null && dbPost.isViewable;\n }\n if (!skipDB) {\n db.saveContent(post);\n if (comments) {\n db.savePostComments(post, comments);\n }\n }\n else {\n this.log('info', `Skip overwrite existing viewable post #${post.id} in DB with current unviewable version`);\n }\n\n this.emit('targetEnd', { target: post, isSkipped: false });\n\n return {\n status: 'downloaded'\n };\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' | 'byURL' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';\n }\n\n async __getCampaign(signal?: AbortSignal) {\n let url: string | null;\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n url = URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n break;\n case 'byUserId':\n url = URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n break;\n default:\n url = null;\n }\n if (!url) {\n throw Error('Internal error: invalid config');\n }\n const postsFetcher = new PostsFetcher({\n config: this.config,\n fetcher: this.fetcher,\n logger: this.logger,\n signal\n });\n const { campaignId } = await postsFetcher.getInitialData(url);\n const postsParser = new PostParser(this.fetcher, this.logger);\n const res = await this.fetchCampaign(campaignId);\n if (signal?.aborted) {\n throw new Error('Aborted');\n }\n if (res.error) {\n throw res.error;\n }\n return postsParser.parseCampaignAPIResponse(res.json);\n }\n\n async #createDownloadTaskBatchForPost(post: Post, postDirs: ReturnType<typeof this.fsHelper['getPostDirs']>, signal?: AbortSignal) {\n\n const incPreview = this.config.include.previewMedia;\n const incContent = this.config.include.contentMedia;\n\n const __incPreview = (mediaType: 'audio' | 'video' | 'image') => {\n if (typeof incPreview === 'boolean') {\n return incPreview;\n }\n return incPreview.includes(mediaType);\n };\n\n const __incContent = (mediaType: 'audio' | 'video' | 'image' | 'attachment') => {\n if (typeof incContent === 'boolean') {\n return incContent;\n }\n return incContent.includes(mediaType);\n };\n\n const __getEmbedTask = () => {\n if (!post.embed) {\n return null;\n }\n\n const hasEmbedDownloader = DownloadTaskFactory.findEmbedDownloader(this.config.embedDownloaders, post.embed.provider);\n const isDownloadableVideo = isYouTubeEmbed(post.embed) || (post.embed.type === 'videoEmbed' && hasEmbedDownloader);\n const isDownloadableOther = !isYouTubeEmbed(post.embed) && post.embed.type !== 'videoEmbed' && hasEmbedDownloader;\n \n if ((isDownloadableVideo && __incContent('video')) || isDownloadableOther) {\n const embedType = post.embed.type === 'videoEmbed' ? ' video' : post.embed.type === 'linkEmbed' ? ' link' : '';\n return {\n target: [ post.embed ],\n targetName: `post #${post.id} -> embedded ${post.embed.provider}${embedType}`,\n src: post,\n dirs: {\n campaign: post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null,\n main: postDirs.embed,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n };\n }\n \n return null;\n }\n\n const campaignDir = post.campaign ? this.fsHelper.getCampaignDirs(post.campaign).root : null;\n\n await this.#processLinkedAttachments(post);\n const downloadableLinkedAttachments = post.linkedAttachments?.reduce<Downloadable<AttachmentMediaItem>[]>((result, att) => {\n if (att.downloadable) {\n result.push(att.downloadable);\n }\n return result;\n }, []) || [];\n\n const allAttachments = [...post.attachments, ...downloadableLinkedAttachments];\n\n const batchResult = this.createDownloadTaskBatch(\n `Post #${post.id} (${post.title})`,\n signal,\n\n __incPreview('audio') && post.audioPreview ? {\n target: [ post.audioPreview ],\n targetName: `post #${post.id} -> audio preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audioPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incPreview('video') && post.videoPreview ? {\n target: [ post.videoPreview ],\n targetName: `post #${post.id} -> video preview`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.videoPreview,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable by current user, its images will be\n * blurry and we should categorize them as image previews.\n */\n __incPreview('image') && post.images.length > 0 && !post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> image previews`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.imagePreviews,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n /**\n * If post is not viewable, audio data should have no URL, so check and\n * skip if this is the case.\n */\n __incContent('audio') && post.audio && (post.isViewable || (post.audio.type === 'audio' && post.audio.url)) ? {\n target: [ post.audio ],\n targetName: `post #${post.id} -> audio`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.audio,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('video') && post.video ? {\n target: [ post.video ],\n targetName: `post #${post.id} -> video`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.video,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('image') && post.images.length > 0 && post.isViewable ? {\n target: post.images,\n targetName: `post #${post.id} -> images`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.images,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content\n } : null,\n\n __incContent('attachment') && allAttachments.length > 0 ? {\n target: allAttachments,\n targetName: `post #${post.id} -> attachments`,\n src: post,\n dirs: {\n campaign: campaignDir,\n main: postDirs.attachments,\n thumbnails: postDirs.thumbnails\n },\n fileExistsAction: this.config.fileExistsAction.content,\n isAttachment: true\n } : null,\n\n __getEmbedTask()\n );\n\n return batchResult;\n }\n\n async #processLinkedAttachments(post: Post, signal?: AbortSignal) {\n if (!post.linkedAttachments || post.linkedAttachments.length === 0) {\n return;\n }\n this.log('debug', `Process linked attachments of post #${post.id}`);\n for (const la of post.linkedAttachments) {\n const laStr = `[#${post.id} -> #${la.mediaId}]`;\n // Only process linked attachment where its postId is not the same as current one being processed.\n // If same as current one, then linked attachment would already be in the current post data.\n if (la.postId === post.id) {\n this.log('debug', `Linked attachment ${laStr} has same parent post`);\n }\n else {\n const apiURL = URLHelper.constructPostsAPIURL({ postId: la.postId });\n let json;\n try {\n this.log('debug', `Linked attachment ${laStr} belongs to post #${la.postId}`);\n json = (await this.fetcher.get({\n url: apiURL,\n type: 'json',\n maxRetries: this.config.request.maxRetries,\n signal }\n )).json;\n }\n catch (error) {\n if (signal?.aborted) {\n throw error;\n }\n else {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: API request failed for \"${apiURL}\": `, error);\n }\n json = null;\n }\n if (json) {\n const parser = new PostParser(this.fetcher);\n const parentPost = (await parser.parsePostsAPIResponse(json, apiURL)).items[0];\n if (!parentPost) {\n this.log('error', `Error fetching linked attachment ${laStr} from parent post #${la.postId}: post data not found in response of \"${apiURL}\"`);\n }\n else {\n if (!parentPost.isViewable) {\n this.log('warn', `Parent post #${la.postId} of linked attachment ${laStr} is not viewable by user`);\n }\n else {\n const attachment = parentPost.attachments.find((att) => att.id === la.mediaId);\n if (!attachment) {\n this.log('warn', `Attachment not found in parent post #${la.postId} of linked attachment ${laStr}`);\n }\n else {\n la.downloadable = attachment;\n this.log('debug', `Obtained attachment from parent post #${la.postId} of linked attachment ${laStr}`);\n }\n }\n }\n }\n }\n }\n }\n\n async #fetchComments(post: Post, signal?: AbortSignal, accumulated?: CommentList & { nextURL: string; }): Promise<Comment[]> {\n if (!post.commentCount) {\n this.log('debug', `Comment count is zero for post #${post.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let commentsURL;\n if (!accumulated) {\n this.log('info', `Fetch comments for post #${post.id}`);\n commentsURL = URLHelper.constructPostCommentsAPIURL({ postId: post.id });\n }\n else {\n this.log('debug', `Fetch next batch of comments for post #${post.id}`);\n commentsURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(commentsURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const comments = parser.parseCommentsAPIResponse(json, commentsURL);\n this.log('debug', `Fetched ${comments.items.length} comments for post #${post.id}`);\n if (comments.items.length > 0 && comments.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: comments.url,\n items: comments.items,\n nextURL: comments.nextURL,\n total: comments.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = comments.url;\n _acc.items.push(...comments.items);\n _acc.nextURL = comments.nextURL;\n }\n return this.#fetchComments(post, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...comments.items ] : comments.items;\n this.log('debug', `Total ${result.length} comments fetched for post #${post.id}`);\n for (const comment of result) {\n if (comment.replyCount > 0) {\n comment.replies = await this.#fetchCommentReplies(comment, signal);\n }\n }\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch comments for post #${post.id}`);\n return [];\n }\n }\n\n async #fetchCommentReplies(comment: Comment, signal?: AbortSignal, accumulated?: CommentReplyList & { nextURL: string; }): Promise<CommentReply[]> {\n if (!comment.replyCount) {\n this.log('debug', `Reply count is zero for comment #${comment.id}`);\n return [];\n }\n if (this.checkAbortSignal(signal)) {\n return [];\n }\n let repliesURL;\n if (!accumulated) {\n this.log('debug', `Fetch replies to comment #${comment.id}`);\n repliesURL = URLHelper.constructPostCommentsAPIURL({ commentId: comment.id, replies: true });\n }\n else {\n this.log('debug', `Fetch next batch of replies to comment #${comment.id}`);\n repliesURL = accumulated.nextURL;\n }\n const { json } = await this.commonFetchAPI(repliesURL, signal);\n const parser = new CommentParser(this.logger);\n if (json) {\n const replies = parser.parseCommentsAPIResponse(json, repliesURL, true);\n this.log('debug', `Fetched ${replies.items.length} replies to comment #${comment.id}`);\n if (replies.items.length > 0 && replies.nextURL) {\n let _acc;\n if (!accumulated) {\n _acc = {\n url: replies.url,\n items: replies.items,\n nextURL: replies.nextURL,\n total: replies.total\n };\n }\n else {\n _acc = accumulated;\n _acc.url = replies.url;\n _acc.items.push(...replies.items);\n _acc.nextURL = replies.nextURL;\n }\n return this.#fetchCommentReplies(comment, signal, _acc);\n }\n else {\n const result = accumulated ? [ ...accumulated.items, ...replies.items ] : replies.items;\n this.log('debug', `Total ${result.length} replies fetched for comment #${comment.id}`);\n return result;\n }\n }\n else if (this.checkAbortSignal(signal)) {\n return [];\n }\n else {\n this.log('warn', `Failed to fetch replies to comment #${comment.id}`);\n return [];\n }\n }\n\n async #saveCollection(collection: Collection, campaign: Campaign, signal?: AbortSignal) {\n const db = await this.db();\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n if (!this.config.include.contentInfo) {\n db.saveCollection(collection, campaign);\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 this.log('info', `Save collection info #${collection.id}`);\n this.emit('targetBegin', { target: collection });\n this.emit('phaseBegin', { target: collection, phase: 'saveInfo' });\n\n // Step 1: create collection directories\n const collectionDirs = this.fsHelper.getCollectionsDir(campaign, collection);\n this.log('debug', 'Campaign directories: ', collectionDirs);\n this.fsHelper.createDir(collectionDirs.root);\n\n // Step 2: save summary and raw json\n const summary = generateCollectionSummary(collection);\n const summaryFile = path.resolve(collectionDirs.root, 'info.txt');\n const saveSummaryResult = await this.fsHelper.writeTextFile(summaryFile, summary, this.config.fileExistsAction.info);\n this.logWriteTextFileResult(saveSummaryResult, collection, 'collection summary');\n\n const collectionRawFile = path.resolve(collectionDirs.root, 'collection-api.json');\n const saveCollectionRawResult = await this.fsHelper.writeTextFile(\n collectionRawFile, collection.raw, this.config.fileExistsAction.infoAPI);\n this.logWriteTextFileResult(saveCollectionRawResult, collection, 'collection API data');\n\n this.emit('phaseEnd', { target: collection, phase: 'saveInfo' });\n\n if (this.checkAbortSignal(signal)) {\n return;\n }\n\n // Step 3: download collection media items\n if (collection.thumbnail) {\n this.emit('phaseBegin', { target: collection, phase: 'saveMedia' });\n const collectionMedia: Downloadable[] = [\n collection.thumbnail\n ];\n batch = (await this.createDownloadTaskBatch(\n `Collection #${collection.id} (${collection.title})`,\n signal,\n {\n target: collectionMedia,\n targetName: `collection #${campaign.id} -> thumbnail`,\n src: collection,\n dirs: {\n campaign: this.fsHelper.getCampaignDirs(campaign).root,\n main: collectionDirs.root,\n thumbnails: null\n },\n fileExistsAction: this.config.fileExistsAction.info\n }\n )).batch;\n if (this.checkAbortSignal(signal)) {\n return;\n }\n batch.prestart();\n this.emit('phaseBegin', { target: collection, phase: 'batchDownload', batch });\n await batch.start();\n await batch.destroy();\n this.emit('phaseEnd', { target: collection, phase: 'batchDownload' });\n this.emit('phaseEnd', { target: collection, phase: 'saveMedia' });\n\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n if (this.checkAbortSignal(signal)) {\n return;\n }\n }\n\n // Step 4: save to DB\n db.saveCollection(collection, campaign);\n\n // Done\n this.log('info', 'Done saving collection info');\n this.emit('targetEnd', { target: collection, isSkipped: false });\n }\n\n}\n"]}
@@ -224,8 +224,8 @@ _PostsFetcher_pointers = new WeakMap(), _PostsFetcher_fetched = new WeakMap(), _
224
224
  __classPrivateFieldGet(this, _PostsFetcher_instances, "m", _PostsFetcher_handleError).call(this, error);
225
225
  return;
226
226
  }
227
- const postsParser = new PostParser(this.logger);
228
- const list = postsParser.parsePostsAPIResponse(json, postsSrc);
227
+ const postsParser = new PostParser(this.fetcher, this.logger);
228
+ const list = await postsParser.parsePostsAPIResponse(json, postsSrc);
229
229
  __classPrivateFieldSet(this, _PostsFetcher_fetched, [list], "f");
230
230
  __classPrivateFieldGet(this, _PostsFetcher_pointers, "f").lastFetched = __classPrivateFieldGet(this, _PostsFetcher_pointers, "f").fetching;
231
231
  __classPrivateFieldGet(this, _PostsFetcher_pointers, "f").fetching = null;
@@ -262,7 +262,7 @@ _PostsFetcher_pointers = new WeakMap(), _PostsFetcher_fetched = new WeakMap(), _
262
262
  nextURL = null;
263
263
  }
264
264
  else {
265
- const list = postsParser.parsePostsAPIResponse(json, nextURL);
265
+ const list = await postsParser.parsePostsAPIResponse(json, nextURL);
266
266
  __classPrivateFieldGet(this, _PostsFetcher_fetched, "f").push(list);
267
267
  const fetched = list.items.length;
268
268
  totalFetched += fetched;
@@ -1 +1 @@
1
- {"version":3,"file":"PostsFetcher.js","sourceRoot":"","sources":["../../src/downloaders/PostsFetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events';\nimport { type Post } from '../entities/index.js';\nimport { type Logger } from '../utils/logging/index.js';\nimport { type LogLevel, commonLog } from '../utils/logging/Logger.js';\nimport { type DownloaderConfig } from './Downloader.js';\nimport URLHelper, { PostSortOrder } from '../utils/URLHelper.js';\nimport type Fetcher from '../utils/Fetcher.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type PostList } from '../entities/Post.js';\nimport Sleeper from '../utils/Sleeper.js';\nimport { InitialData } from './InitialData.js';\nimport fse from 'fs-extra';\n\nexport type PostsFetcherStatus = {\n status: 'ready' | 'running' | 'completed' | 'aborted';\n error?: undefined;\n} | {\n status: 'error';\n error: any;\n};\n\nexport type PostsFetcherEvent = 'fetched' | 'statusChange';\nexport type PostsFetcherEventPayload<T extends PostsFetcherEvent> =\n T extends 'fetched' ? {\n list: PostList;\n index: number;\n } :\n T extends 'statusChange' ? {\n current: PostsFetcherStatus;\n old: PostsFetcherStatus;\n } :\n never;\n\nexport interface PostsFetcherResult {\n list: PostList | null;\n error?: any;\n aborted: boolean;\n}\n\nconst SLEEPER_INTERVAL = 900000; // 15 mins\n\nexport default class PostsFetcher extends EventEmitter {\n\n name = 'PostsFetcher';\n\n protected status: PostsFetcherStatus;\n protected config: DownloaderConfig<Post>;\n protected fetcher: Fetcher;\n protected signal?: AbortSignal;\n protected logger?: Logger | null;\n\n #pointers: {\n fetching: number | null;\n lastFetched: number | null;\n returning: number | null;\n lastReturned: number | null; // Last returned in next()\n };\n #fetched: PostList[];\n #total: number | null;\n #nextPromises: Array<Promise<PostsFetcherResult> | undefined>;\n #sleeper: Sleeper | null;\n #noSleep: boolean;\n\n constructor(params: {\n config: DownloaderConfig<Post>,\n fetcher: Fetcher,\n logger?: Logger | null,\n signal?: AbortSignal\n }) {\n super();\n const { config, fetcher, logger, signal } = params;\n this.config = config;\n this.fetcher = fetcher;\n this.logger = logger;\n this.signal = signal;\n this.#fetched = [];\n this.status = { status: 'ready' };\n this.#pointers = {\n fetching: null,\n lastFetched: null,\n returning: null,\n lastReturned: null\n };\n this.#nextPromises = [];\n this.#sleeper = null;\n this.#noSleep = false;\n }\n\n isFetchingMultiple() {\n return this.#isFetchingMultiplePosts(this.config.postFetch);\n }\n\n getTargetType() {\n return this.#isFetchingMultiplePosts(this.config.postFetch) ? 'posts' : 'post';\n }\n\n protected log(level: LogLevel, ...msg: any[]) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n\n #setStatus(status: PostsFetcherStatus) {\n const oldStatus = this.status;\n this.status = status;\n this.emit('statusChange', { current: status, old: oldStatus });\n }\n\n #isRunning() {\n return this.status.status === 'running';\n }\n\n begin() {\n void this.#doBegin();\n }\n\n async #doBegin() {\n if (this.status.status !== 'ready') {\n throw Error('PostsFetcher already running or has ended');\n }\n\n this.#setStatus({ status: 'running' });\n\n this.#pointers.fetching = 0;\n const postFetch = this.config.postFetch;\n \n let postsSrc: string;\n if (postFetch.type !== 'byFile') {\n try {\n postsSrc = await this.#getInitialPostsAPIURL();\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n }\n else {\n postsSrc = postFetch.filePath;\n }\n \n if (this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', 'Fetch posts');\n this.log('debug', `Request initial posts from API URL \"${postsSrc}\"`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Read post data from \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', 'Fetch target post');\n this.log('debug', `Request post #${postFetch.postId} from API URL \"${postsSrc}`);\n }\n\n let json;\n try {\n if (postFetch.type !== 'byFile') {\n json = await this.#fetchAPI(postsSrc);\n }\n else {\n json = fse.readJSONSync(postFetch.filePath);\n }\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n\n const postsParser = new PostParser(this.logger);\n const list = postsParser.parsePostsAPIResponse(json, postsSrc);\n this.#fetched = [ list ];\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: 0 });\n\n const total = this.#total = this.#fetched[0].total;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n let totalFetched = this.#fetched[0].items.length;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n let nextURL = this.#fetched[0].nextURL;\n while (nextURL) {\n let json;\n try {\n this.#pointers.fetching = this.#pointers.lastFetched !== null ? this.#pointers.lastFetched + 1 : 1;\n const sleep = !this.#pointers.returning || this.#pointers.returning < this.#pointers.fetching;\n if (sleep && !this.#sleeper) {\n this.log('debug', `Has more posts - will fetch in ${SLEEPER_INTERVAL / 1000} seconds`);\n this.#sleeper = Sleeper.getInstance(SLEEPER_INTERVAL, this.signal);\n await this.#sleeper.start();\n }\n this.log('debug', `Request more posts from API URL \"${nextURL}\"`);\n json = await this.#fetchAPI(nextURL);\n }\n catch (error) {\n this.#handleError(error);\n json = null;\n }\n finally {\n if (this.#sleeper) {\n this.#sleeper.destroy();\n this.#sleeper = null;\n }\n }\n if (!json) {\n nextURL = null;\n }\n else {\n const list = postsParser.parsePostsAPIResponse(json, nextURL);\n this.#fetched.push(list);\n const fetched = list.items.length;\n totalFetched += fetched;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n nextURL = list.nextURL;\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: this.#fetched.length - 1 });\n }\n }\n if (!this.checkAbortSignal()) {\n if (total && totalFetched < total) {\n this.log('warn', `Done, but some posts were not fetched. Total expected: ${total}; currently fetched: ${totalFetched}`);\n }\n else {\n this.log('info', `Done. ${totalFetched} posts fetched`);\n }\n\n if (this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n }\n // Set 'completed' if not fetching multiple posts\n else if (!this.checkAbortSignal() && this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n\n #handleError(error: any) {\n const statusName = this.status.status;\n if (statusName === 'aborted' || statusName === 'completed') {\n return;\n }\n if (this.signal?.aborted) {\n this.log('warn', 'Abort');\n this.#setStatus({ status: 'aborted' });\n return;\n }\n this.log('error', error);\n this.#setStatus({ status: 'error', error });\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' | 'byURL' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';\n }\n\n async #getInitialPostsAPIURL() {\n if (this.config.postFetch.type === 'byFile') {\n throw Error('Posts API URL cannot be obtained from file');\n }\n const postFetch = this.config.postFetch;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const pageURL = this.#getInitialDataPageURL();\n const { campaignId, currentUserId } = await this.getInitialData(pageURL);\n let sort: PostSortOrder | undefined;\n if (postFetch.type === 'byCollection') {\n sort = PostSortOrder.CollectionOrder;\n }\n\n return URLHelper.constructPostsAPIURL({\n campaignId,\n currentUserId: this.config.include.lockedContent ? undefined : currentUserId,\n filters: postFetch.filters,\n sort\n });\n }\n\n return URLHelper.constructPostsAPIURL({ postId: postFetch.postId });\n }\n\n #getInitialDataPageURL() {\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n return URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n case 'byUserId':\n return URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n case 'byCollection':\n return URLHelper.constructCollectionURL(postFetch.collectionId);\n case 'byURL':\n return postFetch.url;\n default:\n throw Error(`postFetch type mismatch: expecting 'byUser', 'byUserId', 'byCollection' or 'byURL' but got '${postFetch.type}'`);\n }\n }\n\n getInitialData(url: string) {\n const id = new InitialData(this.config, this.fetcher, this.logger);\n return id.get(url, this.signal);\n }\n\n async #fetchAPI(url: string) {\n return (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal: this.signal })).json;\n }\n\n protected checkAbortSignal() {\n return this.signal && this.signal.aborted;\n }\n\n hasNext() {\n const lastReturned = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned : -1;\n return this.#isRunning() || (this.#fetched.length > 0 && lastReturned < this.#fetched.length - 1);\n }\n\n async next(): Promise<PostsFetcherResult> {\n this.#pointers.returning = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned + 1 : 0;\n const ptr = this.#pointers.returning;\n this.log('debug', `next() requested (${ptr})`);\n const __parseStatus = (status: PostsFetcherStatus) => {\n let list: PostList | null | undefined;\n let aborted = false;\n let error: any;\n switch (status.status) {\n case 'aborted':\n list = null;\n aborted = true;\n break;\n case 'error':\n if (this.#fetched[ptr]) {\n list = this.#fetched[ptr];\n }\n else {\n list = null;\n error = status.error;\n }\n break;\n case 'completed':\n list = this.#fetched[ptr] || null;\n break;\n default:\n list = this.#fetched[ptr] || undefined;\n }\n return { list, aborted, error };\n };\n if (this.#isRunning() && !this.#fetched[ptr]) {\n let result = this.#nextPromises[ptr];\n if (!result) {\n let resolved = false;\n result = new Promise<PostsFetcherResult>((resolve) => {\n const fetchedListener = () => {\n if (resolved) {\n this.off('fetched', fetchedListener);\n return;\n }\n if (this.#fetched[ptr]) {\n this.off('fetched', fetchedListener);\n resolved = true;\n resolve({\n list: this.#fetched[ptr],\n aborted: false\n });\n }\n };\n const statusListener = (args: { current: PostsFetcherStatus }) => {\n if (resolved) {\n this.off('statusChange', statusListener);\n return;\n }\n const { list, aborted, error } = __parseStatus(args.current);\n if (list !== undefined) {\n this.off('statusChange', statusListener);\n resolved = true;\n resolve({ list, aborted, error });\n }\n };\n this.on('fetched', fetchedListener);\n this.on('statusChange', statusListener);\n if (!this.#noSleep) {\n this.#noSleep = true;\n }\n if (this.#sleeper) {\n this.log('debug', 'Wake up early from sleep');\n this.#sleeper.wake();\n }\n })\n .finally(() => {\n this.#nextPromises[ptr] = undefined;\n this.#noSleep = false;\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n if (resolved) {\n this.log('debug', `next() handled (${ptr})`);\n }\n else {\n this.log('debug', `next() handled (${ptr}) - no resolve`);\n }\n });\n this.#nextPromises[ptr] = result;\n }\n return result;\n }\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n this.log('debug', `next() handled (${ptr})`);\n return __parseStatus(this.status);\n }\n\n getTotal() {\n return this.#total;\n }\n\n emit<T extends PostsFetcherEvent>(eventName: T, args: PostsFetcherEventPayload<T>): boolean;\n emit(eventName: string | symbol, ...args: any[]): boolean {\n return super.emit(eventName, ...args);\n }\n\n on<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n on(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(eventName, listener);\n }\n\n off<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n off(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(eventName, listener);\n }\n}\n"]}
1
+ {"version":3,"file":"PostsFetcher.js","sourceRoot":"","sources":["../../src/downloaders/PostsFetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events';\nimport { type Post } from '../entities/index.js';\nimport { type Logger } from '../utils/logging/index.js';\nimport { type LogLevel, commonLog } from '../utils/logging/Logger.js';\nimport { type DownloaderConfig } from './Downloader.js';\nimport URLHelper, { PostSortOrder } from '../utils/URLHelper.js';\nimport type Fetcher from '../utils/Fetcher.js';\nimport PostParser from '../parsers/PostParser.js';\nimport { type PostList } from '../entities/Post.js';\nimport Sleeper from '../utils/Sleeper.js';\nimport { InitialData } from './InitialData.js';\nimport fse from 'fs-extra';\n\nexport type PostsFetcherStatus = {\n status: 'ready' | 'running' | 'completed' | 'aborted';\n error?: undefined;\n} | {\n status: 'error';\n error: any;\n};\n\nexport type PostsFetcherEvent = 'fetched' | 'statusChange';\nexport type PostsFetcherEventPayload<T extends PostsFetcherEvent> =\n T extends 'fetched' ? {\n list: PostList;\n index: number;\n } :\n T extends 'statusChange' ? {\n current: PostsFetcherStatus;\n old: PostsFetcherStatus;\n } :\n never;\n\nexport interface PostsFetcherResult {\n list: PostList | null;\n error?: any;\n aborted: boolean;\n}\n\nconst SLEEPER_INTERVAL = 900000; // 15 mins\n\nexport default class PostsFetcher extends EventEmitter {\n\n name = 'PostsFetcher';\n\n protected status: PostsFetcherStatus;\n protected config: DownloaderConfig<Post>;\n protected fetcher: Fetcher;\n protected signal?: AbortSignal;\n protected logger?: Logger | null;\n\n #pointers: {\n fetching: number | null;\n lastFetched: number | null;\n returning: number | null;\n lastReturned: number | null; // Last returned in next()\n };\n #fetched: PostList[];\n #total: number | null;\n #nextPromises: Array<Promise<PostsFetcherResult> | undefined>;\n #sleeper: Sleeper | null;\n #noSleep: boolean;\n\n constructor(params: {\n config: DownloaderConfig<Post>,\n fetcher: Fetcher,\n logger?: Logger | null,\n signal?: AbortSignal\n }) {\n super();\n const { config, fetcher, logger, signal } = params;\n this.config = config;\n this.fetcher = fetcher;\n this.logger = logger;\n this.signal = signal;\n this.#fetched = [];\n this.status = { status: 'ready' };\n this.#pointers = {\n fetching: null,\n lastFetched: null,\n returning: null,\n lastReturned: null\n };\n this.#nextPromises = [];\n this.#sleeper = null;\n this.#noSleep = false;\n }\n\n isFetchingMultiple() {\n return this.#isFetchingMultiplePosts(this.config.postFetch);\n }\n\n getTargetType() {\n return this.#isFetchingMultiplePosts(this.config.postFetch) ? 'posts' : 'post';\n }\n\n protected log(level: LogLevel, ...msg: any[]) {\n commonLog(this.logger, level, this.name, ...msg);\n }\n\n #setStatus(status: PostsFetcherStatus) {\n const oldStatus = this.status;\n this.status = status;\n this.emit('statusChange', { current: status, old: oldStatus });\n }\n\n #isRunning() {\n return this.status.status === 'running';\n }\n\n begin() {\n void this.#doBegin();\n }\n\n async #doBegin() {\n if (this.status.status !== 'ready') {\n throw Error('PostsFetcher already running or has ended');\n }\n\n this.#setStatus({ status: 'running' });\n\n this.#pointers.fetching = 0;\n const postFetch = this.config.postFetch;\n \n let postsSrc: string;\n if (postFetch.type !== 'byFile') {\n try {\n postsSrc = await this.#getInitialPostsAPIURL();\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n }\n else {\n postsSrc = postFetch.filePath;\n }\n \n if (this.#isFetchingMultiplePosts(postFetch)) {\n this.log('info', 'Fetch posts');\n this.log('debug', `Request initial posts from API URL \"${postsSrc}\"`);\n }\n else if (postFetch.type === 'byFile') {\n this.log('info', `Read post data from \"${postFetch.filePath}\"`);\n }\n else {\n this.log('info', 'Fetch target post');\n this.log('debug', `Request post #${postFetch.postId} from API URL \"${postsSrc}`);\n }\n\n let json;\n try {\n if (postFetch.type !== 'byFile') {\n json = await this.#fetchAPI(postsSrc);\n }\n else {\n json = fse.readJSONSync(postFetch.filePath);\n }\n }\n catch (error) {\n this.#handleError(error);\n return;\n }\n\n const postsParser = new PostParser(this.fetcher, this.logger);\n const list = await postsParser.parsePostsAPIResponse(json, postsSrc);\n this.#fetched = [ list ];\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: 0 });\n\n const total = this.#total = this.#fetched[0].total;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n let totalFetched = this.#fetched[0].items.length;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n let nextURL = this.#fetched[0].nextURL;\n while (nextURL) {\n let json;\n try {\n this.#pointers.fetching = this.#pointers.lastFetched !== null ? this.#pointers.lastFetched + 1 : 1;\n const sleep = !this.#pointers.returning || this.#pointers.returning < this.#pointers.fetching;\n if (sleep && !this.#sleeper) {\n this.log('debug', `Has more posts - will fetch in ${SLEEPER_INTERVAL / 1000} seconds`);\n this.#sleeper = Sleeper.getInstance(SLEEPER_INTERVAL, this.signal);\n await this.#sleeper.start();\n }\n this.log('debug', `Request more posts from API URL \"${nextURL}\"`);\n json = await this.#fetchAPI(nextURL);\n }\n catch (error) {\n this.#handleError(error);\n json = null;\n }\n finally {\n if (this.#sleeper) {\n this.#sleeper.destroy();\n this.#sleeper = null;\n }\n }\n if (!json) {\n nextURL = null;\n }\n else {\n const list = await postsParser.parsePostsAPIResponse(json, nextURL);\n this.#fetched.push(list);\n const fetched = list.items.length;\n totalFetched += fetched;\n this.log('info', `Fetched posts: ${totalFetched} / ${total}`);\n nextURL = list.nextURL;\n this.#pointers.lastFetched = this.#pointers.fetching;\n this.#pointers.fetching = null;\n this.emit('fetched', { list, index: this.#fetched.length - 1 });\n }\n }\n if (!this.checkAbortSignal()) {\n if (total && totalFetched < total) {\n this.log('warn', `Done, but some posts were not fetched. Total expected: ${total}; currently fetched: ${totalFetched}`);\n }\n else {\n this.log('info', `Done. ${totalFetched} posts fetched`);\n }\n\n if (this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n }\n // Set 'completed' if not fetching multiple posts\n else if (!this.checkAbortSignal() && this.#isRunning()) {\n this.#setStatus({ status: 'completed' });\n }\n }\n\n #handleError(error: any) {\n const statusName = this.status.status;\n if (statusName === 'aborted' || statusName === 'completed') {\n return;\n }\n if (this.signal?.aborted) {\n this.log('warn', 'Abort');\n this.#setStatus({ status: 'aborted' });\n return;\n }\n this.log('error', error);\n this.#setStatus({ status: 'error', error });\n }\n\n #isFetchingMultiplePosts(postFetch: DownloaderConfig<Post>['postFetch']): postFetch is DownloaderConfig<Post>['postFetch'] & { type: 'byUser' | 'byUserId' | 'byCollection' | 'byURL' } {\n return postFetch.type === 'byUser' || postFetch.type === 'byUserId' || postFetch.type === 'byCollection' || postFetch.type === 'byURL';\n }\n\n async #getInitialPostsAPIURL() {\n if (this.config.postFetch.type === 'byFile') {\n throw Error('Posts API URL cannot be obtained from file');\n }\n const postFetch = this.config.postFetch;\n if (this.#isFetchingMultiplePosts(postFetch)) {\n const pageURL = this.#getInitialDataPageURL();\n const { campaignId, currentUserId } = await this.getInitialData(pageURL);\n let sort: PostSortOrder | undefined;\n if (postFetch.type === 'byCollection') {\n sort = PostSortOrder.CollectionOrder;\n }\n\n return URLHelper.constructPostsAPIURL({\n campaignId,\n currentUserId: this.config.include.lockedContent ? undefined : currentUserId,\n filters: postFetch.filters,\n sort\n });\n }\n\n return URLHelper.constructPostsAPIURL({ postId: postFetch.postId });\n }\n\n #getInitialDataPageURL() {\n const postFetch = this.config.postFetch;\n switch (postFetch.type) {\n case 'byUser':\n return URLHelper.constructCampaignPageURL({ vanity: postFetch.vanity });\n case 'byUserId':\n return URLHelper.constructCampaignPageURL({ userId: postFetch.userId });\n case 'byCollection':\n return URLHelper.constructCollectionURL(postFetch.collectionId);\n case 'byURL':\n return postFetch.url;\n default:\n throw Error(`postFetch type mismatch: expecting 'byUser', 'byUserId', 'byCollection' or 'byURL' but got '${postFetch.type}'`);\n }\n }\n\n getInitialData(url: string) {\n const id = new InitialData(this.config, this.fetcher, this.logger);\n return id.get(url, this.signal);\n }\n\n async #fetchAPI(url: string) {\n return (await this.fetcher.get({ url, type: 'json', maxRetries: this.config.request.maxRetries, signal: this.signal })).json;\n }\n\n protected checkAbortSignal() {\n return this.signal && this.signal.aborted;\n }\n\n hasNext() {\n const lastReturned = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned : -1;\n return this.#isRunning() || (this.#fetched.length > 0 && lastReturned < this.#fetched.length - 1);\n }\n\n async next(): Promise<PostsFetcherResult> {\n this.#pointers.returning = this.#pointers.lastReturned !== null ? this.#pointers.lastReturned + 1 : 0;\n const ptr = this.#pointers.returning;\n this.log('debug', `next() requested (${ptr})`);\n const __parseStatus = (status: PostsFetcherStatus) => {\n let list: PostList | null | undefined;\n let aborted = false;\n let error: any;\n switch (status.status) {\n case 'aborted':\n list = null;\n aborted = true;\n break;\n case 'error':\n if (this.#fetched[ptr]) {\n list = this.#fetched[ptr];\n }\n else {\n list = null;\n error = status.error;\n }\n break;\n case 'completed':\n list = this.#fetched[ptr] || null;\n break;\n default:\n list = this.#fetched[ptr] || undefined;\n }\n return { list, aborted, error };\n };\n if (this.#isRunning() && !this.#fetched[ptr]) {\n let result = this.#nextPromises[ptr];\n if (!result) {\n let resolved = false;\n result = new Promise<PostsFetcherResult>((resolve) => {\n const fetchedListener = () => {\n if (resolved) {\n this.off('fetched', fetchedListener);\n return;\n }\n if (this.#fetched[ptr]) {\n this.off('fetched', fetchedListener);\n resolved = true;\n resolve({\n list: this.#fetched[ptr],\n aborted: false\n });\n }\n };\n const statusListener = (args: { current: PostsFetcherStatus }) => {\n if (resolved) {\n this.off('statusChange', statusListener);\n return;\n }\n const { list, aborted, error } = __parseStatus(args.current);\n if (list !== undefined) {\n this.off('statusChange', statusListener);\n resolved = true;\n resolve({ list, aborted, error });\n }\n };\n this.on('fetched', fetchedListener);\n this.on('statusChange', statusListener);\n if (!this.#noSleep) {\n this.#noSleep = true;\n }\n if (this.#sleeper) {\n this.log('debug', 'Wake up early from sleep');\n this.#sleeper.wake();\n }\n })\n .finally(() => {\n this.#nextPromises[ptr] = undefined;\n this.#noSleep = false;\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n if (resolved) {\n this.log('debug', `next() handled (${ptr})`);\n }\n else {\n this.log('debug', `next() handled (${ptr}) - no resolve`);\n }\n });\n this.#nextPromises[ptr] = result;\n }\n return result;\n }\n this.#pointers.lastReturned = this.#pointers.returning;\n this.#pointers.returning = null;\n this.log('debug', `next() handled (${ptr})`);\n return __parseStatus(this.status);\n }\n\n getTotal() {\n return this.#total;\n }\n\n emit<T extends PostsFetcherEvent>(eventName: T, args: PostsFetcherEventPayload<T>): boolean;\n emit(eventName: string | symbol, ...args: any[]): boolean {\n return super.emit(eventName, ...args);\n }\n\n on<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n on(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(eventName, listener);\n }\n\n off<T extends PostsFetcherEvent>(eventName: T, listener: (args: PostsFetcherEventPayload<T>) => void): this;\n off(eventName: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(eventName, listener);\n }\n}\n"]}
@@ -16,6 +16,7 @@ import FSHelper from '../../utils/FSHelper.js';
16
16
  import { fileTypeFromFile } from 'file-type';
17
17
  import fs from 'fs/promises';
18
18
  import { imageSize } from 'image-size';
19
+ import Sleeper from '../../utils/Sleeper.js';
19
20
  export class DownloadTaskError extends Error {
20
21
  constructor(message, task, cause) {
21
22
  super(message);
@@ -88,11 +89,20 @@ class DownloadTask {
88
89
  if (signal?.aborted) {
89
90
  throw error;
90
91
  }
91
- const willRetry = t < maxRetries ? 'will retry' : 'max reached';
92
+ const willRetry = t < maxRetries ? `will retry in ${1000 * t}ms` : 'max reached';
92
93
  const retryStr = t > 0 ? `retried ${t} times - ${willRetry}` : willRetry;
93
94
  task.log('error', `(Task create #${task.srcEntity.id}) Error resolving dest path (${retryStr}):`, error);
94
95
  err = error;
95
96
  t++;
97
+ if (t < maxRetries + 1) {
98
+ const sleeper = Sleeper.getInstance(1000 * t, signal);
99
+ try {
100
+ await sleeper.start();
101
+ }
102
+ finally {
103
+ sleeper.destroy();
104
+ }
105
+ }
96
106
  }
97
107
  }
98
108
  return {