ytdl-sub 2025.12.31.post1__tar.gz → 2026.1.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/PKG-INFO +2 -2
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/pyproject.toml +1 -1
- ytdl_sub-2026.1.11/src/ytdl_sub/__init__.py +1 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/overrides.py +8 -3
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/validators/variable_validation.py +3 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/url/downloader.py +20 -12
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/url/validators.py +14 -1
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/variable_types.py +1 -9
- ytdl_sub-2026.1.11/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +177 -0
- ytdl_sub-2026.1.11/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml +111 -0
- ytdl_sub-2026.1.11/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +1327 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/numeric_functions.py +17 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/script.py +24 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/resolvable.py +8 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/variable_dependency.py +28 -12
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/script.py +17 -1
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/string_formatter_validators.py +14 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/PKG-INFO +2 -2
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/requires.txt +1 -1
- ytdl_sub-2025.12.31.post1/src/ytdl_sub/__init__.py +0 -1
- ytdl_sub-2025.12.31.post1/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +0 -1049
- ytdl_sub-2025.12.31.post1/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml +0 -210
- ytdl_sub-2025.12.31.post1/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +0 -5693
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/LICENSE +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/README.md +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/setup.cfg +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/entrypoint.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/output_summary.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/output_transaction_log.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/cli_to_sub.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/dl.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/main.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/config_file.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/config_validator.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/defaults.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/plugin.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/plugin_mapping.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/plugin_operation.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/preset_plugins.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/preset.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/preset_options.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/validators/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/validators/options.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/info_json/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/info_json/info_json_downloader.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/source_plugin.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/url/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/ytdl_options_builder.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/ytdlp.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/base_entry.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/entry.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/entry_parent.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/custom_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/function_scripts.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/variable_definitions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/variables/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/variables/override_variables.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/main.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/audio_extract.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/chapters.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/date_range.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/embed_thumbnail.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/file_convert.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/filter_exclude.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/filter_include.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/format.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/internal/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/internal/view.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/match_filters.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/music_tags.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/nfo_tags.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/output_directory_nfo_tags.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/split_by_chapters.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/square_thumbnail.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/static_nfo_tags.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/subtitles.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/throttle_protection.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/video_tags.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/download_deletion_options.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/filter_duration.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/filter_keywords.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/players.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/url_bilateral.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/internal/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/internal/view.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/albums_from_chapters.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/albums_from_playlists.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/singles.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/soundcloud.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/music_videos.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_by_date.yaml +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/array_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/boolean_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/conditional_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/date_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/error_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/json_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/map_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/print_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/regex_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/string_functions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/parser.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/script_output.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/array.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/function.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/map.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/syntax_tree.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/variable.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/exception_formatters.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/exceptions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/name_validation.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/type_checking.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/base_subscription.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription_download.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription_validators.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription_ytdl_options.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/thread/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/thread/log_entries_downloaded_listener.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/chapters.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/datetime.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/exceptions.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/ffmpeg.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/file_handler.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/file_lock.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/file_path.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/logger.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/retry.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/scriptable.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/subtitles.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/system.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/thumbnail.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/xml.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/yaml.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/audo_codec_validator.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/file_path_validators.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/nfo_validators.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/regex_validator.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/source_variable_validator.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/strict_dict_validator.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/string_datetime.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/string_select_validator.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/validators.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/ytdl_additions/__init__.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/ytdl_additions/enhanced_download_archive.py +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/SOURCES.txt +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/dependency_links.txt +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/entry_points.txt +0 -0
- {ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ytdl-sub
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2026.1.11
|
|
4
4
|
Summary: Automate downloading metadata generation with YoutubeDL
|
|
5
5
|
Author: Jesse Bannon
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -703,7 +703,7 @@ Requires-Dist: black==24.10.0; extra == "lint"
|
|
|
703
703
|
Requires-Dist: isort==7.0.0; extra == "lint"
|
|
704
704
|
Requires-Dist: pylint==4.0.1; extra == "lint"
|
|
705
705
|
Provides-Extra: docs
|
|
706
|
-
Requires-Dist: sphinx<
|
|
706
|
+
Requires-Dist: sphinx<10,>=7; extra == "docs"
|
|
707
707
|
Requires-Dist: sphinx-rtd-theme<4,>=2; extra == "docs"
|
|
708
708
|
Requires-Dist: sphinx-book-theme~=1.0; extra == "docs"
|
|
709
709
|
Requires-Dist: sphinx-copybutton~=0.5; extra == "docs"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__pypi_version__ = "2026.01.11";__local_version__ = "2026.01.11+41a5bf6"
|
|
@@ -238,20 +238,25 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
|
|
238
238
|
def apply_overrides_formatter_to_native(
|
|
239
239
|
self,
|
|
240
240
|
formatter: OverridesStringFormatterValidator,
|
|
241
|
+
function_overrides: Optional[Dict[str, str]] = None,
|
|
241
242
|
) -> Any:
|
|
242
243
|
"""
|
|
243
244
|
Parameters
|
|
244
245
|
----------
|
|
245
246
|
formatter
|
|
246
247
|
Overrides formatter to apply
|
|
248
|
+
function_overrides
|
|
249
|
+
Optional. Explicit values to override the overrides themselves and source variables
|
|
247
250
|
|
|
248
251
|
Returns
|
|
249
252
|
-------
|
|
250
253
|
The native python form of the resolved variable
|
|
251
254
|
"""
|
|
252
|
-
return
|
|
253
|
-
|
|
254
|
-
|
|
255
|
+
return formatter.post_process_native(
|
|
256
|
+
self._apply_to_resolvable(
|
|
257
|
+
formatter=formatter, entry=None, function_overrides=function_overrides
|
|
258
|
+
).native
|
|
259
|
+
)
|
|
255
260
|
|
|
256
261
|
def evaluate_boolean(
|
|
257
262
|
self, formatter: StringFormatterValidator, entry: Optional[Entry] = None
|
|
@@ -84,6 +84,9 @@ class VariableValidation:
|
|
|
84
84
|
)
|
|
85
85
|
resolved_subscription["download"] = []
|
|
86
86
|
for url_output in raw_download_output["download"]:
|
|
87
|
+
if isinstance(url_output["url"], list):
|
|
88
|
+
url_output["url"] = [url for url in url_output["url"] if bool(url)]
|
|
89
|
+
|
|
87
90
|
if url_output["url"]:
|
|
88
91
|
resolved_subscription["download"].append(url_output)
|
|
89
92
|
|
|
@@ -52,12 +52,12 @@ class UrlDownloaderBasePluginExtension(SourcePluginExtension[MultiUrlValidator])
|
|
|
52
52
|
|
|
53
53
|
if 0 <= input_url_idx < len(self.plugin_options.urls.list):
|
|
54
54
|
validator = self.plugin_options.urls.list[input_url_idx]
|
|
55
|
-
if self.overrides.
|
|
55
|
+
if entry_input_url in self.overrides.apply_overrides_formatter_to_native(validator.url):
|
|
56
56
|
return validator
|
|
57
57
|
|
|
58
58
|
# Match the first validator based on the URL, if one exists
|
|
59
59
|
for validator in self.plugin_options.urls.list:
|
|
60
|
-
if self.overrides.
|
|
60
|
+
if entry_input_url in self.overrides.apply_overrides_formatter_to_native(validator.url):
|
|
61
61
|
return validator
|
|
62
62
|
|
|
63
63
|
# Return the first validator if none exist
|
|
@@ -487,19 +487,27 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
|
|
487
487
|
# download the bottom-most urls first since they are top-priority
|
|
488
488
|
for idx, url_validator in reversed(list(enumerate(self.collection.urls.list))):
|
|
489
489
|
# URLs can be empty. If they are, then skip
|
|
490
|
-
if not (
|
|
490
|
+
if not (urls := self.overrides.apply_overrides_formatter_to_native(url_validator.url)):
|
|
491
491
|
continue
|
|
492
492
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
493
|
+
assert isinstance(urls, list)
|
|
494
|
+
|
|
495
|
+
for url in reversed(urls):
|
|
496
|
+
assert isinstance(url, str)
|
|
497
|
+
|
|
498
|
+
if not url:
|
|
499
|
+
continue
|
|
500
|
+
|
|
501
|
+
for entry in self._download_metadata(url=url, validator=url_validator):
|
|
502
|
+
entry.initialize_script(self.overrides).add(
|
|
503
|
+
{
|
|
504
|
+
v.ytdl_sub_input_url: url,
|
|
505
|
+
v.ytdl_sub_input_url_index: idx,
|
|
506
|
+
v.ytdl_sub_input_url_count: len(self.collection.urls.list),
|
|
507
|
+
}
|
|
508
|
+
)
|
|
501
509
|
|
|
502
|
-
|
|
510
|
+
yield entry
|
|
503
511
|
|
|
504
512
|
def download(self, entry: Entry) -> Optional[Entry]:
|
|
505
513
|
"""
|
|
@@ -43,6 +43,19 @@ class UrlThumbnailListValidator(ListValidator[UrlThumbnailValidator]):
|
|
|
43
43
|
_inner_list_type = UrlThumbnailValidator
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
class OverridesOneOrManyUrlValidator(OverridesStringFormatterValidator):
|
|
47
|
+
def post_process_native(self, resolved: Any) -> Any:
|
|
48
|
+
if isinstance(resolved, str):
|
|
49
|
+
return [resolved]
|
|
50
|
+
if isinstance(resolved, list):
|
|
51
|
+
for value in resolved:
|
|
52
|
+
if not isinstance(value, str):
|
|
53
|
+
raise self._validation_exception("Must be a string or an array of strings.")
|
|
54
|
+
return resolved
|
|
55
|
+
|
|
56
|
+
raise self._validation_exception("Must be a string or an array of strings.")
|
|
57
|
+
|
|
58
|
+
|
|
46
59
|
class UrlValidator(StrictDictValidator):
|
|
47
60
|
_required_keys = {"url"}
|
|
48
61
|
_optional_keys = {
|
|
@@ -68,7 +81,7 @@ class UrlValidator(StrictDictValidator):
|
|
|
68
81
|
super().__init__(name, value)
|
|
69
82
|
|
|
70
83
|
# TODO: url validate using yt-dlp IE
|
|
71
|
-
self._url = self._validate_key(key="url", validator=
|
|
84
|
+
self._url = self._validate_key(key="url", validator=OverridesOneOrManyUrlValidator)
|
|
72
85
|
self._variables = self._validate_key_if_present(
|
|
73
86
|
key="variables", validator=DictFormatterValidator, default={}
|
|
74
87
|
)
|
{ytdl_sub-2025.12.31.post1 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/variable_types.py
RENAMED
|
@@ -22,7 +22,6 @@ VariableT = TypeVar("VariableT", bound="Variable")
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def _get(
|
|
25
|
-
cast: str,
|
|
26
25
|
metadata_variable_name: str,
|
|
27
26
|
metadata_key: str,
|
|
28
27
|
variable_name: Optional[str],
|
|
@@ -47,7 +46,7 @@ def _get(
|
|
|
47
46
|
return as_type(
|
|
48
47
|
variable_name=variable_name or metadata_key,
|
|
49
48
|
metadata_key=metadata_key,
|
|
50
|
-
definition=f"{{
|
|
49
|
+
definition=f"{{ {out} }}",
|
|
51
50
|
)
|
|
52
51
|
|
|
53
52
|
|
|
@@ -182,7 +181,6 @@ class MapMetadataVariable(MetadataVariable, MapVariable):
|
|
|
182
181
|
Creates a map variable from entry metadata
|
|
183
182
|
"""
|
|
184
183
|
return _get(
|
|
185
|
-
"map",
|
|
186
184
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
|
187
185
|
metadata_key=metadata_key,
|
|
188
186
|
variable_name=variable_name,
|
|
@@ -204,7 +202,6 @@ class ArrayMetadataVariable(MetadataVariable, ArrayVariable):
|
|
|
204
202
|
Creates an array variable from entry metadata
|
|
205
203
|
"""
|
|
206
204
|
return _get(
|
|
207
|
-
"array",
|
|
208
205
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
|
209
206
|
metadata_key=metadata_key,
|
|
210
207
|
variable_name=variable_name,
|
|
@@ -226,7 +223,6 @@ class StringMetadataVariable(MetadataVariable, StringVariable):
|
|
|
226
223
|
Creates a string variable from entry metadata
|
|
227
224
|
"""
|
|
228
225
|
return _get(
|
|
229
|
-
"string",
|
|
230
226
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
|
231
227
|
metadata_key=metadata_key,
|
|
232
228
|
variable_name=variable_name,
|
|
@@ -245,7 +241,6 @@ class StringMetadataVariable(MetadataVariable, StringVariable):
|
|
|
245
241
|
Creates a string variable from playlist metadata
|
|
246
242
|
"""
|
|
247
243
|
return _get(
|
|
248
|
-
"string",
|
|
249
244
|
metadata_variable_name=PLAYLIST_METADATA_VARIABLE_NAME,
|
|
250
245
|
metadata_key=metadata_key,
|
|
251
246
|
variable_name=variable_name,
|
|
@@ -264,7 +259,6 @@ class StringMetadataVariable(MetadataVariable, StringVariable):
|
|
|
264
259
|
Creates a string variable from source metadata
|
|
265
260
|
"""
|
|
266
261
|
return _get(
|
|
267
|
-
"string",
|
|
268
262
|
metadata_variable_name=SOURCE_METADATA_VARIABLE_NAME,
|
|
269
263
|
metadata_key=metadata_key,
|
|
270
264
|
variable_name=variable_name,
|
|
@@ -301,7 +295,6 @@ class IntegerMetadataVariable(MetadataVariable, IntegerVariable):
|
|
|
301
295
|
Creates an int variable from entry metadata
|
|
302
296
|
"""
|
|
303
297
|
return _get(
|
|
304
|
-
"int",
|
|
305
298
|
metadata_variable_name=ENTRY_METADATA_VARIABLE_NAME,
|
|
306
299
|
metadata_key=metadata_key,
|
|
307
300
|
variable_name=variable_name,
|
|
@@ -320,7 +313,6 @@ class IntegerMetadataVariable(MetadataVariable, IntegerVariable):
|
|
|
320
313
|
Creates an int variable from playlist metadata
|
|
321
314
|
"""
|
|
322
315
|
return _get(
|
|
323
|
-
"int",
|
|
324
316
|
metadata_variable_name=PLAYLIST_METADATA_VARIABLE_NAME,
|
|
325
317
|
metadata_key=metadata_key,
|
|
326
318
|
variable_name=variable_name,
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
presets:
|
|
2
|
+
|
|
3
|
+
##################################################################################
|
|
4
|
+
# Multi urls in the form of
|
|
5
|
+
#
|
|
6
|
+
# "Subscription Name":
|
|
7
|
+
# - "url"
|
|
8
|
+
# - "url2"
|
|
9
|
+
# or
|
|
10
|
+
#
|
|
11
|
+
# "Subscription Name": "url"
|
|
12
|
+
#
|
|
13
|
+
# where the first url tries to grab channel avatar + banner
|
|
14
|
+
#
|
|
15
|
+
_multi_url:
|
|
16
|
+
download:
|
|
17
|
+
- url: "{ %array_at(urls, 0) }"
|
|
18
|
+
playlist_thumbnails:
|
|
19
|
+
- name: "{avatar_uncropped_thumbnail_file_name}"
|
|
20
|
+
uid: "avatar_uncropped"
|
|
21
|
+
- name: "{banner_uncropped_thumbnail_file_name}"
|
|
22
|
+
uid: "banner_uncropped"
|
|
23
|
+
source_thumbnails:
|
|
24
|
+
- name: "{avatar_uncropped_thumbnail_file_name}"
|
|
25
|
+
uid: "avatar_uncropped"
|
|
26
|
+
- name: "{banner_uncropped_thumbnail_file_name}"
|
|
27
|
+
uid: "banner_uncropped"
|
|
28
|
+
include_sibling_metadata: "{include_sibling_metadata}"
|
|
29
|
+
webpage_url: "{modified_webpage_url}"
|
|
30
|
+
|
|
31
|
+
- url: "{ %array_slice(urls, 1) }"
|
|
32
|
+
include_sibling_metadata: "{include_sibling_metadata}"
|
|
33
|
+
webpage_url: "{modified_webpage_url}"
|
|
34
|
+
overrides:
|
|
35
|
+
avatar_uncropped_thumbnail_file_name: ""
|
|
36
|
+
banner_uncropped_thumbnail_file_name: ""
|
|
37
|
+
include_sibling_metadata: False
|
|
38
|
+
modified_webpage_url: "{webpage_url}"
|
|
39
|
+
|
|
40
|
+
subscription_array: >-
|
|
41
|
+
{
|
|
42
|
+
[
|
|
43
|
+
url, url2, url3, url4, url5, url6, url7, url8, url9, url10,
|
|
44
|
+
url11, url12, url13, url14, url15, url16, url17, url18, url19, url20,
|
|
45
|
+
url21, url22, url23, url24, url25, url26, url27, url28, url29, url30,
|
|
46
|
+
url31, url32, url33, url34, url35, url36, url37, url38, url39, url40,
|
|
47
|
+
url41, url42, url43, url44, url45, url46, url47, url48, url49, url50,
|
|
48
|
+
url51, url52, url53, url54, url55, url56, url57, url58, url59, url60,
|
|
49
|
+
url61, url62, url63, url64, url65, url66, url67, url68, url69, url70,
|
|
50
|
+
url71, url72, url73, url74, url75, url76, url77, url78, url79, url80,
|
|
51
|
+
url81, url82, url83, url84, url85, url86, url87, url88, url89, url90,
|
|
52
|
+
url91, url92, url93, url94, url95, url96, url97, url98, url99, url100
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
urls: "{subscription_array}"
|
|
56
|
+
|
|
57
|
+
subscription_value: ""
|
|
58
|
+
url: "{subscription_value}"
|
|
59
|
+
url2: ""
|
|
60
|
+
url3: ""
|
|
61
|
+
url4: ""
|
|
62
|
+
url5: ""
|
|
63
|
+
url6: ""
|
|
64
|
+
url7: ""
|
|
65
|
+
url8: ""
|
|
66
|
+
url9: ""
|
|
67
|
+
url10: ""
|
|
68
|
+
url11: ""
|
|
69
|
+
url12: ""
|
|
70
|
+
url13: ""
|
|
71
|
+
url14: ""
|
|
72
|
+
url15: ""
|
|
73
|
+
url16: ""
|
|
74
|
+
url17: ""
|
|
75
|
+
url18: ""
|
|
76
|
+
url19: ""
|
|
77
|
+
url20: ""
|
|
78
|
+
url21: ""
|
|
79
|
+
url22: ""
|
|
80
|
+
url23: ""
|
|
81
|
+
url24: ""
|
|
82
|
+
url25: ""
|
|
83
|
+
url26: ""
|
|
84
|
+
url27: ""
|
|
85
|
+
url28: ""
|
|
86
|
+
url29: ""
|
|
87
|
+
url30: ""
|
|
88
|
+
url31: ""
|
|
89
|
+
url32: ""
|
|
90
|
+
url33: ""
|
|
91
|
+
url34: ""
|
|
92
|
+
url35: ""
|
|
93
|
+
url36: ""
|
|
94
|
+
url37: ""
|
|
95
|
+
url38: ""
|
|
96
|
+
url39: ""
|
|
97
|
+
url40: ""
|
|
98
|
+
url41: ""
|
|
99
|
+
url42: ""
|
|
100
|
+
url43: ""
|
|
101
|
+
url44: ""
|
|
102
|
+
url45: ""
|
|
103
|
+
url46: ""
|
|
104
|
+
url47: ""
|
|
105
|
+
url48: ""
|
|
106
|
+
url49: ""
|
|
107
|
+
url50: ""
|
|
108
|
+
url51: ""
|
|
109
|
+
url52: ""
|
|
110
|
+
url53: ""
|
|
111
|
+
url54: ""
|
|
112
|
+
url55: ""
|
|
113
|
+
url56: ""
|
|
114
|
+
url57: ""
|
|
115
|
+
url58: ""
|
|
116
|
+
url59: ""
|
|
117
|
+
url60: ""
|
|
118
|
+
url61: ""
|
|
119
|
+
url62: ""
|
|
120
|
+
url63: ""
|
|
121
|
+
url64: ""
|
|
122
|
+
url65: ""
|
|
123
|
+
url66: ""
|
|
124
|
+
url67: ""
|
|
125
|
+
url68: ""
|
|
126
|
+
url69: ""
|
|
127
|
+
url70: ""
|
|
128
|
+
url71: ""
|
|
129
|
+
url72: ""
|
|
130
|
+
url73: ""
|
|
131
|
+
url74: ""
|
|
132
|
+
url75: ""
|
|
133
|
+
url76: ""
|
|
134
|
+
url77: ""
|
|
135
|
+
url78: ""
|
|
136
|
+
url79: ""
|
|
137
|
+
url80: ""
|
|
138
|
+
url81: ""
|
|
139
|
+
url82: ""
|
|
140
|
+
url83: ""
|
|
141
|
+
url84: ""
|
|
142
|
+
url85: ""
|
|
143
|
+
url86: ""
|
|
144
|
+
url87: ""
|
|
145
|
+
url88: ""
|
|
146
|
+
url89: ""
|
|
147
|
+
url90: ""
|
|
148
|
+
url91: ""
|
|
149
|
+
url92: ""
|
|
150
|
+
url93: ""
|
|
151
|
+
url94: ""
|
|
152
|
+
url95: ""
|
|
153
|
+
url96: ""
|
|
154
|
+
url97: ""
|
|
155
|
+
url98: ""
|
|
156
|
+
url99: ""
|
|
157
|
+
url100: ""
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# multi-url with bilateral scraping built into it via
|
|
161
|
+
# inspection of the URL and conditionally adding another
|
|
162
|
+
# ytdl-sub url download with the scraping and download reversed
|
|
163
|
+
_multi_url_bilateral_inner:
|
|
164
|
+
preset:
|
|
165
|
+
- "_url_bilateral_overrides"
|
|
166
|
+
|
|
167
|
+
download:
|
|
168
|
+
- url: "{ %array_apply(urls, %bilateral_url) }"
|
|
169
|
+
download_reverse: False
|
|
170
|
+
ytdl_options:
|
|
171
|
+
playlist_items: "-1:0:-1"
|
|
172
|
+
webpage_url: "{modified_webpage_url}"
|
|
173
|
+
|
|
174
|
+
_multi_url_bilateral:
|
|
175
|
+
preset:
|
|
176
|
+
- "_multi_url_bilateral_inner"
|
|
177
|
+
- "_multi_url"
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
presets:
|
|
2
|
+
# Preset for categorizing URls like so
|
|
3
|
+
#
|
|
4
|
+
# subscription_name:
|
|
5
|
+
# category_1:
|
|
6
|
+
# - https://...1
|
|
7
|
+
# - https://...2
|
|
8
|
+
# category_2:
|
|
9
|
+
# - url: https://...1
|
|
10
|
+
# metadata_field_1: 2011
|
|
11
|
+
# metadata_field_2: 'abc"
|
|
12
|
+
# ...
|
|
13
|
+
#
|
|
14
|
+
# Metadata field of `url` must exist, other ones can be anything.
|
|
15
|
+
# Only supports a single level of nesting.
|
|
16
|
+
_url_categorized:
|
|
17
|
+
preset:
|
|
18
|
+
- "_multi_url_bilateral"
|
|
19
|
+
|
|
20
|
+
overrides:
|
|
21
|
+
# Parameters:
|
|
22
|
+
# $0: url string or map containing url + metadata fields
|
|
23
|
+
# $1: category key
|
|
24
|
+
#
|
|
25
|
+
# Output:
|
|
26
|
+
# Map containing { url: ..., category: ..., metadata_field_1: ... }
|
|
27
|
+
"%flat_array__url_to_map_format": >-
|
|
28
|
+
{
|
|
29
|
+
%elif(
|
|
30
|
+
%is_map($0),
|
|
31
|
+
%map_extend( $0, { "category": $1 } ),
|
|
32
|
+
%is_string($0),
|
|
33
|
+
{ "url": $0, "category": $1 },
|
|
34
|
+
%throw("If using album categories, each URL must be either a string or map with metadata fields")
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Parameters:
|
|
39
|
+
# $0: category key
|
|
40
|
+
# $1: array of URLs in either string or map form
|
|
41
|
+
#
|
|
42
|
+
# Output:
|
|
43
|
+
# Array containing [{ url: ..., category: ... }, ... ]
|
|
44
|
+
"%flat_array__category_to_map_format": >-
|
|
45
|
+
{
|
|
46
|
+
%array_apply_fixed(
|
|
47
|
+
%assert_then(
|
|
48
|
+
%is_array( $1 ),
|
|
49
|
+
$1,
|
|
50
|
+
"If using album categories, each category must map to an array"
|
|
51
|
+
),
|
|
52
|
+
$0,
|
|
53
|
+
%flat_array__url_to_map_format
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# Parameters:
|
|
58
|
+
# $0: map containing fields { url: <url_value>, category: ... }
|
|
59
|
+
#
|
|
60
|
+
# Output:
|
|
61
|
+
# Nested map containing { <url_value>: { url: <url_value>, category: ... } }
|
|
62
|
+
"%flat_array__url_keyed_map_format": >-
|
|
63
|
+
{ { %map_get($0, "url"): $0 } }
|
|
64
|
+
|
|
65
|
+
# Creates an array in the form of [ { url: ..., category: ..., metadata_field_1: ... }, ... ]
|
|
66
|
+
category_url_array: >-
|
|
67
|
+
{ %array_flatten( %map_apply( subscription_map, %flat_array__category_to_map_format ) ) }
|
|
68
|
+
|
|
69
|
+
# Creates a map in the form of { <url value>: { category: ..., metadata_field_1: ... }, ... }
|
|
70
|
+
category_url_map: >-
|
|
71
|
+
{
|
|
72
|
+
%array_reduce(
|
|
73
|
+
%array_apply( category_url_array, %flat_array__url_keyed_map_format ),
|
|
74
|
+
%map_extend
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Parameters:
|
|
79
|
+
# $0: metadata field to fetch for the current url
|
|
80
|
+
# $1: default value
|
|
81
|
+
#
|
|
82
|
+
# Output:
|
|
83
|
+
# Metadata field value if it exists. Otherwise, return default value
|
|
84
|
+
"%get_url_field": >-
|
|
85
|
+
{ %map_get( %map( %map_get( category_url_map, ytdl_sub_input_url, {} ) ), $0, $1 ) }
|
|
86
|
+
|
|
87
|
+
# Parameters:
|
|
88
|
+
# $0: metadata field to fetch for the current url
|
|
89
|
+
#
|
|
90
|
+
# Output:
|
|
91
|
+
# True if field is specified. False otherwise.
|
|
92
|
+
"%contains_url_field": >-
|
|
93
|
+
{ %not( %is_null( %get_url_field( $0, null ) ) ) }
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# Parameters:
|
|
97
|
+
# $0: integer to fetch the i'th url using 1-based indexing
|
|
98
|
+
#
|
|
99
|
+
# Output:
|
|
100
|
+
# i'th url in the category map
|
|
101
|
+
"%get_url_i": >-
|
|
102
|
+
{
|
|
103
|
+
%map_get(
|
|
104
|
+
%map( %array_at( category_url_array, %int( %sub($0, 1) ), {} ) ),
|
|
105
|
+
"url",
|
|
106
|
+
%array_at(subscription_array, %int( %sub($0, 1) ), null)
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
subscription_map: "{ {} }"
|
|
111
|
+
urls: "{ %array_apply(%range(100, 1), %get_url_i) }"
|