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))
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)
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)
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)
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)
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)
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)