From 9afca46c5d93d060609ce4269658a87050c7a99d Mon Sep 17 00:00:00 2001 From: oop7 <110548351+oop7@users.noreply.github.com> Date: Thu, 12 Mar 2026 11:10:10 +0200 Subject: [PATCH] Add generic-mode URL validation and UI Introduce a "generic_mode" option to allow validating/downloading from non-YouTube sites and wire it through the UI, config, and validation logic. Key changes: - Add generic_mode default to ConfigManager and persist setting from DownloadSettingsDialog (checkbox + help text). - Extend validate_video_url to accept a generic_mode flag and allow any http/https URL with a domain when enabled; pass this flag from Analysis and Download flows. - Update YTSageApp to load/save generic_mode, update URL placeholder and settings tooltip behavior, and refresh tooltip when settings change. - Improve robustness in FormatTableMixin: handle None/incorrect types for format_note, abr, resolution, ext, and codec values to avoid type errors and ensure consistent display. - Add localization entries for generic mode, placeholder, and related help text across multiple language files and update the in-app default localization strings. These changes enable broader site support via yt-dlp while hardening UI format handling and keeping user settings persistent. --- ytsage/core/ytsage_utils.py | 10 +++- ytsage/gui/ytsage_gui_analysis.py | 2 +- .../ytsage_dialogs_settings.py | 24 ++++++++ ytsage/gui/ytsage_gui_format_table.py | 22 +++++--- ytsage/gui/ytsage_gui_main.py | 56 ++++++++++++------- ytsage/languages/ar.json | 4 ++ ytsage/languages/de.json | 4 ++ ytsage/languages/en.json | 4 ++ ytsage/languages/es.json | 4 ++ ytsage/languages/fr.json | 4 ++ ytsage/languages/hi.json | 4 ++ ytsage/languages/id.json | 4 ++ ytsage/languages/it.json | 4 ++ ytsage/languages/ja.json | 4 ++ ytsage/languages/pl.json | 4 ++ ytsage/languages/pt.json | 4 ++ ytsage/languages/ru.json | 4 ++ ytsage/languages/tr.json | 4 ++ ytsage/languages/zh.json | 4 ++ ytsage/utils/ytsage_config_manager.py | 1 + ytsage/utils/ytsage_localization.py | 11 ++++ 21 files changed, 152 insertions(+), 30 deletions(-) diff --git a/ytsage/core/ytsage_utils.py b/ytsage/core/ytsage_utils.py index 73ee865..bea2cd6 100644 --- a/ytsage/core/ytsage_utils.py +++ b/ytsage/core/ytsage_utils.py @@ -731,7 +731,7 @@ def parse_yt_dlp_error(error_message: str) -> str: return _("ytdlp_errors.generic_error", error=error_message) -def validate_video_url(url: str) -> tuple[bool, str]: +def validate_video_url(url: str, generic_mode: bool = False) -> tuple[bool, str]: """ Validate a video URL for supported platforms. @@ -743,6 +743,10 @@ def validate_video_url(url: str) -> tuple[bool, str]: - is_valid: True if URL is valid, False otherwise - error_message: Empty string if valid, error description if invalid + Args: + url: URL entered by the user. + generic_mode: When True, allow any http/https URL with a valid domain. + Example: >>> is_valid, error = validate_video_url("https://youtube.com/watch?v=xxx") >>> if not is_valid: @@ -770,6 +774,10 @@ def validate_video_url(url: str) -> tuple[bool, str]: # Check if netloc (domain) exists if not parsed.netloc: return False, _("url_validation.missing_domain") + + if generic_mode: + logger.info(f"Generic mode enabled, allowing URL: {url}") + return True, "" # YTSage focuses on YouTube and YouTube Music only # Supported YouTube domains diff --git a/ytsage/gui/ytsage_gui_analysis.py b/ytsage/gui/ytsage_gui_analysis.py index 58b6308..e05ee70 100644 --- a/ytsage/gui/ytsage_gui_analysis.py +++ b/ytsage/gui/ytsage_gui_analysis.py @@ -287,7 +287,7 @@ class AnalysisMixin: return # Validate URL before processing - is_valid, error_message = validate_video_url(url) + is_valid, error_message = validate_video_url(url, generic_mode=self.generic_mode_enabled) if not is_valid: QMessageBox.warning(self, _("main_ui.error_title"), error_message) if hasattr(self, "animate_widget_shake"): diff --git a/ytsage/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py b/ytsage/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py index 0f69956..6e78e6a 100644 --- a/ytsage/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py +++ b/ytsage/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py @@ -195,6 +195,24 @@ class DownloadSettingsDialog(QDialog): speed_group_box.setLayout(speed_layout) layout.addWidget(speed_group_box) + # --- Generic Mode Section --- + generic_mode_group_box = QGroupBox(_("settings.generic_mode")) + generic_mode_layout = QVBoxLayout() + + self.generic_mode_enabled = ConfigManager.get("generic_mode") or False + + self.generic_mode_checkbox = QCheckBox(_("settings.enable_generic_mode")) + self.generic_mode_checkbox.setChecked(self.generic_mode_enabled) + generic_mode_layout.addWidget(self.generic_mode_checkbox) + + generic_mode_help_label = QLabel(_("settings.generic_mode_help")) + generic_mode_help_label.setWordWrap(True) + generic_mode_help_label.setStyleSheet("color: #cccccc; margin: 5px; font-size: 11px;") + generic_mode_layout.addWidget(generic_mode_help_label) + + generic_mode_group_box.setLayout(generic_mode_layout) + layout.addWidget(generic_mode_group_box) + # --- Output Format Settings Section --- output_format_group_box = QGroupBox(_("settings.output_format_settings")) output_format_layout = QVBoxLayout() @@ -349,6 +367,10 @@ class DownloadSettingsDialog(QDialog): """Returns whether force output format is enabled.""" return self.force_format_checkbox.isChecked() + def get_generic_mode_enabled(self) -> bool: + """Returns whether generic mode is enabled.""" + return self.generic_mode_checkbox.isChecked() + def get_preferred_format(self) -> str: """Returns the selected preferred format (lowercase).""" format_map = {0: "mp4", 1: "webm", 2: "mkv"} @@ -405,6 +427,8 @@ class DownloadSettingsDialog(QDialog): def accept(self) -> None: """Override accept to save format settings.""" try: + ConfigManager.set("generic_mode", self.get_generic_mode_enabled()) + # Save output format settings force_format = self.get_force_format_enabled() preferred_format = self.get_preferred_format() diff --git a/ytsage/gui/ytsage_gui_format_table.py b/ytsage/gui/ytsage_gui_format_table.py index cd3f029..524a350 100644 --- a/ytsage/gui/ytsage_gui_format_table.py +++ b/ytsage/gui/ytsage_gui_format_table.py @@ -207,7 +207,7 @@ class FormatTableMixin: audio_formats = [ f for f in self.all_formats - if (f.get("vcodec") == "none" or "audio only" in f.get("format_note", "").lower()) + if (f.get("vcodec") == "none" or "audio only" in str(f.get("format_note") or "").lower()) and f.get("acodec") != "none" and f.get("filesize") is not None ] @@ -224,7 +224,8 @@ class FormatTableMixin: except (ValueError, IndexError): return 0 else: - return f.get("abr", 0) + abr = f.get("abr") or 0 + return abr if isinstance(abr, (int, float)) else 0 video_formats.sort(key=get_quality, reverse=True) audio_formats.sort(key=get_quality, reverse=True) @@ -320,7 +321,9 @@ class FormatTableMixin: self.format_table.setItem(row, 1, quality_item) # Resolution - resolution = f.get("resolution", "N/A") + resolution = f.get("resolution") or "N/A" + if not isinstance(resolution, str): + resolution = str(resolution) if is_playlist_mode: # Column 2 for playlist mode: Resolution @@ -361,7 +364,8 @@ class FormatTableMixin: self.format_table.setItem(row, 4, hdr_item) else: # Extension for normal mode (column 2) - self.format_table.setItem(row, 2, QTableWidgetItem(f.get("ext", "").upper())) + extension = str(f.get("ext") or "") + self.format_table.setItem(row, 2, QTableWidgetItem(extension.upper())) # Audio Status column needs_audio = f.get("acodec") == "none" and f.get("vcodec") != "none" @@ -387,11 +391,11 @@ class FormatTableMixin: # Column 5: Codec if f.get("vcodec") == "none": - codec = f.get("acodec", "N/A") + codec = str(f.get("acodec") or "N/A") else: - codec = f"{f.get('vcodec', 'N/A')}" + codec = str(f.get("vcodec") or "N/A") if f.get("acodec") != "none": - codec += f" / {f.get('acodec', 'N/A')}" + codec += f" / {str(f.get('acodec') or 'N/A')}" self.format_table.setItem(row, 5, QTableWidgetItem(codec)) # Column 7: FPS (Frame Rate) @@ -469,7 +473,9 @@ class FormatTableMixin: if format_info.get("vcodec") == "none": # Audio quality - abr = format_info.get("abr", 0) + abr = format_info.get("abr") or 0 + if not isinstance(abr, (int, float)): + abr = 0 if abr >= 256: return _("formats.best_audio") elif abr >= 192: diff --git a/ytsage/gui/ytsage_gui_main.py b/ytsage/gui/ytsage_gui_main.py index 250338c..61a66aa 100644 --- a/ytsage/gui/ytsage_gui_main.py +++ b/ytsage/gui/ytsage_gui_main.py @@ -257,6 +257,7 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin, AnalysisMixin): self.preferred_output_format = ConfigManager.get("preferred_output_format") or "mp4" self.force_audio_format = ConfigManager.get("force_audio_format") or False self.preferred_audio_format = ConfigManager.get("preferred_audio_format") or "best" + self.generic_mode_enabled = ConfigManager.get("generic_mode") or False # Track if video analysis is completed self.analysis_completed = False @@ -351,7 +352,7 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin, AnalysisMixin): url_layout.setSpacing(10) self.url_input = QLineEdit() - self.url_input.setPlaceholderText(_("main_ui.url_placeholder")) + self._update_url_placeholder() self.url_input.returnPressed.connect(self.analyze_url) # Analyze on Enter key self.url_input.textChanged.connect(self._on_url_text_changed) # Enable/disable analyze button self.url_input.setMinimumHeight(42) @@ -489,13 +490,7 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin, AnalysisMixin): # --- Rename Path Button to Settings Button --- self.settings_button = QPushButton(_("buttons.download_settings")) # Renamed button self.settings_button.clicked.connect(self.show_download_settings_dialog) # Renamed method - self.settings_button.setToolTip( - _( - "main_ui.settings_tooltip", - path=self.last_path, - speed_limit=_("main_ui.speed_limit_none"), - ) - ) # Update initial tooltip + self._update_settings_tooltip() # --- End Settings Button --- self.download_btn = QPushButton(_("buttons.download")) @@ -581,6 +576,27 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin, AnalysisMixin): """Enable or disable the Analyze button based on URL input content.""" self.analyze_button.setEnabled(bool(text.strip())) + def _get_speed_limit_tooltip_text(self) -> str: + """Return the current speed limit string for the settings tooltip.""" + if self.speed_limit_value: + return f"{self.speed_limit_value} {['KB/s', 'MB/s'][self.speed_limit_unit_index]}" + return _("main_ui.speed_limit_none") + + def _update_settings_tooltip(self) -> None: + """Refresh the download settings tooltip text.""" + self.settings_button.setToolTip( + _( + "main_ui.settings_tooltip", + path=self.last_path, + speed_limit=self._get_speed_limit_tooltip_text(), + ) + ) + + def _update_url_placeholder(self) -> None: + """Update the URL placeholder based on the selected validation mode.""" + placeholder_key = "main_ui.url_placeholder_generic" if self.generic_mode_enabled else "main_ui.url_placeholder" + self.url_input.setPlaceholderText(_(placeholder_key)) + def paste_url(self) -> None: @@ -631,18 +647,18 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin, AnalysisMixin): audio_format_changed = True logger.info(f"Audio format settings updated - Force: {self.force_audio_format}, Preferred: {self.preferred_audio_format}") + # Update Generic Mode Setting + new_generic_mode = dialog.get_generic_mode_enabled() + generic_mode_changed = False + if new_generic_mode != self.generic_mode_enabled: + self.generic_mode_enabled = new_generic_mode + generic_mode_changed = True + self._update_url_placeholder() + logger.info(f"Generic mode updated - Enabled: {self.generic_mode_enabled}") + # Update Tooltip if anything changed - if path_changed or limit_changed or format_changed or audio_format_changed: - limit_text = _("main_ui.speed_limit_none") - if self.speed_limit_value: - limit_text = f"{self.speed_limit_value} {['KB/s', 'MB/s'][self.speed_limit_unit_index]}" - self.settings_button.setToolTip( - _( - "main_ui.settings_tooltip", - path=self.last_path, - speed_limit=limit_text, - ) - ) + if path_changed or limit_changed or format_changed or audio_format_changed or generic_mode_changed: + self._update_settings_tooltip() def start_download(self) -> None: if self.is_updating_ytdlp: @@ -669,7 +685,7 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin, AnalysisMixin): # --- End Path Change --- # Validate URL before starting download - is_valid, error_message = validate_video_url(url) + is_valid, error_message = validate_video_url(url, generic_mode=self.generic_mode_enabled) if not is_valid: QMessageBox.warning(self, _("main_ui.error_title"), error_message) self.animate_widget_shake(self.url_input) diff --git a/ytsage/languages/ar.json b/ytsage/languages/ar.json index 810da58..bce5935 100644 --- a/ytsage/languages/ar.json +++ b/ytsage/languages/ar.json @@ -274,6 +274,9 @@ "browse": "تصفح...", "speed_limit": "حد السرعة", "speed_limit_placeholder": "بدون", + "generic_mode": "الوضع العام", + "enable_generic_mode": "تفعيل الوضع العام (دعم المواقع غير التابعة ليوتيوب)", + "generic_mode_help": "يسمح بالتنزيل من Dailymotion وCBC Gem ومواقع أخرى يدعمها yt-dlp.", "auto_update_ytdlp": "التحديثات التلقائية لـ yt-dlp", "enable_auto_updates": "تفعيل التحديثات التلقائية لـ yt-dlp", "update_frequency": "تكرار التحديثات:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "أدخل رابط فيديو يوتيوب أو قائمة تشغيل", + "url_placeholder_generic": "أدخل رابط فيديو أو قائمة تشغيل من أي موقع مدعوم", "merge_subtitles": "دمج الترجمات", "save_thumbnail": "حفظ الصورة المصغرة", "save_description": "حفظ الوصف", diff --git a/ytsage/languages/de.json b/ytsage/languages/de.json index af55e32..8f7d7a5 100644 --- a/ytsage/languages/de.json +++ b/ytsage/languages/de.json @@ -274,6 +274,9 @@ "browse": "Durchsuchen...", "speed_limit": "Geschwindigkeitsbegrenzung", "speed_limit_placeholder": "Keine", + "generic_mode": "Generischer Modus", + "enable_generic_mode": "Generischen Modus aktivieren (Unterstützung für Nicht-YouTube-Seiten)", + "generic_mode_help": "Ermöglicht Downloads von Dailymotion, CBC Gem und anderen von yt-dlp unterstützten Seiten.", "auto_update_ytdlp": "yt-dlp automatisch aktualisieren", "enable_auto_updates": "Automatische yt-dlp-Updates aktivieren", "update_frequency": "Update-Häufigkeit:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "YouTube-Video- oder Playlist-URL eingeben", + "url_placeholder_generic": "Video- oder Playlist-URL von jeder unterstützten Seite eingeben", "merge_subtitles": "Untertitel zusammenführen", "save_thumbnail": "Thumbnail speichern", "save_description": "Beschreibung speichern", diff --git a/ytsage/languages/en.json b/ytsage/languages/en.json index b275ac4..a98751d 100644 --- a/ytsage/languages/en.json +++ b/ytsage/languages/en.json @@ -275,6 +275,9 @@ "browse": "Browse...", "speed_limit": "Speed Limit", "speed_limit_placeholder": "None", + "generic_mode": "Generic Mode", + "enable_generic_mode": "Enable Generic Mode (support non-YouTube sites)", + "generic_mode_help": "Allows downloading from Dailymotion, CBC Gem, and other sites supported by yt-dlp.", "auto_update_ytdlp": "Auto-Update yt-dlp", "enable_auto_updates": "Enable automatic yt-dlp updates", "update_frequency": "Update frequency:", @@ -338,6 +341,7 @@ }, "main_ui": { "url_placeholder": "Enter YouTube video or playlist URL", + "url_placeholder_generic": "Enter video or playlist URL from any supported site", "merge_subtitles": "Merge Subtitles", "save_thumbnail": "Save Thumbnail", "save_description": "Save Description", diff --git a/ytsage/languages/es.json b/ytsage/languages/es.json index aa05646..974dc59 100644 --- a/ytsage/languages/es.json +++ b/ytsage/languages/es.json @@ -257,6 +257,9 @@ "browse": "Examinar...", "speed_limit": "Límite de Velocidad", "speed_limit_placeholder": "Ninguno", + "generic_mode": "Modo genérico", + "enable_generic_mode": "Habilitar modo genérico (compatibilidad con sitios que no son YouTube)", + "generic_mode_help": "Permite descargar desde Dailymotion, CBC Gem y otros sitios compatibles con yt-dlp.", "auto_update_ytdlp": "Auto-Actualizar yt-dlp", "enable_auto_updates": "Habilitar actualizaciones automáticas de yt-dlp", "update_frequency": "Frecuencia de actualización:", @@ -320,6 +323,7 @@ }, "main_ui": { "url_placeholder": "Ingresa URL de video o lista de YouTube", + "url_placeholder_generic": "Ingresa la URL de un video o una lista de cualquier sitio compatible", "merge_subtitles": "Combinar Subtítulos", "save_thumbnail": "Guardar Miniatura", "save_description": "Guardar Descripción", diff --git a/ytsage/languages/fr.json b/ytsage/languages/fr.json index 75bae7a..997889a 100644 --- a/ytsage/languages/fr.json +++ b/ytsage/languages/fr.json @@ -274,6 +274,9 @@ "browse": "Parcourir...", "speed_limit": "Limite de vitesse", "speed_limit_placeholder": "Aucune", + "generic_mode": "Mode générique", + "enable_generic_mode": "Activer le mode générique (prise en charge des sites non-YouTube)", + "generic_mode_help": "Permet le téléchargement depuis Dailymotion, CBC Gem et d'autres sites pris en charge par yt-dlp.", "auto_update_ytdlp": "Mise à jour automatique de yt-dlp", "enable_auto_updates": "Activer les mises à jour automatiques de yt-dlp", "update_frequency": "Fréquence de mise à jour :", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "Entrer l'URL de la vidéo ou de la playlist YouTube", + "url_placeholder_generic": "Entrez l'URL d'une vidéo ou d'une playlist depuis n'importe quel site pris en charge", "merge_subtitles": "Fusionner les sous-titres", "save_thumbnail": "Sauvegarder la miniature", "save_description": "Sauvegarder la description", diff --git a/ytsage/languages/hi.json b/ytsage/languages/hi.json index aa258fc..ef43692 100644 --- a/ytsage/languages/hi.json +++ b/ytsage/languages/hi.json @@ -274,6 +274,9 @@ "browse": "ब्राउज़ करें...", "speed_limit": "गति सीमा", "speed_limit_placeholder": "कोई नहीं", + "generic_mode": "जेनेरिक मोड", + "enable_generic_mode": "जेनेरिक मोड सक्षम करें (गैर-YouTube साइटों के लिए समर्थन)", + "generic_mode_help": "Dailymotion, CBC Gem और yt-dlp द्वारा समर्थित अन्य साइटों से डाउनलोड की अनुमति देता है।", "auto_update_ytdlp": "yt-dlp स्वचालित अपडेट", "enable_auto_updates": "yt-dlp स्वचालित अपडेट सक्षम करें", "update_frequency": "अपडेट आवृत्ति:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "YouTube वीडियो या प्लेलिस्ट URL दर्ज करें", + "url_placeholder_generic": "किसी भी समर्थित साइट से वीडियो या प्लेलिस्ट URL दर्ज करें", "merge_subtitles": "उपशीर्षक मर्ज करें", "save_thumbnail": "थंबनेल सेव करें", "save_description": "विवरण सेव करें", diff --git a/ytsage/languages/id.json b/ytsage/languages/id.json index ef68be8..97a3f5b 100644 --- a/ytsage/languages/id.json +++ b/ytsage/languages/id.json @@ -274,6 +274,9 @@ "browse": "Jelajahi...", "speed_limit": "Batas kecepatan", "speed_limit_placeholder": "Tidak ada", + "generic_mode": "Mode generik", + "enable_generic_mode": "Aktifkan mode generik (mendukung situs non-YouTube)", + "generic_mode_help": "Memungkinkan pengunduhan dari Dailymotion, CBC Gem, dan situs lain yang didukung oleh yt-dlp.", "auto_update_ytdlp": "Pembaruan otomatis yt-dlp", "enable_auto_updates": "Aktifkan pembaruan otomatis yt-dlp", "update_frequency": "Frekuensi pembaruan:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "Masukkan URL video atau playlist YouTube", + "url_placeholder_generic": "Masukkan URL video atau playlist dari situs apa pun yang didukung", "merge_subtitles": "Gabungkan subtitle", "save_thumbnail": "Simpan thumbnail", "save_description": "Simpan deskripsi", diff --git a/ytsage/languages/it.json b/ytsage/languages/it.json index 2e5e647..24026f4 100644 --- a/ytsage/languages/it.json +++ b/ytsage/languages/it.json @@ -274,6 +274,9 @@ "browse": "Sfoglia...", "speed_limit": "Limite velocità", "speed_limit_placeholder": "Nessuno", + "generic_mode": "Modalità generica", + "enable_generic_mode": "Abilita modalità generica (supporta siti non YouTube)", + "generic_mode_help": "Consente il download da Dailymotion, CBC Gem e altri siti supportati da yt-dlp.", "auto_update_ytdlp": "Aggiornamenti automatici yt-dlp", "enable_auto_updates": "Abilita aggiornamenti automatici yt-dlp", "update_frequency": "Frequenza aggiornamenti:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "Inserisci URL video YouTube o playlist", + "url_placeholder_generic": "Inserisci l'URL di un video o di una playlist da qualsiasi sito supportato", "merge_subtitles": "Unisci sottotitoli", "save_thumbnail": "Salva miniatura", "save_description": "Salva descrizione", diff --git a/ytsage/languages/ja.json b/ytsage/languages/ja.json index 4a71ee5..0520b44 100644 --- a/ytsage/languages/ja.json +++ b/ytsage/languages/ja.json @@ -274,6 +274,9 @@ "browse": "参照...", "speed_limit": "速度制限", "speed_limit_placeholder": "なし", + "generic_mode": "汎用モード", + "enable_generic_mode": "汎用モードを有効化(YouTube以外のサイトをサポート)", + "generic_mode_help": "Dailymotion、CBC Gem、および yt-dlp が対応する他のサイトからのダウンロードを可能にします。", "auto_update_ytdlp": "yt-dlp自動更新", "enable_auto_updates": "yt-dlp自動更新を有効化", "update_frequency": "更新頻度:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "YouTubeの動画URLまたはプレイリストURLを入力", + "url_placeholder_generic": "対応サイトの動画またはプレイリストURLを入力", "merge_subtitles": "字幕を結合", "save_thumbnail": "サムネイルを保存", "save_description": "説明を保存", diff --git a/ytsage/languages/pl.json b/ytsage/languages/pl.json index 5b38dec..229e5df 100644 --- a/ytsage/languages/pl.json +++ b/ytsage/languages/pl.json @@ -274,6 +274,9 @@ "browse": "Przeglądaj...", "speed_limit": "Limit prędkości", "speed_limit_placeholder": "Brak", + "generic_mode": "Tryb ogólny", + "enable_generic_mode": "Włącz tryb ogólny (obsługa stron innych niż YouTube)", + "generic_mode_help": "Umożliwia pobieranie z Dailymotion, CBC Gem i innych stron obsługiwanych przez yt-dlp.", "auto_update_ytdlp": "Automatyczne aktualizacje yt-dlp", "enable_auto_updates": "Włącz automatyczne aktualizacje yt-dlp", "update_frequency": "Częstotliwość aktualizacji:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "Wprowadź URL wideo YouTube lub playlisty", + "url_placeholder_generic": "Wprowadź URL filmu lub playlisty z dowolnej obsługiwanej strony", "merge_subtitles": "Połącz napisy", "save_thumbnail": "Zapisz miniaturę", "save_description": "Zapisz opis", diff --git a/ytsage/languages/pt.json b/ytsage/languages/pt.json index da43811..e6f39aa 100644 --- a/ytsage/languages/pt.json +++ b/ytsage/languages/pt.json @@ -274,6 +274,9 @@ "browse": "Procurar...", "speed_limit": "Limite de Velocidade", "speed_limit_placeholder": "Nenhum", + "generic_mode": "Modo genérico", + "enable_generic_mode": "Ativar modo genérico (suporte a sites que não são do YouTube)", + "generic_mode_help": "Permite baixar de Dailymotion, CBC Gem e outros sites compatíveis com o yt-dlp.", "auto_update_ytdlp": "Auto-Atualizar yt-dlp", "enable_auto_updates": "Habilitar atualizações automáticas do yt-dlp", "update_frequency": "Frequência de atualização:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "Digite a URL do vídeo ou playlist do YouTube", + "url_placeholder_generic": "Digite a URL de um vídeo ou playlist de qualquer site compatível", "merge_subtitles": "Mesclar Legendas", "save_thumbnail": "Salvar Miniatura", "save_description": "Salvar Descrição", diff --git a/ytsage/languages/ru.json b/ytsage/languages/ru.json index 5fcaf7b..fb88854 100644 --- a/ytsage/languages/ru.json +++ b/ytsage/languages/ru.json @@ -274,6 +274,9 @@ "browse": "Обзор...", "speed_limit": "Ограничение скорости", "speed_limit_placeholder": "Нет", + "generic_mode": "Универсальный режим", + "enable_generic_mode": "Включить универсальный режим (поддержка сайтов не только YouTube)", + "generic_mode_help": "Позволяет скачивать с Dailymotion, CBC Gem и других сайтов, поддерживаемых yt-dlp.", "auto_update_ytdlp": "Автообновление yt-dlp", "enable_auto_updates": "Включить автоматические обновления yt-dlp", "update_frequency": "Частота обновления:", @@ -337,6 +340,7 @@ }, "main_ui": { "url_placeholder": "Введите URL видео или плейлиста YouTube", + "url_placeholder_generic": "Введите URL видео или плейлиста с любого поддерживаемого сайта", "merge_subtitles": "Объединить субтитры", "save_thumbnail": "Сохранить миниатюру", "save_description": "Сохранить описание", diff --git a/ytsage/languages/tr.json b/ytsage/languages/tr.json index fd3138a..11599f3 100644 --- a/ytsage/languages/tr.json +++ b/ytsage/languages/tr.json @@ -272,6 +272,9 @@ "browse": "Gözat...", "speed_limit": "Hız sınırı", "speed_limit_placeholder": "Yok", + "generic_mode": "Genel mod", + "enable_generic_mode": "Genel modu etkinleştir (YouTube dışı siteleri destekle)", + "generic_mode_help": "Dailymotion, CBC Gem ve yt-dlp tarafından desteklenen diğer sitelerden indirmeye izin verir.", "auto_update_ytdlp": "yt-dlp otomatik güncelleme", "enable_auto_updates": "yt-dlp otomatik güncellemelerini etkinleştir", "update_frequency": "Güncelleme sıklığı:", @@ -335,6 +338,7 @@ }, "main_ui": { "url_placeholder": "YouTube video veya oynatma listesi URL'sini girin", + "url_placeholder_generic": "Desteklenen herhangi bir siteden video veya oynatma listesi URL'si girin", "merge_subtitles": "Altyazıları birleştir", "save_thumbnail": "Küçük resmi kaydet", "save_description": "Açıklamayı kaydet", diff --git a/ytsage/languages/zh.json b/ytsage/languages/zh.json index 3480e70..c95c01e 100644 --- a/ytsage/languages/zh.json +++ b/ytsage/languages/zh.json @@ -262,6 +262,9 @@ "browse": "浏览...", "speed_limit": "速度限制", "speed_limit_placeholder": "无", + "generic_mode": "通用模式", + "enable_generic_mode": "启用通用模式(支持非 YouTube 网站)", + "generic_mode_help": "允许从 Dailymotion、CBC Gem 以及其他受 yt-dlp 支持的网站下载。", "auto_update_ytdlp": "自动更新 yt-dlp", "enable_auto_updates": "启用 yt-dlp 自动更新", "update_frequency": "更新频率:", @@ -325,6 +328,7 @@ }, "main_ui": { "url_placeholder": "输入 YouTube 视频或播放列表网址", + "url_placeholder_generic": "输入任意受支持网站的视频或播放列表网址", "merge_subtitles": "合并字幕", "save_thumbnail": "保存缩略图", "save_description": "保存描述", diff --git a/ytsage/utils/ytsage_config_manager.py b/ytsage/utils/ytsage_config_manager.py index 4c58d58..fdb2e95 100644 --- a/ytsage/utils/ytsage_config_manager.py +++ b/ytsage/utils/ytsage_config_manager.py @@ -71,6 +71,7 @@ class ConfigManager: _settings: Dict[str, Any] = {} _default_config: Dict[str, Any] = { "download_path": str(USER_HOME_DIR / "Downloads"), + "generic_mode": False, "speed_limit_value": None, "speed_limit_unit_index": 0, "cookie_source": "browser", # "browser" or "file" diff --git a/ytsage/utils/ytsage_localization.py b/ytsage/utils/ytsage_localization.py index 579cd9e..db91723 100644 --- a/ytsage/utils/ytsage_localization.py +++ b/ytsage/utils/ytsage_localization.py @@ -70,12 +70,23 @@ class LocalizationManager: "custom_options": "Custom Options", "settings": "Settings" }, + "settings": { + "generic_mode": "Generic Mode", + "enable_generic_mode": "Enable Generic Mode (support non-YouTube sites)", + "generic_mode_help": "Allows downloading from Dailymotion, CBC Gem, and other sites supported by yt-dlp." + }, "tabs": { "cookies": "Login with Cookies", "custom_command": "Custom Command", "proxy": "Proxy", "language": "Language" }, + "main_ui": { + "url_placeholder": "Enter YouTube video or playlist URL", + "url_placeholder_generic": "Enter video or playlist URL from any supported site", + "settings_tooltip": "Current Path: {path}\nSpeed Limit: {speed_limit}", + "speed_limit_none": "None" + }, "language": { "select_language": "Select Language:", "current_language": "Current language: {language}",