diff --git a/GitUpdateChecker.exe b/GitUpdateChecker.exe index 9dd1984..25b2875 100644 Binary files a/GitUpdateChecker.exe and b/GitUpdateChecker.exe differ diff --git a/git_updater.py b/git_updater.py index 278fc8f..cc698e4 100644 --- a/git_updater.py +++ b/git_updater.py @@ -5,7 +5,7 @@ Accès lecture seule uniquement (fetch/pull/checkout, jamais de push). Tous les chemins sont relatifs à l'emplacement de l'exécutable. """ -VERSION = "0.5.3" +VERSION = "0.5.4" import subprocess import sys @@ -13,6 +13,7 @@ import os import configparser import logging import threading +from concurrent.futures import ThreadPoolExecutor, as_completed import tkinter as tk from tkinter import ttk, messagebox from pathlib import Path @@ -108,19 +109,20 @@ def _version_tuple(v): def _get_self_update_config(): - """Lit la config [self-update] depuis config.ini. Retourne (url, exe_name) ou (None, None).""" + """Lit la config [self-update] depuis config.ini. Retourne (url, exe_name, branch) ou (None, None, None).""" config_path = get_config_path() if not config_path.exists(): - return None, None + return None, None, None config = configparser.ConfigParser() config.read(config_path, encoding="utf-8") if not config.has_section("self-update"): - return None, None + return None, None, None url = config.get("self-update", "url", fallback="").strip().rstrip("/") exe_name = config.get("self-update", "exe_name", fallback="GitUpdateChecker.exe").strip() + branch = config.get("self-update", "branch", fallback="master").strip() if not url: - return None, None - return url, exe_name + return None, None, None + return url, exe_name, branch def check_self_update(): @@ -129,14 +131,14 @@ def check_self_update(): Télécharge version.txt via HTTP et compare avec VERSION locale. Retourne (needs_update: bool, info: str). """ - repo_url, _ = _get_self_update_config() + repo_url, _, branch = _get_self_update_config() if not repo_url: log.info("Auto-update: pas de section [self-update] dans config.ini, skip") return False, "" log.info("Auto-update: verification via HTTP...") - version_url = f"{repo_url}/raw/branch/master/version.txt" + version_url = f"{repo_url}/raw/branch/{branch}/version.txt" try: req = urllib.request.Request(version_url, headers={"User-Agent": "GitUpdateChecker"}) with urllib.request.urlopen(req, timeout=10) as resp: @@ -162,7 +164,7 @@ def do_self_update(): Stratégie : télécharger dans .new, renommer l'exe actuel en .old, placer le nouveau. Retourne (ok, message). """ - repo_url, exe_name = _get_self_update_config() + repo_url, exe_name, branch = _get_self_update_config() if not repo_url: return False, "Configuration [self-update] manquante" @@ -176,21 +178,26 @@ def do_self_update(): exe_new_path = exe_path.with_suffix(".exe.new") # Telecharger le nouvel exe - download_url = f"{repo_url}/raw/branch/master/{exe_name}" + download_url = f"{repo_url}/raw/branch/{branch}/{exe_name}" log.info(f"Auto-update: telechargement de {download_url}") try: req = urllib.request.Request(download_url, headers={"User-Agent": "GitUpdateChecker"}) - with urllib.request.urlopen(req, timeout=60) as resp: - data = resp.read() + total_bytes = 0 + with urllib.request.urlopen(req, timeout=60) as resp, open(exe_new_path, "wb") as f: + while True: + chunk = resp.read(65536) # 64 Ko par bloc + if not chunk: + break + f.write(chunk) + total_bytes += len(chunk) - if len(data) < 1000: - log.error(f"Auto-update: fichier telecharge trop petit ({len(data)} octets)") + if total_bytes < 1000: + log.error(f"Auto-update: fichier telecharge trop petit ({total_bytes} octets)") + exe_new_path.unlink(missing_ok=True) return False, "Le fichier telecharge semble invalide" - with open(exe_new_path, "wb") as f: - f.write(data) - log.info(f"Auto-update: telecharge {len(data)} octets -> {exe_new_path.name}") + log.info(f"Auto-update: telecharge {total_bytes} octets -> {exe_new_path.name}") except (urllib.error.URLError, OSError) as e: log.error(f"Auto-update: echec telechargement: {e}") @@ -671,10 +678,21 @@ class App(tk.Tk): threading.Thread(target=self._check_all, daemon=True).start() def _check_all(self): - """Vérifie tous les repos (dans un thread).""" - results = [] - for repo in self.repos_config: - results.append(check_repo(repo)) + """Vérifie tous les repos en parallèle (max 4 à la fois).""" + total = len(self.repos_config) + results = [None] * total + done = 0 + + with ThreadPoolExecutor(max_workers=4) as executor: + futures = {executor.submit(check_repo, repo): i for i, repo in enumerate(self.repos_config)} + for future in as_completed(futures): + idx = futures[future] + res = future.result() + results[idx] = res + done += 1 + self._log_gui(f"[{res['name']}] Verification terminee", "info") + self.after(0, lambda d=done, t=total: self.status_label.configure(text=f"Verification {d}/{t}...")) + self.repo_results = results self.after(0, self._display_results) diff --git a/version.txt b/version.txt index be14282..7d85683 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.5.3 +0.5.4