ytdl-sub 2026.1.24__tar.gz → 2026.1.24.post1__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.
Files changed (172) hide show
  1. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/PKG-INFO +1 -1
  2. ytdl_sub-2026.1.24.post1/src/ytdl_sub/__init__.py +1 -0
  3. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/overrides.py +37 -16
  4. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/plugin/plugin.py +1 -1
  5. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/preset_options.py +4 -1
  6. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/url/downloader.py +8 -6
  7. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/url/validators.py +1 -2
  8. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/date_range.py +1 -1
  9. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/embed_thumbnail.py +1 -1
  10. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/filter_exclude.py +3 -8
  11. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/filter_include.py +5 -7
  12. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/nfo_tags.py +1 -1
  13. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/square_thumbnail.py +1 -1
  14. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/throttle_protection.py +3 -3
  15. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/string_formatter_validators.py +19 -22
  16. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub.egg-info/PKG-INFO +1 -1
  17. ytdl_sub-2026.1.24/src/ytdl_sub/__init__.py +0 -1
  18. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/LICENSE +0 -0
  19. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/README.md +0 -0
  20. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/pyproject.toml +0 -0
  21. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/setup.cfg +0 -0
  22. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/__init__.py +0 -0
  23. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/entrypoint.py +0 -0
  24. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/output_summary.py +0 -0
  25. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/output_transaction_log.py +0 -0
  26. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/parsers/__init__.py +0 -0
  27. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/parsers/cli_to_sub.py +0 -0
  28. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/parsers/dl.py +0 -0
  29. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/cli/parsers/main.py +0 -0
  30. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/__init__.py +0 -0
  31. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/config_file.py +0 -0
  32. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/config_validator.py +0 -0
  33. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/defaults.py +0 -0
  34. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/plugin/__init__.py +0 -0
  35. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/plugin/plugin_mapping.py +0 -0
  36. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/plugin/plugin_operation.py +0 -0
  37. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/plugin/preset_plugins.py +0 -0
  38. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/preset.py +0 -0
  39. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/validators/__init__.py +0 -0
  40. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/validators/options.py +0 -0
  41. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/config/validators/variable_validation.py +0 -0
  42. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/__init__.py +0 -0
  43. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/info_json/__init__.py +0 -0
  44. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/info_json/info_json_downloader.py +0 -0
  45. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/source_plugin.py +0 -0
  46. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/url/__init__.py +0 -0
  47. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/ytdl_options_builder.py +0 -0
  48. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/downloaders/ytdlp.py +0 -0
  49. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/__init__.py +0 -0
  50. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/base_entry.py +0 -0
  51. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/entry.py +0 -0
  52. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/entry_parent.py +0 -0
  53. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/script/__init__.py +0 -0
  54. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/script/custom_functions.py +0 -0
  55. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/script/function_scripts.py +0 -0
  56. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/script/variable_definitions.py +0 -0
  57. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/script/variable_types.py +0 -0
  58. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/variables/__init__.py +0 -0
  59. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/entries/variables/override_variables.py +0 -0
  60. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/main.py +0 -0
  61. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/__init__.py +0 -0
  62. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/audio_extract.py +0 -0
  63. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/chapters.py +0 -0
  64. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/file_convert.py +0 -0
  65. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/format.py +0 -0
  66. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/internal/__init__.py +0 -0
  67. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/internal/view.py +0 -0
  68. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/match_filters.py +0 -0
  69. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/music_tags.py +0 -0
  70. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/output_directory_nfo_tags.py +0 -0
  71. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/split_by_chapters.py +0 -0
  72. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/static_nfo_tags.py +0 -0
  73. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/subtitles.py +0 -0
  74. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/plugins/video_tags.py +0 -0
  75. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/__init__.py +0 -0
  76. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/__init__.py +0 -0
  77. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/download_deletion_options.yaml +0 -0
  78. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/filter_duration.yaml +0 -0
  79. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/filter_keywords.yaml +0 -0
  80. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml +0 -0
  81. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/players.yaml +0 -0
  82. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml +0 -0
  83. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +0 -0
  84. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/url_bilateral.yaml +0 -0
  85. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml +0 -0
  86. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/internal/__init__.py +0 -0
  87. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/internal/view.yaml +0 -0
  88. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music/__init__.py +0 -0
  89. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music/albums_from_chapters.yaml +0 -0
  90. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music/albums_from_playlists.yaml +0 -0
  91. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music/singles.yaml +0 -0
  92. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music/soundcloud.yaml +0 -0
  93. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py +0 -0
  94. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml +0 -0
  95. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml +0 -0
  96. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/music_videos/music_videos.yaml +0 -0
  97. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/tv_show/__init__.py +0 -0
  98. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml +0 -0
  99. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show.yaml +0 -0
  100. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_by_date.yaml +0 -0
  101. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +0 -0
  102. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/__init__.py +0 -0
  103. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/__init__.py +0 -0
  104. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/array_functions.py +0 -0
  105. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/boolean_functions.py +0 -0
  106. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/conditional_functions.py +0 -0
  107. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/date_functions.py +0 -0
  108. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/error_functions.py +0 -0
  109. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/json_functions.py +0 -0
  110. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/map_functions.py +0 -0
  111. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/numeric_functions.py +0 -0
  112. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/print_functions.py +0 -0
  113. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/regex_functions.py +0 -0
  114. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/functions/string_functions.py +0 -0
  115. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/parser.py +0 -0
  116. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/script.py +0 -0
  117. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/script_output.py +0 -0
  118. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/__init__.py +0 -0
  119. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/array.py +0 -0
  120. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/function.py +0 -0
  121. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/map.py +0 -0
  122. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/resolvable.py +0 -0
  123. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/syntax_tree.py +0 -0
  124. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/variable.py +0 -0
  125. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/types/variable_dependency.py +0 -0
  126. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/utils/__init__.py +0 -0
  127. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/utils/exception_formatters.py +0 -0
  128. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/utils/exceptions.py +0 -0
  129. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/utils/name_validation.py +0 -0
  130. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/script/utils/type_checking.py +0 -0
  131. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/subscriptions/__init__.py +0 -0
  132. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/subscriptions/base_subscription.py +0 -0
  133. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/subscriptions/subscription.py +0 -0
  134. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/subscriptions/subscription_download.py +0 -0
  135. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/subscriptions/subscription_validators.py +0 -0
  136. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/subscriptions/subscription_ytdl_options.py +0 -0
  137. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/thread/__init__.py +0 -0
  138. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/thread/log_entries_downloaded_listener.py +0 -0
  139. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/__init__.py +0 -0
  140. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/chapters.py +0 -0
  141. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/datetime.py +0 -0
  142. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/exceptions.py +0 -0
  143. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/ffmpeg.py +0 -0
  144. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/file_handler.py +0 -0
  145. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/file_lock.py +0 -0
  146. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/file_path.py +0 -0
  147. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/logger.py +0 -0
  148. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/retry.py +0 -0
  149. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/script.py +0 -0
  150. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/scriptable.py +0 -0
  151. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/subtitles.py +0 -0
  152. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/system.py +0 -0
  153. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/thumbnail.py +0 -0
  154. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/xml.py +0 -0
  155. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/utils/yaml.py +0 -0
  156. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/__init__.py +0 -0
  157. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/audo_codec_validator.py +0 -0
  158. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/file_path_validators.py +0 -0
  159. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/nfo_validators.py +0 -0
  160. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/regex_validator.py +0 -0
  161. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/source_variable_validator.py +0 -0
  162. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/strict_dict_validator.py +0 -0
  163. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/string_datetime.py +0 -0
  164. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/string_select_validator.py +0 -0
  165. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/validators/validators.py +0 -0
  166. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/ytdl_additions/__init__.py +0 -0
  167. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub/ytdl_additions/enhanced_download_archive.py +0 -0
  168. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub.egg-info/SOURCES.txt +0 -0
  169. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub.egg-info/dependency_links.txt +0 -0
  170. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub.egg-info/entry_points.txt +0 -0
  171. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/src/ytdl_sub.egg-info/requires.txt +0 -0
  172. {ytdl_sub-2026.1.24 → ytdl_sub-2026.1.24.post1}/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: 2026.1.24
3
+ Version: 2026.1.24.post1
4
4
  Summary: Automate downloading metadata generation with YoutubeDL
5
5
  Author: Jesse Bannon
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -0,0 +1 @@
1
+ __pypi_version__ = "2026.01.24.post1";__local_version__ = "2026.01.24+c1431c8"
@@ -3,8 +3,6 @@ from typing import Dict
3
3
  from typing import Iterable
4
4
  from typing import Optional
5
5
  from typing import Set
6
- from typing import Type
7
- from typing import TypeVar
8
6
 
9
7
  from ytdl_sub.entries.entry import Entry
10
8
  from ytdl_sub.entries.script.variable_definitions import VARIABLES
@@ -22,11 +20,10 @@ from ytdl_sub.utils.exceptions import StringFormattingException
22
20
  from ytdl_sub.utils.exceptions import ValidationException
23
21
  from ytdl_sub.utils.script import ScriptUtils
24
22
  from ytdl_sub.utils.scriptable import Scriptable
23
+ from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
25
24
  from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
26
25
  from ytdl_sub.validators.string_formatter_validators import UnstructuredDictFormatterValidator
27
26
 
28
- ExpectedT = TypeVar("ExpectedT")
29
-
30
27
 
31
28
  class Overrides(UnstructuredDictFormatterValidator, Scriptable):
32
29
  """
@@ -210,8 +207,7 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
210
207
  formatter: StringFormatterValidator,
211
208
  entry: Optional[Entry] = None,
212
209
  function_overrides: Optional[Dict[str, str]] = None,
213
- expected_type: Type[ExpectedT] = str,
214
- ) -> ExpectedT:
210
+ ) -> str:
215
211
  """
216
212
  Parameters
217
213
  ----------
@@ -221,8 +217,6 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
221
217
  Optional. Entry to add source variables to the formatter
222
218
  function_overrides
223
219
  Optional. Explicit values to override the overrides themselves and source variables
224
- expected_type
225
- The expected type that should return. Defaults to string.
226
220
 
227
221
  Returns
228
222
  -------
@@ -233,15 +227,42 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
233
227
  StringFormattingException
234
228
  If the formatter that is trying to be resolved cannot
235
229
  """
236
- out = formatter.post_process(
230
+ return formatter.post_process(
231
+ str(
232
+ self._apply_to_resolvable(
233
+ formatter=formatter, entry=entry, function_overrides=function_overrides
234
+ )
235
+ )
236
+ )
237
+
238
+ def apply_overrides_formatter_to_native(
239
+ self,
240
+ formatter: OverridesStringFormatterValidator,
241
+ function_overrides: Optional[Dict[str, str]] = None,
242
+ ) -> Any:
243
+ """
244
+ Parameters
245
+ ----------
246
+ formatter
247
+ Overrides formatter to apply
248
+ function_overrides
249
+ Optional. Explicit values to override the overrides themselves and source variables
250
+
251
+ Returns
252
+ -------
253
+ The native python form of the resolved variable
254
+ """
255
+ return formatter.post_process_native(
237
256
  self._apply_to_resolvable(
238
- formatter=formatter, entry=entry, function_overrides=function_overrides
257
+ formatter=formatter, entry=None, function_overrides=function_overrides
239
258
  ).native
240
259
  )
241
260
 
242
- if not isinstance(out, expected_type):
243
- raise StringFormattingException(
244
- f"Expected type {expected_type.__name__}, but received '{out.__class__.__name__}'"
245
- )
246
-
247
- return out
261
+ def evaluate_boolean(
262
+ self, formatter: StringFormatterValidator, entry: Optional[Entry] = None
263
+ ) -> bool:
264
+ """
265
+ Apply a formatter, and evaluate it to a boolean
266
+ """
267
+ output = self.apply_formatter(formatter=formatter, entry=entry)
268
+ return ScriptUtils.bool_formatter_output(output)
@@ -48,7 +48,7 @@ class Plugin(BasePlugin[OptionsValidatorT], Generic[OptionsValidatorT], ABC):
48
48
  Returns True if enabled, False if disabled.
49
49
  """
50
50
  if isinstance(self.plugin_options, ToggleableOptionsDictValidator):
51
- return self.overrides.apply_formatter(self.plugin_options.enable, expected_type=bool)
51
+ return self.overrides.evaluate_boolean(self.plugin_options.enable)
52
52
  return True
53
53
 
54
54
  def ytdl_options_match_filters(self) -> Tuple[List[str], List[str]]:
@@ -62,7 +62,10 @@ class YTDLOptions(UnstructuredOverridesDictFormatterValidator):
62
62
  Materializes the entire ytdl-options dict from OverrideStringFormatters into
63
63
  native python.
64
64
  """
65
- out = {key: overrides.apply_formatter(val) for key, val in self.dict.items()}
65
+ out = {
66
+ key: overrides.apply_overrides_formatter_to_native(val)
67
+ for key, val in self.dict.items()
68
+ }
66
69
  if "cookiefile" in out:
67
70
  if not FileHandler.is_file_existent(out["cookiefile"]):
68
71
  raise ValidationException(
@@ -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 entry_input_url in self.overrides.apply_formatter(validator.url, expected_type=list):
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 entry_input_url in self.overrides.apply_formatter(validator.url, expected_type=list):
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
@@ -382,7 +382,7 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
382
382
  entries_to_iter: List[Optional[Entry]] = entries
383
383
 
384
384
  indices = list(range(len(entries_to_iter)))
385
- if self.overrides.apply_formatter(validator.download_reverse, expected_type=bool):
385
+ if self.overrides.evaluate_boolean(validator.download_reverse):
386
386
  indices = reversed(indices)
387
387
 
388
388
  for idx in indices:
@@ -461,8 +461,8 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
461
461
  ytdl_option_overrides=validator.ytdl_options.to_native_dict(self.overrides)
462
462
  )
463
463
 
464
- include_sibling_metadata = self.overrides.apply_formatter(
465
- validator.include_sibling_metadata, expected_type=bool
464
+ include_sibling_metadata = self.overrides.evaluate_boolean(
465
+ validator.include_sibling_metadata
466
466
  )
467
467
 
468
468
  parents, orphan_entries = self._download_url_metadata(
@@ -487,9 +487,11 @@ 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 (urls := self.overrides.apply_formatter(url_validator.url, expected_type=list)):
490
+ if not (urls := self.overrides.apply_overrides_formatter_to_native(url_validator.url)):
491
491
  continue
492
492
 
493
+ assert isinstance(urls, list)
494
+
493
495
  for url in reversed(urls):
494
496
  assert isinstance(url, str)
495
497
 
@@ -1,6 +1,5 @@
1
1
  from typing import Any
2
2
  from typing import Dict
3
- from typing import List
4
3
  from typing import Optional
5
4
  from typing import Set
6
5
 
@@ -45,7 +44,7 @@ class UrlThumbnailListValidator(ListValidator[UrlThumbnailValidator]):
45
44
 
46
45
 
47
46
  class OverridesOneOrManyUrlValidator(OverridesStringFormatterValidator):
48
- def post_process(self, resolved: Any) -> List[str]:
47
+ def post_process_native(self, resolved: Any) -> Any:
49
48
  if isinstance(resolved, str):
50
49
  return [resolved]
51
50
  if isinstance(resolved, list):
@@ -116,7 +116,7 @@ class DateRangePlugin(Plugin[DateRangeOptions]):
116
116
  date_validator=self.plugin_options.after, overrides=self.overrides
117
117
  )
118
118
  after_filter = f"{date_type} >= {after_str}"
119
- if self.overrides.apply_formatter(self.plugin_options.breaks, expected_type=bool):
119
+ if self.overrides.evaluate_boolean(self.plugin_options.breaks):
120
120
  breaking_match_filters.append(after_filter)
121
121
  else:
122
122
  match_filters.append(after_filter)
@@ -33,7 +33,7 @@ class EmbedThumbnailPlugin(Plugin[EmbedThumbnailOptions]):
33
33
 
34
34
  @property
35
35
  def _embed_thumbnail(self) -> bool:
36
- return self.overrides.apply_formatter(self.plugin_options, expected_type=bool)
36
+ return self.overrides.evaluate_boolean(self.plugin_options)
37
37
 
38
38
  @classmethod
39
39
  def _embed_video_thumbnail(cls, entry: Entry) -> None:
@@ -7,14 +7,13 @@ from ytdl_sub.config.validators.options import OptionsValidator
7
7
  from ytdl_sub.entries.entry import Entry
8
8
  from ytdl_sub.utils.exceptions import StringFormattingException
9
9
  from ytdl_sub.utils.logger import Logger
10
- from ytdl_sub.validators.string_formatter_validators import BooleanFormatterValidator
11
- from ytdl_sub.validators.validators import ListValidator
10
+ from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator
12
11
  from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
13
12
 
14
13
  logger = Logger.get("filter-exclude")
15
14
 
16
15
 
17
- class FilterExcludeOptions(ListValidator[BooleanFormatterValidator], OptionsValidator):
16
+ class FilterExcludeOptions(ListFormatterValidator, OptionsValidator):
18
17
  """
19
18
  Applies a conditional OR on any number of filters comprised of either variables or scripts.
20
19
  If any filter evaluates to True, the entry will be excluded.
@@ -30,8 +29,6 @@ class FilterExcludeOptions(ListValidator[BooleanFormatterValidator], OptionsVali
30
29
  { %contains( %lower(description), '#short' ) }
31
30
  """
32
31
 
33
- _inner_list_type = BooleanFormatterValidator
34
-
35
32
 
36
33
  class FilterExcludePlugin(Plugin[FilterExcludeOptions]):
37
34
  plugin_options_type = FilterExcludeOptions
@@ -55,9 +52,7 @@ class FilterExcludePlugin(Plugin[FilterExcludeOptions]):
55
52
  return entry
56
53
 
57
54
  for formatter in self.plugin_options.list:
58
- should_exclude = self.overrides.apply_formatter(
59
- formatter=formatter, entry=entry, expected_type=bool
60
- )
55
+ should_exclude = self.overrides.evaluate_boolean(formatter=formatter, entry=entry)
61
56
 
62
57
  if should_exclude:
63
58
  logger.info(
@@ -7,14 +7,14 @@ from ytdl_sub.config.validators.options import OptionsValidator
7
7
  from ytdl_sub.entries.entry import Entry
8
8
  from ytdl_sub.utils.exceptions import StringFormattingException
9
9
  from ytdl_sub.utils.logger import Logger
10
- from ytdl_sub.validators.string_formatter_validators import BooleanFormatterValidator
11
- from ytdl_sub.validators.validators import ListValidator
10
+ from ytdl_sub.utils.script import ScriptUtils
11
+ from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator
12
12
  from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
13
13
 
14
14
  logger = Logger.get("filter-include")
15
15
 
16
16
 
17
- class FilterIncludeOptions(ListValidator[BooleanFormatterValidator], OptionsValidator):
17
+ class FilterIncludeOptions(ListFormatterValidator, OptionsValidator):
18
18
  """
19
19
  Applies a conditional AND on any number of filters comprised of either variables or scripts.
20
20
  If all filters evaluate to True, the entry will be included.
@@ -38,8 +38,6 @@ class FilterIncludeOptions(ListValidator[BooleanFormatterValidator], OptionsVali
38
38
  }
39
39
  """
40
40
 
41
- _inner_list_type = BooleanFormatterValidator
42
-
43
41
 
44
42
  class FilterIncludePlugin(Plugin[FilterIncludeOptions]):
45
43
  plugin_options_type = FilterIncludeOptions
@@ -63,8 +61,8 @@ class FilterIncludePlugin(Plugin[FilterIncludeOptions]):
63
61
  return entry
64
62
 
65
63
  for formatter in self.plugin_options.list:
66
- should_exclude = self.overrides.apply_formatter(
67
- formatter=formatter, entry=entry, expected_type=bool
64
+ should_exclude = ScriptUtils.bool_formatter_output(
65
+ self.overrides.apply_formatter(formatter=formatter, entry=entry)
68
66
  )
69
67
  if not should_exclude:
70
68
  logger.info(
@@ -140,7 +140,7 @@ class SharedNfoTagsPlugin(Plugin[SharedNfoTagsOptions], ABC):
140
140
  if not nfo_tags:
141
141
  return
142
142
 
143
- if self.overrides.apply_formatter(self.plugin_options.kodi_safe, expected_type=bool):
143
+ if self.overrides.evaluate_boolean(self.plugin_options.kodi_safe):
144
144
  nfo_root = to_max_3_byte_utf8_string(nfo_root)
145
145
  nfo_tags = {
146
146
  to_max_3_byte_utf8_string(key): [
@@ -31,7 +31,7 @@ class SquareThumbnailPlugin(Plugin[SquareThumbnailOptions]):
31
31
 
32
32
  @property
33
33
  def _square_thumbnail(self) -> bool:
34
- return self.overrides.apply_formatter(self.plugin_options, expected_type=bool)
34
+ return self.overrides.evaluate_boolean(self.plugin_options)
35
35
 
36
36
  @classmethod
37
37
  def _convert_to_square_thumbnail(cls, entry: Entry) -> None:
@@ -42,8 +42,8 @@ class _RandomizedRangeValidator(StrictDictValidator, ABC):
42
42
  )
43
43
 
44
44
  def _randomized_float(self, overrides: Overrides, entry: Optional[Entry] = None) -> float:
45
- actualized_min = overrides.apply_formatter(self._min, entry=entry, expected_type=float)
46
- actualized_max = overrides.apply_formatter(self._max, entry=entry, expected_type=float)
45
+ actualized_min = float(overrides.apply_formatter(self._min, entry=entry))
46
+ actualized_max = float(overrides.apply_formatter(self._max, entry=entry))
47
47
 
48
48
  if actualized_min < 0:
49
49
  raise self._validation_exception(
@@ -70,7 +70,7 @@ class _RandomizedRangeValidator(StrictDictValidator, ABC):
70
70
  -------
71
71
  Max possible value
72
72
  """
73
- actualized_max = overrides.apply_formatter(self._max, entry=entry, expected_type=float)
73
+ actualized_max = float(overrides.apply_formatter(self._max, entry=entry))
74
74
  if actualized_max < 0:
75
75
  raise self._validation_exception(
76
76
  f"max must be greater than zero, received {actualized_max}"
@@ -82,27 +82,35 @@ class StringFormatterValidator(StringValidator):
82
82
  """
83
83
  return self._parsed
84
84
 
85
- def post_process(self, resolved: Any) -> Any:
85
+ def post_process(self, resolved: str) -> str:
86
86
  """
87
87
  Returns
88
88
  -------
89
- Apply any post processing to the resolved value. Defaults to casting it to string.
89
+ Apply any post processing to the resolved value
90
90
  """
91
- return str(resolved)
91
+ return resolved
92
+
93
+ def post_process_native(self, resolved: Any) -> Any:
94
+ """
95
+ Returns
96
+ -------
97
+ Apply any post processing to the resolved native value.
98
+ """
99
+ return resolved
92
100
 
93
101
 
94
102
  class FloatFormatterValidator(StringFormatterValidator):
95
103
  _expected_value_type_name = "float"
96
104
 
97
- def post_process(self, resolved: str) -> float:
105
+ def post_process(self, resolved: str) -> str:
98
106
  try:
99
- out = float(resolved)
107
+ float(resolved)
100
108
  except Exception as exc:
101
109
  raise self._validation_exception(
102
110
  f"Expected a float, but received '{resolved}'"
103
111
  ) from exc
104
112
 
105
- return out
113
+ return resolved
106
114
 
107
115
 
108
116
  class StandardizedDateValidator(StringFormatterValidator):
@@ -119,13 +127,6 @@ class StandardizedDateValidator(StringFormatterValidator):
119
127
  return resolved
120
128
 
121
129
 
122
- class BooleanFormatterValidator(StringFormatterValidator):
123
- _expected_value_type_name = "boolean"
124
-
125
- def post_process(self, resolved: Any) -> bool:
126
- return ScriptUtils.bool_formatter_output(output=str(resolved))
127
-
128
-
129
130
  # pylint: disable=line-too-long
130
131
  class OverridesStringFormatterValidator(StringFormatterValidator):
131
132
  """
@@ -145,14 +146,15 @@ class OverridesStringFormatterValidator(StringFormatterValidator):
145
146
  class OverridesIntegerFormatterValidator(OverridesStringFormatterValidator):
146
147
  _expected_value_type_name = "integer"
147
148
 
148
- def post_process(self, resolved: str) -> int:
149
+ def post_process(self, resolved: str) -> str:
149
150
  try:
150
- out = int(resolved)
151
+ int(resolved)
151
152
  except Exception as exc:
152
153
  raise self._validation_exception(
153
154
  f"Expected an integer, but received '{resolved}'"
154
155
  ) from exc
155
- return out
156
+
157
+ return resolved
156
158
 
157
159
 
158
160
  class OverridesFloatFormatterValidator(FloatFormatterValidator, OverridesStringFormatterValidator):
@@ -161,14 +163,9 @@ class OverridesFloatFormatterValidator(FloatFormatterValidator, OverridesStringF
161
163
  """
162
164
 
163
165
 
164
- class OverridesBooleanFormatterValidator(
165
- BooleanFormatterValidator, OverridesStringFormatterValidator
166
- ):
166
+ class OverridesBooleanFormatterValidator(OverridesStringFormatterValidator):
167
167
  _expected_value_type_name = "boolean"
168
168
 
169
- def post_process(self, resolved: Any) -> bool:
170
- return ScriptUtils.bool_formatter_output(output=str(resolved))
171
-
172
169
 
173
170
  class ListFormatterValidator(ListValidator[StringFormatterValidator]):
174
171
  _inner_list_type = StringFormatterValidator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ytdl-sub
3
- Version: 2026.1.24
3
+ Version: 2026.1.24.post1
4
4
  Summary: Automate downloading metadata generation with YoutubeDL
5
5
  Author: Jesse Bannon
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1 +0,0 @@
1
- __pypi_version__ = "2026.01.24";__local_version__ = "2026.01.24+60cdbad"
File without changes