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 import File as MutagenFile
|
||||||
from mutagen.easyid3 import EasyID3
|
from mutagen.easyid3 import EasyID3
|
||||||
|
|
||||||
|
from artwork import prepare_artwork_for_track, ArtworkEntry, write_artworkdb
|
||||||
|
|
||||||
_IOP_ROOT = "/tmp/iOpenPod"
|
_IOP_ROOT = "/tmp/iOpenPod"
|
||||||
_IOP_CACHE: dict[str, Any] = {}
|
_IOP_CACHE: dict[str, Any] = {}
|
||||||
_IOP_READY = False
|
_IOP_READY = False
|
||||||
@ -188,7 +190,8 @@ def _read_audio_tags(filepath: str) -> dict[str, Any]:
|
|||||||
|
|
||||||
|
|
||||||
def _scanned_tracks_to_iop(mountpoint: str,
|
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."""
|
"""Convert our scanned track dicts to iOpenPod TrackInfo objects."""
|
||||||
IopTrackInfo = _import_iop("iTunesDB_Writer.mhit_writer").TrackInfo
|
IopTrackInfo = _import_iop("iTunesDB_Writer.mhit_writer").TrackInfo
|
||||||
tracks: list = []
|
tracks: list = []
|
||||||
@ -201,6 +204,12 @@ def _scanned_tracks_to_iop(mountpoint: str,
|
|||||||
location = f":iPod_Control:Music:{rel.replace('/', ':')}"
|
location = f":iPod_Control:Music:{rel.replace('/', ':')}"
|
||||||
size = os.path.getsize(fpath)
|
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(
|
t = IopTrackInfo(
|
||||||
title=s.get("title") or base,
|
title=s.get("title") or base,
|
||||||
location=location,
|
location=location,
|
||||||
@ -219,9 +228,9 @@ def _scanned_tracks_to_iop(mountpoint: str,
|
|||||||
total_tracks=s.get("track_count", 0),
|
total_tracks=s.get("track_count", 0),
|
||||||
disc_number=s.get("disc_number", 0),
|
disc_number=s.get("disc_number", 0),
|
||||||
total_discs=s.get("disc_count", 0),
|
total_discs=s.get("disc_count", 0),
|
||||||
artwork_count=s.get("art_count", 0),
|
artwork_count=art_count,
|
||||||
artwork_size=s.get("art_size", 0),
|
artwork_size=art_size,
|
||||||
mhii_link=s.get("mhii_link", 0),
|
mhii_link=mhii_link,
|
||||||
)
|
)
|
||||||
tracks.append(t)
|
tracks.append(t)
|
||||||
return tracks
|
return tracks
|
||||||
@ -487,11 +496,58 @@ class Nano7Database:
|
|||||||
self._write_empty_databases()
|
self._write_empty_databases()
|
||||||
return
|
return
|
||||||
|
|
||||||
# 2. Convert to iOpenPod TrackInfo
|
# 2. Prepare artwork for all tracks
|
||||||
tracks = _scanned_tracks_to_iop(self.mountpoint, scanned)
|
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))
|
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")
|
ipod_device = _import_iop("ipod_device")
|
||||||
capabilities = None
|
capabilities = None
|
||||||
try:
|
try:
|
||||||
@ -505,7 +561,7 @@ class Nano7Database:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Capabilities detection failed: %s", 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:
|
try:
|
||||||
firewire_id = ipod_device.get_firewire_id(self.mountpoint)
|
firewire_id = ipod_device.get_firewire_id(self.mountpoint)
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -525,7 +581,7 @@ class Nano7Database:
|
|||||||
return
|
return
|
||||||
logger.info("iTunesDB written (%d tracks)", len(tracks))
|
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
|
db_pid = 0
|
||||||
try:
|
try:
|
||||||
ipod_dev = _import_iop("ipod_device")
|
ipod_dev = _import_iop("ipod_device")
|
||||||
@ -539,7 +595,7 @@ class Nano7Database:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("Could not extract db_pid: %s", 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:
|
try:
|
||||||
write_sqlite_databases = _import_iop("SQLiteDB_Writer").write_sqlite_databases
|
write_sqlite_databases = _import_iop("SQLiteDB_Writer").write_sqlite_databases
|
||||||
sqlite_ok = write_sqlite_databases(
|
sqlite_ok = write_sqlite_databases(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user