Beispiel #1
0
    def get_id_by_external(self, **kwargs):
        """Search tmdb for a show, using an external id.

        Accepts as kwargs, so you'l need to add the externals as key/values.
        :param tvrage_id: The tvrage id.
        :param tvdb_id: The tvdb id.
        :param imdb_id: An imdb id (inc. tt).
        :returns: A dict with externals, including the tvmaze id.
        """
        try:
            wanted_externals = ['tvdb_id', 'imdb_id', 'tvrage_id', 'imdb_id']
            for external_id in wanted_externals:
                if kwargs.get(external_id):
                    result = self.tmdb.Find(kwargs.get(external_id)).info(
                        **{'external_source': external_id})
                    if result.get('tv_results') and result['tv_results'][0]:
                        # Get the external id's for the passed shows id.
                        externals = self.tmdb.TV(
                            result['tv_results'][0]['id']).external_ids()
                        externals = {
                            tmdb_external_id: external_value
                            for tmdb_external_id, external_value in viewitems(
                                externals) if external_value
                            and tmdb_external_id in wanted_externals
                        }
                        externals['tmdb_id'] = result['tv_results'][0]['id']
                        return externals
            return {}
        except RequestException as error:
            raise IndexerException(
                "Could not get external id's. Cause: {cause}".format(
                    cause=error))
Beispiel #2
0
    def _get_series_season_updates(self,
                                   tmdb_id,
                                   start_date=None,
                                   end_date=None):
        """
        Retrieve all updates (show,season,episode) from TMDB.

        :return: A list of updated seasons for a show id.
        """
        results = []
        page = 1
        total_pages = 1

        try:
            while page <= total_pages:
                # Requesting for the changes on a specific showid, will result in json with changes per season.
                updates = self.tmdb.TV_Changes(tmdb_id).series(
                    start_date=start_date, end_date=end_date)
                if updates and updates.get('changes'):
                    for items in [
                            update['items'] for update in updates['changes']
                            if update['key'] == 'season'
                    ]:
                        for season in items:
                            results += [season['value']['season_number']]
                    total_pages = updates.get('total_pages', 0)
                page += 1
        except RequestException as error:
            raise IndexerException(
                'Could not get latest series season updates for series {series}. Cause: {cause}'
                .format(series=tmdb_id, cause=error))

        return set(results)
Beispiel #3
0
    def _parse_actors(self, tmdb_id):
        """Parse actors XML."""
        log.debug('Getting actors for {0}', tmdb_id)

        # TMDB also support passing language here as a param.
        try:
            credits = self.tmdb.TV(tmdb_id).credits(
                language=self.config['language'])  # pylint: disable=W0622
        except RequestException as error:
            raise IndexerException(
                'Could not get actors. Cause: {cause}'.format(cause=error))

        if not credits or not credits.get('cast'):
            log.debug('Actors result returned zero')
            return

        cur_actors = Actors()
        for cur_actor in credits.get('cast'):
            new_actor = Actor()
            new_actor['id'] = cur_actor['credit_id']
            new_actor['image'] = \
                '{base_url}{image_size}{profile_path}'.format(base_url=self.tmdb_configuration.images['base_url'],
                                                              image_size='original',
                                                              profile_path=cur_actor['profile_path'])
            new_actor['name'] = cur_actor['name']
            new_actor['role'] = cur_actor['character']
            new_actor['sortorder'] = cur_actor['order']
            cur_actors.append(new_actor)
        self._set_show_data(tmdb_id, '_actors', cur_actors)
Beispiel #4
0
    def _get_episodes(self, tvdb_id, specials=False, aired_season=None):  # pylint: disable=unused-argument
        """
        Get all the episodes for a show by tvdb id.

        :param tvdb_id: Series tvdb id.
        :return: An ordered dict with the show searched for. In the format of OrderedDict{"episode": [list of episodes]}
        """
        # Parse episode data
        log.debug('Getting all episodes of {0}', tvdb_id)
        try:
            results = self.glotz_api.get_show(tvdb_id)
        except IDNotFound:
            log.debug('Episode search did not return any results.')
            return False
        except BaseError as e:
            raise IndexerException('Show episodes search failed in getting a result with error: {0!r}'.format(e))

        episodes = self._map_results(results.episodes, self.series_map)

        return self._parse_episodes(tvdb_id, episodes)
Beispiel #5
0
    def _get_all_updates(self, start_date=None, end_date=None):
        """Retrieve all updates (show,season,episode) from TMDB."""
        results = []
        page = 1
        total_pages = 1

        try:
            while page <= total_pages:
                updates = self.tmdb.Changes().tv(start_date=start_date, end_date=end_date, page=page)
                if not updates or not updates.get('results'):
                    break
                results += [_.get('id') for _ in updates.get('results')]
                total_pages = updates.get('total_pages')
                page += 1
        except (AttributeError, RequestException) as error:
            raise IndexerException('Could not get latest updates. Cause: {cause}'.format(
                cause=error
            ))

        return set(results)
Beispiel #6
0
    def _get_episodes(self, tvmaze_id, specials=False, aired_season=None):  # pylint: disable=unused-argument
        """
        Get all the episodes for a show by tvmaze id.

        :param tvmaze_id: Series tvmaze id.
        :return: An ordered dict with the show searched for. In the format of OrderedDict{"episode": [list of episodes]}
        """
        # Parse episode data
        log.debug('Getting all episodes of {0}', tvmaze_id)
        try:
            results = self.tvmaze_api.episode_list(tvmaze_id, specials=specials)
        except IDNotFound:
            log.debug('Episode search did not return any results.')
            return False
        except BaseError as e:
            raise IndexerException('Show episodes search failed in getting a result with error: {0!r}'.format(e))

        episodes = self._map_results(results, self.series_map)

        if not episodes:
            return False

        if not isinstance(episodes, list):
            episodes = [episodes]

        absolute_number_counter = 1

        for cur_ep in episodes:
            if self.config['dvdorder']:
                log.debug('Using DVD ordering.')
                use_dvd = cur_ep.get('dvd_season') is not None and cur_ep.get('dvd_episodenumber') is not None
            else:
                use_dvd = False

            if use_dvd:
                seasnum, epno = cur_ep.get('dvd_season'), cur_ep.get('dvd_episodenumber')
            else:
                seasnum, epno = cur_ep.get('seasonnumber'), cur_ep.get('episodenumber')
                if self.config['dvdorder']:
                    log.warning('No DVD order for episode (season: {0}, episode: {1}). '
                                'Falling back to non-DVD order. '
                                'Please consider disabling DVD order for the show with TVmaze ID: {2}',
                                seasnum, epno, tvmaze_id)

            if seasnum is None or epno in (None, 0):
                log.warning('An episode has incomplete season/episode number (season: {0!r}, episode: {1!r})', seasnum, epno)
                continue  # Skip to next episode

            seas_no = int(seasnum)
            ep_no = int(epno)

            if seas_no > 0:
                cur_ep['absolute_number'] = absolute_number_counter
                absolute_number_counter += 1

            for k, v in viewitems(cur_ep):
                k = k.lower()

                if v is not None:
                    if k == 'image_medium':
                        self._set_item(tvmaze_id, seas_no, ep_no, 'filename', v)
                self._set_item(tvmaze_id, seas_no, ep_no, k, v)
Beispiel #7
0
    def _get_episodes(self, tmdb_id, specials=False, aired_season=None):  # pylint: disable=unused-argument
        """Get all the episodes for a show by TMDB id.

        :param tmdb_id: Series tmdb id.
        :return: An ordered dict with the show searched for. In the format of OrderedDict{"episode": [list of episodes]}
        """
        results = []
        if aired_season:
            aired_season = [
                aired_season
            ] if not isinstance(aired_season, list) else aired_season
        else:
            if tmdb_id not in self.shows or not self.shows[tmdb_id].data.get(
                    'seasons'):
                self.config[
                    'episodes_enabled'] = False  # Don't want to get episodes, as where already doing that.
                self._get_show_data(
                    tmdb_id)  # Get show data, with the list of seasons
            aired_season = [
                season['season_number']
                for season in self.shows[tmdb_id].data.get('seasons', [])
            ]

        if not aired_season:
            log.debug(
                'Series does not have any seasons added on indexer TMDB.')
            return

        # Parse episode data
        log.debug('Getting all episodes of {0}', tmdb_id)

        # get episodes for each season
        for season in aired_season:
            try:
                season_info = self.tmdb.TV_Seasons(
                    tmdb_id, season).info(language=self.config['language'])
                results += season_info['episodes']
            except RequestException as error:
                raise IndexerException(
                    'Could not get episodes for series {series} using indexer TMDB. Cause: {cause}'
                    .format(series=tmdb_id, cause=error))

        if not results:
            log.debug(
                'Series does not have any episodes added on indexer TMDB.')
            return

        mapped_episodes = self._map_results(results, self.episodes_map, '|')
        episode_data = OrderedDict({'episode': mapped_episodes})

        if 'episode' not in episode_data:
            return False

        episodes = episode_data['episode']
        if not isinstance(episodes, list):
            episodes = [episodes]

        absolute_number_counter = 1

        for cur_ep in episodes:
            if self.config['dvdorder']:
                log.debug('Using DVD ordering.')
                use_dvd = cur_ep.get('dvd_season') is not None and cur_ep.get(
                    'dvd_episodenumber') is not None
            else:
                use_dvd = False

            if use_dvd:
                seasnum, epno = cur_ep.get('dvd_season'), cur_ep.get(
                    'dvd_episodenumber')
            else:
                seasnum, epno = cur_ep.get('seasonnumber'), cur_ep.get(
                    'episodenumber')
                if self.config['dvdorder']:
                    log.warning(
                        'No DVD order available for episode (season: {0}, episode: {1}). '
                        'Falling back to non-DVD order. '
                        'Please consider disabling DVD order for the show with TMDB ID: {2}',
                        seasnum, epno, tmdb_id)

            if seasnum is None or epno in (None, 0):
                log.warning(
                    'Invalid episode numbering (season: {0!r}, episode: {1!r})',
                    seasnum, epno)
                continue  # Skip to next episode

            seas_no = int(seasnum)
            ep_no = int(epno)

            if seas_no > 0:
                cur_ep['absolute_number'] = absolute_number_counter
                absolute_number_counter += 1

            image_width = {
                'fanart': 'w1280',
                'poster': 'w780',
                'filename': 'w300'
            }
            for k, v in viewitems(cur_ep):
                k = k.lower()

                if v is not None:
                    if k in ['filename', 'poster', 'fanart']:
                        # I'm using the default 'original' quality. But you could also check tmdb_configuration,
                        # for the available image sizes.
                        v = self.config['artwork_prefix'].format(
                            base_url=self.tmdb_configuration.
                            images['base_url'],
                            image_size=image_width[k],
                            file_path=v)
                self._set_item(tmdb_id, seas_no, ep_no, k, v)