Ejemplo n.º 1
0
    def items(self):
        if self._items is None:
            endpoint = self.get_list_endpoint()

            log.verbose('Retrieving `%s` list `%s`' % (self.config['type'], self.config['list']))
            try:
                result = self.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.' % (self.config['type'], self.config['list']))
                return []

            entries = []
            list_type = (self.config['type']).rstrip('s')
            for item in data:
                if self.config['type'] == 'auto':
                    list_type = item['type']
                # 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 list_type != 'episode' and not item[list_type]['title']:
                    # Skip shows/movies with no title
                    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)
                # Override the title if strip_dates is on. TODO: a better way?
                if self.config.get('strip_dates'):
                    if list_type in ['show', 'movie']:
                        entry['title'] = item[list_type]['title']
                    elif list_type == 'episode':
                        entry['title'] = '{show[title]} S{episode[season]:02}E{episode[number]:02}'.format(**item)
                        if item['episode']['title']:
                            entry['title'] += ' {episode[title]}'.format(**item)
                if entry.isvalid():
                    if self.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)

            self._items = entries
        return self._items
Ejemplo n.º 2
0
    def items(self):
        if self._items is None:
            endpoint = self.get_list_endpoint()

            log.verbose('Retrieving `%s` list `%s`' % (self.config['type'], self.config['list']))
            try:
                result = self.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.' % (self.config['type'], self.config['list']))
                return []

            entries = []
            list_type = (self.config['type']).rstrip('s')
            for item in data:
                if self.config['type'] == 'auto':
                    list_type = item['type']
                # 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 list_type != 'episode' and not item[list_type]['title']:
                    # Skip shows/movies with no title
                    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)
                # Override the title if strip_dates is on. TODO: a better way?
                if self.config.get('strip_dates'):
                    if list_type in ['show', 'movie']:
                        entry['title'] = item[list_type]['title']
                    elif list_type == 'episode':
                        entry['title'] = '{show[title]} S{episode[season]:02}E{episode[number]:02}'.format(**item)
                        if item['episode']['title']:
                            entry['title'] += ' {episode[title]}'.format(**item)
                if entry.isvalid():
                    if self.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)

            self._items = entries
        return self._items
Ejemplo n.º 3
0
    def on_task_input(self, task, config):
        start_date = datetime.datetime.now().date() + datetime.timedelta(
            days=config['start_day'])
        log.debug('Start date for calendar: %s, end date: %s', start_date,
                  start_date + datetime.timedelta(days=config['days']))

        url = get_api_url('calendars',
                          'my' if config.get('account') else 'all', 'shows',
                          start_date, config['days'])

        try:
            results = get_session(config.get('account')).get(url,
                                                             params={
                                                                 'extended':
                                                                 'full'
                                                             }).json()
            log.debug('Found %s calendar entries', len(results))
        except RequestException as e:
            raise plugin.PluginError(
                'Error while fetching calendar: {0}'.format(e))

        entries = set()
        for result in results:
            e = Entry()
            e.update_using_map(self.series_map, result['show'])
            if config['type'] == 'episodes':
                e.update_using_map(self.episode_map, result['episode'])

            e['title'] = e['trakt_series_name']
            if not config['strip_dates']:
                e['title'] = '{0} ({1})'.format(e['title'],
                                                e['trakt_series_year'])

            e['url'] = e['trakt_series_url']

            if config['type'] == 'episodes':
                e['title'] = '{0} S{1:02d}E{2:02d}'.format(
                    e['title'], e['trakt_season'], e['trakt_episode'])

                e['url'] = '{0}/seasons/{1}/episodes/{2}'.format(
                    e['url'], e['trakt_season'], e['trakt_episode'])

            entries.add(e)

        return list(entries)
Ejemplo n.º 4
0
    def on_task_input(self, task, config):
        start_date = datetime.datetime.now().date() + datetime.timedelta(days=config['start_day'])
        log.debug('Start date for calendar: %s, end date: %s', start_date,
                  start_date + datetime.timedelta(days=config['days']))

        url = get_api_url('calendars', 'my' if config.get('account') else 'all', 'shows', start_date, config['days'])

        try:
            results = get_session(config.get('account')).get(url, params={'extended': 'full'}).json()
            log.debug('Found %s calendar entries', len(results))
        except RequestException as e:
            raise plugin.PluginError('Error while fetching calendar: {0}'.format(e))

        entries = set()
        for result in results:
            e = Entry()
            e.update_using_map(self.series_map, result['show'])
            if config['type'] == 'episodes':
                e.update_using_map(self.episode_map, result['episode'])

            e['title'] = e['trakt_series_name']
            if not config['strip_dates']:
                e['title'] = '{0} ({1})'.format(e['title'], e['trakt_series_year'])
                
            e['url'] = e['trakt_series_url']
            
            if config['type'] == 'episodes':
                e['title'] = '{0} S{1:02d}E{2:02d}'.format(e['title'], e['trakt_season'], e['trakt_episode'])

                e['url'] = '{0}/seasons/{1}/episodes/{2}'.format(e['url'],
                                                                 e['trakt_season'],
                                                                 e['trakt_episode'])

            entries.add(e)

        return list(entries)
Ejemplo n.º 5
0
    def submit(self, entries, remove=False):
        """Submits movies or episodes to trakt api."""
        found = {}
        for entry in entries:
            if self.config['type'] in ['auto', 'shows', 'seasons', 'episodes'
                                       ] and entry.get('series_name'):
                show_name, show_year = split_title_year(entry['series_name'])
                show = {'title': show_name, 'ids': get_entry_ids(entry)}
                if show_year:
                    show['year'] = show_year
                if self.config['type'] in [
                        'auto', 'seasons', 'episodes'
                ] and entry.get('series_season') is not None:
                    season = {'number': entry['series_season']}
                    if self.config['type'] in [
                            'auto', 'episodes'
                    ] and entry.get('series_episode') is not None:
                        season['episodes'] = [{
                            'number': entry['series_episode']
                        }]
                    show['seasons'] = [season]
                if self.config['type'] in ['seasons', 'episodes'
                                           ] and 'seasons' not in show:
                    log.debug('Not submitting `%s`, no season found.' %
                              entry['title'])
                    continue
                if self.config['type'] == 'episodes' and 'episodes' not in show[
                        'seasons'][0]:
                    log.debug('Not submitting `%s`, no episode number found.' %
                              entry['title'])
                    continue
                found.setdefault('shows', []).append(show)
            elif self.config['type'] in ['auto', 'movies']:
                movie = {'ids': get_entry_ids(entry)}
                if not movie['ids']:
                    if entry.get('movie_name') is not None:
                        movie['title'] = entry.get('movie_name') or entry.get(
                            'imdb_name')
                        movie['year'] = entry.get('movie_year') or entry.get(
                            'imdb_year')
                    else:
                        log.debug(
                            'Not submitting `%s`, no movie name or id found.' %
                            entry['title'])
                        continue
                found.setdefault('movies', []).append(movie)

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

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

        log.debug('Submitting data to trakt.tv (%s): %s' % (url, found))
        try:
            result = self.session.post(url,
                                       data=json.dumps(found),
                                       raise_status=False)
        except RequestException as e:
            log.error('Error submitting data to trakt.tv: %s' % e)
            return
        if 200 <= result.status_code < 300:
            action = 'deleted' if remove else 'added'
            res = result.json()
            # Default to 0 for all categories, even if trakt response didn't include them
            for cat in ('movies', 'shows', 'episodes', 'seasons'):
                res[action].setdefault(cat, 0)
            log.info(
                'Successfully {0} to/from list {1}: {movies} movie(s), {shows} show(s), {episodes} episode(s), '
                '{seasons} season(s).'.format(action, self.config['list'],
                                              **res[action]))
            for k, r in res['not_found'].items():
                if r:
                    log.debug('not found %s: %s' % (k, r))
            # TODO: Improve messages about existing and unknown results
            # Mark the results expired if we added or removed anything
            if sum(res[action].values()) > 0:
                self.invalidate_cache()
        elif result.status_code == 404:
            log.error('List does not appear to exist on trakt: %s' %
                      self.config['list'])
        elif result.status_code == 401:
            log.error(
                'Authentication error: have you authorized Flexget on Trakt.tv?'
            )
            log.debug('trakt response: ' + result.text)
        else:
            log.error('Unknown error submitting data to trakt.tv: %s' %
                      result.text)
Ejemplo n.º 6
0
 def on_task_input(self, task, config):
     if config.get('account') and not config.get('username'):
         config['username'] = '******'
     session = get_session(account=config.get('account'))
     listed_series = {}
     if config.get('list'):
         args = ('users', config['username'])
         if config['list'] in ['collection', 'watchlist', 'watched']:
             args += (config['list'], 'shows')
         else:
             args += ('lists', make_list_slug(config['list']), 'items')
         try:
             data = session.get(get_api_url(args)).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.get('show'):
                 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':
                     '%s (%s)' %
                     (item['show']['title'], item['show']['year']),
                     'trakt_id':
                     trakt_id,
                     'trakt_series_name':
                     item['show']['title'],
                     'trakt_series_year':
                     item['show']['year'],
                     'trakt_list':
                     config.get('list')
                 }
                 if item['show']['ids'].get('tvdb'):
                     listed_series[trakt_id]['tvdb_id'] = item['show'][
                         'ids']['tvdb']
                 if item['show']['ids'].get('tvrage'):
                     listed_series[trakt_id]['tvrage_id'] = item['show'][
                         'ids']['tvrage']
                 if item['show']['ids'].get('imdb'):
                     listed_series[trakt_id]['imdb_id'] = item['show'][
                         'ids']['imdb']
                 if item['show']['ids'].get('tmdb'):
                     listed_series[trakt_id]['tmdb_id'] = item['show'][
                         'ids']['tmdb']
                 if item['show']['ids'].get('slug'):
                     listed_series[trakt_id]['trakt_slug'] = item['show'][
                         'ids']['slug']
     context = config['context']
     if context == 'collected':
         context = 'collection'
     entries = []
     for trakt_id, fields in listed_series.items():
         url = get_api_url('shows', trakt_id, 'progress', context)
         try:
             data = session.get(url).json()
         except RequestException as e:
             raise plugin.PluginError(
                 'An error has occurred looking up: Trakt_id: %s Error: %s'
                 % (trakt_id, e))
         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:
             if config.get('strip_dates'):
                 # remove year from end of series_name if present
                 fields['series_name'] = re.sub(r'\s+\(\d{4}\)$', '',
                                                fields['series_name'])
             entry = self.make_entry(fields, eps, epn)
             entries.append(entry)
     return entries
Ejemplo n.º 7
0
    def items(self):
        if self._items is None:
            if self.config['list'] in ['collection', 'watched'
                                       ] and self.config['type'] == 'auto':
                raise plugin.PluginError(
                    '`type` cannot be `auto` for %s list.' %
                    self.config['list'])

            endpoint = self.get_list_endpoint()

            log.verbose('Retrieving `%s` list `%s`', self.config['type'],
                        self.config['list'])
            try:
                result = self.session.get(
                    plugin_api_trakt.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.')

                current_page = int(result.headers.get('X-Pagination-Page', 1))
                current_page_count = int(
                    result.headers.get('X-Pagination-Page-Count', 1))
                if current_page < current_page_count:
                    # Pagination, gotta get it all, but we'll limit it to 1000 per page
                    # but we'll have to start over from 0
                    data = []

                    limit = 1000
                    pagination_item_count = int(
                        result.headers.get('X-Pagination-Item-Count', 0))
                    number_of_pages = math.ceil(pagination_item_count / limit)
                    log.debug(
                        'Response is paginated. Number of items: %s, number of pages: %s',
                        pagination_item_count, number_of_pages)
                    page = int(result.headers.get('X-Pagination-Page'))
                    while page <= number_of_pages:
                        paginated_result = self.session.get(
                            plugin_api_trakt.get_api_url(endpoint),
                            params={
                                'limit': limit,
                                'page': page
                            })
                        page += 1
                        try:
                            data.extend(paginated_result.json())
                        except ValueError:
                            log.debug(
                                'Could not decode json from response: %s',
                                paginated_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)

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

            entries = []
            list_type = (self.config['type']).rstrip('s')
            for item in data:
                if self.config['type'] == 'auto':
                    list_type = item['type']
                # 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 list_type != 'episode' and not item[list_type]['title']:
                    # Skip shows/movies with no title
                    log.warning(
                        'Item in trakt list does not appear to have a title, skipping.'
                    )
                    continue
                entry = Entry()
                if list_type == 'episode':
                    entry[
                        'url'] = 'https://trakt.tv/shows/%s/seasons/%s/episodes/%s' % (
                            item['show']['ids']['slug'],
                            item['episode']['season'],
                            item['episode']['number'])
                else:
                    entry['url'] = 'https://trakt.tv/%ss/%s' % (
                        list_type, item[list_type]['ids'].get('slug'))

                entry.update_using_map(field_maps[list_type], item)

                # get movie name translation
                language = self.config.get('language')
                if list_type == 'movie' and language:
                    endpoint = [
                        'movies', entry['trakt_movie_id'], 'translations',
                        language
                    ]
                    try:
                        result = self.session.get(
                            plugin_api_trakt.get_api_url(endpoint))
                        try:
                            translation = result.json()
                        except ValueError:
                            raise plugin.PluginError(
                                'Error decoding movie translation from trakt: %s.'
                                % result.text)
                    except RequestException as e:
                        raise plugin.PluginError(
                            'Could not retrieve movie translation from trakt: %s'
                            % str(e))
                    if not translation:
                        log.warning(
                            'No translation data returned from trakt for movie %s.',
                            entry['title'])
                    else:
                        log.verbose(
                            'Found `%s` translation for movie `%s`: %s',
                            language, entry['movie_name'],
                            translation[0]['title'])
                        entry['title'] = translation[0]['title']
                        if entry.get('movie_year'):
                            entry['title'] += ' (' + str(
                                entry['movie_year']) + ')'
                        entry['movie_name'] = translation[0]['title']

                # Override the title if strip_dates is on. TODO: a better way?
                if self.config.get('strip_dates'):
                    if list_type in ['show', 'movie']:
                        entry['title'] = item[list_type]['title']
                    elif list_type == 'episode':
                        entry[
                            'title'] = '{show[title]} S{episode[season]:02}E{episode[number]:02}'.format(
                                **item)
                        if item['episode']['title']:
                            entry['title'] += ' {episode[title]}'.format(
                                **item)
                if entry.isvalid():
                    if self.config.get('strip_dates'):
                        # Remove year from end of name if present
                        entry['title'] = split_title_year(entry['title'])[0]
                    entries.append(entry)
                else:
                    log.debug('Invalid entry created? %s', entry)

            self._items = entries
        return self._items
Ejemplo n.º 8
0
    def submit(self, entries, remove=False):
        """Submits movies or episodes to trakt api."""
        found = {}
        for entry in entries:
            if self.config['type'] in ['auto', 'shows', 'seasons', 'episodes'] and entry.get('series_name'):
                show_name, show_year = split_title_year(entry['series_name'])
                show = {'title': show_name, 'ids': get_entry_ids(entry)}
                if show_year:
                    show['year'] = show_year
                if self.config['type'] in ['auto', 'seasons', 'episodes'] and entry.get('series_season') is not None:
                    season = {'number': entry['series_season']}
                    if self.config['type'] in ['auto', 'episodes'] and entry.get('series_episode') is not None:
                        season['episodes'] = [{'number': entry['series_episode']}]
                    show['seasons'] = [season]
                if self.config['type'] in ['seasons', 'episodes'] and 'seasons' not in show:
                    log.debug('Not submitting `%s`, no season found.' % entry['title'])
                    continue
                if self.config['type'] == 'episodes' and 'episodes' not in show['seasons'][0]:
                    log.debug('Not submitting `%s`, no episode number found.' % entry['title'])
                    continue
                found.setdefault('shows', []).append(show)
            elif self.config['type'] in ['auto', 'movies']:
                movie = {'ids': get_entry_ids(entry)}
                if not movie['ids']:
                    if entry.get('movie_name') is not None:
                        movie['title'] = entry.get('movie_name') or entry.get('imdb_name')
                        movie['year'] = entry.get('movie_year') or entry.get('imdb_year')
                    else:
                        log.debug('Not submitting `%s`, no movie name or id found.' % entry['title'])
                        continue
                found.setdefault('movies', []).append(movie)

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

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

        log.debug('Submitting data to trakt.tv (%s): %s' % (url, found))
        try:
            result = self.session.post(url, data=json.dumps(found), raise_status=False)
        except RequestException as e:
            log.error('Error submitting data to trakt.tv: %s' % e)
            return
        if 200 <= result.status_code < 300:
            action = 'deleted' if remove else 'added'
            res = result.json()
            # Default to 0 for all categories, even if trakt response didn't include them
            for cat in ('movies', 'shows', 'episodes', 'seasons'):
                res[action].setdefault(cat, 0)
            log.info('Successfully {0} to/from list {1}: {movies} movie(s), {shows} show(s), {episodes} episode(s), '
                     '{seasons} season(s).'.format(action, self.config['list'], **res[action]))
            for k, r in res['not_found'].items():
                if r:
                    log.debug('not found %s: %s' % (k, r))
            # TODO: Improve messages about existing and unknown results
            # Mark the results expired if we added or removed anything
            if sum(res[action].values()) > 0:
                self.invalidate_cache()
        elif result.status_code == 404:
            log.error('List does not appear to exist on trakt: %s' % self.config['list'])
        elif result.status_code == 401:
            log.error('Authentication error: have you authorized Flexget on Trakt.tv?')
            log.debug('trakt response: ' + result.text)
        else:
            log.error('Unknown error submitting data to trakt.tv: %s' % result.text)
    def on_task_input(self, task, config):
        if config.get('account') and not config.get('username'):
            config['username'] = '******'
        session = get_session(account=config.get('account'))
        listed_series = {}
        args = ('users', config['username'])
        if config['list'] in ['collection', 'watchlist', 'watched']:
            args += (config['list'], 'shows')
        else:
            args += ('lists', make_list_slug(config['list']), 'items')
        try:
            data = session.get(get_api_url(args)).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.get('show'):
                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
                ids = item['show']['ids']
                trakt_id = ids['trakt']
                listed_series[trakt_id] = {
                    'series_name': '%s (%s)' % (item['show']['title'], item['show']['year']),
                    'trakt_id': trakt_id,
                    'trakt_series_name': item['show']['title'],
                    'trakt_series_year': item['show']['year'],
                    'trakt_list': config.get('list')
                }
                for id_name, id_value in ids.items():
                    entry_field_name = 'trakt_slug' if id_name == 'slug' else id_name  # rename slug to trakt_slug
                    listed_series[trakt_id][entry_field_name] = id_value
        context = 'collection' if config['context'] == 'collected' else config['context']
        entries = []
        for trakt_id, fields in listed_series.items():
            url = get_api_url('shows', trakt_id, 'progress', context)
            try:
                data = session.get(url).json()
            except RequestException as e:
                raise plugin.PluginError('An error has occurred looking up: Trakt_id: %s Error: %s' % (trakt_id, e))
            if config['position'] == 'next' and data.get('next_episode'):
                # If the next episode is already in the trakt database, we'll get it here
                season_number = data['next_episode']['season']
                episode_number = data['next_episode']['number']
            else:
                # If we need last ep, or next_episode was not provided, search for last ep
                for season in reversed(data['seasons']):
                    # Find the first season with collected/watched episodes
                    if not season['completed']:
                        continue
                    season_number = season['number']
                    # Pick the highest collected/watched episode
                    episode_number = max(item['number'] for item in season['episodes'] if item['completed'])
                    # If we are in next episode mode, we have to increment this number
                    if config['position'] == 'next':
                        if season['completed'] >= season['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.
                            season_number += 1
                        episode_number = 1
                    break
                else:
                    if config['position'] != 'next':
                        # There were no watched/collected episodes, nothing to emit in 'last' mode
                        continue
                    season_number = episode_number = 1

            if season_number and episode_number:
                if config.get('strip_dates'):
                    # remove year from end of series_name if present
                    fields['series_name'] = re.sub(r'\s+\(\d{4}\)$', '', fields['series_name'])
                entry = self.make_entry(fields, season_number, episode_number)
                entries.append(entry)
        return entries
Ejemplo n.º 10
0
    def items(self):
        if self._items is None:
            if self.config['list'] in ['collection', 'watched'] and self.config['type'] == 'auto':
                raise plugin.PluginError('`type` cannot be `auto` for %s list.' % self.config['list'])

            endpoint = self.get_list_endpoint()

            log.verbose('Retrieving `%s` list `%s`', self.config['type'], self.config['list'])
            try:
                result = self.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)

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

            entries = []
            list_type = (self.config['type']).rstrip('s')
            for item in data:
                if self.config['type'] == 'auto':
                    list_type = item['type']
                # 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 list_type != 'episode' and not item[list_type]['title']:
                    # Skip shows/movies with no title
                    log.warning('Item in trakt list does not appear to have a title, skipping.')
                    continue
                entry = Entry()
                if list_type == 'episode':
                    entry['url'] = 'https://trakt.tv/shows/%s/seasons/%s/episodes/%s' % (
                        item['show']['ids']['slug'], item['episode']['season'], item['episode']['number'])
                else:
                    entry['url'] = 'https://trakt.tv/%ss/%s' % (list_type, item[list_type]['ids'].get('slug'))

                entry.update_using_map(field_maps[list_type], item)

                # get movie name translation
                language = self.config.get('language')
                if list_type == 'movie' and language:
                    endpoint = ['movies', entry['trakt_movie_id'], 'translations', language]
                    try:
                        result = self.session.get(get_api_url(endpoint))
                        try:
                            translation = result.json()
                        except ValueError:
                            raise plugin.PluginError('Error decoding movie translation from trakt: %s.' % result.text)
                    except RequestException as e:
                        raise plugin.PluginError('Could not retrieve movie translation from trakt: %s' % str(e))
                    if not translation:
                        log.warning('No translation data returned from trakt for movie %s.', entry['title'])
                    else:
                        log.verbose('Found `%s` translation for movie `%s`: %s',
                                    language, entry['movie_name'], translation[0]['title'])
                        entry['title'] = translation[0]['title']
                        if entry.get('movie_year'):
                            entry['title'] += ' (' + str(entry['movie_year']) + ')'
                        entry['movie_name'] = translation[0]['title']

                # Override the title if strip_dates is on. TODO: a better way?
                if self.config.get('strip_dates'):
                    if list_type in ['show', 'movie']:
                        entry['title'] = item[list_type]['title']
                    elif list_type == 'episode':
                        entry['title'] = '{show[title]} S{episode[season]:02}E{episode[number]:02}'.format(**item)
                        if item['episode']['title']:
                            entry['title'] += ' {episode[title]}'.format(**item)
                if entry.isvalid():
                    if self.config.get('strip_dates'):
                        # Remove year from end of name if present
                        entry['title'] = split_title_year(entry['title'])[0]
                    entries.append(entry)
                else:
                    log.debug('Invalid entry created? %s', entry)

            self._items = entries
        return self._items