Initial commit
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
"""Ingest clrmamepro .dat files into the SQLite library database.
|
||||
|
||||
Usage::
|
||||
|
||||
python -m app.ingest [--dats data/dats] [--db data/library.sqlite]
|
||||
"""
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from . import config, matcher
|
||||
from .dat_parser import parse_dat_file
|
||||
from .db import get_connection, init_db
|
||||
|
||||
|
||||
def _norm_hex(value):
|
||||
if not value:
|
||||
return None
|
||||
return str(value).strip().upper()
|
||||
|
||||
|
||||
def detect_system(dat_name):
|
||||
if "UMD Video" in dat_name:
|
||||
return "videos"
|
||||
if "PlayStation Portable" in dat_name:
|
||||
return "games"
|
||||
return "unknown"
|
||||
|
||||
|
||||
def ingest_dat(conn, path):
|
||||
header, entries = parse_dat_file(path)
|
||||
dat_name = header.get("name") if header else path.stem
|
||||
version = header.get("version") if header else None
|
||||
description = header.get("description") if header else None
|
||||
system = detect_system(dat_name)
|
||||
|
||||
existing = conn.execute("SELECT id FROM dats WHERE name = ?", (dat_name,)).fetchone()
|
||||
if existing:
|
||||
dat_id = existing["id"]
|
||||
conn.execute("DELETE FROM roms WHERE release_id IN (SELECT id FROM releases WHERE dat_id = ?)", (dat_id,))
|
||||
conn.execute("DELETE FROM releases WHERE dat_id = ?", (dat_id,))
|
||||
conn.execute(
|
||||
"UPDATE dats SET version=?, description=?, system=?, source_path=?, ingested_at=datetime('now') WHERE id=?",
|
||||
(version, description, system, str(path), dat_id),
|
||||
)
|
||||
else:
|
||||
cur = conn.execute(
|
||||
"INSERT INTO dats (name, version, description, system, source_path, ingested_at) VALUES (?,?,?,?,?,datetime('now'))",
|
||||
(dat_name, version, description, system, str(path)),
|
||||
)
|
||||
dat_id = cur.lastrowid
|
||||
|
||||
release_count = 0
|
||||
rom_count = 0
|
||||
for entry in entries:
|
||||
cur = conn.execute(
|
||||
"INSERT INTO releases (dat_id, name, description, region, serial) VALUES (?,?,?,?,?)",
|
||||
(dat_id, entry.get("name"), entry.get("description"), entry.get("region"), entry.get("serial")),
|
||||
)
|
||||
release_id = cur.lastrowid
|
||||
release_count += 1
|
||||
for rom in entry.get("rom", []):
|
||||
size = rom.get("size")
|
||||
conn.execute(
|
||||
"INSERT INTO roms (release_id, name, size, crc32, md5, sha1, serial) VALUES (?,?,?,?,?,?,?)",
|
||||
(
|
||||
release_id,
|
||||
rom.get("name"),
|
||||
int(size) if size else None,
|
||||
_norm_hex(rom.get("crc")),
|
||||
_norm_hex(rom.get("md5")),
|
||||
_norm_hex(rom.get("sha1")),
|
||||
rom.get("serial"),
|
||||
),
|
||||
)
|
||||
rom_count += 1
|
||||
|
||||
matcher.clear_cache()
|
||||
return dat_name, system, release_count, rom_count
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(description="Ingest clrmamepro DAT files into SQLite")
|
||||
parser.add_argument("--dats", help="directory containing .dat files (default: data/dats)")
|
||||
parser.add_argument("--db", help="SQLite database path (default: data/library.sqlite)")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
dats_dir = Path(args.dats) if args.dats else config.DATS_DIR
|
||||
db_path = Path(args.db) if args.db else config.DB_PATH
|
||||
|
||||
conn = init_db(db_path)
|
||||
files = sorted(dats_dir.glob("*.dat"))
|
||||
if not files:
|
||||
print(f"No .dat files found in {dats_dir}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
for path in files:
|
||||
dat_name, system, releases, roms = ingest_dat(conn, path)
|
||||
print(f"{dat_name} [{system}] -> {releases} releases, {roms} roms")
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print(f"\nLibrary written to {db_path}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user