#!/usr/bin/env python
# NOTE: this script requires MythTV 0.23+fixes r24420 or newer.
# For older versions, you can try applying this patch to the python bindings:
# http://svn.mythtv.org/trac/changeset/24420
# schema version that this code expects
schema_version = 1000
# default number of timeout days
timeout = 30
# if any of these are not None, the given value(s) will be used to create a
# database connection
dbhost = None
dbname = None
dbuser = None
dbpass = None
# includes
from sys import argv, exit
from optparse import OptionParser
from MythTV import OldRecorded
from MythTV import MythDB, MythLog
# print optional message, usage info, and then exit with the given code or not
def __usage(exitmsg='', exitcode=0, shouldexit=True):
if len(exitmsg): print exitmsg
print 'Usage: %s [options]' % argv[0]
if shouldexit: exit(exitcode)
# utility funciton: sotr list of commands by priority
def __commandprioritycmp(a, b):
return cmp(a[1], b[1])
# utility funciton: connect and return a MythDB object
def __db_connect(schemacheck=True):
# connect
args = []
if dbhost: args.append( ('DBHostName', dbhost) )
if dbname: args.append( ('DBName', dbname) )
if dbuser: args.append( ('DBUserName', dbuser) )
if dbpass: args.append( ('DBPassword', dbpass) )
db = MythDB(args=args)
log = MythLog(module='RerecordLater', lstr='important')
# schema version check
if schemacheck:
if db.settings.NULL.RerecordLaterDBSchemaVer == None:
# first time run, auto install
log(
MythLog.IMPORTANT,
'RerecordLater database does not exist, creating it.'
)
action_install(db)
else:
dbversion = int(db.settings.NULL.RerecordLaterDBSchemaVer)
# db schema too new ?
if dbversion > schema_version:
log(
MythLog.IMPORTANT,
'The schema version in the database (%d) is newer than the RerecordLater program (%d). Please update to the appropriate version of RerecordLater.' %
( dbversion, schema_version )
)
exit(3)
# db schema too old?
elif dbversion < schema_version:
log(
MythLog.IMPORTANT,
'The schema version in the database (%d) is older than the RerecordLater program (%d). Updating it.' %
( dbversion, schema_version )
)
action_database_upgrade(db)
# correct db schema version?
else:
pass
return db
# --help handler
def action_help():
__usage('', 0, False)
# TODO: iterate ARGT and print a nice list
exit(0)
# --rerecord handler
def action_rerecord(chanid, starttime):
db = __db_connect()
# search for old recordings with chanid/starttime
q = db.searchOldRecorded(chanid=chanid, starttime=starttime)
if q:
for oldrec in q:
if not oldrec.duplicate:
# This recording was set to re-record. this is where we take action.
# It is told *not* to rerecord now and will be flipped back on after
# the timeout period.
db.cursor().execute("""
INSERT INTO rerecordlater
SET
chanid = %d,
starttime = "%s",
timeout = NOW() + INTERVAL %d DAY
""" % ( chanid, starttime, timeout ) )
oldrec.setDuplicate(True)
# --reschedule handler
def action_reschedule():
# connect
db = __db_connect()
c = db.cursor()
# get rerecordlater records where the timeout has expired
c.execute("""
SELECT chanid, starttime
FROM rerecordlater
WHERE timeout <= NOW()
""")
for rec in c.fetchall():
# find the oldrecorded record and re-allow dupes.
q = db.searchOldRecorded(chanid=rec[0], starttime=rec[1])
for oldrec in q: oldrec.setDuplicate(False)
c.execute("""
DELETE FROM rerecordlater
WHERE chanid = %d AND starttime = "%s"
""" % ( rec[0], rec[1] ) )
# --legacy handler
def action_legacy():
# Find recordings that were set to duplicate
q = db.searchOldRecorded(duplicate=0)
for oldrec in q: action_rerecord(oldrec.chanid, oldrec.starttime)
# --install handler
def action_install(db=None):
if not db: db = __db_connect(schemacheck=False)
db.cursor().execute("""
CREATE TABLE IF NOT EXISTS rerecordlater(
chanid INT(10) UNSIGNED,
starttime datetime,
timeout datetime
)
""")
db.settings.NULL.RerecordLaterDBSchemaVer = schema_version
# --database-upgrade handler
def action_database_upgrade(db=None):
if not db: db = __db_connect()
# TODO: update system when needed. The idea is to iterate
# from db_schema_version+1 through the current version and
# execute a function called database_upgrade_[n] where [n]
# is a particular schema version. Each of these functions
# should have the ability to update the database from the
# previous version, so executing them in a row will upgrade
# from whatever the current db version is to current schema.
# main
if __name__ == '__main__':
argc = len(argv)
if argc < 2: __usage()
parser = OptionParser()
parser.add_option(
'-a', '--legacy', dest='legacy', action='store_true', default=False,
help='Add programs that are marked re-recordable and are not already handled by this script. Use this to seed the database at installation time.'
)
parser.add_option(
'-r', '--reschedule', dest='reschedule', action='store_true', default=False,
help='Mark programs where the timeout has expired as OK to re-record. Run daily. Recommended: put --reschedule on the "mythfilldatabase ran" system event.'
)
parser.add_option(
'-i', '--install', dest='install', action='store_true', default=False,
help='Initialize the database. If it already exists, does nothing. Happens automatically if the program is run without an existing database.'
)
parser.add_option(
'-g', '--database-upgrade', dest='upgrade', action='store_true', default=False,
help='upgrade the database to the current schema version (NOTE: currently not implemented)'
)
parser.add_option(
'-t', '--timeout', dest='timeout', type='int', metavar='LEVEL',
help='number of days before marked programs will time out'
)
parser.add_option(
'-o', '--host', dest='host', metavar='HOST',
help='database host'
)
parser.add_option(
'-d', '--database', dest='database', metavar='NAME',
help='database name'
)
parser.add_option(
'-u', '--user', dest='user', metavar='USER',
help='database user'
)
parser.add_option(
'-p', '--password', dest='password', metavar='PASSWORD',
help='database password'
)
parser.add_option(
'-l', '--log-level', dest='loglevel', metavar='LEVEL',
help='set the log level'
)
(options, args) = parser.parse_args()
# run configuration
if options.timeout: timeout = options.timeout
if options.host: dbhost = options.host
if options.database: dbname = options.database
if options.user: dbuser = options.user
if options.password: dbpass = options.password
if options.loglevel: MythLog._setlevel(options.loglevel)
# actions
if options.legacy: action_legacy()
if options.reschedule: action_reschedule()
if options.install: action_install()
if options.upgrade: action_database_upgrade()
if len(args) % 2 != 0:
usage(
'There must be an even number of positional arguments. Specify one or more sets of {chanid starttime} after other options are specified.'
)
for i in range(0, len(args), 2):
chanid = int(args[i])
starttime = args[i+1]
action_rerecord(chanid, starttime)