flexget.plugins.services.trakt_acquired
Covered: 23 lines
Missed: 65 lines
Skipped 22 lines
Percent: 26 %
  1
import logging
  2
import hashlib
  3
import urllib2
  4
from flexget.plugin import register_plugin, DependencyError
  5
from flexget.utils.tools import urlopener
  7
try:
  8
    import simplejson as json
  9
except ImportError:
 10
    try:
 11
        import json
 12
    except ImportError:
 13
        raise DependencyError(issued_by='trakt_acquired', missing='simplejson',
 14
                              message='trakt_acquired requires either '
 15
                                      'simplejson module or python > 2.5')
 17
log = logging.getLogger('trakt_acquired')
 20
class TraktAcquired(object):
 21
    """Marks all accepted TV episodes or movies as acquired in your trakt.tv library."""
 23
    def validator(self):
 24
        from flexget import validator
 25
        root = validator.factory('dict')
 26
        root.accept('text', key='username', required=True)
 27
        root.accept('text', key='password', required=True)
 28
        root.accept('text', key='api_key', required=True)
 29
        root.accept('choice', key='type', required=True).accept_choices(['movies', 'series'])
 30
        return root
 32
    def on_feed_exit(self, feed, config):
 33
        """Finds accepted movies and series episodes and submits them to trakt as acquired."""
 35
        config['password'] = hashlib.sha1(config['password']).hexdigest()
 36
        found = {}
 37
        for entry in feed.accepted:
 38
            if config['type'] == 'series':
 40
                if entry.get('series_name') and entry.get('series_season') and entry.get('series_episode'):
 41
                    series = found.setdefault(entry['series_name'], {})
 42
                    if not series:
 44
                        series['title'] = entry.get('series_name_tvdb', entry['series_name'])
 45
                        if entry.get('imdb_id'):
 46
                            series['imdb_id'] = entry['imdb_id']
 47
                        if entry.get('thetvdb_id'):
 48
                            series['tvdb_id'] = entry['thetvdb_id']
 49
                        series['episodes'] = []
 50
                    episode = {'season': entry['series_season'], 'episode': entry['series_episode']}
 51
                    series['episodes'].append(episode)
 52
                    log.debug('Marking %s S%02dE%02d for submission to trakt.tv library.' % \
 53
                              (entry['series_name'], entry['series_season'], entry['series_episode']))
 54
            else:
 56
                if entry.get('imdb_id') or entry.get('tmdb_id'):
 57
                    movie = {}
 59
                    if entry.get('movie_name', eval_lazy=False):
 60
                        movie['title'] = entry['movie_name']
 61
                    if entry.get('movie_year', eval_lazy=False):
 62
                        movie['year'] = entry['movie_year']
 63
                    if entry.get('tmdb_id', eval_lazy=False):
 64
                        movie['tmdb_id'] = entry['tmdb_id']
 65
                    if entry.get('imdb_id', eval_lazy=False):
 66
                        movie['imdb_id'] = entry['imdb_id']
 68
                    found.setdefault('movies', {}).setdefault('movies', []).append(movie)
 69
                    log.debug('Marking %s for submission to trakt.tv library.' % entry['title'])
 71
        if not found:
 72
            log.debug('Nothing to submit to trakt.')
 73
            return
 75
        if feed.manager.options.test:
 76
            log.info('Not submitting to trakt.tv because of test mode.')
 77
            return
 80
        if config['type'] == 'series':
 81
            post_url = 'http://api.trakt.tv/show/episode/library/' + config['api_key']
 82
        else:
 83
            post_url = 'http://api.trakt.tv/movie/library/' + config['api_key']
 84
        for item in found.itervalues():
 86
            item.update({'username': config['username'], 'password': config['password']})
 87
            try:
 88
                self.post_json_to_trakt(post_url, item)
 89
            except (urllib2.HTTPError, urllib2.URLError), e:
 90
                if hasattr(e, 'code'):
 91
                    if e.code == 404:
 93
                        for key in ['username', 'password', 'episodes']:
 94
                            item.pop(key, None)
 95
                        log.error('%s not found on trakt: %s' % (config['type'].capitalize(), item))
 96
                        continue
 97
                    elif e.code == 401:
 98
                        log.error('Error authenticating with trakt. Check your username/password/api_key')
 99
                        continue
100
                log.error('Error submitting data to trakt.tv: %s' % e)
101
                continue
103
    def post_json_to_trakt(self, url, data):
104
        """Dumps data as json and POSTs it to the specified url."""
105
        req = urllib2.Request(url, json.dumps(data), {'content-type': 'application/json'})
106
        return urlopener(req, log)
109
register_plugin(TraktAcquired, 'trakt_acquired', api_ver=2)