예제 #1
0
    def on_task_output(self, task, config):
        """Submits accepted movies or episodes to trakt api."""
        found = {'shows': [], 'movies': []}
        for entry in task.accepted:
            if 'series_name' in entry:
                show = {'title': entry['series_name'], 'ids': get_entry_ids(entry)}
                if 'series_season' in entry:
                    season = {'number': entry['series_season']}
                    if 'series_episode' in entry:
                        season['episodes'] = [{'number': entry['series_episode']}]
                    show['seasons'] = [season]
                found['shows'].append(show)
            elif any(field in entry for field in ['imdb_id', 'tmdb_id', 'movie_name']):
                movie = {'ids': get_entry_ids(entry)}
                if not movie['ids']:
                    movie['title'] = entry.get('movie_name') or entry.get('imdb_name')
                    movie['year'] = entry.get('movie_year') or entry.get('imdb_year')
                found['movies'].append(movie)

        if not (found['shows'] or found['movies']):
            self.log.debug('Nothing to submit to trakt.')
            return

        if config['list'] in ['collection', 'watchlist', 'watched']:
            endpoint = 'sync/%s' % ('history' if config['list'] == 'watched' else config['list'])
        else:
            endpoint = 'users/%s/lists/%s/items' % (config['username'], make_list_slug(config['list']))
        if self.remove:
            endpoint += '/remove'
        url = API_URL + endpoint

        if task.manager.options.test:
            self.log.info('Not submitting to trakt.tv because of test mode.')
            return
        session = get_session(config['username'], config['password'])
        self.log.debug('Submitting data to trakt.tv (%s): %s' % (url, found))
        try:
            result = session.post(url, data=json.dumps(found), raise_status=False)
        except RequestException as e:
            self.log.error('Error submitting data to trakt.tv: %s' % e)
            return
        if 200 <= result.status_code < 300:
            self.log.info('Data successfully sent to trakt.tv')
            self.log.debug('trakt response: ' + result.text)
            # TODO: Improve messages about existing and unknown results
        elif result.status_code == 404:
            self.log.error('List does not appear to exist on trakt: %s' % config['list'])
        elif result.status_code == 401:
            self.log.error('Authentication error: check your trakt.tv username/password')
            self.log.debug('trakt response: ' + result.text)
        else:
            self.log.error('Unknown error submitting data to trakt.tv: %s' % result.text)
예제 #2
0
    def on_task_input(self, task, config):
        session = get_session(config['username'], config.get('password'))
        endpoint = ['users', config['username']]
        if config['list'] in ['collection', 'watchlist', 'watched']:
            endpoint += (config['list'], config['type'])
        else:
            endpoint += ('lists', make_list_slug(config['list']), 'items')

        log.verbose('Retrieving `%s` list `%s`' % (config['type'], config['list']))
        try:
            result = session.get(get_api_url(endpoint))
            try:
                data = result.json()
            except ValueError:
                log.debug('Could not decode json from response: %s', result.text)
                raise plugin.PluginError('Error getting list from trakt.')
        except RequestException as e:
            raise plugin.PluginError('Could not retrieve list from trakt (%s)' % e.args[0])

        if not data:
            log.warning('No data returned from trakt for %s list %s.' % (config['type'], config['list']))
            return

        entries = []
        list_type = (config['type']).rstrip('s')
        for item in data:
            # Collection and watched lists don't return 'type' along with the items (right now)
            if 'type' in item and item['type'] != list_type:
                log.debug('Skipping %s because it is not a %s' % (item[item['type']].get('title', 'unknown'),
                                                                  list_type))
                continue
            if not item[list_type]['title']:
                # There seems to be some bad shows sometimes in lists with no titles. Skip them.
                log.warning('Item in trakt list does not appear to have a title, skipping.')
                continue
            entry = Entry()
            if list_type == 'episode':
                entry['url'] = 'http://trakt.tv/shows/%s/seasons/%s/episodes/%s' % (
                    item['show']['ids']['slug'], item['episode']['season'], item['episode']['number'])
            else:
                entry['url'] = 'http://trakt.tv/%s/%s' % (list_type, item[list_type]['ids'].get('slug'))
            entry.update_using_map(field_maps[list_type], item)
            if entry.isvalid():
                if config.get('strip_dates'):
                    # Remove year from end of name if present
                    entry['title'] = re.sub(r'\s+\(\d{4}\)$', '', entry['title'])
                entries.append(entry)
            else:
                log.debug('Invalid entry created? %s' % entry)

        return entries
예제 #3
0
 def on_task_input(self, task, config):
     session = get_session(config['username'], config.get('password'))
     listed_series = {}
     if config.get('list'):
         url = urljoin(API_URL, 'users/%s/' % config['username'])
         if config['list'] in ['collection', 'watchlist', 'watched']:
             url = urljoin(url, '%s/shows' % config['list'])
         else:
             url = urljoin(
                 url, 'lists/%s/items' % make_list_slug(config['list']))
         try:
             data = session.get(url).json()
         except RequestException as e:
             raise plugin.PluginError('Unable to get trakt list `%s`: %s' %
                                      (config['list'], e))
         if not data:
             log.warning('The list "%s" is empty.' % config['list'])
             return
         for item in data:
             if item['show'] is not None:
                 if not item['show']['title']:
                     # Seems we can get entries with a blank show title sometimes
                     log.warning(
                         'Found trakt list show with no series name.')
                     continue
                 trakt_id = item['show']['ids']['trakt']
                 listed_series[trakt_id] = {
                     'series_name': item['show']['title'],
                     'trakt_id': trakt_id,
                     'tvdb_id': item['show']['ids']['tvdb']
                 }
     context = config['context']
     if context == 'collected':
         context = 'collection'
     entries = []
     for trakt_id, fields in listed_series.iteritems():
         url = get_api_url('shows', trakt_id, 'progress', context)
         try:
             data = session.get(url).json()
         except RequestException as e:
             raise plugin.PluginError('TODO: error message')
         if config['position'] == 'next' and data.get('next_episode'):
             # If the next episode is already in the trakt database, we'll get it here
             eps = data['next_episode']['season']
             epn = data['next_episode']['number']
         else:
             # If we need last ep, or next_episode was not provided, search for last ep
             for seas in reversed(data['seasons']):
                 # Find the first season with collected/watched episodes
                 if seas['completed'] > 0:
                     eps = seas['number']
                     # Pick the highest collected/watched episode
                     epn = max(item['number'] for item in seas['episodes']
                               if item['completed'])
                     # If we are in next episode mode, we have to increment this number
                     if config['position'] == 'next':
                         if seas['completed'] >= seas['aired']:
                             # TODO: next_episode doesn't count unaired episodes right now, this will skip to next
                             # season too early when there are episodes left to air this season.
                             eps += 1
                             epn = 1
                         else:
                             epn += 1
                     break
             else:
                 if config['position'] == 'next':
                     eps = epn = 1
                 else:
                     # There were no watched/collected episodes, nothing to emit in 'last' mode
                     continue
         if eps and epn:
             entry = self.make_entry(fields, eps, epn)
             entries.append(entry)
     return entries
예제 #4
0
    def on_task_output(self, task, config):
        """Submits accepted movies or episodes to trakt api."""
        found = {'shows': [], 'movies': []}
        for entry in task.accepted:
            if 'series_name' in entry:
                show = {
                    'title': entry['series_name'],
                    'ids': get_entry_ids(entry)
                }
                if 'series_season' in entry:
                    season = {'number': entry['series_season']}
                    if 'series_episode' in entry:
                        season['episodes'] = [{
                            'number': entry['series_episode']
                        }]
                    show['seasons'] = [season]
                found['shows'].append(show)
            elif any(field in entry
                     for field in ['imdb_id', 'tmdb_id', 'movie_name']):
                movie = {'ids': get_entry_ids(entry)}
                if not movie['ids']:
                    movie['title'] = entry.get('movie_name') or entry.get(
                        'imdb_name')
                    movie['year'] = entry.get('movie_year') or entry.get(
                        'imdb_year')
                found['movies'].append(movie)

        if not (found['shows'] or found['movies']):
            self.log.debug('Nothing to submit to trakt.')
            return

        if config['list'] in ['collection', 'watchlist', 'watched']:
            endpoint = 'sync/%s' % ('history' if config['list'] == 'watched'
                                    else config['list'])
        else:
            endpoint = 'users/%s/lists/%s/items' % (
                config['username'], make_list_slug(config['list']))
        if self.remove:
            endpoint += '/remove'
        url = API_URL + endpoint

        if task.manager.options.test:
            self.log.info('Not submitting to trakt.tv because of test mode.')
            return
        session = get_session(config['username'], config['password'])
        self.log.debug('Submitting data to trakt.tv (%s): %s' % (url, found))
        try:
            result = session.post(url,
                                  data=json.dumps(found),
                                  raise_status=False)
        except RequestException as e:
            self.log.error('Error submitting data to trakt.tv: %s' % e)
            return
        if 200 <= result.status_code < 300:
            self.log.info('Data successfully sent to trakt.tv')
            self.log.debug('trakt response: ' + result.text)
            # TODO: Improve messages about existing and unknown results
        elif result.status_code == 404:
            self.log.error('List does not appear to exist on trakt: %s' %
                           config['list'])
        elif result.status_code == 401:
            self.log.error(
                'Authentication error: check your trakt.tv username/password')
            self.log.debug('trakt response: ' + result.text)
        else:
            self.log.error('Unknown error submitting data to trakt.tv: %s' %
                           result.text)
예제 #5
0
 def on_task_input(self, task, config):
     session = get_session(config['username'], config.get('password'))
     listed_series = {}
     if config.get('list'):
         url = urljoin(API_URL, 'users/%s/' % config['username'])
         if config['list'] in ['collection', 'watchlist', 'watched']:
             url = urljoin(url, '%s/shows' % config['list'])
         else:
             url = urljoin(url, 'lists/%s/items' % make_list_slug(config['list']))
         try:
             data = session.get(url).json()
         except RequestException as e:
             raise plugin.PluginError('Unable to get trakt list `%s`: %s' % (config['list'], e))
         if not data:
             log.warning('The list "%s" is empty.' % config['list'])
             return
         for item in data:
             if item['show'] is not None:
                 if not item['show']['title']:
                     # Seems we can get entries with a blank show title sometimes
                     log.warning('Found trakt list show with no series name.')
                     continue
                 trakt_id = item['show']['ids']['trakt']
                 listed_series[trakt_id] = {
                     'series_name': item['show']['title'],
                     'trakt_id': trakt_id,
                     'tvdb_id': item['show']['ids']['tvdb']}
     context = config['context']
     if context == 'collected':
         context = 'collection'
     entries = []
     for trakt_id, fields in listed_series.iteritems():
         url = get_api_url('shows', trakt_id, 'progress', context)
         try:
             data = session.get(url).json()
         except RequestException as e:
             raise plugin.PluginError('TODO: error message')
         if config['position'] == 'next' and data.get('next_episode'):
             # If the next episode is already in the trakt database, we'll get it here
             eps = data['next_episode']['season']
             epn = data['next_episode']['number']
         else:
             # If we need last ep, or next_episode was not provided, search for last ep
             for seas in reversed(data['seasons']):
                 # Find the first season with collected/watched episodes
                 if seas['completed'] > 0:
                     eps = seas['number']
                     # Pick the highest collected/watched episode
                     epn = max(item['number'] for item in seas['episodes'] if item['completed'])
                     # If we are in next episode mode, we have to increment this number
                     if config['position'] == 'next':
                         if seas['completed'] >= seas['aired']:
                             # TODO: next_episode doesn't count unaired episodes right now, this will skip to next
                             # season too early when there are episodes left to air this season.
                             eps += 1
                             epn = 1
                         else:
                             epn += 1
                     break
             else:
               if config['position'] == 'next':
                 eps = epn = 1
               else:
                 # There were no watched/collected episodes, nothing to emit in 'last' mode
                 continue
         if eps and epn:
             entry = self.make_entry(fields, eps, epn)
             entries.append(entry)
     return entries