From 28cde648871c3e8050e3bd694c7b8071d7dde2bd Mon Sep 17 00:00:00 2001 From: Omni Date: Thu, 18 Sep 2025 10:41:16 +0100 Subject: [PATCH] Sync from development - prepare for v0.1.2 --- jackify/backend/services/update_service.py | 41 +++++++++++---- jackify/frontends/gui/main.py | 59 ++++++++++++++++------ 2 files changed, 76 insertions(+), 24 deletions(-) diff --git a/jackify/backend/services/update_service.py b/jackify/backend/services/update_service.py index 459984f..4ac86c4 100644 --- a/jackify/backend/services/update_service.py +++ b/jackify/backend/services/update_service.py @@ -103,15 +103,33 @@ class UpdateService: # Determine if this is a delta update is_delta = '.delta' in download_url or 'delta' in download_url.lower() - return UpdateInfo( - version=latest_version, - tag_name=release_data['tag_name'], - release_date=release_data['published_at'], - changelog=release_data.get('body', ''), - download_url=download_url, - file_size=file_size, - is_delta_update=is_delta - ) + # Safety checks to prevent segfault + try: + # Sanitize string fields + safe_version = str(latest_version) if latest_version else "" + safe_tag = str(release_data.get('tag_name', '')) + safe_date = str(release_data.get('published_at', '')) + safe_changelog = str(release_data.get('body', ''))[:1000] # Limit size + safe_url = str(download_url) + + logger.debug(f"Creating UpdateInfo for version {safe_version}") + + update_info = UpdateInfo( + version=safe_version, + tag_name=safe_tag, + release_date=safe_date, + changelog=safe_changelog, + download_url=safe_url, + file_size=file_size, + is_delta_update=is_delta + ) + + logger.debug(f"UpdateInfo created successfully") + return update_info + + except Exception as e: + logger.error(f"Failed to create UpdateInfo: {e}") + return None else: logger.warning(f"No AppImage found in release {latest_version}") @@ -173,9 +191,14 @@ class UpdateService: def check_worker(): try: update_info = self.check_for_updates() + logger.debug(f"check_worker: Received update_info: {update_info}") + logger.debug(f"check_worker: About to call callback...") callback(update_info) + logger.debug(f"check_worker: Callback completed") except Exception as e: logger.error(f"Error in background update check: {e}") + import traceback + logger.error(f"Traceback: {traceback.format_exc()}") callback(None) thread = threading.Thread(target=check_worker, daemon=True) diff --git a/jackify/frontends/gui/main.py b/jackify/frontends/gui/main.py index a131251..cc6c3a5 100644 --- a/jackify/frontends/gui/main.py +++ b/jackify/frontends/gui/main.py @@ -801,27 +801,56 @@ class JackifyMainWindow(QMainWindow): # Continue anyway - don't block startup on detection errors def _check_for_updates_on_startup(self): - """Check for updates on startup in background thread""" + """Check for updates on startup - SIMPLE VERSION""" try: debug_print("Checking for updates on startup...") - def update_check_callback(update_info): - """Handle update check results""" - try: - if update_info: - debug_print(f"Update available: v{update_info.version}") - # Show update dialog + # Do it synchronously and simply + update_info = self.update_service.check_for_updates() + if update_info: + debug_print(f"Update available: v{update_info.version}") + + # Simple QMessageBox - no complex dialogs + from PySide6.QtWidgets import QMessageBox + from PySide6.QtCore import QTimer + + def show_update_dialog(): + try: + debug_print("Creating UpdateDialog...") from jackify.frontends.gui.dialogs.update_dialog import UpdateDialog dialog = UpdateDialog(update_info, self.update_service, self) + debug_print("UpdateDialog created, showing...") dialog.show() # Non-blocking - else: - debug_print("No updates available") - except Exception as e: - debug_print(f"Error showing update dialog: {e}") - - # Check for updates in background - self.update_service.check_for_updates_async(update_check_callback) - + debug_print("UpdateDialog shown successfully") + except Exception as e: + debug_print(f"UpdateDialog failed: {e}, falling back to simple dialog") + # Fallback to simple dialog + reply = QMessageBox.question( + self, + "Update Available", + f"Jackify v{update_info.version} is available.\n\nDownload and install now?", + QMessageBox.Yes | QMessageBox.No, + QMessageBox.Yes + ) + if reply == QMessageBox.Yes: + # Simple download and replace + try: + new_appimage = self.update_service.download_update(update_info) + if new_appimage: + if self.update_service.apply_update(new_appimage): + debug_print("Update applied successfully") + else: + QMessageBox.warning(self, "Update Failed", "Failed to apply update.") + else: + QMessageBox.warning(self, "Update Failed", "Failed to download update.") + except Exception as e: + QMessageBox.warning(self, "Update Failed", f"Update failed: {e}") + + # Use QTimer to show dialog after GUI is fully loaded + QTimer.singleShot(1000, show_update_dialog) + else: + debug_print("No updates available") + except Exception as e: debug_print(f"Error checking for updates on startup: {e}") # Continue anyway - don't block startup on update check errors