diff --git a/app/app.py b/app/app.py index e20597d..ce6f90e 100644 --- a/app/app.py +++ b/app/app.py @@ -1,6 +1,7 @@ import io import json import os +import re import shutil import subprocess import threading @@ -663,6 +664,44 @@ def upload_file(): return redirect(url_for("browse", subpath=subpath) if subpath else url_for("browse")) +# ── Vérification des conflits avant redimensionnement ──────────────── + +@app.route("/check-resize", methods=["POST"]) +def check_resize(): + redir = _require_admin() + if redir: + return redir + + subpath = request.form.get("path", "").strip() + raw_sizes = request.form.getlist("sizes") + raw_formats = request.form.getlist("formats") + + if not subpath: + return jsonify({"conflicts": []}) + + target = _safe_path(subpath) + if not target.is_file(): + return jsonify({"conflicts": []}) + + try: + sizes = [int(s) for s in raw_sizes if int(s) in RESIZE_SIZES] + except (ValueError, TypeError): + return jsonify({"conflicts": []}) + + formats = [f for f in raw_formats if f in RESIZE_FORMATS] + stem = re.sub(r"_\d+x\d+$", "", target.stem) + parent = target.parent + + conflicts = [] + for fmt in formats: + for size in sizes: + out_name = f"{stem}_{size}x{size}.{fmt}" + if (parent / out_name).exists(): + conflicts.append(out_name) + + return jsonify({"conflicts": conflicts}) + + # ── Redimensionnement d'images ──────────────────────────────────────── @app.route("/resize", methods=["POST"]) @@ -704,7 +743,7 @@ def resize_image(): conflict = "skip" is_svg = ext == ".svg" - stem = target.stem + stem = re.sub(r"_\d+x\d+$", "", target.stem) parent = target.parent created, errors = [], [] diff --git a/app/templates/preview_image.html b/app/templates/preview_image.html index 00c9641..fb76e26 100644 --- a/app/templates/preview_image.html +++ b/app/templates/preview_image.html @@ -122,33 +122,25 @@ -
✓ ' + data.created.length + ' fichier(s) créé(s)
'; html += 'Erreur réseau.
'; } - result.style.display = 'block'; btn.textContent = 'Générer les copies'; btn.disabled = !canSubmit(); + resizeResolved = false; + } + + btn.addEventListener('click', async () => { + const fd = new FormData(); + fd.append('path', FILE_PATH); + szCbs.forEach(c => { if (c.checked) fd.append('sizes', c.value); }); + fmtCbs.forEach(c => { if (c.checked) fd.append('formats', c.value); }); + + let conflicts = []; + try { + const resp = await fetch(CHECK_RESIZE_URL, { method: 'POST', body: fd }); + const data = await resp.json(); + conflicts = data.conflicts || []; + } catch (_) { /* réseau : on génère directement */ } + + if (!conflicts.length) { + doResize('overwrite'); + return; + } + + conflictList.textContent = conflicts.join(', '); + conflictPanel.style.display = 'block'; + conflictPanel.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + }); + + confirmBtn.addEventListener('click', () => { + const strategy = document.querySelector('input[name="resize-conflict"]:checked')?.value || 'skip'; + conflictPanel.style.display = 'none'; + doResize(strategy); + }); + + cancelConflict.addEventListener('click', () => { + conflictPanel.style.display = 'none'; }); })();