Fixes issues with tvdb and tvrage api content attribute not found

This commit is contained in:
echel0n 2014-04-22 12:15:15 -07:00
parent fdfc8eb219
commit f54a6e25b2
3 changed files with 100 additions and 68 deletions

View file

@ -5,15 +5,8 @@
#repository:http://github.com/dbr/tvdb_api #repository:http://github.com/dbr/tvdb_api
#license:unlicense (http://unlicense.org/) #license:unlicense (http://unlicense.org/)
"""Simple-to-use Python interface to The TVDB's API (thetvdb.com) from functools import wraps
Example usage:
>>> from tvdb_api import Tvdb
>>> t = Tvdb()
>>> t['Lost'][4][11]['episodename']
u'Cabin Fever'
"""
__author__ = "dbr/Ben" __author__ = "dbr/Ben"
__version__ = "1.9" __version__ = "1.9"
@ -25,6 +18,8 @@ import tempfile
import warnings import warnings
import logging import logging
import zipfile import zipfile
import requests
import cachecontrol
try: try:
import xml.etree.cElementTree as ElementTree import xml.etree.cElementTree as ElementTree
@ -36,10 +31,7 @@ try:
except ImportError: except ImportError:
gzip = None gzip = None
from lib import requests from cachecontrol import caches
from lib.requests import exceptions
from lib import cachecontrol
from lib.cachecontrol import caches
from tvdb_ui import BaseUI, ConsoleUI from tvdb_ui import BaseUI, ConsoleUI
from tvdb_exceptions import (tvdb_error, tvdb_userabort, tvdb_shownotfound, from tvdb_exceptions import (tvdb_error, tvdb_userabort, tvdb_shownotfound,
@ -48,6 +40,48 @@ from tvdb_exceptions import (tvdb_error, tvdb_userabort, tvdb_shownotfound,
def log(): def log():
return logging.getLogger("tvdb_api") return logging.getLogger("tvdb_api")
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
"""Retry calling the decorated function using an exponential backoff.
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
:param ExceptionToCheck: the exception to check. may be a tuple of
exceptions to check
:type ExceptionToCheck: Exception or tuple
:param tries: number of times to try (not retry) before giving up
:type tries: int
:param delay: initial delay between retries in seconds
:type delay: int
:param backoff: backoff multiplier e.g. value of 2 will double the delay
each retry
:type backoff: int
:param logger: logger to use. If None, print
:type logger: logging.Logger instance
"""
def deco_retry(f):
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 1:
try:
return f(*args, **kwargs)
except ExceptionToCheck, e:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
if logger:
logger.warning(msg)
else:
print msg
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry # true decorator
return deco_retry
class ShowContainer(dict): class ShowContainer(dict):
"""Simple dict that holds a series of Show instances """Simple dict that holds a series of Show instances
@ -509,27 +543,7 @@ class Tvdb:
return os.path.join(tempfile.gettempdir(), "tvdb_api-%s" % (uid)) return os.path.join(tempfile.gettempdir(), "tvdb_api-%s" % (uid))
@retry(tvdb_error)
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2):
def deco_retry(f):
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 0:
try:
return f(*args, **kwargs)
except ExceptionToCheck, e:
print "%s, Retrying in %d seconds..." % (str(e), mdelay)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
lastException = e
raise lastException
return f_retry # true decorator
return deco_retry
@retry(tvdb_error, tries=4)
def _loadUrl(self, url, params=None, language=None): def _loadUrl(self, url, params=None, language=None):
try: try:
log().debug("Retrieving URL %s" % url) log().debug("Retrieving URL %s" % url)
@ -549,9 +563,6 @@ class Tvdb:
except requests.Timeout, e: except requests.Timeout, e:
raise tvdb_error("Connection timed out " + str(e.message) + " while loading URL " + str(url)) raise tvdb_error("Connection timed out " + str(e.message) + " while loading URL " + str(url))
except Exception, e:
raise tvdb_error("Unknown exception occured: " + str(e.message) + " while loading URL " + str(url))
if 'application/zip' in resp.headers.get("Content-Type", '') and resp.ok: if 'application/zip' in resp.headers.get("Content-Type", '') and resp.ok:
try: try:
# TODO: The zip contains actors.xml and banners.xml, which are currently ignored [GH-20] # TODO: The zip contains actors.xml and banners.xml, which are currently ignored [GH-20]

View file

@ -9,32 +9,29 @@
Modified from http://github.com/dbr/tvrage_api Modified from http://github.com/dbr/tvrage_api
Simple-to-use Python interface to The TVRage's API (tvrage.com) Simple-to-use Python interface to The TVRage's API (tvrage.com)
""" """
from functools import wraps
__author__ = "echel0n" __author__ = "echel0n"
__version__ = "1.0" __version__ = "1.0"
import os import os
import re import re
import time import time
import urllib
import getpass import getpass
import tempfile import tempfile
import warnings import warnings
import logging import logging
import StringIO
import zipfile
import datetime as dt import datetime as dt
import requests
import cachecontrol
try: try:
import xml.etree.cElementTree as ElementTree import xml.etree.cElementTree as ElementTree
except ImportError: except ImportError:
import xml.etree.ElementTree as ElementTree import xml.etree.ElementTree as ElementTree
from lib.dateutil.parser import parse from dateutil.parser import parse
from cachecontrol import caches
from lib import requests
from lib.requests import exceptions
from lib import cachecontrol
from lib.cachecontrol import caches
from tvrage_ui import BaseUI from tvrage_ui import BaseUI
from tvrage_exceptions import (tvrage_error, tvrage_userabort, tvrage_shownotfound, from tvrage_exceptions import (tvrage_error, tvrage_userabort, tvrage_shownotfound,
@ -43,6 +40,49 @@ from tvrage_exceptions import (tvrage_error, tvrage_userabort, tvrage_shownotfou
def log(): def log():
return logging.getLogger("tvrage_api") return logging.getLogger("tvrage_api")
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
"""Retry calling the decorated function using an exponential backoff.
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
:param ExceptionToCheck: the exception to check. may be a tuple of
exceptions to check
:type ExceptionToCheck: Exception or tuple
:param tries: number of times to try (not retry) before giving up
:type tries: int
:param delay: initial delay between retries in seconds
:type delay: int
:param backoff: backoff multiplier e.g. value of 2 will double the delay
each retry
:type backoff: int
:param logger: logger to use. If None, print
:type logger: logging.Logger instance
"""
def deco_retry(f):
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 1:
try:
return f(*args, **kwargs)
except ExceptionToCheck, e:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
if logger:
logger.warning(msg)
else:
print msg
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry # true decorator
return deco_retry
class ShowContainer(dict): class ShowContainer(dict):
"""Simple dict that holds a series of Show instances """Simple dict that holds a series of Show instances
""" """
@ -343,26 +383,7 @@ class TVRage:
return os.path.join(tempfile.gettempdir(), "tvrage_api-%s" % (uid)) return os.path.join(tempfile.gettempdir(), "tvrage_api-%s" % (uid))
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2): @retry(tvrage_error)
def deco_retry(f):
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 0:
try:
return f(*args, **kwargs)
except ExceptionToCheck, e:
print "%s, Retrying in %d seconds..." % (str(e), mdelay)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
lastException = e
raise lastException
return f_retry # true decorator
return deco_retry
@retry(tvrage_error, tries=4)
def _loadUrl(self, url, params=None): def _loadUrl(self, url, params=None):
try: try:
log().debug("Retrieving URL %s" % url) log().debug("Retrieving URL %s" % url)

View file

@ -102,17 +102,17 @@ class MainSanityCheck(db.DBSanityCheck):
def fix_missing_table_indexes(self): def fix_missing_table_indexes(self):
try: try:
self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);") sqlResults = self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);")
logger.log(u"Missing idx_indexer_id for TV Shows table added!") logger.log(u"Missing idx_indexer_id for TV Shows table added!")
except:pass except:pass
try: try:
self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);") sqlResults = self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);")
logger.log(u"Missing idx_tv_episodes_showid_airdate for TV Episodes table added!") logger.log(u"Missing idx_tv_episodes_showid_airdate for TV Episodes table added!")
except:pass except:pass
try: try:
self.connection.action("CREATE INDEX idx_showid ON tv_episodes (showid);") sqlResults = self.connection.action("CREATE INDEX idx_showid ON tv_episodes (showid);")
logger.log(u"Missing idx_showid for TV Episodes table added!") logger.log(u"Missing idx_showid for TV Episodes table added!")
except:pass except:pass