"""What the TUI knows about the server's books beyond the files: title, author, read status and which books exist at all (so a book can be listed before it is downloaded). Set only by `sync`; the reader's position is progress.py. """ from __future__ import annotations import json import os from pathlib import Path from . import paths _DATA_DIR = paths.data_dir() _META_FILE = _DATA_DIR / "library.json" def _load_all() -> dict[str, dict]: try: data = json.loads(_META_FILE.read_text()) except (OSError, ValueError): return {} return data if isinstance(data, dict) else {} def _save_all(data: dict[str, dict]) -> None: _DATA_DIR.mkdir(parents=True, exist_ok=True) tmp = _META_FILE.with_suffix(".tmp") tmp.write_text(json.dumps(data, indent=1)) os.replace(tmp, _META_FILE) def is_read(book_key: str) -> bool: entry = _load_all().get(book_key) return bool(entry and entry.get("is_read")) def get(book_key: str) -> dict | None: return _load_all().get(book_key) def remote_entries() -> dict[str, dict]: """Every server book: key -> {server_id, title, author, is_read, uploaded_at}.""" return {k: v for k, v in _load_all().items() if isinstance(v, dict) and v.get("server_id") is not None} def set_remote(entries: dict[str, dict]) -> None: """Replace the server books with `entries` (a book deleted on the server drops out).""" data = {k: v for k, v in _load_all().items() if not (isinstance(v, dict) and v.get("server_id") is not None)} data.update(entries) _save_all(data)