fix: UUID→fichier via API photobooth (created_at/processed), photo_id dans print_queue
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled

This commit is contained in:
2026-07-17 16:44:33 +02:00
parent 4592f20be3
commit 742186ec8e
4 changed files with 86 additions and 94 deletions
+23
View File
@@ -53,6 +53,29 @@ class PhotoboothService:
items = await self.get_media_collection(limit=1)
return items[0] if items else None
async def get_media_item(self, media_id: str) -> dict | None:
"""Retourne les détails complets d'un item (id, created_at, processed, ...)."""
try:
r = await self._client.get(f"/api/mediacollection/{media_id}")
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()
except Exception as e:
logger.error("Erreur récupération item %s: %s", media_id, e)
return None
def media_file_path(self, item: dict) -> Path | None:
"""Retourne le chemin absolu du fichier traité depuis le champ 'processed' d'un item.
photobooth-app retourne 'processed': 'media/processed_full/YYYYMMDD-HHMMSS-xxx.jpg'
On préfixe avec data_dir pour obtenir le chemin complet.
"""
processed = item.get("processed")
if not processed:
return None
return Path(self._cfg.data_dir) / processed
async def delete_media(self, media_id: str) -> bool:
"""Supprime une photo via l'API photobooth-app."""
try:
+23 -15
View File
@@ -21,6 +21,7 @@ PrintStatus = Literal["pending", "printing", "done", "cancelled", "error"]
CREATE_SQL = """
CREATE TABLE IF NOT EXISTS print_queue (
id TEXT PRIMARY KEY,
photo_id TEXT,
filename TEXT NOT NULL,
thumb_url TEXT,
copies INTEGER DEFAULT 1,
@@ -46,6 +47,12 @@ class PrinterService:
self._db = await aiosqlite.connect(str(db_path))
self._db.row_factory = aiosqlite.Row
await self._db.execute(CREATE_SQL)
# Migration : ajoute photo_id si la colonne n'existe pas encore
try:
await self._db.execute("ALTER TABLE print_queue ADD COLUMN photo_id TEXT")
logger.info("Migration : colonne photo_id ajoutée à print_queue")
except Exception:
pass # Colonne déjà présente
await self._db.commit()
logger.info("Base print_queue initialisée: %s", db_path)
@@ -55,20 +62,23 @@ class PrinterService:
# ── File d'attente ────────────────────────────────────────────────────────
async def add_request(self, filename: str, thumb_url: str = "", copies: int = 1) -> dict:
async def add_request(
self, filename: str, thumb_url: str = "", copies: int = 1, photo_id: str = ""
) -> dict:
"""Ajoute une demande d'impression dans la file. Retourne l'entrée créée."""
entry_id = str(uuid.uuid4())
now = time.time()
await self._db.execute(
"INSERT INTO print_queue (id, filename, thumb_url, copies, status, requested_at) "
"VALUES (?, ?, ?, ?, 'pending', ?)",
(entry_id, filename, thumb_url, copies, now),
"INSERT INTO print_queue (id, photo_id, filename, thumb_url, copies, status, requested_at) "
"VALUES (?, ?, ?, ?, ?, 'pending', ?)",
(entry_id, photo_id, filename, thumb_url, copies, now),
)
await self._db.commit()
entry = {
"id": entry_id,
"photo_id": photo_id,
"filename": filename,
"thumb_url": thumb_url,
"copies": copies,
@@ -101,29 +111,27 @@ class PrinterService:
return await self.get_queue("pending")
async def get_pending_by_photo_id(self) -> dict[str, list]:
"""Retourne un dict {photo_id_stem: [entries]} pour toutes les demandes actives.
"""Retourne un dict {photo_id: [entries]} pour toutes les demandes actives.
Permet à la galerie admin de savoir quelles photos ont une demande en attente
sans modifier le schéma SQLite — on match par stem du filename.
Utilise le champ photo_id (UUID photobooth-app) s'il est renseigné,
sinon fall-back sur le stem du filename.
"""
rows = await self.get_queue("pending")
# Aussi inclure celles "printing" (en cours d'impression)
rows += await self.get_queue("printing")
result: dict[str, list] = {}
for r in rows:
from pathlib import Path
stem = Path(r["filename"]).stem
result.setdefault(stem, []).append(r)
key = r.get("photo_id") or Path(r["filename"]).stem
result.setdefault(key, []).append(r)
return result
async def cancel_by_photo_id(self, photo_stem: str) -> int:
"""Annule toutes les demandes pending pour un photo_id donné. Retourne le nb annulé."""
async def cancel_by_photo_id(self, photo_id: str) -> int:
"""Annule toutes les demandes pending pour un photo_id (UUID) donné."""
pending = await self.get_queue("pending")
from pathlib import Path
cancelled = 0
for r in pending:
if Path(r["filename"]).stem == photo_stem:
key = r.get("photo_id") or Path(r["filename"]).stem
if key == photo_id:
ok = await self.cancel(r["id"])
if ok:
cancelled += 1