Giter VIP home page Giter VIP logo

patreon-dl's Introduction

Buy Me a Coffee at ko-fi.com

patreon-dl

A Patreon downloader written in Node.js.

Features

  • Access to patron-only content through cookie
  • Download posts by user, in a collection or single post
  • Download products (aka shop purchases)
  • Items included in downloads:
    • videos
    • images
    • audio
    • attachments
  • Save campaign and content info
  • Extensively configurable

You can run patreon-dl from the command-line or use it as a library for your project. Node.js v16.16.0 or higher required.

Limitations

  • Embedded videos, other than those from YouTube, are not supported (e.g. Vimeo). Only info about these embeds is saved.
  • Likewise, embedded links are not followed; only info about the embed is saved.

FFmpeg dependency

FFmpeg is required when downloading:

  • videos that are provided only in streaming format; and
  • embedded YouTube videos.

Not all video downloads require FFmpeg, but you should have it installed on your system anyway.

Embedded YouTube videos - Premium access

patreon-dl supports downloading embedded YouTube videos. In addition, if you have a YouTube Premium subscription, you can connect patreon-dl to your account and download videos at qualities available only to Premium accounts (e.g. '1080p Premium'). For CLI users, you would configure patreon-dl as follows:

$ patreon-dl --configure-youtube

For library usage, see Configuring YouTube connection.

Installation

npm i -g patreon-dl

The -g option is for installing patreon-dl globally and have the CLI executable added to the PATH. Depending on your usage, you might not need this.

CLI usage

$ patreon-dl [OPTION]... URL

Options

  -h, --help                 Display this usage guide                           
  -C, --config-file <file>   Load configuration file for setting full options   
  -c, --cookie <string>      Cookie for accessing patron-only content           
  -f, --ffmpeg <string>      Path to FFmpeg executable                          
  -o, --out-dir <dir>        Path to directory where content is saved           
  -l, --log-level <level>    Log level of the console logger: 'info', 'debug',  
                             'warn' or 'error'; set to 'none' to disable the    
                             logger.                                            
  -y, --no-prompt            Do not prompt for confirmation to proceed          
  --configure-youtube        Configure YouTube connection 

Supported URL formats

// Product
https://www.patreon.com/<creator>/shop/<slug>-<product_id>

// Posts
https://www.patreon.com/<creator>/posts

// Single post
https://www.patreon.com/posts/<slug>-<post_id>

// Posts in collection
https://www.patreon.com/collection/<collection_id>

Content is saved with the following directory structure:

out-dir
    ├── campaign
        ├── campaign_info
        ├── posts
        │   ├── post 1
        │   │   ├── post_info
        │   │   ├── images
        │   │   ├── ...
        │   ├── post 2
        │       ├── post_info
        │       ├── images
        │       ├── ...
        ├──shop
            ├── product 1
                ├── product_info
                ├── content_media
                ├── ...

Configuration file

Command-line options are limited. To access the full range of options, create a configuration file and pass it to patreon-dl with the (capital) -C option.

Refer to the example config to see what options are offered. Also see How to obtain Cookie.

Note that you can override an option from a configuration file with one provided at the command-line, provided of course that a command-line equivalent is available.

Library usage

To use patreon-dl in your own project:

import PatreonDownloader from 'patreon-dl';

const url = '....';

const downloader = await PatreonDownloader.getInstance(url, [options]);

await downloader.start();

Here, we first obtain a downloader instance by calling PatreonDownloader.getInstance(), passing to it the URL we want to download from (one of the supported URL formats) and downloader options, if any.

Then, we call start() on the downloader instance to begin the download process. The start() method returns a Promise that resolves when the download process has ended.

Downloader options

An object with the following properties (all optional):

Option Description
cookie Cookie to include in requests; required for accessing patron-only content. See How to obtain Cookie.
useStatusCache Whether to use status cache to quickly determine whether a target that had been downloaded before has changed since the last download. Default: true
pathToFFmpeg Path to ffmpeg executable. If not specified, ffmpeg will be called directly when needed, so make sure it is in the PATH.
pathToYouTubeCredentials Path to file storing YouTube credentials for connecting to a YouTube account when downloading embedded YouTube videos. Its purpose is to allow YouTube Premium accounts to download videos at higher than normal qualities. For more information, see Configuring YouTube connection.
outDir Path to directory where content is saved. Default: current working directory
dirNameFormat How to name directories: (object)
filenameFormat Naming of files: (object)
include What to include in the download: (object)
  • lockedContent: whether to process locked content. Default: true
  • postsWithMediaType: sets the media type criteria for downloading posts. Values can be:
    • any: download posts regardless of the type of media they contain. Also applies to posts that do not contain any media.
    • none: only download posts that do not contain media.
    • Array<image | video | audio | attachment>: only download posts that contain the specified media type(s).
    Default: any
  • campaignInfo: whether to save campaign info. Default: true
  • contentInfo: whether to save content info. Default: true
  • contentMedia: the type of content media to download (images, videos, audio, attachments, excluding previews). Values can be:
    • true: download all content media.
    • false: do not download content media.
    • Array<image | video | audio | attachment | file>: only download the specified media type(s).
    Default: true
  • previewMedia: the type of preview media to download, if available. Values can be:
    • true: download all preview media.
    • false: do not download preview media.
    • Array<image | video | audio>: only download the specified media type(s).
    Default: true
  • allMediaVariants: whether to download all media variants, if available. If false, only the best quality variant will be downloaded. Default: false
request Rate limiting and retry on error: (object)
  • maxRetries: maximum number of retries if a request or download fails. Default: 3
  • maxConcurrent: maximum number of concurrent downloads. Default: 10
  • minTime: minimum time to wait between starting requests or downloads (milliseconds). Default: 333
fileExistsAction What to do when a target file already exists: (object)
  • info: in the context of saving info (such as campaign or post info), the action to take when a file belonging to the info already exists. Default: saveAsCopyIfNewer
  • infoAPI: API data is saved as part of info. Because it changes frequently, and usually used for debugging purpose only, you can set a different action when saving an API data file that already exists. Default: overwrite
  • content: in the context of downloading content, the action to take when a file belonging to the content already exists. Default: skip

Supported actions:

  • overwrite: overwrite existing file.
  • skip: skip saving the file.
  • saveAsCopy: save the file under incremented filename (e.g. "abc.jpg" becomes "abc (1).jpg").
  • saveAsCopyIfNewer: like saveAsCopy, but only do so if the contents have actually changed.

logger See Logger

Campaign directory name format

Format to apply when naming campaign directories. A format is a string pattern consisting of fields enclosed in curly braces.

What is a campaign directory?

When you download content, a directory is created for the campaign that hosts the content. Content directories, which stores the downloaded content, are then placed under the campaign directory. If campaign info could not be obtained from content, then content directory will be created directly under outDir.

A format must contain at least one of the following fields:

  • creator.vanity
  • creator.name
  • creator.id
  • campaign.name
  • campaign.id

Characters enclosed in square brackets followed by a question mark denote conditional separators. If the value of a field could not be obtained or is empty, the conditional separator immediately adjacent to it will be omitted from the name.

Default: '{creator.vanity}[ - ]?{campaign.name}'
Fallback: 'campaign-{campaign.id}'

Content directory name format

Format to apply when naming content directories. A format is a string pattern consisting of fields enclosed in curly braces.

What is a content directory?

Content can be a post or product. A directory is created for each piece of content. Downloaded items for the content are placed under this directory.

A format must contain at least one of the following unique identifier fields:

  • content.id: ID of content
  • content.slug: last segment of the content URL

In addition, a format can contain the following fields:

  • content.name: post title or product name
  • content.type: type of content ('product' or 'post')

Characters enclosed in square brackets followed by a question mark denote conditional separators. If the value of a field could not be obtained or is empty, the conditional separator immediately adjacent to it will be omitted from the name.

Default: '{content.id}[ - ]?{content.name}'
Fallback: '{content.type}-{content.id}'

Media filename format

Filename format of a downloaded item. A format is a string pattern consisting of fields enclosed in curly braces.

A format must contain at least one of the following fields:

  • media.id: ID of the item downloaded (assigned by Patreon)
  • media.filename: can be one of the following, in order of availability:
    • original filename included in the item's API data; or
    • filename derived from the header of the response to the HTTP download request.

In addition, a format can contain the following fields:

  • media.type: type of item (e.g. 'image' or 'video')
  • media.variant: where applicable, the variant of the item (e.g. 'original', 'thumbnailSmall'...for images)

If media.variant is not included in the format, it will be appended to it if allMediaVariants is true.

Sometimes media.filename could not be obtained, in which case it will be replaced with media.id, unless it is already present in the format.

Characters enclosed in square brackets followed by a question mark denote conditional separators. If the value of a field could not be obtained or is empty, the conditional separator immediately adjacent to it will be omitted from the name.

Default: '{media.filename}'
Fallback: '{media.type}-{media.id}'

Configuring YouTube connection

In its simplest form, the process of connecting patreon-dl to a YouTube account is as follows:

  1. Obtain credentials by having the user visit a Google page that links his or her account to a 'device' (which in this case is actually patreon-dl).
  2. Save the credentials, as a JSON string, to a file.
  3. Pass the path of the file to PatreonDownloader.getInstance()

To obtain credentials, you can use the YouTubeCredentialsCapturer class:

import { YouTubeCredentialsCapturer } from 'patreon-dl';

// Note: you should wrap the following logic inside an async
// process, and resolve when the credentials have been saved.

const capturer = new YouTubeCredentialsCapturer();

/**
 * 'pending' event emitted when verification data is ready and waiting
 * for user to carry out the verification process.
 */
capturer.on('pending', (data) => {
  // `data` is an object: { verificationURL: <string>, code: <string> }
  // Use `data` to provide instructions to the user:
  console.log(
    `In a browser, go to the following Verification URL and enter Code:

    - Verification URL: ${data.verificationURL}
    - Code: ${data.code}

    Then wait for this script to complete.`);
});

/**
 * 'capture' event emitted when the user has completed verification and the 
 * credentials have been relayed back to the capturer.
 */
capturer.on('capture', (credentials) => {
  // `credentials` is an object which you need to save to file as JSON string.
  fs.writeFileSync('/path/to/yt-credentials.json', JSON.stringify(credentials));
  console.log('Credentials saved!');
});

// When you have added the listeners, start the capture process.
capturer.begin();

Then, pass the path of the file to PatreonDownloader.getInstance():

const downloader = await PatreonDownloader.getInstance(url, {
  ...
  pathToYouTubeCredentials: '/path/to/yt-credentials.json'
});

You should ensure the credentials file is writable, as it needs to be updated with new credentials when the current ones expire. The process of renewing credentials is done automatically by the downloader.

Logger

Logging is optional, but provides useful information about the download process. You can implement your own logger by extending the Logger abstract class:

import { Logger } from 'patreon-dl';

class MyLogger extends Logger {

  log(entry) {
    // Do something with log entry
  }

  // Called when downloader ends, so you can
  // clean up the logger process if necessary.
  end() {
    // This is not an abstract function, so you don't have to
    // implement it if there is no action to be taken here. Default is
    // to resolve right away.
    return Promise.resolve();
  }
}

Each entry passed to log() is an object with the following properties:

  • level: info, debug, warn or error, indicating the severity of the log message.
  • originator: (string or undefined) where the message is coming from.
  • message: array of elements comprising the message. An element can be anything such as a string, Error or object.

Built-in loggers

The patreon-dl library comes with the following Logger implementations that you may utilize:

  • ConsoleLogger

    Outputs messages to the console:

    import { ConsoleLogger } from 'patreon-dl';
    
    const myLogger = new ConsoleLogger([options]);
    
    const downloader = await PatreonDownloader.getInstance(url, {
        ...
        logger: myLogger
    });
    
    

    options: (object)

    Option Description
    enabled Whether to enable this logger. Default: true
    logLevel

    info, debug, warn or error. Default: info

    Output messages up to the specified severity level.

    include What to include in log messages: (object)
    • dateTime: show date / time of log messages. Default: true
    • level: show the severity level. Default: true
    • originator: show where the messsage came from. Default: true
    • errorStack: for Errors, whether to show the full error stack. Default: false
    dateTimeFormat

    The pattern to format data-time strings, when include.dateTime is true.

    Date-time formatting is provided by dateformat library. Refer to the README of that project for pattern rules.

    Default: 'mmm dd HH:MM:ss'

  • FileLogger

    Like ConsoleLogger, but writes messages to file.

    import { FileLogger } from 'patreon-dl';
    
    const myLogger = new FileLogger(init, [options]);
    
    const downloader = await PatreonDownloader.getInstance(url, {
        ...
        logger: myLogger
    });
    

    init: values that determine the name of the log file (object)

    Property Description
    targetURL The url passed to PatreonDownloader.getInstance()
    outDir Value of outDir specified in PatreonDownloader.getInstance() options, or undefined if none specified (in which case defaults to current working directory).
    date

    (optional) Date instance representing the creation date / time of the logger. Default: current date-time

    You might want to provide this if you are creating multiple FileLogger instances and filenames are to be formatted with the date, otherwise the date-time part of the filenames might have different values.

    options: all ConsoleLogger options plus the following:

    Option Description
    logDir

    Path to directory of the log file.

    The path can be a string pattern consisting of the following fields enclosed in curly braces:

    • out.dir: value of outDir provided in init (or the default current working directory if none provided).
    • target.url.path: the pathname of targetURL provided in init, sanitized as necessary.
    • datetime.<date-time format>: the date-time of logger creation, as represented by date in init and formatted according to <date-time format> (using pattern rules defined by the dateformat library).

    logFilename

    Name of the log file.

    The path can be a string pattern consisting of the following fields enclosed in curly braces:

    • target.url.path: the pathname of targetURL provided in init, sanitized as necessary.
    • datetime.<date-time format>: the date-time of logger creation, as represented by date in init and formatted according to <date-time format> (using pattern rules defined by the dateformat library).

    Default: '{datetime.yyyymmdd}-{log.level}.log'

    fileExistsAction

    What to do if log file already exists? One of the following values:

    • append: append logs to existing file
    • overwrite: overwrite the existing file

    Default: append

  • ChainLogger

    Combines multiple loggers into one single logger.

    import { ConsoleLogger, FileLogger, ChainLogger } from 'patreon-dl';
    
    const consoleLogger = new ConsoleLogger(...);
    const fileLogger = new FileLogger(...);
    const chainLogger = new ChainLogger([ consoleLogger, fileLogger ]);
    
    const downloader = await PatreonDownloader.getInstance(url, {
        ...
        logger: chainLogger
    });
    

Aborting

To prematurely end a download process, use AbortController to send an abort signal to the downloader instance.

const downloader = await PatreonDownloader.getInstance(...);
const abortController = new AbortController();
downloader.start({
    signal: abortController.signal
});

...

abortController.abort();

// Downloader aborts current and pending tasks, then ends.

Workflow and Events

Workflow

  1. Downloader analyzes given URL and determines what targets to fetch.
  2. Downloader begins fetching data from Patreon servers. Emits fetchBegin event.
  3. Downloader obtains the target(s) from the fetched data for downloading.
  4. For each target (which can be a campaign, product or post):
    1. Downloader emits targetBegin event.
    2. Downloader determines whether the target needs to be downloaded, based on downloader configuration and target info such as accessibility.
      • If target is to be skipped, downloader emits targetEnd event with isSkipped: true. It then proceeds to the next target, if any.
    3. If target is to be downloaded, downloader saves target info (subject to downloader configuration), and emits phaseBegin event with phase: saveInfo. When done, downloader emits phaseEnd event.
    4. Downloader begins saving media belonging to target (again, subject to downloader configuration). Emits phaseBegin event with phase: saveMedia.
      1. Downloader saves files that do not need to be downloaded, e.g. embedded video / link info.
      2. Downloader proceeds to download files (images, videos, audio, attachments, etc.) belonging to the target in batches. For each batch, downloader emits phaseBegin event with phase: batchDownload. When done, downloader emits phaseEnd event with phase: batchDownload.
        • In this phaseBegin event, you can attach listeners to the download batch to monitor events for each download. See Download Task Batch.
    5. Downloader emits phaseEnd event with phase: saveMedia.
    6. Downloader emits targetEnd event with isSkipped: false, and proceeds to the next target.
  5. When there are no more targets to be processed, or a fatal error occurred, downloader ends with end event.

Events

const downloader = await PatreonDownloader.getInstance(...);

downloader.on('fetchBegin', (payload) => {
    ...
});

downloader.start();

Each event emitted by a PatreonDownloader instance has a payload, which is an object with properties containing information about the event.

Event Description
fetchBegin

Emitted when downloader begins fetching data about target(s).

Payload properties:

  • targetType: the type of target being fetched; one of product, post or post.

targetBegin

Emitted when downloader begins processing a target.

Payload properties:

targetEnd

Emitted when downloader is done processing a target.

Payload properties:

  • target: the target processed; one of Campaign, Product or Post.
  • isSkipped: whether target was skipped.

If isSkipped is true, the following additional properties are available:

  • skipReason: the reason for skipping the target; one of the following enums:
    • TargetSkipReason.Inaccessible
    • TargetSkipReason.AlreadyDownloaded
    • TargetSkipReason.UnmetMediaTypeCriteria
  • skipMessage: description of the skip reason.

phaseBegin

Emitted when downloader begins a phase in the processing of a target.

Payload properties:

  • target: the subject target of the phase; one of Campaign, Product or Post.
  • phase: the phase that is about to begin; one of saveInfo or batchDownload.

If phase is batchDownload, the following additional property is available:

  • batch: an object representing the batch of downloads to be executed by the downloader. For monitoring downloads in the batch, see Download Task Batch.

phaseEnd

Emitted when a phase ends for a target.

Payload properties:

  • target: the subject target of the phase; one of Campaign, Product or Post.
  • phase: the phase that has ended; one of saveInfo or batchDownload.

end

Emitted when downloader ends.

Payload properties:

  • aborted: boolean indicating whether the downloader is ending because of an abort request
  • error: if downloader ends because of an error, then error will be the captured error. Note that error is not necessarily an Error object; it can be anything other than undefined.

Download Task Batch

Files are downloaded in batches. Each batch is provided in the payload of phaseBegin event with phase: batchDownload. You can monitor events of individual downloads in the batch as follows:

downloader.on('phaseBegin', (payload) => {
    if (payload.phase === 'batchDownload') {
        const batch = payload.batch;
        batch.on(event, listener);
    }
})

Note that you don't have to remove listeners yourself. They will be removed once the batch ends and is destroyed by the downloader.

Download Task

Each download task in a batch is represented by an object with the following properties:

Property Description
id ID assigned to the task.
src The source of the download; URL or otherwise file path if downloading video from a previously-downloaded m3u8 playlist.
srcEntity The Downloadable item from which the download task was created.
retryCount The current retry count if download failed previously.
resolvedDestFilename The resolved destination filename of the download, or null if it has not yet been resolved.
resolvedDestFilename The resolved destination file path of the download, or null if it has not yet been reoslved.
getProgress() Function that returns the download progress.

Events

Each event emitted by a download task batch has a payload, which is an object with properties containing information about the event.

Event Description
taskStart

Emitted when a download starts.

Payload properties:

  • task: the download task

taskProgress

Emitted when a download progress is updated.

Payload properties:

  • task: the download task
  • progress: (object)
    • destFilename: the destination filename of the download
    • destFilePath: the destination file path of the download
    • lengthUnit: the unit measuring the progress. Generally, it would be 'byte', but for videos the unit would be 'second'.
    • length: length downloaded, measured in lengthUnit.
    • percent: percent downloaded
    • sizeDownloaded: size of file downloaded (kb)
    • speed: download speed (kb/s)

taskComplete

Emitted when a download is complete.

Payload properties:

  • task: the download task

taskError

Emitted when a download error occurs.

Payload properties:

  • error: (object)
    • task: the download task
    • cause: Error object or undefined
  • willRetry: whether the download will be reattempted

taskAbort

Emitted when a download is aborted.

Payload properties:

  • task: the download task

taskSkip

Emitted when a download is skipped.

Payload properties:

  • task: the download task
  • reason: (object)
    • name: destFileExists or other
    • message: string indicating the skip reason

If reason.name is destFileExists, reason will also contain the following property:

  • existingDestFilePath: the existing file path that is causing the download to skip

taskSpawn

Emitted when a download task is spawned from another task.

Payload properties:

  • origin: the original download task
  • spawn: the spawned download task

complete

Emitted when the batch is complete and there are no more downloads pending.

Payload properties: none

Changelog

v1.2.2

  • Fix wrong file extension for some content types
  • Fix YouTube API requests throwing errors due to YT changes

v1.2.1

  • Bug fixes

v1.2.0

  • Add support for granular control over:
    • posts to include in download based on type of media contained
    • the type of media to download
  • Bug fixes

v1.1.1

  • Fix initial data parsing following Patreon changes

v1.1.0

  • Add support for downloading embedded YouTube videos

v1.0.1

  • Fix missing types when importing as library
  • Fix link in this README

v1.0.0

  • Initial release

patreon-dl's People

Contributors

patrickkfkan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

patreon-dl's Issues

Not an issue

Hey Patrick,

Sorry to bother you, but I don't know of any other way to contact you regarding a feature request. I was wondering if there's a way to incorporate a feature in the config.json to list multiple target URLs that I frequently download from. This would automate the selection process, removing the need to manually uncomment the URLs in the config, which can be a bit of a hassle. It would be a great convenience to just update the cookie when necessary and have "patreon-dl" cycle through the predefined list of URLs.

Filtering download

First, many thanks, works great. But have someway to download just the posts with attachments?

Thanks again

PostDownloader: Post #93397294 is not viewable by current user

Hello. I keep getting this error message when trying to download. I provide the appropriate cookie patreon_device_id and it is not working. I know the cookie works because i've tried it with other downloader like Stacher. Can you help me diagnose the issue? Thank you!

What am I doing wrong here?

I am encountering an issue where I can't seem to download audio content from Patreon posts, which seems to occur as if the cookie is incorrect. However, I have verified the cookie directly from my browser's developer tools, ensuring it's correct based on the directions in the Wiki. Can you help identify what I might be overlooking?

I'm using the .conf format for the config file as per the tool's documentation. The tool is downloading images alongside audio, which I don't require. Additionally, the audio files are not in a listenable format. Could there be a configuration or tool-related issue?

Command I am using in the terminal:

patreon-dl --config-file /Path/to/config_patreon-dl.conf --cookie "12345678-9abc-def0-1234-56789abcdef0" --out-dir "/Path/to" https://www.patreon.com/creatorname/posts

Path I am using to my config file (wasn't sure if I was supposed to use .conf or .json):

/Path/to/config_patreon-dl.conf

Config File Contents

cookie = 12345678-9abc-def0-1234-56789abcdef0
use.status.cache = 1
no.prompt = 1
path.to.ffmpeg = /opt/homebrew/opt/ffmpeg@4/bin/ffmpeg

[output]
out.dir = /Path/to/dir
campaign.dir.name.format = "{creator.vanity}[ - ]?{campaign.name}"
content.dir.name.format = "{content.id}[ - ]?{content.name}"
media.filename.format = "{media.filename}"

[include]
locked.content = 1
posts.with.media.type = audio
campaign.info = 1
content.info = 1
content.media = audio

[request]
max.retries = 3
max.concurrent = 10
min.time = 333

[logger.console]
enabled = 1
log.level = info
include.date.time = 1
include.level = 1
include.originator = 1
include.error.stack = 0
date.time.format = "mmm dd HH:MM:ss"
color = 1

Filtering Tier

Hello again... sorry! Maybe this one is more difficult, I hope not, but I think it's the last type of filter that I miss. After downloading the posts I need to delete the lowest tier folders. It's not a huge job, but if the filter is possible, the better, I think.

Great job, congrats and again, many thanks!

Update Brew

Your most recent update was not yet updated on HomeBrew, if that's in your control would you mind pushing to it? The update you pushed was the issue I raised a month or so back and it would be great to have it. Also if there is another way to contact you in the future, would you mind providing so I do not bother you here? I appreciate it, thank you!

Json files

Sorry, here I'm again.
The format of the files I downloaded is json, but with the tool, they downloaded as txt. Is there something in the configuration that I can change to resolve this?

Many thanks!

Script hangs if post title starts with an emoji

Windows 10 22H2
Node.js v20.10.0.

When a post starts with an emoji, the script hangs without any output or logging. Curiously, the console output shows about 10 more lines than the logger set at debug.

I've created a public and free patreon page that recreates the issue, here. The newest post downloads but there is nothing in status-cache.json or in any of the output folders that mention the 2nd post by name or ID. WIndows does support emoji in file and directory names. Let me know if other files are needed.

Console output:

Microsoft Windows [Version 10.0.19045.3803]
(c) Microsoft Corporation. All rights reserved.

C:\Users\me>patreon-dl -C "C:\Users\me\Downloads\example.conf" https://www.patreon.com/yuorfaec/posts

patreon-dl v1.1.1 Patreon Downloader

Dec 22 20:38:13: debug: InnertubeLoader: Load YouTube credentials from "C:\Users\me\AppData\Roaming\patreon-dl\Config\youtube-credentials.json"
Dec 22 20:38:13: debug: Created PostDownloader instance with config:  {
  type: 'post',
  targetURL: 'https://www.patreon.com/yuorfaec/posts',
  postFetch: { type: 'byUser', vanity: 'yuorfaec', filters: undefined },
  outDir: 'Y:\\test',
  useStatusCache: true,
  pathToFFmpeg: null,
  pathToYouTubeCredentials: 'C:\\Users\\me\\AppData\\Roaming\\patreon-dl\\Config\\youtube-credentials.json',
  dirNameFormat: {
    campaign: '{creator.vanity}[ - ]?{campaign.name}',
    content: '{content.id}[ - ]?{content.name}'
  },
  filenameFormat: { media: '{media.type}-{media.id}' },
  include: {
    lockedContent: true,
    campaignInfo: true,
    contentInfo: true,
    previewMedia: true,
    contentMedia: true,
    allMediaVariants: false
  },
  request: { maxRetries: 5, maxConcurrent: 10, minTime: 666 },
  fileExistsAction: { content: 'skip', info: 'saveAsCopyIfNewer', infoAPI: 'overwrite' }
}
Dec 22 20:38:13: info: PostDownloader: Targeting posts by 'yuorfaec'
Dec 22 20:38:13: debug: PostDownloader: Fetch initial data from URL "https://www.patreon.com/yuorfaec"
Dec 22 20:38:14: info: PostDownloader: Abort signal received
Dec 22 20:38:14: warn: PostDownloader: Page request aborted
Dec 22 20:38:14: info: PostDownloader aborted

C:\Users\me>patreon-dl -C "C:\Users\me\Downloads\example.conf" https://www.patreon.com/yuorfaec/posts

patreon-dl v1.1.1 Patreon Downloader

Dec 22 20:38:46: debug: InnertubeLoader: Load YouTube credentials from "C:\Users\me\AppData\Roaming\patreon-dl\Config\youtube-credentials.json"
Dec 22 20:38:46: debug: Created PostDownloader instance with config:  {
  type: 'post',
  targetURL: 'https://www.patreon.com/yuorfaec/posts',
  postFetch: { type: 'byUser', vanity: 'yuorfaec', filters: undefined },
  outDir: 'Y:\\test',
  useStatusCache: true,
  pathToFFmpeg: null,
  pathToYouTubeCredentials: 'C:\\Users\\me\\AppData\\Roaming\\patreon-dl\\Config\\youtube-credentials.json',
  dirNameFormat: {
    campaign: '{creator.vanity}[ - ]?{campaign.name}',
    content: '{content.id}[ - ]?{content.name}'
  },
  filenameFormat: { media: '{media.type}-{media.id}' },
  include: {
    lockedContent: true,
    campaignInfo: true,
    contentInfo: true,
    previewMedia: true,
    contentMedia: true,
    allMediaVariants: false
  },
  request: { maxRetries: 5, maxConcurrent: 10, minTime: 666 },
  fileExistsAction: { content: 'skip', info: 'saveAsCopyIfNewer', infoAPI: 'overwrite' }
}
Dec 22 20:38:46: info: PostDownloader: Targeting posts by 'yuorfaec'
Dec 22 20:38:46: debug: PostDownloader: Fetch initial data from URL "https://www.patreon.com/yuorfaec"
Dec 22 20:38:47: debug: PageParser: Parse initial data from https://www.patreon.com/yuorfaec
Dec 22 20:38:47: debug: PageParser: Trying pattern: /window\.patreon\s*?=\s*?({.+?});/gm
Dec 22 20:38:47: debug: PageParser: No match for pattern: /window\.patreon\s*?=\s*?({.+?});/gm
Dec 22 20:38:47: debug: PageParser: Trying pattern: /<script id="__NEXT_DATA__" type="application\/json">(.+)<\/script>/gm
Dec 22 20:38:47: debug: PostDownloader: Initial data: campaign ID '4839753'; current user ID '34188673'
Dec 22 20:38:47: info: PostDownloader: Fetch posts
Dec 22 20:38:47: debug: PostDownloader: Request initial posts from API URL "https://www.patreon.com/api/posts?include=campaign%2Caccess_rules%2Cattachments%2Caudio%2Caudio_preview.null%2Cimages%2Cmedia%2Cnative_video_insights%2Cpoll.choices%2Cpoll.current_user_responses.user%2Cpoll.current_user_responses.choice%2Cpoll.current_user_responses.poll%2Cuser%2Cuser_defined_tags%2Cti_checks&sort=-published_at&json-api-version=1.0&filter%5Bcontains_exclusive_posts%5D=true&filter%5Bis_draft%5D=false&filter%5Bcampaign_id%5D=4839753"
Dec 22 20:38:48: debug: PostParser: Parse API response of "https://www.patreon.com/api/posts?include=campaign%2Caccess_rules%2Cattachments%2Caudio%2Caudio_preview.null%2Cimages%2Cmedia%2Cnative_video_insights%2Cpoll.choices%2Cpoll.current_user_responses.user%2Cpoll.current_user_responses.choice%2Cpoll.current_user_responses.poll%2Cuser%2Cuser_defined_tags%2Cti_checks&sort=-published_at&json-api-version=1.0&filter%5Bcontains_exclusive_posts%5D=true&filter%5Bis_draft%5D=false&filter%5Bcampaign_id%5D=4839753"
Dec 22 20:38:48: debug: PostParser: 4 posts found - iterate and parse
Dec 22 20:38:48: debug: PostParser: Parse post #95146990
Dec 22 20:38:48: debug: PostParser: Find campaign item #4839753 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Find reward item #-1 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing reward #-1
Dec 22 20:38:48: debug: PostParser: Find reward item #15035946 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing reward #15035946
Dec 22 20:38:48: debug: PostParser: Find reward item #5434576 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing reward #5434576
Dec 22 20:38:48: debug: PostParser: Obtain creator info (user ID '34188673')
Dec 22 20:38:48: debug: PostParser: Find user item #34188673 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing user #34188673
Dec 22 20:38:48: debug: PostParser: Done parsing campaign #4839753
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio items from post #95146990 ('relationships.audio')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio preview items from post #95146990 ('relationships.audio_preview')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable images from post #95146990 ('relationships.images')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable attachments from post #95146990 ('relationships.attachments')
Dec 22 20:38:48: debug: PostParser: Find media item #258155918 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing media item #258155918 (type: video)
Dec 22 20:38:48: debug: PostParser: Done parsing post #95146990
Dec 22 20:38:48: debug: PostParser: Parse post #95146711
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio items from post #95146711 ('relationships.audio')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio preview items from post #95146711 ('relationships.audio_preview')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable images from post #95146711 ('relationships.images')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable attachments from post #95146711 ('relationships.attachments')
Dec 22 20:38:48: debug: PostParser: Find media item #258151381 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing media item #258151381 (type: video)
Dec 22 20:38:48: debug: PostParser: Done parsing post #95146711
Dec 22 20:38:48: debug: PostParser: Parse post #95145445
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio items from post #95145445 ('relationships.audio')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio preview items from post #95145445 ('relationships.audio_preview')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable images from post #95145445 ('relationships.images')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable attachments from post #95145445 ('relationships.attachments')
Dec 22 20:38:48: debug: PostParser: Find media item #258150376 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing media item #258150376 (type: video)
Dec 22 20:38:48: debug: PostParser: Done parsing post #95145445
Dec 22 20:38:48: debug: PostParser: Parse post #95145054
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio items from post #95145054 ('relationships.audio')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable audio preview items from post #95145054 ('relationships.audio_preview')
Dec 22 20:38:48: debug: PostParser: Fetch downloadable images from post #95145054 ('relationships.images')
Dec 22 20:38:48: debug: PostParser: Parse images
Dec 22 20:38:48: debug: PostParser: Find media item #258140560 in API response
Dec 22 20:38:48: debug: PostParser: Found - parse item data
Dec 22 20:38:48: debug: PostParser: Done parsing media item #258140560 (type: image)
Dec 22 20:38:48: debug: PostParser: All 1 downloadable images parsed
Dec 22 20:38:48: debug: PostParser: Fetch downloadable attachments from post #95145054 ('relationships.attachments')
Dec 22 20:38:48: debug: PostParser: Done parsing post #95145054
Dec 22 20:38:48: debug: PostParser: Campaign #4839753 found while parsing posts
Dec 22 20:38:48: debug: PostParser: Done parsing posts
Dec 22 20:38:48: info: PostDownloader: Save campaign info #4839753
Dec 22 20:38:48: debug: PostDownloader: Campaign directories:  {
  root: 'Y:\\test\\yuorfaec - yuorfaec',
  info: 'Y:\\test\\yuorfaec - yuorfaec\\campaign_info'
}
Dec 22 20:38:48: info: PostDownloader: Saved campaign summary to "Y:\test\yuorfaec - yuorfaec\campaign_info\info.txt"
Dec 22 20:38:48: debug: PostDownloader: Fetch campaign data from API URL "https://www.patreon.com/api/campaigns/4839753"
Dec 22 20:38:49: debug: PostDownloader: Fetch user data from API URL "https://www.patreon.com/api/user/34188673"
Dec 22 20:38:49: info: PostDownloader: Saved campaign API data to "Y:\test\yuorfaec - yuorfaec\campaign_info\campaign-api.json"
Dec 22 20:38:49: info: PostDownloader: Saved creator API data to "Y:\test\yuorfaec - yuorfaec\campaign_info\creator-api.json"
Dec 22 20:38:49: info: PostDownloader: Create download tasks for campaign #4839753 -> images
Dec 22 20:38:49: info: PostDownloader: Download begin (#0.0): [type: image; ID: #4839753] -> image-4839753.jpg
Dec 22 20:38:49: debug: Fetcher: Pipe "https://c10.patreonusercontent.com/4/patreon-media/p/campaign/4839753/450c325452cc41669e740b587acb6a13/eyJxIjoxMDAsIndlYnAiOjB9/1.jpg?token-time=1704585600&token-hash=QDfSKYNMr3CBd1p8ia-wQC0kZBZMQrVZGKqhKAlboro%3D" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg.part"
Dec 22 20:38:49: debug: Fetcher: Commit "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg.part" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg; filesize: 15842 bytes
Dec 22 20:38:49: info: PostDownloader: Download complete (#0.0): "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg"
Dec 22 20:38:50: info: PostDownloader: Download begin (#0.1): [type: image; ID: #4839753] -> image-4839753.webp
Dec 22 20:38:50: debug: Fetcher: Pipe "https://c10.patreonusercontent.com/4/patreon-media/p/campaign/4839753/50daf576b40243058b791c19f0b7acf2/eyJ3IjoxOTIwLCJ3ZSI6MX0%3D/1.png?token-time=1704326400&token-hash=Rl99n3HfIzYk9BHK4V02FnWRnnUuL20xIlVP0XIfx98%3D" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp.part"
Dec 22 20:38:50: debug: Fetcher: Commit "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp.part" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp; filesize: 2046 bytes
Dec 22 20:38:50: info: PostDownloader: Download complete (#0.1): "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp"
Dec 22 20:38:50: info: PostDownloader: Download begin (#0.2): [type: image; ID: #34188673] -> image-34188673.png
Dec 22 20:38:50: debug: Fetcher: Pipe "https://c8.patreon.com/3/200/34188673" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part"
Dec 22 20:38:50: debug: Fetcher: Commit "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png; filesize: 3138 bytes
Dec 22 20:38:51: info: PostDownloader: Download complete (#0.2): "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png"
Dec 22 20:38:51: info: PostDownloader: Download begin (#0.3): [type: image; ID: #34188673] -> image-34188673 (1).png
Dec 22 20:38:51: debug: Fetcher: Pipe "https://c8.patreon.com/3/200/34188673" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part"
Dec 22 20:38:51: debug: FetcherDownloadTask: (saveAsCopyIfNewer) Compare "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part" with "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png": Files match
Dec 22 20:38:51: debug: Fetcher: Clean up "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part"
Dec 22 20:38:51: warn: PostDownloader: Download skipped (#0.3): Destination file exists with same content (Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png)
Dec 22 20:38:51: info: PostDownloader: Download batch complete (#0): 4 downloads; 3 completed; 0 errors; 1 skipped; 0 aborted
Dec 22 20:38:51: info: PostDownloader: Done saving campaign info
Dec 22 20:38:51: debug: PostDownloader: 4 posts fetched
Dec 22 20:38:51: debug: PostDownloader: Post directories: {
  root: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas',
  info: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\post_info',
  audio: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\audio',
  video: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\video',
  images: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\images',
  audioPreview: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\audio_preview',
  videoPreview: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\video_preview',
  imagePreviews: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\image_previews',
  attachments: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\attachments',
  embed: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\embed',
  statusCache: 'Y:\\test\\yuorfaec - yuorfaec\\.patreon-dl'
}
Dec 22 20:38:51: debug: "Y:\test\yuorfaec - yuorfaec\.patreon-dl\status-cache.json" does not exist. Start with empty data
Dec 22 20:38:51: debug: Status cache entry does not exist for post #95146990
Dec 22 20:38:51: info: PostDownloader: Download post #95146990 (alas)
Dec 22 20:38:51: info: PostDownloader: Save post info #95146990
Dec 22 20:38:52: info: PostDownloader: Saved post summary to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\info.txt"
Dec 22 20:38:52: info: PostDownloader: Saved post API data to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\post-api.json"
Dec 22 20:38:52: info: PostDownloader: Create download tasks for post #95146990 -> video
Dec 22 20:38:52: info: PostDownloader: Create download tasks for post #95146990 -> info elements
Dec 22 20:38:52: info: PostDownloader: Download batch created (#1): 4 downloads pending
Dec 22 20:38:52: info: PostDownloader: Download begin (#1.0): [type: video; ID: #258155918] -> video-258155918.mp4
Dec 22 20:38:52: debug: Fetcher: Pipe "https://stream.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/high.mp4?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwMzM4NjgwMCwiYXVkIjoidiIsInBsYXliYWNrX3Jlc3RyaWN0aW9uX2lkIjoiSXIwMkZtcXNxVW5NSXBFcUg4OU1kbHZXYTE1UXdPbzZkQ25lbEN0U0k5WUkifQ.msmi7niP1eKFRYws0vWFWyjYTSsync2GbFcDdM4ulWDIT0IcLMg2lMoCC-yTgxf3BTXyePq9sdZpUuqyl4FITT_5uaI-XVAyGNqiYgYOTf5tQVgNS9JLmDfEh7iB7RD3XgYZwWd1BsWzFxSvf7owTvVKcJq-rrME0cbmdlGuhBRNti3DwnpQL4X4DXayTX5EisDB41qcRzRi58ZWfqLkLISLqLllPZ33fMLUxowanbSo0u4Y-3O9METsCLTzUSK7V12i-TOpBIpEsB4fdNeL0UvCjqzqbTksSszPoNSHoEHhtppJDKNyoe3ZA2cm03YL0CBrrdmJWUMQJ_pB1XqPCA" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4.part"
Dec 22 20:38:53: info: PostDownloader: Download begin (#1.1): [type: dummy; ID: #258155918] -> dummy-258155918-thumbnail.jpg
Dec 22 20:38:53: debug: Fetcher: Pipe "https://image.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/thumbnail.jpg?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwNTk3NzUyOCwiYXVkIjoidCIsInRpbWUiOjIuMH0.GW_yQpIRWLa2LvzA6J10O39nvXjqgbfu0HIVqYWMETRWQRSwFkQElbzkOh5Sspr00QYW0cKbYQXXVKxJ1dYl40BseQhzGkUToW4VBnNDtEndgixHAqrFgE0B9WtJnqFAyRrMe7rbh6cjyMuT3SNiKL31gU1BEs4IjwtPRZUKgA1cm7xoLUVuAw0WBrDNG8FO8UWBlD_l33N3tTMfVzbjm605taUBJ9ZkjrLWgUza9rIQWGqOFm0NlGJuxxv7XPaSlLQWl6gTXMhaDE3kFzHTTJ9oM-dFxhPmpq9kKSVD8MReMIhsPIl9VmyKTezkXd-ASlOJtf9gvnOE2YZfO7lCkg" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg.part"
Dec 22 20:38:53: debug: Fetcher: Commit "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg.part" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg; filesize: 180273 bytes
Dec 22 20:38:53: info: PostDownloader: Download complete (#1.1): "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg"
Dec 22 20:38:53: info: PostDownloader: Download begin (#1.2): [type: image; ID: #95146990] -> image-95146990.jpg
Dec 22 20:38:53: debug: Fetcher: Pipe "https://image.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/thumbnail.jpg?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwNTk3NzUyOCwiYXVkIjoidCIsInRpbWUiOjIuMH0.GW_yQpIRWLa2LvzA6J10O39nvXjqgbfu0HIVqYWMETRWQRSwFkQElbzkOh5Sspr00QYW0cKbYQXXVKxJ1dYl40BseQhzGkUToW4VBnNDtEndgixHAqrFgE0B9WtJnqFAyRrMe7rbh6cjyMuT3SNiKL31gU1BEs4IjwtPRZUKgA1cm7xoLUVuAw0WBrDNG8FO8UWBlD_l33N3tTMfVzbjm605taUBJ9ZkjrLWgUza9rIQWGqOFm0NlGJuxxv7XPaSlLQWl6gTXMhaDE3kFzHTTJ9oM-dFxhPmpq9kKSVD8MReMIhsPIl9VmyKTezkXd-ASlOJtf9gvnOE2YZfO7lCkg" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part"
Dec 22 20:38:53: debug: Fetcher: Commit "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg; filesize: 180273 bytes
Dec 22 20:38:53: info: PostDownloader: Download complete (#1.2): "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg"
Dec 22 20:38:54: info: PostDownloader: Download begin (#1.3): [type: image; ID: #95146990] -> image-95146990 (1).jpg
Dec 22 20:38:54: debug: Fetcher: Pipe "https://image.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/thumbnail.jpg?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwNTk3NzUyOCwiYXVkIjoidCIsInRpbWUiOjIuMH0.GW_yQpIRWLa2LvzA6J10O39nvXjqgbfu0HIVqYWMETRWQRSwFkQElbzkOh5Sspr00QYW0cKbYQXXVKxJ1dYl40BseQhzGkUToW4VBnNDtEndgixHAqrFgE0B9WtJnqFAyRrMe7rbh6cjyMuT3SNiKL31gU1BEs4IjwtPRZUKgA1cm7xoLUVuAw0WBrDNG8FO8UWBlD_l33N3tTMfVzbjm605taUBJ9ZkjrLWgUza9rIQWGqOFm0NlGJuxxv7XPaSlLQWl6gTXMhaDE3kFzHTTJ9oM-dFxhPmpq9kKSVD8MReMIhsPIl9VmyKTezkXd-ASlOJtf9gvnOE2YZfO7lCkg" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part"
Dec 22 20:38:54: debug: FetcherDownloadTask: (saveAsCopyIfNewer) Compare "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part" with "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg": Files match
Dec 22 20:38:54: debug: Fetcher: Clean up "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part"
Dec 22 20:38:54: warn: PostDownloader: Download skipped (#1.3): Destination file exists with same content (Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg)
Dec 22 20:39:03: debug: Fetcher: Commit "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4.part" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4; filesize: 25054416 bytes
Dec 22 20:39:03: info: PostDownloader: Download complete (#1.0): "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4"
Dec 22 20:39:03: info: PostDownloader: Download batch complete (#1): 4 downloads; 3 completed; 0 errors; 1 skipped; 0 aborted
Dec 22 20:39:03: debug: Update status cache for post #95146990
Dec 22 20:39:03: debug: PostDownloader: Post directories: {
  root: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken',
  info: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\post_info',
  audio: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\audio',
  video: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\video',
  images: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\images',
  audioPreview: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\audio_preview',
  videoPreview: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\video_preview',
  imagePreviews: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\image_previews',
  attachments: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\attachments',
  embed: 'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146711 - 💔 broken\\embed',
  statusCache: 'Y:\\test\\yuorfaec - yuorfaec\\.patreon-dl'
}
Dec 22 20:39:03: debug: Status cache entry does not exist for post #95146711
Dec 22 20:39:03: info: PostDownloader: Download post #95146711 (💔 broken)
Dec 22 20:39:03: info: PostDownloader: Save post info #95146711

Debug output:


*************** LOG BEGIN DEC 22 2023 20:38:46 ***************
Dec 22 20:38:46: �[33mdebug:�[39m �[34mInnertubeLoader:�[39m Load YouTube credentials from "C:\Users\me\AppData\Roaming\patreon-dl\Config\youtube-credentials.json"
Dec 22 20:38:46: �[33mdebug:�[39m Created PostDownloader instance with config:  {
  type: �[32m'post'�[39m,
  targetURL: �[32m'https://www.patreon.com/yuorfaec/posts'�[39m,
  postFetch: { type: �[32m'byUser'�[39m, vanity: �[32m'yuorfaec'�[39m, filters: �[90mundefined�[39m },
  outDir: �[32m'Y:\\test'�[39m,
  useStatusCache: �[33mtrue�[39m,
  pathToFFmpeg: �[1mnull�[22m,
  pathToYouTubeCredentials: �[32m'C:\\Users\\me\\AppData\\Roaming\\patreon-dl\\Config\\youtube-credentials.json'�[39m,
  dirNameFormat: {
    campaign: �[32m'{creator.vanity}[ - ]?{campaign.name}'�[39m,
    content: �[32m'{content.id}[ - ]?{content.name}'�[39m
  },
  filenameFormat: { media: �[32m'{media.type}-{media.id}'�[39m },
  include: {
    lockedContent: �[33mtrue�[39m,
    campaignInfo: �[33mtrue�[39m,
    contentInfo: �[33mtrue�[39m,
    previewMedia: �[33mtrue�[39m,
    contentMedia: �[33mtrue�[39m,
    allMediaVariants: �[33mfalse�[39m
  },
  request: { maxRetries: �[33m5�[39m, maxConcurrent: �[33m10�[39m, minTime: �[33m666�[39m },
  fileExistsAction: { content: �[32m'skip'�[39m, info: �[32m'saveAsCopyIfNewer'�[39m, infoAPI: �[32m'overwrite'�[39m }
}
Dec 22 20:38:46: �[32minfo:�[39m �[34mPostDownloader:�[39m Targeting posts by 'yuorfaec'
Dec 22 20:38:46: �[33mdebug:�[39m �[34mPostDownloader:�[39m Fetch initial data from URL "https://www.patreon.com/yuorfaec"
Dec 22 20:38:47: �[33mdebug:�[39m �[34mPageParser:�[39m Parse initial data from https://www.patreon.com/yuorfaec
Dec 22 20:38:47: �[33mdebug:�[39m �[34mPageParser:�[39m Trying pattern: /window\.patreon\s*?=\s*?({.+?});/gm
Dec 22 20:38:47: �[33mdebug:�[39m �[34mPageParser:�[39m No match for pattern: /window\.patreon\s*?=\s*?({.+?});/gm
Dec 22 20:38:47: �[33mdebug:�[39m �[34mPageParser:�[39m Trying pattern: /<script id="__NEXT_DATA__" type="application\/json">(.+)<\/script>/gm
Dec 22 20:38:47: �[33mdebug:�[39m �[34mPostDownloader:�[39m Initial data: campaign ID '4839753'; current user ID '34188673'
Dec 22 20:38:47: �[32minfo:�[39m �[34mPostDownloader:�[39m Fetch posts
Dec 22 20:38:47: �[33mdebug:�[39m �[34mPostDownloader:�[39m Request initial posts from API URL "https://www.patreon.com/api/posts?include=campaign%2Caccess_rules%2Cattachments%2Caudio%2Caudio_preview.null%2Cimages%2Cmedia%2Cnative_video_insights%2Cpoll.choices%2Cpoll.current_user_responses.user%2Cpoll.current_user_responses.choice%2Cpoll.current_user_responses.poll%2Cuser%2Cuser_defined_tags%2Cti_checks&sort=-published_at&json-api-version=1.0&filter%5Bcontains_exclusive_posts%5D=true&filter%5Bis_draft%5D=false&filter%5Bcampaign_id%5D=4839753"
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Parse API response of "https://www.patreon.com/api/posts?include=campaign%2Caccess_rules%2Cattachments%2Caudio%2Caudio_preview.null%2Cimages%2Cmedia%2Cnative_video_insights%2Cpoll.choices%2Cpoll.current_user_responses.user%2Cpoll.current_user_responses.choice%2Cpoll.current_user_responses.poll%2Cuser%2Cuser_defined_tags%2Cti_checks&sort=-published_at&json-api-version=1.0&filter%5Bcontains_exclusive_posts%5D=true&filter%5Bis_draft%5D=false&filter%5Bcampaign_id%5D=4839753"
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m 4 posts found - iterate and parse
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Parse post #95146990
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find campaign item #4839753 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find reward item #-1 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing reward #-1
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find reward item #15035946 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing reward #15035946
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find reward item #5434576 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing reward #5434576
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Obtain creator info (user ID '34188673')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find user item #34188673 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing user #34188673
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing campaign #4839753
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio items from post #95146990 ('relationships.audio')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio preview items from post #95146990 ('relationships.audio_preview')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable images from post #95146990 ('relationships.images')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable attachments from post #95146990 ('relationships.attachments')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find media item #258155918 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing media item #258155918 (type: video)
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing post #95146990
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Parse post #95146711
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio items from post #95146711 ('relationships.audio')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio preview items from post #95146711 ('relationships.audio_preview')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable images from post #95146711 ('relationships.images')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable attachments from post #95146711 ('relationships.attachments')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find media item #258151381 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing media item #258151381 (type: video)
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing post #95146711
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Parse post #95145445
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio items from post #95145445 ('relationships.audio')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio preview items from post #95145445 ('relationships.audio_preview')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable images from post #95145445 ('relationships.images')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable attachments from post #95145445 ('relationships.attachments')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find media item #258150376 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing media item #258150376 (type: video)
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing post #95145445
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Parse post #95145054
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio items from post #95145054 ('relationships.audio')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable audio preview items from post #95145054 ('relationships.audio_preview')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable images from post #95145054 ('relationships.images')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Parse images
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Find media item #258140560 in API response
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Found - parse item data
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing media item #258140560 (type: image)
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m All 1 downloadable images parsed
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Fetch downloadable attachments from post #95145054 ('relationships.attachments')
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing post #95145054
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Campaign #4839753 found while parsing posts
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostParser:�[39m Done parsing posts
Dec 22 20:38:48: �[32minfo:�[39m �[34mPostDownloader:�[39m Save campaign info #4839753
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostDownloader:�[39m Campaign directories:  {
  root: �[32m'Y:\\test\\yuorfaec - yuorfaec'�[39m,
  info: �[32m'Y:\\test\\yuorfaec - yuorfaec\\campaign_info'�[39m
}
Dec 22 20:38:48: �[32minfo:�[39m �[34mPostDownloader:�[39m Saved campaign summary to "Y:\test\yuorfaec - yuorfaec\campaign_info\info.txt"
Dec 22 20:38:48: �[33mdebug:�[39m �[34mPostDownloader:�[39m Fetch campaign data from API URL "https://www.patreon.com/api/campaigns/4839753"
Dec 22 20:38:49: �[33mdebug:�[39m �[34mPostDownloader:�[39m Fetch user data from API URL "https://www.patreon.com/api/user/34188673"
Dec 22 20:38:49: �[32minfo:�[39m �[34mPostDownloader:�[39m Saved campaign API data to "Y:\test\yuorfaec - yuorfaec\campaign_info\campaign-api.json"
Dec 22 20:38:49: �[32minfo:�[39m �[34mPostDownloader:�[39m Saved creator API data to "Y:\test\yuorfaec - yuorfaec\campaign_info\creator-api.json"
Dec 22 20:38:49: �[32minfo:�[39m �[34mPostDownloader:�[39m Create download tasks for campaign #4839753 -> images
Dec 22 20:38:49: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#0.0): [type: image; ID: #4839753] -> image-4839753.jpg
Dec 22 20:38:49: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://c10.patreonusercontent.com/4/patreon-media/p/campaign/4839753/450c325452cc41669e740b587acb6a13/eyJxIjoxMDAsIndlYnAiOjB9/1.jpg?token-time=1704585600&token-hash=QDfSKYNMr3CBd1p8ia-wQC0kZBZMQrVZGKqhKAlboro%3D" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg.part"
Dec 22 20:38:49: �[33mdebug:�[39m �[34mFetcher:�[39m Commit "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg.part" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg; filesize: 15842 bytes
Dec 22 20:38:49: �[32minfo:�[39m �[34mPostDownloader:�[39m Download complete (#0.0): "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.jpg"
Dec 22 20:38:50: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#0.1): [type: image; ID: #4839753] -> image-4839753.webp
Dec 22 20:38:50: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://c10.patreonusercontent.com/4/patreon-media/p/campaign/4839753/50daf576b40243058b791c19f0b7acf2/eyJ3IjoxOTIwLCJ3ZSI6MX0%3D/1.png?token-time=1704326400&token-hash=Rl99n3HfIzYk9BHK4V02FnWRnnUuL20xIlVP0XIfx98%3D" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp.part"
Dec 22 20:38:50: �[33mdebug:�[39m �[34mFetcher:�[39m Commit "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp.part" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp; filesize: 2046 bytes
Dec 22 20:38:50: �[32minfo:�[39m �[34mPostDownloader:�[39m Download complete (#0.1): "Y:\test\yuorfaec - yuorfaec\campaign_info\image-4839753.webp"
Dec 22 20:38:50: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#0.2): [type: image; ID: #34188673] -> image-34188673.png
Dec 22 20:38:50: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://c8.patreon.com/3/200/34188673" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part"
Dec 22 20:38:50: �[33mdebug:�[39m �[34mFetcher:�[39m Commit "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png; filesize: 3138 bytes
Dec 22 20:38:51: �[32minfo:�[39m �[34mPostDownloader:�[39m Download complete (#0.2): "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png"
Dec 22 20:38:51: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#0.3): [type: image; ID: #34188673] -> image-34188673 (1).png
Dec 22 20:38:51: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://c8.patreon.com/3/200/34188673" to "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part"
Dec 22 20:38:51: �[33mdebug:�[39m �[34mFetcherDownloadTask:�[39m (saveAsCopyIfNewer) Compare "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part" with "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png": Files match
Dec 22 20:38:51: �[33mdebug:�[39m �[34mFetcher:�[39m Clean up "Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png.part"
Dec 22 20:38:51: �[35mwarn:�[39m �[34mPostDownloader:�[39m Download skipped (#0.3): Destination file exists with same content (Y:\test\yuorfaec - yuorfaec\campaign_info\image-34188673.png)
Dec 22 20:38:51: �[32minfo:�[39m �[34mPostDownloader:�[39m Download batch complete (#0): 4 downloads; 3 completed; 0 errors; 1 skipped; 0 aborted
Dec 22 20:38:51: �[32minfo:�[39m �[34mPostDownloader:�[39m Done saving campaign info
Dec 22 20:38:51: �[33mdebug:�[39m �[34mPostDownloader:�[39m 4 posts fetched
Dec 22 20:38:51: �[33mdebug:�[39m �[34mPostDownloader:�[39m Post directories: {
  root: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas'�[39m,
  info: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\post_info'�[39m,
  audio: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\audio'�[39m,
  video: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\video'�[39m,
  images: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\images'�[39m,
  audioPreview: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\audio_preview'�[39m,
  videoPreview: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\video_preview'�[39m,
  imagePreviews: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\image_previews'�[39m,
  attachments: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\attachments'�[39m,
  embed: �[32m'Y:\\test\\yuorfaec - yuorfaec\\posts\\95146990 - alas\\embed'�[39m,
  statusCache: �[32m'Y:\\test\\yuorfaec - yuorfaec\\.patreon-dl'�[39m
}
Dec 22 20:38:51: �[33mdebug:�[39m "Y:\test\yuorfaec - yuorfaec\.patreon-dl\status-cache.json" does not exist. Start with empty data
Dec 22 20:38:51: �[33mdebug:�[39m Status cache entry does not exist for post #95146990
Dec 22 20:38:51: �[32minfo:�[39m �[34mPostDownloader:�[39m Download post #95146990 (alas)
Dec 22 20:38:51: �[32minfo:�[39m �[34mPostDownloader:�[39m Save post info #95146990
Dec 22 20:38:52: �[32minfo:�[39m �[34mPostDownloader:�[39m Saved post summary to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\info.txt"
Dec 22 20:38:52: �[32minfo:�[39m �[34mPostDownloader:�[39m Saved post API data to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\post-api.json"
Dec 22 20:38:52: �[32minfo:�[39m �[34mPostDownloader:�[39m Create download tasks for post #95146990 -> video
Dec 22 20:38:52: �[32minfo:�[39m �[34mPostDownloader:�[39m Create download tasks for post #95146990 -> info elements
Dec 22 20:38:52: �[32minfo:�[39m �[34mPostDownloader:�[39m Download batch created (#1): 4 downloads pending
Dec 22 20:38:52: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#1.0): [type: video; ID: #258155918] -> video-258155918.mp4
Dec 22 20:38:52: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://stream.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/high.mp4?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwMzM4NjgwMCwiYXVkIjoidiIsInBsYXliYWNrX3Jlc3RyaWN0aW9uX2lkIjoiSXIwMkZtcXNxVW5NSXBFcUg4OU1kbHZXYTE1UXdPbzZkQ25lbEN0U0k5WUkifQ.msmi7niP1eKFRYws0vWFWyjYTSsync2GbFcDdM4ulWDIT0IcLMg2lMoCC-yTgxf3BTXyePq9sdZpUuqyl4FITT_5uaI-XVAyGNqiYgYOTf5tQVgNS9JLmDfEh7iB7RD3XgYZwWd1BsWzFxSvf7owTvVKcJq-rrME0cbmdlGuhBRNti3DwnpQL4X4DXayTX5EisDB41qcRzRi58ZWfqLkLISLqLllPZ33fMLUxowanbSo0u4Y-3O9METsCLTzUSK7V12i-TOpBIpEsB4fdNeL0UvCjqzqbTksSszPoNSHoEHhtppJDKNyoe3ZA2cm03YL0CBrrdmJWUMQJ_pB1XqPCA" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4.part"
Dec 22 20:38:53: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#1.1): [type: dummy; ID: #258155918] -> dummy-258155918-thumbnail.jpg
Dec 22 20:38:53: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://image.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/thumbnail.jpg?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwNTk3NzUyOCwiYXVkIjoidCIsInRpbWUiOjIuMH0.GW_yQpIRWLa2LvzA6J10O39nvXjqgbfu0HIVqYWMETRWQRSwFkQElbzkOh5Sspr00QYW0cKbYQXXVKxJ1dYl40BseQhzGkUToW4VBnNDtEndgixHAqrFgE0B9WtJnqFAyRrMe7rbh6cjyMuT3SNiKL31gU1BEs4IjwtPRZUKgA1cm7xoLUVuAw0WBrDNG8FO8UWBlD_l33N3tTMfVzbjm605taUBJ9ZkjrLWgUza9rIQWGqOFm0NlGJuxxv7XPaSlLQWl6gTXMhaDE3kFzHTTJ9oM-dFxhPmpq9kKSVD8MReMIhsPIl9VmyKTezkXd-ASlOJtf9gvnOE2YZfO7lCkg" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg.part"
Dec 22 20:38:53: �[33mdebug:�[39m �[34mFetcher:�[39m Commit "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg.part" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg; filesize: 180273 bytes
Dec 22 20:38:53: �[32minfo:�[39m �[34mPostDownloader:�[39m Download complete (#1.1): "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\dummy-258155918-thumbnail.jpg"
Dec 22 20:38:53: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#1.2): [type: image; ID: #95146990] -> image-95146990.jpg
Dec 22 20:38:53: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://image.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/thumbnail.jpg?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwNTk3NzUyOCwiYXVkIjoidCIsInRpbWUiOjIuMH0.GW_yQpIRWLa2LvzA6J10O39nvXjqgbfu0HIVqYWMETRWQRSwFkQElbzkOh5Sspr00QYW0cKbYQXXVKxJ1dYl40BseQhzGkUToW4VBnNDtEndgixHAqrFgE0B9WtJnqFAyRrMe7rbh6cjyMuT3SNiKL31gU1BEs4IjwtPRZUKgA1cm7xoLUVuAw0WBrDNG8FO8UWBlD_l33N3tTMfVzbjm605taUBJ9ZkjrLWgUza9rIQWGqOFm0NlGJuxxv7XPaSlLQWl6gTXMhaDE3kFzHTTJ9oM-dFxhPmpq9kKSVD8MReMIhsPIl9VmyKTezkXd-ASlOJtf9gvnOE2YZfO7lCkg" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part"
Dec 22 20:38:53: �[33mdebug:�[39m �[34mFetcher:�[39m Commit "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg; filesize: 180273 bytes
Dec 22 20:38:53: �[32minfo:�[39m �[34mPostDownloader:�[39m Download complete (#1.2): "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg"
Dec 22 20:38:54: �[32minfo:�[39m �[34mPostDownloader:�[39m Download begin (#1.3): [type: image; ID: #95146990] -> image-95146990 (1).jpg
Dec 22 20:38:54: �[33mdebug:�[39m �[34mFetcher:�[39m Pipe "https://image.mux.com/00VNZXlRruj02S4sUT019U1Q1a6kxDFRB9LLj7lfiFHr01s/thumbnail.jpg?token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5CY3o3Sk5RcUNmdDdWcmo5MWhra2lEY3Vyc2xtRGNmSU1oSFUzallZMDI0IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwMFZOWlhsUnJ1ajAyUzRzVVQwMTlVMVExYTZreERGUkI5TExqN2xmaUZIcjAxcyIsImV4cCI6MTcwNTk3NzUyOCwiYXVkIjoidCIsInRpbWUiOjIuMH0.GW_yQpIRWLa2LvzA6J10O39nvXjqgbfu0HIVqYWMETRWQRSwFkQElbzkOh5Sspr00QYW0cKbYQXXVKxJ1dYl40BseQhzGkUToW4VBnNDtEndgixHAqrFgE0B9WtJnqFAyRrMe7rbh6cjyMuT3SNiKL31gU1BEs4IjwtPRZUKgA1cm7xoLUVuAw0WBrDNG8FO8UWBlD_l33N3tTMfVzbjm605taUBJ9ZkjrLWgUza9rIQWGqOFm0NlGJuxxv7XPaSlLQWl6gTXMhaDE3kFzHTTJ9oM-dFxhPmpq9kKSVD8MReMIhsPIl9VmyKTezkXd-ASlOJtf9gvnOE2YZfO7lCkg" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part"
Dec 22 20:38:54: �[33mdebug:�[39m �[34mFetcherDownloadTask:�[39m (saveAsCopyIfNewer) Compare "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part" with "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg": Files match
Dec 22 20:38:54: �[33mdebug:�[39m �[34mFetcher:�[39m Clean up "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg.part"
Dec 22 20:38:54: �[35mwarn:�[39m �[34mPostDownloader:�[39m Download skipped (#1.3): Destination file exists with same content (Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\post_info\image-95146990.jpg)
Dec 22 20:39:03: �[33mdebug:�[39m �[34mFetcher:�[39m Commit "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4.part" to "Y:\test\yuorfaec - yuorfaec\posts\95146990 - alas\video\video-258155918.mp4; filesize: 25054416 bytes

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.