PythonApplicationTemplate/app/core/update_manager.py
2025-08-19 19:36:27 +02:00

81 lines
3.9 KiB
Python

import requests
from packaging import version
from PyQt6.QtWidgets import QFileDialog
from app.core.alert_manager import AlertManager
from app.core.settings_manager import SettingsManager
from app.core.language_manager import LanguageManager
import os
import sys
import subprocess
class UpdateManager:
def __init__(self, settings_manager: SettingsManager, language_manager: LanguageManager, alert_manager: AlertManager) -> None:
self.settings_manager = settings_manager
self.language_manager = language_manager
self.alert_manager = alert_manager
self.repo_url = self.settings_manager.get_config("git_repo")
self.app_name = self.settings_manager.get_config("app_name").replace(" ","_")
self.app_os = self.settings_manager.get_config("app_os")
self.arch = self.settings_manager.get_config("architecture")
self.extension = "exe" if self.app_os.lower() == "windows" else "AppImage" # adapte selon OS
def get_latest_release_with_asset(self) -> dict:
# Récupère la release la plus récente qui contient le bon fichier
try:
if "gitea" in self.repo_url:
owner_repo = self.repo_url.split("/")[-2:]
api_url = self.repo_url.replace(owner_repo[0], "api/v1/repos/" + owner_repo[0]) + "/releases"
resp = requests.get(api_url)
releases = resp.json()
else:
owner_repo = self.repo_url.split("/")[-2:]
api_url = f"https://api.github.com/repos/{owner_repo[0]}/{owner_repo[1]}/releases"
resp = requests.get(api_url)
releases = resp.json()
# Cherche le bon asset dans chaque release
expected_filename = f"{self.app_name}-{self.app_os}-{self.arch}.{self.extension}"
for release in releases:
for asset in release.get("assets", []):
if asset.get("name", "") == expected_filename:
return {
"tag_name": release.get("tag_name"),
"download_url": asset.get("browser_download_url")
}
except Exception:
pass
return None
def check_for_update(self, parent=None) -> bool:
current_version = self.settings_manager.get_config("app_version")
release = self.get_latest_release_with_asset()
if release and version.parse(release["tag_name"]) > version.parse(current_version):
choice = self.alert_manager.show_choice(
self.language_manager.get_text("update_found").replace("{latest_tag}", release["tag_name"]),
parent=parent
)
if choice:
folder = QFileDialog.getExistingDirectory(parent, self.language_manager.get_text("choose_update_folder"))
if folder:
self.download(release["download_url"], folder, parent)
return True
return False
def download(self, download_url, folder, parent=None):
try:
filename = os.path.basename(download_url)
local_path = os.path.join(folder, filename)
resp = requests.get(download_url, stream=True)
with open(local_path, "wb") as f:
for chunk in resp.iter_content(chunk_size=8192):
f.write(chunk)
msg = self.language_manager.get_text("update_downloaded").replace("{local_path}", local_path)
self.alert_manager.show_success(msg, parent=parent)
# Ouvre le fichier téléchargé
if sys.platform.startswith("win"):
os.startfile(local_path)
else:
subprocess.Popen(["chmod", "+x", local_path])
subprocess.Popen([local_path])
except Exception:
self.alert_manager.show_error("update_download_error", parent=parent)