X-Git-Url: https://git.distorted.org.uk/~mdw/epls/blobdiff_plain/9b82ff075c7dfbaf6b5588c4a6d7b9675409bf47..d5c4caf19d8d804da5da1e29852f66601a97a2d8:/mkm3u diff --git a/mkm3u b/mkm3u index 7583937..f99d8ca 100755 --- a/mkm3u +++ b/mkm3u @@ -149,28 +149,28 @@ class VideoSeason (object): raise ExpectedError("season %d episode %d already taken" % (me.i, i)) me.episodes[i] = disc; disc.neps += 1 -def some_group(m, *gg): - for g in gg: - s = m.group(g) +def match_group(m, *groups, dflt = None, mustp = False): + for g in groups: + try: s = m.group(g) + except IndexError: continue if s is not None: return s - return None + if mustp: raise ValueError("no match found") + else: return dflt class VideoDir (object): - _R_ISO_PRE = RX.compile(r""" ^ - (?: S (?P \d+) - (?: \. \ (?P .*) — (?: D \d+ \. \ )? | - D \d+ \. \ | - (?= E \d+ \. \ ) | - \. \ ) | - (?P \d+) \. \ ) - (?: (?P - (?: S \d+ \ )? E \d+ (?: – \d+)? - (?: , \ (?: S \d+ \ )? E \d+ (?: – \d+)?)*) | - (?P E \d+) \. \ .* | - .*) - \. iso $ - """, RX.X) + _R_ISO_PRE = list(map(lambda pats: + list(map(lambda pat: + RX.compile("^" + pat + r"\.iso$", RX.X), + pats)), + [[r""" S (?P \d+) \. \ (?P .*) — (?: D \d+ \. \ )? + (?P .*) """, + r""" S (?P \d+) (?: D \d+)? \. \ (?P .*) """, + r""" S (?P \d+) \. \ (?P E \d+ .*) """, + r""" S (?P \d+) (?P E \d+) \. \ .* """], + [r""" (?P \d+) [A-Z]? \. \ (?P .*) — (?P .*) """], + [r""" \d+ \. \ (?P [ES] \d+ .*) """], + [r""" (?P \d+ ) \. \ .* """]])) _R_ISO_EP = RX.compile(r""" ^ (?: S (?P \d+) \ )? @@ -183,25 +183,34 @@ class VideoDir (object): fns.sort() season = None seasons = {} + styles = me._R_ISO_PRE for fn in fns: path = OS.path.join(dir, fn) if not fn.endswith(".iso"): continue - m = me._R_ISO_PRE.match(fn) - if not m: - #print(";; `%s' ignored (regex mismatch)" % path, file = SYS.stderr) + #print(";; `%s'" % path, file = SYS.stderr) + for sty in styles: + for r in sty: + m = r.match(fn) + if m: styles = [sty]; break + else: + continue + break + else: + #print(";;\tignored (regex mismatch)", file = SYS.stderr) continue - i = filter(m.group("si"), int) - stitle = m.group("st") - check(i is not None or stitle is None, + si = filter(match_group(m, "si"), int) + stitle = match_group(m, "stitle") + + check(si 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, + if si is not None: + if season is None or si != season.i: + check(season is None or si == 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) + (si, season is None and -1 or season.i + 1)) + check(si not in seasons, "season %d already seen" % si) + seasons[si] = season = VideoSeason(si, stitle) else: check(stitle == season.title, "season title `%s' /= `%s'" % (stitle, season.title)) @@ -209,14 +218,9 @@ class VideoDir (object): disc = VideoDisc(path) ts = season any, bad = False, False - epname = m.group("epname") - epexpr = m.group("eplist") - epnum = m.group("epnum") - if epname is not None: eplist = [epname] - elif epexpr is not None: eplist = epexpr.split(", ") - elif epnum is not None: eplist = ["E" + epnum] - else: continue - #print(";; `%s'" % path, file = SYS.stderr) + epnum = match_group(m, "epnum") + if epnum is not None: eplist = ["E" + epnum] + else: eplist = match_group(m, "epex", mustp = True).split(", ") for eprange in eplist: mm = me._R_ISO_EP.match(eprange) if mm is None: @@ -235,7 +239,7 @@ class VideoDir (object): ts.set_episode_disc(k, disc) #print(";;\tepisode %d.%d" % (ts.i, k), file = SYS.stderr) if not any: - #print(";;\tignored" % path, file = SYS.stderr) + #print(";;\tignored", file = SYS.stderr) pass elif bad: raise ExpectedError("bad ep list in `%s'", fn) @@ -245,9 +249,7 @@ class AudioDisc (Source): PREFIX = "file://" TITLEP = CHAPTERP = False -class AudioEpisode (Source): - PREFIX = "file://" - TITLEP = CHAPTERP = False +class AudioEpisode (AudioDisc): def __init__(me, fn, i, *args, **kw): super().__init__(fn, *args, **kw) me.i = i @@ -284,12 +286,13 @@ class Chapter (object): me.url = episode.source.url(episode.tno, i, i + 1) class Episode (object): - def __init__(me, season, i, neps, title, src, tno = None, startch = None): + def __init__(me, season, i, neps, title, src, tno = None, + startch = None, endch = None): me.season = season me.i, me.neps, me.title = i, neps, title me.chapters = [] me.source, me.tno = src, tno - me.url = src.url(tno, startch, None) + me.url = src.url(tno, startch, endch) def add_chapter(me, title, j): ch = Chapter(me, title, j) me.chapters.append(ch) @@ -303,8 +306,8 @@ class BaseSeason (object): me.episodes = [] me.implicitp = implicitp me.ep_i, episodes = 1, [] - def add_episode(me, j, neps, title, src, tno, startch): - ep = Episode(me, j, neps, title, src, tno, startch) + def add_episode(me, j, neps, title, src, tno, startch, endch): + ep = Episode(me, j, neps, title, src, tno, startch, endch) me.episodes.append(ep) src.nuses += neps; me.ep_i += neps return ep @@ -335,10 +338,10 @@ class MovieSeason (BaseSeason): super().__init__(series, *args, **kw) me.title = title me.i = None - def add_episode(me, j, neps, title, src, tno, startch): + def add_episode(me, j, neps, title, src, tno, startch, endch): if me.title is None and title is None: raise ExpectedError("movie or movie season must have a title") - return super().add_episode(j, neps, title, src, tno, startch) + return super().add_episode(j, neps, title, src, tno, startch, endch) def _eplabel(me, i, neps, title): if me.title is None: label = title @@ -541,7 +544,7 @@ class EpisodeListParser (object): def _process_episode(me, ww): opts = ww.nextword(); check(opts is not None, "missing title/options") - ti = None; sname = None; neps = 1; epi = None; ch = None + ti = None; sname = None; neps = 1; epi = None; loch = hich = None for k, v in me._keyvals(opts): if k is None: if v.isdigit(): ti = int(v) @@ -550,7 +553,10 @@ class EpisodeListParser (object): elif k == "s": sname = v elif k == "n": neps = getint(v) elif k == "ep": epi = getint(v) - elif k == "ch": ch = getint(v) + elif k == "ch": + try: sep = v.index("-") + except ValueError: loch, hich = getint(v), None + else: loch, hich = getint(v[:sep]), getint(v[sep + 1:]) + 1 else: raise ExpectedError("unknown episode option `%s'" % k) check(ti is not None, "missing title number") series = me._get_series(sname) @@ -572,7 +578,7 @@ class EpisodeListParser (object): try: src = me._isos[series.name] except KeyError: src = me._auto_epsrc(series) - episode = season.add_episode(epi, neps, title, src, ti, ch) + episode = season.add_episode(epi, neps, title, src, ti, loch, hich) me._pl.add_episode(episode) me._cur_episode = episode