mkm3u: Improve the episode-list parser some more.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 14 Mar 2022 15:01:00 +0000 (15:01 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 14 Mar 2022 15:01:00 +0000 (15:01 +0000)
Now it can change season in mid-flight.

mkm3u

diff --git a/mkm3u b/mkm3u
index e250c41..0b5b800 100755 (executable)
--- a/mkm3u
+++ b/mkm3u
@@ -147,6 +147,7 @@ class VideoDir (object):
   """, RX.X)
 
   _R_ISO_EP = RX.compile(r""" ^
+        (?: S (?P<si> \d+) \ )?
         E (?P<ei> \d+) (?: – (?P<ej> \d+))? $
   """, RX.X)
 
@@ -154,7 +155,7 @@ class VideoDir (object):
     me.dir = dir
     fns = OS.listdir(OS.path.join(ROOT, dir))
     fns.sort()
-    season, last_j = None, 0
+    season = None
     seasons = {}
     for fn in fns:
       path = OS.path.join(dir, fn)
@@ -162,35 +163,40 @@ class VideoDir (object):
       m = me._R_ISO_PRE.match(fn)
       if not m: continue
 
-      i = filter(m.group("si"), int, 1)
+      i = filter(m.group("si"), int)
       stitle = m.group("st")
-      if season is None or i != season.i:
-        check(season is None or i == season.i + 1,
-              "season %d /= %d" % (i, season is None and -1 or season.i + 1))
-        check(i not in seasons, "season %d already seen" % i)
-        seasons[i] = season = VideoSeason(i, stitle)
-        last_j = 0
-      else:
-        check(stitle == season.title,
-              "season title `%s' /= `%s'" % (stitle, season.title))
-      j = filter(some_group(m, "sdi", "di"), int)
-      if j is not None:
-        check(j == last_j + 1,
-              "season %d disc %d /= %d" % (season.i, j, last_j + 1))
+      check(i is not None or stitle is None,
+            "explicit season title without number in `%s'" % fn)
+      if i is not None:
+        if season is None or i != season.i:
+          check(season is None or i == season.i + 1,
+                "season %d /= %d" %
+                  (i, season is None and -1 or season.i + 1))
+          check(i not in seasons, "season %d already seen" % i)
+          seasons[i] = season = VideoSeason(i, stitle)
+        else:
+          check(stitle == season.title,
+                "season title `%s' /= `%s'" % (stitle, season.title))
 
       disc = VideoDisc(path)
+      ts = season
       any, bad = False, False
       for eprange in m.group("eps").split(", "):
         mm = me._R_ISO_EP.match(eprange)
         if mm is None: bad = True; continue
+        i = filter(mm.group("si"), int)
+        if i is not None:
+          try: ts = seasons[i]
+          except KeyError: ts = seasons[i] = VideoSeason(i, None)
+        if ts is None:
+          ts = season = seasons[1] = VideoSeason(1, None)
         start = filter(mm.group("ei"), int)
         end = filter(mm.group("ej"), int, start)
         for k in range(start, end + 1):
-          season.set_episode_disc(k, disc)
+          ts.set_episode_disc(k, disc)
         any = True
       if bad and any:
         raise ExpectedError("bad ep list in `%s'", fn)
-      last_j = j
     me.seasons = seasons
 
 class AudioDisc (Source):