diff --git a/src/ytdl_sub/entries/script/__init__.py b/src/ytdl_sub/entries/script/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/ytdl_sub/entries/script/function_scripts.py b/src/ytdl_sub/entries/script/function_scripts.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/ytdl_sub/entries/script/function_scripts.py @@ -0,0 +1 @@ + diff --git a/src/ytdl_sub/entries/script/kwargs.py b/src/ytdl_sub/entries/script/kwargs.py new file mode 100644 index 00000000..fe48804d --- /dev/null +++ b/src/ytdl_sub/entries/script/kwargs.py @@ -0,0 +1,82 @@ +from dataclasses import dataclass +from typing import List +from typing import Optional + + +class KwargKeys: + keys: List[str] = [] + backend_keys: List[str] = [] + + +@dataclass(frozen=True) +class KwargKey: + entry_key: str + variable_name: str + + @classmethod + def init(cls, entry_key: str, variable_name: Optional[str] = None) -> "KwargKey": + return cls(entry_key=entry_key, variable_name=variable_name if variable_name else entry_key) + + +def _(entry_key: str, variable_name: Optional[str] = None, backend: bool = False) -> KwargKey: + if backend: + assert entry_key not in KwargKeys.backend_keys + KwargKeys.backend_keys.append(entry_key) + else: + assert entry_key not in KwargKeys.keys + KwargKeys.keys.append(entry_key) + return KwargKey( + entry_key=entry_key, variable_name=variable_name if variable_name is not None else entry_key + ) + + +SOURCE_ENTRY = _("source_entry", backend=True) +SOURCE_INDEX = _("source_index") +SOURCE_COUNT = _("source_count") +SOURCE_TITLE = _("source_title") +SOURCE_UID = _("source_uid") +SOURCE_DESCRIPTION = _("source_description") +SOURCE_WEBPAGE_URL = _("source_webpage_url") +SOURCE_UPLOADER = _("source_uploader") +SOURCE_UPLOADER_ID = _("source_uploader_id") +SOURCE_UPLOADER_URL = _("source_uploader_url") + +PLAYLIST_ENTRY = _("playlist_entry", backend=True) +PLAYLIST_WEBPAGE_URL = _("playlist_webpage_url") +PLAYLIST_INDEX = _("playlist_index") +PLAYLIST_COUNT = _("playlist_count") +PLAYLIST_MAX_UPLOAD_YEAR = _("playlist_max_upload_year") +PLAYLIST_MAX_UPLOAD_YEAR_TRUNCATED = _("playlist_max_upload_year_truncated") +PLAYLIST_TITLE = _("playlist_title") +PLAYLIST_DESCRIPTION = _("playlist_description") +PLAYLIST_UID = _("playlist_uid") +PLAYLIST_UPLOADER = _("playlist_uploader") +PLAYLIST_UPLOADER_ID = _("playlist_uploader_id") +PLAYLIST_UPLOADER_URL = _("playlist_uploader_url") + +COLLECTION_URL = _("collection_url", backend=True) +DOWNLOAD_INDEX = _("download_index", backend=True) +UPLOAD_DATE_INDEX = _("upload_date_index", backend=True) +REQUESTED_SUBTITLES = _("requested_subtitles", backend=True) +CHAPTERS = _("chapters", backend=True) +YTDL_SUB_CUSTOM_CHAPTERS = _("ytdl_sub_custom_chapters", backend=True) +YTDL_SUB_REGEX_SOURCE_VARS = _("ytdl_sub_regex_source_vars", backend=True) +SPONSORBLOCK_CHAPTERS = _("sponsorblock_chapters", backend=True) +SPLIT_BY_CHAPTERS_PARENT_ENTRY = _("split_by_chapters_parent_entry", backend=True) +COMMENTS = _("comments", backend=True) +UID = _(entry_key="id", variable_name="uid") +EXTRACTOR = _("extractor") +IE_KEY = _("ie_key") +EPOCH = _("epoch") +CHANNEL = _("channel") +CHANNEL_ID = _("channel_id") +CREATOR = _("creator") +EXT = _("ext") +TITLE = _("title") +DESCRIPTION = _("description") +WEBPAGE_URL = _("webpage_url") +RELEASE_DATE = _("release_date") +UPLOAD_DATE = _("upload_date") +UPLOADER = _("uploader") +UPLOADER_ID = _("uploader_id") +UPLOADER_URL = _("uploader_url") diff --git a/src/ytdl_sub/entries/script/variable_scripts.py b/src/ytdl_sub/entries/script/variable_scripts.py new file mode 100644 index 00000000..36372562 --- /dev/null +++ b/src/ytdl_sub/entries/script/variable_scripts.py @@ -0,0 +1,161 @@ +from typing import Dict +from typing import Optional + +from ytdl_sub.entries.script.kwargs import KwargKey +from ytdl_sub.entries.script.variables import Variables + +ENTRY_MAP_VARIABLE = "entry" + + +def _entry_get(key: KwargKey, default: Optional[KwargKey | str | int]) -> str: + if default is None: + # TODO: assert with good error message if key DNE + return f"%map_get({ENTRY_MAP_VARIABLE}, '{key.entry_key}')" + if isinstance(default, KwargKey): + return f"%map_get({ENTRY_MAP_VARIABLE}, '{key.entry_key}', {default.variable_name})" + if isinstance(default, str): + return f"%map_get({ENTRY_MAP_VARIABLE}, '{key.entry_key}', '{default}')" + + return f"%map_get({ENTRY_MAP_VARIABLE}, '{key.entry_key}', {default})" + + +def entry_get(key: KwargKey, default: Optional[KwargKey | str | int] = None) -> str: + return f"{{{_entry_get(key=key, default=default)}}}" + + +def entry_get_int(key: KwargKey, default: Optional[KwargKey] = None) -> str: + return f"{{%int({_entry_get(key=key, default=default)}}}" + + +def sanitized(key: KwargKey) -> str: + return f"{{%sanitize({key.variable_name})}}" + + +def sanitized_plex(key: KwargKey) -> str: + return f"""{{ + }}""" + + +# singleton to produce variable keys +v = Variables() + + +ENTRY_HARDCODED_VARIABLES: Dict[KwargKey, str] = { + v.info_json_ext: "info.json", + v.thumbnail_ext: "jpg", +} + +ENTRY_REQUIRED_VARIABLES: Dict[KwargKey, str] = { + v.uid: entry_get(v.uid), + v.ie_key: entry_get(v.ie_key), + v.epoch: entry_get_int(v.epoch), + v.webpage_url: entry_get(v.webpage_url), +} + +ENTRY_DEFAULT_VARIABLES: Dict[KwargKey, str] = { + v.title: entry_get(v.title, v.uid), + v.extractor: entry_get(v.extractor, v.ie_key), + v.description: entry_get(v.description, ""), + v.uploader_id: entry_get(v.uploader_id, v.uid), + v.uploader: entry_get(v.uploader, v.uploader_id), + v.uploader_url: entry_get(v.uploader_url, v.webpage_url), +} + +ENTRY_DERIVED_VARIABLES: Dict[KwargKey, str] = { + # UID_SANITIZED + # UID_SANITIZED_PLEX + # title_sanitized + # title_sanitized_plex + # epoch_date + # epoch_hour + # creator + # creator_sanitized + # channel + # channel_sanitized + # channel_id + # ext +} + +ENTRY_ARCHIVE_VARIABLES: Dict[KwargKey, str] = { + # download_index + # download_index_padded6 + # upload_date_index + # upload_date_index_padded + # upload_date_index_reversed + # upload_date_index_reversed_padded +} + +ENTRY_UPLOAD_DATE_VARIABLES: Dict[KwargKey, str] = { + # upload_date + # upload_year + # upload_year_truncated + # upload_year_truncated_reversed + # upload_month_reversed + # upload_month_reversed_padded + # upload_month_padded + # upload_day_padded + # upload_month + # upload_day + # upload_day_reversed + # upload_day_reversed_padded + # upload_day_of_year + # upload_day_of_year_padded + # upload_day_of_year_reversed + # upload_day_of_year_reversed_padded + # upload_date_standardized +} + +ENTRY_RELEASE_DATE_VARIABLES: Dict[KwargKey, str] = { + # release_date + # release_year + # release_year_truncated + # release_year_truncated_reversed + # release_month_reversed + # release_month_reversed_padded + # release_month_padded + # release_day_padded + # release_month + # release_day + # release_day_reversed + # release_day_reversed_padded + # release_day_of_year + # release_day_of_year_padded + # release_day_of_year_reversed + # release_day_of_year_reversed_padded + # release_date_standardized +} + +ENTRY_SOURCE_VARIABLES: Dict[KwargKey, str] = { + # source_title + # source_title_sanitized + # source_uid + # source_index + # source_index_padded + # source_count + # source_webpage_url + # source_description +} + +ENTRY_PLAYLIST_VARIABLES: Dict[KwargKey, str] = { + # playlist_uid + # playlist_title + # playlist_title_sanitized + # playlist_index + # playlist_index_reversed + # playlist_index_padded + # playlist_index_reversed_padded + # playlist_index_padded6 + # playlist_index_reversed_padded6 + # playlist_count + # playlist_description + # playlist_webpage_url + # playlist_max_upload_year + # playlist_max_upload_year_truncated + # playlist_uploader_id + # playlist_uploader + # playlist_uploader_sanitized + # playlist_uploader_url + # source_uploader_id + # source_uploader + # source_uploader_url +} diff --git a/src/ytdl_sub/entries/script/variables.py b/src/ytdl_sub/entries/script/variables.py new file mode 100644 index 00000000..c3b5151a --- /dev/null +++ b/src/ytdl_sub/entries/script/variables.py @@ -0,0 +1,961 @@ +from ytdl_sub.entries.script.kwargs import KwargKey + +# This file contains mixins to a BaseEntry subclass. Ignore pylint's "no kwargs member" suggestion +# pylint: disable=no-member +# pylint: disable=too-many-public-methods + + +class Variables: + @property + def uid(self) -> KwargKey: + """ + Returns + ------- + str + The entry's unique ID + """ + return KwargKey.init(entry_key="id", variable_name="uid") + + @property + def uid_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The sanitized uid of the entry, which is safe to use for Unix and Windows file names. + """ + return KwargKey.init("uid_sanitized") + + @property + def uid_sanitized_plex(self) -> KwargKey: + """ + Returns + ------- + str + 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. + """ + return KwargKey.init("uid_sanitized_plex") + + @property + def ie_key(self) -> KwargKey: + """ + Returns + ------- + str + The info-extractor key + """ + return KwargKey.init("ie_key") + + @property + def extractor(self) -> KwargKey: + """ + Returns + ------- + str + The ytdl extractor name + """ + return KwargKey.init("extractor") + + @property + def epoch(self) -> KwargKey: + """ + Returns + ------- + int + The unix epoch of when the metadata was scraped by yt-dlp. + """ + return KwargKey.init("epoch") + + @property + def epoch_date(self) -> KwargKey: + """ + Returns + ------- + str + The epoch's date, in YYYYMMDD format. + """ + return KwargKey.init("epoch_date") + + @property + def epoch_hour(self) -> KwargKey: + """ + Returns + ------- + str + The epoch's hour, padded + """ + return KwargKey.init("epoch_hour") + + @property + def title(self) -> KwargKey: + """ + Returns + ------- + str + The title of the entry. If a title does not exist, returns its unique ID. + """ + return KwargKey.init("title") + + @property + def title_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The sanitized title of the entry, which is safe to use for Unix and Windows file names. + """ + return KwargKey.init("title_sanitized") + + @property + def title_sanitized_plex(self) -> KwargKey: + """ + Returns + ------- + str + The sanitized title with additional sanitizing for Plex. Replaces numbers with + fixed-width numbers so Plex does not recognize them as season or episode numbers. + """ + return KwargKey.init("title_sanitized_plex") + + @property + def webpage_url(self) -> KwargKey: + """ + Returns + ------- + str + The url to the webpage. + """ + return KwargKey.init("webpage_url") + + @property + def info_json_ext(self) -> KwargKey: + """ + Returns + ------- + str + The "info.json" extension + """ + return KwargKey.init("info_json_ext") + + @property + def description(self) -> KwargKey: + """ + Returns + ------- + str + The description if it exists. Otherwise, returns an emtpy string. + """ + return KwargKey.init("description") + + @property + def uploader_id(self) -> KwargKey: + """ + Returns + ------- + str + The uploader id if it exists, otherwise return the unique ID. + """ + return KwargKey.init("uploader_id") + + @property + def uploader(self) -> KwargKey: + """ + Returns + ------- + str + The uploader if it exists, otherwise return the uploader ID. + """ + return KwargKey.init("uploader") + + @property + def uploader_url(self) -> KwargKey: + """ + Returns + ------- + str + The uploader url if it exists, otherwise returns the webpage_url. + """ + return KwargKey.init("uploader_url") + + @property + def source_title(self) -> KwargKey: + """ + Returns + ------- + str + Name of the source (i.e. channel with multiple playlists) if it exists, otherwise + returns its playlist_title. + """ + return KwargKey.init("source_title") + + @property + def source_title_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The source title, sanitized + """ + return KwargKey.init("source_title_sanitized") + + @property + def source_uid(self) -> KwargKey: + """ + Returns + ------- + str + The source unique id if it exists, otherwise returns the playlist unique ID. + """ + return KwargKey.init("source_uid") + + @property + def source_index(self) -> KwargKey: + """ + Returns + ------- + int + 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). + """ + return KwargKey.init("source_index") + + @property + def source_index_padded(self) -> KwargKey: + """ + Returns + ------- + int + The source index, padded. + """ + return KwargKey.init("source_index_padded") + + @property + def source_count(self) -> KwargKey: + """ + Returns + ------- + int + The source count if it exists, otherwise returns the playlist count. + """ + return KwargKey.init("source_count") + + @property + def source_webpage_url(self) -> KwargKey: + """ + Returns + ------- + str + The source webpage url if it exists, otherwise returns the playlist webpage url. + """ + return KwargKey.init("source_webpage_url") + + @property + def source_description(self) -> KwargKey: + """ + Returns + ------- + str + The source description if it exists, otherwise returns the playlist description. + """ + return KwargKey.init("source_description") + + @property + def playlist_uid(self) -> KwargKey: + """ + Returns + ------- + str + The playlist unique ID if it exists, otherwise return KwargKey.init("") + """ + return KwargKey.init("playlist_uid") + + @property + def playlist_title(self) -> KwargKey: + """ + Returns + ------- + str + Name of its parent playlist/channel if it exists, otherwise returns its title. + """ + return KwargKey.init("playlist_title") + + @property + def playlist_title_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The playlist name, sanitized + """ + return KwargKey.init("playlist_title_sanitized") + + @property + def playlist_index(self) -> KwargKey: + """ + Returns + ------- + int + 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. + """ + return KwargKey.init("playlist_index") + + @property + def playlist_index_reversed(self) -> KwargKey: + """ + Returns + ------- + int + Playlist index reversed via ``playlist_count - playlist_index + 1`` + """ + return KwargKey.init("playlist_index_reversed") + + @property + def playlist_index_padded(self) -> KwargKey: + """ + Returns + ------- + str + playlist_index padded two digits + """ + return KwargKey.init("playlist_index_padded") + + @property + def playlist_index_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + playlist_index_reversed padded two digits + """ + return KwargKey.init("playlist_index_reversed_padded") + + @property + def playlist_index_padded6(self) -> KwargKey: + """ + Returns + ------- + str + playlist_index padded six digits. + """ + return KwargKey.init("playlist_index_padded6") + + @property + def playlist_index_reversed_padded6(self) -> KwargKey: + """ + Returns + ------- + str + playlist_index_reversed padded six digits. + """ + return KwargKey.init("playlist_index_reversed_padded6") + + @property + def playlist_count(self) -> KwargKey: + """ + Returns + ------- + int + 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. + """ + return KwargKey.init("playlist_count") + + @property + def playlist_description(self) -> KwargKey: + """ + Returns + ------- + str + The playlist description if it exists, otherwise returns the entry's description. + """ + return KwargKey.init("playlist_description") + + @property + def playlist_webpage_url(self) -> KwargKey: + """ + Returns + ------- + str + The playlist webpage url if it exists. Otherwise, returns the entry webpage url. + """ + return KwargKey.init("playlist_webpage_url") + + @property + def playlist_max_upload_year(self) -> KwargKey: + """ + Returns + ------- + int + Max upload_year for all entries in this entry's playlist if it exists, otherwise returns + ``upload_year`` + """ + # override in EntryParent + return KwargKey.init("playlist_max_upload_year") + + @property + def playlist_max_upload_year_truncated(self) -> KwargKey: + """ + Returns + ------- + int + The max playlist truncated upload year for all entries in this entry's playlist if it + exists, otherwise returns ``upload_year_truncated``. + """ + return KwargKey.init("playlist_max_upload_year_truncated") + + @property + def playlist_uploader_id(self) -> KwargKey: + """ + Returns + ------- + str + The playlist uploader id if it exists, otherwise returns the entry uploader ID. + """ + return KwargKey.init("playlist_uploader_id") + + @property + def playlist_uploader(self) -> KwargKey: + """ + Returns + ------- + str + The playlist uploader if it exists, otherwise return KwargKey.init("") + """ + return KwargKey.init("playlist_uploader") + + @property + def playlist_uploader_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The playlist uploader, sanitized. + """ + return KwargKey.init("playlist_uploader_sanitized") + + @property + def playlist_uploader_url(self) -> KwargKey: + """ + Returns + ------- + str + The playlist uploader url if it exists, otherwise returns the playlist webpage_url. + """ + return KwargKey.init("playlist_uploader_url") + + @property + def source_uploader_id(self) -> KwargKey: + """ + Returns + ------- + str + The source uploader id if it exists, otherwise returns the playlist_uploader_id + """ + return KwargKey.init("source_uploader_id") + + @property + def source_uploader(self) -> KwargKey: + """ + Returns + ------- + str + The source uploader if it exists, otherwise return KwargKey.init("") + """ + return KwargKey.init("source_uploader") + + @property + def source_uploader_url(self) -> KwargKey: + """ + Returns + ------- + str + The source uploader url if it exists, otherwise returns the source webpage_url. + """ + return KwargKey.init("source_uploader_url") + + @property + def creator(self) -> KwargKey: + """ + Returns + ------- + str + The creator name if it exists, otherwise returns the channel. + """ + return KwargKey.init("creator") + + @property + def creator_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The creator name, sanitized + """ + return KwargKey.init("creator_sanitized") + + @property + def channel(self) -> KwargKey: + """ + Returns + ------- + str + The channel name if it exists, otherwise returns the uploader. + """ + return KwargKey.init("channel") + + @property + def channel_sanitized(self) -> KwargKey: + """ + Returns + ------- + str + The channel name, sanitized. + """ + return KwargKey.init("channel_sanitized") + + @property + def channel_id(self) -> KwargKey: + """ + Returns + ------- + str + The channel id if it exists, otherwise returns the entry uploader ID. + """ + return KwargKey.init("channel_id") + + @property + def ext(self) -> KwargKey: + """ + Returns + ------- + str + The downloaded entry's file extension + """ + return KwargKey.init("ext") + + @property + def thumbnail_ext(self) -> KwargKey: + """ + Returns + ------- + str + The download entry's thumbnail extension. Will always return KwargKey.init("") + need to support other image types, we always convert to jpg. + """ + return KwargKey.init("thumbnail_ext") + + @property + def download_index(self) -> KwargKey: + """ + Returns + ------- + int + The i'th entry downloaded. NOTE that this is fetched dynamically from the download + archive. + """ + return KwargKey.init("download_index") + + @property + def download_index_padded6(self) -> KwargKey: + """ + Returns + ------- + str + The download_index padded six digits + """ + return KwargKey.init("download_index_padded6") + + @property + def upload_date_index(self) -> KwargKey: + """ + Returns + ------- + int + The i'th entry downloaded with this upload date. + """ + return KwargKey.init("upload_date_index") + + @property + def upload_date_index_padded(self) -> KwargKey: + """ + Returns + ------- + int + The upload_date_index padded two digits + """ + return KwargKey.init("upload_date_index_padded") + + @property + def upload_date_index_reversed(self) -> KwargKey: + """ + Returns + ------- + int + 100 - upload_date_index + """ + return KwargKey.init("upload_date_index_reversed") + + @property + def upload_date_index_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + int + The upload_date_index padded two digits + """ + return KwargKey.init("upload_date_index_reversed_padded") + + @property + def upload_date(self) -> KwargKey: + """ + Returns + ------- + str + The entry's uploaded date, in YYYYMMDD format. If not present, return KwargKey.init("") + """ + return KwargKey.init("upload_date") + + @property + def upload_year(self) -> KwargKey: + """ + Returns + ------- + int + The entry's upload year + """ + return KwargKey.init("upload_year") + + @property + def upload_year_truncated(self) -> KwargKey: + """ + Returns + ------- + int + The last two digits of the upload year, i.e. 22 in 2022 + """ + return KwargKey.init("upload_year_truncated") + + @property + def upload_year_truncated_reversed(self) -> KwargKey: + """ + Returns + ------- + int + The upload year truncated, but reversed using ``100 - {upload_year_truncated}``, i.e. + 2022 returns ``100 - 22`` = ``78`` + """ + return KwargKey.init("upload_year_truncated_reversed") + + @property + def upload_month_reversed(self) -> KwargKey: + """ + Returns + ------- + int + The upload month, but reversed using ``13 - {upload_month}``, i.e. March returns ``10`` + """ + return KwargKey.init("upload_month_reversed") + + @property + def upload_month_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + The reversed upload month, but padded. i.e. November returns "02" + """ + return KwargKey.init("upload_month_reversed_padded") + + @property + def upload_month_padded(self) -> KwargKey: + """ + Returns + ------- + str + The entry's upload month padded to two digits, i.e. March returns "03" + """ + return KwargKey.init("upload_month_padded") + + @property + def upload_day_padded(self) -> KwargKey: + """ + Returns + ------- + str + The entry's upload day padded to two digits, i.e. the fifth returns "05" + """ + return KwargKey.init("upload_day_padded") + + @property + def upload_month(self) -> KwargKey: + """ + Returns + ------- + int + The upload month as an integer (no padding). + """ + return KwargKey.init("upload_month") + + @property + def upload_day(self) -> KwargKey: + """ + Returns + ------- + int + The upload day as an integer (no padding). + """ + return KwargKey.init("upload_day") + + @property + def upload_day_reversed(self) -> KwargKey: + """ + Returns + ------- + int + 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`` + """ + return KwargKey.init("upload_day_reversed") + + @property + def upload_day_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + The reversed upload day, but padded. i.e. August 30th returns "02". + """ + return KwargKey.init("upload_day_reversed_padded") + + @property + def upload_day_of_year(self) -> KwargKey: + """ + Returns + ------- + int + The day of the year, i.e. February 1st returns ``32`` + """ + return KwargKey.init("upload_day_of_year") + + @property + def upload_day_of_year_padded(self) -> KwargKey: + """ + Returns + ------- + str + The upload day of year, but padded i.e. February 1st returns "032" + """ + return KwargKey.init("upload_day_of_year_padded") + + @property + def upload_day_of_year_reversed(self) -> KwargKey: + """ + Returns + ------- + int + 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`` + """ + return KwargKey.init("upload_day_of_year_reversed") + + @property + def upload_day_of_year_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + The reversed upload day of year, but padded i.e. December 31st returns "001" + """ + return KwargKey.init("upload_day_of_year_reversed_padded") + + @property + def upload_date_standardized(self) -> KwargKey: + """ + Returns + ------- + str + The uploaded date formatted as YYYY-MM-DD + """ + return KwargKey.init("upload_date_standardized") + + @property + def release_date(self) -> KwargKey: + """ + Returns + ------- + str + The entry's release date, in YYYYMMDD format. If not present, return KwargKey.init("") + """ + return KwargKey.init("release_date") + + @property + def release_year(self) -> KwargKey: + """ + Returns + ------- + int + The entry's release year + """ + return KwargKey.init("release_year") + + @property + def release_year_truncated(self) -> KwargKey: + """ + Returns + ------- + int + The last two digits of the release year, i.e. 22 in 2022 + """ + return KwargKey.init("release_year_truncated") + + @property + def release_year_truncated_reversed(self) -> KwargKey: + """ + Returns + ------- + int + The release year truncated, but reversed using ``100 - {release_year_truncated}``, i.e. + 2022 returns ``100 - 22`` = ``78`` + """ + return KwargKey.init("release_year_truncated_reversed") + + @property + def release_month_reversed(self) -> KwargKey: + """ + Returns + ------- + int + The release month, but reversed + using ``13 - {release_month}``, i.e. March returns ``10`` + """ + return KwargKey.init("release_month_reversed") + + @property + def release_month_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + The reversed release month, but padded. i.e. November returns "02" + """ + return KwargKey.init("release_month_reversed_padded") + + @property + def release_month_padded(self) -> KwargKey: + """ + Returns + ------- + str + The entry's release month padded to two digits, i.e. March returns "03" + """ + return KwargKey.init("release_month_padded") + + @property + def release_day_padded(self) -> KwargKey: + """ + Returns + ------- + str + The entry's release day padded to two digits, i.e. the fifth returns "05" + """ + return KwargKey.init("release_day_padded") + + @property + def release_month(self) -> KwargKey: + """ + Returns + ------- + int + The release month as an integer (no padding). + """ + return KwargKey.init("release_month") + + @property + def release_day(self) -> KwargKey: + """ + Returns + ------- + int + The release day as an integer (no padding). + """ + return KwargKey.init("release_day") + + @property + def release_day_reversed(self) -> KwargKey: + """ + Returns + ------- + int + 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`` + """ + return KwargKey.init("release_day_reversed") + + @property + def release_day_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + The reversed release day, but padded. i.e. August 30th returns "02". + """ + return KwargKey.init("release_day_reversed_padded") + + @property + def release_day_of_year(self) -> KwargKey: + """ + Returns + ------- + int + The day of the year, i.e. February 1st returns ``32`` + """ + return KwargKey.init("release_day_of_year") + + @property + def release_day_of_year_padded(self) -> KwargKey: + """ + Returns + ------- + str + The release day of year, but padded i.e. February 1st returns "032" + """ + return KwargKey.init("release_day_of_year_padded") + + @property + def release_day_of_year_reversed(self) -> KwargKey: + """ + Returns + ------- + int + 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`` + """ + return KwargKey.init("release_day_of_year_reversed") + + @property + def release_day_of_year_reversed_padded(self) -> KwargKey: + """ + Returns + ------- + str + The reversed release day of year, but padded i.e. December 31st returns "001" + """ + return KwargKey.init("release_day_of_year_reversed_padded") + + @property + def release_date_standardized(self) -> KwargKey: + """ + Returns + ------- + str + The release date formatted as YYYY-MM-DD + """ + return KwargKey.init("release_date_standardized")