Share Pastebin
Guest
Public paste!

Untitled

By: a guest | May 4th, 2010 | Syntax: Python | Size: 7.57 KB | Hits: 48 | Expires: Never
Copy text to clipboard
  1. #!/usr/bin/env python
  2.  
  3.  
  4. # NOTE: this script requires MythTV 0.23+fixes r24420 or newer.
  5. # For older versions, you can try applying this patch to the python bindings:
  6. #   http://svn.mythtv.org/trac/changeset/24420
  7.  
  8.  
  9. # schema version that this code expects
  10. schema_version = 1000
  11.  
  12.  
  13. # default number of timeout days
  14. timeout = 30
  15.  
  16.  
  17. # if any of these are not None, the given value(s) will be used to create a
  18. # database connection
  19. dbhost = None
  20. dbname = None
  21. dbuser = None
  22. dbpass = None
  23.  
  24.  
  25. # includes
  26. from sys import argv, exit
  27. from optparse import OptionParser
  28. from MythTV import OldRecorded
  29. from MythTV import MythDB, MythLog
  30.  
  31.  
  32. # print optional message, usage info, and then exit with the given code or not
  33. def __usage(exitmsg='', exitcode=0, shouldexit=True):
  34.   if len(exitmsg): print exitmsg
  35.   print 'Usage: %s [options]' % argv[0]
  36.   if shouldexit: exit(exitcode)
  37.  
  38.  
  39. # utility funciton: sotr list of commands by priority
  40. def __commandprioritycmp(a, b):
  41.   return cmp(a[1], b[1])
  42.  
  43.  
  44. # utility funciton: connect and return a MythDB object
  45. def __db_connect(schemacheck=True):
  46.  
  47.   # connect
  48.   args = []
  49.   if dbhost: args.append( ('DBHostName', dbhost) )
  50.   if dbname: args.append( ('DBName', dbname) )
  51.   if dbuser: args.append( ('DBUserName', dbuser) )
  52.   if dbpass: args.append( ('DBPassword', dbpass) )
  53.   db = MythDB(args=args)
  54.   log = MythLog(module='RerecordLater', lstr='important')
  55.  
  56.   # schema version check
  57.   if schemacheck:
  58.  
  59.     if db.settings.NULL.RerecordLaterDBSchemaVer == None:
  60.  
  61.       # first time run, auto install
  62.       log(
  63.         MythLog.IMPORTANT,
  64.         'RerecordLater database does not exist, creating it.'
  65.       )
  66.       action_install(db)
  67.  
  68.     else:
  69.  
  70.       dbversion = int(db.settings.NULL.RerecordLaterDBSchemaVer)
  71.  
  72.       # db schema too new ?
  73.       if dbversion > schema_version:
  74.         log(
  75.           MythLog.IMPORTANT,
  76.           'The schema version in the database (%d) is newer than the RerecordLater program (%d). Please update to the appropriate version of RerecordLater.' %
  77.           ( dbversion, schema_version )
  78.         )
  79.         exit(3)
  80.  
  81.       # db schema too old?
  82.       elif dbversion < schema_version:
  83.         log(
  84.           MythLog.IMPORTANT,
  85.           'The schema version in the database (%d) is older than the RerecordLater program (%d). Updating it.' %
  86.           ( dbversion, schema_version )
  87.         )
  88.         action_database_upgrade(db)
  89.  
  90.       # correct db schema version?
  91.       else:
  92.         pass
  93.  
  94.   return db
  95.  
  96.  
  97. # --help handler
  98. def action_help():
  99.   __usage('', 0, False)
  100.   # TODO: iterate ARGT and print a nice list
  101.   exit(0)
  102.  
  103.  
  104. # --rerecord handler
  105. def action_rerecord(chanid, starttime):
  106.  
  107.   db = __db_connect()
  108.  
  109.   # search for old recordings with chanid/starttime
  110.   q = db.searchOldRecorded(chanid=chanid, starttime=starttime)
  111.   if q:
  112.     for oldrec in q:
  113.       if not oldrec.duplicate:
  114.         # This recording was set to re-record. this is where we take action.
  115.         # It is told *not* to rerecord now and will be flipped back on after
  116.         # the timeout period.
  117.         db.cursor().execute("""
  118.          INSERT INTO rerecordlater
  119.          SET
  120.            chanid = %d,
  121.             starttime = "%s",
  122.             timeout = NOW() + INTERVAL %d DAY
  123.        """ % ( chanid, starttime, timeout ) )
  124.         oldrec.setDuplicate(True)
  125.  
  126.  
  127. # --reschedule handler
  128. def action_reschedule():
  129.  
  130.   # connect
  131.   db = __db_connect()
  132.   c = db.cursor()
  133.  
  134.   # get rerecordlater records where the timeout has expired
  135.   c.execute("""
  136.    SELECT chanid, starttime
  137.    FROM rerecordlater
  138.    WHERE timeout <= NOW()
  139.  """)
  140.   for rec in c.fetchall():
  141.     # find the oldrecorded record and re-allow dupes.
  142.     q = db.searchOldRecorded(chanid=rec[0], starttime=rec[1])
  143.     for oldrec in q: oldrec.setDuplicate(False)
  144.     c.execute("""
  145.      DELETE FROM rerecordlater
  146.      WHERE chanid = %d AND starttime = "%s"
  147.    """ % ( rec[0], rec[1] ) )
  148.  
  149.  
  150. # --legacy handler
  151. def action_legacy():
  152.   # Find recordings that were set to duplicate
  153.   q = db.searchOldRecorded(duplicate=0)
  154.   for oldrec in q: action_rerecord(oldrec.chanid, oldrec.starttime)
  155.  
  156.  
  157. # --install handler
  158. def action_install(db=None):
  159.   if not db: db = __db_connect(schemacheck=False)
  160.   db.cursor().execute("""
  161.    CREATE TABLE IF NOT EXISTS rerecordlater(
  162.      chanid INT(10) UNSIGNED,
  163.      starttime datetime,
  164.      timeout datetime
  165.    )
  166.  """)
  167.   db.settings.NULL.RerecordLaterDBSchemaVer = schema_version
  168.  
  169.  
  170. # --database-upgrade handler
  171. def action_database_upgrade(db=None):
  172.   if not db: db = __db_connect()
  173.   # TODO: update system when needed. The idea is to iterate
  174.   # from db_schema_version+1 through the current version and
  175.   # execute a function called database_upgrade_[n] where [n]
  176.   # is a particular schema version. Each of these functions
  177.   # should have the ability to update the database from the
  178.   # previous version, so executing them in a row will upgrade
  179.   # from whatever the current db version is to current schema.
  180.  
  181.  
  182. # main
  183. if __name__ == '__main__':
  184.  
  185.   argc = len(argv)
  186.   if argc < 2: __usage()
  187.  
  188.   parser = OptionParser()
  189.   parser.add_option(
  190.     '-a', '--legacy', dest='legacy', action='store_true', default=False,
  191.     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.'
  192.   )
  193.   parser.add_option(
  194.     '-r', '--reschedule', dest='reschedule', action='store_true', default=False,
  195.     help='Mark programs where the timeout has expired as OK to re-record. Run daily. Recommended: put --reschedule on the "mythfilldatabase ran" system event.'
  196.   )
  197.   parser.add_option(
  198.     '-i', '--install', dest='install', action='store_true', default=False,
  199.     help='Initialize the database. If it already exists, does nothing. Happens automatically if the program is run without an existing database.'
  200.   )
  201.   parser.add_option(
  202.     '-g', '--database-upgrade', dest='upgrade', action='store_true', default=False,
  203.     help='upgrade the database to the current schema version (NOTE: currently not implemented)'
  204.   )
  205.   parser.add_option(
  206.     '-t', '--timeout', dest='timeout', type='int', metavar='LEVEL',
  207.     help='number of days before marked programs will time out'
  208.   )
  209.   parser.add_option(
  210.     '-o', '--host', dest='host', metavar='HOST',
  211.     help='database host'
  212.   )
  213.   parser.add_option(
  214.     '-d', '--database', dest='database', metavar='NAME',
  215.     help='database name'
  216.   )
  217.   parser.add_option(
  218.     '-u', '--user', dest='user', metavar='USER',
  219.     help='database user'
  220.   )
  221.   parser.add_option(
  222.     '-p', '--password', dest='password', metavar='PASSWORD',
  223.     help='database password'
  224.   )
  225.   parser.add_option(
  226.     '-l', '--log-level', dest='loglevel', metavar='LEVEL',
  227.     help='set the log level'
  228.   )
  229.   (options, args) = parser.parse_args()
  230.  
  231.   # run configuration
  232.   if options.timeout: timeout = options.timeout
  233.   if options.host: dbhost = options.host
  234.   if options.database: dbname = options.database
  235.   if options.user: dbuser = options.user
  236.   if options.password: dbpass = options.password
  237.   if options.loglevel: MythLog._setlevel(options.loglevel)
  238.  
  239.   # actions
  240.   if options.legacy: action_legacy()
  241.   if options.reschedule: action_reschedule()
  242.   if options.install: action_install()
  243.   if options.upgrade: action_database_upgrade()
  244.  
  245.   if len(args) % 2 != 0:
  246.     usage(
  247.       'There must be an even number of positional arguments. Specify one or more sets of {chanid starttime} after other options are specified.'
  248.     )
  249.  
  250.   for i in range(0, len(args), 2):
  251.     chanid = int(args[i])
  252.     starttime = args[i+1]
  253.     action_rerecord(chanid, starttime)