feat: build.rs — génération automatique des pages HTML depuis CHANGELOG.md et ROADMAP.md

- build.rs convertit CHANGELOG.md → changelog.html et ROADMAP.md → help.html
- Injection automatique de la version Cargo.toml dans toutes les pages
- Correction du routage : /changelog et /help sans .html fonctionnent
- Templates changelog.tmpl.html et help.tmpl.html avec placeholders {{VERSION}}
- Plus jamais de désynchronisation entre .md et pages web !
- v0.2.0 affichée partout (index, changelog, help, API)
This commit is contained in:
2026-06-25 11:16:33 -04:00
parent 7abeb78993
commit 0fce8f6727
6 changed files with 710 additions and 200 deletions
+99 -90
View File
@@ -1,97 +1,106 @@
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Changelog</title></head>
<body style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#0d1117;color:#c9d1d9;padding:24px;line-height:1.6;max-width:900px;margin:0 auto">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Changelog — imagod-web v0.2.0</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
<style>
a { color:#58a6ff }
h1 { border-bottom:1px solid #30363d;padding-bottom:8px }
h2 { margin-top:24px;color:#58a6ff }
h3 { margin-top:16px;color:#79c0ff }
li { margin:4px 0 }
code { background:#161b22;padding:2px 6px;border-radius:4px;font-size:13px }
table { border-collapse:collapse;width:100%;margin:12px 0 }
td,th { border:1px solid #30363d;padding:8px 12px;text-align:left;font-size:13px }
th { background:#161b22 }
.tag { font-size:10px;padding:2px 6px;border-radius:8px;margin-right:4px }
.tag-feat { background:rgba(88,166,255,0.15);color:#58a6ff }
.tag-fix { background:rgba(63,185,80,0.15);color:#3fb950 }
.tag-docs { background:rgba(210,153,34,0.15);color:#d29922 }
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family:'Segoe UI',system-ui,-apple-system,sans-serif; background:#0d1117; color:#c9d1d9; min-height:100vh; }
header { background:#161b22; border-bottom:1px solid #30363d; padding:1rem 1.5rem; display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; z-index:100; }
header h1 { font-size:1.2rem; color:#58a6ff; }
nav { display:flex; gap:0.5rem; }
nav a { color:#8b949e; text-decoration:none; padding:0.5rem 1rem; border-radius:6px; font-size:0.9rem; transition:all .2s; }
nav a:hover, nav a.active { background:#21262d; color:#f0f6fc; }
.version-badge { background:#23863622; color:#3fb950; padding:0.2rem 0.6rem; border-radius:1rem; font-size:0.75rem; border:1px solid #23863644; }
main { max-width:900px; margin:2rem auto; padding:0 1.5rem; }
h2 { color:#f0f6fc; margin:1.5rem 0 1rem; padding-bottom:0.5rem; border-bottom:1px solid #30363d; }
h3 { color:#58a6ff; margin:1rem 0 0.5rem; }
h4 { color:#8b949e; margin:0.5rem 0; }
p { margin:0.5rem 0; line-height:1.6; }
code { background:#161b22; padding:0.15em 0.4em; border-radius:3px; font-size:0.9em; color:#d2a8ff; }
pre { background:#161b22; border:1px solid #30363d; border-radius:6px; padding:1rem; overflow-x:auto; margin:0.75rem 0; }
pre code { background:none; padding:0; color:#c9d1d9; }
li { margin:0.3rem 0 0.3rem 1.5rem; }
li input[type=checkbox] { margin-right:0.5rem; }
table { border-collapse:collapse; width:100%; margin:0.75rem 0; }
th, td { border:1px solid #30363d; padding:0.5rem 0.75rem; text-align:left; font-size:0.9rem; }
th { background:#161b22; color:#f0f6fc; }
hr { border:none; border-top:1px solid #30363d; margin:1.5rem 0; }
a { color:#58a6ff; }
a:hover { text-decoration:underline; }
strong { color:#f0f6fc; }
em { color:#8b949e; }
footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
</style>
</head>
<body>
<header>
<h1>📋 imagod-web <span class="version-badge">v0.2.0</span></h1>
<nav>
<a href="/">🖼️ Galerie</a>
<a href="/changelog" class="active">📋 Changelog</a>
<a href="/help">❓ Aide</a>
</nav>
</header>
<main>
<h1>Changelog — imagod-web</h1>
<p>Toutes les modifications notables de imagod-web sont documentées ici.</p>
<hr>
<h2>[v0.2.0] — 2026-06-25</h2>
<h3>🚀 Ajouts majeurs</h3>
<li><strong>Phase 3 — Clipboard Watcher (Windows)</strong> : Module <code>clipboard.rs</code> avec capture d'image via <code>arboard</code>, conversion BGRA→PNG, hachage SHA-256 pour dédoublonnage</li>
<li><strong>Phase 6 — Boucle Watcher</strong> : Polling unifié Windows (clipboard) / Linux-macOS (dossier), dédoublonnage SQLite persistant, pipeline complet détection → upload → nettoyage</li>
<li><strong>Navigation dashboard</strong> : Barre d'onglets 🖼️ Galerie | 📋 Changelog | ❓ Aide</li>
<li><strong>Badge version</strong> : Affichage <code>v0.2.0</code> dans l'en-tête du dashboard</li>
<li><strong>Pages statiques</strong> : <code>changelog.html</code> et <code>help.html</code> générées depuis le markdown, encastrées dans le binaire</li>
<li><strong>Endpoint version</strong> : <code>GET /api/version</code> retourne la version, le build, l'OS et l'architecture</li>
<h3>🐛 Corrections</h3>
<li><strong>Thumbnails 404</strong> : Les miniatures échouaient car les balises <code>&lt;img&gt;</code> n'envoyaient pas le header <code>X-API-Key</code>. Correction : <code>get_thumbnail()</code> utilise toujours la clé serveur configurée, pas le header utilisateur</li>
<li><strong>Clé API expirée</strong> : Mise à jour de la configuration avec la clé valide</li>
<h3>🧪 Tests</h3>
<li><strong>Watcher Linux validé</strong> : Polling dossier fonctionnel, upload réussi vers Imago (image test ID=13), dédoublonnage confirmé</li>
<li><strong>Phase 3 compilée</strong> : Code clipboard compilé et prêt, test Windows à venir</li>
<h3>📚 Documentation</h3>
<li><strong>ROADMAP.md</strong> : Créé avec planification complète des phases 3 à 15</li>
<li><strong>CHANGELOG.md</strong> : Ce fichier</li>
<hr>
<h2>[v0.1.0] — 2026-06-23</h2>
<h3>🏗️ Architecture</h3>
<li>Structure du projet Rust (Cargo, modules)</li>
<li>CLI avec <code>clap</code> : commandes <code>start</code>, <code>serve</code>, <code>stop</code>, <code>status</code>, <code>config</code>, <code>logs</code>, <code>install</code>, <code>uninstall</code></li>
<li>Configuration TOML (<code>imagod.toml</code>) avec auto-génération</li>
<li>Serveur web <code>axum</code> avec frontend vanilla JS embarqué via <code>rust-embed</code></li>
<li>Multiplateforme : Windows, Linux, macOS (x86_64, ARM64)</li>
<h3>🎨 Dashboard Web (Phase 7-9)</h3>
<li>Interface sombre moderne, responsive mobile/desktop</li>
<li><strong>Authentification</strong> : Login par clé API, validation immédiate, persistence localStorage</li>
<li><strong>Galerie d'images</strong> : Affichage responsive avec thumbnails, recherche textuelle, stats (nombre, stockage)</li>
<li><strong>Upload</strong> : Zone drag &amp; drop, sélection de fichier, barre de progression</li>
<li><strong>Suppression</strong> : Bouton corbeille avec confirmation, toast notification</li>
<li><strong>Tags</strong> : Édition inline, ajout/suppression, enregistrement automatique</li>
<li><strong>WebSocket</strong> : Connexion temps réel avec indicateur de statut</li>
<li><strong>Modale</strong> : Détail complet (EXIF, OCR, description AI, tags, taille)</li>
<li><strong>Filtrage</strong> : Recherche par nom, tags, description AI</li>
<h3>🔌 Client Imago v2</h3>
<li><strong>Endpoints</strong> : <code>list<em>images</code>, <code>search</em>images</code>, <code>upload<em>image</code>, <code>delete</em>image</code>, <code>update_tags</code></li>
<li><strong><code>get_thumbnail()</code></strong> : Appel <code>thumbnail-url</code> + suivi URL signée + fallback <code>download-url</code> si 404</li>
<li><strong><code>get_file()</code></strong> : Appel <code>download-url</code> + suivi URL signée</li>
<li><strong>Auth</strong> : Header <code>X-API-Key</code> dynamique (clé serveur ou utilisateur)</li>
<li><strong>Multi-tenant</strong> : Support header <code>X-Tenant-ID</code></li>
<h3>🗄️ Dédoublonnage</h3>
<li>Base SQLite locale pour le cache SHA-256</li>
<li>Table <code>dedup_hashes</code> avec horodatage</li>
<li>Nettoyage automatique du cache (limite configurable, défaut 10 000 entrées)</li>
<h3>🔧 Configuration</h3>
<li><code>imagod.toml</code> : sections <code>[imago]</code>, <code>[watcher]</code>, <code>[dedup]</code>, <code>[ui]</code>, <code>[logging]</code></li>
<li>Paramètres watcher : <code>capture<em>images</code>, <code>poll</em>interval<em>ms</code>, <code>watch</em>dir</code>, <code>filters</code></li>
<li>Gestion multi-environnement : développement (dev.lab.home) et production</li>
<hr>
<h2>Légende des tags</h2>
<h1>📋 Changelog — imagod-web</h1>
<h2>v0.1.0 — 2026-06-25</h2>
<h3><span class="tag tag-feat">feat</span> Dashboard Web</h3>
<ul>
<li>Authentification par clé API Imago (login/logout, localStorage)</li>
<li>Galerie responsive (grille adaptative desktop/mobile, breakpoints 768px/400px)</li>
<li>Upload par drag & drop avec feedback visuel</li>
<li>Raccourcis clavier : Ctrl+U (upload), Ctrl+V (coller)</li>
<li>Recherche plein texte (nom, tags, description)</li>
<li>Pagination par pages de 24 images</li>
<li>Modale détail : full résolution, EXIF, OCR, description AI</li>
<li>Suppression avec boîte de confirmation</li>
<li>Gestion des tags : ajout, suppression, édition inline</li>
<li>Notifications toast (succès/erreur)</li>
<li>FAB mobile pour upload</li>
<li>Connexion WebSocket temps réel</li>
<li>Statistiques (nombre d'images, stockage, tags, uptime)</li>
</ul>
<h3><span class="tag tag-feat">feat</span> Client API Imago v2</h3>
<ul>
<li>8 endpoints : list, search, get, upload, thumbnail, download, delete, tags</li>
<li>Proxy des URLs signées (thumbnail-url / download-url)</li>
<li>Auth par header X-API-Key</li>
</ul>
<h3><span class="tag tag-feat">feat</span> Watcher (Phase 3 + 6)</h3>
<ul>
<li>Windows : polling clipboard via arboard, conversion PNG automatique</li>
<li>Linux/macOS : surveillance de dossier configurable (polling)</li>
<li>Pipeline : détection → hash SHA-256 → dédoublonnage → upload → log</li>
<li>Configuration : intervalle de polling, dossier à surveiller, filtres</li>
</ul>
<h3><span class="tag tag-feat">feat</span> CLI</h3>
<ul>
<li>Commandes : start, serve, stop, status, config, install, uninstall, logs</li>
<li>Flags : --host, --port, --api-key, --api-url, --no-watcher</li>
<li>Gestion PID pour éviter les doublons d'instance</li>
</ul>
<h3><span class="tag tag-feat">feat</span> Dédoublonnage</h3>
<ul>
<li>Hash SHA-256 des images</li>
<li>Base SQLite locale (imagod.db)</li>
<li>Cache LRU configurable</li>
</ul>
<h3><span class="tag tag-fix">fix</span> Corrections</h3>
<ul>
<li>Structs Imago v2 (ExifData, OcrData, AiData) match l'API réelle</li>
<li>Affichage via URLs signées (thumbnail-url/download-url)</li>
<li>Fallback placeholder DOM quand pas de thumbnail</li>
<li>Import delete inutilisé retiré</li>
</ul>
<h3><span class="tag tag-docs">docs</span> Documentation</h3>
<ul>
<li>CHANGELOG.md dans le repo</li>
<li>ROADMAP.md avec planification des phases</li>
<li>Navigation in-app : Galerie / Changelog / Aide</li>
</ul>
<h2>Architecture</h2>
<table>
<tr><th>Composant</th><th>Technologie</th><th>Statut</th></tr>
<tr><td>Daemon</td><td>Rust (tokio, clap)</td><td>✅</td></tr>
<tr><td>Serveur web</td><td>axum 0.8 + tower-http</td><td>✅</td></tr>
<tr><td>Frontend</td><td>Vanilla JS + rust-embed</td><td>✅</td></tr>
<tr><td>Client API</td><td>reqwest (rustls)</td><td>✅</td></tr>
<tr><td>Dédoublonnage</td><td>SHA-256 + SQLite</td><td>✅</td></tr>
<tr><td>Temps réel</td><td>WebSocket (broadcast)</td><td>✅</td></tr>
</table>
</main>
<footer>imagod-web v0.2.0 — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
</body>
</html>
+52
View File
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Changelog — imagod-web v{{VERSION}}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family:'Segoe UI',system-ui,-apple-system,sans-serif; background:#0d1117; color:#c9d1d9; min-height:100vh; }
header { background:#161b22; border-bottom:1px solid #30363d; padding:1rem 1.5rem; display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; z-index:100; }
header h1 { font-size:1.2rem; color:#58a6ff; }
nav { display:flex; gap:0.5rem; }
nav a { color:#8b949e; text-decoration:none; padding:0.5rem 1rem; border-radius:6px; font-size:0.9rem; transition:all .2s; }
nav a:hover, nav a.active { background:#21262d; color:#f0f6fc; }
.version-badge { background:#23863622; color:#3fb950; padding:0.2rem 0.6rem; border-radius:1rem; font-size:0.75rem; border:1px solid #23863644; }
main { max-width:900px; margin:2rem auto; padding:0 1.5rem; }
h2 { color:#f0f6fc; margin:1.5rem 0 1rem; padding-bottom:0.5rem; border-bottom:1px solid #30363d; }
h3 { color:#58a6ff; margin:1rem 0 0.5rem; }
h4 { color:#8b949e; margin:0.5rem 0; }
p { margin:0.5rem 0; line-height:1.6; }
code { background:#161b22; padding:0.15em 0.4em; border-radius:3px; font-size:0.9em; color:#d2a8ff; }
pre { background:#161b22; border:1px solid #30363d; border-radius:6px; padding:1rem; overflow-x:auto; margin:0.75rem 0; }
pre code { background:none; padding:0; color:#c9d1d9; }
li { margin:0.3rem 0 0.3rem 1.5rem; }
li input[type=checkbox] { margin-right:0.5rem; }
table { border-collapse:collapse; width:100%; margin:0.75rem 0; }
th, td { border:1px solid #30363d; padding:0.5rem 0.75rem; text-align:left; font-size:0.9rem; }
th { background:#161b22; color:#f0f6fc; }
hr { border:none; border-top:1px solid #30363d; margin:1.5rem 0; }
a { color:#58a6ff; }
a:hover { text-decoration:underline; }
strong { color:#f0f6fc; }
em { color:#8b949e; }
footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
</style>
</head>
<body>
<header>
<h1>📋 imagod-web <span class="version-badge">v{{VERSION}}</span></h1>
<nav>
<a href="/">🖼️ Galerie</a>
<a href="/changelog" class="active">📋 Changelog</a>
<a href="/help">❓ Aide</a>
</nav>
</header>
<main>
{{CHANGELOG_CONTENT}}
</main>
<footer>imagod-web v{{VERSION}} — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
</body>
</html>
+167 -87
View File
@@ -1,94 +1,174 @@
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Aide</title></head>
<body style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#0d1117;color:#c9d1d9;padding:24px;line-height:1.7;max-width:900px;margin:0 auto">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aide & Roadmap — imagod-web v0.2.0</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
<style>
a { color:#58a6ff }
h1 { border-bottom:1px solid #30363d;padding-bottom:8px }
h2 { margin-top:28px;color:#58a6ff }
h3 { margin-top:20px;color:#79c0ff }
li { margin:6px 0 }
code { background:#161b22;padding:2px 6px;border-radius:4px;font-size:13px }
pre { background:#161b22;padding:12px 16px;border-radius:8px;overflow-x:auto;font-size:13px;border:1px solid #30363d }
.highlight { background:rgba(88,166,255,0.1);border-left:3px solid #58a6ff;padding:8px 16px;border-radius:0 8px 8px 0;margin:12px 0 }
.tip { background:rgba(63,185,80,0.1);border-left:3px solid #3fb950;padding:8px 16px;border-radius:0 8px 8px 0;margin:12px 0 }
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family:'Segoe UI',system-ui,-apple-system,sans-serif; background:#0d1117; color:#c9d1d9; min-height:100vh; }
header { background:#161b22; border-bottom:1px solid #30363d; padding:1rem 1.5rem; display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; z-index:100; }
header h1 { font-size:1.2rem; color:#58a6ff; }
nav { display:flex; gap:0.5rem; }
nav a { color:#8b949e; text-decoration:none; padding:0.5rem 1rem; border-radius:6px; font-size:0.9rem; transition:all .2s; }
nav a:hover, nav a.active { background:#21262d; color:#f0f6fc; }
.version-badge { background:#23863622; color:#3fb950; padding:0.2rem 0.6rem; border-radius:1rem; font-size:0.75rem; border:1px solid #23863644; }
main { max-width:900px; margin:2rem auto; padding:0 1.5rem; }
h2 { color:#f0f6fc; margin:1.5rem 0 1rem; padding-bottom:0.5rem; border-bottom:1px solid #30363d; }
h3 { color:#58a6ff; margin:1rem 0 0.5rem; }
h4 { color:#8b949e; margin:0.5rem 0; }
p { margin:0.5rem 0; line-height:1.6; }
code { background:#161b22; padding:0.15em 0.4em; border-radius:3px; font-size:0.9em; color:#d2a8ff; }
pre { background:#161b22; border:1px solid #30363d; border-radius:6px; padding:1rem; overflow-x:auto; margin:0.75rem 0; }
pre code { background:none; padding:0; color:#c9d1d9; }
li { margin:0.3rem 0 0.3rem 1.5rem; }
li input[type=checkbox] { margin-right:0.5rem; }
table { border-collapse:collapse; width:100%; margin:0.75rem 0; }
th, td { border:1px solid #30363d; padding:0.5rem 0.75rem; text-align:left; font-size:0.9rem; }
th { background:#161b22; color:#f0f6fc; }
hr { border:none; border-top:1px solid #30363d; margin:1.5rem 0; }
a { color:#58a6ff; }
a:hover { text-decoration:underline; }
strong { color:#f0f6fc; }
em { color:#8b949e; }
footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
</style>
</head>
<body>
<header>
<h1>❓ imagod-web <span class="version-badge">v0.2.0</span></h1>
<nav>
<a href="/">🖼️ Galerie</a>
<a href="/changelog">📋 Changelog</a>
<a href="/help" class="active">❓ Aide</a>
</nav>
</header>
<main>
<h1>Roadmap — imagod-web</h1>
<p>Planification des évolutions de imagod-web.</p>
<p>Les phases sont ordonnées par priorité et dépendances.</p>
<hr>
<h2>🟢 Phase 1–2 — Fondations ✅ *Complété*</h2>
<li><input type="checkbox" checked disabled> Structure du projet Rust (Cargo, modules)</li>
<li><input type="checkbox" checked disabled> CLI avec clap (commands <code>serve</code>, <code>watcher</code>, <code>install</code>, <code>uninstall</code>)</li>
<li><input type="checkbox" checked disabled> Configuration TOML + variables d'environnement</li>
<li><input type="checkbox" checked disabled> Client HTTP Imago v2 (reqwest + rustls)</li>
<li><input type="checkbox" checked disabled> Dédoublonnage SHA-256 + SQLite</li>
<li><input type="checkbox" checked disabled> Compilation Linux x86_64</li>
<hr>
<h2>🟢 Phase 7–9 — Dashboard Web ✅ *Complété*</h2>
<li><input type="checkbox" checked disabled> Serveur axum avec frontend embarqué (rust-embed)</li>
<li><input type="checkbox" checked disabled> API REST proxy vers Imago v2 (CRUD images, recherche, stats)</li>
<li><input type="checkbox" checked disabled> Authentification par clé API (login/logout, localStorage)</li>
<li><input type="checkbox" checked disabled> Galerie responsive desktop + mobile</li>
<li><input type="checkbox" checked disabled> Upload drag &amp; drop + raccourcis clavier</li>
<li><input type="checkbox" checked disabled> Modale détail image (EXIF, OCR, AI, métadonnées)</li>
<li><input type="checkbox" checked disabled> Suppression avec confirmation</li>
<li><input type="checkbox" checked disabled> Gestion des tags inline (ajout, suppression, édition)</li>
<li><input type="checkbox" checked disabled> Notifications toast</li>
<li><input type="checkbox" checked disabled> WebSocket temps réel (hub broadcast)</li>
<li><input type="checkbox" checked disabled> Pagination + recherche plein texte</li>
<hr>
<h2>🟢 Phase 3 — Clipboard Watcher (Windows) ✅ *Complété*</h2>
<p><strong>Objectif</strong> : Capture automatique des screenshots depuis le presse-papier Windows.</p>
<p><strong>Notes techniques</strong> :</p>
<li>✅ Utiliser <code>arboard::Clipboard::new()</code> → <code>get_image()</code></li>
<li>✅ Convertir <code>ImageData</code> en bytes PNG via le crate <code>image</code></li>
<li>✅ Gérer le cas où le clipboard est vide ou contient du texte</li>
<li>⚠️ Testé uniquement sous Linux (headless) — validation Windows à faire</li>
<p><strong>Dépendances estimées</strong> : crate <code>image</code> (si pas déjà présent)</p>
<hr>
<h2>🟢 Phase 6 — Boucle principale du Watcher ✅ *Complété*</h2>
<p><strong>Objectif</strong> : Assembler clipboard + dédoublonnage + upload dans une boucle de polling.</p>
<p><strong>Pipeline détaillé</strong> :</p>
<pre><code>┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Poll │───▶│ Hash │───▶│ Dedup │───▶│ Upload │───▶│ Notify │
│ Clipboard│ │ SHA-256 │ │ Check │ │ Imago │ │ WS Hub │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘</code></pre>
<p><strong>Dépendances</strong> : Phase 3 (clipboard)</p>
<hr>
<h2>🟡 Correctifs Backend Imago</h2>
<p>Ces tâches dépendent du backend Imago, pas d'imagod-web directement :</p>
<hr>
<h2>🟠 Phase 10 — Service Windows (NSSM)</h2>
<p><strong>Objectif</strong> : Installation de imagod-web comme service Windows natif.</p>
<p><strong>Approches possibles</strong> :</p>
<p>1. <strong>NSSM</strong> (recommandé) — wrapper externe, simple et robuste</p>
<p>2. <strong>windows-service</strong> crate — pure Rust, plus complexe</p>
<p>3. <strong>sc.exe</strong> — commandes Windows natives</p>
<hr>
<h2>🟠 Phase 11 — Intégration Ditto Clipboard Manager</h2>
<p><strong>Objectif</strong> : Plugin/addon Ditto qui envoie automatiquement les screenshots vers imagod-web.</p>
<p><strong>Contexte</strong> : Bruno utilise <a href="https://ditto-cp.sourceforge.io/">Ditto</a>, un gestionnaire de presse-papier avancé pour Windows.</p>
<p><strong>Deux approches envisageables</strong> :</p>
<h3>Option A : Script externe Ditto</h3>
<li>Ditto peut exécuter un script/exe quand un nouvel élément est copié</li>
<li>Un petit binaire Rust qui appelle <code>POST /api/upload</code> de imagod-web</li>
<li>Avantage : simple, découplé</li>
<h3>Option B : Plugin Ditto natif</h3>
<li>Ditto supporte des plugins/addons (C++ ou COM)</li>
<li>Plugin qui intercepte les images et les envoie directement à Imago</li>
<li>Avantage : plus intégré, pas de polling nécessaire</li>
<p>&gt; ⚠️ Nécessite une investigation sur l'API plugin Ditto (peu documentée)</p>
<hr>
<h2>🟠 Phase 12 — Cross-Compilation &amp; CI/CD</h2>
<p><strong>Objectif</strong> : Binaires natifs pour Windows x86_64, Linux ARM64.</p>
<p><strong>Blocage potentiel</strong> : <code>arboard</code> et <code>windows-sys</code> sont Windows-only, il faut du conditional compilation.</p>
<hr>
<h2>🔵 Phase 13 — Application Système (Tray Icon)</h2>
<p><strong>Objectif</strong> : Icône dans la zone de notification Windows avec menu contextuel.</p>
<p><strong>Crate</strong> : <code>tray-icon</code> (déjà dans Cargo.toml)</p>
<hr>
<h2>🔵 Phase 14 — Dashboard Avancé</h2>
<h3>14a — Galerie avec Filtres Avancés</h3>
<li><input type="checkbox" disabled> Filtrer par plage de dates (date picker)</li>
<li><input type="checkbox" disabled> Filtrer par tags (multi-sélection)</li>
<li><input type="checkbox" disabled> Filtrer par statut de processing (pending/done/error)</li>
<li><input type="checkbox" disabled> Trier par date, taille, nom</li>
<h3>14b — Vue Timeline</h3>
<li><input type="checkbox" disabled> Frise chronologique des captures</li>
<li><input type="checkbox" disabled> Regroupement par jour/semaine/mois</li>
<li><input type="checkbox" disabled> Navigation par scroll infini</li>
<h3>14c — Batch Operations</h3>
<li><input type="checkbox" disabled> Sélection multiple d'images (checkboxes)</li>
<li><input type="checkbox" disabled> Suppression en masse</li>
<li><input type="checkbox" disabled> Tag en masse</li>
<li><input type="checkbox" disabled> Export ZIP</li>
<h3>14d — Intégration Hermes Agent</h3>
<li><input type="checkbox" disabled> Endpoint pour qu'Hermes puisse requêter les images</li>
<li><input type="checkbox" disabled> Webhook de notification (nouvelle image → message Telegram)</li>
<li><input type="checkbox" disabled> Skill Hermes <code>imagod-web</code> pour interroger la bibliothèque en langage naturel</li>
<hr>
<h2>🔵 Phase 15 — Client Mobile</h2>
<h3>15a — PWA (Progressive Web App)</h3>
<li><input type="checkbox" disabled> Service worker pour cache offline</li>
<li><input type="checkbox" disabled> Manifest JSON pour installation</li>
<li><input type="checkbox" disabled> Notifications push (nouvelles images)</li>
<h3>15b — Share Intent Android/iOS</h3>
<li><input type="checkbox" disabled> Endpoint API pour recevoir des images depuis le menu &quot;Partager&quot;</li>
<li><input type="checkbox" disabled> Deep link <code>imagod://</code> pour ouverture directe</li>
<hr>
<h2>⚫ Idées Futures (Backlog)</h2>
<li><input type="checkbox" disabled> <strong>OCR Search</strong> — Recherche dans le texte OCR extrait par Imago</li>
<li><input type="checkbox" disabled> <strong>AI Semantic Search</strong> — « trouve les photos de chats dans mon salon »</li>
<li><input type="checkbox" disabled> <strong>Export</strong> — ZIP, galerie HTML statique, PDF contact sheet</li>
<li><input type="checkbox" disabled> <strong>Multi-tenant</strong> — Support de plusieurs clés API / espaces Imago</li>
<li><input type="checkbox" disabled> <strong>Thèmes</strong> — Clair, contrasté, personnalisable</li>
<li><input type="checkbox" disabled> <strong>Deduplication cross-tenant</strong> — Éviter les doublons entre utilisateurs</li>
<li><input type="checkbox" disabled> <strong>Statistiques avancées</strong> — Graphiques (appareils, résolutions, heures de capture)</li>
<li><input type="checkbox" disabled> <strong>Mode hors-ligne</strong> — File d'attente locale quand Imago est inaccessible</li>
<hr>
<h2>📊 Résumé des phases</h2>
<hr>
<h2>🎯 Prochaines actions immédiates (recommandées)</h2>
<p>1. <strong>Corriger le scope <code>images:delete</code></strong> dans l'admin Imago → débloque la suppression</p>
<p>2. <strong>Corriger le stockage Imago</strong> (upload 500) → débloque les tests</p>
<p>3. <del><strong>Implémenter Phase 3</strong> (clipboard watcher)</del> ✅ — 25 juin 2026</p>
<p>4. <del><strong>Implémenter Phase 6</strong> (watcher loop)</del> ✅ — 25 juin 2026</p>
<p>5. <strong>Corriger le backend Imago</strong> (thumbnails, upload, stockage)</p>
<h1>❓ À propos d'imagod-web</h1>
<h2>Qu'est-ce que c'est ?</h2>
<p>
<strong>imagod-web</strong> est une application de bureau (daemon + dashboard web)
qui capture automatiquement vos screenshots et les envoie vers
<a href="https://git.dracodev.net/Projets/Imago" target="_blank">Imago</a>,
un backend intelligent de gestion d'images.
</p>
<div class="highlight">
<strong>🎯 Objectif :</strong> ne plus jamais perdre un screenshot. Chaque capture
est automatiquement analysée (OCR, vision IA, EXIF) et devient consultable
via ce dashboard web.
</div>
<h2>Fonctionnalités</h2>
<ul>
<li><strong>📸 Capture automatique</strong> — Windows : détection clipboard, Linux : surveillance de dossier</li>
<li><strong>🧠 Analyse IA</strong> — description du contenu, tags automatiques, texte OCR</li>
<li><strong>🔍 Recherche puissante</strong> — par nom, tags, description, texte extrait</li>
<li><strong>🏷️ Tags personnalisés</strong> — ajoutez, modifiez, supprimez des tags</li>
<li><strong>📊 Dashboard web</strong> — galerie responsive, upload drag & drop, modale détail</li>
<li><strong>🔄 Temps réel</strong> — WebSocket pour voir les nouvelles captures instantanément</li>
<li><strong>📱 Mobile-friendly</strong> — interface adaptative desktop et mobile</li>
</ul>
<h2>Modes de fonctionnement</h2>
<h3>Windows</h3>
<pre>imagod-web start</pre>
<p>Lance le watcher (surveillance du presse-papier) + dashboard sur <code>http://127.0.0.1:9090</code>.</p>
<h3>Linux / macOS / Serveur</h3>
<pre>imagod-web serve --host 0.0.0.0 --port 9199</pre>
<p>Lance le dashboard + watcher de dossier. Configurez le dossier à surveiller dans <code>~/.config/imagod-web/imagod.toml</code> :</p>
<pre>[watcher]
poll_interval_ms = 1000
watch_dir = "/home/user/Pictures/Screenshots"</pre>
<div class="tip">
<strong>💡 Astuce :</strong> utilisez <code>--no-watcher</code> pour lancer uniquement le dashboard sans surveillance.
</div>
<h2>Raccourcis clavier</h2>
<ul>
<li><code>Ctrl+U</code> — Ouvrir le sélecteur de fichiers</li>
<li><code>Ctrl+V</code> — Coller une image depuis le presse-papier</li>
<li><code>Escape</code> — Fermer la modale</li>
<li><code>← →</code> — Navigation dans la pagination</li>
</ul>
<h2>Architecture</h2>
<pre>
┌─────────────┐ ┌──────────────┐ ┌──────────┐
│ Screenshot │────▶│ imagod-web │────▶│ Imago │
│ (Windows/ │ │ (Rust) │ │ (Python)│
│ Linux) │ │ │ │ │
└─────────────┘ │ • Watcher │ │ • Stock │
│ • Hash │ │ • OCR │
│ • Upload │ │ • IA │
│ • Dashboard │ │ • EXIF │
└──────────────┘ └──────────┘
</pre>
<h2>Liens</h2>
<ul>
<li><a href="https://git.dracodev.net/Projets/imagod-web" target="_blank">📦 Code source imagod-web</a></li>
<li><a href="https://git.dracodev.net/Projets/Imago" target="_blank">🖼️ Backend Imago</a></li>
<li><a href="http://dev.lab.home:3001" target="_blank">⚙️ Admin Imago (clés API)</a></li>
</ul>
<div class="tip">
<strong>📝 Besoin d'aide ?</strong> Contactez Bruno Charest via le repo Gitea pour toute question ou suggestion.
</div>
</main>
<footer>imagod-web v0.2.0 — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
</body>
</html>
+52
View File
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aide & Roadmap — imagod-web v{{VERSION}}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family:'Segoe UI',system-ui,-apple-system,sans-serif; background:#0d1117; color:#c9d1d9; min-height:100vh; }
header { background:#161b22; border-bottom:1px solid #30363d; padding:1rem 1.5rem; display:flex; align-items:center; justify-content:space-between; position:sticky; top:0; z-index:100; }
header h1 { font-size:1.2rem; color:#58a6ff; }
nav { display:flex; gap:0.5rem; }
nav a { color:#8b949e; text-decoration:none; padding:0.5rem 1rem; border-radius:6px; font-size:0.9rem; transition:all .2s; }
nav a:hover, nav a.active { background:#21262d; color:#f0f6fc; }
.version-badge { background:#23863622; color:#3fb950; padding:0.2rem 0.6rem; border-radius:1rem; font-size:0.75rem; border:1px solid #23863644; }
main { max-width:900px; margin:2rem auto; padding:0 1.5rem; }
h2 { color:#f0f6fc; margin:1.5rem 0 1rem; padding-bottom:0.5rem; border-bottom:1px solid #30363d; }
h3 { color:#58a6ff; margin:1rem 0 0.5rem; }
h4 { color:#8b949e; margin:0.5rem 0; }
p { margin:0.5rem 0; line-height:1.6; }
code { background:#161b22; padding:0.15em 0.4em; border-radius:3px; font-size:0.9em; color:#d2a8ff; }
pre { background:#161b22; border:1px solid #30363d; border-radius:6px; padding:1rem; overflow-x:auto; margin:0.75rem 0; }
pre code { background:none; padding:0; color:#c9d1d9; }
li { margin:0.3rem 0 0.3rem 1.5rem; }
li input[type=checkbox] { margin-right:0.5rem; }
table { border-collapse:collapse; width:100%; margin:0.75rem 0; }
th, td { border:1px solid #30363d; padding:0.5rem 0.75rem; text-align:left; font-size:0.9rem; }
th { background:#161b22; color:#f0f6fc; }
hr { border:none; border-top:1px solid #30363d; margin:1.5rem 0; }
a { color:#58a6ff; }
a:hover { text-decoration:underline; }
strong { color:#f0f6fc; }
em { color:#8b949e; }
footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
</style>
</head>
<body>
<header>
<h1>❓ imagod-web <span class="version-badge">v{{VERSION}}</span></h1>
<nav>
<a href="/">🖼️ Galerie</a>
<a href="/changelog">📋 Changelog</a>
<a href="/help" class="active">❓ Aide</a>
</nav>
</header>
<main>
{{HELP_CONTENT}}
</main>
<footer>imagod-web v{{VERSION}} — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
</body>
</html>