From 6a3e8700c3ddd420bcfee8713e008afc3f6b909c Mon Sep 17 00:00:00 2001 From: Johnny Date: Fri, 4 Sep 2026 15:25:01 +0200 Subject: [PATCH] chore(release): v0.7.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute un fichier log texte rotatif (wgsecure.log) dans le dossier applicatif, en complément du journal JSON interne, pour diagnostiquer un échec (ex. split-DNS) sans dépendre de l'UI. Corrige le panneau Journal qui coupait les messages longs sans moyen de les lire en entier (défilement horizontal réactivé + infobulle). Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 10 ++++++++++ Makefile | 2 +- README.md | 4 ++-- app/__init__.py | 2 +- app/core/log.py | 36 ++++++++++++++++++++++++++++++++++++ app/ui/main_window.py | 6 +++++- wgsecure.iss | 2 +- 7 files changed, 56 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a5780e..0830f05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ Ce projet suit le [Versionnage Sémantique](https://semver.org/lang/fr/). --- +## [0.7.6] — 2026-09-04 + +### Ajouté +- **Fichier log texte des opérations.** En plus du journal JSON interne (`events.json`, limité à 200 entrées et illisible hors de l'application), chaque événement est désormais aussi écrit dans `wgsecure.log` (rotation automatique, 1 Mo × 3 fichiers) dans le dossier applicatif (`%APPDATA%\WGSecure` sous Windows, `~/.wgsecure` sous Linux) — consultable avec un simple éditeur de texte pour diagnostiquer un échec (ex. configuration du split-DNS) sans dépendre de l'interface. + +### Corrigé +- **Messages du panneau Journal tronqués sans moyen de les lire en entier.** La barre de défilement horizontale était explicitement désactivée sur le panneau Journal, coupant net les messages longs (ex. une erreur NRPT complète sous Windows). Le défilement horizontal est réactivé et une infobulle affiche désormais le message complet au survol de chaque entrée. + +--- + ## [0.7.5] — 2026-09-04 ### Corrigé diff --git a/Makefile b/Makefile index 287c1c8..cae4d7f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ## ────────────────────────────────────────────── APP := wgsecure -VERSION := 0.7.5 +VERSION := 0.7.6 VENV := .venv PYTHON := $(VENV)/bin/python3 PIP := $(VENV)/bin/pip diff --git a/README.md b/README.md index 028983b..c0a2494 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🛡️ WGSecure (WGS) -🚀 v0.7.5 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard +🚀 v0.7.6 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard **WGSecure** est une interface graphique multiplateforme (Windows & Linux) pour gérer une connexion WireGuard avec une surcouche MFA (authentification à deux facteurs TOTP). @@ -210,4 +210,4 @@ WGSecure/ ## 👤 Auteur Développé par **Johnny** — [JT-Tools](https://github.com/JT-Tools) -Version : ![v0.7.5](https://img.shields.io/badge/v0.7.5-septembre%202026-2980b9?style=flat-square) — Septembre 2026 +Version : ![v0.7.6](https://img.shields.io/badge/v0.7.6-septembre%202026-2980b9?style=flat-square) — Septembre 2026 diff --git a/app/__init__.py b/app/__init__.py index 065db2c..bdb71b6 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,3 +1,3 @@ -__version__ = "0.7.5" +__version__ = "0.7.6" APP_NAME = "WGSecure" APP_SHORT = "WGS" diff --git a/app/core/log.py b/app/core/log.py index b6c5455..bc5ff66 100644 --- a/app/core/log.py +++ b/app/core/log.py @@ -1,17 +1,48 @@ """Journal des événements de connexion WGSecure.""" import os import json +import logging from datetime import datetime +from logging.handlers import RotatingFileHandler + from app.utils.platform_utils import get_config_dir _FILE = "events.json" _MAX_ENTRIES = 200 +_LOG_FILE = "wgsecure.log" +_LOG_LEVELS = { + "error": logging.ERROR, + "warning": logging.WARNING, +} +_file_logger: logging.Logger | None = None + def _path() -> str: return os.path.join(get_config_dir(), _FILE) +def _get_file_logger() -> logging.Logger: + """Logger fichier rotatif : trace texte des opérations, lisible sans + passer par l'UI (diagnostic d'un échec quand le panneau Journal ne + suffit pas).""" + global _file_logger + if _file_logger is None: + logger = logging.getLogger("wgsecure") + logger.setLevel(logging.INFO) + handler = RotatingFileHandler( + os.path.join(get_config_dir(), _LOG_FILE), + maxBytes=1_000_000, backupCount=3, encoding="utf-8", + ) + handler.setFormatter(logging.Formatter( + "%(asctime)s [%(levelname)s] %(message)s", "%Y-%m-%d %H:%M:%S", + )) + logger.addHandler(handler) + logger.propagate = False + _file_logger = logger + return _file_logger + + def log_event(msg: str, kind: str = "info") -> None: """Ajoute un événement horodaté au journal.""" events = _load() @@ -21,6 +52,11 @@ def log_event(msg: str, kind: str = "info") -> None: "msg": msg, }) _save(events[-_MAX_ENTRIES:]) + # Une ligne = un événement, même si msg contient des retours à la ligne + # (ex. message de succès de connexion suivi d'un avertissement). + _get_file_logger().log( + _LOG_LEVELS.get(kind, logging.INFO), msg.replace("\n", " | ") + ) def get_events(n: int = 50) -> list[dict]: diff --git a/app/ui/main_window.py b/app/ui/main_window.py index 4e3a4b9..572272c 100644 --- a/app/ui/main_window.py +++ b/app/ui/main_window.py @@ -138,7 +138,7 @@ class MainWindow(QMainWindow): " border: none; font-size: 10px; font-family: Courier; }" "QListWidget::item { padding: 1px 6px; }" ) - self._log_list.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) + self._log_list.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) d.addWidget(self._log_list) d.addWidget(self._hsep()) @@ -454,6 +454,10 @@ class MainWindow(QMainWindow): color = theme.LOG_COLORS.get(kind, theme.ACCENT_LIGHT) item = QListWidgetItem(f"[{ts}] {msg}") item.setForeground(QColor(color)) + # Ligne trop longue pour tenir dans le panneau : barre de défilement + # horizontale (ci-dessus) + tooltip pour lire le message complet + # sans avoir à défiler. + item.setToolTip(msg) self._log_list.addItem(item) self._log_list.scrollToBottom() diff --git a/wgsecure.iss b/wgsecure.iss index 44fd8bb..52ccf92 100644 --- a/wgsecure.iss +++ b/wgsecure.iss @@ -5,7 +5,7 @@ ; ────────────────────────────────────────────── #define MyAppName "WGSecure" -#define MyAppVersion "0.7.5" +#define MyAppVersion "0.7.6" #define MyAppPublisher "WGSecure" #define MyAppExeName "wgsecure.exe"