Fix missing DB tables: container, version_info, db_info, genre_map, extra DBs
- Add container table with Master (iPod) and Music containers - Add version_info, db_info, genre_map, location_kind_map, category_map - Create Dynamic.itdb, Extras.itdb, Genius.itdb with minimal schemas - Insert default container entries with correct PIDs - Nano 7G firmware requires all these for music display
This commit is contained in:
parent
75ea0204ff
commit
29e4cc7398
@ -32,6 +32,38 @@ logger = logging.getLogger(__name__)
|
|||||||
MASTER_CONTAINER_PID = 203092939621887772 # "iPod" master playlist
|
MASTER_CONTAINER_PID = 203092939621887772 # "iPod" master playlist
|
||||||
|
|
||||||
LIBRARY_SCHEMA_SQL = """
|
LIBRARY_SCHEMA_SQL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS version_info (
|
||||||
|
major INTEGER, minor INTEGER, device_update_level INTEGER,
|
||||||
|
platform INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS db_info (
|
||||||
|
primary_container_pid INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS container (
|
||||||
|
pid INTEGER PRIMARY KEY, distinguished_kind INTEGER,
|
||||||
|
is_hidden INTEGER, is_master INTEGER, media_kind INTEGER,
|
||||||
|
name TEXT, parent_pid INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS genre_map (
|
||||||
|
pid INTEGER PRIMARY KEY, name TEXT, name_order INTEGER,
|
||||||
|
has_songs INTEGER, has_music_videos INTEGER, item_count INTEGER,
|
||||||
|
computed_has_songs INTEGER, computed_has_music_videos INTEGER,
|
||||||
|
computed_item_count INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS location_kind_map (
|
||||||
|
pid INTEGER PRIMARY KEY, name TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS category_map (
|
||||||
|
pid INTEGER PRIMARY KEY, name TEXT,
|
||||||
|
is_protected INTEGER, is_subscribed INTEGER,
|
||||||
|
feed_url TEXT, user_pid INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS item (
|
CREATE TABLE IF NOT EXISTS item (
|
||||||
pid INTEGER PRIMARY KEY, media_kind INTEGER, is_song INTEGER,
|
pid INTEGER PRIMARY KEY, media_kind INTEGER, is_song INTEGER,
|
||||||
date_modified INTEGER, year INTEGER, is_compilation INTEGER,
|
date_modified INTEGER, year INTEGER, is_compilation INTEGER,
|
||||||
@ -89,6 +121,36 @@ CREATE TABLE IF NOT EXISTS track_size_calc (
|
|||||||
);
|
);
|
||||||
|
|
||||||
INSERT OR IGNORE INTO track_size_calc (kind, size) VALUES ('audio', 0);
|
INSERT OR IGNORE INTO track_size_calc (kind, size) VALUES ('audio', 0);
|
||||||
|
INSERT OR IGNORE INTO version_info (major, minor, device_update_level, platform) VALUES (1, 111, 1104, 2);
|
||||||
|
INSERT OR IGNORE INTO db_info (primary_container_pid) VALUES (203092939621887772);
|
||||||
|
INSERT OR IGNORE INTO location_kind_map (pid, name) VALUES (1, 'MPEG audio file');
|
||||||
|
INSERT OR IGNORE INTO location_kind_map (pid, name) VALUES (2, 'Purchased AAC audio file');
|
||||||
|
INSERT OR IGNORE INTO location_kind_map (pid, name) VALUES (3, 'AAC audio file');
|
||||||
|
INSERT OR IGNORE INTO container (pid, distinguished_kind, is_hidden, is_master, media_kind, name, parent_pid)
|
||||||
|
VALUES (203092939621887772, 0, 1, 1, 1, 'iPod', NULL);
|
||||||
|
INSERT OR IGNORE INTO container (pid, distinguished_kind, is_hidden, is_master, media_kind, name, parent_pid)
|
||||||
|
VALUES (4872745547565090077, 4, 1, 0, 1, 'Music', NULL);
|
||||||
|
"""
|
||||||
|
|
||||||
|
DYNAMIC_SCHEMA_SQL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS item (
|
||||||
|
item_pid INTEGER PRIMARY KEY, play_count INTEGER,
|
||||||
|
last_played_date INTEGER, skip_count INTEGER,
|
||||||
|
rating INTEGER, bookmark INTEGER
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXTRAS_SCHEMA_SQL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS item (
|
||||||
|
item_pid INTEGER PRIMARY KEY, lyrics TEXT,
|
||||||
|
chapter_data BLOB, description TEXT
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
GENIUS_SCHEMA_SQL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS item (
|
||||||
|
item_pid INTEGER PRIMARY KEY
|
||||||
|
);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LOCATIONS_SCHEMA_SQL = """
|
LOCATIONS_SCHEMA_SQL = """
|
||||||
@ -135,21 +197,26 @@ class Nano7Database:
|
|||||||
self._ensure_schema()
|
self._ensure_schema()
|
||||||
|
|
||||||
def _ensure_schema(self) -> None:
|
def _ensure_schema(self) -> None:
|
||||||
"""Create required tables in Library.itdb and Locations.itdb if missing."""
|
"""Create required tables in all SQLite databases on the iPod."""
|
||||||
sqlite_path = self.sqlite_path
|
itlp_dir = os.path.join(self.itunes_dir, "iTunes Library.itlp")
|
||||||
locations_path = self.locations_path
|
os.makedirs(itlp_dir, exist_ok=True)
|
||||||
|
os.makedirs(os.path.dirname(self.locations_path), exist_ok=True)
|
||||||
|
|
||||||
for db_path, schema in [(sqlite_path, LIBRARY_SCHEMA_SQL),
|
dbs = [
|
||||||
(locations_path, LOCATIONS_SCHEMA_SQL)]:
|
(self.sqlite_path, LIBRARY_SCHEMA_SQL),
|
||||||
|
(self.locations_path, LOCATIONS_SCHEMA_SQL),
|
||||||
|
(os.path.join(itlp_dir, "Dynamic.itdb"), DYNAMIC_SCHEMA_SQL),
|
||||||
|
(os.path.join(itlp_dir, "Extras.itdb"), EXTRAS_SCHEMA_SQL),
|
||||||
|
(os.path.join(itlp_dir, "Genius.itdb"), GENIUS_SCHEMA_SQL),
|
||||||
|
]
|
||||||
|
for db_path, schema in dbs:
|
||||||
try:
|
try:
|
||||||
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
|
||||||
conn = sqlite3.connect(db_path)
|
conn = sqlite3.connect(db_path)
|
||||||
conn.executescript(schema)
|
conn.executescript(schema)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
logger.info(f"Schema ensured in {os.path.basename(db_path)}")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Failed to ensure schema in {db_path}: {e}")
|
logger.warning(f"Failed to ensure schema in {os.path.basename(db_path)}: {e}")
|
||||||
|
|
||||||
def _detect_firewire_id(self) -> bytes:
|
def _detect_firewire_id(self) -> bytes:
|
||||||
"""Parse FirewireGuid from SysInfo file on the iPod."""
|
"""Parse FirewireGuid from SysInfo file on the iPod."""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user