From 2e302f1d0e6d05b7cee9fa108a28177021e64dcc Mon Sep 17 00:00:00 2001 From: oop7 <110548351+oop7@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:33:25 +0200 Subject: [PATCH] Move yt-dlp auto-update settings to updater tab Refactored auto-update settings for yt-dlp from DownloadSettingsDialog to the UpdaterTabWidget in the Custom Options dialog. Updated logic to use ConfigManager for settings management and ensured settings are saved when the dialog is accepted. This improves separation of concerns and centralizes update-related options. --- src/core/ytsage_utils.py | 21 +-- .../ytsage_dialogs_custom.py | 20 ++- .../ytsage_dialogs_settings.py | 92 +------------ .../ytsage_dialogs_updater.py | 128 +++++++++++++++++- 4 files changed, 164 insertions(+), 97 deletions(-) diff --git a/src/core/ytsage_utils.py b/src/core/ytsage_utils.py index c1e2241..6f273bb 100644 --- a/src/core/ytsage_utils.py +++ b/src/core/ytsage_utils.py @@ -643,21 +643,26 @@ def check_and_update_ytdlp_auto() -> bool: def get_auto_update_settings() -> dict: """Get current auto-update settings from config.""" - config = load_config() + from src.utils.ytsage_config_manager import ConfigManager + + enabled = ConfigManager.get("auto_update_ytdlp") + frequency = ConfigManager.get("auto_update_frequency") + last_check = ConfigManager.get("last_update_check") + return { - "enabled": config.get("auto_update_ytdlp", True), - "frequency": config.get("auto_update_frequency", "daily"), - "last_check": config.get("last_update_check", 0), + "enabled": enabled if enabled is not None else True, + "frequency": frequency if frequency is not None else "daily", + "last_check": last_check if last_check is not None else 0, } def update_auto_update_settings(enabled, frequency) -> bool: """Update auto-update settings in config.""" try: - config = load_config() - config["auto_update_ytdlp"] = enabled - config["auto_update_frequency"] = frequency - save_config(config) + from src.utils.ytsage_config_manager import ConfigManager + + ConfigManager.set("auto_update_ytdlp", enabled) + ConfigManager.set("auto_update_frequency", frequency) return True except Exception as e: logger.exception(f"Error updating auto-update settings: {e}") diff --git a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_custom.py b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_custom.py index 75efe7a..5f14511 100644 --- a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_custom.py +++ b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_custom.py @@ -30,6 +30,7 @@ from PySide6.QtWidgets import ( ) from src.core.ytsage_yt_dlp import get_yt_dlp_path +from src.core.ytsage_utils import update_auto_update_settings from src.utils.ytsage_constants import YTDLP_DOCS_URL from src.utils.ytsage_config_manager import ConfigManager from src.utils.ytsage_localization import LocalizationManager, _ @@ -518,14 +519,14 @@ class CustomOptionsDialog(QDialog): language_layout.addStretch() # === Updater Tab === - updater_tab = UpdaterTabWidget(self) + self.updater_tab = UpdaterTabWidget(self) # Add tabs to the tab widget self.tab_widget.addTab(cookies_tab, _("tabs.cookies")) self.tab_widget.addTab(command_tab, _("tabs.custom_command")) self.tab_widget.addTab(proxy_tab, _("tabs.proxy")) self.tab_widget.addTab(language_tab, _("tabs.language")) - self.tab_widget.addTab(updater_tab, _("tabs.updater")) + self.tab_widget.addTab(self.updater_tab, _("tabs.updater")) # Dialog buttons button_box = QDialogButtonBox() @@ -930,6 +931,21 @@ class CustomOptionsDialog(QDialog): self.restart_notice.setVisible(True) logger.info(f"Language changed to: {selected_lang_code}") + + def accept(self) -> None: + """Override accept to save auto-update settings from the updater tab.""" + logger.info("CustomOptionsDialog.accept() called") + try: + # Save auto-update settings from the updater tab + enabled, frequency = self.updater_tab.get_auto_update_settings() + logger.info(f"Saving auto-update settings: enabled={enabled}, frequency={frequency}") + result = update_auto_update_settings(enabled, frequency) + logger.info(f"Auto-update settings save result: {result}") + except Exception as e: + logger.exception(f"Error saving auto-update settings: {e}") + + # Call the parent accept method to close the dialog + super().accept() class TimeRangeDialog(QDialog): diff --git a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py index 585f07a..4189106 100644 --- a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py +++ b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_settings.py @@ -1,6 +1,6 @@ """ Settings-related dialogs for YTSage application. -Contains dialogs for configuring download settings and auto-update preferences. +Contains dialogs for configuring download settings. """ import threading @@ -27,13 +27,6 @@ from PySide6.QtWidgets import ( QVBoxLayout, ) -from src.core.ytsage_utils import ( - check_and_update_ytdlp_auto, - get_auto_update_settings, - get_ytdlp_version, - update_auto_update_settings, -) -from src.gui.ytsage_gui_dialogs.ytsage_dialogs_update import YTDLPUpdateDialog from src.utils.ytsage_logger import logger from src.utils.ytsage_localization import _ from src.utils.ytsage_config_manager import ConfigManager @@ -241,51 +234,6 @@ class DownloadSettingsDialog(QDialog): output_format_group_box.setLayout(output_format_layout) layout.addWidget(output_format_group_box) - # --- Auto-Update yt-dlp Section --- - auto_update_group_box = QGroupBox(_("settings.auto_update_ytdlp")) - auto_update_layout = QVBoxLayout() - - # Load current auto-update settings - auto_settings = get_auto_update_settings() - - # Enable/Disable auto-update checkbox - self.auto_update_enabled = QCheckBox(_("settings.enable_auto_updates")) - self.auto_update_enabled.setChecked(auto_settings["enabled"]) - auto_update_layout.addWidget(self.auto_update_enabled) - - # Frequency options - frequency_label = QLabel(_("settings.update_frequency")) - frequency_label.setStyleSheet("color: #ffffff; margin-top: 10px;") - auto_update_layout.addWidget(frequency_label) - - self.startup_radio = QRadioButton(_("settings.check_startup")) - self.daily_radio = QRadioButton(_("settings.check_daily")) - self.weekly_radio = QRadioButton(_("settings.check_weekly")) - - # Set current selection based on saved settings - current_frequency = auto_settings["frequency"] - if current_frequency == "startup": - self.startup_radio.setChecked(True) - elif current_frequency == "daily": - self.daily_radio.setChecked(True) - else: # weekly - self.weekly_radio.setChecked(True) - - auto_update_layout.addWidget(self.startup_radio) - auto_update_layout.addWidget(self.daily_radio) - auto_update_layout.addWidget(self.weekly_radio) - - # Test update button - test_update_layout = QHBoxLayout() - test_update_button = QPushButton(_("settings.check_updates_now")) - test_update_button.clicked.connect(self.test_update_check) - test_update_layout.addWidget(test_update_button) - test_update_layout.addStretch() - auto_update_layout.addLayout(test_update_layout) - - auto_update_group_box.setLayout(auto_update_layout) - layout.addWidget(auto_update_group_box) - # Dialog buttons (OK/Cancel) button_box = QDialogButtonBox() ok_button = button_box.addButton(_("buttons.ok"), QDialogButtonBox.ButtonRole.AcceptRole) @@ -364,46 +312,20 @@ class DownloadSettingsDialog(QDialog): ) return msg_box - def test_update_check(self) -> None: - """Open the yt-dlp update dialog with proper progress tracking.""" - # Create and show the update dialog (non-modal to prevent blocking) - dialog = YTDLPUpdateDialog(self) - dialog.setModal(False) # Make it non-modal - dialog.show() # Use show() instead of exec() to avoid blocking - - def get_auto_update_settings(self) -> tuple[bool, str]: - """Returns the auto-update settings from the dialog.""" - enabled = self.auto_update_enabled.isChecked() - - if self.startup_radio.isChecked(): - frequency = "startup" - elif self.daily_radio.isChecked(): - frequency = "daily" - else: # weekly_radio is checked - frequency = "weekly" - - return enabled, frequency - def accept(self) -> None: - """Override accept to save auto-update and format settings.""" + """Override accept to save format settings.""" try: - # Save auto-update settings - enabled, frequency = self.get_auto_update_settings() - # Save output format settings force_format = self.get_force_format_enabled() preferred_format = self.get_preferred_format() ConfigManager.set("force_output_format", force_format) ConfigManager.set("preferred_output_format", preferred_format) - if update_auto_update_settings(enabled, frequency): - QMessageBox.information( - self, - _("settings.settings_saved_title"), - _("settings.settings_saved_message"), - ) - else: - QMessageBox.warning(self, _("settings.error_title"), _("settings.failed_save_settings")) + QMessageBox.information( + self, + _("settings.settings_saved_title"), + _("settings.settings_saved_message"), + ) except Exception as e: QMessageBox.critical(self, _("settings.error_title"), _("settings.error_saving_settings", error=str(e))) diff --git a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py index e3e7d2f..125142d 100644 --- a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py +++ b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py @@ -1,6 +1,6 @@ """ Updater tab for Custom Options dialog. -Handles checking for and installing FFmpeg updates. +Handles checking for and installing FFmpeg updates and yt-dlp auto-update settings. """ import threading @@ -8,16 +8,23 @@ from typing import TYPE_CHECKING, cast from PySide6.QtCore import QObject, Signal from PySide6.QtWidgets import ( + QCheckBox, QGroupBox, QHBoxLayout, QLabel, QProgressBar, QPushButton, + QRadioButton, QTextEdit, QVBoxLayout, QWidget, ) +from src.core.ytsage_utils import ( + get_auto_update_settings, + update_auto_update_settings, +) +from src.gui.ytsage_gui_dialogs.ytsage_dialogs_update import YTDLPUpdateDialog from src.utils.ytsage_localization import _ from src.utils.ytsage_logger import logger from src.core.ytsage_ffmpeg_updater import check_ffmpeg_update_available, update_ffmpeg @@ -66,6 +73,7 @@ class UpdaterTabWidget(QWidget): self.update_available = False self._init_ui() + self._load_auto_update_settings() def _init_ui(self) -> None: """Initialize the UI components.""" @@ -207,7 +215,8 @@ class UpdaterTabWidget(QWidget): self.log_output = QTextEdit() self.log_output.setReadOnly(True) self.log_output.setPlaceholderText("Update logs will appear here...") - self.log_output.setMinimumHeight(150) + self.log_output.setMinimumHeight(80) + self.log_output.setMaximumHeight(120) self.log_output.setStyleSheet( """ QTextEdit { @@ -224,8 +233,123 @@ class UpdaterTabWidget(QWidget): ffmpeg_layout.addWidget(self.log_output) layout.addWidget(ffmpeg_group) + + # === Auto-Update yt-dlp Section === + auto_update_group_box = QGroupBox(_("settings.auto_update_ytdlp")) + auto_update_layout = QVBoxLayout() + + # Enable/Disable auto-update checkbox + self.auto_update_enabled = QCheckBox(_("settings.enable_auto_updates")) + auto_update_layout.addWidget(self.auto_update_enabled) + + # Frequency options + frequency_label = QLabel(_("settings.update_frequency")) + frequency_label.setStyleSheet("color: #ffffff; margin-top: 10px;") + auto_update_layout.addWidget(frequency_label) + + self.startup_radio = QRadioButton(_("settings.check_startup")) + self.daily_radio = QRadioButton(_("settings.check_daily")) + self.weekly_radio = QRadioButton(_("settings.check_weekly")) + + self.startup_radio.setStyleSheet( + """ + QRadioButton { + color: #ffffff; + spacing: 5px; + } + QRadioButton::indicator { + width: 18px; + height: 18px; + border-radius: 9px; + } + QRadioButton::indicator:unchecked { + border: 2px solid #666666; + background: #15181b; + } + QRadioButton::indicator:checked { + border: 2px solid #c90000; + background: #c90000; + } + """ + ) + self.daily_radio.setStyleSheet(self.startup_radio.styleSheet()) + self.weekly_radio.setStyleSheet(self.startup_radio.styleSheet()) + + auto_update_layout.addWidget(self.startup_radio) + auto_update_layout.addWidget(self.daily_radio) + auto_update_layout.addWidget(self.weekly_radio) + + # Test update button + test_update_layout = QHBoxLayout() + test_update_button = QPushButton(_("settings.check_updates_now")) + test_update_button.clicked.connect(self.test_update_check) + test_update_button.setStyleSheet( + """ + QPushButton { + padding: 8px 15px; + background-color: #c90000; + border: none; + border-radius: 4px; + color: white; + font-weight: bold; + min-width: 120px; + } + QPushButton:hover { + background-color: #a50000; + } + QPushButton:pressed { + background-color: #800000; + } + """ + ) + test_update_layout.addWidget(test_update_button) + test_update_layout.addStretch() + auto_update_layout.addLayout(test_update_layout) + + auto_update_group_box.setLayout(auto_update_layout) + layout.addWidget(auto_update_group_box) + layout.addStretch() + def _load_auto_update_settings(self) -> None: + """Load current auto-update settings for yt-dlp.""" + try: + auto_settings = get_auto_update_settings() + + # Set checkbox + self.auto_update_enabled.setChecked(auto_settings["enabled"]) + + # Set current selection based on saved settings + current_frequency = auto_settings["frequency"] + if current_frequency == "startup": + self.startup_radio.setChecked(True) + elif current_frequency == "daily": + self.daily_radio.setChecked(True) + else: # weekly + self.weekly_radio.setChecked(True) + except Exception as e: + logger.exception(f"Error loading auto-update settings: {e}") + + def get_auto_update_settings(self) -> tuple[bool, str]: + """Returns the auto-update settings from the dialog.""" + enabled = self.auto_update_enabled.isChecked() + + if self.startup_radio.isChecked(): + frequency = "startup" + elif self.daily_radio.isChecked(): + frequency = "daily" + else: # weekly_radio is checked + frequency = "weekly" + + return enabled, frequency + + def test_update_check(self) -> None: + """Open the yt-dlp update dialog with proper progress tracking.""" + # Create and show the update dialog (non-modal to prevent blocking) + dialog = YTDLPUpdateDialog(self) + dialog.setModal(False) # Make it non-modal + dialog.show() # Use show() instead of exec() to avoid blocking + def check_for_updates(self) -> None: """Check if FFmpeg updates are available.""" self.check_button.setEnabled(False)