video scan: don't crash on episodes with no episode number
Plex specials/unmatched episodes can have a null index -> getattr(...,0) still returned None -> 'NOT NULL constraint failed: episodes.episode_number'. - Plex adapter skips episodes with no index (logged), passes a real number. - upsert_show_tree defensively skips any episode missing season/episode number, so no source can crash a scan. Test added.
This commit is contained in:
parent
bc334df719
commit
061079f0f6
3 changed files with 21 additions and 4 deletions
|
|
@ -122,13 +122,13 @@ class PlexVideoSource:
|
|||
"file": self._part_file(m),
|
||||
}
|
||||
|
||||
def _episode(self, ep, snum) -> dict:
|
||||
def _episode(self, ep, snum, enum) -> dict:
|
||||
dur = getattr(ep, "duration", None)
|
||||
aired = getattr(ep, "originallyAvailableAt", None)
|
||||
return {
|
||||
"server_id": str(ep.ratingKey),
|
||||
"season_number": snum,
|
||||
"episode_number": getattr(ep, "index", 0),
|
||||
"episode_number": enum,
|
||||
"title": ep.title,
|
||||
"overview": getattr(ep, "summary", None),
|
||||
"air_date": aired.date().isoformat() if aired else None,
|
||||
|
|
@ -142,8 +142,12 @@ class PlexVideoSource:
|
|||
seasons_map = {}
|
||||
try:
|
||||
for ep in sh.episodes():
|
||||
enum = getattr(ep, "index", None)
|
||||
if enum is None:
|
||||
# No episode number (unmatched/special) — can't key it; skip.
|
||||
continue
|
||||
snum = ep.parentIndex if getattr(ep, "parentIndex", None) is not None else 0
|
||||
seasons_map.setdefault(snum, []).append(self._episode(ep, snum))
|
||||
seasons_map.setdefault(snum, []).append(self._episode(ep, snum, enum))
|
||||
except Exception:
|
||||
logger.exception("Plex: failed reading episodes for %s", getattr(sh, "title", "?"))
|
||||
seasons = [{"server_id": None, "season_number": n, "title": None,
|
||||
|
|
|
|||
|
|
@ -252,7 +252,9 @@ class VideoDatabase:
|
|||
).fetchone()["id"]
|
||||
|
||||
for ep in season.get("episodes", []):
|
||||
enum = ep["episode_number"]
|
||||
enum = ep.get("episode_number")
|
||||
if enum is None or snum is None:
|
||||
continue # can't key an episode without season+episode numbers
|
||||
seen_eps.add((snum, enum))
|
||||
conn.execute(
|
||||
"INSERT INTO episodes (show_id, season_id, server_source, server_id, "
|
||||
|
|
|
|||
|
|
@ -216,6 +216,17 @@ def test_upsert_show_tree_builds_seasons_episodes_and_prunes(db):
|
|||
assert eps == [1]
|
||||
|
||||
|
||||
def test_upsert_show_tree_skips_episodes_without_number(db):
|
||||
sid = db.upsert_show_tree("plex", {"server_id": "s1", "title": "S", "seasons": [
|
||||
{"season_number": 1, "episodes": [
|
||||
{"episode_number": 1, "title": "E1"},
|
||||
{"episode_number": None, "title": "Unmatched special"}]}]})
|
||||
with db.connect() as c:
|
||||
eps = [r["episode_number"] for r in c.execute(
|
||||
"SELECT episode_number FROM episodes WHERE show_id=?", (sid,)).fetchall()]
|
||||
assert eps == [1]
|
||||
|
||||
|
||||
def test_prune_missing_removes_unseen_top_level(db):
|
||||
db.upsert_movie("plex", {"server_id": "a", "title": "A"})
|
||||
db.upsert_movie("plex", {"server_id": "b", "title": "B"})
|
||||
|
|
|
|||
Loading…
Reference in a new issue