Add in generated docs, documenting prebuilt_presets

This commit is contained in:
Qualis Svagtlys 2023-12-21 11:32:27 -06:00
parent ed0a69561e
commit c7b25d202d
12 changed files with 1806 additions and 145 deletions

View file

@ -1,11 +1,439 @@
===============
Entry Variables Entry Variables
=============== ===============
.. .. autoclass:: ytdl_sub.entries.script.variable_definitions.VariableDefinitions Entry Variables
.. :members: ---------------
.. :inherited-members:
.. :undoc-members:
.. autoclass:: ytdl_sub.entries.script.variable_definitions.VariableDefinitions channel
:members: ~~~~~~~
The channel name if it exists, otherwise returns the uploader.
channel_id
~~~~~~~~~~
The channel id if it exists, otherwise returns the entry uploader ID.
chapters
~~~~~~~~
Chapters if they exist
comments
~~~~~~~~
Comments if they are requested
creator
~~~~~~~
The creator name if it exists, otherwise returns the channel.
description
~~~~~~~~~~~
The description if it exists. Otherwise, returns an emtpy string.
duration
~~~~~~~~
The duration of the entry in seconds
epoch
~~~~~
The unix epoch of when the metadata was scraped by yt-dlp.
epoch_date
~~~~~~~~~~
The epoch's date, in YYYYMMDD format.
epoch_hour
~~~~~~~~~~
The epoch's hour
ext
~~~
The downloaded entry's file extension
extractor
~~~~~~~~~
The yt-dlp extractor name
extractor_key
~~~~~~~~~~~~~
The yt-dlp extractor key
ie_key
~~~~~~
The ie_key, used in legacy yt-dlp things as the 'info-extractor key'
info_json_ext
~~~~~~~~~~~~~
The "info.json" extension
requested_subtitles
~~~~~~~~~~~~~~~~~~~
Subtitles if they are requested and exist
sponsorblock_chapters
~~~~~~~~~~~~~~~~~~~~~
Sponsorblock Chapters if they are requested and exist
thumbnail_ext
~~~~~~~~~~~~~
The download entry's thumbnail extension. Will always return 'jpg'. Until there is a
need to support other image types, we always convert to jpg.
title
~~~~~
The title of the entry. If a title does not exist, returns its unique ID.
title_sanitized_plex
~~~~~~~~~~~~~~~~~~~~
The sanitized title with additional sanitizing for Plex. It replaces numbers with
fixed-width numbers so Plex does not recognize them as season or episode numbers.
uid
~~~
The entry's unique ID
uid_sanitized_plex
~~~~~~~~~~~~~~~~~~
The sanitized uid with additional sanitizing for Plex. Replaces numbers with
fixed-width numbers so Plex does not recognize them as season or episode numbers.
uploader
~~~~~~~~
The uploader if it exists, otherwise return the uploader ID.
uploader_id
~~~~~~~~~~~
The uploader id if it exists, otherwise return the unique ID.
uploader_url
~~~~~~~~~~~~
The uploader url if it exists, otherwise returns the webpage_url.
webpage_url
~~~~~~~~~~~
The url to the webpage.
Metadata Variables
------------------
entry_metadata
~~~~~~~~~~~~~~
The entry's info.json
playlist_metadata
~~~~~~~~~~~~~~~~~
Metadata from the playlist (i.e. the parent metadata, like playlist -> entry)
sibling_metadata
~~~~~~~~~~~~~~~~
Metadata from any sibling entries that reside in the same playlist as this entry.
source_metadata
~~~~~~~~~~~~~~~
Metadata from the source (i.e. the grandparent metadata, like channel -> playlist -> entry)
Playlist Variables
------------------
playlist_count
~~~~~~~~~~~~~~
Playlist count if it exists, otherwise returns ``1``.
Note that for channels/playlists, any change (i.e. adding or removing a video) will make
this value change. Use with caution.
playlist_description
~~~~~~~~~~~~~~~~~~~~
The playlist description if it exists, otherwise returns the entry's description.
playlist_index
~~~~~~~~~~~~~~
Playlist index if it exists, otherwise returns ``1``.
Note that for channels/playlists, any change (i.e. adding or removing a video) will make
this value change. Use with caution.
playlist_index_padded
~~~~~~~~~~~~~~~~~~~~~
playlist_index padded two digits
playlist_index_padded6
~~~~~~~~~~~~~~~~~~~~~~
playlist_index padded six digits.
playlist_index_reversed
~~~~~~~~~~~~~~~~~~~~~~~
Playlist index reversed via ``playlist_count - playlist_index + 1``
playlist_index_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
playlist_index_reversed padded two digits
playlist_index_reversed_padded6
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
playlist_index_reversed padded six digits.
playlist_max_upload_date
~~~~~~~~~~~~~~~~~~~~~~~~
Max upload_date for all entries in this entry's playlist if it exists, otherwise returns
``upload_date``
playlist_max_upload_year
~~~~~~~~~~~~~~~~~~~~~~~~
Max upload_year for all entries in this entry's playlist if it exists, otherwise returns
``upload_year``
playlist_max_upload_year_truncated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The max playlist truncated upload year for all entries in this entry's playlist if it
exists, otherwise returns ``upload_year_truncated``.
playlist_title
~~~~~~~~~~~~~~
Name of its parent playlist/channel if it exists, otherwise returns its title.
playlist_uid
~~~~~~~~~~~~
The playlist unique ID if it exists, otherwise return the entry unique ID.
playlist_uploader
~~~~~~~~~~~~~~~~~
The playlist uploader if it exists, otherwise return the entry uploader.
playlist_uploader_id
~~~~~~~~~~~~~~~~~~~~
The playlist uploader id if it exists, otherwise returns the entry uploader ID.
playlist_uploader_url
~~~~~~~~~~~~~~~~~~~~~
The playlist uploader url if it exists, otherwise returns the playlist webpage_url.
playlist_webpage_url
~~~~~~~~~~~~~~~~~~~~
The playlist webpage url if it exists. Otherwise, returns the entry webpage url.
Release Date Variables
----------------------
release_date
~~~~~~~~~~~~
The entrys release date, in YYYYMMDD format. If not present, return the upload date.
release_date_standardized
~~~~~~~~~~~~~~~~~~~~~~~~~
The release date formatted as YYYY-MM-DD
release_day
~~~~~~~~~~~
The release day as an integer (no padding).
release_day_of_year
~~~~~~~~~~~~~~~~~~~
The day of the year, i.e. February 1st returns ``32``
release_day_of_year_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~
The release day of year, but padded i.e. February 1st returns "032"
release_day_of_year_reversed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The release day, but reversed using ``{total_days_in_year} + 1 - {release_day}``,
i.e. February 2nd would have release_day_of_year_reversed of ``365 + 1 - 32`` = ``334``
release_day_of_year_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reversed release day of year, but padded i.e. December 31st returns "001"
release_day_padded
~~~~~~~~~~~~~~~~~~
The entry's release day padded to two digits, i.e. the fifth returns "05"
release_day_reversed
~~~~~~~~~~~~~~~~~~~~
The release day, but reversed using ``{total_days_in_month} + 1 - {release_day}``,
i.e. August 8th would have release_day_reversed of ``31 + 1 - 8`` = ``24``
release_day_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reversed release day, but padded. i.e. August 30th returns "02".
release_month
~~~~~~~~~~~~~
The release month as an integer (no padding).
release_month_padded
~~~~~~~~~~~~~~~~~~~~
The entry's release month padded to two digits, i.e. March returns "03"
release_month_reversed
~~~~~~~~~~~~~~~~~~~~~~
The release month, but reversed
using ``13 - {release_month}``, i.e. March returns ``10``
release_month_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reversed release month, but padded. i.e. November returns "02"
release_year
~~~~~~~~~~~~
The entry's release year
release_year_truncated
~~~~~~~~~~~~~~~~~~~~~~
The last two digits of the release year, i.e. 22 in 2022
release_year_truncated_reversed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The release year truncated, but reversed using ``100 - {release_year_truncated}``, i.e.
2022 returns ``100 - 22`` = ``78``
Source Variables
----------------
source_count
~~~~~~~~~~~~
The source count if it exists, otherwise returns the playlist count.
source_description
~~~~~~~~~~~~~~~~~~
The source description if it exists, otherwise returns the playlist description.
source_index
~~~~~~~~~~~~
Source index if it exists, otherwise returns ``1``.
It is recommended to not use this unless you know the source will never add new content
(it is easy for this value to change).
source_index_padded
~~~~~~~~~~~~~~~~~~~
The source index, padded.
source_title
~~~~~~~~~~~~
Name of the source (i.e. channel with multiple playlists) if it exists, otherwise
returns its playlist_title.
source_uid
~~~~~~~~~~
The source unique id if it exists, otherwise returns the playlist unique ID.
source_uploader
~~~~~~~~~~~~~~~
The source uploader if it exists, otherwise return the playlist_uploader
source_uploader_id
~~~~~~~~~~~~~~~~~~
The source uploader id if it exists, otherwise returns the playlist_uploader_id
source_uploader_url
~~~~~~~~~~~~~~~~~~~
The source uploader url if it exists, otherwise returns the source webpage_url.
source_webpage_url
~~~~~~~~~~~~~~~~~~
The source webpage url if it exists, otherwise returns the playlist webpage url.
Upload Date Variables
---------------------
upload_date
~~~~~~~~~~~
The entrys uploaded date, in YYYYMMDD format. If not present, return todays date.
upload_date_standardized
~~~~~~~~~~~~~~~~~~~~~~~~
The uploaded date formatted as YYYY-MM-DD
upload_day
~~~~~~~~~~
The upload day as an integer (no padding).
upload_day_of_year
~~~~~~~~~~~~~~~~~~
The day of the year, i.e. February 1st returns ``32``
upload_day_of_year_padded
~~~~~~~~~~~~~~~~~~~~~~~~~
The upload day of year, but padded i.e. February 1st returns "032"
upload_day_of_year_reversed
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The upload day, but reversed using ``{total_days_in_year} + 1 - {upload_day}``,
i.e. February 2nd would have upload_day_of_year_reversed of ``365 + 1 - 32`` = ``334``
upload_day_of_year_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reversed upload day of year, but padded i.e. December 31st returns "001"
upload_day_padded
~~~~~~~~~~~~~~~~~
The entry's upload day padded to two digits, i.e. the fifth returns "05"
upload_day_reversed
~~~~~~~~~~~~~~~~~~~
The upload day, but reversed using ``{total_days_in_month} + 1 - {upload_day}``,
i.e. August 8th would have upload_day_reversed of ``31 + 1 - 8`` = ``24``
upload_day_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~
The reversed upload day, but padded. i.e. August 30th returns "02".
upload_month
~~~~~~~~~~~~
The upload month as an integer (no padding).
upload_month_padded
~~~~~~~~~~~~~~~~~~~
The entry's upload month padded to two digits, i.e. March returns "03"
upload_month_reversed
~~~~~~~~~~~~~~~~~~~~~
The upload month, but reversed using ``13 - {upload_month}``, i.e. March returns ``10``
upload_month_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reversed upload month, but padded. i.e. November returns "02"
upload_year
~~~~~~~~~~~
The entry's upload year
upload_year_truncated
~~~~~~~~~~~~~~~~~~~~~
The last two digits of the upload year, i.e. 22 in 2022
upload_year_truncated_reversed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The upload year truncated, but reversed using ``100 - {upload_year_truncated}``, i.e.
2022 returns ``100 - 22`` = ``78``
Ytdl-Sub Variables
------------------
download_index
~~~~~~~~~~~~~~
The i'th entry downloaded. NOTE that this is fetched dynamically from the download
archive.
download_index_padded6
~~~~~~~~~~~~~~~~~~~~~~
The download_index padded six digits
upload_date_index
~~~~~~~~~~~~~~~~~
The i'th entry downloaded with this upload date.
upload_date_index_padded
~~~~~~~~~~~~~~~~~~~~~~~~
The upload_date_index padded two digits
upload_date_index_reversed
~~~~~~~~~~~~~~~~~~~~~~~~~~
100 - upload_date_index
upload_date_index_reversed_padded
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The upload_date_index padded two digits
ytdl_sub_input_url
~~~~~~~~~~~~~~~~~~
The input URL used in ytdl-sub to create this entry.

View file

@ -10,3 +10,5 @@ This section contains direct references to the code of ``ytdl-sub`` and informat
entry_variables entry_variables
override_variables override_variables
config config
prebuilt_presets
scripting_functions

View file

@ -1,7 +1,44 @@
==================
Override Variables Override Variables
================== ==================
.. autoclass:: ytdl_sub.entries.variables.override_variables.OverrideVariables() subscription_indent_i
:members: ---------------------
:member-order: bysource For subscriptions in the form of
.. code-block:: yaml
Preset | = Indent Value 1:
= Indent Value 2:
"Subscription Name": "https://..."
``subscription_indent_1`` and ``subscription_indent_2`` get set to
``Indent Value 1`` and ``Indent Value 2``.
subscription_name
-----------------
Name of the subscription
subscription_value
------------------
For subscriptions in the form of
.. code-block:: yaml
"Subscription Name": "https://..."
``subscription_value`` gets set to ``https://...``.
subscription_value_i
--------------------
For subscriptions in the form of
.. code-block:: yaml
"Subscription Name":
- "https://url1.com/..."
- "https://url2.com/..."
``subscription_value_1`` and ``subscription_value_2`` get set to ``https://url1.com/...``
and ``https://url2.com/...``. Note that ``subscription_value_1`` also gets set to
``subscription_value``.

View file

@ -1,128 +1,767 @@
=======
Plugins Plugins
======= =======
Plugins are used to perform any type of post-processing to the already downloaded files.
audio_extract audio_extract
''''''''''''' -------------
.. autoclass:: ytdl_sub.plugins.audio_extract.AudioExtractOptions() Extracts audio from a video file.
:members:
:member-order: bysource
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
audio_extract:
codec: "mp3"
quality: 128
codec
~~~~~
The codec to output after extracting the audio. Supported codecs are aac, flac, mp3, m4a,
opus, vorbis, wav, and best to grab the best possible format at runtime.
quality
~~~~~~~
Optional. Specify ffmpeg audio quality. Insert a value between ``0`` (better) and ``9``
(worse) for variable bitrate, or a specific bitrate like ``128`` for 128k.
chapters chapters
'''''''' --------
.. autoclass:: ytdl_sub.plugins.chapters.ChaptersOptions() Embeds chapters to video files if they are present. Additional options to add SponsorBlock
:members: chapters and remove specific ones. Can also remove chapters using regex.
:member-order: bysource
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
chapters:
# Embedded Chapter Fields
embed_chapters: True
allow_chapters_from_comments: False
remove_chapters_regex:
- "Intro"
- "Outro"
# Sponsorblock Fields
sponsorblock_categories:
- "outro"
- "selfpromo"
- "preview"
- "interaction"
- "sponsor"
- "music_offtopic"
- "intro"
remove_sponsorblock_categories: "all"
force_key_frames: False
allow_chapters_from_comments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Optional. If chapters do not exist in the video/description itself, attempt to scrape
comments to find the chapters. Defaults to False.
embed_chapters
~~~~~~~~~~~~~~
Optional. Embed chapters into the file. Defaults to True.
force_key_frames
~~~~~~~~~~~~~~~~
Optional. Force keyframes at cuts when removing sections. This is slow due to needing a
re-encode, but the resulting video may have fewer artifacts around the cuts. Defaults to
False.
remove_chapters_regex
~~~~~~~~~~~~~~~~~~~~~
Optional. List of regex patterns to match chapter titles against and remove them from the
entry.
remove_sponsorblock_categories
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Optional. List of SponsorBlock categories to remove from the output file. Can only remove
categories that are specified in ``sponsorblock_categories`` or "all", which removes
everything specified in ``sponsorblock_categories``.
sponsorblock_categories
~~~~~~~~~~~~~~~~~~~~~~~
Optional. List of SponsorBlock categories to embed as chapters. Supports "sponsor",
"intro", "outro", "selfpromo", "preview", "filler", "interaction", "music_offtopic",
"poi_highlight", or "all" to include all categories.
date_range date_range
'''''''''' ----------
.. autoclass:: ytdl_sub.plugins.date_range.DateRangeOptions() Only download files uploaded within the specified date range.
:members:
:member-order: bysource
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
date_range:
before: "now"
after: "today-2weeks"
after
~~~~~
Optional. Only download videos after this datetime.
before
~~~~~~
Optional. Only download videos before this datetime.
embed_thumbnail embed_thumbnail
'''''''''''''''' ---------------
Whether to embed thumbnails to the audio/video file or not.
.. autoclass:: ytdl_sub.plugins.embed_thumbnail.EmbedThumbnailOptions() Usage:
------------------------------------------------------------------------------- .. code-block:: yaml
presets:
my_example_preset:
embed_thumbnail: True
file_convert file_convert
'''''''''''' ------------
.. autoclass:: ytdl_sub.plugins.file_convert.FileConvertOptions() Converts video files from one extension to another.
:members:
:member-order: bysource
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
file_convert:
convert_to: "mp4"
Supports custom ffmpeg conversions:
.. code-block:: yaml
presets:
my_example_preset:
file_convert:
convert_to: "mkv"
convert_with: "ffmpeg"
ffmpeg_post_process_args: >
-bitexact
-vcodec copy
-acodec copy
-scodec mov_text
convert_to
~~~~~~~~~~
Convert to a desired file type. Supports:
* Video: avi, flv, mkv, mov, mp4, webm
* Audio: aac, flac, mp3, m4a, opus, vorbis, wav
convert_with
~~~~~~~~~~~~
Optional. Supports ``yt-dlp`` and ``ffmpeg``. ``yt-dlp`` will convert files within
yt-dlp whereas ``ffmpeg`` specifies it will be converted using a custom command specified
with ``ffmpeg_post_process_args``. Defaults to ``yt-dlp``.
ffmpeg_post_process_args
~~~~~~~~~~~~~~~~~~~~~~~~
Optional. ffmpeg args to post-process an entry file with. The args will be inserted in the
form of:
.. code-block:: bash
ffmpeg -i input_file.ext {ffmpeg_post_process_args) output_file.output_ext
The output file will use the extension specified in ``convert_to``. Post-processing args
can still be set with ``convert_with`` set to ``yt-dlp``.
format format
'''''' ------
.. autoclass:: ytdl_sub.plugins.format.FormatOptions() Set ``--format`` to pass into yt-dlp to download a specific format quality.
Uses the same syntax as yt-dlp.
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
format: "(bv*[height<=1080]+bestaudio/best[height<=1080])"
format
~~~~~~
yt-dlp format, uses same syntax as yt-dlp.
match_filters match_filters
''''''''''''' -------------
.. autoclass:: ytdl_sub.plugins.match_filters.MatchFiltersOptions() Set ``--match-filters``` to pass into yt-dlp to filter entries from being downloaded.
:members: Uses the same syntax as yt-dlp.
:member-order: bysource
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
match_filters:
filters: "original_url!*=/shorts/"
Supports one or multiple filters:
.. code-block:: yaml
presets:
my_example_preset:
match_filters:
filters:
- "age_limit<?18"
- "like_count>?100"
# Other common match-filters
# - "original_url!*=/shorts/ & !is_live"
# - "age_limit<?18"
# - "availability=?public"
filters
~~~~~~~
The filters themselves. If used multiple times, the filter matches if at least one of the
conditions are met. For logical AND's between match filters, use the ``&`` operator in
a single match filter. These are applied when gathering metadata.
music_tags music_tags
'''''''''' ----------
.. autoclass:: ytdl_sub.plugins.music_tags.MusicTagsOptions() Adds tags to every download audio file using
`MediaFile <https://mediafile.readthedocs.io/en/latest/>`_,
the same audio file tagging package used by
`beets <https://beets.readthedocs.io/en/stable/>`_.
It supports basic tags like ``title``, ``album``, ``artist`` and ``albumartist``. You can find
a full list of tags for various file types in MediaFile's
`source code <https://github.com/beetbox/mediafile/blob/v0.9.0/mediafile.py#L1770>`_.
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
music_tags:
tags:
artist: "{artist}"
album: "{album}"
# Supports id3v2.4 multi-tags
genres:
- "{genre}"
- "ytdl-sub"
albumartists:
- "{artist}"
- "ytdl-sub"
embed_thumbnail
~~~~~~~~~~~~~~~
Optional. Whether to embed the thumbnail into the audio file.
tags
~~~~
Key, values of tag names, tag values. Supports source and override variables.
Supports lists which will get written to MP3s as id3v2.4 multi-tags.
nfo_tags nfo_tags
'''''''' --------
.. autoclass:: ytdl_sub.plugins.nfo_tags.NfoTagsOptions() Adds an NFO file for every download file. An NFO file is simply an XML file
:members: nfo_name, nfo_root, tags, kodi_safe with a ``.nfo`` extension. You can add any values into the NFO.
:member-order: bysource
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
nfo_tags:
# required
nfo_name: "{title_sanitized}.nfo"
nfo_root: "episodedetails"
tags:
title: "{title}"
season: "{upload_year}"
episode: "{upload_month}{upload_day_padded}"
# optional
kodi_safe: False
kodi_safe
~~~~~~~~~
Optional. Kodi does not support > 3-byte unicode characters, which include emojis and some
foreign language characters. Setting this to True will replace those characters with '□'.
Defaults to False.
nfo_name
~~~~~~~~
The NFO file name.
nfo_root
~~~~~~~~
The root tag of the NFO's XML. In the usage above, it would look like
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<episodedetails>
</episodedetails>
tags
~~~~
Tags within the nfo_root tag. In the usage above, it would look like
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<episodedetails>
<title>Awesome Youtube Video</title>
<season>2022</season>
<episode>502</episode>
</episodedetails>
Also supports xml attributes and duplicate keys:
.. code-block:: yaml
tags:
season:
attributes:
name: "Best Year"
tag: "{upload_year}"
genre:
- "Comedy"
- "Drama"
Which translates to
.. code-block:: xml
<season name="Best Year">2022</season>
<genre>Comedy</genre>
<genre>Drama</genre>
output_directory_nfo_tags output_directory_nfo_tags
''''''''''''''''''''''''' -------------------------
.. autoclass:: ytdl_sub.plugins.output_directory_nfo_tags.OutputDirectoryNfoTagsOptions() Adds a single NFO file in the output directory. An NFO file is simply an XML file with a
:members: nfo_name, nfo_root, tags, kodi_safe ``.nfo`` extension. It uses the last entry's source variables which can change per download
:member-order: bysource invocation. Be cautious of which variables you use.
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
output_directory_nfo_tags:
# required
nfo_name: "tvshow.nfo"
nfo_root: "tvshow"
tags:
title: "Sweet youtube TV show"
# optional
kodi_safe: False
kodi_safe
~~~~~~~~~
Optional. Kodi does not support > 3-byte unicode characters, which include emojis and some
foreign language characters. Setting this to True will replace those characters with '□'.
Defaults to False.
nfo_name
~~~~~~~~
The NFO file name.
nfo_root
~~~~~~~~
The root tag of the NFO's XML. In the usage above, it would look like
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
</tvshow>
tags
~~~~
Tags within the nfo_root tag. In the usage above, it would look like
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tvshow>
<title>Sweet youtube TV show</title>
</tvshow>
Also supports xml attributes and duplicate keys:
.. code-block:: yaml
tags:
named_season:
- tag: "{source_title}"
attributes:
number: "{collection_index}"
genre:
- "Comedy"
- "Drama"
Which translates to
.. code-block:: xml
<title year="2022">Sweet youtube TV show</season>
<genre>Comedy</genre>
<genre>Drama</genre>
output_options
--------------
Defines where to output files and thumbnails after all post-processing has completed.
Usage:
.. code-block:: yaml
presets:
my_example_preset:
output_options:
# required
output_directory: "/path/to/videos_or_music"
file_name: "{title_sanitized}.{ext}"
# optional
thumbnail_name: "{title_sanitized}.{thumbnail_ext}"
info_json_name: "{title_sanitized}.{info_json_ext}"
download_archive_name: ".ytdl-sub-{subscription_name}-download-archive.json"
migrated_download_archive_name: ".ytdl-sub-{subscription_name_sanitized}-download-archive.json"
maintain_download_archive: True
keep_files_before: now
keep_files_after: 19000101
download_archive_name
~~~~~~~~~~~~~~~~~~~~~
Optional. The file name to store a subscriptions download archive placed relative to
the output directory. Defaults to ``.ytdl-sub-{subscription_name}-download-archive.json``
file_name
~~~~~~~~~
Required. The file name for the media file. This can include directories such as
``"Season {upload_year}/{title}.{ext}"``, and will be placed in the output directory.
info_json_name
~~~~~~~~~~~~~~
Optional. The file name for the media's info json file. This can include directories such
as ``"Season {upload_year}/{title}.{info_json_ext}"``, and will be placed in the output
directory. Can be set to empty string or `null` to disable info json writes.
keep_files_after
~~~~~~~~~~~~~~~~
Optional. Requires ``maintain_download_archive`` set to True.
Only keeps files that are uploaded after this datetime. By default, ytdl-sub will keep
files after ``19000101``, which implies all files. Can be used in conjunction with
``keep_max_files``.
keep_files_before
~~~~~~~~~~~~~~~~~
Optional. Requires ``maintain_download_archive`` set to True.
Only keeps files that are uploaded before this datetime. By default, ytdl-sub will keep
files before ``now``, which implies all files. Can be used in conjunction with
``keep_max_files``.
keep_max_files
~~~~~~~~~~~~~~
Optional. Requires ``maintain_download_archive`` set to True.
Only keeps N most recently uploaded videos. If set to <= 0, ``keep_max_files`` will not be
applied. Can be used in conjunction with ``keep_files_before`` and ``keep_files_after``.
maintain_download_archive
~~~~~~~~~~~~~~~~~~~~~~~~~
Optional. Maintains a download archive file in the output directory for a subscription.
It is named ``.ytdl-sub-{subscription_name}-download-archive.json``, stored in the
output directory.
The download archive contains a mapping of ytdl IDs to downloaded files. This is used to
create a ytdl download-archive file when invoking a download on a subscription. This will
prevent ytdl from redownloading media already downloaded.
Defaults to False.
migrated_download_archive_name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Optional. Intended to be used if you are migrating a subscription with either a new
subscription name or output directory. It will try to load the archive file using this name
first, and fallback to ``download_archive_name``. It will always save to this file
and remove the original ``download_archive_name``.
output_directory
~~~~~~~~~~~~~~~~
Required. The output directory to store all media files downloaded.
thumbnail_name
~~~~~~~~~~~~~~
Optional. The file name for the media's thumbnail image. This can include directories such
as ``"Season {upload_year}/{title}.{thumbnail_ext}"``, and will be placed in the output
directory. Can be set to empty string or `null` to disable thumbnail writes.
overrides
---------
Optional. This section allows you to define variables that can be used in any string formatter.
For example, if you want your file and thumbnail files to match without copy-pasting a large
format string, you can define something like:
.. code-block:: yaml
presets:
my_example_preset:
overrides:
output_directory: "/path/to/media"
custom_file_name: "{upload_date_standardized}.{title_sanitized}"
# Then use the override variables in the output options
output_options:
output_directory: "{output_directory}"
file_name: "{custom_file_name}.{ext}"
thumbnail_name: "{custom_file_name}.{thumbnail_ext}"
Override variables can contain explicit values and other variables, including both override
and source variables.
In addition, any override variable defined will automatically create a ``sanitized`` variable
for use. In the example above, ``output_directory_sanitized`` will exist and perform
sanitization on the value when used.
regex regex
''''' -----
.. autoclass:: ytdl_sub.plugins.regex.RegexOptions() Performs regex matching on an entry's source or override variables. Regex can be used to filter
:members: skip_if_match_fails entries from proceeding with download or capture groups to create new source variables.
.. autoclass:: ytdl_sub.plugins.regex.VariableRegex() NOTE that YAML differentiates between single-quote (``'``) and double-quote (``"``), which can
:members: match, capture_group_names, capture_group_defaults, exclude affect regex. Double-quote implies string literals, i.e. ``"\n"`` is the literal chars ``\n``,
:member-order: bysource whereas single-quote, ``'\n'`` gets evaluated to a new line. To escape ``\`` when using
:exclude-members: partial_validate single-quote, use ``\\``. This is necessary if you want your regex to be something like
``\d\n`` to match a number and adjacent new-line. It must be written as ``\\d\n``.
------------------------------------------------------------------------------- If you want to regex-search multiple source variables to create a logical OR effect, you can
create an override variable that contains the concatenation of them, and search that with regex.
For example, creating the override variable ``"title_and_description": "{title} {description}"``
and using ``title_and_description`` can regex match/exclude from either ``title`` or
``description``.
Usage:
.. code-block:: yaml
presets:
my_example_preset:
regex:
# By default, if any match fails and has no defaults, the entry will
# be skipped. If False, ytdl-sub will error and stop all downloads
# from proceeding.
skip_if_match_fails: True
from:
# For each entry's `title` value...
title:
# Perform this regex match on it to act as a filter.
# This will only download videos with "[Official Video]" in it. Note that we
# double backslash to make YAML happy
match:
- '\\[Official Video\\]'
# For each entry's `description` value...
description:
# Match with capture groups and defaults.
# This tries to scrape a date from the description and produce new
# source variables
match:
- '([0-9]{4})-([0-9]{2})-([0-9]{2})'
# Exclude any entry where the description contains #short
exclude:
- '#short'
# Each capture group creates these new source variables, respectively,
# as well a sanitized version, i.e. `captured_upload_year_sanitized`
capture_group_names:
- "captured_upload_year"
- "captured_upload_month"
- "captured_upload_day"
# And if the string does not match, use these as respective default
# values for the new source variables.
capture_group_defaults:
- "{upload_year}"
- "{upload_month}"
- "{upload_day}"
skip_if_match_fails
~~~~~~~~~~~~~~~~~~~
Defaults to True. If True, when any match fails and has no defaults, the entry will be
skipped. If False, ytdl-sub will error and all downloads will not proceed.
split_by_chapters split_by_chapters
''''''''''''''''' -----------------
.. autoclass:: ytdl_sub.plugins.split_by_chapters.SplitByChaptersOptions() Splits a file by chapters into multiple files. Each file becomes its own entry with the
:members: when_no_chapters new source variables ``chapter_title``, ``chapter_title_sanitized``, ``chapter_index``,
:member-order: bysource ``chapter_index_padded``, ``chapter_count``.
:exclude-members: partial_validate
------------------------------------------------------------------------------- If a file has no chapters, and ``when_no_chapters`` is set to "pass", then ``chapter_title`` is
set to the entry's title and ``chapter_index``, ``chapter_count`` are both set to 1.
Note that when using this plugin and performing dry-run, it assumes embedded chapters are being
used with no modifications.
Usage:
.. code-block:: yaml
presets:
my_example_preset:
split_by_chapters:
when_no_chapters: "pass"
when_no_chapters
~~~~~~~~~~~~~~~~
Behavior to perform when no chapters are present. Supports "pass" (continue processing),
"drop" (exclude it from output), and "error" (stop processing for everything).
subtitles subtitles
''''''''' ---------
.. autoclass:: ytdl_sub.plugins.subtitles.SubtitleOptions() Defines how to download and store subtitles. Using this plugin creates two new variables:
:members: subtitles_name, subtitles_type, embed_subtitles, languages, allow_auto_generated_subtitles ``lang`` and ``subtitles_ext``. ``lang`` is dynamic since you can download multiple subtitles.
:member-order: bysource It will set the respective language to the correct subtitle file.
:exclude-members: partial_validate
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
subtitles:
subtitles_name: "{title_sanitized}.{lang}.{subtitles_ext}"
subtitles_type: "srt"
embed_subtitles: False
languages: "en" # supports list of multiple languages
allow_auto_generated_subtitles: False
allow_auto_generated_subtitles
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Optional. Whether to allow auto generated subtitles. Defaults to False.
embed_subtitles
~~~~~~~~~~~~~~~
Optional. Whether to embed the subtitles into the video file. Defaults to False.
NOTE: webm files can only embed "vtt" subtitle types.
languages
~~~~~~~~~
Optional. Language code(s) to download for subtitles. Supports a single or list of multiple
language codes. Defaults to "en".
subtitles_name
~~~~~~~~~~~~~~
Optional. The file name for the media's subtitles if they are present. This can include
directories such as ``"Season {upload_year}/{title_sanitized}.{lang}.{subtitles_ext}"``, and
will be placed in the output directory. ``lang`` is dynamic since you can download multiple
subtitles. It will set the respective language to the correct subtitle file.
subtitles_type
~~~~~~~~~~~~~~
Optional. One of the subtitle file types "srt", "vtt", "ass", "lrc". Defaults to "srt"
throttle_protection throttle_protection
''''''''''''''''''' -------------------
.. autoclass:: ytdl_sub.plugins.throttle_protection.ThrottleProtectionOptions() Provides options to make ytdl-sub look more 'human-like' to protect from throttling. For
:members: range-based values, a random number will be chosen within the range to avoid sleeps looking
:member-order: bysource scripted.
------------------------------------------------------------------------------- Usage:
.. code-block:: yaml
presets:
my_example_preset:
throttle_protection:
sleep_per_download_s:
min: 2.2
max: 10.8
sleep_per_subscription_s:
min: 9.0
max: 14.1
max_downloads_per_subscription:
min: 10
max: 36
subscription_download_probability: 1.0
max_downloads_per_subscription
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Number of downloads to perform per subscription.
sleep_per_download_s
~~~~~~~~~~~~~~~~~~~~
Number in seconds to sleep between each download. Does not include time it takes for
ytdl-sub to perform post-processing.
sleep_per_subscription_s
~~~~~~~~~~~~~~~~~~~~~~~~
Number in seconds to sleep between each subscription.
subscription_download_probability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Probability to perform any downloads, recomputed for each subscription. This is only
recommended to set if you run ytdl-sub in a cron-job, that way you are statistically
guaranteed over time to eventually download the subscription.
video_tags video_tags
'''''''''' ----------
.. autoclass:: ytdl_sub.plugins.video_tags.VideoTagsOptions() Adds tags to every downloaded video file using ffmpeg ``-metadata key=value`` args.
Usage:
.. code-block:: yaml
presets:
my_example_preset:
video_tags:
title: "{title}"
date: "{upload_date}"
description: "{description}"
tags
~~~~
Key/values of tag names/values. Supports source and override variables.
ytdl_options
------------
Optional. This section allows you to add any ytdl argument to ytdl-sub's downloader.
The argument names can differ slightly from the command-line argument names. See
`this docstring <https://github.com/yt-dlp/yt-dlp/blob/2022.04.08/yt_dlp/YoutubeDL.py#L197>`_
for more details.
ytdl_options should be formatted like:
.. code-block:: yaml
presets:
my_example_preset:
ytdl_options:
# Ignore any download related errors and continue
ignoreerrors: True
# Stop downloading additional metadata/videos if it
# exists in your download archive
break_on_existing: True
# Stop downloading additional metadata/videos if it
# is out of your date range
break_on_reject: True
# Path to your YouTube cookies file to download 18+ restricted content
cookiefile: "/path/to/cookies/file.txt"
# Only download this number of videos/audio
max_downloads: 10
# Download and use English title/description/etc YouTube metadata
extractor_args:
youtube:
lang:
- "en"
where each key is a ytdl argument. Include in the example are some popular ytdl_options.

View file

@ -0,0 +1,87 @@
================
Prebuilt Presets
================
If you are ready to start downloading, see our
`examples directory <https://github.com/jmbannon/ytdl-sub/tree/master/examples>`_
for ready-to-use configs and subscriptions. Read through them carefully before use.
Helper Presets
==============
By themselves, these presets won't get your media downloaded, but they're useful for condensing multi-line modifications to other presets into a single line through :ref:`guides/getting_started/advanced_configuration:preset inheritance`.
best_video_quality
------------------
This preset:
``1`` Is named ``best_video_quality``
``2`` Searches for the best video and audio formats available to download
``4`` Uses the ``mp4`` extension when merging multiple formats into one file
.. code-block:: yaml
:linenos:
best_video_quality:
format: "bestvideo+bestaudio/best"
ytdl_options:
merge_output_format: "mp4"
max_1080p
---------
This preset:
``1`` Is named ``max_1080p``
``2`` Searches for the best video (up to 1080p) and audio formats to download
``4`` Uses the ``mp4`` extension when merging multiple formats into one file
.. code-block:: yaml
:linenos:
max_1080p:
format: "(bv*[height<=1080]+bestaudio/best[height<=1080])"
ytdl_options:
merge_output_format: "mp4"
chunk_initial_download
----------------------
This preset:
``1`` Is named ``chunk_initial_download``
``3`` Downloads up to 20 videos per subscription per run
``4`` Reverses the subscription playlist, which starts from the beginning of the playlist in most cases
``5`` Will not stop downloading videos when it reaches a video that exists, but will skip the existing videos instead of redownloading them
``6`` Will stop downloading videos if a yt-dlp reject occurs
.. code-block:: yaml
:linenos:
chunk_initial_download:
ytdl_options:
max_downloads: 20
playlistreverse: True
break_on_existing: False
break_on_reject: True
Only Recent
-----------
This preset:
``1`` Is named "Only Recent"
``3`` Only attempts to download videos uploaded after ``today-{only_recent_date_range}``, where ``{only_recent_date_range}`` is set as an override variable in your subscription or a :ref:`child preset <guides/getting_started/advanced_configuration:preset inheritance>`.
.. code-block:: yaml
:linenos:
"Only Recent":
date_range:
after: "today-{only_recent_date_range}"

View file

@ -0,0 +1,474 @@
Scripting Functions
===================
Array Functions
---------------
array
~~~~~
``array(maybe_array: AnyArgument) -> Array``
Tries to cast an unknown variable type to an Array.
array_apply
~~~~~~~~~~~
``array_apply(array: Array, lambda_function: Lambda) -> Array``
Apply a lambda function on every element in the Array.
array_at
~~~~~~~~
``array_at(array: Array, idx: Integer) -> AnyArgument``
Return the element in the Array at index ``idx``.
array_contains
~~~~~~~~~~~~~~
``array_contains(array: Array, value: AnyArgument) -> Boolean``
Return True if the value exists in the Array. False otherwise.
array_enumerate
~~~~~~~~~~~~~~~
``array_enumerate(array: Array, lambda_function: LambdaTwo) -> Array``
Apply a lambda function on every element in the Array, where each arg
passed to the lambda function is ``idx, element`` as two separate args.
array_extend
~~~~~~~~~~~~
``array_extend(arrays: Array, ...) -> Array``
Combine multiple Arrays into a single Array.
array_flatten
~~~~~~~~~~~~~
``array_flatten(array: Array) -> Array``
Flatten any nested Arrays into a single-dimensional Array.
array_index
~~~~~~~~~~~
``array_index(array: Array, value: AnyArgument) -> Integer``
Return the index of the value within the Array if it exists. If it does not, it will
throw an error.
array_product
~~~~~~~~~~~~~
``array_product(arrays: Array, ...) -> Array``
Returns the Cartesian product of elements from different arrays
array_reduce
~~~~~~~~~~~~
``array_reduce(array: Array, lambda_reduce_function: LambdaReduce) -> AnyArgument``
Apply a reduce function on pairs of elements in the Array, until one element remains.
Executes using the left-most and reduces in the right direction.
array_reverse
~~~~~~~~~~~~~
``array_reverse(array: Array) -> Array``
Reverse an Array.
array_size
~~~~~~~~~~
``array_size(array: Array) -> Integer``
Returns the size of an Array.
array_slice
~~~~~~~~~~~
``array_slice(array: Array, start: Integer, end: Optional[Integer]) -> Array``
Returns the slice of the Array.
Boolean Functions
-----------------
and
~~~
``and(values: AnyArgument, ...) -> Boolean``
``and`` operator. Returns True if all values evaluate to True. False otherwise.
bool
~~~~
``bool(value: AnyArgument) -> Boolean``
Cast any type to a Boolean.
eq
~~
``eq(left: AnyArgument, right: AnyArgument) -> Boolean``
``==`` operator. Returns True if left == right. False otherwise.
gt
~~
``gt(left: AnyArgument, right: AnyArgument) -> Boolean``
``>`` operator. Returns True if left > right. False otherwise.
gte
~~~
``gte(left: AnyArgument, right: AnyArgument) -> Boolean``
``>=`` operator. Returns True if left >= right. False otherwise.
lt
~~
``lt(left: AnyArgument, right: AnyArgument) -> Boolean``
``<`` operator. Returns True if left < right. False otherwise.
lte
~~~
``lte(left: AnyArgument, right: AnyArgument) -> Boolean``
``<=`` operator. Returns True if left <= right. False otherwise.
ne
~~
``ne(left: AnyArgument, right: AnyArgument) -> Boolean``
``!=`` operator. Returns True if left != right. False otherwise.
not
~~~
``not(value: Boolean) -> Boolean``
``not`` operator. Returns the opposite of value.
or
~~
``or(values: AnyArgument, ...) -> Boolean``
``or`` operator. Returns True if any value evaluates to True. False otherwise.
xor
~~~
``xor(values: AnyArgument, ...) -> Boolean``
``^`` operator. Returns True if exactly one value is set to True. False otherwise.
Conditional Functions
---------------------
if
~~
``if(condition: Boolean, true: ReturnableArgumentA, false: ReturnableArgumentB) -> Union[ReturnableArgumentA, ReturnableArgumentB]``
Conditional ``if`` statement that returns the ``true`` or ``false`` parameter
depending on the ``condition`` value.
if_passthrough
~~~~~~~~~~~~~~
``if_passthrough(maybe_true_arg: ReturnableArgumentA, else_arg: ReturnableArgumentB) -> Union[ReturnableArgumentA, ReturnableArgumentB]``
Conditional ``if`` statement that returns the ``maybe_true_arg`` if it evaluates to True,
otherwise returns ``else_arg``.
Date Functions
--------------
datetime_strftime
~~~~~~~~~~~~~~~~~
``datetime_strftime(posix_timestamp: Integer, date_format: String) -> String``
Converts a posix timestamp to a date using strftime formatting.
Error Functions
---------------
assert
~~~~~~
``assert(value: ReturnableArgument, assert_message: String) -> ReturnableArgument``
Explicitly throw an error with the provided assert message if ``value`` evaluates to False.
If it evaluates to True, it will return ``value``.
throw
~~~~~
``throw(error_message: String) -> AnyArgument``
Explicitly throw an error with the provided error message.
Json Functions
--------------
from_json
~~~~~~~~~
``from_json(argument: String) -> AnyArgument``
Converts a JSON string into an actual type.
Map Functions
-------------
map
~~~
``map(maybe_mapping: AnyArgument) -> Map``
Tries to cast an unknown variable type to a Map.
map_apply
~~~~~~~~~
``map_apply(mapping: Map, lambda_function: LambdaTwo) -> Array``
Apply a lambda function on the Map, where each arg
passed to the lambda function is ``key, value`` as two separate args.
map_contains
~~~~~~~~~~~~
``map_contains(mapping: Map, key: AnyArgument) -> Boolean``
Returns True if the key is in the Map. False otherwise.
map_enumerate
~~~~~~~~~~~~~
``map_enumerate(mapping: Map, lambda_function: LambdaThree) -> Array``
Apply a lambda function on the Map, where each arg
passed to the lambda function is ``idx, key, value`` as three separate args.
map_get
~~~~~~~
``map_get(mapping: Map, key: AnyArgument, default: Optional[AnyArgument]) -> AnyArgument``
Return ``key``'s value within the Map. If ``key`` does not exist, and ``default`` is
provided, it will return ``default``. Otherwise, will error.
map_get_non_empty
~~~~~~~~~~~~~~~~~
``map_get_non_empty(mapping: Map, key: AnyArgument, default: AnyArgument) -> AnyArgument``
Return ``key``'s value within the Map. If ``key`` does not exist or is an empty string,
return ``default``. Otherwise, will error.
map_size
~~~~~~~~
``map_size(mapping: Map) -> Integer``
Returns the size of a Map.
Numeric Functions
-----------------
add
~~~
``add(values: Numeric, ...) -> Numeric``
``+`` operator. Returns the sum of all values.
div
~~~
``div(left: Numeric, right: Numeric) -> Numeric``
``/`` operator. Returns ``left / right``.
float
~~~~~
``float(value: AnyArgument) -> Float``
Cast to Float.
int
~~~
``int(value: AnyArgument) -> Integer``
Cast to Integer.
max
~~~
``max(values: Numeric, ...) -> Numeric``
Returns max of all values.
min
~~~
``min(values: Numeric, ...) -> Numeric``
Returns min of all values.
mod
~~~
``mod(left: Numeric, right: Numeric) -> Numeric``
``%`` operator. Returns ``left % right``.
mul
~~~
``mul(values: Numeric, ...) -> Numeric``
``*`` operator. Returns the product of all values.
pow
~~~
``pow(base: Numeric, exponent: Numeric) -> Numeric``
``**`` operator. Returns the exponential of the base and exponent value.
sub
~~~
``sub(values: Numeric, ...) -> Numeric``
``-`` operator. Subtracts all values from left to right.
Regex Functions
---------------
regex_fullmatch
~~~~~~~~~~~~~~~
``regex_fullmatch(regex: String, string: String) -> Array``
Checks for entire string to be a match. If a match exists, returns
the string as the first element of the Array. If there are capture groups, returns each
group as a subsequent element in the Array.
regex_match
~~~~~~~~~~~
``regex_match(regex: String, string: String) -> Array``
Checks for a match only at the beginning of the string. If a match exists, returns
the string as the first element of the Array. If there are capture groups, returns each
group as a subsequent element in the Array.
regex_search
~~~~~~~~~~~~
``regex_search(regex: String, string: String) -> Array``
Checks for a match anywhere in the string. If a match exists, returns
the string as the first element of the Array. If there are capture groups, returns each
group as a subsequent element in the Array.
String Functions
----------------
capitalize
~~~~~~~~~~
``capitalize(string: String) -> String``
Capitalize the first character in the string.
concat
~~~~~~
``concat(values: String, ...) -> String``
Concatenate multiple Strings into a single String.
lower
~~~~~
``lower(string: String) -> String``
Lower-case the entire String.
pad
~~~
``pad(string: String, length: Integer, char: String) -> String``
Pads the string to the given length
pad_zero
~~~~~~~~
``pad_zero(numeric: Numeric, length: Integer) -> String``
Pads a numeric with zeros to the given length
replace
~~~~~~~
``replace(string: String, old: String, new: String, count: Optional[Integer]) -> String``
Replace the ``old`` part of the String with the ``new``. Optionally only replace it
``count`` number of times.
slice
~~~~~
``slice(string: String, start: Integer, end: Optional[Integer]) -> String``
Returns the slice of the Array.
string
~~~~~~
``string(value: AnyArgument) -> String``
Cast to String.
titlecase
~~~~~~~~~
``titlecase(string: String) -> String``
Capitalize each word in the string.
upper
~~~~~
``upper(string: String) -> String``
Upper-case the entire String.
Ytdl-Sub Functions
------------------
legacy_bracket_safety
~~~~~~~~~~~~~~~~~~~~~
``legacy_bracket_safety(value: ReturnableArgument) -> ReturnableArgument``
ytdl-sub used to replace brackets ('{', '}') with unicode brackets ('', '') to not
interfere with its legacy variable scripting system. This function replicates that
behavior.
sanitize
~~~~~~~~
``sanitize(value: AnyArgument) -> String``
Sanitize a string using yt-dlp's ``sanitize_filename`` method to ensure it's safe to use
for file/directory names on any OS.
sanitize_plex_episode
~~~~~~~~~~~~~~~~~~~~~
``sanitize_plex_episode(string: String) -> String``
Sanitize a string using ``sanitize`` and replace numerics with their respective fixed-width
numbers. This is used to have Plex avoid scraping numbers like ``4x4`` as the
season and/or episode.
to_date_metadata
~~~~~~~~~~~~~~~~
``to_date_metadata(yyyymmdd: String) -> Map``
Takes a date in the form of YYYYMMDD and returns a Map containing:
- date (String, YYYYMMDD)
- date_standardized (String, YYYY-MM-DD)
- year (Integer)
- month (Integer)
- day (Integer)
- year_truncated (String, YY from YY[YY])
- month_padded (String)
- day_padded (String)
- year_truncated_reversed (Integer, 100 - year_truncated)
- month_reversed (Integer, 13 - month)
- month_reversed_padded (String)
- day_reversed (Integer, total_days_in_month + 1 - day)
- day_reversed_padded (String)
- day_of_year (Integer)
- day_of_year_padded (String, padded 3)
- day_of_year_reversed (Integer, total_days_in_year + 1 - day_of_year)
- day_of_year_reversed_padded (String, padded 3)
to_native_filepath
~~~~~~~~~~~~~~~~~~
``to_native_filepath(filepath: String) -> String``
Convert any unix-based path separators ('/') with the OS's native
separator.
truncate_filepath_if_too_long
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``truncate_filepath_if_too_long(filepath: String) -> String``
If a file-path is too long for the OS, this function will truncate it while preserving
the extension.

View file

@ -10,7 +10,7 @@ to define a ``subscription``: something we want to recurrently download such as
channel or playlist. channel or playlist.
The only difference between a ``subscription`` and ``preset`` is that the subscription The only difference between a ``subscription`` and ``preset`` is that the subscription
must have all required fields and ``{variables}`` defined so it can perform a download. must have all required fields and ``{override_variables}`` defined so it can perform a download.
Below is an example that downloads a YouTube playlist: Below is an example that downloads a YouTube playlist:

View file

@ -1,9 +1,5 @@
# Configuration file for the Sphinx documentation builder. # Configuration file for the Sphinx documentation builder.
import os
import sys
sys.path.insert(0, os.path.abspath('../../src'))
# For the full list of built-in configuration values, see the documentation: # For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html # https://www.sphinx-doc.org/en/master/usage/configuration.html
@ -19,13 +15,12 @@ release = "2023.12.15"
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [ extensions = [
"sphinx.ext.autodoc", "sphinx.ext.autodoc",
"sphinx.ext.autosectionlabel", "sphinx.ext.autosectionlabel",
# "sphinx.ext.autosummary", "sphinx.ext.extlinks",
"sphinx.ext.extlinks", "sphinx.ext.napoleon",
"sphinx.ext.napoleon", "sphinx_copybutton",
"sphinx_copybutton", "sphinx_design",
"sphinx_design",
] ]
templates_path = ["_templates"] templates_path = ["_templates"]
@ -38,25 +33,25 @@ exclude_patterns = []
html_theme = "sphinx_book_theme" html_theme = "sphinx_book_theme"
html_theme_options = { html_theme_options = {
"icon_links": [ "icon_links": [
{ {
"name": "GitHub", "name": "GitHub",
"url": "https://github.com/jmbannon/ytdl-sub", "url": "https://github.com/jmbannon/ytdl-sub",
"icon": "fa-brands fa-square-github", "icon": "fa-brands fa-square-github",
"type": "fontawesome", "type": "fontawesome",
}, },
{ {
"name": "Discord", "name": "Discord",
"url": "https://discord.gg/v8j9RAHb4k", "url": "https://discord.gg/v8j9RAHb4k",
"icon": "https://img.shields.io/discord/994270357957648404?logo=Discord", "icon": "https://img.shields.io/discord/994270357957648404?logo=Discord",
"type": "url", "type": "url",
}, },
], ],
"announcement": ( "announcement": (
"Migration to <a href='https://ytdl-sub--841.org.readthedocs.build/en/841/config.html#beautifying-subscriptions'>beautiful subscriptions</a> is now live" "Migration to <a href='https://ytdl-sub--841.org.readthedocs.build/en/841/config.html#beautifying-subscriptions'>beautiful subscriptions</a> is now live"
), ),
"navigation_depth": 10, "navigation_depth": 10,
"show_toc_level": 10, "show_toc_level": 10,
} }
html_static_path = ["_static"] html_static_path = ["_static"]
@ -65,8 +60,13 @@ html_static_path = ["_static"]
# Make sure the all autosectionlabel targets are unique # Make sure the all autosectionlabel targets are unique
autosectionlabel_prefix_document = True autosectionlabel_prefix_document = True
suppress_warnings = [
'autosectionlabel.*',
]
extlinks = {"yt-dlp": ("https://github.com/yt-dlp/yt-dlp/%s", "yt-dlp%s")} extlinks = {
"yt-dlp": ("https://github.com/yt-dlp/yt-dlp/%s", "yt-dlp%s"),
}
# -- Options for autodoc ---------------------------------------------------- # -- Options for autodoc ----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#configuration # https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#configuration
@ -74,10 +74,10 @@ extlinks = {"yt-dlp": ("https://github.com/yt-dlp/yt-dlp/%s", "yt-dlp%s")}
# Automatically extract typehints when specified and place them in # Automatically extract typehints when specified and place them in
# descriptions of the relevant function/method. # descriptions of the relevant function/method.
autodoc_default_options = { autodoc_default_options = {
"autodoc_typehints_format": "short", "autodoc_typehints_format": "short",
"autodoc_class_signature": "separated", "autodoc_class_signature": "separated",
"add_module_names": False, "add_module_names": False,
# "add_class_names": False, # "add_class_names": False,
} }
python_use_unqualified_type_names = True python_use_unqualified_type_names = True

View file

@ -1,7 +1,7 @@
Advanced Configuration Advanced Configuration
====================== ======================
If the :doc:`prebuilt presets </guides/getting_started/prebuilt_presets>` aren't suitable for your needs, you may want to set up an advanced configuration. If the :doc:`prebuilt presets </code_reference/prebuilt_presets>` aren't suitable for your needs, you may want to set up an advanced configuration.
Layout of a Config file Layout of a Config file
----------------------- -----------------------
@ -17,5 +17,5 @@ The layout of the ``config.yaml`` file is relatively straightforward:
plugin1_option1: value1 plugin1_option1: value1
Modifying an Existing Preset Preset Inheritance
---------------------------- ------------------

View file

@ -22,9 +22,9 @@ Your first configuration will look pretty simple:
The first two lines in this ``config.yaml`` file are the ``configuration``, and define the ``working_directory``, which is described near the bottom of :ref:`this section <guides/getting_started/index:quick overview of \`\`ytdl-sub\`\`>` The first two lines in this ``config.yaml`` file are the ``configuration``, and define the ``working_directory``, which is described near the bottom of :ref:`this section <guides/getting_started/index:quick overview of \`\`ytdl-sub\`\`>`
Line 4 begins the definition o your custom ``presets``, with line 5 being the name of your first custom ``preset``. Line 4 begins the definition of your custom ``presets``, with line 5 being the name of your first custom ``preset``.
Lines 7 and 8 tell ``ytdl-sub`` which :doc:`/guides/getting_started/prebuilt_presets` to expand on; these ``presets`` already indicate that the downloaded files should be: Lines 7 and 8 tell ``ytdl-sub`` which :doc:`/code_reference/prebuilt_presets` to expand on; these ``presets`` already indicate that the downloaded files should be:
- in a format usable by, and with metadata accessible to, Jellyfin - in a format usable by, and with metadata accessible to, Jellyfin
- sorted by upload date, and - sorted by upload date, and

View file

@ -3,7 +3,7 @@ Getting Started
Now that you've completed your install of ``ytdl-sub``, it's time to get started. This is a 3-step process: Now that you've completed your install of ``ytdl-sub``, it's time to get started. This is a 3-step process:
- Create your configuration file (if the :doc:`prebuilt_presets` don't fit your needs) - Create your configuration file (if the :doc:`/code_reference/prebuilt_presets` don't fit your needs)
- Create your subscription file - Create your subscription file
- Automate starting YTDL-Sub - Automate starting YTDL-Sub
@ -57,19 +57,19 @@ Ready to Start?
Now that you have installed ``ytdl-sub``, checked your skills, and gotten a bit of background on how ``ytdl-sub`` functions, read through the articles below to get started: Now that you have installed ``ytdl-sub``, checked your skills, and gotten a bit of background on how ``ytdl-sub`` functions, read through the articles below to get started:
:doc:`Step 1: Initial Configuration <first_config>` :doc:`Step 1: Initial Subscriptions <first_sub>`
:doc:`Step 2: Initial Subscriptions <first_sub>` :doc:`Step 2: Your First Download <first_download>`
:doc:`Step 3: Your First Download <first_download>` :doc:`Step 3: Automating Downloads <automating_downloads>`
:doc:`Step 4: Automating Downloads <automating_downloads>` :doc:`Step 4: Initial Configuration <first_config>`
:doc:`Advanced Configuration <advanced_configuration>` :doc:`Advanced Configuration <advanced_configuration>`
Other docs that may be of use: Other docs that may be of use:
:doc:`prebuilt_presets` :doc:`/code_reference/prebuilt_presets`
:doc:`examples` :doc:`examples`
@ -83,5 +83,4 @@ Other docs that may be of use:
first_download first_download
automating_downloads automating_downloads
advanced_configuration advanced_configuration
prebuilt_presets
examples examples

View file

@ -1,5 +0,0 @@
Example Configs
===============
If you are ready to start downloading, see our
`examples directory <https://github.com/jmbannon/ytdl-sub/tree/master/examples>`_
for ready-to-use configs and subscriptions. Read through them carefully before use.