"""Seed the Space's journal DB with the demo entries. The Space prefers a pre-built SQLite snapshot when one is present, but it can also fall back to the JSON-backed demo seed from `engine.store`. That keeps the Space publishable without checking a large binary DB into the Hugging Face repo. Idempotent: if the user's home DB already has entries, seeding is skipped. """ from __future__ import annotations import os import shutil import time from pathlib import Path # Resolve paths relative to this file. On the Space, all files land at /app/, # so the prebuilt DB is a sibling of seed_data.py. In dev, we also try the # repo root. _SPACE_DIR = Path(__file__).resolve().parent DEFAULT_DB_SIBLING = _SPACE_DIR / "data" / "journal_preloaded.db" DEFAULT_DB_REPOROOT = _SPACE_DIR.parent / "data" / "journal_preloaded.db" def _resolve_prebuilt_db() -> Path | None: if DEFAULT_DB_SIBLING.exists(): return DEFAULT_DB_SIBLING if DEFAULT_DB_REPOROOT.exists(): return DEFAULT_DB_REPOROOT return None def seed_journal(target_db_path: str | os.PathLike) -> int: """Copy the pre-built journal DB to the user's home directory. Idempotent: if the target DB already has entries, this is a no-op. Returns the number of entries in the target DB after seeding. """ target = Path(target_db_path) target.parent.mkdir(parents=True, exist_ok=True) # Check if the target already has entries (idempotent) if target.exists(): try: import sqlite3 conn = sqlite3.connect(str(target)) existing = conn.execute("SELECT COUNT(*) FROM entries").fetchone()[0] conn.close() if existing >= 1: print(f"[seed_data] target DB already has {existing} entries; skipping copy") return existing except Exception as exc: print(f"[seed_data] could not check target DB: {exc}") prebuilt = _resolve_prebuilt_db() if prebuilt is None: print("[seed_data] no prebuilt DB found; seeding from JSON demo data") try: from engine.store import seed_demo_data except Exception as exc: print(f"[seed_data] could not import JSON seed helper: {exc}") return 0 t0 = time.time() n = seed_demo_data(target) elapsed = time.time() - t0 print(f"[seed_data] seeded {n} entries from JSON in {elapsed:.2f}s") return n print(f"[seed_data] copying prebuilt DB: {prebuilt} -> {target}") t0 = time.time() shutil.copy2(str(prebuilt), str(target)) elapsed = time.time() - t0 # Count entries import sqlite3 conn = sqlite3.connect(str(target)) n = conn.execute("SELECT COUNT(*) FROM entries").fetchone()[0] conn.close() print(f"[seed_data] seeded {n} entries in {elapsed:.2f}s (file copy)") return n # --------------------------------------------------------------------------- # # Sync seed_journal signature for backward-compat with calls that pass `store` # --------------------------------------------------------------------------- # def seed_journal_compat(store=None, json_path=None, max_entries=50): """Backward-compat wrapper for the old seed_journal(store, ...) API. Tries to use the prebuilt DB; falls back to no-op if not present. """ if store is not None: try: db_path = store.db_path except AttributeError: return 0 return seed_journal(db_path) return 0 if __name__ == "__main__": # Smoke test: copy the prebuilt DB to a temp location and count. import sys target = sys.argv[1] if len(sys.argv) > 1 else str(Path.home() / ".pocket-confidant" / "journal.db") n = seed_journal(target) print(f"OK: {n} entries at {target}")