diff --git a/languages/ar.json b/languages/ar.json index 8ddb6fc..219b56c 100644 --- a/languages/ar.json +++ b/languages/ar.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/de.json b/languages/de.json index e2c064e..87bd810 100644 --- a/languages/de.json +++ b/languages/de.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/en.json b/languages/en.json index 9ce6965..cc0a24c 100644 --- a/languages/en.json +++ b/languages/en.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/es.json b/languages/es.json index 3bbd6bf..88c2627 100644 --- a/languages/es.json +++ b/languages/es.json @@ -486,5 +486,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/fr.json b/languages/fr.json index 41679e5..6546a71 100644 --- a/languages/fr.json +++ b/languages/fr.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/hi.json b/languages/hi.json index e7de12a..858980d 100644 --- a/languages/hi.json +++ b/languages/hi.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/id.json b/languages/id.json index 3cc9ed4..fe3e9ac 100644 --- a/languages/id.json +++ b/languages/id.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/it.json b/languages/it.json index 6613b42..36b46a8 100644 --- a/languages/it.json +++ b/languages/it.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/ja.json b/languages/ja.json index 1223f74..49fd581 100644 --- a/languages/ja.json +++ b/languages/ja.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/pl.json b/languages/pl.json index 606a076..47a7875 100644 --- a/languages/pl.json +++ b/languages/pl.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/pt.json b/languages/pt.json index c8a30fe..4963d1b 100644 --- a/languages/pt.json +++ b/languages/pt.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/ru.json b/languages/ru.json index bc92200..0af313e 100644 --- a/languages/ru.json +++ b/languages/ru.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/tr.json b/languages/tr.json index b06145d..4a5a2f7 100644 --- a/languages/tr.json +++ b/languages/tr.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/languages/zh.json b/languages/zh.json index f5fe7e2..13eaacf 100644 --- a/languages/zh.json +++ b/languages/zh.json @@ -503,5 +503,22 @@ "verification_failed": "SHA256 verification failed. The downloaded file may be corrupted or tampered with.", "setup_failed": "Failed to set up Deno. Some features may not work correctly.", "setup_error": "Setup Error" + }, + "deno_updater": { + "title": "Deno Version Checker & Updater", + "description": "Check your Deno version and update to the latest release.", + "current_version": "Current Version:", + "latest_version": "Latest Version:", + "status_idle": "Click 'Check for Updates' to get started", + "status_checking": "🔄 Checking for updates...", + "status_up_to_date": "✓ Up to date", + "status_update_available": "⚠ Update available", + "status_not_installed": "✗ Not installed", + "check_updates": "Check for Updates", + "update_now": "Update Deno", + "updating": "🔄 Updating Deno...", + "update_success": "✅ Deno has been successfully updated!", + "update_failed": "❌ Update failed: {error}", + "check_failed": "Failed to check for updates. Please check your internet connection." } } \ No newline at end of file diff --git a/src/core/ytsage_deno.py b/src/core/ytsage_deno.py index 5d6d137..7444cfd 100644 --- a/src/core/ytsage_deno.py +++ b/src/core/ytsage_deno.py @@ -595,3 +595,150 @@ def setup_deno(parent_widget=None): # User cancelled or setup failed, return the fallback command logger.debug("Returning fallback command 'deno'") return "deno" + + +def get_latest_deno_version() -> Optional[str]: + """ + Fetch the latest Deno version from GitHub API. + + Returns: + str: Version string (e.g., "2.5.6") or None if fetch failed + """ + try: + response = requests.get( + "https://api.github.com/repos/denoland/deno/releases/latest", + timeout=10 + ) + response.raise_for_status() + data = response.json() + + # Get tag_name (e.g., "v2.5.6") and remove 'v' prefix + tag_name = data.get("tag_name", "") + if tag_name.startswith("v"): + version = tag_name[1:] + else: + version = tag_name + + logger.info(f"Latest Deno version: {version}") + return version + + except requests.RequestException as e: + logger.error(f"Failed to fetch latest Deno version: {e}") + return None + except Exception as e: + logger.exception(f"Unexpected error fetching Deno version: {e}") + return None + + +def compare_deno_versions(current: str, latest: str) -> bool: + """ + Compare two Deno version strings. + + Args: + current: Current version string (e.g., "2.5.6") + latest: Latest version string (e.g., "2.5.7") + + Returns: + bool: True if update is needed (latest > current), False otherwise + """ + try: + import re + + def parse_version(version_str: str) -> tuple: + """Parse version string into tuple of integers.""" + # Remove 'v' prefix if present + if version_str.startswith('v'): + version_str = version_str[1:] + + # Extract version numbers + match = re.search(r'(\d+\.\d+\.\d+)', version_str) + if match: + version_str = match.group(1) + + parts = version_str.split('.') + return tuple(int(p) for p in parts if p.isdigit()) + + current_tuple = parse_version(current) + latest_tuple = parse_version(latest) + + logger.debug(f"Comparing Deno versions: {current_tuple} vs {latest_tuple}") + return latest_tuple > current_tuple + + except (ValueError, AttributeError) as e: + logger.warning(f"Could not compare Deno versions: {e}") + return False + + +def upgrade_deno() -> tuple[bool, str]: + """ + Upgrade Deno to the latest version using 'deno upgrade' command. + + Returns: + tuple: (success: bool, output: str) - Success status and command output + """ + try: + deno_path = DENO_APP_BIN_PATH + + if not deno_path.exists(): + error_msg = f"Deno binary not found at: {deno_path}" + logger.error(error_msg) + return False, error_msg + + logger.info(f"Upgrading Deno using: {deno_path}") + + # Run deno upgrade command + result = subprocess.run( + [str(deno_path), "upgrade"], + capture_output=True, + text=True, + timeout=300, # 5 minutes timeout + creationflags=SUBPROCESS_CREATIONFLAGS + ) + + output = result.stdout + result.stderr + + if result.returncode == 0: + logger.info("Deno upgrade successful") + logger.debug(f"Upgrade output: {output}") + return True, output + else: + logger.error(f"Deno upgrade failed with code {result.returncode}") + logger.error(f"Output: {output}") + return False, output + + except subprocess.TimeoutExpired: + error_msg = "Deno upgrade timed out after 5 minutes" + logger.error(error_msg) + return False, error_msg + except Exception as e: + error_msg = f"Error upgrading Deno: {str(e)}" + logger.exception(error_msg) + return False, error_msg + + +def check_deno_update() -> tuple[bool, str, str]: + """ + Check if a Deno update is available. + + Returns: + tuple: (update_needed: bool, current_version: str, latest_version: str) + """ + try: + # Get current version + current_version = get_deno_version_direct() + if current_version in ["Not found", "Error getting version"]: + return False, current_version, "Unknown" + + # Get latest version + latest_version = get_latest_deno_version() + if not latest_version: + return False, current_version, "Error" + + # Compare versions + update_needed = compare_deno_versions(current_version, latest_version) + + return update_needed, current_version, latest_version + + except Exception as e: + logger.exception(f"Error checking Deno update: {e}") + return False, "Error", "Error" diff --git a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py index c0a67b2..c86d1ba 100644 --- a/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py +++ b/src/gui/ytsage_gui_dialogs/ytsage_dialogs_updater.py @@ -29,6 +29,7 @@ from src.core.ytsage_utils import ( update_auto_update_settings, ) from src.core.ytsage_yt_dlp import get_yt_dlp_path +from src.core.ytsage_deno import check_deno_update, upgrade_deno from src.gui.ytsage_gui_dialogs.ytsage_dialogs_update import YTDLPUpdateDialog from src.utils.ytsage_config_manager import ConfigManager from src.utils.ytsage_localization import _ @@ -290,6 +291,116 @@ class UpdaterTabWidget(QWidget): layout.addWidget(ffmpeg_group) + # === Deno Version Check & Update Section === + deno_group = QGroupBox(_('deno_updater.title')) + deno_layout = QVBoxLayout(deno_group) + + # Description + deno_desc = QLabel(_('deno_updater.description')) + deno_desc.setWordWrap(True) + deno_desc.setStyleSheet("color: #999999; padding: 10px;") + deno_layout.addWidget(deno_desc) + + # Version information layout + deno_version_layout = QVBoxLayout() + + # Current version + deno_current_layout = QHBoxLayout() + deno_current_label = QLabel(_('deno_updater.current_version')) + deno_current_label.setStyleSheet("font-weight: bold; color: #ffffff;") + deno_current_layout.addWidget(deno_current_label) + + self.deno_current_version_label = QLabel("...") + self.deno_current_version_label.setStyleSheet("color: #cccccc;") + deno_current_layout.addWidget(self.deno_current_version_label) + deno_current_layout.addStretch() + deno_version_layout.addLayout(deno_current_layout) + + # Latest version + deno_latest_layout = QHBoxLayout() + deno_latest_label = QLabel(_('deno_updater.latest_version')) + deno_latest_label.setStyleSheet("font-weight: bold; color: #ffffff;") + deno_latest_layout.addWidget(deno_latest_label) + + self.deno_latest_version_label = QLabel("...") + self.deno_latest_version_label.setStyleSheet("color: #cccccc;") + deno_latest_layout.addWidget(self.deno_latest_version_label) + deno_latest_layout.addStretch() + deno_version_layout.addLayout(deno_latest_layout) + + deno_layout.addLayout(deno_version_layout) + + # Status label + self.deno_status_label = QLabel(_('deno_updater.status_idle')) + self.deno_status_label.setWordWrap(True) + self.deno_status_label.setStyleSheet( + "color: #888888; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + deno_layout.addWidget(self.deno_status_label) + + # Buttons layout + deno_button_layout = QHBoxLayout() + + # Check for updates button + self.deno_check_button = QPushButton(_('deno_updater.check_updates')) + self.deno_check_button.clicked.connect(self.check_deno_updates) + self.deno_check_button.setStyleSheet( + """ + QPushButton { + padding: 8px 15px; + background-color: #444444; + border: none; + border-radius: 4px; + color: white; + font-weight: bold; + min-width: 120px; + } + QPushButton:hover { + background-color: #555555; + } + QPushButton:disabled { + background-color: #2a2a2a; + color: #666666; + } + """ + ) + deno_button_layout.addWidget(self.deno_check_button) + + # Update button (initially hidden) + self.deno_update_button = QPushButton(_('deno_updater.update_now')) + self.deno_update_button.clicked.connect(self.update_deno) + self.deno_update_button.setVisible(False) + self.deno_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; + } + QPushButton:disabled { + background-color: #2a2a2a; + color: #666666; + } + """ + ) + deno_button_layout.addWidget(self.deno_update_button) + + deno_button_layout.addStretch() + deno_layout.addLayout(deno_button_layout) + + layout.addWidget(deno_group) + # === yt-dlp Release Channel Section === ytdlp_channel_group = QGroupBox(_("settings.ytdlp_channel")) ytdlp_channel_layout = QVBoxLayout() @@ -697,3 +808,116 @@ class UpdaterTabWidget(QWidget): "color: #ff6666; font-size: 12px; padding: 8px; " "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" ) + + def check_deno_updates(self) -> None: + """Check for Deno updates.""" + self.deno_check_button.setEnabled(False) + self.deno_update_button.setVisible(False) + self.deno_status_label.setText(_('deno_updater.status_checking')) + self.deno_status_label.setStyleSheet( + "color: #ffaa00; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + + # Run check in background thread + def check_thread(): + try: + update_available, current_version, latest_version = check_deno_update() + + # Update UI in main thread + self.deno_check_button.setEnabled(True) + self._update_deno_check_results(update_available, current_version, latest_version) + + except Exception as e: + logger.exception(f"Error checking Deno version: {e}") + self.deno_check_button.setEnabled(True) + self._show_deno_check_error(str(e)) + + thread = threading.Thread(target=check_thread, daemon=True) + thread.start() + + def _update_deno_check_results(self, update_available: bool, current_version: str, latest_version: str) -> None: + """Handle completion of Deno version check.""" + # Update version labels + self.deno_current_version_label.setText(current_version) + self.deno_latest_version_label.setText(latest_version) + + # Update status + if current_version in ["Not found", "Error getting version"]: + self.deno_status_label.setText(_('deno_updater.status_not_installed')) + self.deno_status_label.setStyleSheet( + "color: #ff6666; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + elif update_available: + self.deno_status_label.setText(_('deno_updater.status_update_available')) + self.deno_status_label.setStyleSheet( + "color: #ffaa00; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + # Show update button + self.deno_update_button.setVisible(True) + else: + self.deno_status_label.setText(_('deno_updater.status_up_to_date')) + self.deno_status_label.setStyleSheet( + "color: #00cc00; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + + def _show_deno_check_error(self, error: str) -> None: + """Handle error during Deno version check.""" + self.deno_status_label.setText(_('deno_updater.check_failed')) + self.deno_status_label.setStyleSheet( + "color: #ff6666; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + + def update_deno(self) -> None: + """Update Deno to the latest version.""" + self.deno_check_button.setEnabled(False) + self.deno_update_button.setEnabled(False) + self.deno_status_label.setText(_('deno_updater.updating')) + self.deno_status_label.setStyleSheet( + "color: #ffaa00; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + + # Run update in background thread + def update_thread(): + try: + success, output = upgrade_deno() + + # Update UI in main thread + self.deno_check_button.setEnabled(True) + self.deno_update_button.setEnabled(True) + self._handle_deno_update_result(success, output) + + except Exception as e: + logger.exception(f"Error updating Deno: {e}") + self.deno_check_button.setEnabled(True) + self.deno_update_button.setEnabled(True) + self._handle_deno_update_result(False, str(e)) + + thread = threading.Thread(target=update_thread, daemon=True) + thread.start() + + def _handle_deno_update_result(self, success: bool, output: str) -> None: + """Handle Deno update completion.""" + if success: + self.deno_status_label.setText(_('deno_updater.update_success')) + self.deno_status_label.setStyleSheet( + "color: #00cc00; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + ) + self.deno_update_button.setVisible(False) + + # Re-check version to update display + self.check_deno_updates() + else: + # Extract meaningful error from output + error_msg = output if output else "Unknown error" + self.deno_status_label.setText(_('deno_updater.update_failed', error=error_msg)) + self.deno_status_label.setStyleSheet( + "color: #ff6666; font-size: 12px; padding: 8px; " + "background-color: #2a2d36; border-radius: 4px; margin: 5px 0;" + )