diff --git a/backend/appsettings/serializers.py b/backend/appsettings/serializers.py index f26bc73d..918ec870 100644 --- a/backend/appsettings/serializers.py +++ b/backend/appsettings/serializers.py @@ -59,6 +59,7 @@ class AppConfigDownloadsSerializer( extractor_lang = serializers.CharField(allow_null=True) integrate_ryd = serializers.BooleanField() integrate_sponsorblock = serializers.BooleanField() + stop_on_bot = serializers.BooleanField() class AppConfigAppSerializer( diff --git a/backend/appsettings/src/config.py b/backend/appsettings/src/config.py index 103a59ab..03ee9db0 100644 --- a/backend/appsettings/src/config.py +++ b/backend/appsettings/src/config.py @@ -46,6 +46,7 @@ class DownloadsConfigType(TypedDict): extractor_lang: str | None integrate_ryd: bool integrate_sponsorblock: bool + stop_on_bot: bool class ApplicationConfigType(TypedDict): @@ -95,6 +96,7 @@ class AppConfig: "extractor_lang": None, "integrate_ryd": False, "integrate_sponsorblock": False, + "stop_on_bot": True, }, "application": { "enable_snapshot": True, diff --git a/backend/download/src/yt_dlp_base.py b/backend/download/src/yt_dlp_base.py index 8c416fbd..026374b9 100644 --- a/backend/download/src/yt_dlp_base.py +++ b/backend/download/src/yt_dlp_base.py @@ -94,6 +94,11 @@ class YtWrap: print(f"{url}: failed to download with message {err}") if "Temporary failure in name resolution" in str(err): raise ConnectionError("lost the internet, abort!") from err + if self.config["downloads"].get("stop_on_bot"): + if "not a bot" in str(err): + raise ConnectionError( + "YouTube bot detection, abort!" + ) from err return False, str(err) @@ -122,6 +127,11 @@ class YtWrap: print(f"{url}: failed to get info from youtube: {err}") if "Temporary failure in name resolution" in str(err): raise ConnectionError("lost the internet, abort!") from err + if self.config["downloads"].get("stop_on_bot"): + if "not a bot" in str(err): + raise ConnectionError( + "YouTube bot detection, abort!" + ) from err return None, str(err) diff --git a/frontend/src/api/loader/loadAppsettingsConfig.ts b/frontend/src/api/loader/loadAppsettingsConfig.ts index 47b1ba3a..a3345c3d 100644 --- a/frontend/src/api/loader/loadAppsettingsConfig.ts +++ b/frontend/src/api/loader/loadAppsettingsConfig.ts @@ -27,6 +27,7 @@ export type AppSettingsConfigType = { extractor_lang: string | null; integrate_ryd: boolean; integrate_sponsorblock: boolean; + stop_on_bot: boolean; }; application: { enable_snapshot: boolean; diff --git a/frontend/src/pages/SettingsApplication.tsx b/frontend/src/pages/SettingsApplication.tsx index d5a56e9f..c813988f 100644 --- a/frontend/src/pages/SettingsApplication.tsx +++ b/frontend/src/pages/SettingsApplication.tsx @@ -50,6 +50,7 @@ const SettingsApplication = () => { const [currentThrottledRate, setCurrentThrottledRate] = useState(null); const [currentScrapingSleep, setCurrentScrapingSleep] = useState(null); const [currentAutodelete, setCurrentAutodelete] = useState(null); + const [stopOnBot, setStopOnBot] = useState(true); // Download Format const [downloadsFormat, setDownloadsFormat] = useState(null); @@ -106,6 +107,7 @@ const SettingsApplication = () => { setCurrentThrottledRate(appSettingsConfigData?.downloads.throttledratelimit || null); setCurrentScrapingSleep(appSettingsConfigData?.downloads.sleep_interval || null); setCurrentAutodelete(appSettingsConfigData?.downloads.autodelete_days || null); + setStopOnBot(appSettingsConfigData?.downloads.stop_on_bot ?? true); // Download Format setDownloadsFormat(appSettingsConfigData?.downloads.format || null); @@ -308,6 +310,10 @@ const SettingsApplication = () => {
  • Minimal recommended is 10.
  • +
  • + Stop on bot detection will stop the download queue when YT returns a bot + detection error instead of continuing to fail every remaining video. +
  • Auto delete deletes videos marked as watched after x days.
      @@ -357,6 +363,16 @@ const SettingsApplication = () => { updateCallback={handleUpdateConfig} /> +
      +
      +

      Stop queue on bot detection

      +
      + +

      diff --git a/frontend/src/stores/AppSettingsStore.ts b/frontend/src/stores/AppSettingsStore.ts index 1f8654e2..0a508a82 100644 --- a/frontend/src/stores/AppSettingsStore.ts +++ b/frontend/src/stores/AppSettingsStore.ts @@ -34,6 +34,7 @@ export const useAppSettingsStore = create(set => ({ extractor_lang: null, integrate_ryd: false, integrate_sponsorblock: false, + stop_on_bot: true, }, application: { enable_snapshot: false,