From 1766dcfb5f4bd45bb5e5cfbe88e024070a7a6b17 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 30 Mar 2022 20:05:32 +0100 Subject: [PATCH] mkm3u, Makefile: Make `dump' files from the playlists. These are much easier to process than the episode list files, and more informative than M3U files. They'll be fed into a database at some point. --- .gitignore | 3 +++ Makefile | 9 +++++++++ mkm3u | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 8d9d856..56272c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ *.m3u-dep +*.pl-dep *.m3u8 *.m3u8.new +*.pl +*.pl.new !/ref/*.m3u8 /mkm3u.cache diff --git a/Makefile b/Makefile index 37651f1..09537a7 100644 --- a/Makefile +++ b/Makefile @@ -202,6 +202,15 @@ $(M3US): %.m3u8: $$($$*_EPLS) mkm3u mkm3u.cache-stamp $(call v-tag,MKM3U)./mkm3u $(MKM3UFLAGS) $($*_MKM3UFLAGS) \ -M$*.m3u-dep -O$@ -o"$@.new" "$<" && mv "$@.new" "$@" +PLS = $(sort $(foreach p,$(PLAYLISTS), \ + $($p_EPLS:.epls=.pl))) +DEPFILES += $(addsuffix -dep,$(PLS)) +TARGETS += $(PLS) +CLEANFILES += *.pl.new +$(PLS): %.pl: %.epls mkm3u mkm3u.cache-stamp + $(call v-tag,MKPL)./mkm3u -D $(MKM3UFLAGS) $($*_MKM3UFLAGS) \ + -M$*.pl-dep -O$@ -o"$@.new" "$<" && mv "$@.new" "$@" + CHECKS = $(foreach p,$(PLAYLISTS), check/$p) check: $(CHECKS) $(CHECKS): check/%: %.m3u8 diff --git a/mkm3u b/mkm3u index 3eb16b1..596c223 100755 --- a/mkm3u +++ b/mkm3u @@ -44,6 +44,10 @@ def getbool(s): elif s == "nil": return False else: raise ExpectedError("bad boolean `%s'" % s) +def quote(s): + if s is None: return "-" + else: return '"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"' + class Words (object): def __init__(me, s): me._s = s @@ -412,6 +416,7 @@ class Episode (object): me.chapters = [] me.source, me.tno = src, tno me.series_title_p = series_title_p + me.tno, me.start_chapter, me.end_chapter = tno, startch, endch me.url, me.duration = src.url_and_duration(tno, startch, endch) def add_chapter(me, title, j): ch = Chapter(me, title, j) @@ -537,7 +542,38 @@ class Playlist (object): else: for ch in ep.chapters: f.write("#EXTINF:%d,,%s: %s\n%s\n" % - (ch.duration, label, ch.title, ch.url)) + (ch.duration, label, ch.title, ch.url)) + + def dump(me, f): + if me.series_title is not None and \ + me.nseries > 1 and not me.single_series_p: + raise ExpectedError("can't force series name for multi-series list") + six, series = 0, {} + prefix = None + if me.single_series_p: + series["-"] = "S0" + f.write("SERIES S0 %s\n" % quote(me.series_title)) + for season in me.seasons: + for ep in season: + if me.single_series_p: + prefix = ep.season.series.full_title + stag = "S0" + else: + skey = ep.season.series + try: + stag = series[skey] + except KeyError: + stag = "S%d" % six + series[skey] = stag + six += 1 + title = ep.season.series.full_title + if title is None: title = me.series_title + f.write("SERIES %s %s\n" % (stag, quote(title))) + label = ep.label() + if prefix is not None: label = prefix + " " + label + f.write("ENTRY %s %s %s %d %d %d %d\n" % + (stag, quote(label), quote(ep.source.fn), + ep.tno, ep.start_chapter, ep.end_chapter, ep.duration)) def write_deps(me, f, out): deps = set() @@ -853,9 +889,12 @@ class EpisodeListParser (object): return me._pl op = OP.OptionParser \ - (usage = "%prog [-c] [-M DEPS] [-d CACHE] [-o OUT] [-s SERIES] EPLS\n" - "%prog -i -d CACHE", + (usage = "%prog [-Dc] [-M DEPS] [-d CACHE] [-o OUT] [-s SERIES] EPLS\n" + "%prog -i -d CACHE", description = "Generate M3U playlists from an episode list.") +op.add_option("-D", "--dump", + dest = "dump", action = "store_true", default = False, + help = "Dump playlist in machine-readable form") op.add_option("-M", "--make-deps", metavar = "DEPS", dest = "deps", type = "str", default = None, help = "Write a `make' fragment for dependencies") @@ -908,10 +947,12 @@ try: ep.parse_file(argv[0]) pl = ep.done() + if opts.dump: outfn = pl.dump + else: outfn = pl.write if opts.output is None or opts.output == "-": - pl.write(SYS.stdout) + outfn(SYS.stdout) else: - with open(opts.output, "w") as f: pl.write(f) + with open(opts.output, "w") as f: outfn(f) if opts.deps: if opts.deps == "-": -- 2.11.0