def test_Dataheap_VideoGrabber_001_search_01(self): """Test 'search' method from MythTV.VideoGrabber using 'searchVideos'. """ from MythTV import MythDB, RecordedArtwork, Video, VideoGrabber with add_log_flags(): self.mydb = MythDB() title = self.testenv['VIDTITLE'] cast = self.testenv['VIDCAST'] inetrefstr = self.testenv['VIDINETREF'] lang = self.testenv['VIDLANGUAGE'] # remove grabber from inetref: try: inetref = inetrefstr.split('_')[-1] except IndexError: inetref = inetrefstr vids = self.mydb.searchVideos( title = title ) vid = next(vids) # print("%s : %s" %(vid.title, type(vid.title))) self.assertTrue(isinstance(vid, Video)) grab = VideoGrabber("Movie", lang = lang, db = self.mydb) metadatalistgen = grab.search(vid.title, subtitle=None, tolerance=1) mlist = list(metadatalistgen) inetref_found = False for m in mlist: if (m.inetref == inetref): inetref_found = True break self.assertTrue(inetref_found)
def __init__(self): self.db = MythDB() self.be = MythBE(db=db) self.vids = {} self._addCallback = doNothing self._events = [self.handleUpdate] self.be.registerevent(self.handleUpdate)
def test_repr_001_02(self): """ Test '__repr__' and '__str__' methods from MythTV.MythDB.settings """ db = MythDB() s = db.settings print() print(repr(s)) print(str(s)) #self.assertTrue(u'DBSchemaVer' in str(s)) sn = db.settings['NULL'] print() print(repr(sn)) print(str(sn)) ip = db.settings.NULL.MasterServerIP print() print(repr(ip)) print(str(ip)) fn = db.settings['%s' % self.testenv['FRONTENDNAME']] print() print(repr(fn)) print(str(fn)) fnp = fn.NetworkControlPort print() print(repr(fnp)) print(str(fnp))
def transcode(jobid=None, chanid=None, starttime=None): ' connect to mythtv database ' db = MythDB() be = MythBE(db=db) logging.info("start transcode") if jobid: job = Job(jobid, db=db) chanid = job.chanid starttime = job.starttime logging.info("%s" % jobid) logging.info("%s" % chanid) logging.info("%s" % starttime) rec = Recorded((chanid, starttime), db=db) ' TODO: get the starttime into the correct format (from 20150827014200 to 2015-08-27 00:42:00-06:00)' ' loop all files in lib_dir that are symlinks and find the one that matches this recording ' for ld in LIBDIR: for dp, dn, files in os.walk(ld): for file in files: filepath = os.path.join(dp,file) if (os.path.islink(filepath)): logging.debug("%s -> %s" % (filepath, os.readlink(filepath))) ' do the transode ' ' update the database for the new file name ' ' update the symlink for the new file name '
def test_Dataheap_VideoGrabber_002_importMetadata_02(self): """Test 'VideoGrabber.grabInetref' method and 'Video.importMetadata' methods using predefined values. See 'mythvidexport.py' as well. See MythtTV trac tickets #12243 and #12245. Note: Use a TV series with season and episode. """ from MythTV import MythDB, Video, VideoGrabber with add_log_flags(): self.mydb = MythDB() alf_metadata = { u'title' : u'Alf', u'subtitle' : u'Wedding Bell Blues', u'season' : 2, u'episode' : 4, u'inetref' : '78020'} grab = VideoGrabber('TV', lang='en', db=self.mydb) metadata = grab.grabInetref( alf_metadata['inetref'], alf_metadata['season'], alf_metadata['episode']) # print(metadata.collectionref) # ---> '78020' self.assertEqual(metadata.collectionref, alf_metadata[u'inetref']) # run the grabber again, but based on a 'VideoMetadata' object new_metadata = grab.grabInetref(metadata) # check if collected metadata are the equal self.assertEqual(new_metadata, metadata)
def test_Dataheap_VideoGrabber_001_sortedSearch_01(self): """Test 'sortedSearch' method from MythTV.VideoGrabber using predefined values. """ from MythTV import MythDB, RecordedArtwork, Video, VideoGrabber with add_log_flags(): self.mydb = MythDB() title = self.testenv['VIDTITLE_DE'] cast = self.testenv['VIDCAST_DE'] inetrefstr = self.testenv['VIDINETREF_DE'] lang = self.testenv['VIDLANGUAGE_DE'] # remove grabber from inetref: try: inetref = inetrefstr.split('_')[-1] except IndexError: inetref = inetrefstr grab = VideoGrabber("Movie", lang=lang, db=self.mydb) metadatalist = grab.sortedSearch(title, subtitle=None, tolerance=2) inetref_found = False for m in metadatalist: if (m.inetref == inetref): inetref_found = True break self.assertTrue(inetref_found)
def getjob(jobid=None, chanid=None, starttime=None): db = MythDB() if jobid: job = Job(jobid, db=db) chanid = job.chanid starttime = job.starttime return Recorded((chanid, starttime), db=db)
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 test_repr_002_01(self): """ Test '__repr__' and '__str__' methods from dataheap.py """ chanid = self.testenv['RECCHANID'] starttimemyth = self.testenv['RECSTARTTIMEMYTH'] title = self.testenv['RECTITLE'] c_s = (chanid, starttimemyth) db = MythDB() # Recorded class r = Recorded(c_s, db=db) print() print(repr(r)) print(str(r)) # Markup table m = r.markup print() print(repr(m)) print(str(m)) # one entry of the marlup table: print() print(repr(m[0])) print(str(m[0])) # one value of a single entry: print() print(repr(m[0].mark)) print(str(m[0].mark)) print() print(repr(m[0].data)) print(str(m[0].data)) # Artwork a = r.artwork print() print(repr(a)) print(str(a)) # Coverart of an Artwork ac = a.coverart print() print(repr(ac)) print(str(ac)) # Program of the recorded entry: prgrm = r.getRecordedProgram() print() print(repr(prgrm)) print(str(prgrm)) # OldRecorded of the recorded entry: oldrecs = db.searchOldRecorded(chanid=chanid, title=title) oldrec = next(oldrecs) print() print(repr(oldrec)) print(str(oldrec))
def store_format(): i = iter(sys.argv) while i.next() != '--storeformat': pass tag = i.next() fmt = i.next() db = MythDB() db.settings.NULL['mythfs.format.%s' % tag] = fmt 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=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_repr_004_01(self): """ Test '__repr__' and '__str__' methods of 'MythBE' class. Note: MythBE inherits from 'FileOps', which is inherited from 'BeCache'. """ db = MythDB() be = MythBE(db=db) print() print(repr(be)) print(str(be))
def main(): db = MythDB() jobs = db.searchJobs() activejob = 0 for job in jobs: if job.status in [Job.ABORTING, Job.ERRORING, Job.PAUSED, Job.PENDING, \ Job.QUEUED, Job.RETRY, Job.RUNNING, Job.STARTING, Job.STOPPING]: activejob = 1 break sys.exit(activejob)
def test_repr_001_03(self): """ Test '__repr__' and '__str__' methods from MythTV.MythDB.StorageGroup """ db = MythDB() sgi = db.getStorageGroup('LiveTV') sg = next(sgi) print() print(repr(sg)) print(str(sg))
def print_formats(): db = MythDB() print ' Label Format ' print ' ----- ------ ' with db as cursor: cursor.execute( """SELECT value,data FROM settings WHERE value like 'mythfs.format.%'""" ) for lbl, fmt in cursor.fetchall(): lbl = lbl[14:] print '%s %s' % (lbl.center(16), fmt) sys.exit()
def setUp(self): # create a file with this name if it does not exist self.frtitle = self.testenv["VIDFRTITLE"] # Le Dernier Métro" self.frfilename = self.testenv["VIDFRFILENAME"] self.frpath = self.testenv["VIDFRPATH"] self.frfullpath = os.path.join(self.frpath, self.frfilename) with add_log_flags(): self.mydb = MythDB() self.master_backend_ip = self.mydb.settings['NULL']['MasterServerIP'] shcmd = 'head -c 10M </dev/urandom > "%s"' % self.frfullpath cmd = "ssh mythtv@%s '%s'" % (self.master_backend_ip, shcmd) print(cmd) self.result = subprocess.call(cmd, shell=True) # will be checked later
def getDbObject(credentials=getCredentials(mythConfig)): """ Returns a MythTV database object (MythTV Python Bindings) Usage: myVar = getDbObject() #Use credentials located at mythConfig path myVar = getDbObject((hostname, databasename, username, password)) #Manually specify credentials """ dbObj = MythDB(args=(('DBHostName', credentials[0]), ('DBName', credentials[1]), ('DBUserName', credentials[2]), ('DBPassword', credentials[3]))) return dbObj
def test_Dataheap_VideoGrabber_001_grabInetref_01(self): """Test 'grabInetref' and 'toXML' methods from MythTV.VideoGrabber using predefined values. """ from MythTV import MythDB, RecordedArtwork, Video, VideoGrabber with add_log_flags(): self.mydb = MythDB() title = self.testenv['VIDTITLE_DE'] cast = self.testenv['VIDCAST_DE'] inetrefstr = self.testenv['VIDINETREF_DE'] lang = self.testenv['VIDLANGUAGE_DE'] # remove grabber from inetref: try: inetref = inetrefstr.split('_')[-1] except IndexError: inetref = inetrefstr grab = VideoGrabber("Movie", lang=lang, db=self.mydb) metadatalist = grab.sortedSearch(title, subtitle=None, tolerance=2) details = grab.grabInetref(metadatalist[0].inetref) # details has lists of dicts for # 'certifications', 'categories', 'countries', 'studios', 'people', 'images' names = [n.name for n in details.people] self.assertTrue(cast in names) tree = etree.XML(u'<metadata></metadata>') tree.append(details.toXML()) xml_str = etree.tostring ( tree , pretty_print = True , xml_declaration = True , encoding = "UTF-8" , standalone = "yes" ) xml_file = open("/tmp/details.xml", "wb") xml_file.write(xml_str) xml_file.close() # read xml file and check for cast root = etree.parse(r'/tmp/details.xml').getroot() cast_found = False for name in root.findall('item/people/person'): if (name.attrib['name'] == cast): cast_found = True self.assertTrue(cast_found)
def runjob(jobid=None, chanid=None, starttime=None): db = MythDB() if jobid: job = Job(jobid, db=db) chanid = job.chanid starttime = job.starttime rec = Recorded((chanid, starttime), db=db) timestr = time.strftime("%m-%d-%y %H:%M:%S") title_san = re.sub("\s", ".", rec.title) print title_san try: os.mkdir(log_dir) except OSError, e: pass
def findrecs(title): db = MythDB() if title is None: print 'title is the only supported query right now...' return None recs = db.searchRecorded(title=title) tobedone = [] for rec in recs: #print 'Checking rec:' #print rec if rec.basename.endswith('mpg'): tobedone.append(rec) else: print 'Skipping non mpg: %s' % rec.basename return tobedone
def print_format(): db = MythDB() host = gethostname() tfmt = db.settings[host]['mythvideo.TVexportfmt'] if not tfmt: tfmt = 'Television/%TITLE%/Season %SEASON%/%TITLE% - S%SEASON%E%EPISODEPAD% - %SUBTITLE%' mfmt = db.settings[host]['mythvideo.MOVIEexportfmt'] if not mfmt: mfmt = 'Movies/%TITLE%' gfmt = db.settings[host]['mythvideo.GENERICexportfmt'] if not gfmt: gfmt = 'Videos/%TITLE%' print "Current output formats:" print " TV: " + tfmt print " Movies: " + mfmt print " Generic: " + gfmt
def test_repr_002_02(self): """ Test '__repr__' and '__str__' methods from dataheap.py """ # Channel object: db = MythDB() c = Channel(self.testenv['RECCHANID'], db) print() print(repr(c)) print(str(c)) # 'visible' property of that channel: v = c.visible print() print(repr(v)) print(str(v))
def link_all(): db = MythDB() channels = get_channels(db) if opts.live: recs = db.searchRecorded(livetv=True) else: recs = db.searchRecorded() targets = {} for rec in recs: details = get_link_details(rec, channels) if details is None: continue source, dest, destfile = details if dest not in targets: targets[dest] = {} targets[dest][destfile] = source for (path, dirs, files) in os.walk(opts.dest, topdown=False): dir = path.split("/")[-1] if dir == "": continue if dir not in targets: for fname in files: if not os.path.islink(path + "/" + fname): raise Exception("Found non link - " + path + "/" + fname) os.unlink(path + "/" + fname) os.rmdir(path) continue else: for fname in files: print dir, fname if dir not in targets or fname not in targets[dir]: if not os.path.islink(path + "/" + fname): raise Exception("Found non link - " + path + "/" + fname) os.unlink(path + "/" + fname) else: del targets[dir][fname] print targets[dir] if len(targets[dir]) == 0: del targets[dir] for dir in targets: if not os.path.exists(opts.dest + dir): os.mkdir(opts.dest + dir) for fname in targets[dir]: os.symlink(targets[dir][fname], opts.dest + "/" + dir + "/" + fname)
def link_all(): # removing old content for path,dirs,files in os.walk(opts.dest, topdown=False): for fname in files: tmppath = os.path.join(path, fname) if not os.path.islink(tmppath): raise Exception('Non-link file found in destination path.') os.unlink(tmppath) os.rmdir(path) db = MythDB() if opts.live: recs = db.searchRecorded(livetv=True) else: recs = db.searchRecorded() for rec in recs: gen_link(rec)
def runjob(jobid=None, chanid=None, starttime=None): db = MythDB() if jobid: job = Job(jobid, db=db) chanid = job.chanid starttime = job.starttime else: starttime = datetime.strptime(str(starttime), "%Y%m%d%H%M%S") + timedelta(hours=-5) rec = Recorded((chanid, starttime), db=db) timestr = time.strftime("%m-%d-%y %H:%M:%S") title_san = re.sub("\s", ".", rec.title) print title_san try: os.mkdir(log_dir) except OSError, e: pass
def test_repr_003_01(self): """ Test '__repr__' and '__str__' methods of 'Frontend' class. """ db = MythDB() fe = Frontend("%s" % (self.testenv['FRONTENDIP']), 6546) print() print(repr(fe)) print(str(fe)) # print list of keys and jump values print() print(repr(fe.key)) print(str(fe.key)) print() print(repr(fe.jump)) print(str(fe.jump))
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 runjob(rec): db = MythDB() timestr = time.strftime("%m-%d-%y %H:%M:%S") title_san = re.sub("\s", ".", rec.title) trans_log_file = os.path.join(log_dir, "%s_transcode_log_%s.hb.txt" % (title_san, timestr)) commflag_log_file = os.path.join(log_dir, "%s_transcode_log_%s.cf.txt" % (title_san, timestr)) mythical_log_file = os.path.join(log_dir, "%s_transcode_log_%s.ml.txt" % (title_san, timestr)) sg = findfile('/'+rec.basename, rec.storagegroup, db=db) if sg is None: print 'Local access to recording not found.' sys.exit(1) infile = os.path.join(sg.dirname, rec.basename) tmpfile = '%s.tmp' % infile.rsplit('.',1)[0] outfile = '%s.mp4' % infile.rsplit('.',1)[0] print "Infile: %s" % infile print "Outfile: %s" % outfile # reformat 'starttime' for use with mythtranscode/ffmpeg/mythcommflag starttime = str(rec.starttime.utcisoformat().replace(u':', '').replace(u' ', '').replace(u'T', '').replace('-', '')) chanid = rec.chanid # Lossless transcode to strip cutlist if rec.cutlist == 1 and false: if job: job.update({'status':4, 'comment':'Removing Cutlist'}) task = System(path='mythtranscode', db=db) try: output = task('--chanid "%s"' % chanid, '--starttime "%s"' % starttime, '--mpeg2', '--honorcutlist', '-o "%s"' % tmpfile, '2> /dev/null') except MythError, e: print 'Command failed with output:\n%s' % e.stderr if job: job.update({'status':304, 'comment':'Removing Cutlist failed'}) sys.exit(e.retcode)
def runjob(jobid=None, chanid=None, starttime=None): db = MythDB() if jobid: job = Job(jobid, db=db) chanid = job.chanid starttime = job.starttime rec = Recorded((chanid, starttime), db=db) sg = findfile('/' + rec.basename, rec.storagegroup, db=db) if sg is None: print 'Local access to recording not found.' sys.exit(1) infile = os.path.join(sg.dirname, rec.basename) tmpfile = '%s.tmp' % infile.rsplit('.', 1)[0] outfile = '%s.mp4' % infile.rsplit('.', 1)[0] # reformat 'starttime' for use with mythtranscode/ffmpeg/mythcommflag starttime = str(starttime.utcisoformat().replace(u':', '').replace( u' ', '').replace(u'T', '').replace('-', '')) # Lossless transcode to strip cutlist if rec.cutlist == 1: if jobid: job.update({'status': 4, 'comment': 'Removing Cutlist'}) task = System(path='mythtranscode', db=db) try: output = task('--chanid "%s"' % chanid, '--starttime "%s"' % starttime, '--mpeg2', '--honorcutlist', '-o "%s"' % tmpfile, '2> /dev/null') except MythError, e: print 'Command failed with output:\n%s' % e.stderr if jobid: job.update({ 'status': 304, 'comment': 'Removing Cutlist failed' }) sys.exit(e.retcode)