Wire the incremental pipeline to real sources and expose two workflows. Config (Env.py): three explicit paths — LOCAL_LIBRARY_PATH (scan source), ITUNES_XML_PATH (manual export), DATA_DIR (storage root: DB + Spotify cache). Real, incremental ingesters: - local_scan: walks the library, skips files whose mtime/size are unchanged, prunes deleted ones, and reads embedded ISRC + recording MBID from tags (tagged files get real IDs with no network), via tags.py. - itunes_xml: parse the iTunes Library.xml as a plist; skip if mtime unchanged. - spotify_raw: ingest raw Spotify JSON (ISRC from external_ids); live fetch wrapper for when credentials are set. Workflows (src/workflows.py + main.py): - `fetch` — pull + scan + parse + enrich + match, with readable step logs. First run is slow (full scan + MB lookups); later runs only touch changes (verified: ~71s first, ~0.6s second). - `display` — launch the GUI. Also: enrich uses ISRC-first again (local MBIDs now come from tags), fix --enrich-limit 0, quiet musicbrainzngs XML warnings, ignore /data/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
38 lines
1,003 B
Python
38 lines
1,003 B
Python
"""Engine/session helpers. The DB URL comes from Env.database_url so the same
|
|
code runs on SQLite (default) or Postgres by changing one env var."""
|
|
from contextlib import contextmanager
|
|
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from Env import database_url
|
|
from src.db.models import Base
|
|
|
|
_engine = create_engine(database_url, future=True)
|
|
SessionLocal = sessionmaker(bind=_engine, future=True, expire_on_commit=False)
|
|
|
|
|
|
def get_engine():
|
|
return _engine
|
|
|
|
|
|
def init_db():
|
|
"""Create the storage dir + tables if missing (safe to call every run)."""
|
|
from Env import data_dir
|
|
|
|
data_dir.mkdir(parents=True, exist_ok=True)
|
|
Base.metadata.create_all(_engine)
|
|
|
|
|
|
@contextmanager
|
|
def session_scope():
|
|
"""Transactional session: commit on success, roll back on error."""
|
|
session = SessionLocal()
|
|
try:
|
|
yield session
|
|
session.commit()
|
|
except Exception:
|
|
session.rollback()
|
|
raise
|
|
finally:
|
|
session.close()
|