diff --git a/src/ytdl_sub/plugins/throttle_protection.py b/src/ytdl_sub/plugins/throttle_protection.py index 77ec4fa8..27cad374 100644 --- a/src/ytdl_sub/plugins/throttle_protection.py +++ b/src/ytdl_sub/plugins/throttle_protection.py @@ -185,6 +185,13 @@ class ThrottleProtectionOptions(ToggleableOptionsDictValidator): class ThrottleProtectionPlugin(Plugin[ThrottleProtectionOptions]): plugin_options_type = ThrottleProtectionOptions + @classmethod + def perform_sleep(cls, sleep_time: float) -> None: + """ + Wrapper to be able to mock + """ + time.sleep(sleep_time) + def __init__( self, options: ThrottleProtectionOptions, @@ -239,7 +246,7 @@ class ThrottleProtectionPlugin(Plugin[ThrottleProtectionOptions]): self._subscription_max_downloads is not None and self._subscription_download_counter == 0 ): - logger.debug( + logger.info( "Setting subscription max downloads to %d", self._subscription_max_downloads ) @@ -248,8 +255,8 @@ class ThrottleProtectionPlugin(Plugin[ThrottleProtectionOptions]): if self.plugin_options.sleep_per_download_s: sleep_time = self.plugin_options.sleep_per_download_s.randomized_float() - logger.debug("Sleeping between downloads for %0.2f seconds", sleep_time) - time.sleep(sleep_time) + logger.info("Sleeping between downloads for %0.2f seconds", sleep_time) + self.perform_sleep(sleep_time) return None @@ -265,5 +272,5 @@ class ThrottleProtectionPlugin(Plugin[ThrottleProtectionOptions]): if self.plugin_options.sleep_per_subscription_s: sleep_time = self.plugin_options.sleep_per_subscription_s.randomized_float() - logger.debug("Sleeping between subscriptions for %0.2f seconds", sleep_time) - time.sleep(sleep_time) + logger.info("Sleeping between subscriptions for %0.2f seconds", sleep_time) + self.perform_sleep(sleep_time) diff --git a/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml b/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml new file mode 100644 index 00000000..81264d69 --- /dev/null +++ b/src/ytdl_sub/prebuilt_presets/helpers/throttle_protection.yaml @@ -0,0 +1,26 @@ +presets: + + _throttle_protection: + throttle_protection: + enable: >- + { + %print( + %if( + enable_throttle_protection, + "Throttle protection is enabled. Disable using the override variable `enable_throttle_protection: False`", + "Throttle protection is disabled. Use at your own risk!" + ), + enable_throttle_protection + ) + } + sleep_per_request_s: + min: 3.5 + max: 3.5 + sleep_per_download_s: + min: 13.8 + max: 28.4 + sleep_per_subscription_s: + min: 16.3 + max: 26.1 + overrides: + enable_throttle_protection: True \ No newline at end of file diff --git a/src/ytdl_sub/prebuilt_presets/music/singles.yaml b/src/ytdl_sub/prebuilt_presets/music/singles.yaml index dc7b5a25..98675adc 100644 --- a/src/ytdl_sub/prebuilt_presets/music/singles.yaml +++ b/src/ytdl_sub/prebuilt_presets/music/singles.yaml @@ -2,6 +2,11 @@ presets: _music_base: + preset: + # ytdl-sub includes throttle prootection by default or all prebuilt presets. + # Can be disabled with override variable `enable_throttle_protection: False` + - "_throttle_protection" + output_options: output_directory: "{music_directory}" file_name: "{track_full_path}" diff --git a/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml index 25b97697..a0c93c4b 100644 --- a/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml +++ b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml @@ -2,6 +2,9 @@ presets: _music_video_base: preset: + # ytdl-sub includes throttle prootection by default or all prebuilt presets. + # Can be disabled with override variable `enable_throttle_protection: False` + - "_throttle_protection" - "_url_categorized" output_options: diff --git a/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml b/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml index fe39e5cf..de02cfbb 100644 --- a/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml +++ b/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml @@ -3,6 +3,11 @@ presets: #################################################################################################### _episode_base: + preset: + # ytdl-sub includes throttle prootection by default or all prebuilt presets. + # Can be disabled with override variable `enable_throttle_protection: False` + - "_throttle_protection" + output_options: output_directory: "{tv_show_directory}/{tv_show_name_sanitized}" file_name: "{episode_file_path}.{ext}" diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index fbd26c4c..17da55c1 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -15,6 +15,7 @@ from ytdl_sub.downloaders.url.downloader import MultiUrlDownloader from ytdl_sub.downloaders.ytdlp import YTDLP from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.entries.script.variable_definitions import VariableDefinitions +from ytdl_sub.plugins.throttle_protection import ThrottleProtectionPlugin v: VariableDefinitions = VARIABLES @@ -264,6 +265,11 @@ def mock_download_collection_entries( patch.object( MultiUrlDownloader, "_extract_entry_info_with_retry", new=lambda _, entry: entry ), + # Throttle protection is included in all prebuilt presets. Mock the sleep avoid + # actual sleeps + patch.object( + ThrottleProtectionPlugin, "perform_sleep", new=lambda _1, _2: None + ) ): # Stub out metadata. TODO: update this if we do metadata plugins yield