flexget.plugins.filter_thetvdb_favorites
Covered: 42 lines
Missed: 62 lines
Skipped 28 lines
Percent: 40 %
  1
import logging
  2
import re
  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
  9
import urllib2
 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()
 31
    def __repr__(self):
 32
        return '<series_favorites(account_id=%s, series_name=%s)>' % (self.account_id, self.series_name)
 35
class FilterThetvdbFavorites(FilterSeriesBase):
 36
    """
 37
        Creates a series config containing all your thetvdb.com favorites
 39
        Example:
 41
        thetvdb_favorites:
 42
          account_id: 23098230
 43
    """
 45
    def validator(self):
 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)
 52
        return root
 54
    @internet(log)
 55
    def on_feed_start(self, feed):
 56
        config = feed.config.get('thetvdb_favorites')
 57
        account_id = str(config['account_id'])
 58
        session = Session()
 61
        user_update = session.query(ThetvdbFavorites).filter(ThetvdbFavorites.account_id == account_id).\
 62
            filter(ThetvdbFavorites.series_id == u'')
 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)
 68
        else:
 70
            user_update.delete()
 71
            session.add(ThetvdbFavorites(account_id, u'User Series List Update Time', u''))
 72
            session.commit()
 73
            log.debug('Updating favorite series information from thetvdb.com for account ID %s' % account_id)
 74
            try:
 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))
 78
                favorite_ids = []
 79
                for i in data.favorites.findAll("series", recursive=False):
 80
                    favorite_ids.append(i.string)
 83
                items = []
 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))
 90
                    else:
 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))
 96
                        else:
 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):
101
                import traceback
103
                log.error('Error retrieving favorites from thetvdb, using cache.')
104
                log.debug(traceback.format_exc())
105
            else:
107
                log.debug('Successfully updated favorites from thetvdb.com')
108
                cache.delete()
109
                session.add_all(items)
110
                session.commit()
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.')
115
            return
118
        series_group = config.get('series_group', 'thetvdb_favs')
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: []}
122
        for series in cache:
123
            series_name = series.series_name
124
            if config.get('strip_dates'):
126
                series_name = re.sub('\s+\(\d{4}\)$', '', series_name)
127
            tvdb_series_config[series_group].append(series_name)
129
        self.merge_config(feed, tvdb_series_config)
131
register_plugin(FilterThetvdbFavorites, 'thetvdb_favorites')