TiVo Import
From MythTV Official Wiki
TiVo Recordings Import
Below is a script which will import recordings from a TiVo into MythTV's Recordings section in 0.25 and 0.26. Use at your own risk as it inserts recordings directly into the database.
Recordings and Metadata must be downloaded from the TiVo using KMTTG. The script looks for the downloads in /data/tivo, and moves them into /data. You'll need to change this based on where your mythtv is configured to save recordings. (Or symlink those directories.) Kmttg must be configured to use this filename format:
[channelNum]_[channel]_[hour]_[min]-[monthNum]_[mday]_[year]-[EpisodeNumber]
Here's the script:
#!/usr/bin/python import os import sys import _mysql import glob import datetime import isodate import shutil db = _mysql.connect("localhost","root","mythtv","mythconverg") if not db: exit(1) for metafile in glob.glob('/data/tivo/*.mpg'): mpgfile = metafile metafile += ".txt" if not os.path.exists(mpgfile) or not os.path.exists(metafile): continue print "" print metafile meta = dict() for line in open(metafile, "r"): parts = line.partition(':') if not parts[2]: continue meta[parts[0].strip()] = _mysql.escape_string(parts[2].strip()) try: db.query("SELECT chanid FROM channel WHERE channum = '"+meta['displayMajorNumber']+"'") chanid = db.use_result().fetch_row()[0][0] except: print "Unable to get channel id for channel", meta['displayMajorNumber'] continue try: rectime = isodate.parse_datetime(meta['time']) recdur = isodate.parse_duration(meta['iso_duration']) meta['time'] = str(rectime) meta['endtime'] = str(rectime+recdur) except: print "Failed to parse time/duration" rectime = datetime.datetime.today(); meta['endtime'] = meta['time'] = str(rectime) recdur = None try: ep = int(meta['episodeNumber']) season = ep/100 episode = ep%100 except: meta['episodeNumber'] = ""; season = 0 episode = 0 pass newmpgfile = chanid + "_" + rectime.strftime("%Y%m%d%H%M%S") + ".mpg" print newmpgfile, "=>", meta recently = datetime.datetime.today()-datetime.timedelta(minutes=60) if datetime.datetime.fromtimestamp(os.path.getmtime(mpgfile)) >= recently: print "Too soon to do", metafile continue elif os.path.exists('/data/'+newmpgfile): print "File /data/"+newmpgfile, "already exists, not doing anything" shutil.move(mpgfile, mpgfile+".done") else: db.query(''' INSERT INTO recorded (chanid, starttime, endtime, title, subtitle, description, hostname, autoexpire, seriesid, filesize, originalairdate, basename, progstart, progend, season, episode) VALUES('''+chanid+",'"+meta['time']+"','"+meta['endtime']+"',"+ "'"+meta['title']+"','"+meta['episodeTitle']+"',"+ "'[Imported from TiVo] "+meta['description']+"',"+ "'mediapc',1,'"+meta['seriesId']+"',"+str(os.path.getsize(mpgfile))+","+ "'"+meta['originalAirDate']+"','"+newmpgfile+"',"+ "'"+meta['time']+"','"+meta['endtime']+"',"+str(season)+","+str(episode)+")"); db.query('''INSERT IGNORE INTO recordedprogram(chanid, starttime, endtime, title, subtitle, description, seriesid, originalairdate, syndicatedepisodenumber) VALUES('''+chanid+",'"+meta['time']+"','"+meta['endtime']+"',"+ "'"+meta['title']+"','"+meta['episodeTitle']+"','[Imported from TiVo] "+meta['description']+"',"+ "'"+meta['seriesId']+"','"+meta['originalAirDate']+"'," "'"+meta['episodeNumber']+"')"); db.query("INSERT IGNORE INTO recordedrating(chanid, starttime, system, rating) "+ "VALUES("+chanid+",'"+meta['time']+"','VCHIP','U')"); db.query("INSERT INTO jobqueue(chanid,starttime,inserttime,"+ "type,status,hostname,comment)"+ "VALUES("+chanid+",'"+meta['time']+"',NOW(),2,1,'mediapc','Queued by TiVo')"); db.query("INSERT INTO jobqueue(chanid,starttime,inserttime,"+ "type,status,hostname,comment)"+ "VALUES("+chanid+",'"+meta['time']+"',NOW(),4,1,'mediapc','Queued by TiVo')"); shutil.move(mpgfile, '/data/'+newmpgfile) shutil.move(metafile, metafile + '.done') #exit(0) db.query("update recorded r set r.recordid = (select s.recordid from record s where s.title = r.title) "+ "where r.recordid is null and r.description like '[Import%'"); print "Done!!"