Be smarter about the generation of the filenames

This commit is contained in:
Stefan Bethke 2017-04-16 17:46:43 +02:00
parent 28067b7632
commit 2dead3bacc
2 changed files with 93 additions and 64 deletions

View file

View file

@ -1,4 +1,5 @@
#!/usr/local/bin/python #!/usr/local/bin/python
# -*- coding: utf8 -*-
# Stefans Script, um die Sendungen vom Tivo runterzuladen und in MPEG4 # Stefans Script, um die Sendungen vom Tivo runterzuladen und in MPEG4
# zu transkodieren. # zu transkodieren.
@ -18,6 +19,7 @@ import functools
import logging import logging
import logging.handlers import logging.handlers
import os import os
import pytz
import re import re
import requests import requests
import signal import signal
@ -48,46 +50,51 @@ headers.update(
} }
) )
arset = dict() class IncludeShow:
includes = dict()
includes = dict() def __init__(self, title, short=None):
includes['Anthony Bourdain Parts Unknown'] = 1 self.short = short
includes['Better Call Saul'] = 1 self.title = title
includes['Brooklyn Nine-Nine'] = 1 self.timestamp = False
includes['Bull'] = 1 self.includes[title] = self
includes['College Football'] = 1
includes['Conan'] = 1 IncludeShow('Splash and Bubbles')
includes["Dirk Gently's Holistic Detective Agency"] = 1 IncludeShow('Angie Tribeca')
includes['The Expanse'] = 1 IncludeShow('Anthony Bourdain Parts Unknown')
includes['Family Guy'] = 1 IncludeShow('Better Call Saul')
includes['Full Frontal With Samantha Bee'] = 1 IncludeShow('Brooklyn Nine-Nine')
includes['Hot in Cleveland'] = 1 IncludeShow('Bull')
includes["How It's Made"] = 1 IncludeShow('College Football')
includes["How Do They Do It?"] = 1 IncludeShow('Conan')
includes["How We Got to Now With Steven Johnson"] = 1 IncludeShow("Dirk Gently's Holistic Detective Agency", short='Dirk Gently')
includes['Inside Amy Schumer'] = 1 IncludeShow('The Expanse')
includes['Join or Die With Craig Ferguson'] = 1 IncludeShow('Family Guy')
includes['Last Week Tonight With John Oliver'] = 1 IncludeShow('Full Frontal With Samantha Bee', short='Full Frontal')
includes['Louie'] = 1 IncludeShow("How It's Made")
includes['Mad Men'] = 1 IncludeShow("How Do They Do It?")
includes['Modern Family'] = 1 IncludeShow("How We Got to Now With Steven Johnson")
includes['MythBusters'] = 1 IncludeShow('Inside Amy Schumer')
includes['MythBusters: The Search'] = 1 IncludeShow('Join or Die With Craig Ferguson')
includes['NCIS'] = 1 IncludeShow('Last Week Tonight With John Oliver', short='John Oliver')
includes['NCIS: New Orleans'] = 1 IncludeShow('Louie')
#includes['NFL Football'] = 1 IncludeShow('Modern Family')
includes['Person of Interest'] = 1 IncludeShow('MythBusters')
includes['Saturday Night Live'] = 1 IncludeShow('NCIS')
includes['Sesame Street'] = 1 IncludeShow('NCIS: New Orleans')
includes["Somebody's Gotta Do It With Mike Rowe"] = 1 #IncludeShow('NFL Football')
includes['StarTalk'] = 1 IncludeShow('Person of Interest')
includes['The Big Bang Theory'] = 1 IncludeShow('Saturday Night Live', short='SNL')
includes['The Daily Show With Trevor Noah'] = 1 IncludeShow('Sesame Street')
includes['The Late Show With Stephen Colbert'] = 1 IncludeShow("Somebody's Gotta Do It With Mike Rowe")
#includes['The Late Late Show With James Corden'] = 1 IncludeShow('StarTalk')
includes['The Muppets'] = 1 IncludeShow('The Big Bang Theory')
includes['The X-Files'] = 1 IncludeShow('The Daily Show With Trevor Noah', short='Daily Show')
#includes['The Tonight Show Starring Jimmy Fallon'] = 1 IncludeShow('The Late Show With Stephen Colbert', short='Colbert')
#IncludeShow('The Late Late Show With James Corden')
IncludeShow('The Muppets')
IncludeShow('The X-Files')
#IncludeShow('The Tonight Show Starring Jimmy Fallon')
@ -113,6 +120,17 @@ session.auth = requests.auth.HTTPDigestAuth("tivo", mak)
session.keep_alive = False session.keep_alive = False
session.proxies = proxies session.proxies = proxies
def roundTime(dt=None, roundTo=60):
"""
http://stackoverflow.com/questions/3463930/how-to-round-the-minute-of-a-datetime-object-python
"""
if dt == None : dt = datetime.datetime.now()
seconds = (dt.replace(tzinfo=None) - dt.min).seconds
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)
class TimeoutError(Exception): class TimeoutError(Exception):
pass pass
@ -169,21 +187,18 @@ class TivoItem:
self.episodeNumber = getTagText(i, "EpisodeNumber") self.episodeNumber = getTagText(i, "EpisodeNumber")
self.description = trimDescription(getTagText(i, "Description")) self.description = trimDescription(getTagText(i, "Description"))
d = getTagText(i, "CaptureDate") d = getTagText(i, "CaptureDate")
self.date = datetime.datetime.utcfromtimestamp(int(d, 16)) self.date = datetime.datetime.fromtimestamp(int(d, 16), pytz.utc)
self.time = int(d, base=0) est = pytz.timezone('US/Eastern')
eastern = roundTime(self.date, 15*60).astimezone(est)
self.datestr = self.date.strftime("%Y%m%d-%H%M") self.datestr = self.date.strftime("%Y%m%d-%H%M")
self.shortdate = eastern.strftime("%m%d-%H%M")
self.url = getTagText(i, "Url") self.url = getTagText(i, "Url")
self.url = self.url + "&Format=video/x-tivo-mpeg-ts" self.url = self.url + "&Format=video/x-tivo-mpeg-ts"
self.inprogress = getTagText(i, "InProgress") self.inprogress = getTagText(i, "InProgress")
self.available = getTagText(i, "Available") self.available = getTagText(i, "Available")
self.sourcesize = int(getTagText(i, "SourceSize")) self.sourcesize = int(getTagText(i, "SourceSize"))
self.highdef = getTagText(i, "HighDefinition") self.highdef = getTagText(i, "HighDefinition")
self.ar = 43
self.unique = True self.unique = True
if arset.has_key(self.title):
self.ar = arset[self.title]
elif self.highdef == "Yes":
self.ar = "hd"
if ignoreepisodetitle: if ignoreepisodetitle:
self.episode = self.datestr self.episode = self.datestr
if self.episode == "": if self.episode == "":
@ -211,6 +226,22 @@ class TivoItem:
self.name = self.name.encode("utf-8"); self.name = self.name.encode("utf-8");
self.dir = self.dir.encode("utf-8"); self.dir = self.dir.encode("utf-8");
self.file = self.file.encode("utf-8"); self.file = self.file.encode("utf-8");
def getPath(self, options):
title = self.title
if options.short:
title = options.short
if self.episodeNumber and self.episodeNumber != u'0':
en = int(self.episodeNumber)
if en >= 100:
name = "%s S%02dE%02d %s" % (title, en / 100, en % 100, self.episode)
else:
name = "%s E%s %s" % (title, self.episodeNumber, self.episode)
elif self.unique:
name = "%s - %s" % (title, self.episode)
else:
name = "%s - %s %s" % (title, self.shortdate, self.episode)
path = "%s/%s" % (self.dir, re.sub("[:/]", "-", name))
return path.encode("utf-8");
def __str__(self): def __str__(self):
return repr(self.title) return repr(self.title)
@ -351,6 +382,7 @@ def download_item(item, mak, target):
url = item.url url = item.url
#url = re.sub("tivo.lassitu.de:80", "wavehh.lassitu.de:30080", url) #url = re.sub("tivo.lassitu.de:80", "wavehh.lassitu.de:30080", url)
logger.info("--- downloading \"%s\"" % (url)) logger.info("--- downloading \"%s\"" % (url))
logger.info(" {}".format(target))
start = time.time() start = time.time()
r = session.get(url, stream=True, verify=False, proxies=proxies, headers=headers) r = session.get(url, stream=True, verify=False, proxies=proxies, headers=headers)
r.raise_for_status() r.raise_for_status()
@ -419,8 +451,8 @@ def download_item(item, mak, target):
raise TivoException("downloaded file is too small") raise TivoException("downloaded file is too small")
def download_decode(item, mak): def download_decode(item, options, mak):
target = "%s.mpg" % item.file target = "%s.mpg" % item.getPath(options)
try: try:
os.makedirs(item.dir) os.makedirs(item.dir)
except OSError: except OSError:
@ -440,11 +472,11 @@ def download_decode(item, mak):
logger.error("Problem setting timestamp: %" % (e)) logger.error("Problem setting timestamp: %" % (e))
def download_one(item, downloaddb): def download_one(item, downloaddb, options):
global logger, mak global logger, mak
logger.info("*** downloading \"%s\": %.3fGB" % (item.name, item.sourcesize / 1e9)) logger.info("*** downloading \"%s\": %.3fGB" % (item.name, item.sourcesize / 1e9))
try: try:
download_decode(item, mak) download_decode(item, options, mak)
downloaddb[item.name] = item.datestr downloaddb[item.name] = item.datestr
if getattr(downloaddb, "sync", None) and callable(downloaddb.sync): if getattr(downloaddb, "sync", None) and callable(downloaddb.sync):
downloaddb.sync() downloaddb.sync()
@ -461,13 +493,10 @@ def wantitem(item, downloaddb):
return "not available" return "not available"
if downloaddb.has_key(item.name): if downloaddb.has_key(item.name):
return "already downloaded" return "already downloaded"
#if excludes.has_key(item.title) or excludes.has_key(item.episode) or excludes.has_key(item.name): for i in (item.title, item.episode, item.name):
# return "excluded" if IncludeShow.includes.has_key(i):
if includes.has_key(item.title) or includes.has_key(item.episode) or includes.has_key(item.name): return IncludeShow.includes[i]
pass
else:
return "not included" return "not included"
return ""
def mirror(toc, downloaddb, one=False): def mirror(toc, downloaddb, one=False):
@ -480,11 +509,11 @@ def mirror(toc, downloaddb, one=False):
items = toc.getItems() items = toc.getItems()
logger.info("*** %d shows listed" % (len(items))) logger.info("*** %d shows listed" % (len(items)))
for item in items: for item in items:
reason = wantitem(item, downloaddb) options = wantitem(item, downloaddb)
if reason != "": if isinstance(options, basestring):
logger.debug("*** skipping \"%s\": %s" % (item.name, reason)) logger.debug("*** skipping \"%s\": %s" % (item.name, options))
else: else:
download_one(item, downloaddb) download_one(item, downloaddb, options)
if one: if one:
break break
@ -506,9 +535,9 @@ def printtoc(toc, downloaddb):
shows[item.title].append(item) shows[item.title].append(item)
for title in sorted(shows): for title in sorted(shows):
for item in sorted(shows[title], key=lambda i: i.name): for item in sorted(shows[title], key=lambda i: i.name):
reason = wantitem(item, downloaddb) options = wantitem(item, downloaddb)
if (reason != ""): if isinstance(options, basestring):
print "%-7.7s: %s" % (reason, item.name) print "%-7.7s: %s" % (options, item.name)
continue continue
print "*** downloading %s (%.3fGB)" % (item.name, item.sourcesize / 1e9) print "*** downloading %s (%.3fGB)" % (item.name, item.sourcesize / 1e9)