"""Lectura/escritura de la metadata cacheada de cada juego (info.json + icon.png).""" from __future__ import annotations import json from dataclasses import asdict, dataclass, field from pathlib import Path from .paths import metadata_dir INFO_NAME = "info.json" ICON_NAME = "icon.png" @dataclass class GameMeta: description: str = "" version: str = "" default_branch: str = "main" updated_at: str = "" # ISO-8601; lo rellena el worker tras un update topics: list[str] = field(default_factory=list) # tags de Gitea (controller, sdl3…) created_at: str = "" # ISO-8601 de creación del repo en Gitea (≈ lanzamiento) def info_path(root: Path, game_id: str) -> Path: return metadata_dir(root, game_id) / INFO_NAME def icon_path(root: Path, game_id: str) -> Path: return metadata_dir(root, game_id) / ICON_NAME def load_meta(root: Path, game_id: str) -> GameMeta: """Lee info.json cacheado; devuelve GameMeta vacío si no existe o es ilegible.""" path = info_path(root, game_id) if not path.exists(): return GameMeta() try: data = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): return GameMeta() return GameMeta( description=data.get("description", ""), version=data.get("version", ""), default_branch=data.get("default_branch", "main"), updated_at=data.get("updated_at", ""), topics=list(data.get("topics", [])), created_at=data.get("created_at", ""), ) def save_meta(root: Path, game_id: str, meta: GameMeta) -> None: path = info_path(root, game_id) path.parent.mkdir(parents=True, exist_ok=True) path.write_text( json.dumps(asdict(meta), ensure_ascii=False, indent=2), encoding="utf-8", ) def has_icon(root: Path, game_id: str) -> bool: return icon_path(root, game_id).exists()