Server (Plex/Jellyfin) is the source of truth, so every scanned row carries (server_source, server_id) for upsert + stale-removal — mirroring how music keys on server_source + ratingKey. - schema: server_source/server_id columns on movies/shows/episodes (+ server_id on seasons); unique (server_source,server_id) on movies/shows (multiple NULLs allowed so wishlist rows never block). - VideoDatabase.upsert_movie / upsert_show_tree: take normalized, server- agnostic dicts (a Plex/Jellyfin adapter produces them — DB never touches a media SDK), set has_file + media_files, and prune episodes/seasons the server no longer reports. - prune_missing(): removes top-level movies/shows the scan didn't see (cascades clean children). 6 new tests (insert/update/file-replace, season/episode build+prune, top-level prune); 18 video-DB tests green. |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| music_database.py | ||
| personalized_schema.py | ||
| video_database.py | ||
| video_schema.sql | ||