[BACKEND] Enable throttle protection by default (#1257)
To protect new users, all prebuilt preset (excluding Soundcloud and Bandcamp) will include throttle protection by default.
> How do I disable?
Set the override variable `enable_throttle_protection: False`.
This can be done on a per-subscription basis and/or in the top __preset__ section to apply to all presets:
```
__preset__:
overrides:
enable_throttle_protection: False
```
> What if I already use throttle protection?
Your settings will override whatever values are set in the defaults.
Closes:
- https://github.com/jmbannon/ytdl-sub/issues/1121
- https://github.com/jmbannon/ytdl-sub/issues/1186
This commit is contained in:
parent
a055c9b07a
commit
6c180c9478
12 changed files with 64 additions and 10 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -22,4 +22,5 @@ presets:
|
|||
|
||||
"YouTube Full Albums":
|
||||
preset:
|
||||
- "_albums_from_chapters"
|
||||
- "_albums_from_chapters"
|
||||
- "_throttle_protection"
|
||||
|
|
@ -18,6 +18,7 @@ presets:
|
|||
"YouTube Releases":
|
||||
preset:
|
||||
- "_albums_from_playlists"
|
||||
- "_throttle_protection"
|
||||
|
||||
"Bandcamp":
|
||||
preset:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ presets:
|
|||
|
||||
|
||||
_music_base:
|
||||
|
||||
output_options:
|
||||
output_directory: "{music_directory}"
|
||||
file_name: "{track_full_path}"
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ logger = Logger.get(name="preset")
|
|||
|
||||
|
||||
def _log(message: AnyArgument, level: Optional[Integer]) -> None:
|
||||
if not str(message):
|
||||
return
|
||||
|
||||
if level is None:
|
||||
logger.info(str(message))
|
||||
return
|
||||
|
|
|
|||
|
|
@ -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,9 @@ 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
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class TestThrottleProtectionPlugin:
|
|||
assert_logs(
|
||||
logger=throttle_protection_logger,
|
||||
expected_message="Sleeping between downloads for %0.2f seconds",
|
||||
log_level="debug",
|
||||
log_level="info",
|
||||
expected_occurrences=4,
|
||||
),
|
||||
):
|
||||
|
|
@ -68,7 +68,7 @@ class TestThrottleProtectionPlugin:
|
|||
assert_logs(
|
||||
logger=throttle_protection_logger,
|
||||
expected_message="Sleeping between subscriptions for %0.2f seconds",
|
||||
log_level="debug",
|
||||
log_level="info",
|
||||
expected_occurrences=1,
|
||||
),
|
||||
):
|
||||
|
|
@ -92,7 +92,7 @@ class TestThrottleProtectionPlugin:
|
|||
mock_download_collection_entries,
|
||||
disable_value,
|
||||
):
|
||||
throttle_subscription_dict["throttle_protection"]["enable"] = disable_value
|
||||
throttle_subscription_dict["overrides"]["enable_throttle_protection"] = disable_value
|
||||
subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
|
|
@ -106,7 +106,7 @@ class TestThrottleProtectionPlugin:
|
|||
assert_logs(
|
||||
logger=throttle_protection_logger,
|
||||
expected_message="Sleeping between downloads for %0.2f seconds",
|
||||
log_level="debug",
|
||||
log_level="info",
|
||||
expected_occurrences=0,
|
||||
),
|
||||
):
|
||||
|
|
|
|||
|
|
@ -15,12 +15,15 @@ class TestPrintFunctions:
|
|||
("{%print('hi mom', True)}", "hi mom", True),
|
||||
("{%print('this is great', [1, 2, 3])}", "this is great", [1, 2, 3]),
|
||||
("{%print([1, 2], [3, 4])}", "[1, 2]", [3, 4]),
|
||||
("{%print('', True)}", None, True),
|
||||
# print_if_true
|
||||
("{%print_if_true('hi mom', True)}", "hi mom", True),
|
||||
("{%print_if_true('hi mom', False)}", None, False),
|
||||
("{%print_if_true('', True)}", None, True),
|
||||
# print_if_false
|
||||
("{%print_if_false('hi mom', True)}", None, True),
|
||||
("{%print_if_false('hi mom', False)}", "hi mom", False),
|
||||
("{%print_if_false('', True)}", None, True),
|
||||
],
|
||||
)
|
||||
def test_print_functions(
|
||||
|
|
|
|||
Loading…
Reference in a new issue