From 6d25cab2958bc59163ef0631ee3f2dcde7ea84d2 Mon Sep 17 00:00:00 2001 From: Alpinux Date: Wed, 6 May 2026 11:43:26 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20changelog=20+=20versioning=20s=C3=A9man?= =?UTF-8?q?tique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fichier VERSION (1.4.0) lu par l'app au démarrage - CHANGELOG.md versionné (v1.0.0 → v1.4.0) - Route /changelog avec parsing du markdown et rendu structuré - Lien cliquable sur le numéro de version dans le footer Co-Authored-By: Claude Sonnet 4.6 --- app/CHANGELOG.md | 67 ++++++++++++++++++++++++++++++++++++ app/VERSION | 1 + app/app.py | 52 ++++++++++++++++++++++++++-- app/static/app.css | 22 +++++++++++- app/templates/base.html | 2 +- app/templates/changelog.html | 31 +++++++++++++++++ 6 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 app/CHANGELOG.md create mode 100644 app/VERSION create mode 100644 app/templates/changelog.html diff --git a/app/CHANGELOG.md b/app/CHANGELOG.md new file mode 100644 index 0000000..983144a --- /dev/null +++ b/app/CHANGELOG.md @@ -0,0 +1,67 @@ +# Changelog — Alpinux Static + +## [1.4.0] — 2026-05-06 + +### Ajouté +- Sélecteur de largeur du contenu dans le header : Étroit (900 px), Normal (1 200 px), Large (1 600 px), Plein — préférence mémorisée dans le navigateur +- Changelog avec numéro de version sémantique, accessible depuis le footer + +### Corrigé +- Décalage de largeur entre les pages dû à l'apparition/disparition de la scrollbar (`scrollbar-gutter: stable`) +- Labels EXIF non traduits : `ResolutionUnit`, `XResolution`, `YResolution` +- Valeur numérique brute pour `ColorSpace` → libellé lisible (sRGB, Adobe RGB, Non calibré) + +### Modifié +- Contenu principal en pleine largeur (suppression du `max-width` fixe sur `
`) + +--- + +## [1.3.0] — 2026-05-06 + +### Ajouté +- Prévisualisation des fichiers depuis la corbeille (propriétés, métadonnées, téléchargement) +- Footer sur toutes les pages avec liens de navigation et numéro de version +- Stats corbeille dans le tableau de bord (nombre de fichiers, taille totale, date du plus ancien) + +### Modifié +- Header compact : avatar initiale + prénom + icône déconnexion (suppression du bouton texte) +- Suppression du lien « Tableau de bord » dans la navigation (doublon avec le logo) +- `user`, `humansize`, `trash_count` centralisés dans le context processor Flask (disponibles sur toutes les pages) + +--- + +## [1.2.0] — 2026-05-06 + +### Ajouté +- Corbeille : mise à la corbeille depuis `/browse`, restauration avec gestion des conflits (écraser / renommer), suppression définitive +- Purge automatique des éléments en corbeille depuis plus de 30 jours +- Badge dans la navigation indiquant le nombre d'éléments en corbeille +- Page `/trash` avec tableau partagé (mode `browse` / `trash`) et bouton « Vider la corbeille » + +--- + +## [1.1.0] — 2026-05-06 + +### Ajouté +- Redimensionnement d'images depuis la prévisualisation : tailles prédéfinies, dimension libre, formats PNG/JPG/ICO +- Gestion des conflits lors du redimensionnement (backup, écraser, renommer, ignorer) +- Renommage de fichiers inline dans `/browse` et la page de prévisualisation +- Affichage des métadonnées image (dimensions, format, mode couleur, DPI, EXIF) +- Dimension libre avec contrainte de proportions (mode « carré ») + +### Corrigé +- Échec du redimensionnement sur les fichiers ICO en mode palette (conversion RGBA avant LANCZOS) +- Aucune sélection de taille ou format → copie à l'identique (comportement par défaut) + +--- + +## [1.0.0] — 2026-05-03 + +### Ajouté +- Upload de fichiers par glisser-déposer avec gestion des conflits (écraser, backup, renommer, ignorer) +- Parcourir les assets CDN depuis `/browse` avec fil d'Ariane +- Statistiques de consultation via GoAccess (`/stats`), générées à la demande +- Authentification SSO via AlpID (Keycloak / OpenID Connect) +- Recherche dans les fichiers +- Scripts rsync `push-assets.sh` et `pull-assets.sh` pour la synchronisation locale ↔ serveur +- Script `deploy-app.sh` pour le déploiement de l'application Flask diff --git a/app/VERSION b/app/VERSION new file mode 100644 index 0000000..88c5fb8 --- /dev/null +++ b/app/VERSION @@ -0,0 +1 @@ +1.4.0 diff --git a/app/app.py b/app/app.py index 4624c02..b00054a 100644 --- a/app/app.py +++ b/app/app.py @@ -46,12 +46,12 @@ _gen_lock = threading.Lock() _gen_state = {"generating": False} try: - _APP_VERSION = subprocess.check_output( - ["git", "rev-parse", "--short", "HEAD"], stderr=subprocess.DEVNULL, text=True - ).strip() + _APP_VERSION = (Path(__file__).parent / "VERSION").read_text().strip() except Exception: _APP_VERSION = "—" +_CHANGELOG_FILE = Path(__file__).parent / "CHANGELOG.md" + _HIDDEN = frozenset({ ".git", "scripts", "app", @@ -434,6 +434,52 @@ def dashboard(): ) +@app.route("/changelog") +def changelog(): + redir = _require_admin() + if redir: + return redir + sections = _parse_changelog() + return render_template("changelog.html", sections=sections) + + +def _parse_changelog(): + """Parse CHANGELOG.md into a list of version dicts.""" + try: + text = _CHANGELOG_FILE.read_text() + except Exception: + return [] + + sections = [] + current = None + current_group = None + + for line in text.splitlines(): + if line.startswith("## "): + if current: + if current_group: + current["groups"].append(current_group) + sections.append(current) + m = re.match(r"## \[(.+?)\] — (.+)", line) + current = {"version": m.group(1) if m else line[3:], + "date": m.group(2) if m else "", + "groups": []} + current_group = None + elif line.startswith("### ") and current is not None: + if current_group: + current["groups"].append(current_group) + current_group = {"title": line[4:], "items": []} + elif line.startswith("- ") and current_group is not None: + current_group["items"].append(line[2:]) + + if current: + if current_group: + current["groups"].append(current_group) + sections.append(current) + + return sections + + # ── Navigateur de fichiers ──────────────────────────────────────────── @app.route("/browse/") diff --git a/app/static/app.css b/app/static/app.css index 3eff4c6..8591ef5 100644 --- a/app/static/app.css +++ b/app/static/app.css @@ -283,7 +283,27 @@ footer { background: var(--blue-dark); color: rgba(255,255,255,.6); margin-top: .footer-nav a { color: rgba(255,255,255,.55); font-size: .82rem; } .footer-nav a:hover { color: rgba(255,255,255,.9); text-decoration: none; } .footer-version { margin-left: auto; font-size: .75rem; color: rgba(255,255,255,.35); - font-family: monospace; } + font-family: monospace; text-decoration: none; } +.footer-version:hover { color: rgba(255,255,255,.7); text-decoration: none; } + +/* ── Changelog ──────────────────────────────────────────────────────── */ +.cl-section { padding: .25rem 0 1rem; } +.cl-section--latest .cl-header { margin-bottom: .75rem; } +.cl-header { display: flex; align-items: baseline; gap: .75rem; margin-bottom: .6rem; flex-wrap: wrap; } +.cl-version { font-size: 1.05rem; font-weight: 700; color: var(--blue-dark); font-family: monospace; } +.cl-date { font-size: .82rem; color: var(--muted); } +.cl-badge { background: var(--blue); color: #fff; font-size: .68rem; font-weight: 700; + padding: .15rem .5rem; border-radius: 20px; letter-spacing: .03em; } +.cl-group { margin: .6rem 0 0 0; } +.cl-group-title { display: inline-block; font-size: .72rem; font-weight: 700; text-transform: uppercase; + letter-spacing: .06em; padding: .1rem .5rem; border-radius: 3px; margin-bottom: .35rem; } +.cl-group-title--ajouté { background: #dcfce7; color: #166534; } +.cl-group-title--corrigé { background: #fee2e2; color: #991b1b; } +.cl-group-title--modifié { background: #fef3c7; color: #92400e; } +.cl-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: .3rem; } +.cl-list li { font-size: .88rem; color: var(--text); padding-left: 1.1rem; position: relative; } +.cl-list li::before { content: "–"; position: absolute; left: 0; color: var(--muted); } +.cl-sep { border: none; border-top: 1px solid var(--border); margin: 1rem 0; } /* ── Corbeille ──────────────────────────────────────────────────────── */ .trash-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .75rem; margin-bottom: .5rem; } diff --git a/app/templates/base.html b/app/templates/base.html index 05802c8..16e53d9 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -61,7 +61,7 @@ Statistiques Corbeille - v {{ app_version }} + v {{ app_version }} diff --git a/app/templates/changelog.html b/app/templates/changelog.html new file mode 100644 index 0000000..b0b1b90 --- /dev/null +++ b/app/templates/changelog.html @@ -0,0 +1,31 @@ +{% extends "base.html" %} +{% block title %}Changelog{% endblock %} + +{% block content %} +
+

+ Historique des versions — Alpinux Static +

+ + {% for sec in sections %} +
+
+ v {{ sec.version }} + {% if sec.date %}{{ sec.date }}{% endif %} + {% if loop.first %}Actuelle{% endif %} +
+ {% for grp in sec.groups %} +
+ {{ grp.title }} +
    + {% for item in grp.items %} +
  • {{ item }}
  • + {% endfor %} +
+
+ {% endfor %} +
+ {% if not loop.last %}
{% endif %} + {% endfor %} +
+{% endblock %}