patreon-dl 3.7.1 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/browse/api/CampaignAPIMixin.d.ts +1 -1
- package/dist/browse/api/ContentAPIMixin.d.ts +3 -3
- package/dist/browse/api/FilterAPIMixin.d.ts +1 -1
- package/dist/browse/api/index.d.ts +10 -10
- package/dist/browse/db/CampaignDBMixin.d.ts +3 -3
- package/dist/browse/db/ContentDBMixin.d.ts +13 -13
- package/dist/browse/db/ContentDBMixin.js +1 -1
- package/dist/browse/db/ContentDBMixin.js.map +1 -1
- package/dist/browse/db/MediaDBMixin.js +1 -1
- package/dist/browse/db/MediaDBMixin.js.map +1 -1
- package/dist/browse/db/index.d.ts +16 -16
- package/dist/browse/web/assets/index-CtZbx-Du.js +218 -0
- package/dist/browse/web/index.html +1 -1
- package/dist/cli/CommandLineParser.d.ts +4 -0
- package/dist/cli/CommandLineParser.js +65 -32
- package/dist/cli/CommandLineParser.js.map +1 -1
- package/dist/cli/helper/PostList.d.ts +6 -0
- package/dist/cli/helper/PostList.js +106 -0
- package/dist/cli/helper/PostList.js.map +1 -0
- package/dist/cli/index.js +73 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/downloaders/Bootstrap.d.ts +5 -0
- package/dist/downloaders/Bootstrap.js +10 -0
- package/dist/downloaders/Bootstrap.js.map +1 -1
- package/dist/downloaders/Downloader.d.ts +4 -4
- package/dist/downloaders/Downloader.js +6 -59
- package/dist/downloaders/Downloader.js.map +1 -1
- package/dist/downloaders/IncludeCriteriaHelper.d.ts +25 -0
- package/dist/downloaders/IncludeCriteriaHelper.js +160 -0
- package/dist/downloaders/IncludeCriteriaHelper.js.map +1 -0
- package/dist/downloaders/InitialData.js +20 -6
- package/dist/downloaders/InitialData.js.map +1 -1
- package/dist/downloaders/PostDownloader.js +67 -103
- package/dist/downloaders/PostDownloader.js.map +1 -1
- package/dist/downloaders/PostsFetcher.js +7 -5
- package/dist/downloaders/PostsFetcher.js.map +1 -1
- package/dist/downloaders/ProductDownloader.js +31 -21
- package/dist/downloaders/ProductDownloader.js.map +1 -1
- package/dist/downloaders/task/YouTubeDownloadTask.js +1 -3
- package/dist/downloaders/task/YouTubeDownloadTask.js.map +1 -1
- package/dist/parsers/PageParser.js +7 -2
- package/dist/parsers/PageParser.js.map +1 -1
- package/dist/parsers/PostParser.d.ts +4 -1
- package/dist/parsers/PostParser.js +54 -5
- package/dist/parsers/PostParser.js.map +1 -1
- package/dist/utils/Fetcher.d.ts +1 -0
- package/dist/utils/Fetcher.js +5 -0
- package/dist/utils/Fetcher.js.map +1 -1
- package/dist/utils/URLHelper.d.ts +4 -0
- package/dist/utils/URLHelper.js +17 -0
- package/dist/utils/URLHelper.js.map +1 -1
- package/dist/utils/YouTubeCredentialsCapturer.js +1 -1
- package/dist/utils/YouTubeCredentialsCapturer.js.map +1 -1
- package/dist/utils/logging/ConsoleLogger.js +5 -0
- package/dist/utils/logging/ConsoleLogger.js.map +1 -1
- package/dist/utils/yt/InnertubeLoader.d.ts +4 -6
- package/dist/utils/yt/InnertubeLoader.js +14 -14
- package/dist/utils/yt/InnertubeLoader.js.map +1 -1
- package/dist/utils/yt/PoToken.js +53 -27
- package/dist/utils/yt/PoToken.js.map +1 -1
- package/package.json +12 -8
- package/dist/browse/web/assets/index-B1h15ViZ.js +0 -218
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageParser.js","sourceRoot":"","sources":["../../src/parsers/PageParser.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAqB,UAAW,SAAQ,MAAM;IAA9C;;;QAEY,SAAI,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"PageParser.js","sourceRoot":"","sources":["../../src/parsers/PageParser.ts"],"names":[],"mappings":"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","sourcesContent":["import ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\n\nexport default class PageParser extends Parser {\n\n protected name = 'PageParser';\n\n parseInitialData(html: string, _url: string) {\n this.log('debug', `Parse initial data from ${_url}`);\n\n const initialDataRegex = /window\\.patreon\\s*?=\\s*?({.+?});/gm;\n const initialDataRegex2 = /<script id=\"__NEXT_DATA__\" type=\"application\\/json\">(.+)<\\/script>/gm;\n\n this.log('debug', `Trying pattern: ${initialDataRegex}`);\n const match = initialDataRegex.exec(html);\n if (match && match[1]) {\n try {\n return JSON.parse(match[1]);\n }\n catch (error: any) {\n throw Error(`Parse error: ${error instanceof Error ? error.message : error}`);\n }\n }\n this.log('debug', `No match for pattern: ${initialDataRegex}`);\n\n this.log('debug', `Trying pattern: ${initialDataRegex2}`);\n const match2 = initialDataRegex2.exec(html);\n if (match2 && match2[1]) {\n try {\n const parsed = JSON.parse(match2[1]);\n return ObjectHelper.getProperty(parsed, 'props.pageProps.bootstrapEnvelope');\n }\n catch (error: any) {\n throw Error(`Parse error: ${error instanceof Error ? error.message : error}`);\n }\n }\n this.log('debug', `No match for pattern: ${initialDataRegex2}`);\n\n this.log('debug', 'Check Next.js streaming response');\n const isNextJSStreamingResponse = html.includes('self.__next_f.push');\n if (isNextJSStreamingResponse) {\n this.log('debug', 'Detected Next.js streaming response');\n\n let currentUserId: string | null = null;\n for (const { data: currentUser } of this.#extractJsonFromKey(html, 'currentUser')) {\n if (currentUser) {\n currentUserId = ObjectHelper.getProperty(currentUser, 'data.id');\n if (currentUserId) {\n break;\n }\n }\n }\n if (!currentUserId) {\n const matchCurrentUserNullRegex = /\\\\\"currentUser\\\\\"\\s*:\\s*null/g;\n const matchCurrentUserNull = matchCurrentUserNullRegex.exec(html);\n if (!matchCurrentUserNull) {\n throw Error(`Failed to obtain initial data - \"currentUserId\" not found in Next.js streaming response`);\n }\n }\n\n const campaignIdRegex = /{\\\\\"self\\\\\":\\\\\"https:\\/\\/www\\.patreon\\.com\\/api\\/campaigns\\/(.+?)\\\\\"}/gm;\n this.log('debug', `Trying pattern in Next.js streaming response: ${campaignIdRegex}`);\n let campaignIdMatch = campaignIdRegex.exec(html);\n\n if (!campaignIdMatch || !campaignIdMatch[1]) {\n const campaignIdRegexSimple = /{\\\\\"self\\\\\":\\\\\"https:\\/\\/[^\"]+\\/api\\/campaigns\\/(.+?)\\\\\"}/gm;\n this.log('debug', `Trying fallback pattern: ${campaignIdRegexSimple}`);\n campaignIdMatch = campaignIdRegexSimple.exec(html);\n }\n\n if (!campaignIdMatch || !campaignIdMatch[1]) {\n throw Error(`Initial data not found - campaign ID not found in Next.js streaming response`);\n }\n\n const campaignId = campaignIdMatch ? campaignIdMatch[1] : undefined;\n return {\n pageBootstrap: {\n campaign: {\n data: {\n id: campaignId\n }\n }\n },\n commonBootstrap: {\n currentUser: {\n data: {\n id: currentUserId === null || currentUserId === 'null' ? undefined : currentUserId\n }\n }\n }\n };\n }\n\n throw Error('Initial data not found - no regex matches');\n }\n\n *#extractJsonFromKey(input: string, key: string) {\n const keyPattern = `\\\\\\\\\"${key}\\\\\\\\\"\\\\s*:\\\\s*{`;\n const keyRegex = new RegExp(keyPattern, 'g');\n\n let match;\n while ((match = keyRegex.exec(input)) !== null) {\n const start = match.index + match[0].length - 1; // position of opening {\n let end = start;\n let braceCount = 1;\n\n while (end < input.length && braceCount > 0) {\n end++;\n if (input[end] === '{') braceCount++;\n if (input[end] === '}') braceCount--;\n }\n\n const jsonFragment = input.slice(start, end + 1).replaceAll('\\\\', '');\n try {\n yield {\n data: JSON.parse(jsonFragment)\n };\n } catch (error) {\n this.log('debug', 'Error parsing JSON fragment:', error);\n yield {\n data: null,\n };\n }\n }\n }\n}\n"]}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { type PostList as PostList } from '../entities/Post.js';
|
|
2
2
|
import Parser from './Parser.js';
|
|
3
|
+
import type Logger from '../utils/logging/Logger.js';
|
|
4
|
+
import type Fetcher from '../utils/Fetcher.js';
|
|
3
5
|
export default class PostParser extends Parser {
|
|
4
6
|
#private;
|
|
5
7
|
protected name: string;
|
|
6
|
-
|
|
8
|
+
constructor(fetcher: Fetcher, logger?: Logger | null);
|
|
9
|
+
parsePostsAPIResponse(json: any, src: string): Promise<PostList>;
|
|
7
10
|
}
|
|
@@ -1,22 +1,31 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
1
7
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
8
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
11
|
};
|
|
6
|
-
var _PostParser_instances, _PostParser_parseContent, _PostParser_getVideoMediaItemFromAttr;
|
|
12
|
+
var _PostParser_instances, _PostParser_fetcher, _PostParser_parseContent, _PostParser_getVideoMediaItemFromAttr;
|
|
7
13
|
import { stripHtml } from 'string-strip-html';
|
|
14
|
+
import { isYouTubeEmbed } from '../entities/Downloadable.js';
|
|
8
15
|
import { PostType } from '../entities/Post.js';
|
|
9
16
|
import { pickDefined } from '../utils/Misc.js';
|
|
10
17
|
import ObjectHelper from '../utils/ObjectHelper.js';
|
|
11
18
|
import Parser from './Parser.js';
|
|
12
19
|
import URLHelper from '../utils/URLHelper.js';
|
|
13
20
|
class PostParser extends Parser {
|
|
14
|
-
constructor() {
|
|
15
|
-
super(
|
|
21
|
+
constructor(fetcher, logger) {
|
|
22
|
+
super(logger);
|
|
16
23
|
_PostParser_instances.add(this);
|
|
17
24
|
this.name = 'PostParser';
|
|
25
|
+
_PostParser_fetcher.set(this, void 0);
|
|
26
|
+
__classPrivateFieldSet(this, _PostParser_fetcher, fetcher, "f");
|
|
18
27
|
}
|
|
19
|
-
parsePostsAPIResponse(json, src) {
|
|
28
|
+
async parsePostsAPIResponse(json, src) {
|
|
20
29
|
this.log('debug', `Parse API data obtained from "${src}"`);
|
|
21
30
|
/*If (json.errors) {
|
|
22
31
|
this.log('error', `API response error:`, json.errors);
|
|
@@ -225,6 +234,46 @@ class PostParser extends Parser {
|
|
|
225
234
|
thumbnailURL: ObjectHelper.getProperty(attributes, 'image.large_url') || null // Use cover image
|
|
226
235
|
};
|
|
227
236
|
}
|
|
237
|
+
// YouTube embeds can have 0-byte thumbnail:
|
|
238
|
+
// https://github.com/patrickkfkan/patreon-dl/issues/120
|
|
239
|
+
if (embed && isYouTubeEmbed(embed) && embed.url) {
|
|
240
|
+
// Credit: @Fabelwesen (https://github.com/Fabelwesen)
|
|
241
|
+
const ytMatch = embed.url.match(/(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))([a-zA-Z0-9_-]{11})/);
|
|
242
|
+
if (ytMatch) {
|
|
243
|
+
const ytId = ytMatch[1];
|
|
244
|
+
// Use maxresdefault for best quality
|
|
245
|
+
const ytThumbnailURL = `https://img.youtube.com/vi/${ytId}/maxresdefault.jpg`;
|
|
246
|
+
if (await __classPrivateFieldGet(this, _PostParser_fetcher, "f").test(ytThumbnailURL)) {
|
|
247
|
+
this.log('debug', `Set YouTube embed thumbnail URL to "${ytThumbnailURL}"`);
|
|
248
|
+
const originalThumbnailURL = embed.thumbnailURL;
|
|
249
|
+
embed.thumbnailURL = ytThumbnailURL;
|
|
250
|
+
const __replace = (o) => {
|
|
251
|
+
Object.keys(o.imageURLs).forEach((key) => {
|
|
252
|
+
if (o?.imageURLs[key] === originalThumbnailURL) {
|
|
253
|
+
o.imageURLs[key] = ytThumbnailURL;
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
if (coverImage) {
|
|
258
|
+
__replace(coverImage);
|
|
259
|
+
}
|
|
260
|
+
if (thumbnail) {
|
|
261
|
+
__replace(thumbnail);
|
|
262
|
+
}
|
|
263
|
+
if (images) {
|
|
264
|
+
for (const img of images) {
|
|
265
|
+
__replace(img);
|
|
266
|
+
if (img.thumbnailURL === originalThumbnailURL) {
|
|
267
|
+
img.thumbnailURL = ytThumbnailURL;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
this.log('debug', `Test failed for YouTube thumbnail URL "${ytThumbnailURL}". Going to use URL from API data.`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
228
277
|
// Tiers
|
|
229
278
|
let tiers = [];
|
|
230
279
|
const tierData = ObjectHelper.getProperty(postJSON, 'relationships.access_rules.data');
|
|
@@ -320,7 +369,7 @@ class PostParser extends Parser {
|
|
|
320
369
|
}
|
|
321
370
|
;
|
|
322
371
|
}
|
|
323
|
-
_PostParser_instances = new WeakSet(), _PostParser_parseContent = function _PostParser_parseContent(data) {
|
|
372
|
+
_PostParser_fetcher = new WeakMap(), _PostParser_instances = new WeakSet(), _PostParser_parseContent = function _PostParser_parseContent(data) {
|
|
324
373
|
const { content, content_json_string } = data;
|
|
325
374
|
if (typeof content === 'string' && content.trim()) {
|
|
326
375
|
return content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostParser.js","sourceRoot":"","sources":["../../src/parsers/PostParser.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripHtml } from 'string-strip-html';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport { type AttachmentMediaItem, type AudioMediaItem, type DefaultImageMediaItem, type MediaItem, type PostCoverImageMediaItem, type PostThumbnailMediaItem, type VideoMediaItem } from '../entities/MediaItem.js';\nimport { type LinkedAttachment, PostType, type Post, type PostList as PostList, type PostEmbed, type Collection, type PostTag } from '../entities/Post.js';\nimport { type Tier } from '../entities/Reward.js';\nimport { pickDefined } from '../utils/Misc.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\nimport URLHelper from '../utils/URLHelper.js';\n\nexport default class PostParser extends Parser {\n\n protected name = 'PostParser';\n\n parsePostsAPIResponse(json: any, src: string): PostList {\n\n this.log('debug', `Parse API data obtained from \"${src}\"`);\n\n /*If (json.errors) {\n this.log('error', `API response error:`, json.errors);\n return null;\n }*/\n\n const includedJSON = json.included;\n const dataJSON = json.data;\n let postsJSONArray: any[];\n // Check if API data consists of just a single post (not an array).\n // If so, place the post data in an array.\n if (dataJSON && !Array.isArray(dataJSON) && dataJSON.type === 'post') {\n postsJSONArray = [ dataJSON ];\n }\n // If API data is an array, filter out those matching 'post' type.\n else if (dataJSON && Array.isArray(dataJSON)) {\n postsJSONArray = dataJSON.filter((data) => data.type === 'post');\n }\n else {\n // No posts found\n postsJSONArray = [];\n }\n const collection: PostList = {\n items: [],\n total: ObjectHelper.getProperty(json, 'meta.pagination.total') || null,\n // src could be a file, in which case there'll be no nextURL.\n nextURL: URLHelper.validateURL(src) ? this.parseCollectionNextURL(json, src) : null\n };\n\n let hasIncludedJSON = true;\n if (!includedJSON || !Array.isArray(includedJSON)) {\n this.log('warn', `'included' field missing in API data obtained from \"${src}\" or has incorrect type - no media items and campaign info will be returned`);\n hasIncludedJSON = false;\n }\n\n if (postsJSONArray.length === 0) {\n this.log('warn', `No posts found in API data obtained from \"${src}\"`);\n return collection;\n }\n if (postsJSONArray.length > 1) {\n this.log('debug', `${postsJSONArray.length} posts found - iterate and parse`);\n }\n else {\n this.log('debug', '1 post found - parse');\n }\n\n let campaign: Campaign | null | undefined;\n\n for (const postJSON of postsJSONArray) {\n if (!postJSON || typeof postJSON !== 'object') {\n this.log('error', 'Parse error: API data of post has incorrect type');\n continue;\n }\n\n const { id, attributes, relationships = {} } = postJSON;\n\n if (!id) {\n this.log('error', 'Parse error: \\'id\\' field missing in API data of post');\n continue;\n }\n\n this.log('debug', `Parse post #${id}`);\n\n if (!attributes || typeof attributes !== 'object') {\n this.log('error', `Parse error: 'attributes' field missing in API data of post #${id} or has incorrect type`);\n continue;\n }\n\n // Campaign info\n if (campaign === undefined) {\n const campaignId = ObjectHelper.getProperty(postJSON, 'relationships.campaign.data.id') || null;\n if (!campaignId || typeof campaignId !== 'string') {\n this.log('warn', `Campaign ID missing in API data of post #${id} or has incorrect type` +\n ' - no campaign info will be available until campaign ID is obtained');\n }\n else if (hasIncludedJSON) {\n campaign = this.findInAPIResponseIncludedArray(includedJSON, campaignId, 'campaign');\n }\n }\n\n // Viewability\n const isViewable = pickDefined(attributes.current_user_can_view, true);\n if (attributes.current_user_can_view === undefined) {\n this.log('warn', `'current_user_can_view' attribute missing in API data of post #${id} - assuming post is viewable`);\n }\n\n // Get downloadables from relationships\n let audio: Downloadable<AudioMediaItem> | null = null;\n let audioPreview: Downloadable<AudioMediaItem> | null = null;\n let images: Downloadable<DefaultImageMediaItem>[] = [];\n let attachments: Downloadable<AttachmentMediaItem>[] = [];\n if (hasIncludedJSON) {\n const downloadables = this.fetchDownloadablesFromRelationships(\n relationships,\n {\n 'audio': 'audio items',\n 'audio_preview': 'audio preview items',\n 'images': 'images',\n 'attachments_media': 'attachments'\n },\n includedJSON,\n `post #${id}`,\n false\n );\n audio = downloadables.audio?.[0] as Downloadable<AudioMediaItem> || null;\n audioPreview = downloadables.audio_preview?.[0] as Downloadable<AudioMediaItem> || null;\n images = downloadables.images as Downloadable<DefaultImageMediaItem>[] || [];\n attachments = downloadables.attachments_media as Downloadable<AttachmentMediaItem>[] || [];\n }\n\n // Post content and teaser\n const content = this.#parseContent(attributes);\n const teaserText = this.#parseContent({\n content: attributes.teaser_text,\n content_json_string: attributes.teaser_text_json_string\n });\n\n // Get inline media from content (currently only images and linked attachments supported)\n const linkedAttachments: LinkedAttachment[] = [];\n const inlineMediaBody = content || teaserText;\n if (hasIncludedJSON && inlineMediaBody) {\n const inlineMedia = this.parseInlineMedia(id, inlineMediaBody, includedJSON);\n images.push(...inlineMedia.images);\n linkedAttachments.push(...inlineMedia.linkedAttachments);\n }\n\n // Video preview\n let videoPreview: Downloadable<VideoMediaItem> | null = null;\n const vidPreviewJSON = attributes.video_preview;\n if (vidPreviewJSON && typeof vidPreviewJSON === 'object') {\n videoPreview = this.#getVideoMediaItemFromAttr(vidPreviewJSON, includedJSON, id);\n if (!videoPreview.downloadURL && !videoPreview.displayURL) {\n this.log('warn', `Video preview for post #${id} is missing URLs`);\n }\n }\n\n // Video - `postType` is 'video_external_file' and has `postFile`\n let video: Downloadable<VideoMediaItem> | null = null;\n const postFileJSON = attributes.post_file;\n const hasPostFile = postFileJSON && typeof postFileJSON === 'object';\n if (attributes.post_type === PostType.Video && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id);\n if (!video.downloadURL && !video.displayURL) {\n this.log('warn', `Video for post #${id} is missing URLs`);\n }\n }\n // Repeat for 'podcast' type - but note that `postFile` here can be audio or video.\n // We are only interested in video. For audio, info should have already been obtained\n // through relationships above.\n if (attributes.post_type === PostType.Podcast && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id, true);\n }\n\n if (attributes.post_type === PostType.Podcast && isViewable && !video && !audio) {\n this.log('warn', `Post #${id} is podcast type and is viewable, but no video or audio was found`);\n }\n\n // Cover image\n let coverImage: PostCoverImageMediaItem | null = null;\n if (attributes.image) {\n coverImage = {\n type: 'image',\n id: `post:${id}:cover`,\n filename: isViewable ? 'cover-image' : 'cover-image-preview',\n mimeType: null,\n imageType: 'postCoverImage',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'image.large_url') || null,\n thumbSquareLarge: ObjectHelper.getProperty(attributes, 'image.thumb_square_large_url') || null,\n thumbSquare: ObjectHelper.getProperty(attributes, 'image.thumb_square_url') || null,\n thumb: ObjectHelper.getProperty(attributes, 'image.thumb_url') || null,\n default: ObjectHelper.getProperty(attributes, 'image.url') || null\n }\n };\n }\n\n // Thumbnail\n let thumbnail: PostThumbnailMediaItem | null = null;\n if (attributes.thumbnail) {\n thumbnail = {\n type: 'image',\n id: `post:${id}:thumbnail`,\n filename: isViewable ? 'thumbnail' : 'thumbnail-preview',\n mimeType: null,\n imageType: 'postThumbnail',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'thumbnail.large') || null,\n large2: ObjectHelper.getProperty(attributes, 'thumbnail.large_2') || null,\n square: ObjectHelper.getProperty(attributes, 'thumbnail.square') || null,\n default: ObjectHelper.getProperty(attributes, 'thumbnail.url') || null\n }\n };\n }\n\n // Audio items doesn't have thumbnail - use first image or thumbnail\n if (audio) {\n audio.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n if (audioPreview) {\n audioPreview.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n\n // Embed\n const embedJSON = attributes.embed;\n let embed: PostEmbed | null = null;\n if (embedJSON && typeof embedJSON === 'object') {\n let embedType: PostEmbed['type'];\n switch (attributes.post_type) {\n case 'video_embed':\n embedType = 'videoEmbed';\n break;\n case 'link':\n embedType = 'linkEmbed';\n break;\n default:\n embedType = 'unknownEmbed';\n }\n embed = {\n id: `${id}-embed`,\n postId: id,\n postURL: attributes.url || null,\n type: embedType,\n description: embedJSON.descripton || null,\n html: embedJSON.html || null,\n provider: embedJSON.provider || null,\n providerURL: embedJSON.provider_url || null,\n subject: embedJSON.subject || null,\n url: embedJSON.url || null,\n thumbnailURL: ObjectHelper.getProperty(attributes, 'image.large_url') || null // Use cover image\n };\n }\n\n // Tiers\n let tiers: Tier[] = [];\n const tierData = ObjectHelper.getProperty(postJSON, 'relationships.access_rules.data');\n if (Array.isArray(tierData) && campaign) {\n const c = campaign;\n tiers = tierData.reduce<Tier[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tier = this.findInAPIResponseIncludedArray(includedJSON, id, 'tier', c);\n if (tier) {\n result.push(tier);\n }\n }\n return result;\n }, []);\n }\n if (tiers.length === 0) {\n this.log('warn', `Could not obtain tier info for post #${id}`);\n }\n\n // Collections\n let collections: Collection[] = [];\n const collectionsData = ObjectHelper.getProperty(postJSON, 'relationships.collections.data');\n if (Array.isArray(collectionsData)) {\n collections = collectionsData.reduce<Collection[]>((result, c) => {\n const id = ObjectHelper.getProperty(c, 'id');\n if (id) {\n const collection = this.findInAPIResponseIncludedArray(includedJSON, id, 'collection');\n if (collection) {\n result.push(collection);\n }\n }\n return result;\n }, []);\n }\n\n // Tags\n let tags: PostTag[] = [];\n const tagsData = ObjectHelper.getProperty(postJSON, 'relationships.user_defined_tags.data');\n if (Array.isArray(tagsData)) {\n tags = tagsData.reduce<PostTag[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tag = this.findInAPIResponseIncludedArray(includedJSON, id, 'post_tag');\n if (tag) {\n result.push(tag);\n }\n }\n return result;\n }, []);\n }\n\n const post: Post = {\n id,\n type: 'post',\n postType: attributes.post_type || null,\n isViewable,\n url: attributes.url || null,\n title: attributes.title || null,\n content,\n contentText: stripHtml(content || '').result,\n teaserText,\n publishedAt: attributes.published_at || null,\n editedAt: attributes.edited_at || null,\n commentCount: attributes.comment_count || 0,\n coverImage,\n thumbnail,\n tiers,\n collections,\n tags,\n embed,\n attachments,\n linkedAttachments,\n audio,\n audioPreview,\n images,\n videoPreview,\n video,\n campaign: null,\n raw: json\n };\n\n this.log('debug', `Done parsing post #${id}`);\n\n collection.items.push(post);\n }\n\n if (campaign) {\n this.log('debug', `Campaign #${campaign.id} found while parsing posts`);\n for (const post of collection.items) {\n post.campaign = campaign;\n }\n }\n else {\n this.log('warn', 'No campaign info found while parsing posts');\n }\n\n this.log('debug', 'Done parsing posts');\n\n return collection;\n }\n\n /**\n * Returns `content` if value is not empty.\n * Otherwise, returns HTML assembled from `content_json_string`.\n * \n * Contributed by: Fabelwesen (https://github.com/Fabelwesen)\n * Origin: https://github.com/patrickkfkan/patreon-dl/issues/119\n * \n * @param data \n * @returns HTML or null\n */\n #parseContent(data: { content?: string | null; content_json_string?: string | null }) {\n const { content, content_json_string } = data;\n if (typeof content === 'string' && content.trim()) {\n return content;\n }\n if (!content_json_string) {\n return null;\n }\n try {\n const doc = JSON.parse(content_json_string);\n let parsedHTML = '';\n\n function extractHTML(node: any) {\n if (!node) return;\n\n if (node.type === 'text') {\n if (node.marks && node.marks.find((m: any) => m.type === 'link')) {\n const linkMark = node.marks.find((m: any) => m.type === 'link');\n parsedHTML += `<a href=\"${linkMark.attrs.href}\" target=\"_blank\">${node.text || ''}</a>`;\n } else {\n // You can expand this to handle bold, italic, etc.\n parsedHTML += (String(node.text) || '');\n }\n } else if (node.type === 'paragraph' || node.type === 'heading' || node.type === 'listItem') {\n parsedHTML += '<p>';\n if (node.content && Array.isArray(node.content)) {\n node.content.forEach(extractHTML);\n }\n parsedHTML += '</p>';\n } else if (node.type === 'image') {\n // Ensure media_id is passed so the local web server can link downloaded assets\n const mediaIdAttr = (node.attrs && node.attrs.media_id) ? `data-media-id=\"${node.attrs.media_id}\" ` : '';\n const srcAttr = (node.attrs && node.attrs.src) ? node.attrs.src : '';\n parsedHTML += `<img ${mediaIdAttr}src=\"${srcAttr}\" />`;\n } else if (node.content && Array.isArray(node.content)) {\n node.content.forEach(extractHTML);\n }\n }\n\n extractHTML(doc);\n return parsedHTML;\n } catch (e) {\n this.log('warn', 'Failed to parse content_json_string:', e);\n }\n return null;\n }\n\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict: true): VideoMediaItem | null;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict?: false): VideoMediaItem;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict = false) {\n let miFromIncluded: MediaItem | null = null;\n const _mediaId = attrJSON.media_id !== undefined ? attrJSON.media_id.toString() : null;\n const hasIncludedJSON = includedJSON && Array.isArray(includedJSON)\n if (_mediaId && hasIncludedJSON) {\n // Fetch item from 'included' array, matching `media_id`\n miFromIncluded = this.findInAPIResponseIncludedArray(includedJSON, _mediaId, 'media', 'video');\n }\n const vidInc = miFromIncluded && miFromIncluded.type === 'video' ? miFromIncluded : null;\n if (strict && !miFromIncluded) {\n return null;\n }\n const mediaId = _mediaId || postId; // Fallback to post ID\n\n const { download_url: downloadURL = null, url: displayURL = null } = attrJSON;\n\n // Convert `attrJSON` to Downloadable (VideoMediaItem)\n return {\n type: 'video',\n id: mediaId,\n filename: vidInc?.filename || null,\n mimeType: vidInc?.mimeType || null,\n createdAt: vidInc?.createdAt || null,\n size: {\n width: attrJSON.width || vidInc?.size.width,\n height: attrJSON.height || vidInc?.size.height\n },\n duration: attrJSON.duration || vidInc?.duration,\n downloadURL: downloadURL || vidInc?.downloadURL,\n displayURL: displayURL || vidInc?.downloadURL,\n thumbnailURL: vidInc?.thumbnailURL || null\n };\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PostParser.js","sourceRoot":"","sources":["../../src/parsers/PostParser.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripHtml } from 'string-strip-html';\nimport { type Campaign } from '../entities/Campaign.js';\nimport { isYouTubeEmbed, type Downloadable } from '../entities/Downloadable.js';\nimport { type AttachmentMediaItem, type AudioMediaItem, type DefaultImageMediaItem, type MediaItem, type PostCoverImageMediaItem, type PostThumbnailMediaItem, type VideoMediaItem } from '../entities/MediaItem.js';\nimport { type LinkedAttachment, PostType, type Post, type PostList as PostList, type PostEmbed, type Collection, type PostTag } from '../entities/Post.js';\nimport { type Tier } from '../entities/Reward.js';\nimport { pickDefined } from '../utils/Misc.js';\nimport ObjectHelper from '../utils/ObjectHelper.js';\nimport Parser from './Parser.js';\nimport URLHelper from '../utils/URLHelper.js';\nimport type Logger from '../utils/logging/Logger.js';\nimport type Fetcher from '../utils/Fetcher.js';\n\nexport default class PostParser extends Parser {\n\n protected name = 'PostParser';\n\n #fetcher: Fetcher;\n\n constructor(fetcher: Fetcher, logger?: Logger | null) {\n super(logger);\n this.#fetcher = fetcher;\n }\n\n async parsePostsAPIResponse(json: any, src: string): Promise<PostList> {\n\n this.log('debug', `Parse API data obtained from \"${src}\"`);\n\n /*If (json.errors) {\n this.log('error', `API response error:`, json.errors);\n return null;\n }*/\n\n const includedJSON = json.included;\n const dataJSON = json.data;\n let postsJSONArray: any[];\n // Check if API data consists of just a single post (not an array).\n // If so, place the post data in an array.\n if (dataJSON && !Array.isArray(dataJSON) && dataJSON.type === 'post') {\n postsJSONArray = [ dataJSON ];\n }\n // If API data is an array, filter out those matching 'post' type.\n else if (dataJSON && Array.isArray(dataJSON)) {\n postsJSONArray = dataJSON.filter((data) => data.type === 'post');\n }\n else {\n // No posts found\n postsJSONArray = [];\n }\n const collection: PostList = {\n items: [],\n total: ObjectHelper.getProperty(json, 'meta.pagination.total') || null,\n // src could be a file, in which case there'll be no nextURL.\n nextURL: URLHelper.validateURL(src) ? this.parseCollectionNextURL(json, src) : null\n };\n\n let hasIncludedJSON = true;\n if (!includedJSON || !Array.isArray(includedJSON)) {\n this.log('warn', `'included' field missing in API data obtained from \"${src}\" or has incorrect type - no media items and campaign info will be returned`);\n hasIncludedJSON = false;\n }\n\n if (postsJSONArray.length === 0) {\n this.log('warn', `No posts found in API data obtained from \"${src}\"`);\n return collection;\n }\n if (postsJSONArray.length > 1) {\n this.log('debug', `${postsJSONArray.length} posts found - iterate and parse`);\n }\n else {\n this.log('debug', '1 post found - parse');\n }\n\n let campaign: Campaign | null | undefined;\n\n for (const postJSON of postsJSONArray) {\n if (!postJSON || typeof postJSON !== 'object') {\n this.log('error', 'Parse error: API data of post has incorrect type');\n continue;\n }\n\n const { id, attributes, relationships = {} } = postJSON;\n\n if (!id) {\n this.log('error', 'Parse error: \\'id\\' field missing in API data of post');\n continue;\n }\n\n this.log('debug', `Parse post #${id}`);\n\n if (!attributes || typeof attributes !== 'object') {\n this.log('error', `Parse error: 'attributes' field missing in API data of post #${id} or has incorrect type`);\n continue;\n }\n\n // Campaign info\n if (campaign === undefined) {\n const campaignId = ObjectHelper.getProperty(postJSON, 'relationships.campaign.data.id') || null;\n if (!campaignId || typeof campaignId !== 'string') {\n this.log('warn', `Campaign ID missing in API data of post #${id} or has incorrect type` +\n ' - no campaign info will be available until campaign ID is obtained');\n }\n else if (hasIncludedJSON) {\n campaign = this.findInAPIResponseIncludedArray(includedJSON, campaignId, 'campaign');\n }\n }\n\n // Viewability\n const isViewable = pickDefined(attributes.current_user_can_view, true);\n if (attributes.current_user_can_view === undefined) {\n this.log('warn', `'current_user_can_view' attribute missing in API data of post #${id} - assuming post is viewable`);\n }\n\n // Get downloadables from relationships\n let audio: Downloadable<AudioMediaItem> | null = null;\n let audioPreview: Downloadable<AudioMediaItem> | null = null;\n let images: Downloadable<DefaultImageMediaItem>[] = [];\n let attachments: Downloadable<AttachmentMediaItem>[] = [];\n if (hasIncludedJSON) {\n const downloadables = this.fetchDownloadablesFromRelationships(\n relationships,\n {\n 'audio': 'audio items',\n 'audio_preview': 'audio preview items',\n 'images': 'images',\n 'attachments_media': 'attachments'\n },\n includedJSON,\n `post #${id}`,\n false\n );\n audio = downloadables.audio?.[0] as Downloadable<AudioMediaItem> || null;\n audioPreview = downloadables.audio_preview?.[0] as Downloadable<AudioMediaItem> || null;\n images = downloadables.images as Downloadable<DefaultImageMediaItem>[] || [];\n attachments = downloadables.attachments_media as Downloadable<AttachmentMediaItem>[] || [];\n }\n\n // Post content and teaser\n const content = this.#parseContent(attributes);\n const teaserText = this.#parseContent({\n content: attributes.teaser_text,\n content_json_string: attributes.teaser_text_json_string\n });\n\n // Get inline media from content (currently only images and linked attachments supported)\n const linkedAttachments: LinkedAttachment[] = [];\n const inlineMediaBody = content || teaserText;\n if (hasIncludedJSON && inlineMediaBody) {\n const inlineMedia = this.parseInlineMedia(id, inlineMediaBody, includedJSON);\n images.push(...inlineMedia.images);\n linkedAttachments.push(...inlineMedia.linkedAttachments);\n }\n\n // Video preview\n let videoPreview: Downloadable<VideoMediaItem> | null = null;\n const vidPreviewJSON = attributes.video_preview;\n if (vidPreviewJSON && typeof vidPreviewJSON === 'object') {\n videoPreview = this.#getVideoMediaItemFromAttr(vidPreviewJSON, includedJSON, id);\n if (!videoPreview.downloadURL && !videoPreview.displayURL) {\n this.log('warn', `Video preview for post #${id} is missing URLs`);\n }\n }\n\n // Video - `postType` is 'video_external_file' and has `postFile`\n let video: Downloadable<VideoMediaItem> | null = null;\n const postFileJSON = attributes.post_file;\n const hasPostFile = postFileJSON && typeof postFileJSON === 'object';\n if (attributes.post_type === PostType.Video && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id);\n if (!video.downloadURL && !video.displayURL) {\n this.log('warn', `Video for post #${id} is missing URLs`);\n }\n }\n // Repeat for 'podcast' type - but note that `postFile` here can be audio or video.\n // We are only interested in video. For audio, info should have already been obtained\n // through relationships above.\n if (attributes.post_type === PostType.Podcast && hasPostFile) {\n video = this.#getVideoMediaItemFromAttr(postFileJSON, includedJSON, id, true);\n }\n\n if (attributes.post_type === PostType.Podcast && isViewable && !video && !audio) {\n this.log('warn', `Post #${id} is podcast type and is viewable, but no video or audio was found`);\n }\n\n // Cover image\n let coverImage: PostCoverImageMediaItem | null = null;\n if (attributes.image) {\n coverImage = {\n type: 'image',\n id: `post:${id}:cover`,\n filename: isViewable ? 'cover-image' : 'cover-image-preview',\n mimeType: null,\n imageType: 'postCoverImage',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'image.large_url') || null,\n thumbSquareLarge: ObjectHelper.getProperty(attributes, 'image.thumb_square_large_url') || null,\n thumbSquare: ObjectHelper.getProperty(attributes, 'image.thumb_square_url') || null,\n thumb: ObjectHelper.getProperty(attributes, 'image.thumb_url') || null,\n default: ObjectHelper.getProperty(attributes, 'image.url') || null\n }\n };\n }\n\n // Thumbnail\n let thumbnail: PostThumbnailMediaItem | null = null;\n if (attributes.thumbnail) {\n thumbnail = {\n type: 'image',\n id: `post:${id}:thumbnail`,\n filename: isViewable ? 'thumbnail' : 'thumbnail-preview',\n mimeType: null,\n imageType: 'postThumbnail',\n imageURLs: {\n large: ObjectHelper.getProperty(attributes, 'thumbnail.large') || null,\n large2: ObjectHelper.getProperty(attributes, 'thumbnail.large_2') || null,\n square: ObjectHelper.getProperty(attributes, 'thumbnail.square') || null,\n default: ObjectHelper.getProperty(attributes, 'thumbnail.url') || null\n }\n };\n }\n\n // Audio items doesn't have thumbnail - use first image or thumbnail\n if (audio) {\n audio.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n if (audioPreview) {\n audioPreview.thumbnailURL =\n images[0]?.imageURLs.default ||\n thumbnail?.imageURLs.default || null;\n }\n\n // Embed\n const embedJSON = attributes.embed;\n let embed: PostEmbed | null = null;\n if (embedJSON && typeof embedJSON === 'object') {\n let embedType: PostEmbed['type'];\n switch (attributes.post_type) {\n case 'video_embed':\n embedType = 'videoEmbed';\n break;\n case 'link':\n embedType = 'linkEmbed';\n break;\n default:\n embedType = 'unknownEmbed';\n }\n embed = {\n id: `${id}-embed`,\n postId: id,\n postURL: attributes.url || null,\n type: embedType,\n description: embedJSON.descripton || null,\n html: embedJSON.html || null,\n provider: embedJSON.provider || null,\n providerURL: embedJSON.provider_url || null,\n subject: embedJSON.subject || null,\n url: embedJSON.url || null,\n thumbnailURL: ObjectHelper.getProperty(attributes, 'image.large_url') || null // Use cover image\n };\n }\n // YouTube embeds can have 0-byte thumbnail:\n // https://github.com/patrickkfkan/patreon-dl/issues/120\n if (embed && isYouTubeEmbed(embed) && embed.url) {\n // Credit: @Fabelwesen (https://github.com/Fabelwesen)\n const ytMatch = embed.url.match(/(?:youtu\\.be\\/|youtube\\.com\\/(?:embed\\/|v\\/|watch\\?v=|watch\\?.+&v=))([a-zA-Z0-9_-]{11})/);\n if (ytMatch) {\n const ytId = ytMatch[1];\n // Use maxresdefault for best quality\n const ytThumbnailURL = `https://img.youtube.com/vi/${ytId}/maxresdefault.jpg`;\n if (await this.#fetcher.test(ytThumbnailURL)) {\n this.log('debug', `Set YouTube embed thumbnail URL to \"${ytThumbnailURL}\"`);\n const originalThumbnailURL = embed.thumbnailURL;\n embed.thumbnailURL = ytThumbnailURL;\n const __replace = (o: { imageURLs: Record<string, string | null | undefined> }) => {\n Object.keys(o.imageURLs).forEach((key) => {\n if (o?.imageURLs[key] === originalThumbnailURL) {\n o.imageURLs[key] = ytThumbnailURL;\n }\n });\n }\n if (coverImage) {\n __replace(coverImage);\n }\n if (thumbnail) {\n __replace(thumbnail);\n }\n if (images) {\n for (const img of images) {\n __replace(img);\n if (img.thumbnailURL === originalThumbnailURL) {\n img.thumbnailURL = ytThumbnailURL;\n }\n }\n }\n }\n else {\n this.log('debug', `Test failed for YouTube thumbnail URL \"${ytThumbnailURL}\". Going to use URL from API data.`);\n }\n }\n }\n\n // Tiers\n let tiers: Tier[] = [];\n const tierData = ObjectHelper.getProperty(postJSON, 'relationships.access_rules.data');\n if (Array.isArray(tierData) && campaign) {\n const c = campaign;\n tiers = tierData.reduce<Tier[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tier = this.findInAPIResponseIncludedArray(includedJSON, id, 'tier', c);\n if (tier) {\n result.push(tier);\n }\n }\n return result;\n }, []);\n }\n if (tiers.length === 0) {\n this.log('warn', `Could not obtain tier info for post #${id}`);\n }\n\n // Collections\n let collections: Collection[] = [];\n const collectionsData = ObjectHelper.getProperty(postJSON, 'relationships.collections.data');\n if (Array.isArray(collectionsData)) {\n collections = collectionsData.reduce<Collection[]>((result, c) => {\n const id = ObjectHelper.getProperty(c, 'id');\n if (id) {\n const collection = this.findInAPIResponseIncludedArray(includedJSON, id, 'collection');\n if (collection) {\n result.push(collection);\n }\n }\n return result;\n }, []);\n }\n\n // Tags\n let tags: PostTag[] = [];\n const tagsData = ObjectHelper.getProperty(postJSON, 'relationships.user_defined_tags.data');\n if (Array.isArray(tagsData)) {\n tags = tagsData.reduce<PostTag[]>((result, t) => {\n const id = ObjectHelper.getProperty(t, 'id');\n if (id) {\n const tag = this.findInAPIResponseIncludedArray(includedJSON, id, 'post_tag');\n if (tag) {\n result.push(tag);\n }\n }\n return result;\n }, []);\n }\n\n const post: Post = {\n id,\n type: 'post',\n postType: attributes.post_type || null,\n isViewable,\n url: attributes.url || null,\n title: attributes.title || null,\n content,\n contentText: stripHtml(content || '').result,\n teaserText,\n publishedAt: attributes.published_at || null,\n editedAt: attributes.edited_at || null,\n commentCount: attributes.comment_count || 0,\n coverImage,\n thumbnail,\n tiers,\n collections,\n tags,\n embed,\n attachments,\n linkedAttachments,\n audio,\n audioPreview,\n images,\n videoPreview,\n video,\n campaign: null,\n raw: json\n };\n\n this.log('debug', `Done parsing post #${id}`);\n\n collection.items.push(post);\n }\n\n if (campaign) {\n this.log('debug', `Campaign #${campaign.id} found while parsing posts`);\n for (const post of collection.items) {\n post.campaign = campaign;\n }\n }\n else {\n this.log('warn', 'No campaign info found while parsing posts');\n }\n\n this.log('debug', 'Done parsing posts');\n\n return collection;\n }\n\n /**\n * Returns `content` if value is not empty.\n * Otherwise, returns HTML assembled from `content_json_string`.\n * \n * Contributed by: Fabelwesen (https://github.com/Fabelwesen)\n * Origin: https://github.com/patrickkfkan/patreon-dl/issues/119\n * \n * @param data \n * @returns HTML or null\n */\n #parseContent(data: { content?: string | null; content_json_string?: string | null }) {\n const { content, content_json_string } = data;\n if (typeof content === 'string' && content.trim()) {\n return content;\n }\n if (!content_json_string) {\n return null;\n }\n try {\n const doc = JSON.parse(content_json_string);\n let parsedHTML = '';\n\n function extractHTML(node: any) {\n if (!node) return;\n\n if (node.type === 'text') {\n if (node.marks && node.marks.find((m: any) => m.type === 'link')) {\n const linkMark = node.marks.find((m: any) => m.type === 'link');\n parsedHTML += `<a href=\"${linkMark.attrs.href}\" target=\"_blank\">${node.text || ''}</a>`;\n } else {\n // You can expand this to handle bold, italic, etc.\n parsedHTML += (String(node.text) || '');\n }\n } else if (node.type === 'paragraph' || node.type === 'heading' || node.type === 'listItem') {\n parsedHTML += '<p>';\n if (node.content && Array.isArray(node.content)) {\n node.content.forEach(extractHTML);\n }\n parsedHTML += '</p>';\n } else if (node.type === 'image') {\n // Ensure media_id is passed so the local web server can link downloaded assets\n const mediaIdAttr = (node.attrs && node.attrs.media_id) ? `data-media-id=\"${node.attrs.media_id}\" ` : '';\n const srcAttr = (node.attrs && node.attrs.src) ? node.attrs.src : '';\n parsedHTML += `<img ${mediaIdAttr}src=\"${srcAttr}\" />`;\n } else if (node.content && Array.isArray(node.content)) {\n node.content.forEach(extractHTML);\n }\n }\n\n extractHTML(doc);\n return parsedHTML;\n } catch (e) {\n this.log('warn', 'Failed to parse content_json_string:', e);\n }\n return null;\n }\n\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict: true): VideoMediaItem | null;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict?: false): VideoMediaItem;\n #getVideoMediaItemFromAttr(attrJSON: any, includedJSON: any, postId: string, strict = false) {\n let miFromIncluded: MediaItem | null = null;\n const _mediaId = attrJSON.media_id !== undefined ? attrJSON.media_id.toString() : null;\n const hasIncludedJSON = includedJSON && Array.isArray(includedJSON)\n if (_mediaId && hasIncludedJSON) {\n // Fetch item from 'included' array, matching `media_id`\n miFromIncluded = this.findInAPIResponseIncludedArray(includedJSON, _mediaId, 'media', 'video');\n }\n const vidInc = miFromIncluded && miFromIncluded.type === 'video' ? miFromIncluded : null;\n if (strict && !miFromIncluded) {\n return null;\n }\n const mediaId = _mediaId || postId; // Fallback to post ID\n\n const { download_url: downloadURL = null, url: displayURL = null } = attrJSON;\n\n // Convert `attrJSON` to Downloadable (VideoMediaItem)\n return {\n type: 'video',\n id: mediaId,\n filename: vidInc?.filename || null,\n mimeType: vidInc?.mimeType || null,\n createdAt: vidInc?.createdAt || null,\n size: {\n width: attrJSON.width || vidInc?.size.width,\n height: attrJSON.height || vidInc?.size.height\n },\n duration: attrJSON.duration || vidInc?.duration,\n downloadURL: downloadURL || vidInc?.downloadURL,\n displayURL: displayURL || vidInc?.downloadURL,\n thumbnailURL: vidInc?.thumbnailURL || null\n };\n };\n}\n"]}
|
package/dist/utils/Fetcher.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export default class Fetcher {
|
|
|
59
59
|
}>;
|
|
60
60
|
abort: () => void;
|
|
61
61
|
}>;
|
|
62
|
+
test(url: string): Promise<boolean>;
|
|
62
63
|
getPageWithPuppeteer(url: string): Promise<string>;
|
|
63
64
|
protected log(level: LogLevel, ...msg: Array<any>): void;
|
|
64
65
|
get proxyAgent(): Dispatcher | undefined;
|
package/dist/utils/Fetcher.js
CHANGED
|
@@ -191,6 +191,11 @@ class Fetcher {
|
|
|
191
191
|
}
|
|
192
192
|
return undefined;
|
|
193
193
|
}
|
|
194
|
+
async test(url) {
|
|
195
|
+
const request = new Request(url, { method: 'HEAD' });
|
|
196
|
+
const res = await fetch(request, { dispatcher: __classPrivateFieldGet(this, _Fetcher_proxyAgent, "f") });
|
|
197
|
+
return res.ok;
|
|
198
|
+
}
|
|
194
199
|
async getPageWithPuppeteer(url) {
|
|
195
200
|
this.log('debug', `Fetch "${url}" with Puppeteer`);
|
|
196
201
|
const browser = await puppeteer.launch({ headless: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Fetcher.js","sourceRoot":"","sources":["../../src/utils/Fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport { pipeline } from 'stream/promises';\nimport { fetch, Request, type Response } from 'undici';\nimport path from 'path';\nimport { type Dispatcher } from 'undici';\nimport puppeteer from 'puppeteer';\nimport FetcherProgressMonitor from './FetcherProgressMonitor.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport type FilenameResolver from './FllenameResolver.js';\nimport { pickDefined } from './Misc.js';\nimport {type LogLevel} from './logging/Logger.js';\nimport type Logger from './logging/Logger.js';\nimport { commonLog } from './logging/Logger.js';\nimport FSHelper from './FSHelper.js';\nimport { type DownloaderConfig } from '../downloaders/Downloader.js';\nimport Progress from './Progress.js';\nimport { createProxyAgent } from './Proxy.js';\nimport { SITE_URL } from './URLHelper.js';\n\nexport interface PrepareDownloadParams<T extends Downloadable> {\n url: string;\n srcEntity: T;\n destFilePath: string;\n setReferer?: boolean;\n signal: AbortSignal;\n}\n\nexport interface StartDownloadOverrides {\n destFilePath?: string;\n tmpFilePath?: string;\n}\n\nexport class FetcherError extends Error {\n\n url: string;\n method: string;\n\n constructor(message: string, url: string, method: string) {\n super(message);\n this.name = 'FetcherError';\n this.url = url;\n this.method = method;\n }\n}\n\nexport type FetcherGetType = 'html' | 'm3u8' | 'json';\nexport type FetcherGetResultOf<T extends FetcherGetType> =\n T extends 'html' ? { html: string; lastUrl: string; }:\n T extends 'm3u8' ? { contents: string; lastUrl: string; }:\n T extends 'json' ? { json: any; lastUrl: string; } :\n never;\n\nexport default class Fetcher {\n\n name = 'Fetcher';\n\n #cookie?: string;\n #logger?: Logger | null;\n #dryRun: boolean;\n #fsHelper: FSHelper;\n #proxyAgent?: Dispatcher;\n #userAgent: string;\n\n constructor(config: DownloaderConfig<any>, logger?: Logger | null) {\n this.#cookie = config.cookie;\n this.#logger = logger;\n this.#dryRun = config.dryRun;\n this.#fsHelper = new FSHelper(config, logger);\n this.#proxyAgent = createProxyAgent(config)?.agent || undefined;\n this.#userAgent = config.request.userAgent;\n }\n\n async get<T extends FetcherGetType>(args: {\n url: string,\n type: T,\n payload?: Record<string, any>,\n maxRetries: number,\n signal?: AbortSignal\n }, rt = 0): Promise<FetcherGetResultOf<T>> {\n\n const { url, type, payload, maxRetries, signal } = args;\n\n const urlObj = new URL(url);\n if (payload) {\n for (const [ p, v ] of Object.entries(payload)) {\n urlObj.searchParams.set(p, v);\n }\n }\n const request = new Request(urlObj, { method: 'GET' });\n this.#setHeaders(request, type, type === 'm3u8' ? { setReferer: true } : {});\n const internalAbortController = new AbortController();\n let removeAbortHandler: undefined | (() => void) = undefined;\n if (signal) {\n const abortHandler = () => internalAbortController.abort();\n signal.addEventListener('abort', abortHandler, {once: true});\n removeAbortHandler = () => signal.removeEventListener('abort', abortHandler);\n }\n try {\n const res = await fetch(request, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n const lastUrl = res.url;\n switch (type) {\n case 'html':\n return {\n html: await res.text(),\n lastUrl\n } as FetcherGetResultOf<T>;\n case 'm3u8':\n return {\n contents: await res.text(),\n lastUrl\n } as FetcherGetResultOf<T>;\n case 'json':\n return {\n json: await res.json(),\n lastUrl\n } as FetcherGetResultOf<T>;\n default:\n return undefined as never;\n }\n }\n catch (error: any) {\n if (signal?.aborted) {\n throw error;\n }\n if (rt < maxRetries) {\n if (removeAbortHandler) removeAbortHandler();\n return await this.get({ url, type, payload, maxRetries, signal }, rt + 1);\n }\n let errMsg;\n if (error instanceof Error) {\n const errMsgParts = [error.message];\n let _err = error.cause;\n while (_err) {\n errMsgParts.push(_err instanceof Error ? _err.message : JSON.stringify(_err));\n _err = _err instanceof Error ? _err.cause : null;\n }\n errMsg = errMsgParts.join(': ');\n }\n else {\n errMsg = String(error);\n }\n const retriedMsg = rt > 0 ? ` (retried ${rt} times)` : '';\n throw new FetcherError(`${errMsg}${retriedMsg}`, urlObj.toString(), request.method);\n }\n finally {\n if (removeAbortHandler) removeAbortHandler();\n }\n }\n\n async resolveDestFilePath<T extends Downloadable>(params: {\n url: string;\n destDir: string;\n destFilenameResolver: FilenameResolver<T>;\n setReferer?: boolean;\n signal?: AbortSignal;\n }) {\n const { url, destDir, destFilenameResolver, setReferer = false, signal } = params;\n const request = new Request(url, { method: 'HEAD' });\n this.#setHeaders(request, 'html', { setCookie: false, setHost: false, setReferer });\n const internalAbortController = new AbortController();\n const abortHandler = () => internalAbortController.abort();\n if (signal) {\n signal.addEventListener('abort', abortHandler, {once: true});\n }\n\n try {\n const res = await fetch(request, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n\n if (this.#assertResponseOK(res, url, request.method, false)) {\n const destFilename = destFilenameResolver.resolve(res);\n const destFilePath = path.resolve(destDir, destFilename);\n return destFilePath;\n }\n }\n finally {\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n }\n\n return undefined as never;\n }\n\n async prepareDownload<T extends Downloadable>(params: PrepareDownloadParams<T>) {\n const { url, srcEntity, destFilePath, setReferer = false, signal } = params;\n const request = new Request(url, { method: 'GET' });\n this.#setHeaders(request, 'html', { setCookie: false, setHost: false, setReferer });\n const internalAbortController = new AbortController();\n let removeAbortHandler: undefined | (() => void) = undefined;\n if (signal) {\n const abortHandler = () => internalAbortController.abort();\n signal.addEventListener('abort', abortHandler, {once: true});\n removeAbortHandler = () => signal.removeEventListener('abort', abortHandler);\n }\n\n try {\n let res = await fetch(request, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n\n // Special handling for attachment\n if (params.srcEntity.type === 'attachment' && !res.ok && res.redirected && res.url) {\n const redirectReq = new Request(res.url, { method: 'GET' });\n this.#setHeaders(redirectReq, 'html', { setCookie: false, setHost: false });\n res = await fetch(redirectReq, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n }\n\n if (this.#assertResponseOK(res, url, request.method)) {\n const destFilename = path.parse(destFilePath).base;\n const progress = new Progress(res, {\n reportInterval: 300\n });\n const monitor = new FetcherProgressMonitor(progress, destFilename, destFilePath);\n\n const _res = res;\n const start = (overrides?: StartDownloadOverrides) => {\n const _destFilePath = overrides?.destFilePath || destFilePath;\n const _tmpFilePath = overrides?.tmpFilePath || FSHelper.createTmpFilePath(_destFilePath, srcEntity.id);\n return this.#startDownload(_res, _tmpFilePath, _destFilePath, progress, removeAbortHandler)\n };\n const abort = () => {\n if (removeAbortHandler) removeAbortHandler();\n internalAbortController.abort();\n };\n\n return {\n monitor,\n start,\n abort\n };\n }\n }\n catch (error: unknown) {\n if (removeAbortHandler) removeAbortHandler();\n throw error;\n }\n\n return undefined as never;\n }\n\n async #startDownload(\n response: Response & { body: NodeJS.ReadableStream },\n tmpFilePath: string,\n destFilePath: string,\n progress: Progress,\n cleanup?: () => void) {\n\n try {\n let size = 0;\n if (this.#dryRun) {\n try {\n for await (const chunk of response.body) {\n size += chunk.length as number;\n }\n }\n catch (_error: unknown) {\n // Do nothing\n }\n }\n else {\n this.log('debug', `Pipe \"${response.url}\" to \"${tmpFilePath}\"`);\n await pipeline(\n response.body,\n progress.stream,\n fs.createWriteStream(tmpFilePath)\n );\n size = fs.lstatSync(tmpFilePath).size;\n }\n\n const commit = () => {\n this.#commitDownload(tmpFilePath, destFilePath, size, cleanup);\n };\n\n const discard = () => {\n this.#cleanupDownload(tmpFilePath, cleanup);\n };\n\n return {\n tmpFilePath,\n commit,\n discard\n };\n }\n catch (error) {\n this.#cleanupDownload(tmpFilePath, cleanup);\n throw error;\n }\n }\n\n #commitDownload(tmpFilePath: string, destFilePath: string, size: number, cleanup?: () => void) {\n try {\n this.log('debug', `Commit \"${tmpFilePath}\" to \"${destFilePath}; filesize: ${size} bytes`);\n this.#fsHelper.rename(tmpFilePath, destFilePath);\n }\n finally {\n this.#cleanupDownload(tmpFilePath, cleanup);\n }\n }\n\n #cleanupDownload(tmpFilePath: string, extra?: () => void) {\n try {\n if (this.#dryRun || fs.existsSync(tmpFilePath)) {\n this.log('debug', `Clean up \"${tmpFilePath}\"`);\n this.#fsHelper.unlink(tmpFilePath);\n }\n }\n catch (error) {\n this.log('error', `Error cleaning up \"${tmpFilePath}:`, error);\n }\n finally {\n if (extra) extra();\n }\n }\n\n #setHeaders(request: Request, type: FetcherGetType, opts?: { setCookie?: boolean; setHost?: boolean; setReferer?: boolean; }) {\n const setCookie = pickDefined(opts?.setCookie, true);\n const setHost = pickDefined(opts?.setHost, true);\n const setReferer = pickDefined(opts?.setReferer, false);\n if (this.#cookie && setCookie) {\n request.headers.set('Cookie', this.#cookie);\n }\n if (setHost) {\n request.headers.set('Host', 'www.patreon.com');\n }\n if (setReferer) {\n request.headers.set('referer', SITE_URL);\n }\n request.headers.set('User-Agent', this.#userAgent);\n if (type === 'json') {\n request.headers.set('Content-Type', 'application/vnd.api+json');\n }\n else {\n request.headers.set('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8');\n }\n }\n\n #assertResponseOK(response: Response | null, originURL: string, method: string, requireBody: false): response is Response;\n #assertResponseOK(response: Response | null, originURL: string, method: string, requireBody?: true): response is Response & { body: NodeJS.ReadableStream };\n #assertResponseOK(response: Response | null, originURL: string, method: string, requireBody = true) {\n if (!response) {\n throw new FetcherError('No response', originURL, method);\n }\n if (!response.ok) {\n throw new FetcherError(`${response.status} - ${response.statusText}`, originURL, method);\n }\n if (requireBody && !response.body) {\n throw new FetcherError('Empty response body', originURL, method);\n }\n return true;\n }\n\n async getPageWithPuppeteer(url: string) {\n this.log('debug', `Fetch \"${url}\" with Puppeteer`);\n const browser = await puppeteer.launch({ headless: true });\n const page = await browser.newPage();\n await page.setUserAgent({ userAgent: this.#userAgent });\n await page.goto(url, { waitUntil: 'networkidle2' });\n const html = await page.evaluate(() => document.documentElement.innerHTML);\n await browser.close();\n return html;\n }\n\n protected log(level: LogLevel, ...msg: Array<any>) {\n commonLog(this.#logger, level, this.name, ...msg);\n }\n\n get proxyAgent() {\n return this.#proxyAgent;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Fetcher.js","sourceRoot":"","sources":["../../src/utils/Fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport { pipeline } from 'stream/promises';\nimport { fetch, Request, type Response } from 'undici';\nimport path from 'path';\nimport { type Dispatcher } from 'undici';\nimport puppeteer from 'puppeteer';\nimport FetcherProgressMonitor from './FetcherProgressMonitor.js';\nimport { type Downloadable } from '../entities/Downloadable.js';\nimport type FilenameResolver from './FllenameResolver.js';\nimport { pickDefined } from './Misc.js';\nimport {type LogLevel} from './logging/Logger.js';\nimport type Logger from './logging/Logger.js';\nimport { commonLog } from './logging/Logger.js';\nimport FSHelper from './FSHelper.js';\nimport { type DownloaderConfig } from '../downloaders/Downloader.js';\nimport Progress from './Progress.js';\nimport { createProxyAgent } from './Proxy.js';\nimport { SITE_URL } from './URLHelper.js';\n\nexport interface PrepareDownloadParams<T extends Downloadable> {\n url: string;\n srcEntity: T;\n destFilePath: string;\n setReferer?: boolean;\n signal: AbortSignal;\n}\n\nexport interface StartDownloadOverrides {\n destFilePath?: string;\n tmpFilePath?: string;\n}\n\nexport class FetcherError extends Error {\n\n url: string;\n method: string;\n\n constructor(message: string, url: string, method: string) {\n super(message);\n this.name = 'FetcherError';\n this.url = url;\n this.method = method;\n }\n}\n\nexport type FetcherGetType = 'html' | 'm3u8' | 'json';\nexport type FetcherGetResultOf<T extends FetcherGetType> =\n T extends 'html' ? { html: string; lastUrl: string; }:\n T extends 'm3u8' ? { contents: string; lastUrl: string; }:\n T extends 'json' ? { json: any; lastUrl: string; } :\n never;\n\nexport default class Fetcher {\n\n name = 'Fetcher';\n\n #cookie?: string;\n #logger?: Logger | null;\n #dryRun: boolean;\n #fsHelper: FSHelper;\n #proxyAgent?: Dispatcher;\n #userAgent: string;\n\n constructor(config: DownloaderConfig<any>, logger?: Logger | null) {\n this.#cookie = config.cookie;\n this.#logger = logger;\n this.#dryRun = config.dryRun;\n this.#fsHelper = new FSHelper(config, logger);\n this.#proxyAgent = createProxyAgent(config)?.agent || undefined;\n this.#userAgent = config.request.userAgent;\n }\n\n async get<T extends FetcherGetType>(args: {\n url: string,\n type: T,\n payload?: Record<string, any>,\n maxRetries: number,\n signal?: AbortSignal\n }, rt = 0): Promise<FetcherGetResultOf<T>> {\n\n const { url, type, payload, maxRetries, signal } = args;\n\n const urlObj = new URL(url);\n if (payload) {\n for (const [ p, v ] of Object.entries(payload)) {\n urlObj.searchParams.set(p, v);\n }\n }\n const request = new Request(urlObj, { method: 'GET' });\n this.#setHeaders(request, type, type === 'm3u8' ? { setReferer: true } : {});\n const internalAbortController = new AbortController();\n let removeAbortHandler: undefined | (() => void) = undefined;\n if (signal) {\n const abortHandler = () => internalAbortController.abort();\n signal.addEventListener('abort', abortHandler, {once: true});\n removeAbortHandler = () => signal.removeEventListener('abort', abortHandler);\n }\n try {\n const res = await fetch(request, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n const lastUrl = res.url;\n switch (type) {\n case 'html':\n return {\n html: await res.text(),\n lastUrl\n } as FetcherGetResultOf<T>;\n case 'm3u8':\n return {\n contents: await res.text(),\n lastUrl\n } as FetcherGetResultOf<T>;\n case 'json':\n return {\n json: await res.json(),\n lastUrl\n } as FetcherGetResultOf<T>;\n default:\n return undefined as never;\n }\n }\n catch (error: any) {\n if (signal?.aborted) {\n throw error;\n }\n if (rt < maxRetries) {\n if (removeAbortHandler) removeAbortHandler();\n return await this.get({ url, type, payload, maxRetries, signal }, rt + 1);\n }\n let errMsg;\n if (error instanceof Error) {\n const errMsgParts = [error.message];\n let _err = error.cause;\n while (_err) {\n errMsgParts.push(_err instanceof Error ? _err.message : JSON.stringify(_err));\n _err = _err instanceof Error ? _err.cause : null;\n }\n errMsg = errMsgParts.join(': ');\n }\n else {\n errMsg = String(error);\n }\n const retriedMsg = rt > 0 ? ` (retried ${rt} times)` : '';\n throw new FetcherError(`${errMsg}${retriedMsg}`, urlObj.toString(), request.method);\n }\n finally {\n if (removeAbortHandler) removeAbortHandler();\n }\n }\n\n async resolveDestFilePath<T extends Downloadable>(params: {\n url: string;\n destDir: string;\n destFilenameResolver: FilenameResolver<T>;\n setReferer?: boolean;\n signal?: AbortSignal;\n }) {\n const { url, destDir, destFilenameResolver, setReferer = false, signal } = params;\n const request = new Request(url, { method: 'HEAD' });\n this.#setHeaders(request, 'html', { setCookie: false, setHost: false, setReferer });\n const internalAbortController = new AbortController();\n const abortHandler = () => internalAbortController.abort();\n if (signal) {\n signal.addEventListener('abort', abortHandler, {once: true});\n }\n\n try {\n const res = await fetch(request, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n\n if (this.#assertResponseOK(res, url, request.method, false)) {\n const destFilename = destFilenameResolver.resolve(res);\n const destFilePath = path.resolve(destDir, destFilename);\n return destFilePath;\n }\n }\n finally {\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n }\n\n return undefined as never;\n }\n\n async prepareDownload<T extends Downloadable>(params: PrepareDownloadParams<T>) {\n const { url, srcEntity, destFilePath, setReferer = false, signal } = params;\n const request = new Request(url, { method: 'GET' });\n this.#setHeaders(request, 'html', { setCookie: false, setHost: false, setReferer });\n const internalAbortController = new AbortController();\n let removeAbortHandler: undefined | (() => void) = undefined;\n if (signal) {\n const abortHandler = () => internalAbortController.abort();\n signal.addEventListener('abort', abortHandler, {once: true});\n removeAbortHandler = () => signal.removeEventListener('abort', abortHandler);\n }\n\n try {\n let res = await fetch(request, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n\n // Special handling for attachment\n if (params.srcEntity.type === 'attachment' && !res.ok && res.redirected && res.url) {\n const redirectReq = new Request(res.url, { method: 'GET' });\n this.#setHeaders(redirectReq, 'html', { setCookie: false, setHost: false });\n res = await fetch(redirectReq, { signal: internalAbortController.signal, dispatcher: this.#proxyAgent });\n }\n\n if (this.#assertResponseOK(res, url, request.method)) {\n const destFilename = path.parse(destFilePath).base;\n const progress = new Progress(res, {\n reportInterval: 300\n });\n const monitor = new FetcherProgressMonitor(progress, destFilename, destFilePath);\n\n const _res = res;\n const start = (overrides?: StartDownloadOverrides) => {\n const _destFilePath = overrides?.destFilePath || destFilePath;\n const _tmpFilePath = overrides?.tmpFilePath || FSHelper.createTmpFilePath(_destFilePath, srcEntity.id);\n return this.#startDownload(_res, _tmpFilePath, _destFilePath, progress, removeAbortHandler)\n };\n const abort = () => {\n if (removeAbortHandler) removeAbortHandler();\n internalAbortController.abort();\n };\n\n return {\n monitor,\n start,\n abort\n };\n }\n }\n catch (error: unknown) {\n if (removeAbortHandler) removeAbortHandler();\n throw error;\n }\n\n return undefined as never;\n }\n\n async #startDownload(\n response: Response & { body: NodeJS.ReadableStream },\n tmpFilePath: string,\n destFilePath: string,\n progress: Progress,\n cleanup?: () => void) {\n\n try {\n let size = 0;\n if (this.#dryRun) {\n try {\n for await (const chunk of response.body) {\n size += chunk.length as number;\n }\n }\n catch (_error: unknown) {\n // Do nothing\n }\n }\n else {\n this.log('debug', `Pipe \"${response.url}\" to \"${tmpFilePath}\"`);\n await pipeline(\n response.body,\n progress.stream,\n fs.createWriteStream(tmpFilePath)\n );\n size = fs.lstatSync(tmpFilePath).size;\n }\n\n const commit = () => {\n this.#commitDownload(tmpFilePath, destFilePath, size, cleanup);\n };\n\n const discard = () => {\n this.#cleanupDownload(tmpFilePath, cleanup);\n };\n\n return {\n tmpFilePath,\n commit,\n discard\n };\n }\n catch (error) {\n this.#cleanupDownload(tmpFilePath, cleanup);\n throw error;\n }\n }\n\n async test(url: string) {\n const request = new Request(url, { method: 'HEAD' });\n const res = await fetch(request, { dispatcher: this.#proxyAgent });\n return res.ok;\n }\n\n #commitDownload(tmpFilePath: string, destFilePath: string, size: number, cleanup?: () => void) {\n try {\n this.log('debug', `Commit \"${tmpFilePath}\" to \"${destFilePath}; filesize: ${size} bytes`);\n this.#fsHelper.rename(tmpFilePath, destFilePath);\n }\n finally {\n this.#cleanupDownload(tmpFilePath, cleanup);\n }\n }\n\n #cleanupDownload(tmpFilePath: string, extra?: () => void) {\n try {\n if (this.#dryRun || fs.existsSync(tmpFilePath)) {\n this.log('debug', `Clean up \"${tmpFilePath}\"`);\n this.#fsHelper.unlink(tmpFilePath);\n }\n }\n catch (error) {\n this.log('error', `Error cleaning up \"${tmpFilePath}:`, error);\n }\n finally {\n if (extra) extra();\n }\n }\n\n #setHeaders(request: Request, type: FetcherGetType, opts?: { setCookie?: boolean; setHost?: boolean; setReferer?: boolean; }) {\n const setCookie = pickDefined(opts?.setCookie, true);\n const setHost = pickDefined(opts?.setHost, true);\n const setReferer = pickDefined(opts?.setReferer, false);\n if (this.#cookie && setCookie) {\n request.headers.set('Cookie', this.#cookie);\n }\n if (setHost) {\n request.headers.set('Host', 'www.patreon.com');\n }\n if (setReferer) {\n request.headers.set('referer', SITE_URL);\n }\n request.headers.set('User-Agent', this.#userAgent);\n if (type === 'json') {\n request.headers.set('Content-Type', 'application/vnd.api+json');\n }\n else {\n request.headers.set('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8');\n }\n }\n\n #assertResponseOK(response: Response | null, originURL: string, method: string, requireBody: false): response is Response;\n #assertResponseOK(response: Response | null, originURL: string, method: string, requireBody?: true): response is Response & { body: NodeJS.ReadableStream };\n #assertResponseOK(response: Response | null, originURL: string, method: string, requireBody = true) {\n if (!response) {\n throw new FetcherError('No response', originURL, method);\n }\n if (!response.ok) {\n throw new FetcherError(`${response.status} - ${response.statusText}`, originURL, method);\n }\n if (requireBody && !response.body) {\n throw new FetcherError('Empty response body', originURL, method);\n }\n return true;\n }\n\n async getPageWithPuppeteer(url: string) {\n this.log('debug', `Fetch \"${url}\" with Puppeteer`);\n const browser = await puppeteer.launch({ headless: true });\n const page = await browser.newPage();\n await page.setUserAgent({ userAgent: this.#userAgent });\n await page.goto(url, { waitUntil: 'networkidle2' });\n const html = await page.evaluate(() => document.documentElement.innerHTML);\n await browser.close();\n return html;\n }\n\n protected log(level: LogLevel, ...msg: Array<any>) {\n commonLog(this.#logger, level, this.name, ...msg);\n }\n\n get proxyAgent() {\n return this.#proxyAgent;\n }\n}\n"]}
|
|
@@ -28,6 +28,9 @@ export type URLAnalysis = {
|
|
|
28
28
|
} | {
|
|
29
29
|
type: 'shop';
|
|
30
30
|
vanity: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'customURL';
|
|
33
|
+
url: string;
|
|
31
34
|
};
|
|
32
35
|
export default class URLHelper {
|
|
33
36
|
static constructCurrentUserAPIURL(): string;
|
|
@@ -60,6 +63,7 @@ export default class URLHelper {
|
|
|
60
63
|
static analyzeURL(url: string): URLAnalysis | null;
|
|
61
64
|
static stripSearchParamsFromURL(url: string): string;
|
|
62
65
|
static getExtensionFromURL(url: string): string;
|
|
66
|
+
static isPatreonURL(url: string): boolean;
|
|
63
67
|
static validateURL(url: any): boolean;
|
|
64
68
|
static isAttachmentLink(url: string): {
|
|
65
69
|
validated: true;
|
package/dist/utils/URLHelper.js
CHANGED
|
@@ -484,6 +484,14 @@ export default class URLHelper {
|
|
|
484
484
|
vanity: shopURLMatchVanity
|
|
485
485
|
};
|
|
486
486
|
}
|
|
487
|
+
// Fallback: treat valid HTTPS URLs with non-patreon.com hostnames as custom Patreon domains
|
|
488
|
+
// Note: `base` is already a valid URL (came from stripSearchParamsFromURL), no need to re-validate
|
|
489
|
+
if (!this.isPatreonURL(base)) {
|
|
490
|
+
return {
|
|
491
|
+
type: 'customURL',
|
|
492
|
+
url: base
|
|
493
|
+
};
|
|
494
|
+
}
|
|
487
495
|
return null;
|
|
488
496
|
}
|
|
489
497
|
static stripSearchParamsFromURL(url) {
|
|
@@ -498,6 +506,15 @@ export default class URLHelper {
|
|
|
498
506
|
const urlObj = new URL(url);
|
|
499
507
|
return path.extname(urlObj.pathname.split('/').pop() || '');
|
|
500
508
|
}
|
|
509
|
+
static isPatreonURL(url) {
|
|
510
|
+
try {
|
|
511
|
+
const { protocol, hostname } = new URL(url);
|
|
512
|
+
return protocol === 'https:' && (hostname === 'www.patreon.com' || hostname === 'patreon.com');
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
501
518
|
static validateURL(url) {
|
|
502
519
|
let urlObj;
|
|
503
520
|
try {
|