ytdl-sub 2025.11.8__tar.gz → 2025.12.8__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 (173) hide show
  1. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/PKG-INFO +2 -2
  2. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/pyproject.toml +1 -1
  3. ytdl_sub-2025.12.8/src/ytdl_sub/__init__.py +1 -0
  4. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/config_validator.py +8 -0
  5. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/overrides.py +5 -0
  6. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/preset_options.py +33 -2
  7. ytdl_sub-2025.12.8/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +5693 -0
  8. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/parser.py +1 -1
  9. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/script.py +8 -3
  10. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/function.py +11 -6
  11. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/syntax_tree.py +28 -2
  12. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/variable_dependency.py +4 -4
  13. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/subscriptions/base_subscription.py +8 -0
  14. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/subscriptions/subscription_download.py +3 -0
  15. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/exceptions.py +4 -0
  16. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/file_handler.py +49 -0
  17. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/string_formatter_validators.py +1 -0
  18. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/ytdl_additions/enhanced_download_archive.py +20 -0
  19. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub.egg-info/PKG-INFO +2 -2
  20. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub.egg-info/requires.txt +1 -1
  21. ytdl_sub-2025.11.8/src/ytdl_sub/__init__.py +0 -1
  22. ytdl_sub-2025.11.8/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +0 -1131
  23. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/LICENSE +0 -0
  24. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/README.md +0 -0
  25. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/setup.cfg +0 -0
  26. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/__init__.py +0 -0
  27. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/entrypoint.py +0 -0
  28. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/output_summary.py +0 -0
  29. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/output_transaction_log.py +0 -0
  30. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/parsers/__init__.py +0 -0
  31. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/parsers/cli_to_sub.py +0 -0
  32. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/parsers/dl.py +0 -0
  33. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/cli/parsers/main.py +0 -0
  34. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/__init__.py +0 -0
  35. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/config_file.py +0 -0
  36. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/defaults.py +0 -0
  37. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/plugin/__init__.py +0 -0
  38. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/plugin/plugin.py +0 -0
  39. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/plugin/plugin_mapping.py +0 -0
  40. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/plugin/plugin_operation.py +0 -0
  41. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/plugin/preset_plugins.py +0 -0
  42. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/preset.py +0 -0
  43. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/validators/__init__.py +0 -0
  44. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/validators/options.py +0 -0
  45. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/config/validators/variable_validation.py +0 -0
  46. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/__init__.py +0 -0
  47. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/info_json/__init__.py +0 -0
  48. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/info_json/info_json_downloader.py +0 -0
  49. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/source_plugin.py +0 -0
  50. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/url/__init__.py +0 -0
  51. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/url/downloader.py +0 -0
  52. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/url/validators.py +0 -0
  53. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/ytdl_options_builder.py +0 -0
  54. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/downloaders/ytdlp.py +0 -0
  55. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/__init__.py +0 -0
  56. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/base_entry.py +0 -0
  57. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/entry.py +0 -0
  58. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/entry_parent.py +0 -0
  59. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/script/__init__.py +0 -0
  60. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/script/custom_functions.py +0 -0
  61. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/script/function_scripts.py +0 -0
  62. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/script/variable_definitions.py +0 -0
  63. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/script/variable_types.py +0 -0
  64. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/variables/__init__.py +0 -0
  65. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/entries/variables/override_variables.py +0 -0
  66. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/main.py +0 -0
  67. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/__init__.py +0 -0
  68. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/audio_extract.py +0 -0
  69. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/chapters.py +0 -0
  70. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/date_range.py +0 -0
  71. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/embed_thumbnail.py +0 -0
  72. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/file_convert.py +0 -0
  73. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/filter_exclude.py +0 -0
  74. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/filter_include.py +0 -0
  75. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/format.py +0 -0
  76. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/internal/__init__.py +0 -0
  77. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/internal/view.py +0 -0
  78. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/match_filters.py +0 -0
  79. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/music_tags.py +0 -0
  80. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/nfo_tags.py +0 -0
  81. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/output_directory_nfo_tags.py +0 -0
  82. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/split_by_chapters.py +0 -0
  83. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/square_thumbnail.py +0 -0
  84. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/static_nfo_tags.py +0 -0
  85. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/subtitles.py +0 -0
  86. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/throttle_protection.py +0 -0
  87. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/plugins/video_tags.py +0 -0
  88. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/__init__.py +0 -0
  89. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/__init__.py +0 -0
  90. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/download_deletion_options.yaml +0 -0
  91. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/filter_duration.yaml +0 -0
  92. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/filter_keywords.yaml +0 -0
  93. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml +0 -0
  94. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/players.yaml +0 -0
  95. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml +0 -0
  96. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +0 -0
  97. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/url_bilateral.yaml +0 -0
  98. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml +0 -0
  99. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/internal/__init__.py +0 -0
  100. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/internal/view.yaml +0 -0
  101. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music/__init__.py +0 -0
  102. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music/albums_from_chapters.yaml +0 -0
  103. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music/albums_from_playlists.yaml +0 -0
  104. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music/singles.yaml +0 -0
  105. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music/soundcloud.yaml +0 -0
  106. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py +0 -0
  107. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml +0 -0
  108. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml +0 -0
  109. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/music_videos/music_videos.yaml +0 -0
  110. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/tv_show/__init__.py +0 -0
  111. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml +0 -0
  112. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show.yaml +0 -0
  113. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_by_date.yaml +0 -0
  114. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/__init__.py +0 -0
  115. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/__init__.py +0 -0
  116. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/array_functions.py +0 -0
  117. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/boolean_functions.py +0 -0
  118. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/conditional_functions.py +0 -0
  119. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/date_functions.py +0 -0
  120. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/error_functions.py +0 -0
  121. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/json_functions.py +0 -0
  122. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/map_functions.py +0 -0
  123. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/numeric_functions.py +0 -0
  124. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/print_functions.py +0 -0
  125. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/regex_functions.py +0 -0
  126. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/functions/string_functions.py +0 -0
  127. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/script_output.py +0 -0
  128. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/__init__.py +0 -0
  129. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/array.py +0 -0
  130. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/map.py +0 -0
  131. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/resolvable.py +0 -0
  132. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/types/variable.py +0 -0
  133. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/utils/__init__.py +0 -0
  134. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/utils/exception_formatters.py +0 -0
  135. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/utils/exceptions.py +0 -0
  136. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/utils/name_validation.py +0 -0
  137. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/script/utils/type_checking.py +0 -0
  138. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/subscriptions/__init__.py +0 -0
  139. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/subscriptions/subscription.py +0 -0
  140. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/subscriptions/subscription_validators.py +0 -0
  141. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/subscriptions/subscription_ytdl_options.py +0 -0
  142. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/thread/__init__.py +0 -0
  143. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/thread/log_entries_downloaded_listener.py +0 -0
  144. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/__init__.py +0 -0
  145. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/chapters.py +0 -0
  146. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/datetime.py +0 -0
  147. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/ffmpeg.py +0 -0
  148. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/file_lock.py +0 -0
  149. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/file_path.py +0 -0
  150. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/logger.py +0 -0
  151. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/retry.py +0 -0
  152. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/script.py +0 -0
  153. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/scriptable.py +0 -0
  154. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/subtitles.py +0 -0
  155. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/system.py +0 -0
  156. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/thumbnail.py +0 -0
  157. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/xml.py +0 -0
  158. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/utils/yaml.py +0 -0
  159. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/__init__.py +0 -0
  160. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/audo_codec_validator.py +0 -0
  161. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/file_path_validators.py +0 -0
  162. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/nfo_validators.py +0 -0
  163. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/regex_validator.py +0 -0
  164. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/source_variable_validator.py +0 -0
  165. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/strict_dict_validator.py +0 -0
  166. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/string_datetime.py +0 -0
  167. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/string_select_validator.py +0 -0
  168. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/validators/validators.py +0 -0
  169. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub/ytdl_additions/__init__.py +0 -0
  170. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub.egg-info/SOURCES.txt +0 -0
  171. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub.egg-info/dependency_links.txt +0 -0
  172. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/src/ytdl_sub.egg-info/entry_points.txt +0 -0
  173. {ytdl_sub-2025.11.8 → ytdl_sub-2025.12.8}/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.11.8
3
+ Version: 2025.12.8
4
4
  Summary: Automate downloading metadata generation with YoutubeDL
5
5
  Author: Jesse Bannon
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -689,7 +689,7 @@ Classifier: Programming Language :: Python :: 3.11
689
689
  Requires-Python: >=3.10
690
690
  Description-Content-Type: text/markdown
691
691
  License-File: LICENSE
692
- Requires-Dist: yt-dlp[default]==2025.10.22
692
+ Requires-Dist: yt-dlp[default]==2025.12.8
693
693
  Requires-Dist: colorama~=0.4
694
694
  Requires-Dist: mergedeep~=1.3
695
695
  Requires-Dist: mediafile~=0.12
@@ -15,7 +15,7 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3.11",
16
16
  ]
17
17
  dependencies = [
18
- "yt-dlp[default]==2025.10.22",
18
+ "yt-dlp[default]==2025.12.8",
19
19
  "colorama~=0.4",
20
20
  "mergedeep~=1.3",
21
21
  "mediafile~=0.12",
@@ -0,0 +1 @@
1
+ __pypi_version__ = "2025.12.08";__local_version__ = "2025.12.08+157a0b5"
@@ -12,6 +12,8 @@ from ytdl_sub.config.defaults import DEFAULT_FFPROBE_PATH
12
12
  from ytdl_sub.config.defaults import DEFAULT_LOCK_DIRECTORY
13
13
  from ytdl_sub.config.defaults import MAX_FILE_NAME_BYTES
14
14
  from ytdl_sub.prebuilt_presets import PREBUILT_PRESETS
15
+ from ytdl_sub.utils.exceptions import SubscriptionPermissionError
16
+ from ytdl_sub.utils.file_handler import FileHandler
15
17
  from ytdl_sub.validators.file_path_validators import FFmpegFileValidator
16
18
  from ytdl_sub.validators.file_path_validators import FFprobeFileValidator
17
19
  from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
@@ -147,6 +149,12 @@ class ConfigOptions(StrictDictValidator):
147
149
  key="file_name_max_bytes", validator=IntValidator, default=MAX_FILE_NAME_BYTES
148
150
  )
149
151
 
152
+ if not FileHandler.is_path_writable(self.working_directory):
153
+ raise SubscriptionPermissionError(
154
+ "ytdl-sub does not have permissions to the working directory: "
155
+ f"{self.working_directory}"
156
+ )
157
+
150
158
  @property
151
159
  def working_directory(self) -> str:
152
160
  """
@@ -158,10 +158,15 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
158
158
  script = entry.script
159
159
  unresolvable = entry.unresolvable
160
160
 
161
+ # Update the script internally so long as we are not supplying overrides
162
+ # that could alter the script with one-off state
163
+ update = function_overrides is None
164
+
161
165
  try:
162
166
  return script.resolve_once(
163
167
  dict({"tmp_var": formatter.format_string}, **(function_overrides or {})),
164
168
  unresolvable=unresolvable,
169
+ update=update,
165
170
  )["tmp_var"]
166
171
  except ScriptVariableNotResolved as exc:
167
172
  raise StringFormattingException(
@@ -8,6 +8,9 @@ from ytdl_sub.config.overrides import Overrides
8
8
  from ytdl_sub.config.plugin.plugin_operation import PluginOperation
9
9
  from ytdl_sub.config.validators.options import OptionsDictValidator
10
10
  from ytdl_sub.entries.script.variable_definitions import VARIABLES as v
11
+ from ytdl_sub.utils.exceptions import SubscriptionPermissionError
12
+ from ytdl_sub.utils.exceptions import ValidationException
13
+ from ytdl_sub.utils.file_handler import FileHandler
11
14
  from ytdl_sub.validators.file_path_validators import OverridesStringFormatterFilePathValidator
12
15
  from ytdl_sub.validators.file_path_validators import StringFormatterFileNameValidator
13
16
  from ytdl_sub.validators.string_datetime import StringDatetimeValidator
@@ -57,12 +60,24 @@ class YTDLOptions(UnstructuredOverridesDictFormatterValidator):
57
60
  def to_native_dict(self, overrides: Overrides) -> Dict:
58
61
  """
59
62
  Materializes the entire ytdl-options dict from OverrideStringFormatters into
60
- native python
63
+ native python.
61
64
  """
62
- return {
65
+ out = {
63
66
  key: overrides.apply_overrides_formatter_to_native(val)
64
67
  for key, val in self.dict.items()
65
68
  }
69
+ if "cookiefile" in out:
70
+ if not FileHandler.is_file_existent(out["cookiefile"]):
71
+ raise ValidationException(
72
+ f"Specified cookiefile {out['cookiefile']} but it does not exist as a file."
73
+ )
74
+
75
+ if not FileHandler.is_file_readable(out["cookiefile"]):
76
+ raise SubscriptionPermissionError(
77
+ f"Cannot read cookiefile {out['cookiefile']} due to permissions issue."
78
+ )
79
+
80
+ return out
66
81
 
67
82
 
68
83
  # Disable for proper docstring formatting
@@ -107,6 +122,7 @@ class OutputOptions(OptionsDictValidator):
107
122
  "keep_max_files",
108
123
  "download_archive_standardized_date",
109
124
  "keep_files_date_eval",
125
+ "preserve_mtime",
110
126
  }
111
127
 
112
128
  @classmethod
@@ -170,6 +186,10 @@ class OutputOptions(OptionsDictValidator):
170
186
  default=f"{{{v.upload_date_standardized.variable_name}}}",
171
187
  )
172
188
 
189
+ self._preserve_mtime = self._validate_key_if_present(
190
+ key="preserve_mtime", validator=BoolValidator, default=False
191
+ )
192
+
173
193
  if (
174
194
  self._keep_files_before or self._keep_files_after or self._keep_max_files
175
195
  ) and not self.maintain_download_archive:
@@ -309,6 +329,17 @@ class OutputOptions(OptionsDictValidator):
309
329
  """
310
330
  return self._keep_max_files
311
331
 
332
+ @property
333
+ def preserve_mtime(self) -> bool:
334
+ """
335
+ :expected type: Optional[Boolean]
336
+ :description:
337
+ Preserve the video's original upload time as the file modification time.
338
+ When True, sets the file's mtime to match the video's upload_date from
339
+ yt-dlp metadata. Defaults to False.
340
+ """
341
+ return self._preserve_mtime.value
342
+
312
343
  def added_variables(self, unresolved_variables: Set[str]) -> Dict[PluginOperation, Set[str]]:
313
344
  return {
314
345
  # PluginOperation.MODIFY_ENTRY_METADATA: {