diff --git a/src/tivomirror/tivomirror b/src/tivomirror/tivomirror index b3b1aa0..13586a4 100755 --- a/src/tivomirror/tivomirror +++ b/src/tivomirror/tivomirror @@ -1,6 +1,6 @@ #!/usr/local/bin/python -# $Schlepperbande: src/tivomirror/tivomirror,v 1.63 2014/07/05 15:23:02 stb Exp $ +# $Schlepperbande: src/tivomirror/tivomirror,v 1.64 2014/07/07 21:50:28 stb Exp $ # # Stefans Script, um die Sendungen vom Tivo runterzuladen und in MPEG4 # zu transkodieren. @@ -138,6 +138,7 @@ class TivoItem: self.sourcesize = int(getTagText(i, "SourceSize")) self.highdef = getTagText(i, "HighDefinition") self.ar = 43 + self.unique = True if arset.has_key(self.title): self.ar = arset[self.title] elif self.highdef == "Yes": @@ -149,14 +150,21 @@ class TivoItem: self.episode = self.description else: self.episode = self.datestr + self.formatnames() + def makeNotUnique(self): + self.unique = False + self.formatnames() + def formatnames(self): if self.episodeNumber and self.episodeNumber != u'0': en = int(self.episodeNumber) if en >= 100: self.name = "%s S%02dE%02d %s" % (self.title, en / 100, en % 100, self.episode) else: self.name = "%s E%s %s" % (self.title, self.episodeNumber, self.episode) - else: + elif self.unique: self.name = "%s - %s" % (self.title, self.episode) + else: + self.name = "%s - %s - %s" % (self.title, self.datestr, self.episode) self.dir = "%s/%s" % (targetdir, re.sub("[:/]", "-", self.title)) self.file = "%s/%s" % (self.dir, re.sub("[:/]", "-", self.name)) self.name = self.name.encode("utf-8"); @@ -168,19 +176,21 @@ class TivoItem: class TivoToc: def __init__(self): - self.toc = None + self.dom = None self.filename = "toc.xml" + self.uniquedb = anydbm.open("unique.db", "c") + self.items = [] pass def load(self): fd = open(self.filename, "r") - self.toc = xml.dom.minidom.parseString(fd.read()) + self.dom = xml.dom.minidom.parseString(fd.read()) fd.close() - return self.toc + return self.dom def save(self): fd = open(self.filename, "w") - fd.write(self.toc.toprettyxml()) + fd.write(self.dom.toprettyxml()) fd.close() def download_chunk(self, offset): @@ -195,7 +205,7 @@ class TivoToc: } url = "https://{}/TiVoConnect".format(host) logger.debug(" offset %d" % (offset)) - r = session.get(url, params=params) + r = session.get(url, params=params, timeout=30) if r.status_code != 200: r.raise_for_status() return r.text @@ -203,22 +213,47 @@ class TivoToc: def download(self): offset = 0 itemCount = 1 - self.toc = None + self.dom = None root = None logger.info("*** Getting listing") while itemCount > 0: dom = xml.dom.minidom.parseString(self.download_chunk(offset)) - if self.toc == None: - self.toc = dom - root = self.toc.childNodes.item(0) + if self.dom == None: + self.dom = dom + root = self.dom.childNodes.item(0) else: for child in dom.childNodes.item(0).childNodes: if child.nodeName == "Item": root.appendChild(child.cloneNode(True)) itemCount = int(getElementText(dom.documentElement.childNodes, "ItemCount")) offset += itemCount + return self.dom - return self.toc + def getItems(self): + self.titles = {} + for node in self.dom.getElementsByTagName("Item"): + item = TivoItem(node) + self.items.append(item) + if item.title not in self.titles: + self.titles[item.title] = [] + self.titles[item.title].append(item) + # see if we have items that end up having an identical name; mark + # the program title in uniquedb if that's the case + for title in self.titles: + names = {} + for item in self.titles[title]: + if item.name not in names: + names[item.name] = [] + names[item.name].append(item) + for name in names: + if len(names[name]) > 1: + self.uniquedb[title.encode("utf-8")] = "1" + if getattr(self.uniquedb, "sync", None) and callable(self.uniquedb.sync): + self.uniquedb.sync() + for item in self.items: + if self.uniquedb.has_key(item.title.encode("utf-8")): + item.makeNotUnique() + return self.items def getText(nodelist): @@ -418,10 +453,9 @@ def mirror(toc, downloaddb, one=False): (targetdir, avail / gig, minfree / gig)) sys.exit(1) - items = toc.toc.getElementsByTagName("Item") - logger.info("*** %d shows listed" % (items.length)) - for node in items: - item = TivoItem(node) + items = toc.getItems() + print "*** %d shows listed" % (len(items)) + for item in items: reason = wantitem(item, downloaddb) if reason != "": logger.debug("*** skipping \"%s\": %s" % (item.name, reason)) @@ -432,7 +466,7 @@ def mirror(toc, downloaddb, one=False): def download_episode(toc, downloaddb, episode): - items = toc.toc.getElementsByTagName("Item") + items = toc.dom.getElementsByTagName("Item") for node in items: item = TivoItem(node) if item.title == episode or item.name == episode or item.episode == episode: @@ -440,11 +474,10 @@ def download_episode(toc, downloaddb, episode): def printtoc(toc, downloaddb): - items = toc.toc.getElementsByTagName("Item") - print "*** %d shows listed" % (items.length) + items = toc.getItems() + print "*** %d shows listed" % (len(items)) shows = {} - for node in items: - item = TivoItem(node) + for item in items: if item.title not in shows: shows[item.title] = [] shows[item.title].append(item) @@ -489,6 +522,7 @@ def main(): if updateToc or cmd == "mirror": toc.download() + toc.save() else: toc.load()