def cleanYaml(): try: config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str( config["tvhport"]) tot, ents = TVH.finishedRecordings() titles = set() for entry in ents: if "disp_title" in entry: titles.add(entry["disp_title"]) if config["Year"] is not None: ycn = ocn = 0 txy = [] while len(config["Year"]) > 0: ty = config["Year"].pop() # ty.keys() returns a 1 element list, this turns it into a string (year, ) = ty.keys() tmpyear = [] for title in ty[year]: ycn += 1 if title in titles: ocn += 1 tmpyear.append(title) if len(tmpyear) > 0: txy.append({year: tmpyear}) config["Year"] = txy print("searched {} titles, found {}".format(ycn, ocn)) CONF.writeConfig(config) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def main(): try: files = [] dbfn = "/home/chris/Videos/kmedia/tvh/tvh.db" fffn = "/home/chris/Videos/kmedia/TV/mpeg-todo" db = tvheadend.tvhdb.TVHDb(dbfn) sql = "insert into files (name,size,hash) values (?, ?, ?)" with open(fffn, "r") as fn: lines = fn.readlines() for line in lines: files.append(line.strip()) log.info("Found {} files to insert".format(len(files))) cn = 0 for fn in files: if FUT.fileExists(fn): log.info("obtaining details of {}".format(fn)) fhash, fsize = FUT.getFileHash(fn, blocksize=10485760) log.info("{} {}".format(fhash, FUT.sizeof_fmt(fsize))) log.info("inserting into db") db.doInsertSql(sql, [fn, fsize, fhash]) cn += 1 log.info("inserted {} files into DB".format(cn)) db.doInsertSql(sql, fvals) sql = "select count(*) as cn from files" row = db.doSql(sql, one=1) log.info("there are {} files currently in the db".format(row["cn"])) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvhwatchlist(): try: log.info("tvheadend watch utility " + tvheadend.__version__) config = CONF.readConfig() db = tvheadend.tvhdb.TVHDb(config["tvhdb"]) listFilesWaiting(db) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def writeConfig(config): try: yamlfn = "tvh.yaml" home = Path.home() configfn = home.joinpath(".config", yamlfn) with open(str(configfn), "w") as cfn: yaml.dump(config, cfn, default_flow_style=False) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e, 1)
def readConfig(): try: config = {} yamlfn = "tvh.yaml" home = Path.home() configfn = home.joinpath(".config", yamlfn) with open(str(configfn), "r") as cfn: config = yaml.safe_load(cfn) return config except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e, 1)
def tvhPrograms(start=0, length=2): try: print("tvheadend enabled channel lister " + tvheadend.__version__) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str( config["tvhport"]) TVH.timeSlotPrograms(start, length) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def doFile(): try: log.info("tvheadend TS file insert utility " + tvheadend.__version__) config = CONF.readConfig() db = tvheadend.tvhdb.TVHDb(config["tvhdb"]) if len(sys.argv) > 1: for fn in sys.argv[1:]: processFile(fn, db) else: sys.exit(USAGE) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def processFile(fn, db): try: fhash, fsize = FUT.getFileHash(fn) sql = "insert into files (name,size,hash) values (?, ?, ?)" db.doInsertSql(sql, ( fn, fsize, fhash, )) log.info("added {} to db".format(fn)) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def main(): try: log.info("tvheadend db insert utility " + tvheadend.__version__) config = CONF.readConfig() db = tvheadend.tvhdb.TVHDb(config["tvhdb"]) with open("/home/chris/Videos/kmedia/TV/mpeg-todo", "r") as ifn: lines = ifn.readlines() for line in lines: fqfn = line.strip() log.info("processing {}".format(fqfn)) processFile(fqfn, db) log.info("done") except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvhChannels(channel="BBC ONE HD"): try: print("tvheadend enabled channel lister " + tvheadend.__version__) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str( config["tvhport"]) sents = TVH.channels() for chan in sents: print(UT.padStr(str(chan["number"]), 3), chan["name"]) TVH.channelPrograms(channel) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def cleanYears(config): try: txy = [] xy = config["Year"] if xy is not None: while len(xy) > 0: ty = xy.pop() for key in ty.keys(): if len(ty[key]) == 0: log.info("Remove empty year: {}".format(key)) else: txy.append(ty) config["Year"] = txy except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvhlist(): try: print("tvheadend file lister " + tvheadend.__version__) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str( config["tvhport"]) tot, ents = TVH.finishedRecordings() for show in ents: UT.addBaseFn(show) msg = "{}".format(show["opbase"]) msg += " {}".format(show["filename"]) print(msg) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def main(): try: log.info("tvheadend gui " + tvheadend.__version__) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) tvheadend.videohome = config["videohome"] tvheadend.filmhome = config["filmhome"] app = tvhg() app.run(sys.argv) # win = MainWindow() # win.connect("destroy", Gtk.main_quit) # win.CurrRecs() # Gtk.main() except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvhwatch(): try: log.info("tvheadend watch utility " + tvheadend.__version__) config = CONF.readConfig() db = tvheadend.tvhdb.TVHDb(config["tvhdb"]) stopnow = False while not stopnow: stopnow = processFiles(db) if stopnow: FUT.fileDelete(stopnext) log.info("Stop file found, stopping now") break time.sleep(30) except KeyboardInterrupt: log.info(f"Keyboard interrupt") stopnow = True except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def updateKodi(): try: data = {"jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": "1"} headers = {"content-type": "application/json"} url = "http://127.0.0.1:8080/jsonrpc" resp = requests.post(url, json=data, headers=headers, timeout=10) if resp.status_code < 399: log.info("Kodi update starting") log.info("response: {}".format(resp)) log.info("response text: {}".format(resp.text)) else: log.info("Failed to update Kodi") log.info("response: {}".format(resp)) log.info("response text: {}".format(resp.text)) except ConnectionError as ce: log.info("Kodi isn't running") except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def removeFromYear(show, config): try: if "year" in show: if config["Year"] is not None: syear = str(show["year"]) years = config["Year"] changed = False for xyear in years: for yearname in xyear: if yearname == syear: if show["title"] in xyear[yearname]: xyear[yearname].remove(show["title"]) changed = True break if changed: break except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def gobabe(): try: config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) start, length = getStartLength() epg = TVH.filterPrograms(channel="BBC Two HD") print(f"channel filter returned {len(epg)} progs") epg = TVH.filterPrograms(start=start, length=length) print(f"time filter returned {len(epg)} progs") epg = TVH.filterPrograms(channel="BBC Two HD", start=start, length=length) print(f"time/channel filter returned {len(epg)} progs") # total, entries = TVH.getEpg() # if total is not None and entries is not None: # print(f"received {total} entries") # TVH.timeSlotPrograms(start, length) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvhdelete(): try: print("tvheadend file deletion " + tvheadend.__version__) if len(sys.argv) > 1: showfiles = sys.argv[1:] else: raise(TvhInputError("Please supply a filename")) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) # ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) # tvhauth = {"ip": ipaddr, "xuser": config["user"], "xpass": config["pass"]} tot, ents = TVH.finishedRecordings() for show in ents: if show["filename"] in showfiles: print("Deleting {}".format(show["filename"])) TVH.deleteRecording(show["uuid"]) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvhnfo(): try: print("tvheadend nfo writer " + tvheadend.__version__) if len(sys.argv) > 1: fns = sys.argv[1:] else: raise(TvhInputError("Please supply a filename")) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) tot, ents = TVH.finishedRecordings() for show in ents: if show["filename"] in fns: UT.addBaseFn(show) snfo = NFO.makeProgNfo(show) nfofn = show["opbase"] + ".nfo" with open(nfofn, "w") as nfn: nfn.write(snfo) print("nfo written to {}".format(nfofn)) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def tvh(): try: print("tvheadend file utility " + tvheadend.__version__) config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str( config["tvhport"]) # ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) # tvhauth = {"ip": ipaddr, "xuser": config["user"], "xpass": config["pass"]} tot, ents = TVH.finishedRecordings() exit = False while not exit: shows = CATS.setCategories(ents, config) print("\nshows: {}, uncat: {}, ignore: {}\n".format( len(shows["shows"]), len(shows["uncatshows"]), len(shows["ignores"]))) for ent in shows["shows"]: if "category" in ent: cat = ent["category"] elif "year" in ent: cat = ent["year"] else: cat = None print("{}: {}: {}: {}".format(cat, ent["disp_title"], ent["disp_subtitle"], ent["filename"])) print("\n") if len(shows["uncatshows"]) == 0: exit = True else: exit = UT.mainMenu(shows, config) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e) finally: CONF.writeConfig(config)
def tvhbatch(): try: log.info("tvheadend batch utility " + tvheadend.__version__) # update kodi from last time, as hopefully, the transcode process will have done it's job updateKodi() config = CONF.readConfig() tvheadend.user = config["user"] tvheadend.passw = config["pass"] tvheadend.ipaddr = str(config["tvhipaddr"]) + ":" + str( config["tvhport"]) # ipaddr = str(config["tvhipaddr"]) + ":" + str(config["tvhport"]) # tvhauth = {"ip": ipaddr, "xuser": config["user"], "xpass": config["pass"]} tot, ents = TVH.finishedRecordings() shows = CATS.setCategories(ents, config) cn = 0 for show in shows["shows"]: UT.addBaseFn(show) moveShow(show, config) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e) finally: cleanYears(config) CONF.writeConfig(config)
def tvhc(): """ decide whether we want to show a single channels programs for the next 24 hours or the channel grid params: channel name - will detect if it has spaces in it's name or start - number of hours relative to now() length - number of hours to show programs for - optional """ try: starth = 0 length = 2 channel = None cn = len(sys.argv) if cn > 2: # could be a channel name with spaces or a start and length parameter if sys.argv[1].isnumeric(): starth = int(sys.argv[1]) length = int(sys.argv[2]) else: channel = " ".join(sys.argv[1:]) elif cn == 2: if sys.argv[1].isnumeric(): starth = int(sys.argv[1]) else: channel = sys.argv[1] if channel is not None: tvhChannels(channel) else: start = int(time.time()) + (3600 * starth) tvhPrograms(start, length) except: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def moveShow(self, show): try: then = time.time() tvhstat = os.stat(show["filename"]) self.log.info("{}: {}".format(show["opbase"], FUT.sizeof_fmt(tvhstat.st_size))) if "year" in show: if show["title"].startswith("The "): letter = show["title"][4:5].upper() else: letter = show["title"][0:1].upper() opdir = "/".join([tvheadend.filmhome, letter, show["opbase"]]) snfo = NFO.makeFilmNfo(show) else: category = show["category"] if category == "drama": category = "Drama" opdir = "/".join( [tvheadend.videohome, category, show["title"]]) snfo = NFO.makeProgNfo(show) basefn = "/".join([opdir, show["opbase"]]) opfn = basefn + ".mpg" mkopfn = basefn + ".mkv" existingfile = None if FUT.fileExists(opfn): existingfile = opfn elif FUT.fileExists(mkopfn): existingfile = mkopfn if existingfile is not None: self.log.info( "kodi file already exists, not copying {}".format( existingfile)) self.log.info("deleting from tvheadend") TVH.deleteRecording(show["uuid"]) else: self.log.info("making directory {}".format(opdir)) FUT.makePath(opdir) nfofn = basefn + ".nfo" self.log.info("writing nfo to {}".format(nfofn)) with open(nfofn, "w") as nfn: nfn.write(snfo) self.log.info("copying {} to {}".format( show["filename"], opfn)) t = threading.Thread(target=copyFile, args=(show["filename"], opfn)) t.start() while t.is_alive(): Gtk.main_iteration() # time.sleep(1) # wait for thread to complete t.join() # shutil.copy2(show["filename"], opfn) if FUT.fileExists(opfn): cstat = os.stat(opfn) if cstat.st_size == tvhstat.st_size: self.log.info("copying {} took: {}".format( FUT.sizeof_fmt(cstat.st_size), NFO.hmsDisplay(int(time.time() - then)), )) self.log.info("show copied to {} OK.".format(opfn)) fhash, fsize = FUT.getFileHash(show["filename"]) self.log.info("deleting from tvheadend") TVH.deleteRecording(show["uuid"]) self.log.info("updating DB") db = tvheadend.tvhdb.TVHDb(tvheadend.dbfn) sql = "insert into files (name,size,hash) values (?, ?, ?)" return db.doInsertSql(sql, ( opfn, fsize, fhash, )) else: raise (CopyFailure("Failed to copy {} to {}".format( show["filename"], opfn))) return False except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)
def moveShow(show, config): try: then = time.time() tvhstat = os.stat(show["filename"]) log.info("{}: {}".format(show["opbase"], FUT.sizeof_fmt(tvhstat.st_size))) if "year" in show: if show["title"].startswith("The "): letter = show["title"][4:5].upper() else: letter = show["title"][0:1].upper() opdir = "/".join([config["filmhome"], letter, show["opbase"]]) snfo = NFO.makeFilmNfo(show) else: opdir = "/".join( [config["videohome"], show["category"], show["title"]]) snfo = NFO.makeProgNfo(show) basefn = "/".join([opdir, show["opbase"]]) opfn = basefn + ".mpg" mkopfn = basefn + ".mkv" existingfile = None if FUT.fileExists(opfn): existingfile = opfn elif FUT.fileExists(mkopfn): existingfile = mkopfn if existingfile is not None: log.info("kodi file already exists, not copying {}".format( existingfile)) log.info("deleting from tvheadend") TVH.deleteRecording(show["uuid"]) else: log.info("making directory {}".format(opdir)) FUT.makePath(opdir) nfofn = basefn + ".nfo" log.info("writing nfo to {}".format(nfofn)) with open(nfofn, "w") as nfn: nfn.write(snfo) log.info("copying {} to {}".format(show["filename"], opfn)) shutil.copy2(show["filename"], opfn) if FUT.fileExists(opfn): cstat = os.stat(opfn) if cstat.st_size == tvhstat.st_size: log.info("copying {} took: {}".format( FUT.sizeof_fmt(cstat.st_size), NFO.hmsDisplay(int(time.time() - then)), )) log.info("show copied to {} OK.".format(opfn)) fhash, fsize = FUT.getFileHash(show["filename"]) log.info("deleting from tvheadend") TVH.deleteRecording(show["uuid"]) log.info("updating DB") db = tvheadend.tvhdb.TVHDb(dbfn) # sql = "insert into files (name,size,hash) values (" # sql += "'{}',{},'{}')".format(opfn, fsize, fhash) # db.doSql(sql) sql = "insert into files (name,size,hash) values (?, ?, ?)" db.doInsertSql(sql, ( opfn, fsize, fhash, )) # it is safe to run removeFromYear for all shows # as it tests whether this is a movie or not removeFromYear(show, config) # log.info("\n") # if show["channelname"].endswith("HD"): # log.info("Not converting HD programme {}".format(show["title"])) # else: # log.info("converting {} to mkv".format(show["title"])) # convertToMkv(opfn) # FFMPEG.convert(opfn) else: raise (CopyFailure("Failed to copy {} to {}".format( show["filename"], opfn))) except Exception as e: fname = sys._getframe().f_code.co_name errorExit(fname, e)