feat: integrate artwork module into sync pipeline for Nano 7G
This commit is contained in:
parent
9da689782a
commit
71928d3478
@ -35,6 +35,8 @@ from typing import Any, Optional
|
||||
from mutagen import File as MutagenFile
|
||||
from mutagen.easyid3 import EasyID3
|
||||
|
||||
from artwork import prepare_artwork_for_track, ArtworkEntry, write_artworkdb
|
||||
|
||||
_IOP_ROOT = "/tmp/iOpenPod"
|
||||
_IOP_CACHE: dict[str, Any] = {}
|
||||
_IOP_READY = False
|
||||
@ -188,7 +190,8 @@ def _read_audio_tags(filepath: str) -> dict[str, Any]:
|
||||
|
||||
|
||||
def _scanned_tracks_to_iop(mountpoint: str,
|
||||
scanned: list[dict]) -> list:
|
||||
scanned: list[dict],
|
||||
artwork_map: dict[str, tuple[int, int, int]] | None = None) -> list:
|
||||
"""Convert our scanned track dicts to iOpenPod TrackInfo objects."""
|
||||
IopTrackInfo = _import_iop("iTunesDB_Writer.mhit_writer").TrackInfo
|
||||
tracks: list = []
|
||||
@ -201,6 +204,12 @@ def _scanned_tracks_to_iop(mountpoint: str,
|
||||
location = f":iPod_Control:Music:{rel.replace('/', ':')}"
|
||||
size = os.path.getsize(fpath)
|
||||
|
||||
art_count = 0
|
||||
art_size = 0
|
||||
mhii_link = 0
|
||||
if artwork_map and fpath in artwork_map:
|
||||
mhii_link, art_count, art_size = artwork_map[fpath]
|
||||
|
||||
t = IopTrackInfo(
|
||||
title=s.get("title") or base,
|
||||
location=location,
|
||||
@ -219,9 +228,9 @@ def _scanned_tracks_to_iop(mountpoint: str,
|
||||
total_tracks=s.get("track_count", 0),
|
||||
disc_number=s.get("disc_number", 0),
|
||||
total_discs=s.get("disc_count", 0),
|
||||
artwork_count=s.get("art_count", 0),
|
||||
artwork_size=s.get("art_size", 0),
|
||||
mhii_link=s.get("mhii_link", 0),
|
||||
artwork_count=art_count,
|
||||
artwork_size=art_size,
|
||||
mhii_link=mhii_link,
|
||||
)
|
||||
tracks.append(t)
|
||||
return tracks
|
||||
@ -487,11 +496,58 @@ class Nano7Database:
|
||||
self._write_empty_databases()
|
||||
return
|
||||
|
||||
# 2. Convert to iOpenPod TrackInfo
|
||||
tracks = _scanned_tracks_to_iop(self.mountpoint, scanned)
|
||||
# 2. Prepare artwork for all tracks
|
||||
artwork_map: dict[str, tuple[int, int, int]] = {}
|
||||
art_entries: list[ArtworkEntry] = []
|
||||
art_hash_to_img_id: dict[str, int] = {}
|
||||
next_img_id = 100
|
||||
|
||||
for idx, s in enumerate(scanned):
|
||||
fpath = s["file_path"]
|
||||
try:
|
||||
art_result = prepare_artwork_for_track(fpath)
|
||||
except Exception:
|
||||
art_result = None
|
||||
if art_result is not None:
|
||||
art_hash, formats = art_result
|
||||
art_count = len(formats)
|
||||
total_size = sum(p.size for p in formats.values())
|
||||
|
||||
if art_hash not in art_hash_to_img_id:
|
||||
img_id = next_img_id
|
||||
next_img_id += 1
|
||||
art_hash_to_img_id[art_hash] = img_id
|
||||
art_entries.append(ArtworkEntry(
|
||||
img_id=img_id,
|
||||
db_track_id=idx,
|
||||
art_hash=art_hash,
|
||||
src_img_size=total_size,
|
||||
formats=formats,
|
||||
db_track_ids=[idx],
|
||||
))
|
||||
else:
|
||||
img_id = art_hash_to_img_id[art_hash]
|
||||
for entry in art_entries:
|
||||
if entry.img_id == img_id:
|
||||
if idx not in entry.db_track_ids:
|
||||
entry.db_track_ids.append(idx)
|
||||
break
|
||||
|
||||
artwork_map[fpath] = (img_id, art_count, total_size)
|
||||
|
||||
if art_entries:
|
||||
try:
|
||||
write_artworkdb(self.mountpoint, art_entries)
|
||||
logger.info("ArtworkDB written: %d unique covers, %d total tracks",
|
||||
len(art_entries), len(artwork_map))
|
||||
except Exception as e:
|
||||
logger.warning("ArtworkDB write failed: %s", e)
|
||||
|
||||
# 3. Convert to iOpenPod TrackInfo
|
||||
tracks = _scanned_tracks_to_iop(self.mountpoint, scanned, artwork_map)
|
||||
logger.info("Built %d iOpenPod TrackInfo objects", len(tracks))
|
||||
|
||||
# 3. Determine capabilities for this device
|
||||
# 4. Determine capabilities for this device
|
||||
ipod_device = _import_iop("ipod_device")
|
||||
capabilities = None
|
||||
try:
|
||||
@ -505,7 +561,7 @@ class Nano7Database:
|
||||
except Exception as e:
|
||||
logger.debug("Capabilities detection failed: %s", e)
|
||||
|
||||
# 4. Generate and write binary iTunesDB first (to get db_pid)
|
||||
# 5. Generate and write binary iTunesDB first (to get db_pid)
|
||||
try:
|
||||
firewire_id = ipod_device.get_firewire_id(self.mountpoint)
|
||||
except Exception:
|
||||
@ -525,7 +581,7 @@ class Nano7Database:
|
||||
return
|
||||
logger.info("iTunesDB written (%d tracks)", len(tracks))
|
||||
|
||||
# 5. Extract db_pid from the binary DB for SQLite cross-reference
|
||||
# 6. Extract db_pid from the binary DB for SQLite cross-reference
|
||||
db_pid = 0
|
||||
try:
|
||||
ipod_dev = _import_iop("ipod_device")
|
||||
@ -539,7 +595,7 @@ class Nano7Database:
|
||||
except Exception as e:
|
||||
logger.warning("Could not extract db_pid: %s", e)
|
||||
|
||||
# 6. Write SQLite databases (Nano 6G/7G require this)
|
||||
# 7. Write SQLite databases (Nano 6G/7G require this)
|
||||
try:
|
||||
write_sqlite_databases = _import_iop("SQLiteDB_Writer").write_sqlite_databases
|
||||
sqlite_ok = write_sqlite_databases(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user