ytdl-sub 2025.12.8__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.
Files changed (176) hide show
  1. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/PKG-INFO +2 -2
  2. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/pyproject.toml +1 -1
  3. ytdl_sub-2026.1.11/src/ytdl_sub/__init__.py +1 -0
  4. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/overrides.py +47 -16
  5. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/preset_plugins.py +33 -0
  6. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/preset.py +36 -8
  7. ytdl_sub-2026.1.11/src/ytdl_sub/config/validators/variable_validation.py +94 -0
  8. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/url/downloader.py +20 -12
  9. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/url/validators.py +16 -3
  10. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/variable_types.py +1 -9
  11. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/variables/override_variables.py +1 -4
  12. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/download_deletion_options.yaml +1 -2
  13. ytdl_sub-2026.1.11/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +177 -0
  14. ytdl_sub-2026.1.11/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml +111 -0
  15. ytdl_sub-2026.1.11/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +1327 -0
  16. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/numeric_functions.py +17 -0
  17. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/parser.py +5 -0
  18. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/script.py +133 -43
  19. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/resolvable.py +8 -0
  20. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/variable_dependency.py +29 -2
  21. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/name_validation.py +21 -0
  22. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/base_subscription.py +21 -3
  23. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/script.py +36 -3
  24. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/string_formatter_validators.py +77 -31
  25. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/validators.py +3 -13
  26. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/PKG-INFO +2 -2
  27. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/requires.txt +1 -1
  28. ytdl_sub-2025.12.8/src/ytdl_sub/__init__.py +0 -1
  29. ytdl_sub-2025.12.8/src/ytdl_sub/config/validators/variable_validation.py +0 -215
  30. ytdl_sub-2025.12.8/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +0 -1049
  31. ytdl_sub-2025.12.8/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml +0 -210
  32. ytdl_sub-2025.12.8/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +0 -5693
  33. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/LICENSE +0 -0
  34. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/README.md +0 -0
  35. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/setup.cfg +0 -0
  36. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/__init__.py +0 -0
  37. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/entrypoint.py +0 -0
  38. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/output_summary.py +0 -0
  39. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/output_transaction_log.py +0 -0
  40. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/__init__.py +0 -0
  41. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/cli_to_sub.py +0 -0
  42. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/dl.py +0 -0
  43. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/cli/parsers/main.py +0 -0
  44. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/__init__.py +0 -0
  45. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/config_file.py +0 -0
  46. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/config_validator.py +0 -0
  47. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/defaults.py +0 -0
  48. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/__init__.py +0 -0
  49. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/plugin.py +0 -0
  50. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/plugin_mapping.py +0 -0
  51. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/plugin/plugin_operation.py +0 -0
  52. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/preset_options.py +0 -0
  53. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/validators/__init__.py +0 -0
  54. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/config/validators/options.py +0 -0
  55. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/__init__.py +0 -0
  56. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/info_json/__init__.py +0 -0
  57. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/info_json/info_json_downloader.py +0 -0
  58. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/source_plugin.py +0 -0
  59. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/url/__init__.py +0 -0
  60. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/ytdl_options_builder.py +0 -0
  61. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/downloaders/ytdlp.py +0 -0
  62. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/__init__.py +0 -0
  63. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/base_entry.py +0 -0
  64. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/entry.py +0 -0
  65. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/entry_parent.py +0 -0
  66. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/__init__.py +0 -0
  67. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/custom_functions.py +0 -0
  68. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/function_scripts.py +0 -0
  69. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/script/variable_definitions.py +0 -0
  70. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/entries/variables/__init__.py +0 -0
  71. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/main.py +0 -0
  72. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/__init__.py +0 -0
  73. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/audio_extract.py +0 -0
  74. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/chapters.py +0 -0
  75. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/date_range.py +0 -0
  76. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/embed_thumbnail.py +0 -0
  77. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/file_convert.py +0 -0
  78. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/filter_exclude.py +0 -0
  79. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/filter_include.py +0 -0
  80. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/format.py +0 -0
  81. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/internal/__init__.py +0 -0
  82. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/internal/view.py +0 -0
  83. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/match_filters.py +0 -0
  84. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/music_tags.py +0 -0
  85. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/nfo_tags.py +0 -0
  86. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/output_directory_nfo_tags.py +0 -0
  87. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/split_by_chapters.py +0 -0
  88. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/square_thumbnail.py +0 -0
  89. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/static_nfo_tags.py +0 -0
  90. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/subtitles.py +0 -0
  91. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/throttle_protection.py +0 -0
  92. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/plugins/video_tags.py +0 -0
  93. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/__init__.py +0 -0
  94. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/__init__.py +0 -0
  95. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/filter_duration.yaml +0 -0
  96. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/filter_keywords.yaml +0 -0
  97. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml +0 -0
  98. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/players.yaml +0 -0
  99. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml +0 -0
  100. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/helpers/url_bilateral.yaml +0 -0
  101. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/internal/__init__.py +0 -0
  102. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/internal/view.yaml +0 -0
  103. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/__init__.py +0 -0
  104. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/albums_from_chapters.yaml +0 -0
  105. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/albums_from_playlists.yaml +0 -0
  106. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/singles.yaml +0 -0
  107. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music/soundcloud.yaml +0 -0
  108. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py +0 -0
  109. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml +0 -0
  110. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml +0 -0
  111. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/music_videos/music_videos.yaml +0 -0
  112. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/__init__.py +0 -0
  113. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml +0 -0
  114. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show.yaml +0 -0
  115. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_by_date.yaml +0 -0
  116. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/__init__.py +0 -0
  117. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/__init__.py +0 -0
  118. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/array_functions.py +0 -0
  119. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/boolean_functions.py +0 -0
  120. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/conditional_functions.py +0 -0
  121. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/date_functions.py +0 -0
  122. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/error_functions.py +0 -0
  123. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/json_functions.py +0 -0
  124. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/map_functions.py +0 -0
  125. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/print_functions.py +0 -0
  126. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/regex_functions.py +0 -0
  127. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/functions/string_functions.py +0 -0
  128. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/script_output.py +0 -0
  129. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/__init__.py +0 -0
  130. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/array.py +0 -0
  131. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/function.py +0 -0
  132. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/map.py +0 -0
  133. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/syntax_tree.py +0 -0
  134. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/types/variable.py +0 -0
  135. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/__init__.py +0 -0
  136. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/exception_formatters.py +0 -0
  137. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/exceptions.py +0 -0
  138. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/script/utils/type_checking.py +0 -0
  139. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/__init__.py +0 -0
  140. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription.py +0 -0
  141. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription_download.py +0 -0
  142. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription_validators.py +0 -0
  143. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/subscriptions/subscription_ytdl_options.py +0 -0
  144. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/thread/__init__.py +0 -0
  145. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/thread/log_entries_downloaded_listener.py +0 -0
  146. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/__init__.py +0 -0
  147. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/chapters.py +0 -0
  148. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/datetime.py +0 -0
  149. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/exceptions.py +0 -0
  150. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/ffmpeg.py +0 -0
  151. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/file_handler.py +0 -0
  152. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/file_lock.py +0 -0
  153. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/file_path.py +0 -0
  154. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/logger.py +0 -0
  155. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/retry.py +0 -0
  156. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/scriptable.py +0 -0
  157. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/subtitles.py +0 -0
  158. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/system.py +0 -0
  159. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/thumbnail.py +0 -0
  160. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/xml.py +0 -0
  161. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/utils/yaml.py +0 -0
  162. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/__init__.py +0 -0
  163. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/audo_codec_validator.py +0 -0
  164. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/file_path_validators.py +0 -0
  165. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/nfo_validators.py +0 -0
  166. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/regex_validator.py +0 -0
  167. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/source_variable_validator.py +0 -0
  168. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/strict_dict_validator.py +0 -0
  169. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/string_datetime.py +0 -0
  170. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/validators/string_select_validator.py +0 -0
  171. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/ytdl_additions/__init__.py +0 -0
  172. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub/ytdl_additions/enhanced_download_archive.py +0 -0
  173. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/SOURCES.txt +0 -0
  174. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/dependency_links.txt +0 -0
  175. {ytdl_sub-2025.12.8 → ytdl_sub-2026.1.11}/src/ytdl_sub.egg-info/entry_points.txt +0 -0
  176. {ytdl_sub-2025.12.8 → 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: 2025.12.8
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<9,>=7; extra == "docs"
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"
@@ -52,7 +52,7 @@ lint = [
52
52
  "pylint==4.0.1",
53
53
  ]
54
54
  docs = [
55
- "sphinx>=7,<9",
55
+ "sphinx>=7,<10",
56
56
  "sphinx-rtd-theme>=2,<4",
57
57
  "sphinx-book-theme~=1.0",
58
58
  "sphinx-copybutton~=0.5",
@@ -0,0 +1 @@
1
+ __pypi_version__ = "2026.01.11";__local_version__ = "2026.01.11+41a5bf6"
@@ -1,17 +1,19 @@
1
1
  from typing import Any
2
2
  from typing import Dict
3
+ from typing import Iterable
3
4
  from typing import Optional
4
5
  from typing import Set
5
6
 
6
- import mergedeep
7
-
8
7
  from ytdl_sub.entries.entry import Entry
9
8
  from ytdl_sub.entries.script.variable_definitions import VARIABLES
10
9
  from ytdl_sub.entries.variables.override_variables import REQUIRED_OVERRIDE_VARIABLE_NAMES
11
10
  from ytdl_sub.entries.variables.override_variables import OverrideHelpers
12
11
  from ytdl_sub.script.parser import parse
13
12
  from ytdl_sub.script.script import Script
13
+ from ytdl_sub.script.types.function import BuiltInFunction
14
14
  from ytdl_sub.script.types.resolvable import Resolvable
15
+ from ytdl_sub.script.types.resolvable import String
16
+ from ytdl_sub.script.types.syntax_tree import SyntaxTree
15
17
  from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
16
18
  from ytdl_sub.utils.exceptions import InvalidVariableNameException
17
19
  from ytdl_sub.utils.exceptions import StringFormattingException
@@ -88,6 +90,24 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
88
90
 
89
91
  return True
90
92
 
93
+ def ensure_variable_names_not_a_plugin(self, plugin_names: Iterable[str]) -> None:
94
+ """
95
+ Throws an error if an override variable or function has the same name as a
96
+ preset key. This is to avoid confusion when accidentally defining things in
97
+ overrides that are meant to be in the preset.
98
+ """
99
+ for name in self.keys:
100
+ if name.startswith("%"):
101
+ name = name[1:]
102
+
103
+ if name in plugin_names:
104
+ raise self._validation_exception(
105
+ f"Override variable with name {name} cannot be used since it is"
106
+ " the name of a plugin. Perhaps you meant to define it as a plugin? If so,"
107
+ " indent it left to make it at the same level as overrides.",
108
+ exception_class=InvalidVariableNameException,
109
+ )
110
+
91
111
  def ensure_variable_name_valid(self, name: str) -> None:
92
112
  """
93
113
  Ensures the variable name does not collide with any entry variables or built-in functions.
@@ -115,29 +135,35 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
115
135
  )
116
136
 
117
137
  def initial_variables(
118
- self, unresolved_variables: Optional[Dict[str, str]] = None
119
- ) -> Dict[str, str]:
138
+ self, unresolved_variables: Optional[Dict[str, SyntaxTree]] = None
139
+ ) -> Dict[str, SyntaxTree]:
120
140
  """
121
141
  Returns
122
142
  -------
123
143
  Variables and format strings for all Override variables + additional variables (Optional)
124
144
  """
125
- initial_variables: Dict[str, str] = {}
126
- mergedeep.merge(
127
- initial_variables,
128
- self.dict_with_format_strings,
129
- unresolved_variables if unresolved_variables else {},
130
- )
131
- return ScriptUtils.add_sanitized_variables(initial_variables)
145
+ initial_variables: Dict[str, SyntaxTree] = self.dict_with_parsed_format_strings
146
+ if unresolved_variables:
147
+ initial_variables |= unresolved_variables
148
+ return ScriptUtils.add_sanitized_parsed_variables(initial_variables)
132
149
 
133
150
  def initialize_script(self, unresolved_variables: Set[str]) -> "Overrides":
134
151
  """
135
152
  Initialize the override script with any unresolved variables
136
153
  """
137
- self.script.add(
154
+ self.script.add_parsed(
138
155
  self.initial_variables(
139
156
  unresolved_variables={
140
- var_name: f"{{%throw('Plugin variable {var_name} has not been created yet')}}"
157
+ var_name: SyntaxTree(
158
+ ast=[
159
+ BuiltInFunction(
160
+ name="throw",
161
+ args=[
162
+ String(f"Plugin variable {var_name} has not been created yet")
163
+ ],
164
+ )
165
+ ]
166
+ )
141
167
  for var_name in unresolved_variables
142
168
  }
143
169
  )
@@ -212,20 +238,25 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
212
238
  def apply_overrides_formatter_to_native(
213
239
  self,
214
240
  formatter: OverridesStringFormatterValidator,
241
+ function_overrides: Optional[Dict[str, str]] = None,
215
242
  ) -> Any:
216
243
  """
217
244
  Parameters
218
245
  ----------
219
246
  formatter
220
247
  Overrides formatter to apply
248
+ function_overrides
249
+ Optional. Explicit values to override the overrides themselves and source variables
221
250
 
222
251
  Returns
223
252
  -------
224
253
  The native python form of the resolved variable
225
254
  """
226
- return self._apply_to_resolvable(
227
- formatter=formatter, entry=None, function_overrides=None
228
- ).native
255
+ return formatter.post_process_native(
256
+ self._apply_to_resolvable(
257
+ formatter=formatter, entry=None, function_overrides=function_overrides
258
+ ).native
259
+ )
229
260
 
230
261
  def evaluate_boolean(
231
262
  self, formatter: StringFormatterValidator, entry: Optional[Entry] = None
@@ -1,5 +1,7 @@
1
+ from typing import Iterable
1
2
  from typing import List
2
3
  from typing import Optional
4
+ from typing import Set
3
5
  from typing import Tuple
4
6
  from typing import Type
5
7
 
@@ -44,3 +46,34 @@ class PresetPlugins:
44
46
  if plugin_type in plugin_option_types:
45
47
  return self.plugin_options[plugin_option_types.index(plugin_type)]
46
48
  return None
49
+
50
+ def get_added_and_modified_variables(
51
+ self, additional_options: List[OptionsValidator]
52
+ ) -> Iterable[Tuple[OptionsValidator, Set[str], Set[str]]]:
53
+ """
54
+ Iterates and returns the plugin options, added variables, modified variables
55
+ """
56
+ for plugin_options in self.plugin_options + additional_options:
57
+ added_variables: Set[str] = set()
58
+ modified_variables: Set[str] = set()
59
+
60
+ for plugin_added_variables in plugin_options.added_variables(
61
+ unresolved_variables=set(),
62
+ ).values():
63
+ added_variables |= set(plugin_added_variables)
64
+
65
+ for plugin_modified_variables in plugin_options.modified_variables().values():
66
+ modified_variables = plugin_modified_variables
67
+
68
+ yield plugin_options, added_variables, modified_variables
69
+
70
+ def get_all_variables(self, additional_options: List[OptionsValidator]) -> Set[str]:
71
+ """
72
+ Returns set of all added and modified variables' names.
73
+ """
74
+ all_variables: Set[str] = set()
75
+ for _, added, modified in self.get_added_and_modified_variables(additional_options):
76
+ all_variables.update(added)
77
+ all_variables.update(modified)
78
+
79
+ return all_variables
@@ -2,6 +2,7 @@ import copy
2
2
  from typing import Any
3
3
  from typing import Dict
4
4
  from typing import List
5
+ from typing import Set
5
6
 
6
7
  from mergedeep import mergedeep
7
8
 
@@ -11,7 +12,6 @@ from ytdl_sub.config.plugin.plugin_mapping import PluginMapping
11
12
  from ytdl_sub.config.plugin.preset_plugins import PresetPlugins
12
13
  from ytdl_sub.config.preset_options import OutputOptions
13
14
  from ytdl_sub.config.preset_options import YTDLOptions
14
- from ytdl_sub.config.validators.variable_validation import VariableValidation
15
15
  from ytdl_sub.downloaders.url.validators import MultiUrlValidator
16
16
  from ytdl_sub.prebuilt_presets import PREBUILT_PRESET_NAMES
17
17
  from ytdl_sub.prebuilt_presets import PUBLISHED_PRESET_NAMES
@@ -172,6 +172,37 @@ class Preset(_PresetShell):
172
172
  mergedeep.merge({}, *reversed(presets_to_merge), strategy=mergedeep.Strategy.ADDITIVE)
173
173
  )
174
174
 
175
+ def _initialize_overrides_script(self, overrides: Overrides) -> Overrides:
176
+ """
177
+ Do some gymnastics to initialize the Overrides script.
178
+ """
179
+ unresolved_variables: Set[str] = set()
180
+
181
+ for (
182
+ plugin_options,
183
+ added_variables,
184
+ modified_variables,
185
+ ) in self.plugins.get_added_and_modified_variables(
186
+ additional_options=[self.downloader_options, self.output_options]
187
+ ):
188
+ for added_variable in added_variables:
189
+ if not overrides.ensure_added_plugin_variable_valid(added_variable=added_variable):
190
+ # pylint: disable=protected-access
191
+ raise plugin_options._validation_exception(
192
+ f"Cannot use the variable name {added_variable} because it exists as a"
193
+ " built-in ytdl-sub variable name."
194
+ )
195
+ # pylint: enable=protected-access
196
+
197
+ # Set unresolved as variables that are added but do not exist as
198
+ # entry/override variables since they are created at run-time
199
+ unresolved_variables |= added_variables | modified_variables
200
+
201
+ # Initialize overrides with unresolved variables + modified variables to throw an error.
202
+ # For modified variables, this is to prevent a resolve(update=True) to setting any
203
+ # dependencies until it has been explicitly added
204
+ return overrides.initialize_script(unresolved_variables=unresolved_variables)
205
+
175
206
  def __init__(self, config: ConfigValidator, name: str, value: Any):
176
207
  super().__init__(name=name, value=value)
177
208
 
@@ -192,13 +223,10 @@ class Preset(_PresetShell):
192
223
  )
193
224
 
194
225
  self.plugins: PresetPlugins = self._validate_and_get_plugins()
195
- self.overrides = self._validate_key(key="overrides", validator=Overrides, default={})
196
-
197
- VariableValidation(
198
- downloader_options=self.downloader_options,
199
- output_options=self.output_options,
200
- plugins=self.plugins,
201
- ).initialize_preset_overrides(overrides=self.overrides).ensure_proper_usage()
226
+ self.overrides = self._initialize_overrides_script(
227
+ overrides=self._validate_key(key="overrides", validator=Overrides, default={})
228
+ )
229
+ self.overrides.ensure_variable_names_not_a_plugin(plugin_names=PRESET_KEYS)
202
230
 
203
231
  @property
204
232
  def name(self) -> str:
@@ -0,0 +1,94 @@
1
+ from typing import Dict
2
+
3
+ from ytdl_sub.config.overrides import Overrides
4
+ from ytdl_sub.config.plugin.plugin_mapping import PluginMapping
5
+ from ytdl_sub.config.plugin.plugin_operation import PluginOperation
6
+ from ytdl_sub.config.plugin.preset_plugins import PresetPlugins
7
+ from ytdl_sub.config.preset_options import OutputOptions
8
+ from ytdl_sub.config.validators.options import OptionsValidator
9
+ from ytdl_sub.downloaders.url.validators import MultiUrlValidator
10
+ from ytdl_sub.validators.string_formatter_validators import validate_formatters
11
+
12
+
13
+ class VariableValidation:
14
+ def __init__(
15
+ self,
16
+ overrides: Overrides,
17
+ downloader_options: MultiUrlValidator,
18
+ output_options: OutputOptions,
19
+ plugins: PresetPlugins,
20
+ ):
21
+ self.overrides = overrides
22
+ self.downloader_options = downloader_options
23
+ self.output_options = output_options
24
+ self.plugins = plugins
25
+
26
+ self.script = self.overrides.script
27
+ self.unresolved_variables = self.plugins.get_all_variables(
28
+ additional_options=[self.output_options, self.downloader_options]
29
+ )
30
+
31
+ def _add_variables(self, plugin_op: PluginOperation, options: OptionsValidator) -> None:
32
+ """
33
+ Add dummy variables for script validation
34
+ """
35
+ added_variables = options.added_variables(
36
+ unresolved_variables=self.unresolved_variables,
37
+ ).get(plugin_op, set())
38
+ modified_variables = options.modified_variables().get(plugin_op, set())
39
+
40
+ self.unresolved_variables -= added_variables | modified_variables
41
+
42
+ def ensure_proper_usage(self) -> Dict:
43
+ """
44
+ Validate variables resolve as plugins are executed, and return
45
+ a mock script which contains actualized added variables from the plugins
46
+ """
47
+
48
+ resolved_subscription: Dict = {}
49
+
50
+ self._add_variables(PluginOperation.DOWNLOADER, options=self.downloader_options)
51
+
52
+ # Always add output options first
53
+ self._add_variables(PluginOperation.MODIFY_ENTRY_METADATA, options=self.output_options)
54
+
55
+ # Metadata variables to be added
56
+ for plugin_options in PluginMapping.order_options_by(
57
+ self.plugins.zipped(), PluginOperation.MODIFY_ENTRY_METADATA
58
+ ):
59
+ self._add_variables(PluginOperation.MODIFY_ENTRY_METADATA, options=plugin_options)
60
+
61
+ for plugin_options in PluginMapping.order_options_by(
62
+ self.plugins.zipped(), PluginOperation.MODIFY_ENTRY
63
+ ):
64
+ self._add_variables(PluginOperation.MODIFY_ENTRY, options=plugin_options)
65
+
66
+ # Validate that any formatter in the plugin options can resolve
67
+ resolved_subscription |= validate_formatters(
68
+ script=self.script,
69
+ unresolved_variables=self.unresolved_variables,
70
+ validator=plugin_options,
71
+ )
72
+
73
+ resolved_subscription |= validate_formatters(
74
+ script=self.script,
75
+ unresolved_variables=self.unresolved_variables,
76
+ validator=self.output_options,
77
+ )
78
+
79
+ # TODO: make this a function
80
+ raw_download_output = validate_formatters(
81
+ script=self.script,
82
+ unresolved_variables=self.unresolved_variables,
83
+ validator=self.downloader_options.urls,
84
+ )
85
+ resolved_subscription["download"] = []
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
+
90
+ if url_output["url"]:
91
+ resolved_subscription["download"].append(url_output)
92
+
93
+ assert not self.unresolved_variables
94
+ return resolved_subscription
@@ -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.apply_formatter(validator.url) == entry_input_url:
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.apply_formatter(validator.url) == entry_input_url:
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 (url := self.overrides.apply_formatter(url_validator.url)):
490
+ if not (urls := self.overrides.apply_overrides_formatter_to_native(url_validator.url)):
491
491
  continue
492
492
 
493
- for entry in self._download_metadata(url=url, validator=url_validator):
494
- entry.initialize_script(self.overrides).add(
495
- {
496
- v.ytdl_sub_input_url: url,
497
- v.ytdl_sub_input_url_index: idx,
498
- v.ytdl_sub_input_url_count: len(self.collection.urls.list),
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
- yield entry
510
+ yield entry
503
511
 
504
512
  def download(self, entry: Entry) -> Optional[Entry]:
505
513
  """
@@ -21,7 +21,7 @@ class UrlThumbnailValidator(StrictDictValidator):
21
21
  def __init__(self, name, value):
22
22
  super().__init__(name, value)
23
23
 
24
- self._name = self._validate_key(key="name", validator=StringFormatterValidator)
24
+ self._thumb_name = self._validate_key(key="name", validator=StringFormatterValidator)
25
25
  self._uid = self._validate_key(key="uid", validator=OverridesStringFormatterValidator)
26
26
 
27
27
  @property
@@ -29,7 +29,7 @@ class UrlThumbnailValidator(StrictDictValidator):
29
29
  """
30
30
  File name for the thumbnail
31
31
  """
32
- return self._name
32
+ return self._thumb_name
33
33
 
34
34
  @property
35
35
  def uid(self) -> OverridesStringFormatterValidator:
@@ -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=OverridesStringFormatterValidator)
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
  )
@@ -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"{{ %legacy_bracket_safety(%{cast}({out})) }}",
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,
@@ -11,9 +11,6 @@ from ytdl_sub.entries.script.variable_types import Variable
11
11
  from ytdl_sub.script.functions import Functions
12
12
  from ytdl_sub.script.utils.name_validation import is_valid_name
13
13
 
14
- # TODO: use this
15
- SUBSCRIPTION_ARRAY = "subscription_array"
16
-
17
14
 
18
15
  class SubscriptionVariables:
19
16
  @staticmethod
@@ -163,7 +160,7 @@ class OverrideHelpers:
163
160
  True if the override name itself is valid. False otherwise.
164
161
  """
165
162
  if name.startswith("%"):
166
- return is_valid_name(name=name[1:])
163
+ name = name[1:]
167
164
 
168
165
  return is_valid_name(name=name)
169
166
 
@@ -11,8 +11,7 @@ presets:
11
11
 
12
12
  # Set the default date_range to 2 months
13
13
  overrides:
14
- date_range: "2months" # keep for legacy-reasons
15
- only_recent_date_range: "{date_range}"
14
+ only_recent_date_range: "2months"
16
15
 
17
16
  #############################################################################
18
17
  # Only Recent