3
from flexget.plugin import register_plugin, internet
4
from flexget.manager import Base, Session
5
from flexget.utils.tools import urlopener
6
from BeautifulSoup import BeautifulStoneSoup
7
from sqlalchemy import Column, Integer, Unicode, DateTime, String
8
from datetime import datetime, timedelta
10
from flexget.plugins.filter_series import FilterSeriesBase
12
log = logging.getLogger('thetvdb_favorites')
15
class ThetvdbFavorites(Base):
17
__tablename__ = 'thetvdb_favorites'
19
id = Column(Integer, primary_key=True)
20
account_id = Column(String, index=True)
21
series_name = Column(Unicode)
22
series_id = Column(Unicode)
23
added = Column(DateTime)
25
def __init__(self, account_id, series_name, series_id):
26
self.series_name = series_name
27
self.account_id = account_id
28
self.series_id = series_id
29
self.added = datetime.now()
32
return '<series_favorites(account_id=%s, series_name=%s)>' % (self.account_id, self.series_name)
35
class FilterThetvdbFavorites(FilterSeriesBase):
37
Creates a series config containing all your thetvdb.com favorites
46
from flexget import validator
47
root = validator.factory('dict')
48
root.accept('text', key='account_id', required=True)
49
root.accept('text', key='series_group')
50
root.accept('boolean', key='strip_dates')
51
self.build_options_validator(root)
55
def on_feed_start(self, feed):
56
config = feed.config.get('thetvdb_favorites')
57
account_id = str(config['account_id'])
59
# Check when the last time the user information (favorites) were updated.
60
# The user info is stored where a series_id == ''
61
user_update = session.query(ThetvdbFavorites).filter(ThetvdbFavorites.account_id == account_id).\
62
filter(ThetvdbFavorites.series_id == u'')
63
# Grab all info from cache just in case.
64
cache = session.query(ThetvdbFavorites).filter(ThetvdbFavorites.account_id == account_id).\
65
filter(ThetvdbFavorites.series_id != u'')
66
if cache.count() and user_update.count() and user_update.first().added > datetime.now() - timedelta(minutes=1):
67
log.debug('Using cached thetvdb favorite series information for account ID %s' % account_id)
69
# Wipe out previous user info update time
71
session.add(ThetvdbFavorites(account_id, u'User Series List Update Time', u''))
73
log.debug('Updating favorite series information from thetvdb.com for account ID %s' % account_id)
75
url = 'http://thetvdb.com/api/User_Favorites.php?accountid=%s' % account_id
76
log.debug('requesting %s' % url)
77
data = BeautifulStoneSoup(urlopener(url, log))
79
for i in data.favorites.findAll("series", recursive=False):
80
favorite_ids.append(i.string)
81
# We found new data, check each show, and if older than
82
# 3 hours, update the individual series information
84
for fid in favorite_ids:
85
fidcache = cache.filter(ThetvdbFavorites.series_id == fid)
86
if fidcache.count() and fidcache.first().added > datetime.now() - timedelta(hours=3):
87
series_name = fidcache.first().series_name
88
log.debug('Using series info from cache for %s - %s' % (fid, series_name))
89
items.append(ThetvdbFavorites(account_id, series_name, fid))
91
log.debug('Looking up series info for %s' % fid)
92
data = BeautifulStoneSoup(urlopener('http://thetvdb.com//data/series/%s/' % fid, log), \
93
convertEntities=BeautifulStoneSoup.HTML_ENTITIES)
94
if data.series.seriesname.string:
95
items.append(ThetvdbFavorites(account_id, data.series.seriesname.string, fid))
97
log.warning('thetvdb did not return a series name for favorite with id %s' % fid)
98
if not len(items) % 10:
99
log.info('Parsed %i of %i series from thetvdb favorites' % (len(items), len(favorite_ids)))
100
except (urllib2.URLError, IOError, AttributeError):
102
# If there are errors getting the favorites or parsing the xml, fall back on cache
103
log.error('Error retrieving favorites from thetvdb, using cache.')
104
log.debug(traceback.format_exc())
106
# Successfully updated from tvdb, update the database
107
log.debug('Successfully updated favorites from thetvdb.com')
109
session.add_all(items)
111
cache = session.query(ThetvdbFavorites).filter(ThetvdbFavorites.account_id == account_id).\
112
filter(ThetvdbFavorites.series_id != u'')
113
if not cache.count():
114
log.info('Didn\'t find any thetvdb.com favorites.')
117
# Construct series plugin config
118
series_group = config.get('series_group', 'thetvdb_favs')
119
# Pass all config options to series plugin except our special ones
120
group_config = dict([(key, config[key]) for key in config if key not in ['account_id', 'series_group', 'strip_dates']])
121
tvdb_series_config = {'settings': {series_group: group_config}, series_group: []}
123
series_name = series.series_name
124
if config.get('strip_dates'):
125
# Remove year from end of series name if present
126
series_name = re.sub('\s+\(\d{4}\)$', '', series_name)
127
tvdb_series_config[series_group].append(series_name)
128
# Merge our config in to the main series config
129
self.merge_config(feed, tvdb_series_config)
131
register_plugin(FilterThetvdbFavorites, 'thetvdb_favorites')