From 4b3347a06974b2c1621414c4c4ab2f22db0556de Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 15 Feb 2026 23:51:44 +0300 Subject: [PATCH] fix(update,security): add release notes in updater and bump to 2.2.1 --- app_version.py | 2 +- main.py | 46 ++++++++++++++++++++++++++++++-------- services/token_store.py | 4 ++-- services/update_service.py | 2 ++ 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/app_version.py b/app_version.py index d51e447..773702f 100644 --- a/app_version.py +++ b/app_version.py @@ -1 +1 @@ -APP_VERSION = "2.2.0" +APP_VERSION = "2.2.1" diff --git a/main.py b/main.py index 2fc17d8..3379531 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,6 @@ import os import shutil import sys -import threading import time from PySide6.QtCore import QProcess @@ -463,7 +462,7 @@ class VkChatManager(QMainWindow): self._log_event("update_channel", f"update_channel={self.update_channel}") def check_for_updates(self, silent_no_updates=False): - if self.update_thread and self.update_thread.is_alive(): + if self.update_thread and self.update_thread.isRunning(): return self._update_check_silent = silent_no_updates @@ -477,9 +476,16 @@ class VkChatManager(QMainWindow): request_timeout=UPDATE_REQUEST_TIMEOUT, channel=self.update_channel, ) + self.update_thread = QThread(self) + self.update_checker.moveToThread(self.update_thread) + self.update_thread.started.connect(self.update_checker.run) self.update_checker.check_finished.connect(self._on_update_check_finished) self.update_checker.check_failed.connect(self._on_update_check_failed) - self.update_thread = threading.Thread(target=self.update_checker.run, daemon=True) + self.update_checker.check_finished.connect(self.update_thread.quit) + self.update_checker.check_failed.connect(self.update_thread.quit) + self.update_checker.check_finished.connect(self.update_checker.deleteLater) + self.update_checker.check_failed.connect(self.update_checker.deleteLater) + self.update_thread.finished.connect(self.update_thread.deleteLater) self.update_thread.start() def _on_update_check_finished(self, result): @@ -499,6 +505,14 @@ class VkChatManager(QMainWindow): f"Доступная версия: {latest_version}\n\n" "Открыть страницу загрузки?" ) + release_notes = (result.get("release_notes") or "").strip() + if release_notes: + preview_lines = [line.strip() for line in release_notes.splitlines() if line.strip()] + preview_text = "\n".join(preview_lines[:8]) + if len(preview_lines) > 8: + preview_text += "\n..." + message_box.setInformativeText(f"Что нового:\n{preview_text}") + message_box.setDetailedText(release_notes) update_now_button = message_box.addButton("Обновить сейчас", QMessageBox.ButtonRole.AcceptRole) download_button = message_box.addButton("Скачать", QMessageBox.ButtonRole.AcceptRole) setup_button = None @@ -975,12 +989,26 @@ class VkChatManager(QMainWindow): self.token = token # Сохраняем и получаем корректный expiration_time (0 или будущее время) - self.token_expiration_time = token_store_save_token( - self.token, - TOKEN_FILE, - APP_DATA_DIR, - expires_in=expires_in, - ) + try: + self.token_expiration_time = token_store_save_token( + self.token, + TOKEN_FILE, + APP_DATA_DIR, + expires_in=expires_in, + ) + except Exception as e: + try: + expires_value = int(expires_in) + except (TypeError, ValueError): + expires_value = 0 + self.token_expiration_time = (time.time() + expires_value) if expires_value > 0 else 0 + self._log_event("token_store_save", str(e), level="WARN") + QMessageBox.warning( + self, + "Предупреждение", + "Не удалось безопасно сохранить токен на диске. " + "Текущая сессия активна, но после перезапуска потребуется повторная авторизация.", + ) self.token_input.setText(self.token[:50] + "...") self.status_label.setText("Статус: авторизован") diff --git a/services/token_store.py b/services/token_store.py index 6e76f95..998f8d1 100644 --- a/services/token_store.py +++ b/services/token_store.py @@ -91,8 +91,8 @@ def save_token(token, token_file, app_data_dir, expires_in=0): try: stored_token = _encrypt_token(token) encrypted = True - except Exception: - pass + except Exception as exc: + raise RuntimeError("Failed to securely store token with DPAPI.") from exc data = { "token": stored_token, diff --git a/services/update_service.py b/services/update_service.py index 3c65918..cd0f5a3 100644 --- a/services/update_service.py +++ b/services/update_service.py @@ -102,6 +102,7 @@ def _extract_release_payload(release_data, repository_url, current_version): latest_tag = release_data.get("tag_name") or release_data.get("name") or "" latest_version = latest_tag.lstrip("vV").strip() html_url = release_data.get("html_url") or releases_url + release_notes = (release_data.get("body") or "").strip() assets = release_data.get("assets") or [] download_url = "" download_name = "" @@ -147,6 +148,7 @@ def _extract_release_payload(release_data, repository_url, current_version): "current_version": current_version, "latest_tag": latest_tag, "release_url": html_url, + "release_notes": release_notes, "download_url": download_url, "download_name": download_name, "installer_url": installer_url,