[REFACTOR] Organize variable definitions (#860)
This commit is contained in:
parent
189e897888
commit
f2d55fdb23
14 changed files with 1532 additions and 917 deletions
|
|
@ -7,110 +7,163 @@ Entry Variables
|
||||||
|
|
||||||
channel
|
channel
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
The channel name if it exists, otherwise returns the uploader.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The channel name if it exists, otherwise returns the uploader.
|
||||||
|
|
||||||
channel_id
|
channel_id
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
The channel id if it exists, otherwise returns the entry uploader ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The channel id if it exists, otherwise returns the entry uploader ID.
|
||||||
|
|
||||||
chapters
|
chapters
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
Chapters if they exist
|
:type: ``Array``
|
||||||
|
:description:
|
||||||
|
Chapters if they exist
|
||||||
|
|
||||||
comments
|
comments
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
Comments if they are requested
|
:type: ``Array``
|
||||||
|
:description:
|
||||||
|
Comments if they are requested
|
||||||
|
|
||||||
creator
|
creator
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
The creator name if it exists, otherwise returns the channel.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The creator name if it exists, otherwise returns the channel.
|
||||||
|
|
||||||
description
|
description
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
The description if it exists. Otherwise, returns an emtpy string.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The description if it exists. Otherwise, returns an emtpy string.
|
||||||
|
|
||||||
duration
|
duration
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
The duration of the entry in seconds
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The duration of the entry in seconds if it exists. Defaults to zero otherwise.
|
||||||
|
|
||||||
epoch
|
epoch
|
||||||
~~~~~
|
~~~~~
|
||||||
The unix epoch of when the metadata was scraped by yt-dlp.
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The unix epoch of when the metadata was scraped by yt-dlp.
|
||||||
|
|
||||||
epoch_date
|
epoch_date
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
The epoch's date, in YYYYMMDD format.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The epoch's date, in YYYYMMDD format.
|
||||||
|
|
||||||
epoch_hour
|
epoch_hour
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
The epoch's hour
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The epoch's hour
|
||||||
|
|
||||||
ext
|
ext
|
||||||
~~~
|
~~~
|
||||||
The downloaded entry's file extension
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The downloaded entry's file extension
|
||||||
|
|
||||||
extractor
|
extractor
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
The yt-dlp extractor name
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The yt-dlp extractor name
|
||||||
|
|
||||||
extractor_key
|
extractor_key
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
The yt-dlp extractor key
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The yt-dlp extractor key
|
||||||
|
|
||||||
ie_key
|
ie_key
|
||||||
~~~~~~
|
~~~~~~
|
||||||
The ie_key, used in legacy yt-dlp things as the 'info-extractor key'
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The ie_key, used in legacy yt-dlp things as the 'info-extractor key'.
|
||||||
|
If it does not exist, return ``extractor_key``
|
||||||
|
|
||||||
info_json_ext
|
info_json_ext
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
The "info.json" extension
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The "info.json" extension
|
||||||
|
|
||||||
requested_subtitles
|
requested_subtitles
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
Subtitles if they are requested and exist
|
:type: ``Map``
|
||||||
|
:description:
|
||||||
|
Subtitles if they are requested and exist
|
||||||
|
|
||||||
sponsorblock_chapters
|
sponsorblock_chapters
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
Sponsorblock Chapters if they are requested and exist
|
:type: ``Array``
|
||||||
|
:description:
|
||||||
|
Sponsorblock Chapters if they are requested and exist
|
||||||
|
|
||||||
thumbnail_ext
|
thumbnail_ext
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
The download entry's thumbnail extension. Will always return 'jpg'. Until there is a
|
:type: ``String``
|
||||||
need to support other image types, we always convert to jpg.
|
:description:
|
||||||
|
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
|
title
|
||||||
~~~~~
|
~~~~~
|
||||||
The title of the entry. If a title does not exist, returns its unique ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The title of the entry. If a title does not exist, returns its unique ID.
|
||||||
|
|
||||||
title_sanitized_plex
|
title_sanitized_plex
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
The sanitized title with additional sanitizing for Plex. It replaces numbers with
|
:type: ``String``
|
||||||
fixed-width numbers so Plex does not recognize them as season or episode numbers.
|
:description:
|
||||||
|
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
|
uid
|
||||||
~~~
|
~~~
|
||||||
The entry's unique ID
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry's unique ID
|
||||||
|
|
||||||
uid_sanitized_plex
|
uid_sanitized_plex
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The sanitized uid with additional sanitizing for Plex. Replaces numbers with
|
:type: ``String``
|
||||||
fixed-width numbers so Plex does not recognize them as season or episode numbers.
|
:description:
|
||||||
|
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
|
uploader
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
The uploader if it exists, otherwise return the uploader ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The uploader if it exists, otherwise return the uploader ID.
|
||||||
|
|
||||||
uploader_id
|
uploader_id
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
The uploader id if it exists, otherwise return the unique ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The uploader id if it exists, otherwise return the unique ID.
|
||||||
|
|
||||||
uploader_url
|
uploader_url
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
The uploader url if it exists, otherwise returns the webpage_url.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The uploader url if it exists, otherwise returns the webpage_url.
|
||||||
|
|
||||||
webpage_url
|
webpage_url
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
The url to the webpage.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The url to the webpage.
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -119,19 +172,28 @@ Metadata Variables
|
||||||
|
|
||||||
entry_metadata
|
entry_metadata
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
The entry's info.json
|
:type: ``Map``
|
||||||
|
:description:
|
||||||
|
The entry's info.json
|
||||||
|
|
||||||
playlist_metadata
|
playlist_metadata
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
Metadata from the playlist (i.e. the parent metadata, like playlist -> entry)
|
:type: ``Map``
|
||||||
|
:description:
|
||||||
|
Metadata from the playlist (i.e. the parent metadata, like playlist -> entry)
|
||||||
|
|
||||||
sibling_metadata
|
sibling_metadata
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
Metadata from any sibling entries that reside in the same playlist as this entry.
|
:type: ``Array``
|
||||||
|
:description:
|
||||||
|
Metadata from any sibling entries that reside in the same playlist as this entry.
|
||||||
|
|
||||||
source_metadata
|
source_metadata
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
Metadata from the source (i.e. the grandparent metadata, like channel -> playlist -> entry)
|
:type: ``Map``
|
||||||
|
:description:
|
||||||
|
Metadata from the source
|
||||||
|
(i.e. the grandparent metadata, like channel -> playlist -> entry)
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -140,80 +202,114 @@ Playlist Variables
|
||||||
|
|
||||||
playlist_count
|
playlist_count
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
Playlist count if it exists, otherwise returns ``1``.
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
Playlist count if it exists, otherwise returns ``1``.
|
||||||
|
|
||||||
Note that for channels/playlists, any change (i.e. adding or removing a video) will make
|
Note that for channels/playlists, any change (i.e. adding or removing a video) will make
|
||||||
this value change. Use with caution.
|
this value change. Use with caution.
|
||||||
|
|
||||||
playlist_description
|
playlist_description
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
The playlist description if it exists, otherwise returns the entry's description.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The playlist description if it exists, otherwise returns the entry's description.
|
||||||
|
|
||||||
playlist_index
|
playlist_index
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
Playlist index if it exists, otherwise returns ``1``.
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
Playlist index if it exists, otherwise returns ``1``.
|
||||||
|
|
||||||
Note that for channels/playlists, any change (i.e. adding or removing a video) will make
|
Note that for channels/playlists, any change (i.e. adding or removing a video) will make
|
||||||
this value change. Use with caution.
|
this value change. Use with caution.
|
||||||
|
|
||||||
playlist_index_padded
|
playlist_index_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
playlist_index padded two digits
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
playlist_index padded two digits
|
||||||
|
|
||||||
playlist_index_padded6
|
playlist_index_padded6
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
playlist_index padded six digits.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
playlist_index padded six digits.
|
||||||
|
|
||||||
playlist_index_reversed
|
playlist_index_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Playlist index reversed via ``playlist_count - playlist_index + 1``
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
Playlist index reversed via ``playlist_count - playlist_index + 1``
|
||||||
|
|
||||||
playlist_index_reversed_padded
|
playlist_index_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
playlist_index_reversed padded two digits
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
playlist_index_reversed padded two digits
|
||||||
|
|
||||||
playlist_index_reversed_padded6
|
playlist_index_reversed_padded6
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
playlist_index_reversed padded six digits.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
playlist_index_reversed padded six digits.
|
||||||
|
|
||||||
playlist_max_upload_date
|
playlist_max_upload_date
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Max upload_date for all entries in this entry's playlist if it exists, otherwise returns
|
:type: ``String``
|
||||||
``upload_date``
|
:description:
|
||||||
|
Max upload_date for all entries in this entry's playlist if it exists, otherwise returns
|
||||||
|
``upload_date``
|
||||||
|
|
||||||
playlist_max_upload_year
|
playlist_max_upload_year
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Max upload_year for all entries in this entry's playlist if it exists, otherwise returns
|
:type: ``Integer``
|
||||||
``upload_year``
|
:description:
|
||||||
|
Max upload_year for all entries in this entry's playlist if it exists, otherwise returns
|
||||||
|
``upload_year``
|
||||||
|
|
||||||
playlist_max_upload_year_truncated
|
playlist_max_upload_year_truncated
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The max playlist truncated upload year for all entries in this entry's playlist if it
|
:type: ``Integer``
|
||||||
exists, otherwise returns ``upload_year_truncated``.
|
:description:
|
||||||
|
The max playlist truncated upload year for all entries in this entry's playlist if it
|
||||||
|
exists, otherwise returns ``upload_year_truncated``.
|
||||||
|
|
||||||
playlist_title
|
playlist_title
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
Name of its parent playlist/channel if it exists, otherwise returns its title.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
Name of its parent playlist/channel if it exists, otherwise returns its title.
|
||||||
|
|
||||||
playlist_uid
|
playlist_uid
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
The playlist unique ID if it exists, otherwise return the entry unique ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The playlist unique ID if it exists, otherwise return the entry unique ID.
|
||||||
|
|
||||||
playlist_uploader
|
playlist_uploader
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
The playlist uploader if it exists, otherwise return the entry uploader.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The playlist uploader if it exists, otherwise return the entry uploader.
|
||||||
|
|
||||||
playlist_uploader_id
|
playlist_uploader_id
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
The playlist uploader id if it exists, otherwise returns the entry uploader ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The playlist uploader id if it exists, otherwise returns the entry uploader ID.
|
||||||
|
|
||||||
playlist_uploader_url
|
playlist_uploader_url
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
The playlist uploader url if it exists, otherwise returns the playlist webpage_url.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The playlist uploader url if it exists, otherwise returns the playlist webpage_url.
|
||||||
|
|
||||||
playlist_webpage_url
|
playlist_webpage_url
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
The playlist webpage url if it exists. Otherwise, returns the entry webpage url.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The playlist webpage url if it exists. Otherwise, returns the entry webpage url.
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -222,75 +318,108 @@ Release Date Variables
|
||||||
|
|
||||||
release_date
|
release_date
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
The entry’s release date, in YYYYMMDD format. If not present, return the upload date.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry’s release date, in YYYYMMDD format. If not present, return the upload date.
|
||||||
|
|
||||||
release_date_standardized
|
release_date_standardized
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The release date formatted as YYYY-MM-DD
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The uploaded date formatted as YYYY-MM-DD
|
||||||
|
|
||||||
release_day
|
release_day
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
The release day as an integer (no padding).
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The upload day as an integer (no padding).
|
||||||
|
|
||||||
release_day_of_year
|
release_day_of_year
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
The day of the year, i.e. February 1st returns ``32``
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The day of the year, i.e. February 1st returns ``32``
|
||||||
|
|
||||||
release_day_of_year_padded
|
release_day_of_year_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The release day of year, but padded i.e. February 1st returns "032"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The upload day of year, but padded i.e. February 1st returns "032"
|
||||||
|
|
||||||
release_day_of_year_reversed
|
release_day_of_year_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The release day, but reversed using ``{total_days_in_year} + 1 - {release_day}``,
|
:type: ``Integer``
|
||||||
i.e. February 2nd would have release_day_of_year_reversed of ``365 + 1 - 32`` = ``334``
|
:description:
|
||||||
|
The upload 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
|
release_day_of_year_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The reversed release day of year, but padded i.e. December 31st returns "001"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The reversed upload day of year, but padded i.e. December 31st returns "001"
|
||||||
|
|
||||||
release_day_padded
|
release_day_padded
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The entry's release day padded to two digits, i.e. the fifth returns "05"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry's upload day padded to two digits, i.e. the fifth returns "05"
|
||||||
|
|
||||||
release_day_reversed
|
release_day_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
The release day, but reversed using ``{total_days_in_month} + 1 - {release_day}``,
|
:type: ``Integer``
|
||||||
i.e. August 8th would have release_day_reversed of ``31 + 1 - 8`` = ``24``
|
:description:
|
||||||
|
The upload 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
|
release_day_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The reversed release day, but padded. i.e. August 30th returns "02".
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The reversed upload day, but padded. i.e. August 30th returns "02".
|
||||||
|
|
||||||
release_month
|
release_month
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
The release month as an integer (no padding).
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The upload month as an integer (no padding).
|
||||||
|
|
||||||
release_month_padded
|
release_month_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
The entry's release month padded to two digits, i.e. March returns "03"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry's upload month padded to two digits, i.e. March returns "03"
|
||||||
|
|
||||||
release_month_reversed
|
release_month_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The release month, but reversed
|
:type: ``Integer``
|
||||||
using ``13 - {release_month}``, i.e. March returns ``10``
|
:description:
|
||||||
|
The upload month, but reversed using ``13 - {release_month}``, i.e. March returns ``10``
|
||||||
|
|
||||||
release_month_reversed_padded
|
release_month_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The reversed release month, but padded. i.e. November returns "02"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The reversed upload month, but padded. i.e. November returns "02"
|
||||||
|
|
||||||
release_year
|
release_year
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
The entry's release year
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The entry's upload year
|
||||||
|
|
||||||
release_year_truncated
|
release_year_truncated
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The last two digits of the release year, i.e. 22 in 2022
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The last two digits of the upload year, i.e. 22 in 2022
|
||||||
|
|
||||||
release_year_truncated_reversed
|
release_year_truncated_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The release year truncated, but reversed using ``100 - {release_year_truncated}``, i.e.
|
:type: ``Integer``
|
||||||
2022 returns ``100 - 22`` = ``78``
|
:description:
|
||||||
|
The upload year truncated, but reversed using ``100 - {release_year_truncated}``, i.e.
|
||||||
|
2022 returns ``100 - 22`` = ``78``
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -299,47 +428,67 @@ Source Variables
|
||||||
|
|
||||||
source_count
|
source_count
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
The source count if it exists, otherwise returns the playlist count.
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The source count if it exists, otherwise returns ``1``.
|
||||||
|
|
||||||
source_description
|
source_description
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The source description if it exists, otherwise returns the playlist description.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source description if it exists, otherwise returns the playlist description.
|
||||||
|
|
||||||
source_index
|
source_index
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
Source index if it exists, otherwise returns ``1``.
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
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 recommended to not use this unless you know the source will never add new content
|
||||||
(it is easy for this value to change).
|
(it is easy for this value to change).
|
||||||
|
|
||||||
source_index_padded
|
source_index_padded
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
The source index, padded.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source index, padded two digits.
|
||||||
|
|
||||||
source_title
|
source_title
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
Name of the source (i.e. channel with multiple playlists) if it exists, otherwise
|
:type: ``String``
|
||||||
returns its playlist_title.
|
:description:
|
||||||
|
Name of the source (i.e. channel with multiple playlists) if it exists, otherwise
|
||||||
|
returns its playlist_title.
|
||||||
|
|
||||||
source_uid
|
source_uid
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
The source unique id if it exists, otherwise returns the playlist unique ID.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source unique id if it exists, otherwise returns the playlist unique ID.
|
||||||
|
|
||||||
source_uploader
|
source_uploader
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
The source uploader if it exists, otherwise return the playlist_uploader
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source uploader if it exists, otherwise return the playlist_uploader
|
||||||
|
|
||||||
source_uploader_id
|
source_uploader_id
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The source uploader id if it exists, otherwise returns the playlist_uploader_id
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source uploader id if it exists, otherwise returns the playlist_uploader_id
|
||||||
|
|
||||||
source_uploader_url
|
source_uploader_url
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
The source uploader url if it exists, otherwise returns the source webpage_url.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source uploader url if it exists, otherwise returns the source webpage_url.
|
||||||
|
|
||||||
source_webpage_url
|
source_webpage_url
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The source webpage url if it exists, otherwise returns the playlist webpage url.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The source webpage url if it exists, otherwise returns the playlist webpage url.
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -348,74 +497,108 @@ Upload Date Variables
|
||||||
|
|
||||||
upload_date
|
upload_date
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
The entry’s uploaded date, in YYYYMMDD format. If not present, return today’s date.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry’s uploaded date, in YYYYMMDD format. If not present, return today’s date.
|
||||||
|
|
||||||
upload_date_standardized
|
upload_date_standardized
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The uploaded date formatted as YYYY-MM-DD
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The uploaded date formatted as YYYY-MM-DD
|
||||||
|
|
||||||
upload_day
|
upload_day
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
The upload day as an integer (no padding).
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The upload day as an integer (no padding).
|
||||||
|
|
||||||
upload_day_of_year
|
upload_day_of_year
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The day of the year, i.e. February 1st returns ``32``
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The day of the year, i.e. February 1st returns ``32``
|
||||||
|
|
||||||
upload_day_of_year_padded
|
upload_day_of_year_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The upload day of year, but padded i.e. February 1st returns "032"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The upload day of year, but padded i.e. February 1st returns "032"
|
||||||
|
|
||||||
upload_day_of_year_reversed
|
upload_day_of_year_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The upload day, but reversed using ``{total_days_in_year} + 1 - {upload_day}``,
|
:type: ``Integer``
|
||||||
i.e. February 2nd would have upload_day_of_year_reversed of ``365 + 1 - 32`` = ``334``
|
:description:
|
||||||
|
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
|
upload_day_of_year_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The reversed upload day of year, but padded i.e. December 31st returns "001"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The reversed upload day of year, but padded i.e. December 31st returns "001"
|
||||||
|
|
||||||
upload_day_padded
|
upload_day_padded
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
The entry's upload day padded to two digits, i.e. the fifth returns "05"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry's upload day padded to two digits, i.e. the fifth returns "05"
|
||||||
|
|
||||||
upload_day_reversed
|
upload_day_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
The upload day, but reversed using ``{total_days_in_month} + 1 - {upload_day}``,
|
:type: ``Integer``
|
||||||
i.e. August 8th would have upload_day_reversed of ``31 + 1 - 8`` = ``24``
|
:description:
|
||||||
|
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
|
upload_day_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The reversed upload day, but padded. i.e. August 30th returns "02".
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The reversed upload day, but padded. i.e. August 30th returns "02".
|
||||||
|
|
||||||
upload_month
|
upload_month
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
The upload month as an integer (no padding).
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The upload month as an integer (no padding).
|
||||||
|
|
||||||
upload_month_padded
|
upload_month_padded
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
The entry's upload month padded to two digits, i.e. March returns "03"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The entry's upload month padded to two digits, i.e. March returns "03"
|
||||||
|
|
||||||
upload_month_reversed
|
upload_month_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
The upload month, but reversed using ``13 - {upload_month}``, i.e. March returns ``10``
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The upload month, but reversed using ``13 - {upload_month}``, i.e. March returns ``10``
|
||||||
|
|
||||||
upload_month_reversed_padded
|
upload_month_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The reversed upload month, but padded. i.e. November returns "02"
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The reversed upload month, but padded. i.e. November returns "02"
|
||||||
|
|
||||||
upload_year
|
upload_year
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
The entry's upload year
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The entry's upload year
|
||||||
|
|
||||||
upload_year_truncated
|
upload_year_truncated
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
The last two digits of the upload year, i.e. 22 in 2022
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The last two digits of the upload year, i.e. 22 in 2022
|
||||||
|
|
||||||
upload_year_truncated_reversed
|
upload_year_truncated_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The upload year truncated, but reversed using ``100 - {upload_year_truncated}``, i.e.
|
:type: ``Integer``
|
||||||
2022 returns ``100 - 22`` = ``78``
|
:description:
|
||||||
|
The upload year truncated, but reversed using ``100 - {upload_year_truncated}``, i.e.
|
||||||
|
2022 returns ``100 - 22`` = ``78``
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -424,29 +607,43 @@ Ytdl-Sub Variables
|
||||||
|
|
||||||
download_index
|
download_index
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
The i'th entry downloaded. NOTE that this is fetched dynamically from the download
|
:type: ``Integer``
|
||||||
archive.
|
:description:
|
||||||
|
The i'th entry downloaded. NOTE that this is fetched dynamically from the download
|
||||||
|
archive.
|
||||||
|
|
||||||
download_index_padded6
|
download_index_padded6
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The download_index padded six digits
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The download_index padded six digits
|
||||||
|
|
||||||
upload_date_index
|
upload_date_index
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
The i'th entry downloaded with this upload date.
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
The i'th entry downloaded with this upload date.
|
||||||
|
|
||||||
upload_date_index_padded
|
upload_date_index_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The upload_date_index padded two digits
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The upload_date_index padded two digits
|
||||||
|
|
||||||
upload_date_index_reversed
|
upload_date_index_reversed
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
100 - upload_date_index
|
:type: ``Integer``
|
||||||
|
:description:
|
||||||
|
100 - upload_date_index
|
||||||
|
|
||||||
upload_date_index_reversed_padded
|
upload_date_index_reversed_padded
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The upload_date_index padded two digits
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The upload_date_index padded two digits
|
||||||
|
|
||||||
ytdl_sub_input_url
|
ytdl_sub_input_url
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
The input URL used in ytdl-sub to create this entry.
|
:type: ``String``
|
||||||
|
:description:
|
||||||
|
The input URL used in ytdl-sub to create this entry.
|
||||||
|
|
|
||||||
|
|
@ -603,7 +603,7 @@ Takes a date in the form of YYYYMMDD and returns a Map containing:
|
||||||
- year (Integer)
|
- year (Integer)
|
||||||
- month (Integer)
|
- month (Integer)
|
||||||
- day (Integer)
|
- day (Integer)
|
||||||
- year_truncated (String, YY from YY[YY])
|
- year_truncated (Integer, YY from YY[YY])
|
||||||
- month_padded (String)
|
- month_padded (String)
|
||||||
- day_padded (String)
|
- day_padded (String)
|
||||||
- year_truncated_reversed (Integer, 100 - year_truncated)
|
- year_truncated_reversed (Integer, 100 - year_truncated)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from ytdl_sub.config.plugin.preset_plugins import PresetPlugins
|
||||||
from ytdl_sub.config.preset_options import OutputOptions
|
from ytdl_sub.config.preset_options import OutputOptions
|
||||||
from ytdl_sub.config.validators.options import OptionsValidator
|
from ytdl_sub.config.validators.options import OptionsValidator
|
||||||
from ytdl_sub.downloaders.url.validators import MultiUrlValidator
|
from ytdl_sub.downloaders.url.validators import MultiUrlValidator
|
||||||
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
|
from ytdl_sub.entries.script.variable_definitions import VARIABLE_SCRIPTS
|
||||||
from ytdl_sub.script.script import Script
|
from ytdl_sub.script.script import Script
|
||||||
from ytdl_sub.validators.string_formatter_validators import validate_formatters
|
from ytdl_sub.validators.string_formatter_validators import validate_formatters
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,9 @@ from ytdl_sub.config.validators.options import OptionsDictValidator
|
||||||
from ytdl_sub.downloaders.source_plugin import SourcePlugin
|
from ytdl_sub.downloaders.source_plugin import SourcePlugin
|
||||||
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
|
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
|
from ytdl_sub.entries.script.variable_definitions import VARIABLE_SCRIPTS
|
||||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
||||||
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
||||||
from ytdl_sub.entries.script.variable_scripts import DOWNLOADER_INJECTED_VARIABLES
|
|
||||||
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
|
|
||||||
from ytdl_sub.utils.exceptions import ValidationException
|
from ytdl_sub.utils.exceptions import ValidationException
|
||||||
from ytdl_sub.utils.file_handler import FileHandler
|
from ytdl_sub.utils.file_handler import FileHandler
|
||||||
from ytdl_sub.utils.file_handler import get_file_extension
|
from ytdl_sub.utils.file_handler import get_file_extension
|
||||||
|
|
@ -114,7 +113,7 @@ class InfoJsonDownloader(SourcePlugin[InfoJsonDownloaderOptions]):
|
||||||
inj.variable_name,
|
inj.variable_name,
|
||||||
VARIABLE_SCRIPTS[inj.variable_name],
|
VARIABLE_SCRIPTS[inj.variable_name],
|
||||||
)
|
)
|
||||||
for inj in DOWNLOADER_INJECTED_VARIABLES
|
for inj in v.injected_variables()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
entries.append(entry)
|
entries.append(entry)
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ from typing import final
|
||||||
|
|
||||||
from ytdl_sub.entries.base_entry import BaseEntry
|
from ytdl_sub.entries.base_entry import BaseEntry
|
||||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
||||||
from ytdl_sub.entries.script.variable_definitions import Variable
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
||||||
|
from ytdl_sub.entries.script.variable_types import ArrayVariable
|
||||||
|
from ytdl_sub.entries.script.variable_types import StringVariable
|
||||||
|
from ytdl_sub.entries.script.variable_types import Variable
|
||||||
from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
|
from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
|
||||||
from ytdl_sub.utils.script import ScriptUtils
|
from ytdl_sub.utils.script import ScriptUtils
|
||||||
from ytdl_sub.utils.scriptable import Scriptable
|
from ytdl_sub.utils.scriptable import Scriptable
|
||||||
|
|
@ -23,8 +25,12 @@ from ytdl_sub.validators.audo_codec_validator import VIDEO_CODEC_EXTS
|
||||||
v: VariableDefinitions = VARIABLES
|
v: VariableDefinitions = VARIABLES
|
||||||
|
|
||||||
_YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY: str = "ytdl_sub_entry_variables"
|
_YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY: str = "ytdl_sub_entry_variables"
|
||||||
ytdl_sub_chapters_from_comments = Variable("ytdl_sub_chapters_from_comments")
|
ytdl_sub_chapters_from_comments = ArrayVariable(
|
||||||
ytdl_sub_split_by_chapters_parent_uid = Variable("ytdl_sub_split_by_chapters_parent_uid")
|
"ytdl_sub_chapters_from_comments", definition="{ [] }"
|
||||||
|
)
|
||||||
|
ytdl_sub_split_by_chapters_parent_uid = StringVariable(
|
||||||
|
"ytdl_sub_split_by_chapters_parent_uid", definition="{ %string('') }"
|
||||||
|
)
|
||||||
|
|
||||||
TypeT = TypeVar("TypeT")
|
TypeT = TypeVar("TypeT")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,14 @@ from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
from ytdl_sub.entries.base_entry import BaseEntry
|
from ytdl_sub.entries.base_entry import BaseEntry
|
||||||
from ytdl_sub.entries.base_entry import TBaseEntry
|
from ytdl_sub.entries.base_entry import TBaseEntry
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
||||||
from ytdl_sub.entries.script.variable_definitions import MetadataVariable
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
||||||
from ytdl_sub.entries.script.variable_scripts import ENTRY_DEFAULT_VARIABLES
|
from ytdl_sub.entries.script.variable_types import MetadataVariable
|
||||||
from ytdl_sub.entries.script.variable_scripts import ENTRY_REQUIRED_VARIABLES
|
|
||||||
|
|
||||||
v: VariableDefinitions = VARIABLES
|
v: VariableDefinitions = VARIABLES
|
||||||
|
|
||||||
|
|
@ -53,8 +52,8 @@ class EntryParent(BaseEntry):
|
||||||
|
|
||||||
def _sibling_entry_metadata(self) -> List[Dict[str, Any]]:
|
def _sibling_entry_metadata(self) -> List[Dict[str, Any]]:
|
||||||
sibling_entry_metadata: List[Dict[str, Any]] = []
|
sibling_entry_metadata: List[Dict[str, Any]] = []
|
||||||
variable_filter: List[MetadataVariable] = list(ENTRY_REQUIRED_VARIABLES.keys()) + list(
|
variable_filter: Set[MetadataVariable] = (
|
||||||
ENTRY_DEFAULT_VARIABLES.keys()
|
v.required_entry_variables() | v.default_entry_variables()
|
||||||
)
|
)
|
||||||
for entry in self.entry_children():
|
for entry in self.entry_children():
|
||||||
sibling_entry_metadata.append(
|
sibling_entry_metadata.append(
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ class CustomFunctions:
|
||||||
- year (Integer)
|
- year (Integer)
|
||||||
- month (Integer)
|
- month (Integer)
|
||||||
- day (Integer)
|
- day (Integer)
|
||||||
- year_truncated (String, YY from YY[YY])
|
- year_truncated (Integer, YY from YY[YY])
|
||||||
- month_padded (String)
|
- month_padded (String)
|
||||||
- day_padded (String)
|
- day_padded (String)
|
||||||
- year_truncated_reversed (Integer, 100 - year_truncated)
|
- year_truncated_reversed (Integer, 100 - year_truncated)
|
||||||
|
|
@ -149,7 +149,7 @@ class CustomFunctions:
|
||||||
String("year"): Integer(year),
|
String("year"): Integer(year),
|
||||||
String("month"): Integer(month),
|
String("month"): Integer(month),
|
||||||
String("day"): Integer(day),
|
String("day"): Integer(day),
|
||||||
String("year_truncated"): String(year_truncated),
|
String("year_truncated"): Integer(year_truncated),
|
||||||
String("month_padded"): String(month_padded),
|
String("month_padded"): String(month_padded),
|
||||||
String("day_padded"): String(day_padded),
|
String("day_padded"): String(day_padded),
|
||||||
String("year_truncated_reversed"): Integer(100 - year_truncated),
|
String("year_truncated_reversed"): Integer(100 - year_truncated),
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,296 +0,0 @@
|
||||||
from typing import Dict
|
|
||||||
from typing import List
|
|
||||||
from typing import Optional
|
|
||||||
from typing import Set
|
|
||||||
|
|
||||||
import mergedeep
|
|
||||||
|
|
||||||
from ytdl_sub.entries.script.custom_functions import CustomFunctions
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import Metadata
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import MetadataVariable
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import Variable
|
|
||||||
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# Helpers
|
|
||||||
|
|
||||||
v: VariableDefinitions = VARIABLES
|
|
||||||
|
|
||||||
|
|
||||||
def _pad_int(key: Variable, pad: int) -> str:
|
|
||||||
return f"{{%pad_zero({key.variable_name}, {pad})}}"
|
|
||||||
|
|
||||||
|
|
||||||
def _sanitized_plex(key: Variable) -> str:
|
|
||||||
return f"{{%sanitize_plex_episode({key.variable_name})}}"
|
|
||||||
|
|
||||||
|
|
||||||
def _date_metadata(date_key: Variable, metadata_key: str) -> str:
|
|
||||||
return f"{{%map_get(%to_date_metadata({date_key.variable_name}), '{metadata_key}')}}"
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# Metadata Getters
|
|
||||||
|
|
||||||
|
|
||||||
def _get(
|
|
||||||
cast: str,
|
|
||||||
metadata: Metadata,
|
|
||||||
key: MetadataVariable,
|
|
||||||
default: Optional[Variable | str | int | Dict | List],
|
|
||||||
) -> str:
|
|
||||||
if default is None:
|
|
||||||
# TODO: assert with good error message if key DNE
|
|
||||||
out = f"%map_get({metadata.variable_name}, '{key.metadata_key}')"
|
|
||||||
elif isinstance(default, Variable):
|
|
||||||
args = f"{metadata.variable_name}, '{key.metadata_key}', {default.variable_name}"
|
|
||||||
out = f"%map_get_non_empty({args})"
|
|
||||||
elif isinstance(default, str):
|
|
||||||
out = f"%map_get_non_empty({metadata.variable_name}, '{key.metadata_key}', '{default}')"
|
|
||||||
elif isinstance(default, dict):
|
|
||||||
out = f"%map_get_non_empty({metadata.variable_name}, '{key.metadata_key}', {{}})"
|
|
||||||
elif isinstance(default, list):
|
|
||||||
out = f"%map_get_non_empty({metadata.variable_name}, '{key.metadata_key}', [])"
|
|
||||||
else:
|
|
||||||
out = f"%map_get_non_empty({metadata.variable_name}, '{key.metadata_key}', {default})"
|
|
||||||
|
|
||||||
return f"{{ %legacy_bracket_safety(%{cast}({out})) }}"
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# Entry Getters
|
|
||||||
|
|
||||||
|
|
||||||
def _entry_get_str(key: MetadataVariable, default: Optional[Variable | str] = None) -> str:
|
|
||||||
return _get("string", metadata=v.entry_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
def _entry_get_int(key: MetadataVariable, default: Optional[Variable | int] = None) -> str:
|
|
||||||
return _get("int", metadata=v.entry_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
def _entry_get_map(key: MetadataVariable, default: Optional[Variable | Dict] = None):
|
|
||||||
return _get("map", metadata=v.entry_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
def _entry_get_array(key: MetadataVariable, default: Optional[Variable | List] = None):
|
|
||||||
return _get("array", metadata=v.entry_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# Playlist Getters
|
|
||||||
|
|
||||||
|
|
||||||
def _playlist_get_str(key: MetadataVariable, default: Optional[Variable | str] = None) -> str:
|
|
||||||
return _get("string", metadata=v.playlist_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
def _playlist_get_int(key: MetadataVariable, default: Optional[Variable | int] = None) -> str:
|
|
||||||
return _get("int", metadata=v.playlist_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# Source Getters
|
|
||||||
|
|
||||||
|
|
||||||
def _source_get_str(key: MetadataVariable, default: Optional[Variable | str] = None) -> str:
|
|
||||||
return _get("string", metadata=v.source_metadata, key=key, default=default)
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# Scripts
|
|
||||||
|
|
||||||
ENTRY_EMPTY_METADATA: Dict[Variable, str] = {v.entry_metadata: "{ {} }"}
|
|
||||||
|
|
||||||
ENTRY_HARDCODED_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.info_json_ext: "info.json",
|
|
||||||
v.thumbnail_ext: "jpg",
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY_RELATIVE_VARIABLES: Dict[MetadataVariable, str] = {
|
|
||||||
v.playlist_metadata: _entry_get_map(v.playlist_metadata, {}),
|
|
||||||
v.source_metadata: _entry_get_map(v.source_metadata, {}),
|
|
||||||
v.sibling_metadata: _entry_get_array(v.sibling_metadata, []),
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY_REQUIRED_VARIABLES: Dict[MetadataVariable, str] = {
|
|
||||||
v.uid: _entry_get_str(v.uid),
|
|
||||||
v.extractor_key: _entry_get_str(v.extractor_key),
|
|
||||||
v.epoch: _entry_get_int(v.epoch),
|
|
||||||
v.webpage_url: _entry_get_str(v.webpage_url),
|
|
||||||
v.ext: _entry_get_str(v.ext),
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY_DEFAULT_VARIABLES: Dict[MetadataVariable, str] = {
|
|
||||||
v.title: _entry_get_str(v.title, v.uid),
|
|
||||||
v.extractor: _entry_get_str(v.extractor, v.extractor_key),
|
|
||||||
v.description: _entry_get_str(v.description, ""),
|
|
||||||
v.ie_key: _entry_get_str(v.ie_key, v.extractor_key),
|
|
||||||
v.uploader_id: _entry_get_str(v.uploader_id, v.uid),
|
|
||||||
v.uploader: _entry_get_str(v.uploader, v.uploader_id),
|
|
||||||
v.uploader_url: _entry_get_str(v.uploader_url, v.webpage_url),
|
|
||||||
v.upload_date: _entry_get_str(v.upload_date, v.epoch_date),
|
|
||||||
v.release_date: _entry_get_str(v.release_date, v.upload_date),
|
|
||||||
v.channel: _entry_get_str(v.channel, v.uploader),
|
|
||||||
v.creator: _entry_get_str(v.creator, v.channel),
|
|
||||||
v.channel_id: _entry_get_str(v.channel_id, v.uploader_id),
|
|
||||||
v.duration: _entry_get_int(v.duration, 0),
|
|
||||||
v.playlist_index: _entry_get_int(v.playlist_index, 1),
|
|
||||||
v.playlist_count: _entry_get_int(v.playlist_count, 1),
|
|
||||||
v.playlist_uid: _entry_get_str(v.playlist_uid, v.uid),
|
|
||||||
v.playlist_title: _entry_get_str(v.playlist_title, v.title),
|
|
||||||
v.playlist_uploader_id: _entry_get_str(v.playlist_uploader_id, v.uploader_id),
|
|
||||||
}
|
|
||||||
|
|
||||||
# MARK AS UNRESOLVABLE UNTIL THEY ARE ADDED IN THE DOWNLOADER
|
|
||||||
DOWNLOADER_INJECTED_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.download_index: "{%int(1)}",
|
|
||||||
v.upload_date_index: "{%int(1)}",
|
|
||||||
v.comments: "{ [] }",
|
|
||||||
v.requested_subtitles: "{ {} }",
|
|
||||||
v.chapters: "{ [] }",
|
|
||||||
v.sponsorblock_chapters: "{ [] }",
|
|
||||||
v.ytdl_sub_input_url: f"{{{v.source_webpage_url.variable_name}}}",
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY_DERIVED_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.uid_sanitized_plex: _sanitized_plex(v.uid),
|
|
||||||
v.title_sanitized_plex: _sanitized_plex(v.title),
|
|
||||||
v.epoch_date: f"{{%datetime_strftime({v.epoch.variable_name}, '%Y%m%d')}}",
|
|
||||||
v.epoch_hour: f"{{%datetime_strftime({v.epoch.variable_name}, '%H')}}",
|
|
||||||
v.download_index_padded6: _pad_int(v.download_index, 6),
|
|
||||||
v.upload_date_index_padded: _pad_int(v.upload_date_index, 2),
|
|
||||||
v.upload_date_index_reversed: f"{{%sub(100, {v.upload_date_index.variable_name})}}",
|
|
||||||
v.upload_date_index_reversed_padded: _pad_int(v.upload_date_index_reversed, 2),
|
|
||||||
v.playlist_index_reversed: (
|
|
||||||
f"{{%sub({v.playlist_count.variable_name}, {v.playlist_index.variable_name}, -1)}}"
|
|
||||||
),
|
|
||||||
v.playlist_index_padded: _pad_int(v.playlist_index, 2),
|
|
||||||
v.playlist_index_reversed_padded: _pad_int(v.playlist_index_reversed, 2),
|
|
||||||
v.playlist_index_padded6: _pad_int(v.playlist_index, 6),
|
|
||||||
v.playlist_index_reversed_padded6: _pad_int(v.playlist_index_reversed, 6),
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY_UPLOAD_DATE_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.upload_year: _date_metadata(v.upload_date, "year"),
|
|
||||||
v.upload_year_truncated: _date_metadata(v.upload_date, "year_truncated"),
|
|
||||||
v.upload_year_truncated_reversed: _date_metadata(v.upload_date, "year_truncated_reversed"),
|
|
||||||
v.upload_month_reversed: _date_metadata(v.upload_date, "month_reversed"),
|
|
||||||
v.upload_month_reversed_padded: _date_metadata(v.upload_date, "month_reversed_padded"),
|
|
||||||
v.upload_month_padded: _date_metadata(v.upload_date, "month_padded"),
|
|
||||||
v.upload_day_padded: _date_metadata(v.upload_date, "day_padded"),
|
|
||||||
v.upload_month: _date_metadata(v.upload_date, "month"),
|
|
||||||
v.upload_day: _date_metadata(v.upload_date, "day"),
|
|
||||||
v.upload_day_reversed: _date_metadata(v.upload_date, "day_reversed"),
|
|
||||||
v.upload_day_reversed_padded: _date_metadata(v.upload_date, "day_reversed_padded"),
|
|
||||||
v.upload_day_of_year: _date_metadata(v.upload_date, "day_of_year"),
|
|
||||||
v.upload_day_of_year_padded: _date_metadata(v.upload_date, "day_of_year_padded"),
|
|
||||||
v.upload_day_of_year_reversed: _date_metadata(v.upload_date, "day_of_year_reversed"),
|
|
||||||
v.upload_day_of_year_reversed_padded: _date_metadata(
|
|
||||||
v.upload_date, "day_of_year_reversed_padded"
|
|
||||||
),
|
|
||||||
v.upload_date_standardized: _date_metadata(v.upload_date, "date_standardized"),
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY_RELEASE_DATE_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.release_year: _date_metadata(v.release_date, "year"),
|
|
||||||
v.release_year_truncated: _date_metadata(v.release_date, "year_truncated"),
|
|
||||||
v.release_year_truncated_reversed: _date_metadata(v.release_date, "year_truncated_reversed"),
|
|
||||||
v.release_month_reversed: _date_metadata(v.release_date, "month_reversed"),
|
|
||||||
v.release_month_reversed_padded: _date_metadata(v.release_date, "month_reversed_padded"),
|
|
||||||
v.release_month_padded: _date_metadata(v.release_date, "month_padded"),
|
|
||||||
v.release_day_padded: _date_metadata(v.release_date, "day_padded"),
|
|
||||||
v.release_month: _date_metadata(v.release_date, "month"),
|
|
||||||
v.release_day: _date_metadata(v.release_date, "day"),
|
|
||||||
v.release_day_reversed: _date_metadata(v.release_date, "day_reversed"),
|
|
||||||
v.release_day_reversed_padded: _date_metadata(v.release_date, "day_reversed_padded"),
|
|
||||||
v.release_day_of_year: _date_metadata(v.release_date, "day_of_year"),
|
|
||||||
v.release_day_of_year_padded: _date_metadata(v.release_date, "day_of_year_padded"),
|
|
||||||
v.release_day_of_year_reversed: _date_metadata(v.release_date, "day_of_year_reversed"),
|
|
||||||
v.release_day_of_year_reversed_padded: _date_metadata(
|
|
||||||
v.release_date, "day_of_year_reversed_padded"
|
|
||||||
),
|
|
||||||
v.release_date_standardized: _date_metadata(v.release_date, "date_standardized"),
|
|
||||||
}
|
|
||||||
|
|
||||||
PLAYLIST_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.playlist_webpage_url: _playlist_get_str(v.playlist_webpage_url, v.webpage_url),
|
|
||||||
v.playlist_description: _playlist_get_str(v.playlist_description, v.description),
|
|
||||||
v.playlist_uploader: _playlist_get_str(v.playlist_uploader, v.uploader),
|
|
||||||
v.playlist_uploader_url: _playlist_get_str(v.playlist_uploader_url, v.playlist_webpage_url),
|
|
||||||
v.source_index: _playlist_get_int(v.source_index, 1),
|
|
||||||
v.source_count: _playlist_get_int(v.source_count, 1),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SOURCE_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.source_uid: _source_get_str(v.source_uid, v.playlist_uid),
|
|
||||||
v.source_title: _source_get_str(v.source_title, v.playlist_title),
|
|
||||||
v.source_webpage_url: _source_get_str(v.source_webpage_url, v.playlist_webpage_url),
|
|
||||||
v.source_description: _source_get_str(v.source_description, v.playlist_description),
|
|
||||||
v.source_uploader_id: _source_get_str(v.source_uploader_id, v.playlist_uploader_id),
|
|
||||||
v.source_uploader: _source_get_str(v.source_uploader, v.playlist_uploader),
|
|
||||||
v.source_uploader_url: _source_get_str(v.source_uploader_url, v.source_webpage_url),
|
|
||||||
}
|
|
||||||
|
|
||||||
SOURCE_DERIVED_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.source_index_padded: _pad_int(v.source_index, 2),
|
|
||||||
}
|
|
||||||
|
|
||||||
SIBLING_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.playlist_max_upload_date: f"""{{
|
|
||||||
%array_reduce(
|
|
||||||
%if_passthrough(
|
|
||||||
%extract_field_from_siblings('{v.upload_date.variable_name}'),
|
|
||||||
[{v.upload_date.variable_name}]
|
|
||||||
),
|
|
||||||
%max
|
|
||||||
)
|
|
||||||
}}"""
|
|
||||||
}
|
|
||||||
|
|
||||||
SIBLING_DERIVED_VARIABLES: Dict[Variable, str] = {
|
|
||||||
v.playlist_max_upload_year: _date_metadata(v.playlist_max_upload_date, "year"),
|
|
||||||
v.playlist_max_upload_year_truncated: _date_metadata(
|
|
||||||
v.playlist_max_upload_date, "year_truncated"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
_VARIABLE_SCRIPTS: Dict[Variable, str] = {}
|
|
||||||
mergedeep.merge(
|
|
||||||
_VARIABLE_SCRIPTS,
|
|
||||||
ENTRY_EMPTY_METADATA,
|
|
||||||
ENTRY_HARDCODED_VARIABLES,
|
|
||||||
ENTRY_RELATIVE_VARIABLES,
|
|
||||||
ENTRY_REQUIRED_VARIABLES,
|
|
||||||
ENTRY_DEFAULT_VARIABLES,
|
|
||||||
DOWNLOADER_INJECTED_VARIABLES,
|
|
||||||
ENTRY_DERIVED_VARIABLES,
|
|
||||||
ENTRY_UPLOAD_DATE_VARIABLES,
|
|
||||||
ENTRY_RELEASE_DATE_VARIABLES,
|
|
||||||
SIBLING_VARIABLES,
|
|
||||||
SIBLING_DERIVED_VARIABLES,
|
|
||||||
PLAYLIST_VARIABLES,
|
|
||||||
SOURCE_VARIABLES,
|
|
||||||
SOURCE_DERIVED_VARIABLES,
|
|
||||||
)
|
|
||||||
|
|
||||||
VARIABLE_SCRIPTS: Dict[str, str] = {
|
|
||||||
var.variable_name: script for var, script in _VARIABLE_SCRIPTS.items()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _keys(*variables: Dict[Variable, str]) -> Set[str]:
|
|
||||||
keys: Set[str] = set()
|
|
||||||
for variable_set in variables:
|
|
||||||
keys.update(set(var.variable_name for var in variable_set.keys()))
|
|
||||||
return keys
|
|
||||||
|
|
||||||
|
|
||||||
UNRESOLVED_VARIABLES: Set[str] = _keys(
|
|
||||||
ENTRY_EMPTY_METADATA,
|
|
||||||
DOWNLOADER_INJECTED_VARIABLES,
|
|
||||||
)
|
|
||||||
|
|
||||||
CustomFunctions.register()
|
|
||||||
321
src/ytdl_sub/entries/script/variable_types.py
Normal file
321
src/ytdl_sub/entries/script/variable_types.py
Normal file
|
|
@ -0,0 +1,321 @@
|
||||||
|
from abc import ABC
|
||||||
|
from abc import abstractmethod
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Dict
|
||||||
|
from typing import List
|
||||||
|
from typing import Optional
|
||||||
|
from typing import Type
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from ytdl_sub.script.types.array import Array
|
||||||
|
from ytdl_sub.script.types.map import Map
|
||||||
|
from ytdl_sub.script.types.resolvable import Integer
|
||||||
|
from ytdl_sub.script.types.resolvable import String
|
||||||
|
|
||||||
|
ENTRY_METADATA_VARIABLE_NAME = "entry_metadata"
|
||||||
|
PLAYLIST_METADATA_VARIABLE_NAME = "playlist_metadata"
|
||||||
|
SOURCE_METADATA_VARIABLE_NAME = "source_metadata"
|
||||||
|
|
||||||
|
TMetadataVariable = TypeVar("TMetadataVariable", bound="MetadataVariable")
|
||||||
|
TVariable = TypeVar("TVariable", bound="Variable")
|
||||||
|
|
||||||
|
|
||||||
|
def _get(
|
||||||
|
cast: str,
|
||||||
|
metadata_variable_name: str,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str],
|
||||||
|
default: Optional[TVariable | str | int | Dict | List],
|
||||||
|
as_type: Type[TMetadataVariable],
|
||||||
|
) -> TMetadataVariable:
|
||||||
|
if default is None:
|
||||||
|
# TODO: assert with good error message if key DNE
|
||||||
|
out = f"%map_get({metadata_variable_name}, '{metadata_key}')"
|
||||||
|
elif isinstance(default, Variable):
|
||||||
|
args = f"{metadata_variable_name}, '{metadata_key}', {default.variable_name}"
|
||||||
|
out = f"%map_get_non_empty({args})"
|
||||||
|
elif isinstance(default, str):
|
||||||
|
out = f"%map_get_non_empty({metadata_variable_name}, '{metadata_key}', '{default}')"
|
||||||
|
elif isinstance(default, dict):
|
||||||
|
out = f"%map_get_non_empty({metadata_variable_name}, '{metadata_key}', {{}})"
|
||||||
|
elif isinstance(default, list):
|
||||||
|
out = f"%map_get_non_empty({metadata_variable_name}, '{metadata_key}', [])"
|
||||||
|
else:
|
||||||
|
out = f"%map_get_non_empty({metadata_variable_name}, '{metadata_key}', {default})"
|
||||||
|
|
||||||
|
return as_type(
|
||||||
|
variable_name=variable_name or metadata_key,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
definition=f"{{ %legacy_bracket_safety(%{cast}({out})) }}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Variable(ABC):
|
||||||
|
variable_name: str
|
||||||
|
definition: str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@abstractmethod
|
||||||
|
def human_readable_type(cls) -> str:
|
||||||
|
"""
|
||||||
|
Script type of the variable, for documentation
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class StringVariable(Variable):
|
||||||
|
@classmethod
|
||||||
|
def human_readable_type(cls) -> str:
|
||||||
|
return String.__name__
|
||||||
|
|
||||||
|
def to_sanitized_plex(self, variable_name: str) -> "StringVariable":
|
||||||
|
"""
|
||||||
|
Converts a String variable to be plex sanitized
|
||||||
|
"""
|
||||||
|
return StringVariable(
|
||||||
|
variable_name=variable_name,
|
||||||
|
definition=f"{{%sanitize_plex_episode({self.variable_name})}}",
|
||||||
|
)
|
||||||
|
|
||||||
|
def as_date_variable(self) -> "StringDateVariable":
|
||||||
|
"""
|
||||||
|
Converts a String variable to a date variable (which has metadata helpers)
|
||||||
|
"""
|
||||||
|
return StringDateVariable(
|
||||||
|
variable_name=self.variable_name,
|
||||||
|
definition=self.definition,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class StringDateVariable(StringVariable):
|
||||||
|
def get_string_date_metadata(
|
||||||
|
self, date_metadata_key: str, variable_name: Optional[str] = None
|
||||||
|
) -> StringVariable:
|
||||||
|
"""
|
||||||
|
Gets a string-based date metadata variable
|
||||||
|
"""
|
||||||
|
return StringVariable(
|
||||||
|
variable_name=variable_name or date_metadata_key,
|
||||||
|
definition=f"""{{
|
||||||
|
%string(
|
||||||
|
%map_get(
|
||||||
|
%to_date_metadata({self.variable_name}),
|
||||||
|
'{date_metadata_key}'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}}""",
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_integer_date_metadata(
|
||||||
|
self, date_metadata_key: str, variable_name: str
|
||||||
|
) -> "IntegerVariable":
|
||||||
|
"""
|
||||||
|
Gets an int-based date metadata variable
|
||||||
|
"""
|
||||||
|
return IntegerVariable(
|
||||||
|
variable_name=variable_name,
|
||||||
|
definition=f"""{{
|
||||||
|
%int(
|
||||||
|
%map_get(
|
||||||
|
%to_date_metadata({self.variable_name}),
|
||||||
|
'{date_metadata_key}'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}}""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class IntegerVariable(Variable):
|
||||||
|
@classmethod
|
||||||
|
def human_readable_type(cls) -> str:
|
||||||
|
return Integer.__name__
|
||||||
|
|
||||||
|
def to_padded_int(self, variable_name: str, pad: int) -> StringVariable:
|
||||||
|
"""
|
||||||
|
Pads an integer
|
||||||
|
"""
|
||||||
|
return StringVariable(
|
||||||
|
variable_name=variable_name, definition=f"{{%pad_zero({self.variable_name}, {pad})}}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ArrayVariable(Variable):
|
||||||
|
@classmethod
|
||||||
|
def human_readable_type(cls) -> str:
|
||||||
|
return Array.__name__
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class MapVariable(Variable):
|
||||||
|
@classmethod
|
||||||
|
def human_readable_type(cls) -> str:
|
||||||
|
return Map.__name__
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class MetadataVariable(Variable, ABC):
|
||||||
|
metadata_key: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class MapMetadataVariable(MetadataVariable, MapVariable):
|
||||||
|
@classmethod
|
||||||
|
def from_entry(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional["MapMetadataVariable" | Dict] = None,
|
||||||
|
) -> "MapMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates a map variable from entry metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"map",
|
||||||
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=MapMetadataVariable,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ArrayMetadataVariable(MetadataVariable, ArrayVariable):
|
||||||
|
@classmethod
|
||||||
|
def from_entry(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional["ArrayMetadataVariable" | List] = None,
|
||||||
|
) -> "ArrayMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates an array variable from entry metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"array",
|
||||||
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=ArrayMetadataVariable,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class StringMetadataVariable(MetadataVariable, StringVariable):
|
||||||
|
@classmethod
|
||||||
|
def from_entry(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional[StringVariable | str] = None,
|
||||||
|
) -> "StringMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates a string variable from entry metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"string",
|
||||||
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=StringMetadataVariable,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_playlist(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional[StringVariable | str] = None,
|
||||||
|
) -> "StringMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates a string variable from playlist metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"string",
|
||||||
|
metadata_variable_name=PLAYLIST_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=StringMetadataVariable,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_source(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional[StringVariable | str] = None,
|
||||||
|
) -> "StringMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates a string variable from source metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"string",
|
||||||
|
metadata_variable_name=SOURCE_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=StringMetadataVariable,
|
||||||
|
)
|
||||||
|
|
||||||
|
def as_date_variable(self) -> "StringDateMetadataVariable":
|
||||||
|
"""
|
||||||
|
Converts a String variable to a date variable (which has metadata helpers)
|
||||||
|
"""
|
||||||
|
return StringDateMetadataVariable(
|
||||||
|
metadata_key=self.metadata_key,
|
||||||
|
variable_name=self.variable_name,
|
||||||
|
definition=self.definition,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class StringDateMetadataVariable(StringMetadataVariable, StringDateVariable):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class IntegerMetadataVariable(MetadataVariable, IntegerVariable):
|
||||||
|
@classmethod
|
||||||
|
def from_entry(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional[IntegerVariable | int] = None,
|
||||||
|
) -> "IntegerMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates an int variable from entry metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"int",
|
||||||
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=IntegerMetadataVariable,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_playlist(
|
||||||
|
cls,
|
||||||
|
metadata_key: str,
|
||||||
|
variable_name: Optional[str] = None,
|
||||||
|
default: Optional[IntegerVariable | int] = None,
|
||||||
|
) -> "IntegerMetadataVariable":
|
||||||
|
"""
|
||||||
|
Creates an int variable from playlist metadata
|
||||||
|
"""
|
||||||
|
return _get(
|
||||||
|
"int",
|
||||||
|
metadata_variable_name=PLAYLIST_METADATA_VARIABLE_NAME,
|
||||||
|
metadata_key=metadata_key,
|
||||||
|
variable_name=variable_name,
|
||||||
|
default=default,
|
||||||
|
as_type=IntegerMetadataVariable,
|
||||||
|
)
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
|
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
|
||||||
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
|
from ytdl_sub.entries.script.variable_definitions import VARIABLE_SCRIPTS
|
||||||
from ytdl_sub.script.functions import Functions
|
from ytdl_sub.script.functions import Functions
|
||||||
from ytdl_sub.script.utils.name_validation import is_valid_name
|
from ytdl_sub.script.utils.name_validation import is_valid_name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ from typing import Dict
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
|
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
|
||||||
from ytdl_sub.entries.script.variable_definitions import Variable
|
from ytdl_sub.entries.script.variable_definitions import UNRESOLVED_VARIABLES
|
||||||
from ytdl_sub.entries.script.variable_scripts import UNRESOLVED_VARIABLES
|
from ytdl_sub.entries.script.variable_definitions import VARIABLE_SCRIPTS
|
||||||
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
|
from ytdl_sub.entries.script.variable_types import Variable
|
||||||
from ytdl_sub.script.script import Script
|
from ytdl_sub.script.script import Script
|
||||||
from ytdl_sub.script.utils.exceptions import RuntimeException
|
from ytdl_sub.script.utils.exceptions import RuntimeException
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ from typing import Dict
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
from tools.docgen.docgen import DocGen
|
from tools.docgen.docgen import DocGen
|
||||||
|
from tools.docgen.utils import cached_properties
|
||||||
from tools.docgen.utils import camel_case_to_human
|
from tools.docgen.utils import camel_case_to_human
|
||||||
from tools.docgen.utils import get_function_docs
|
from tools.docgen.utils import get_function_docs
|
||||||
from tools.docgen.utils import line_section
|
from tools.docgen.utils import line_section
|
||||||
from tools.docgen.utils import properties
|
|
||||||
from tools.docgen.utils import section
|
from tools.docgen.utils import section
|
||||||
|
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
||||||
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,10 +38,11 @@ class EntryVariablesDocGen(DocGen):
|
||||||
docs += line_section(section_idx=idx)
|
docs += line_section(section_idx=idx)
|
||||||
docs += section(name, level=1)
|
docs += section(name, level=1)
|
||||||
|
|
||||||
for variable_function_name in properties(parent_objs[name]):
|
for variable_function_name in cached_properties(parent_objs[name]):
|
||||||
docs += get_function_docs(
|
docs += get_function_docs(
|
||||||
function_name=variable_function_name,
|
function_name=variable_function_name,
|
||||||
obj=parent_objs[name],
|
obj=parent_objs[name],
|
||||||
|
pre_docstring=f":type: ``{getattr(VARIABLES, variable_function_name).human_readable_type()}``\n",
|
||||||
level=2,
|
level=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import inspect
|
import inspect
|
||||||
|
from functools import cached_property
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
@ -18,6 +19,10 @@ def properties(obj: Type[Any]) -> List[str]:
|
||||||
return sorted(prop for prop in dir(obj) if isinstance(getattr(obj, prop), property))
|
return sorted(prop for prop in dir(obj) if isinstance(getattr(obj, prop), property))
|
||||||
|
|
||||||
|
|
||||||
|
def cached_properties(obj: Type[Any]) -> List[str]:
|
||||||
|
return sorted(prop for prop in dir(obj) if isinstance(getattr(obj, prop), cached_property))
|
||||||
|
|
||||||
|
|
||||||
def static_methods(obj: Type[Any]) -> List[str]:
|
def static_methods(obj: Type[Any]) -> List[str]:
|
||||||
return sorted(
|
return sorted(
|
||||||
name for name in dir(obj) if isinstance(inspect.getattr_static(obj, name), staticmethod)
|
name for name in dir(obj) if isinstance(inspect.getattr_static(obj, name), staticmethod)
|
||||||
|
|
@ -36,11 +41,16 @@ def camel_case_to_human(string: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def get_function_docs(
|
def get_function_docs(
|
||||||
function_name: str, obj: Any, level: int, display_function_name: Optional[str] = None
|
function_name: str,
|
||||||
|
obj: Any,
|
||||||
|
level: int,
|
||||||
|
display_function_name: Optional[str] = None,
|
||||||
|
pre_docstring: Optional[str] = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
display_function_name = display_function_name if display_function_name else function_name
|
display_function_name = display_function_name if display_function_name else function_name
|
||||||
|
|
||||||
docs = section(display_function_name, level=level)
|
docs = section(display_function_name, level=level)
|
||||||
|
docs += pre_docstring or ""
|
||||||
docs += inspect.cleandoc(getattr(obj, function_name).__doc__)
|
docs += inspect.cleandoc(getattr(obj, function_name).__doc__)
|
||||||
docs += "\n"
|
docs += "\n"
|
||||||
return docs
|
return docs
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue