### -*- mode: python; coding: utf-8 -*-
from contextlib import contextmanager
+import errno as E
import optparse as OP
import os as OS
import re as RX
+import sqlite3 as SQL
import subprocess as SP
import sys as SYS
LOC = DummyLocation()
+ROOT = "/mnt/dvd/archive/"
+DB = None
+
+def init_db(fn):
+ global DB
+ DB = SQL.connect(fn)
+ DB.cursor().execute("PRAGMA journal_mode = WAL")
+
+def setup_db(fn):
+ try: OS.unlink(fn)
+ except OSError as e:
+ if e.errno == E.ENOENT: pass
+ else: raise
+ init_db(fn)
+ DB.cursor().execute("""
+ CREATE TABLE duration
+ (path TEXT NOT NULL,
+ title INTEGER NOT NULL,
+ start_chapter INTEGER NOT NULL,
+ end_chapter INTEGER NOT NULL,
+ inode INTEGER NOT NULL,
+ device INTEGER NOT NULL,
+ size INTEGER NOT NULL,
+ mtime REAL NOT NULL,
+ duration REAL NOT NULL,
+ PRIMARY KEY (path, title, start_chapter, end_chapter));
+ """)
+
class Source (object):
PREFIX = ""
TITLEP = CHAPTERP = False
else:
suffix = "#%d:%d-%d:%d" % (title, start_chapter, title, end_chapter - 1)
- duration = me._duration(title, start_chapter, end_chapter)
+ duration = None
+ if DB is None:
+ duration = me._duration(title, start_chapter, end_chapter)
+ else:
+ st = OS.stat(OS.path.join(ROOT, me.fn))
+ duration = None
+ c = DB.cursor()
+ c.execute("""
+ SELECT device, inode, size, mtime, duration FROM duration
+ WHERE path = ? AND title = ? AND
+ start_chapter = ? AND end_chapter = ?
+ """, [me.fn, title, start_chapter is None and -1 or start_chapter,
+ end_chapter is None and -1 or end_chapter])
+ row = c.fetchone()
+ foundp = False
+ if row is None:
+ duration = me._duration(title, start_chapter, end_chapter)
+ c.execute("""
+ INSERT OR REPLACE INTO duration
+ (path, title, start_chapter, end_chapter,
+ device, inode, size, mtime, duration)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+ """, [me.fn, title, start_chapter is None and -1 or start_chapter,
+ end_chapter is None and -1 or end_chapter,
+ st.st_dev, st.st_ino, st.st_size, st.st_mtime,
+ duration])
+ else:
+ dev, ino, sz, mt, d = row
+ if (dev, ino, sz, mt) == \
+ (st.st_dev, st.st_ino, st.st_size, st.st_mtime):
+ duration = d
+ else:
+ duration = me._duration(title, start_chapter, end_chapter)
+ c.execute("""
+ UPDATE duration
+ SET device = ?, inode = ?, size = ?, mtime = ?, duration = ?
+ WHERE path = ? AND title = ? AND
+ start_chapter = ? AND end_chapter = ?
+ """, [st.st_dev, st.st_dev, st.st_size, st.st_mtime, duration,
+ me.fn, title, start_chapter is None and -1 or start_chapter,
+ end_chapter is None and -1 or end_chapter])
+ DB.commit()
if end_chapter is not None:
keys = [(title, ch) for ch in range(start_chapter, end_chapter)]
(d.fn, d.neps, d.nuses))
return me._pl
-ROOT = "/mnt/dvd/archive/"
-
op = OP.OptionParser \
- (usage = "%prog [-c] [-s SERIES] EPLS",
+ (usage = "%prog [-c] [-d CACHE] [-s SERIES] EPLS\n"
+ "%prog -i -d CACHE",
description = "Generate M3U playlists from an episode list.")
op.add_option("-c", "--chapters",
dest = "chaptersp", action = "store_true", default = False,
help = "Output individual chapter names")
+op.add_option("-i", "--init-db",
+ dest = "initdbp", action = "store_true", default = False,
+ help = "Initialize the database")
+op.add_option("-d", "--database",
+ dest = "database", type = "str", default = None,
+ help = "Set filename for cache database")
op.add_option("-s", "--series",
dest = "series", type = "str", default = None,
help = "Output only the listed SERIES (comma-separated)")
-opts, argv = op.parse_args()
-if len(argv) != 1: op.print_usage(file = SYS.stderr); SYS.exit(2)
-if opts.series is None:
- series_wanted = None
-else:
- series_wanted = set()
- for name in opts.series.split(","): series_wanted.add(name)
try:
- ep = EpisodeListParser(series_wanted, opts.chaptersp)
- ep.parse_file(argv[0])
- pl = ep.done()
- pl.write(SYS.stdout)
+ opts, argv = op.parse_args()
+ if opts.initdbp:
+ if opts.chaptersp or opts.series is not None or \
+ opts.database is None or len(argv):
+ op.print_usage(file = SYS.stderr); SYS.exit(2)
+ setup_db(opts.database)
+ else:
+ if len(argv) != 1: op.print_usage(file = SYS.stderr); SYS.exit(2)
+ if opts.database is not None: init_db(opts.database)
+ if opts.series is None:
+ series_wanted = None
+ else:
+ series_wanted = set()
+ for name in opts.series.split(","): series_wanted.add(name)
+ ep = EpisodeListParser(series_wanted, opts.chaptersp)
+ ep.parse_file(argv[0])
+ pl = ep.done()
+ pl.write(SYS.stdout)
except (ExpectedError, IOError, OSError) as e:
LOC.report(e)
SYS.exit(2)