100 lines
4.7 KiB
Python
100 lines
4.7 KiB
Python
import requests
|
|
from packaging import version
|
|
from PyQt6.QtWidgets import QApplication
|
|
from PyQt6.QtWidgets import QFileDialog, QDialog, QVBoxLayout
|
|
from app.core.alert_manager import AlertManager
|
|
from app.core.settings_manager import SettingsManager
|
|
from app.core.language_manager import LanguageManager
|
|
from app.ui.widgets.loading_bar import LoadingBar
|
|
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")
|
|
|
|
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}"
|
|
for release in releases:
|
|
for asset in release.get("assets", []):
|
|
if expected_filename in asset.get("name", ""):
|
|
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"], release["tag_name"], folder, parent)
|
|
return True
|
|
return False
|
|
|
|
def download(self, download_url, version, folder, parent=None):
|
|
try:
|
|
filename = os.path.basename(download_url).replace(".", "-" +version + ".")
|
|
local_path = os.path.join(folder, filename)
|
|
resp = requests.get(download_url, stream=True)
|
|
total = int(resp.headers.get('content-length', 0))
|
|
|
|
# Crée une boîte de dialogue avec la barre de chargement
|
|
dialog = QDialog(parent)
|
|
dialog.setWindowTitle(self.language_manager.get_text("update"))
|
|
layout = QVBoxLayout(dialog)
|
|
loading_bar = LoadingBar(self.language_manager.get_text("downloading_update"), dialog)
|
|
layout.addWidget(loading_bar)
|
|
dialog.setModal(True)
|
|
dialog.show()
|
|
|
|
downloaded = 0
|
|
with open(local_path, "wb") as f:
|
|
for chunk in resp.iter_content(chunk_size=8192):
|
|
if chunk:
|
|
f.write(chunk)
|
|
downloaded += len(chunk)
|
|
percent = int(downloaded * 100 / total) if total else 0
|
|
loading_bar.set_progress(percent)
|
|
QApplication.processEvents()
|
|
dialog.close()
|
|
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)
|