flexget.plugins.input.trakt_list
Covered: 58 lines
Missed: 49 lines
Skipped 21 lines
Percent: 54 %
  1
import hashlib
  2
import logging
  3
import urllib2
  4
import re
  5
from flexget.utils.tools import urlopener
  6
from flexget.utils.cached_input import cached
  7
from flexget.plugin import register_plugin, PluginError, DependencyError
  8
from flexget.entry import Entry
 10
try:
 11
    import simplejson as json
 12
except ImportError:
 13
    try:
 14
        import json
 15
    except ImportError:
 16
        raise DependencyError(issued_by='trakt_list', missing='simplejson',
 17
                              message='trakt_list requires either simplejson module or python > 2.5')
 19
log = logging.getLogger('trakt_list')
 22
class TraktList(object):
 23
    """Creates an entry for each item in your trakt list.
 25
    Syntax:
 27
    trakt_list:
 28
      username: <value>
 29
      api_key: <value>
 30
      strip_dates: <yes|no>
 31
      movies: <all|loved|hated|collection|watchlist>
 32
      series: <all|loved|hated|collection|watchlist|watched>
 33
      custom: <value>
 35
    Options username and api_key are required.
 36
    """
 38
    movie_map = {
 39
        'title': 'title',
 40
        'url': 'url',
 41
        'imdb_id': 'imdb_id',
 42
        'tmdb_id': 'tmdb_id',
 44
        'movie_name': 'title',
 45
        'movie_year': 'year'}
 47
    series_map = {
 48
        'title': 'title',
 49
        'url': 'url',
 50
        'imdb_id': 'imdb_id',
 51
        'tvdb_id': 'tvdb_id',
 52
        'tvrage_id': 'tvrage_id'}
 54
    def validator(self):
 55
        from flexget import validator
 56
        root = validator.factory('dict')
 57
        root.accept('text', key='username', requried=True)
 58
        root.accept('text', key='api_key', required=True)
 59
        root.accept('text', key='password')
 60
        root.accept('choice', key='movies').accept_choices(['all', 'loved', 'hated', 'collection', 'watchlist'])
 61
        root.accept('choice', key='series').accept_choices(['all', 'loved', 'hated', 'collection', 'watched', 'watchlist'])
 62
        root.accept('text', key='custom')
 63
        root.accept('boolean', key='strip_dates')
 64
        return root
 66
    @cached('trakt_list', persist='2 hours')
 67
    def on_feed_input(self, feed, config):
 68
        if 'movies' in config and 'series' in config:
 69
            raise PluginError('Cannot use both series list and movies list in the same feed.')
 70
        if 'movies' in config:
 71
            config['data_type'] = 'movies'
 72
            config['list_type'] = config['movies']
 73
            map = self.movie_map
 74
        elif 'series' in config:
 75
            config['data_type'] = 'shows'
 76
            config['list_type'] = config['series']
 77
            map = self.series_map
 78
        elif 'custom' in config:
 79
            config['data_type'] = 'custom'
 80
            config['list_type'] = config['custom'].replace(' ', '-')
 82
        else:
 83
            raise PluginError('Must define movie or series lists to retrieve from trakt.')
 85
        url = 'http://api.trakt.tv/user/'
 86
        if config['data_type'] == 'custom':
 87
            url += 'list.json/%(api_key)s/%(username)s/%(list_type)s'
 88
        elif config['list_type'] == 'watchlist':
 89
            url += 'watchlist/%(data_type)s.json/%(api_key)s/%(username)s'
 90
        else:
 91
            url += 'library/%(data_type)s/%(list_type)s.json/%(api_key)s/%(username)s'
 92
        url = url % config
 94
        if 'password' in config:
 95
            auth = {'username': config['username'], 'password': hashlib.sha1(config['password']).hexdigest()}
 96
            url = urllib2.Request(url, json.dumps(auth), {'content-type': 'application/json'})
 98
        entries = []
 99
        log.verbose('Retrieving list %s %s...' % (config['data_type'], config['list_type']))
100
        try:
101
            data = json.load(urlopener(url, log, retries=2))
102
        except urllib2.URLError, e:
103
            raise PluginError('Could not retrieve list from trakt (%s)' % e)
104
        if 'error' in data:
105
            raise PluginError('Error getting trakt list: %s' % data['error'])
106
        if config['data_type'] == 'custom':
107
            data = data['items']
108
        for item in data:
109
            if config['data_type'] == 'custom':
110
                if item['type'] == 'movie':
111
                    map = self.movie_map
112
                    item = item['movie']
113
                else:
114
                    map = self.series_map
115
                    item = item['show']
116
            entry = Entry()
117
            entry.update_using_map(map, item)
118
            if entry.isvalid():
119
                if config.get('strip_dates'):
121
                    entry['title'] = re.sub('\s+\(\d{4}\)$', '', entry['title'])
122
                entries.append(entry)
124
        return entries
127
register_plugin(TraktList, 'trakt_list', api_ver=2)