def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option('--chanid', action='store', type='int', dest='chanid', help='Use chanid for manual operation') parser.add_option('--starttime', action='store', type='int', dest='starttime', help='Use starttime for manual operation') #MythLog.loadOptParse(parser) #MythLog._optparseinput() MythLog._setpath('/tmp') opts, args = parser.parse_args() j = TranscodeJob() try: if len(args) == 1: j.run(jobid=args[0]) elif opts.chanid and opts.starttime: j.run(chanid=opts.chanid, starttime=opts.starttime) else: print 'Script must be provided jobid, or chanid and starttime.' sys.exit(1) except: j.logTB() sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option('--chanid', action='store', type='int', dest='chanid', help='Use chanid with both starttime and tzoffset for manual operation') parser.add_option('--starttime', action='store', type='string', dest='starttime', help='Use starttime with both chanid and tzoffset for manual operation') parser.add_option('--tzoffset', action='store', type='int', dest='tzoffset', help='Use tzoffset with both chanid and starttime for manual operation') parser.add_option('-v', '--verbose', action='store', type='string', dest='verbose', help='Verbosity level') opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if len(args) == 1: runjob(jobid=args[0]) elif opts.chanid and opts.starttime and opts.tzoffset is not None: runjob(chanid=opts.chanid, starttime=opts.starttime, tzoffset=opts.tzoffset) else: print 'Script must be provided jobid, or chanid, starttime and timezone offset.' sys.exit(1)
def initializeMythDB(self): ''' Import the MythTV database bindings return nothing ''' try: from MythTV import MythDB, MythLog, MythError try: '''Create an instance of each: MythDB ''' MythLog._setlevel( 'none' ) # Some non option -M cannot have any logging on stdout self.mythdb = MythDB() except MythError as e: sys.stderr.write('\n! Error - %s\n' % e.args[0]) filename = os.path.expanduser("~") + '/.mythtv/config.xml' if not os.path.isfile(filename): sys.stderr.write( '\n! Error - A correctly configured (%s) file must exist\n' % filename) else: sys.stderr.write( '\n! Error - Check that (%s) is correctly configured\n' % filename) sys.exit(1) except Exception as e: sys.stderr.write( "\n! Error - Creating an instance caused an error for one of: MythDB. error(%s)\n" % e) sys.exit(1) except Exception as e: sys.stderr.write( "\n! Error - MythTV python bindings could not be imported. error(%s)\n" % e) sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option('--chanid', action='store', type='int', dest='chanid', help='Use chanid for manual operation') parser.add_option('--starttime', action='store', type='int', dest='starttime', help='Use starttime for manual operation') parser.add_option('-v', '--verbose', action='store', type='string', dest='verbose', help='Verbosity level') opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if len(args) == 1: runjob(jobid=args[0]) elif opts.chanid and opts.starttime: runjob(chanid=opts.chanid, starttime=opts.starttime) else: print 'Script must be provided jobid, or chanid and starttime.' sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option("-f", "--helpformat", action="store_true", default=False, dest="fmthelp", help="Print explination of file format string.") parser.add_option("-p", "--printformat", action="store_true", default=False, dest="fmtprint", help="Print current file format string.") parser.add_option("--tformat", action="store", type="string", dest="tformat", help="Use TV format for current task. If no task, store in database.") parser.add_option("--mformat", action="store", type="string", dest="mformat", help="Use Movie format for current task. If no task, store in database.") parser.add_option("--gformat", action="store", type="string", dest="gformat", help="Use Generic format for current task. If no task, store in database.") parser.add_option("--chanid", action="store", type="int", dest="chanid", help="Use chanid for manual operation") parser.add_option("--starttime", action="store", type="int", dest="starttime", help="Use starttime for manual operation") parser.add_option("--listingonly", action="store_true", default=False, dest="listingonly", help="Use data from listing provider, rather than grabber") parser.add_option("--seekdata", action="store_true", default=False, dest="seekdata", help="Copy seekdata from source recording.") parser.add_option("--skiplist", action="store_true", default=False, dest="skiplist", help="Copy commercial detection from source recording.") parser.add_option("--cutlist", action="store_true", default=False, dest="cutlist", help="Copy manual commercial cuts from source recording.") parser.add_option('-v', '--verbose', action='store', type='string', dest='verbose', help='Verbosity level') opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if opts.fmthelp: usage_format() sys.exit(0) if opts.fmtprint: print_format() sys.exit(0) if opts.chanid and opts.starttime: export = VIDEO(opts) elif len(args) == 1: try: export = VIDEO(opts, int(args[0])) except Exception, e: Job(int(args[0])).update({'status':304, 'comment':'ERROR: ' + e.args[0]}) MythLog(module='mythvidexport.py').logTB(MythLog.IMPORTANT) sys.exit(1)
def test_Logging_Basic_002_01(self): """Test if options can be modified from MythTV.MythLog.""" m = MythLog('simple_test') m._setmask("most") # check the modified mask: self.assertEqual(m._MASK, LOGMASK.MOST) # check the default level: self.assertEqual(m._LEVEL, LOGLEVEL.INFO) # check the default file: self.assertTrue('stdout' in repr(m._LOGFILE)) m._setlevel("notice") # check the modified mask: self.assertEqual(m._MASK, LOGMASK.MOST) # check the modified level: self.assertEqual(m._LEVEL, LOGLEVEL.NOTICE) # check the default file: self.assertTrue('stdout' in repr(m._LOGFILE)) m._setfile("/tmp/my_logfile") # check the modified mask: self.assertEqual(m._MASK, LOGMASK.MOST) # check the modified level: self.assertEqual(m._LEVEL, LOGLEVEL.NOTICE) # check the modified file: self.assertTrue(os.path.exists("/tmp/my_logfile"))
def main(): """Startup function.""" parser = OptionParser(usage="usage: %prog [options]") parser.add_option( "--verbose", action="store_true", default=False, help="enable verbose output of MythTV API") parser.add_option( '-f', "--force", action="store_true", default=False, help="non-interactive mode, answer 'yes' to all questions") parser.add_option( '-t', "--title", action="store", type="string", help="limit recordings that match title") opts, _ = parser.parse_args() MythLog._setlevel('unknown' if opts.verbose else 'err') # pylint:disable=protected-access try: backend = MythBE() recs = [ r for r in list(backend.getRecordings()) if r.recgroup == 'Deleted' ] if opts.title: recs = [ r for r in recs if re.findall(opts.title, r.title, re.IGNORECASE) ] if len(recs) == 0: print('no matching recordings found') sys.exit(0) if opts.force: undelete_all(backend, recs) else: interactive_undelete(backend, recs) except MythDBError as e: if e.name == 'DB_CREDENTIALS': print("ERROR: Could not find MythDB host:port OR correct login " "credentials!") sys.exit(-1) else: raise sys.exit(0)
def main(): """Startup function.""" parser = OptionParser(usage="usage: %prog [options]") parser.add_option("--verbose", action="store_true", default=False, help="enable verbose output of MythTV API") parser.add_option( '-f', "--force", action="store_true", default=False, help="non-interactive mode, answer 'yes' to all questions") parser.add_option('-t', "--title", action="store", type="string", help="limit recordings that match title") opts, _ = parser.parse_args() MythLog._setlevel('unknown' if opts.verbose else 'err') # pylint:disable=protected-access try: backend = MythBE() recs = [ r for r in list(backend.getRecordings()) if r.recgroup == 'Deleted' ] if opts.title: recs = [ r for r in recs if re.findall(opts.title, r.title, re.IGNORECASE) ] if len(recs) == 0: print('no matching recordings found') sys.exit(0) if opts.force: undelete_all(backend, recs) else: interactive_undelete(backend, recs) except MythDBError as e: if e.name == 'DB_CREDENTIALS': print("ERROR: Could not find MythDB host:port OR correct login " "credentials!") sys.exit(-1) else: raise sys.exit(0)
class TranscodeJob: def __init__(self): self.l = MythLog('transcode.py', db=self.db()) def db(self): return MythDB() def log(self, message, level=LOGLEVEL.INFO, detail=None): return self.l.log(LOGMASK.GENERAL, level, message, detail) def logTB(self): return self.l.logTB(LOGMASK.GENERAL) def run(self, jobid=None, chanid=None, starttime=None): if jobid: job = Job(jobid, db=self.db()) chanid = job.chanid starttime = job.starttime rec = Recorded((chanid, starttime), db=self.db()) sg = mythproto.findfile(rec.basename, rec.storagegroup, db=self.db()) if sg is None: self.log('Local access to recording not found.', LOGLEVEL.ERR) sys.exit(1) infile = os.path.join(sg.dirname, rec.basename) #### list of segments to be cut # rec.markup.gencutlist() #### list of segments to keep # rec.markup.genuncutlist() del(rec) task = System(path=TRANSCODER, db=self.db()) try: outfile = task(infile).strip() if not os.path.exists(outfile): raise OSError('output file %s not found' % repr(outfile)) except MythError, e: self.log('Transcode failed with output:', LOGLEVEL.ERR, task.stderr) sys.exit(task.returncode) except OSError, e: self.log('Transcode failed to produce an output file:', LOGLEVEL.ERR, repr(e)) sys.exit(1)
def run_debug(): MythLog._setfile('/var/log/mythtv/mythfs.log') MythLog._setlevel('important,general,file') fs = DebugFS() fs.fsinit() banner = 'MythTV Python interactive shell.' import code try: import readline, rlcompleter except: pass else: readline.parse_and_bind("tab: complete") banner += ' TAB completion available.' namespace = globals().copy() namespace.update(locals()) code.InteractiveConsole(namespace).interact(banner) sys.exit()
def __init__(self, host=None): self.db = MythDB() self.db.searchRecorded.handler = Recorded self.be = MythBE(db=self.db) self.log = MythLog(db=self.db) self.set_host(host) self.load_backends() self.load_storagegroups()
def __init__(self, opts, jobid=None): if jobid: self.job = Job(jobid) self.chanid = self.job.chanid self.starttime = self.job.starttime self.job.update(status=3) else: self.job = None self.chanid = opts.chanid self.starttime = opts.starttime self.opts = opts self.db = MythDB() self.log = MythLog(module='mythvidexport.py', db=self.db) # load setting strings self.get_format() # prep objects self.rec = Recorded((self.chanid, self.starttime), db=self.db) self.log(MythLog.IMPORTANT, 'Using recording', '%s - %s' % (self.rec.title, self.rec.subtitle)) self.vid = Video(db=self.db).create({ 'title': '', 'filename': '', 'host': gethostname() }) # process data self.get_meta() self.get_dest() # save file self.copy() if opts.seekdata: self.copy_seek() if opts.skiplist: self.copy_markup(static.MARKUP.MARK_COMM_START, static.MARKUP.MARK_COMM_END) if opts.cutlist: self.copy_markup(static.MARKUP.MARK_CUT_START, static.MARKUP.MARK_CUT_END) self.vid.update()
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option('--jobid', action='store', type='int', dest='jobid') parser.add_option('--chanid', action='store', type='int', dest='chanid') parser.add_option('--starttime', action='store', type='int', dest='starttime') parser.add_option('-v', '--verbose', action='store', type='string', dest='verbose', help='Verbosity level') parser.add_option('--title', action='store', type='string', dest='title', help='Title of Show') parser.add_option('--limit', action='store', type='int', dest='limit', default=100, help='Limit of how many recordings to do') opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) title = None if opts.jobid: rec = getjob(jobid=opts.jobid) title = rec.title elif opts.chanid and opts.starttime: rec = getjob(chanid=opts.chanid, starttime=opts.starttime) title = rec.title elif opts.title: title = opts.title if title is None: print 'Unable to determine title.' sys.exit(1) timestr = time.strftime("%m-%d-%y %H:%M:%S") title_san = re.sub("\s", ".", title) print title_san try: os.mkdir(log_dir) except OSError, e: pass
def __init__(self, opts, jobid=None): if jobid: self.job = Job(jobid) self.chanid = self.job.chanid self.starttime = self.job.starttime self.job.update(status=Job.STARTING) else: self.job = None self.chanid = opts.chanid self.starttime = opts.starttime self.opts = opts self.db = MythDB() self.log = MythLog(module='mythvidexport.py', db=self.db) # load setting strings self.get_format() # prep objects self.rec = Recorded((self.chanid, self.starttime), db=self.db) self.log( MythLog.GENERAL, MythLog.INFO, 'Using recording', '%s - %s' % (self.rec.title.encode('utf-8'), self.rec.subtitle.encode('utf-8'))) self.vid = Video(db=self.db).create({ 'title': '', 'filename': '', 'host': gethostname() }) # process data self.get_meta() self.get_dest() # bug fix to work around limitation in the bindings where DBDataRef classes # are mapped to the filename at time of Video element creation. since the # filename is specified as blank when the video is created, the markup # handler is not properly initialized self.vid.markup._refdat = (self.vid.filename, ) # save file self.copy() if opts.seekdata: self.copy_seek() if opts.skiplist: self.copy_markup(static.MARKUP.MARK_COMM_START, static.MARKUP.MARK_COMM_END) if opts.cutlist: self.copy_markup(static.MARKUP.MARK_CUT_START, static.MARKUP.MARK_CUT_END) self.vid.update() # delete old file if opts.delete: self.rec.delete()
def test_logging_OptParse_002_01(self): """Test if 'OptParse' works with MythLog.""" # set default values acc. source code m_dblog = False m_loglevel = LOGLEVEL.INFO m_verbose = LOGMASK.GENERAL m_logfile = stdout with add_log_flags(): m = MythLog('simple_test') #print ("m._LEVEL = %d" %m._LEVEL) #print ("m._MASK = %d" %m._MASK) #print ("m._DBLOG = %s" %m._DBLOG) #print (sys.argv) parser = OptionParser(prog="simple_test") # silence warnings in unittest about missing '-v' option: parser.add_option('-v', action='store_true', dest='uv', default=False, help='Use to set verbosity in unittest') # load MYthTV's extension m.loadOptParse(parser) opts, args = parser.parse_args() # check the options provided by 'additional_args': m_dblog = opts.nodblog # the option is named '--nodblog', stored in 'nodblog' m_loglevel = m._LEVEL m_verbose = m._MASK m_logfile = m._LOGFILE self.assertEqual(m_dblog, True) self.assertEqual(m_loglevel, LOGLEVEL.DEBUG) self.assertEqual( m_verbose, LOGMASK.ALL) ### XXX RER '-v' from unittest collides with this self.assertTrue(os.path.exists("/tmp/my_logfile"))
def test_Logging_Basic_004_01(self): """"Test if setting options works without a MythLog instance.""" MythLog._setmask("most") # check the modified mask: self.assertEqual(MythLog._MASK, LOGMASK.MOST) # check the default level: self.assertEqual(MythLog._LEVEL, LOGLEVEL.INFO) # check the default file: self.assertTrue('stdout' in repr(MythLog._LOGFILE)) MythLog._setlevel("notice") # check the modified mask: self.assertEqual(MythLog._MASK, LOGMASK.MOST) # check the modified level: self.assertEqual(MythLog._LEVEL, LOGLEVEL.NOTICE) # check the default file: self.assertTrue('stdout' in repr(MythLog._LOGFILE)) MythLog._setfile("/tmp/my_logfile") # check the modified mask: self.assertEqual(MythLog._MASK, LOGMASK.MOST) # check the modified level: self.assertEqual(MythLog._LEVEL, LOGLEVEL.NOTICE) # check the modified file: self.assertTrue(os.path.exists("/tmp/my_logfile"))
def test_Logging_argparse_001_01(self): """Test if 'argparse' works with MythLog.""" m = MythLog('simple_test') parser = argparse.ArgumentParser(prog="simple_test") # Add arbitrary option: parser.add_argument('--chanid', action='store', dest='chanid', default=0, help='Use chanid for manual operation') # load MYthTV's extension m.loadArgParse(parser) # unittest : first arguements are the test class or the verbosity flag test_args = [] args_found = False for a in argv: if not args_found: args_found = a.startswith('test') else: test_args.append(a) args = parser.parse_args(test_args) # check the default mask: self.assertEqual(m._MASK, LOGMASK.GENERAL) # check if helptext contains 'siparser' h = m.helptext found = False for line in h.split("\n"): match = re.findall(r'siparser', line) if match: found = True self.assertEqual(found, True)
def test_Logging_argparse_002_01(self): """Test if 'argparse' works with MythLog.""" # set default values acc. source code m_dblog = True m_loglevel = LOGLEVEL.INFO m_verbose = LOGMASK.GENERAL m_logfile = stdout with add_log_flags(): m = MythLog('simple_test') parser = argparse.ArgumentParser(prog="simple_test") # load MYthTV's extension m.loadArgParse(parser) # unittest : first arguements are the test class or the verbosity flag # filter out arguements for unittesting: test_args = add_log_flags.additional_args # according 'add_log_flags', test_args should be: # ['--nodblog', '--loglevel', 'debug', '--verbose', 'all', '--logfile', '/tmp/my_logfile'] args = parser.parse_args(test_args) #print(test_args) #print(args) # check the options provided by 'additional_args': m_dblog = m._DBLOG m_loglevel = m._LEVEL m_verbose = m._MASK m_logfile = m._LOGFILE self.assertEqual(m_dblog, False) self.assertEqual(m_loglevel, LOGLEVEL.DEBUG) self.assertEqual(m_verbose, LOGMASK.ALL) self.assertTrue(os.path.exists("/tmp/my_logfile"))
def test_Logging_Basic_001_01(self): """Test if default options works with MythLog.""" m = MythLog('simple_test') # check the default mask: self.assertEqual(m._MASK, LOGMASK.GENERAL) # check the default level: self.assertEqual(m._LEVEL, LOGLEVEL.INFO) # check the default file: self.assertTrue('stdout' in repr(m._LOGFILE)) # test '__repr__' and '__str__' print() print(repr(m)) print(str(m))
def __init__(self, opts, jobid=None): if jobid: self.job = Job(jobid) self.chanid = self.job.chanid self.starttime = self.job.starttime self.job.update(status=3) else: self.job = None self.chanid = opts.chanid self.starttime = opts.starttime self.opts = opts self.db = MythDB() self.log = MythLog(module='mythvidexport.py', db=self.db) # load setting strings self.get_format() # prep objects self.rec = Recorded((self.chanid, self.starttime), db=self.db) self.log(MythLog.IMPORTANT, 'Using recording', '%s - %s' % (self.rec.title, self.rec.subtitle)) self.vid = Video(db=self.db).create({'title':'', 'filename':'', 'host':gethostname()}) # process data self.get_meta() self.get_dest() # kludgy fix for issue with altered filenames in the bindings self.vid.markup._refdat = (self.vid.filename,) # save file self.copy() if opts.seekdata: self.copy_seek() if opts.skiplist: self.copy_markup(static.MARKUP.MARK_COMM_START, static.MARKUP.MARK_COMM_END) if opts.cutlist: self.copy_markup(static.MARKUP.MARK_CUT_START, static.MARKUP.MARK_CUT_END) self.vid.update()
def __init__(self, opts, jobid=None): # Setup for the job to run if jobid: self.thisJob = Job(jobid) self.chanID = self.thisJob.chanid self.startTime = self.thisJob.starttime self.thisJob.update(status=Job.STARTING) # If no job ID given, must be a command line run else: self.thisJob = jobid self.chanID = opts.chanid self.startTime = opts.startdate + " " + opts.starttime + opts.offset self.opts = opts self.type = "none" self.db = MythDB() self.log = MythLog(module='Myth-Rec-to-Vid.py', db=self.db) # Capture the backend host name self.host = self.db.gethostname() # prep objects self.rec = Recorded((self.chanID, self.startTime), db=self.db) self.log( MythLog.GENERAL, MythLog.INFO, 'Using recording', '%s - %s' % (self.rec.title.encode('utf-8'), self.rec.subtitle.encode('utf-8'))) self.vid = Video(db=self.db).create({ 'title': '', 'filename': '', 'host': self.host }) self.bend = MythBE(db=self.db)
a = a[2:] if '=' in a: a = a.split('=', 1) param[a[0]] = a[1] else: if len(temp): b = temp.pop(0) if (b[:2] == '--') or (b[:1] == '-'): temp.insert(0, b) param[a] = '' else: param[a] = b else: param[a] = '' MythLog._setlevel(param.get('verbose', 'none')) try: param.pop('verbose') except: pass force = False if 'force' in param: force = True param.pop('force') if len(a) == 0: sys.exit(0) recs = list(MythDB().searchRecorded(**param)) if len(recs) == 0:
class VIDEO: def __init__(self, opts, jobid=None): if jobid: self.job = Job(jobid) self.chanid = self.job.chanid self.starttime = self.job.starttime self.job.update(status=3) else: self.job = None self.chanid = opts.chanid self.starttime = opts.starttime self.opts = opts self.db = MythDB() self.log = MythLog(module='mythvidexport.py', db=self.db) # load setting strings self.get_format() # prep objects self.rec = Recorded((self.chanid, self.starttime), db=self.db) self.log(MythLog.IMPORTANT, 'Using recording', '%s - %s' % (self.rec.title, self.rec.subtitle)) self.vid = Video(db=self.db).create({'title':'', 'filename':'', 'host':gethostname()}) # process data self.get_meta() self.get_dest() # kludgy fix for issue with altered filenames in the bindings self.vid.markup._refdat = (self.vid.filename,) # save file self.copy() if opts.seekdata: self.copy_seek() if opts.skiplist: self.copy_markup(static.MARKUP.MARK_COMM_START, static.MARKUP.MARK_COMM_END) if opts.cutlist: self.copy_markup(static.MARKUP.MARK_CUT_START, static.MARKUP.MARK_CUT_END) self.vid.update() def get_format(self): host = self.db.gethostname() # TV Format if self.opts.tformat: self.tfmt = self.opts.tformat elif self.db.settings[host]['mythvideo.TVexportfmt']: self.tfmt = self.db.settings[host]['mythvideo.TVexportfmt'] else: self.tfmt = 'Television/%TITLE%/Season %SEASON%/' + \ '%TITLE% - S%SEASON%E%EPISODEPAD% - %SUBTITLE%' # Movie Format if self.opts.mformat: self.mfmt = self.opts.mformat elif self.db.settings[host]['mythvideo.MOVIEexportfmt']: self.mfmt = self.db.settings[host]['mythvideo.MOVIEexportfmt'] else: self.mfmt = 'Movies/%TITLE%' # Generic Format if self.opts.gformat: self.gfmt = self.opts.gformat elif self.db.settings[host]['mythvideo.GENERICexportfmt']: self.gfmt = self.db.settings[host]['mythvideo.GENERICexportfmt'] else: self.gfmt = 'Videos/%TITLE%' def get_meta(self): self.vid.hostname = self.db.gethostname() if self.rec.subtitle: # subtitle exists, assume tv show self.type = 'TV' self.log(self.log.IMPORTANT, 'Attempting TV export.') if self.opts.listingonly: self.log(self.log.IMPORTANT, 'Forcing listing data only.') self.get_generic(False) return grab = VideoGrabber(self.type) match = grab.sortedSearch(self.rec.title, self.rec.subtitle) else: # assume movie self.type = 'MOVIE' self.log(self.log.IMPORTANT, 'Attempting Movie export.') if self.opts.listingonly: self.log(self.log.IMPORTANT, 'Forcing listing data only.') self.get_generic(False) return grab = VideoGrabber(self.type) match = grab.sortedSearch(self.rec.title) if len(match) == 0: # no match found self.log(self.log.IMPORTANT, 'Falling back to generic export.') self.get_generic() elif (len(match) > 1) & (match[0].levenshtein > 0): # multiple matches found, and closest is not exact self.vid.delete() raise MythError('Multiple metadata matches found: '\ + self.rec.title) else: self.log(self.log.IMPORTANT, 'Importing content from', match[0].inetref) self.vid.importMetadata(grab.grabInetref(match[0])) def get_generic(self, name_as_generic=True): self.vid.title = self.rec.title if self.rec.subtitle: self.vid.subtitle = self.rec.subtitle if self.rec.description: self.vid.plot = self.rec.description if self.rec.originalairdate: self.vid.year = self.rec.originalairdate.year self.vid.releasedate = self.rec.originalairdate lsec = (self.rec.endtime - self.rec.starttime).seconds self.vid.length = str(lsec / 60) for member in self.rec.cast: if member.role == 'director': self.vid.director = member.name elif member.role == 'actor': self.vid.cast.append(member.name) if name_as_generic: self.type = 'GENERIC' def get_dest(self): if self.type == 'TV': self.vid.filename = self.process_fmt(self.tfmt) elif self.type == 'MOVIE': self.vid.filename = self.process_fmt(self.mfmt) elif self.type == 'GENERIC': self.vid.filename = self.process_fmt(self.gfmt) def process_fmt(self, fmt): # replace fields from viddata # print self.vid.data ext = '.' + self.rec.basename.rsplit('.', 1)[1] rep = (('%TITLE%', 'title', '%s'), ('%SUBTITLE%', 'subtitle', '%s'), ('%SEASON%', 'season', '%d'), ('%SEASONPAD%', 'season', '%02d'), ('%EPISODE%', 'episode', '%d'), ('%EPISODEPAD%', 'episode', '%02d'), ('%YEAR%', 'year', '%s'), ('%DIRECTOR%', 'director', '%s')) for tag, data, format in rep: if self.vid[data]: fmt = fmt.replace(tag, format % self.vid[data]) else: fmt = fmt.replace(tag, '') # replace fields from program data rep = (('%HOSTNAME', 'hostname', '%s'), ('%STORAGEGROUP%', 'storagegroup', '%s')) for tag, data, format in rep: data = getattr(self.rec, data) fmt = fmt.replace(tag, format % data) # fmt = fmt.replace('%CARDID%',self.rec.cardid) # fmt = fmt.replace('%CARDNAME%',self.rec.cardid) # fmt = fmt.replace('%SOURCEID%',self.rec.cardid) # fmt = fmt.replace('%SOURCENAME%',self.rec.cardid) # fmt = fmt.replace('%CHANNUM%',self.rec.channum) # fmt = fmt.replace('%CHANNAME%',self.rec.cardid) if len(self.vid.genre): fmt = fmt.replace('%GENRE%', self.vid.genre[0].genre) else: fmt = fmt.replace('%GENRE%', '') # if len(self.country): # fmt = fmt.replace('%COUNTRY%',self.country[0]) # else: # fmt = fmt.replace('%COUNTRY%','') return fmt + ext def copy(self): stime = time.time() srcsize = self.rec.filesize htime = [stime, stime, stime, stime] self.log.log(MythLog.IMPORTANT | MythLog.FILE, "Copying myth://%s@%s/%s"\ % (self.rec.storagegroup, self.rec.hostname, self.rec.basename)\ + " to myth://Videos@%s/%s"\ % (self.vid.host, self.vid.filename)) srcfp = self.rec.open('r') dstfp = self.vid.open('w') if self.job: self.job.setStatus(4) tsize = 2 ** 24 while tsize == 2 ** 24: tsize = min(tsize, srcsize - dstfp.tell()) dstfp.write(srcfp.read(tsize)) htime.append(time.time()) rate = float(tsize * 4) / (time.time() - htime.pop(0)) remt = (srcsize - dstfp.tell()) / rate if self.job: self.job.setComment("%02d%% complete - %d seconds remaining" % \ (dstfp.tell() * 100 / srcsize, remt)) srcfp.close() dstfp.close() self.vid.hash = self.vid.getHash() self.log(MythLog.IMPORTANT | MythLog.FILE, "Transfer Complete", "%d seconds elapsed" % int(time.time() - stime)) if self.job: self.job.setComment("Complete - %d seconds elapsed" % \ (int(time.time() - stime))) self.job.setStatus(256) def copy_seek(self): for seek in self.rec.seek: self.vid.markup.add(seek.mark, seek.offset, seek.type) def copy_markup(self, start, stop): for mark in self.rec.markup: if mark.type in (start, stop): self.vid.markup.add(mark.mark, 0, mark.type)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option("-f", "--helpformat", action="store_true", default=False, dest="fmthelp", help="Print explination of file format string.") parser.add_option("-p", "--printformat", action="store_true", default=False, dest="fmtprint", help="Print current file format string.") parser.add_option( "--tformat", action="store", type="string", dest="tformat", help="Use TV format for current task. If no task, store in database.") parser.add_option( "--mformat", action="store", type="string", dest="mformat", help="Use Movie format for current task. If no task, store in database." ) parser.add_option( "--gformat", action="store", type="string", dest="gformat", help= "Use Generic format for current task. If no task, store in database.") parser.add_option("--chanid", action="store", type="int", dest="chanid", help="Use chanid for manual operation") parser.add_option("--starttime", action="store", type="int", dest="starttime", help="Use starttime for manual operation") parser.add_option( "--listingonly", action="store_true", default=False, dest="listingonly", help="Use data from listing provider, rather than grabber") parser.add_option("--seekdata", action="store_true", default=False, dest="seekdata", help="Copy seekdata from source recording.") parser.add_option("--skiplist", action="store_true", default=False, dest="skiplist", help="Copy commercial detection from source recording.") parser.add_option( "--cutlist", action="store_true", default=False, dest="cutlist", help="Copy manual commercial cuts from source recording.") parser.add_option('-v', '--verbose', action='store', type='string', dest='verbose', help='Verbosity level') opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if opts.fmthelp: usage_format() sys.exit(0) if opts.fmtprint: print_format() sys.exit(0) if opts.chanid and opts.starttime: export = VIDEO(opts) elif len(args) == 1: try: export = VIDEO(opts, int(args[0])) except Exception, e: Job(int(args[0])).update({ 'status': 304, 'comment': 'ERROR: ' + e.args[0] }) MythLog(module='mythvidexport.py').logTB(MythLog.IMPORTANT) sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") sourcegroup = OptionGroup(parser, "Source Definition", "These options can be used to manually specify a recording to operate on "+\ "in place of the job id.") sourcegroup.add_option("--chanid", action="store", type="int", dest="chanid", help="Use chanid for manual operation, format interger") sourcegroup.add_option("--startdate", action="store", type="string", dest="startdate", help="Use startdate for manual operation, format is year-mm-dd") sourcegroup.add_option("--starttime", action="store", type="string", dest="starttime", help="Use starttime for manual operation, format is hh:mm:ss in UTC") sourcegroup.add_option("--offset", action="store", type="string", dest="offset", help="Use offset(timezone) for manual operation, format is [+/-]hh:mm. Do not adjust for DST") parser.add_option_group(sourcegroup) actiongroup = OptionGroup(parser, "Additional Actions", "These options perform additional actions after the recording has been migrated. "+\ "A safe copy is always performed in that the file is checked to match the "+\ "MythBE hash. The safe copy option will abort the entire process if selected "+\ "along with Other Data and an exception occurs in the process") actiongroup.add_option('--safe', action='store_true', default=False, dest='safe', help='If other data is copied and a failure occurs this will abort the whole process.') actiongroup.add_option("--delete", action="store_true", default=False, help="Delete source recording after successful export. Enforces use of --safe.") parser.add_option_group(actiongroup) othergroup = OptionGroup(parser, "Other Data", "These options copy additional information from the source recording.") othergroup.add_option("--seekdata", action="store_true", default=False, dest="seekdata", help="Copy seekdata from source recording.") othergroup.add_option("--skiplist", action="store_true", default=False, dest="skiplist", help="Copy commercial detection from source recording.") othergroup.add_option("--cutlist", action="store_true", default=False, dest="cutlist", help="Copy manual commercial cuts from source recording.") parser.add_option_group(othergroup) MythLog.loadOptParse(parser) opts, args = parser.parse_args() def error_out(): export.delete_vid() if export.thisJob: export.set_job_status(Job.ERRORED) sys.exit(1) if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if opts.delete: opts.safe = True # if a manual channel and time entry then setup the export with opts if opts.chanid and opts.startdate and opts.starttime and opts.offset: try: export = VIDEO(opts) except Exception, e: sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") formatgroup = OptionGroup(parser, "Formatting Options", "These options are used to display and manipulate the output file formats.") formatgroup.add_option("-f", "--helpformat", action="store_true", default=False, dest="fmthelp", help="Print explination of file format string.") formatgroup.add_option("-p", "--printformat", action="store_true", default=False, dest="fmtprint", help="Print current file format string.") formatgroup.add_option("--tformat", action="store", type="string", dest="tformat", help="Use TV format for current task. If no task, store in database.") formatgroup.add_option("--mformat", action="store", type="string", dest="mformat", help="Use Movie format for current task. If no task, store in database.") formatgroup.add_option("--gformat", action="store", type="string", dest="gformat", help="Use Generic format for current task. If no task, store in database.") formatgroup.add_option("--listingonly", action="store_true", default=False, dest="listingonly", help="Use data from listing provider, rather than grabber") parser.add_option_group(formatgroup) sourcegroup = OptionGroup(parser, "Source Definition", "These options can be used to manually specify a recording to operate on "+\ "in place of the job id.") sourcegroup.add_option("--chanid", action="store", type="int", dest="chanid", help="Use chanid for manual operation") sourcegroup.add_option("--starttime", action="store", type="int", dest="starttime", help="Use starttime for manual operation") parser.add_option_group(sourcegroup) actiongroup = OptionGroup(parser, "Additional Actions", "These options perform additional actions after the recording has been exported.") actiongroup.add_option('--safe', action='store_true', default=False, dest='safe', help='Perform quick sanity check of exported file using file size.') actiongroup.add_option('--really-safe', action='store_true', default=False, dest='reallysafe', help='Perform slow sanity check of exported file using SHA1 hash.') actiongroup.add_option("--delete", action="store_true", default=False, help="Delete source recording after successful export. Enforces use of --safe.") parser.add_option_group(actiongroup) othergroup = OptionGroup(parser, "Other Data", "These options copy additional information from the source recording.") othergroup.add_option("--seekdata", action="store_true", default=False, dest="seekdata", help="Copy seekdata from source recording.") othergroup.add_option("--skiplist", action="store_true", default=False, dest="skiplist", help="Copy commercial detection from source recording.") othergroup.add_option("--cutlist", action="store_true", default=False, dest="cutlist", help="Copy manual commercial cuts from source recording.") parser.add_option_group(othergroup) MythLog.loadOptParse(parser) opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if opts.fmthelp: usage_format() sys.exit(0) if opts.fmtprint: print_format() sys.exit(0) if opts.delete: opts.safe = True if opts.chanid and opts.starttime: export = VIDEO(opts) elif len(args) == 1: try: export = VIDEO(opts,int(args[0])) except Exception, e: Job(int(args[0])).update({'status':Job.ERRORED, 'comment':'ERROR: '+e.args[0]}) MythLog(module='mythvidexport.py').logTB(MythLog.GENERAL) sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") formatgroup = OptionGroup( parser, "Formatting Options", "These options are used to display and manipulate the output file formats." ) formatgroup.add_option("-f", "--helpformat", action="store_true", default=False, dest="fmthelp", help="Print explination of file format string.") formatgroup.add_option("-p", "--printformat", action="store_true", default=False, dest="fmtprint", help="Print current file format string.") formatgroup.add_option( "--tformat", action="store", type="string", dest="tformat", help="Use TV format for current task. If no task, store in database.") formatgroup.add_option( "--mformat", action="store", type="string", dest="mformat", help="Use Movie format for current task. If no task, store in database." ) formatgroup.add_option( "--gformat", action="store", type="string", dest="gformat", help= "Use Generic format for current task. If no task, store in database.") formatgroup.add_option( "--listingonly", action="store_true", default=False, dest="listingonly", help="Use data from listing provider, rather than grabber") parser.add_option_group(formatgroup) sourcegroup = OptionGroup(parser, "Source Definition", "These options can be used to manually specify a recording to operate on "+\ "in place of the job id.") sourcegroup.add_option("--chanid", action="store", type="int", dest="chanid", help="Use chanid for manual operation") sourcegroup.add_option("--starttime", action="store", type="string", dest="starttime", help="Use starttime for manual operation") parser.add_option_group(sourcegroup) actiongroup = OptionGroup( parser, "Additional Actions", "These options perform additional actions after the recording has been exported." ) actiongroup.add_option( '--safe', action='store_true', default=False, dest='safe', help='Perform quick sanity check of exported file using file size.') actiongroup.add_option( '--really-safe', action='store_true', default=False, dest='reallysafe', help='Perform slow sanity check of exported file using SHA1 hash.') actiongroup.add_option( "--delete", action="store_true", default=False, help= "Delete source recording after successful export. Enforces use of --safe." ) parser.add_option_group(actiongroup) othergroup = OptionGroup( parser, "Other Data", "These options copy additional information from the source recording.") othergroup.add_option("--seekdata", action="store_true", default=False, dest="seekdata", help="Copy seekdata from source recording.") othergroup.add_option( "--skiplist", action="store_true", default=False, dest="skiplist", help="Copy commercial detection from source recording.") othergroup.add_option( "--cutlist", action="store_true", default=False, dest="cutlist", help="Copy manual commercial cuts from source recording.") parser.add_option_group(othergroup) MythLog.loadOptParse(parser) opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if opts.fmthelp: usage_format() sys.exit(0) if opts.fmtprint: print_format() sys.exit(0) if opts.delete: opts.safe = True if opts.chanid and opts.starttime: export = VIDEO(opts) elif len(args) == 1: try: export = VIDEO(opts, int(args[0])) except Exception, e: Job(int(args[0])).update({ 'status': Job.ERRORED, 'comment': 'ERROR: ' + e.args[0] }) MythLog(module='mythvidexport.py').logTB(MythLog.GENERAL) sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") sourcegroup = OptionGroup(parser, "Source Definition", "These options can be used to manually specify a recording to operate on "+\ "in place of the job id.") sourcegroup.add_option( "--chanid", action="store", type="int", dest="chanid", help="Use chanid for manual operation, format interger") sourcegroup.add_option( "--startdate", action="store", type="string", dest="startdate", help="Use startdate for manual operation, format is year-mm-dd") sourcegroup.add_option( "--starttime", action="store", type="string", dest="starttime", help="Use starttime for manual operation, format is hh:mm:ss in UTC") sourcegroup.add_option( "--offset", action="store", type="string", dest="offset", help= "Use offset(timezone) for manual operation, format is [+/-]hh:mm. Do not adjust for DST" ) parser.add_option_group(sourcegroup) actiongroup = OptionGroup(parser, "Additional Actions", "These options perform additional actions after the recording has been migrated. "+\ "A safe copy is always performed in that the file is checked to match the "+\ "MythBE hash. The safe copy option will abort the entire process if selected "+\ "along with Other Data and an exception occurs in the process") actiongroup.add_option( '--safe', action='store_true', default=False, dest='safe', help= 'If other data is copied and a failure occurs this will abort the whole process.' ) actiongroup.add_option( "--delete", action="store_true", default=False, help= "Delete source recording after successful export. Enforces use of --safe." ) parser.add_option_group(actiongroup) othergroup = OptionGroup( parser, "Other Data", "These options copy additional information from the source recording.") othergroup.add_option("--seekdata", action="store_true", default=False, dest="seekdata", help="Copy seekdata from source recording.") othergroup.add_option( "--skiplist", action="store_true", default=False, dest="skiplist", help="Copy commercial detection from source recording.") othergroup.add_option( "--cutlist", action="store_true", default=False, dest="cutlist", help="Copy manual commercial cuts from source recording.") parser.add_option_group(othergroup) MythLog.loadOptParse(parser) opts, args = parser.parse_args() def error_out(): export.delete_vid() if export.thisJob: export.set_job_status(Job.ERRORED) sys.exit(1) if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if opts.delete: opts.safe = True # if a manual channel and time entry then setup the export with opts if opts.chanid and opts.startdate and opts.starttime and opts.offset: try: export = VIDEO(opts) except Exception, e: sys.exit(1)
#!/usr/bin/env python import os import sys try: from MythTV import MythVideo, VideoGrabber, MythLog except: print 'ERROR: The python bindings are not installed' sys.exit(-1) LOG = MythLog('MythVideo Scanner', lstr='general') mvid = MythVideo() def format_name(vid): # returns a string in the format 'TITLE[ - SEASONxEPISODE][ - SUBTITLE]' s = vid.title if vid.season: s += ' - %dx%02d' % (vid.season, vid.episode) if vid.subtitle: s += ' - ' + vid.subtitle return s.encode('utf-8', 'replace') # Load TV Grabber try: TVgrab = VideoGrabber('TV', db=mvid) except: print 'ERROR: Cannot find MythVideo TV grabber' sys.exit(-1)
#!/usr/bin/env python from MythTV import MythDB, MythError, MythLog, Frontend from datetime import datetime, timedelta from curses import wrapper, ascii from time import sleep import sys, socket, curses, re #note for ticket, on-screen-keyboard remotely does not have focus MythLog._setlevel('none') frontend = None rplaytype = re.compile('Playback ([a-zA-Z]+)') rrecorded = re.compile('Playback ([a-zA-Z]+) ([\d:]+) of ([\d:]+) ([-0-9\.]+x) (\d*) ([0-9-T:]+)') rlivetv = rrecorded rvideo = re.compile('Playback [a-zA-Z]+ ([\d:]+) ([-0-9\.]+x) .*/(.*) \d+ [\.\d]+') rrname = re.compile('\d+ [0-9-T:]+ (.*)') rlname = re.compile('\d+ [0-9-T: ]+ (.*)') def align(side, window, y, string, flush=0): w = window.getmaxyx()[1]-1 if len(string) > w: string = string[:w] if side == 0: x = 1 elif side == 1: x = (w-len(string))/2+1 elif side == 2: x = w-len(string) window.addstr(y,x,string)
a = a[2:] if '=' in a: a = a.split('=',1) param[a[0]] = a[1] else: if len(temp): b = temp.pop(0) if (b[:2] == '--') or (b[:1] == '-'): temp.insert(0,b) param[a] = '' else: param[a] = b else: param[a] = '' MythLog._setlevel(param.get('verbose','none')) try: param.pop('verbose') except: pass force = False if 'force' in param: force = True param.pop('force') if len(a) == 0: sys.exit(0) recs = list(MythDB().searchRecorded(**param)) if len(recs) == 0: print 'no matching recordings found'
class VIDEO: def __init__(self, opts, jobid=None): if jobid: self.job = Job(jobid) self.chanid = self.job.chanid self.starttime = self.job.starttime self.job.update(status=3) else: self.job = None self.chanid = opts.chanid self.starttime = opts.starttime self.opts = opts self.db = MythDB() self.log = MythLog(module='mythvidexport.py', db=self.db) # load setting strings self.get_format() # prep objects self.rec = Recorded((self.chanid, self.starttime), db=self.db) self.log(MythLog.IMPORTANT, 'Using recording', '%s - %s' % (self.rec.title, self.rec.subtitle)) self.vid = Video(db=self.db).create({ 'title': '', 'filename': '', 'host': gethostname() }) # process data self.get_meta() self.get_dest() # save file self.copy() if opts.seekdata: self.copy_seek() if opts.skiplist: self.copy_markup(static.MARKUP.MARK_COMM_START, static.MARKUP.MARK_COMM_END) if opts.cutlist: self.copy_markup(static.MARKUP.MARK_CUT_START, static.MARKUP.MARK_CUT_END) self.vid.update() def get_format(self): host = self.db.gethostname() # TV Format if self.opts.tformat: self.tfmt = self.opts.tformat elif self.db.settings[host]['mythvideo.TVexportfmt']: self.tfmt = self.db.settings[host]['mythvideo.TVexportfmt'] else: self.tfmt = 'Television/%TITLE%/Season %SEASON%/'+\ '%TITLE% - S%SEASON%E%EPISODEPAD% - %SUBTITLE%' # Movie Format if self.opts.mformat: self.mfmt = self.opts.mformat elif self.db.settings[host]['mythvideo.MOVIEexportfmt']: self.mfmt = self.db.settings[host]['mythvideo.MOVIEexportfmt'] else: self.mfmt = 'Movies/%TITLE%' # Generic Format if self.opts.gformat: self.gfmt = self.opts.gformat elif self.db.settings[host]['mythvideo.GENERICexportfmt']: self.gfmt = self.db.settings[host]['mythvideo.GENERICexportfmt'] else: self.gfmt = 'Videos/%TITLE%' def get_meta(self): self.vid.hostname = self.db.gethostname() if self.rec.subtitle: # subtitle exists, assume tv show self.type = 'TV' self.log(self.log.IMPORTANT, 'Attempting TV export.') if self.opts.listingonly: self.log(self.log.IMPORTANT, 'Forcing listing data only.') self.get_generic(False) return grab = VideoGrabber(self.type) match = grab.sortedSearch(self.rec.title, self.rec.subtitle) else: # assume movie self.type = 'MOVIE' self.log(self.log.IMPORTANT, 'Attempting Movie export.') if self.opts.listingonly: self.log(self.log.IMPORTANT, 'Forcing listing data only.') self.get_generic(False) return grab = VideoGrabber(self.type) match = grab.sortedSearch(self.rec.title) if len(match) == 0: # no match found self.log(self.log.IMPORTANT, 'Falling back to generic export.') self.get_generic() elif (len(match) > 1) & (match[0].levenshtein > 0): # multiple matches found, and closest is not exact self.vid.delete() raise MythError('Multiple metadata matches found: '\ +self.rec.title) else: self.log(self.log.IMPORTANT, 'Importing content from', match[0].inetref) self.vid.importMetadata(grab.grabInetref(match[0])) def get_generic(self, name_as_generic=True): self.vid.title = self.rec.title if self.rec.subtitle: self.vid.subtitle = self.rec.subtitle if self.rec.description: self.vid.plot = self.rec.description if self.rec.originalairdate: self.vid.year = self.rec.originalairdate.year self.vid.releasedate = self.rec.originalairdate lsec = (self.rec.endtime - self.rec.starttime).seconds self.vid.length = str(lsec / 60) for member in self.rec.cast: if member.role == 'director': self.vid.director = member.name elif member.role == 'actor': self.vid.cast.append(member.name) if name_as_generic: self.type = 'GENERIC' def get_dest(self): if self.type == 'TV': self.vid.filename = self.process_fmt(self.tfmt) elif self.type == 'MOVIE': self.vid.filename = self.process_fmt(self.mfmt) elif self.type == 'GENERIC': self.vid.filename = self.process_fmt(self.gfmt) def process_fmt(self, fmt): # replace fields from viddata #print self.vid.data ext = '.' + self.rec.basename.rsplit('.', 1)[1] rep = (('%TITLE%', 'title', '%s'), ('%SUBTITLE%', 'subtitle', '%s'), ('%SEASON%', 'season', '%d'), ('%SEASONPAD%', 'season', '%02d'), ('%EPISODE%', 'episode', '%d'), ('%EPISODEPAD%', 'episode', '%02d'), ('%YEAR%', 'year', '%s'), ('%DIRECTOR%', 'director', '%s')) for tag, data, format in rep: if self.vid[data]: fmt = fmt.replace(tag, format % self.vid[data]) else: fmt = fmt.replace(tag, '') # replace fields from program data rep = (('%HOSTNAME', 'hostname', '%s'), ('%STORAGEGROUP%', 'storagegroup', '%s')) for tag, data, format in rep: data = getattr(self.rec, data) fmt = fmt.replace(tag, format % data) # fmt = fmt.replace('%CARDID%',self.rec.cardid) # fmt = fmt.replace('%CARDNAME%',self.rec.cardid) # fmt = fmt.replace('%SOURCEID%',self.rec.cardid) # fmt = fmt.replace('%SOURCENAME%',self.rec.cardid) # fmt = fmt.replace('%CHANNUM%',self.rec.channum) # fmt = fmt.replace('%CHANNAME%',self.rec.cardid) if len(self.vid.genre): fmt = fmt.replace('%GENRE%', self.vid.genre[0].genre) else: fmt = fmt.replace('%GENRE%', '') # if len(self.country): # fmt = fmt.replace('%COUNTRY%',self.country[0]) # else: # fmt = fmt.replace('%COUNTRY%','') return fmt + ext def copy(self): stime = time.time() srcsize = self.rec.filesize htime = [stime, stime, stime, stime] self.log.log(MythLog.IMPORTANT|MythLog.FILE, "Copying myth://%s@%s/%s"\ % (self.rec.storagegroup, self.rec.hostname, self.rec.basename)\ +" to myth://Videos@%s/%s"\ % (self.vid.host, self.vid.filename)) srcfp = self.rec.open('r') dstfp = self.vid.open('w') if self.job: self.job.setStatus(4) tsize = 2**24 while tsize == 2**24: tsize = min(tsize, srcsize - dstfp.tell()) dstfp.write(srcfp.read(tsize)) htime.append(time.time()) rate = float(tsize * 4) / (time.time() - htime.pop(0)) remt = (srcsize - dstfp.tell()) / rate if self.job: self.job.setComment("%02d%% complete - %d seconds remaining" %\ (dstfp.tell()*100/srcsize, remt)) srcfp.close() dstfp.close() self.vid.hash = self.vid.getHash() self.log(MythLog.IMPORTANT | MythLog.FILE, "Transfer Complete", "%d seconds elapsed" % int(time.time() - stime)) if self.job: self.job.setComment("Complete - %d seconds elapsed" % \ (int(time.time()-stime))) self.job.setStatus(256) def copy_seek(self): for seek in self.rec.seek: self.vid.markup.add(seek.mark, seek.offset, seek.type) def copy_markup(self, start, stop): for mark in self.rec.markup: if mark.type in (start, stop): self.vid.markup.add(mark.mark, 0, mark.type)
def LOG(msg): logger = MythLog(module='mythadder.py') logger(MythLog.GENERAL, MythLog.INFO, msg)
try: import MythTV except: print 'Warning! MythTV Python bindings could not be found' sys.exit(1) if MythTV.__version__ < (0,24,0,0): print 'Warning! Installed MythTV Python bindings are tool old. Please update' print ' to 0.23.0.18 or later.' sys.exit(1) from MythTV import MythDB, MythVideo, ftopen, MythBE,\ Video, Recorded, MythLog, static fuse.fuse_python_api = (0, 2) LOG = MythLog(lstr='none') MythLog._setfile('/dev/null') BACKEND = None def doNothing(*args, **kwargs): pass def increment(): res = 1 while True: yield res res += 1 class Attr(fuse.Stat): def __init__(self): self.st_mode = 0 self.st_ino = 0
def __init__(self): self.l = MythLog('transcode.py', db=self.db())
def __getattr__(self, attr): """Delegate everything but write to the stream""" return getattr(self.out, attr) sys.stdout = OutStreamEncoder(sys.stdout, 'utf8') sys.stderr = OutStreamEncoder(sys.stderr, 'utf8') # Find out if the MythTV python bindings can be accessed and instances can created try: '''If the MythTV python interface is found, required to access Netvision icon directory settings ''' from MythTV import MythDB, MythLog try: '''Create an instance of each: MythDB ''' MythLog._setlevel('none') # Some non option -M cannot have any logging on stdout mythdb = MythDB() except MythError, e: sys.stderr.write(u'\n! Error - %s\n' % e.args[0]) filename = os.path.expanduser("~")+'/.mythtv/config.xml' if not os.path.isfile(filename): sys.stderr.write(u'\n! Error - A correctly configured (%s) file must exist\n' % filename) else: sys.stderr.write(u'\n! Error - Check that (%s) is correctly configured\n' % filename) sys.exit(1) except Exception, e: sys.stderr.write(u"\n! Error - Creating an instance caused an error for one of: MythDB. error(%s)\n" % e) sys.exit(1) except Exception, e: sys.stderr.write(u"\n! Error - MythTV python bindings could not be imported. error(%s)\n" % e) sys.exit(1)
def main(): parser = OptionParser(usage="usage: %prog [options] [jobid]") parser.add_option( '--chanid', action='store', type='int', dest='chanid', help='Use chanid with both starttime and tzoffset for manual operation' ) parser.add_option( '--starttime', action='store', type='string', dest='starttime', help='Use starttime with both chanid and tzoffset for manual operation' ) parser.add_option( '--tzoffset', action='store', type='int', dest='tzoffset', help='Use tzoffset with both chanid and starttime for manual operation' ) parser.add_option( '--overwrite', action='store', type='int', default=1, dest='overwrite', help='Use overwrite to force the output to replace the original file') parser.add_option('--sd', action='store', type='int', default=0, dest='sdonly', help='Use sd to force the output to be SD dimentions') parser.add_option('--burncc', action='store', type='int', default=0, dest='burncc', help='Use burncc to burn the subtitle/cc into the video') parser.add_option('--mkv', action='store', type='int', default=0, dest='usemkv', help='Use mkv instead of mp4') parser.add_option('-v', '--verbose', action='store', type='string', dest='verbose', help='Verbosity level') opts, args = parser.parse_args() if opts.verbose: if opts.verbose == 'help': print MythLog.helptext sys.exit(0) MythLog._setlevel(opts.verbose) if len(args) == 1: runjob(jobid=args[0], overwrite=opts.overwrite, sdonly=opts.sdonly, burncc=opts.burncc, usemkv=opts.usemkv) elif opts.chanid and opts.starttime and opts.tzoffset is not None: runjob(chanid=opts.chanid, starttime=opts.starttime, tzoffset=opts.tzoffset, overwrite=opts.overwrite, sdonly=opts.sdonly, burncc=opts.burncc, usemkv=opts.usemkv) else: print 'Script must be provided jobid, or chanid, starttime and timezone offset.' sys.exit(1)
"""Delegate everything but write to the stream""" return getattr(self.out, attr) sys.stdout = OutStreamEncoder(sys.stdout, 'utf8') sys.stderr = OutStreamEncoder(sys.stderr, 'utf8') # Find out if the MythTV python bindings can be accessed and instances can created try: '''If the MythTV python interface is found, required to access Netvision icon directory settings ''' from MythTV import MythDB, MythLog try: '''Create an instance of each: MythDB ''' MythLog._setlevel( 'none') # Some non option -M cannot have any logging on stdout mythdb = MythDB() except MythError, e: sys.stderr.write(u'\n! Error - %s\n' % e.args[0]) filename = os.path.expanduser("~") + '/.mythtv/config.xml' if not os.path.isfile(filename): sys.stderr.write( u'\n! Error - A correctly configured (%s) file must exist\n' % filename) else: sys.stderr.write( u'\n! Error - Check that (%s) is correctly configured\n' % filename) sys.exit(1) except Exception, e: sys.stderr.write(
from fuse import Fuse try: import MythTV except: print 'Warning! MythTV Python bindings could not be found' sys.exit(1) if MythTV.__version__ < (0, 24, 0, 0): print 'Warning! Installed MythTV Python bindings are tool old. Please update' print ' to 0.23.0.18 or later.' sys.exit(1) from MythTV import MythDB, MythVideo, ftopen, MythBE,\ Video, Recorded, MythLog, static fuse.fuse_python_api = (0, 2) LOG = MythLog(lstr='none') MythLog._setfile('/dev/null') BACKEND = None def doNothing(*args, **kwargs): pass def increment(): res = 1 while True: yield res res += 1
export = VIDEO(opts) except Exception, e: sys.exit(1) # If an auto or manual job entry then setup the export with the jobID elif len(args) == 1: try: export = VIDEO(opts, int(args[0])) except Exception, e: Job(int(args[0])).update({ 'status': Job.ERRORED, 'comment': 'ERROR: ' + e.args[0] }) MythLog(module='Myth-Rec-to-Vid.py').logTB(MythLog.GENERAL) sys.exit(1) # else bomb the job and return an error code else: parser.print_help() sys.exit(2) # Export object created so process the job try: export.get_type() export.get_meta() export.get_dest() except Exception, e: export.log(MythLog.GENERAL | MythLog.FILE, MythLog.INFO,