def search_by_id(query, id_type='imdb'): """Perform a search query by using a Trakt.tv ID or other external ID :param query: Your search string :param id_type: The type of object you're looking for. Must be one of 'trakt-movie', 'trakt-show', 'trakt-episode', 'imdb', 'tmdb', 'tvdb' or 'tvrage' """ valids = ('trakt-movie', 'trakt-show', 'trakt-episode', 'imdb', 'tmdb', 'tvdb', 'tvrage') if id_type not in valids: raise ValueError('search_type must be one of {}'.format(valids)) data = yield 'search?id={query}&id_type={id_type}'.format( query=slugify(query), id_type=id_type) for media_item in data: extract_ids(media_item) results = [] for d in data: if 'episode' in d: from trakt.tv import TVEpisode show = d.pop('show') extract_ids(d['episode']) results.append(TVEpisode(show['title'], **d['episode'])) elif 'movie' in d: from trakt.movies import Movie results.append(Movie(**d.pop('movie'))) elif 'show' in d: from trakt.tv import TVShow results.append(TVShow(**d.pop('show'))) elif 'person' in d: from trakt.people import Person results.append(Person(**d.pop('person'))) yield results
def _build(self, data): extract_ids(data) for key, val in data.items(): if hasattr(self, '_' + key): setattr(self, '_' + key, val) else: setattr(self, key, val)
def _build(self, data): """Build this :class:`TVEpisode` object with the data in *data*""" extract_ids(data) for key, val in data.items(): if hasattr(self, '_' + key): setattr(self, '_' + key, val) else: setattr(self, key, val)
def _build(self, data): extract_ids(data) for key, val in data.items(): try: setattr(self, key, val) except AttributeError as ae: if not hasattr(self, '_' + key): raise ae
def popular_shows(): data = yield 'shows/popular' shows = [] for show in data: data = show.get('ids', {}) extract_ids(data) data['year'] = show['year'] shows.append(TVShow(show['title'], **data)) yield shows
def get(cls, title, creator): """Returns a single custom :class:`UserList` :param title: Name of the list. """ data = yield 'users/{user}/lists/{id}'.format(user=creator, id=slugify(title)) extract_ids(data) yield UserList(creator=creator, **data)
def seasons(self): """A list of :class:`TVSeason` objects representing all of this show's seasons """ if self._seasons is None: data = yield (self.ext + '/seasons?extended=full') self._seasons = [] for season in data: extract_ids(season) self._seasons.append(TVSeason(self.title, **season)) yield self._seasons
def get_recommended_movies(): """Get a list of :class:`Movie`'s recommended based on your watching history and your friends. Results are returned with the top recommendation first. """ data = yield 'recommendations/movies' movies = [] for movie in data: extract_ids(movie) movies.append(Movie(**movie)) yield movies
def trending_shows(): """All :class:`TVShow`'s being watched right now""" data = yield 'shows/trending' to_ret = [] for show in data: show_data = show.pop('show') ids = show_data.pop('ids') extract_ids(ids) show_data['watchers'] = show.get('watchers') to_ret.append(TVShow(**show_data)) yield to_ret
def watchlist_movies(self): """Returns all watchlist movies of :class:`User`. """ if self._movie_watchlist is None: data = yield 'users/{username}/watchlist/movies'.format( username=self.username, ) self._movie_watchlist = [] for movie in data: mov = movie.pop('movie') extract_ids(mov) self._movie_watchlist.append(Movie(**mov)) yield self._movie_watchlist yield self._movie_watchlist
def movie_collection(self): """All :class:`Movie`'s in this :class:`User`'s library collection. Collection items might include blu-rays, dvds, and digital downloads. Protected users won't return any data unless you are friends. """ if self._movie_collection is None: ext = 'users/{username}/collection/movies?extended=metadata' data = yield ext.format(username=self.username) self._movie_collection = [] for movie in data: mov = movie.pop('movie') extract_ids(mov) self._movie_collection.append(Movie(**mov)) yield self._movie_collection
def updated_movies(timestamp=None): """Returns all movies updated since a timestamp. The server time is in PST. To establish a baseline timestamp, you can use the server/time method. It's recommended to store the timestamp so you can be efficient in using this method. """ ts = timestamp or now() data = yield 'movies/updates/{start_date}'.format(start_date=ts) to_ret = [] for movie in data: mov = movie.pop('movie') extract_ids(mov) mov.update({'updated_at': movie.pop('updated_at')}) to_ret.append(Movie(**mov)) yield to_ret
def watched_shows(self): """Watched profess for all :class:`TVShow`'s in this :class:`User`'s collection. """ if self._watched_shows is None: data = yield 'users/{user}/watched/shows'.format( user=self.username ) self._watched_shows = [] for show in data: show_data = show.pop('show') extract_ids(show_data) show_data.update(show) self._watched_shows.append(TVShow(**show_data)) yield self._watched_shows
def watched_movies(self): """Watched profess for all :class:`Movie`'s in this :class:`User`'s collection. """ if self._watched_movies is None: data = yield 'users/{user}/watched/movies'.format( user=self.username ) self._watched_movies = [] for movie in data: movie_data = movie.pop('movie') extract_ids(movie_data) movie_data.update(movie) self._watched_movies.append(Movie(**movie_data)) yield self._watched_movies
def watchlist_shows(self): """Returns all watchlist shows of :class:`User`. """ if self._show_watchlist is None: data = yield 'users/{username}/watchlist/shows'.format( username=self.username, ) self._show_watchlist = [] for show in data: show_data = show.pop('show') extract_ids(show_data) show_data.update(show) self._show_watchlist.append(TVShow(**show_data)) yield self._show_watchlist yield self._show_watchlist
def test_extract_ids(): """verify that id dicts can be correctly extracted""" ids = dict(trakt=443, tvdb=4851180, imdb='tt3500614', tmdb=988123, tvrage=None) input_dict = {'ids': ids} result = extract_ids(input_dict) assert result == ids
def show_collection(self): """All :class:`TVShow`'s in this :class:`User`'s library collection. Collection items might include blu-rays, dvds, and digital downloads. Protected users won't return any data unless you are friends. """ if self._show_collection is None: ext = 'users/{username}/collection/shows?extended=metadata' data = yield ext.format(username=self.username) self._show_collection = [] for show in data: s = show.pop('show') extract_ids(s) sh = TVShow(**s) sh._seasons = [TVSeason(show=sh.title, **sea) for sea in show.pop('seasons')] self._show_collection.append(sh) yield self._show_collection
def create(cls, name, creator, description=None, privacy='private', display_numbers=False, allow_comments=True): """Create a new custom class:`UserList`. *name* is the only required field, but the other info is recommended. :param name: Name of the list. :param description: Description of this list. :param privacy: Valid values are 'private', 'friends', or 'public' :param display_numbers: Bool, should each item be numbered? :param allow_comments: Bool, are comments allowed? """ args = {'name': name, 'privacy': privacy, 'display_numbers': display_numbers, 'allow_comments': allow_comments} if description is not None: args['description'] = description data = yield 'users/{user}/lists'.format(user=creator), args extract_ids(data) yield UserList(creator=creator, user=creator, **data)
def search(query, search_type='movie', year=None): """Perform a search query against all of trakt's media types :param query: Your search string :param search_type: The type of object you're looking for. Must be one of 'movie', 'show', 'episode', or 'person' """ valids = ('movie', 'show', 'episode', 'person') if search_type not in valids: raise ValueError('search_type must be one of {}'.format(valids)) uri = 'search?query={query}&type={type}'.format( query=slugify(query), type=search_type) if year is not None: uri += '&year={}'.format(year) data = yield uri for media_item in data: extract_ids(media_item) # Need to do imports here to prevent circular imports with modules that # need to import Scrobblers if search_type == 'movie': from trakt.movies import Movie yield [Movie(**d.pop('movie')) for d in data] elif search_type == 'show': from trakt.tv import TVShow yield [TVShow(**d.pop('show')) for d in data] elif search_type == 'episode': from trakt.tv import TVEpisode episodes = [] for episode in data: show = episode.pop('show') extract_ids(episode['episode']) episodes.append(TVEpisode(show.get('title', None), **episode['episode'])) yield episodes elif search_type == 'person': from trakt.people import Person yield [Person(**d.pop('person')) for d in data]
def _build(self, data): """Build the calendar""" self._calendar = [] for cal_item in data: show_data = cal_item.get('show', {}) episode = cal_item.get('episode', {}) first_aired = cal_item.get('first_aired') season = episode.get('season') ep_num = episode.get('number') extract_ids(show_data) show_data.update(show_data) e_data = { 'airs_at': airs_date(first_aired), 'ids': episode.get('ids'), 'title': episode.get('title'), 'show_data': TVShow(**show_data) } self._calendar.append( TVEpisode(show_data['trakt'], season, ep_num, **e_data) ) self._calendar = sorted(self._calendar, key=lambda x: x.airs_at)
def lists(self): """All custom lists for this :class:`User`. Protected :class:`User`'s won't return any data unless you are friends. To view your own private lists, you will need to authenticate as yourself. """ if self._lists is None: data = yield 'users/{username}/lists'.format( username=self.username ) self._lists = [UserList(creator=self.username, user=self, **extract_ids(ul)) for ul in data] yield self._lists
def lists(self): """All custom lists for this :class:`User`. Protected :class:`User`'s won't return any data unless you are friends. To view your own private lists, you will need to authenticate as yourself. """ if self._lists is None: data = yield 'users/{username}/lists'.format( username=self.username) self._lists = [ UserList(creator=self.username, user=self, **extract_ids(ul)) for ul in data ] yield self._lists
def get_search_results(query, search_type=None): """Perform a search query against all of trakt's media types :param query: Your search string :param search_type: The types of objects you're looking for. Must be specified as a list of strings containing any of 'movie', 'show', 'episode', or 'person'. """ # if no search type was specified, then search everything if search_type is None: search_type = ['movie', 'show', 'episode', 'person'] uri = 'search/{type}?query={query}'.format(query=slugify(query), type=','.join(search_type)) data = yield uri # Need to do imports here to prevent circular imports with modules that # need to import Scrobblers results = [] for media_item in data: extract_ids(media_item) result = SearchResult(media_item['type'], media_item['score']) if media_item['type'] == 'movie': from trakt.movies import Movie result.media = Movie(**media_item.pop('movie')) elif media_item['type'] == 'show': from trakt.tv import TVShow result.media = TVShow(**media_item.pop('show')) elif media_item['type'] == 'episode': from trakt.tv import TVEpisode show = media_item.pop('show') result.media = TVEpisode(show.get('title', None), **media_item.pop('episode')) elif media_item['type'] == 'person': from trakt.people import Person result.media = Person(**media_item.pop('person')) results.append(result) yield results
def watching(self): """The :class:`TVEpisode` or :class:`Movie` this :class:`User` is currently watching. If they aren't watching anything, a blank object will be returned. Protected users won't return any data unless you are friends. """ data = yield 'users/{user}/watching'.format(user=self.username) # if a user isn't watching anything, trakt returns a 204 if data is None or data == '': yield None media_type = data.pop('type') if media_type == 'movie': movie_data = data.pop('movie') extract_ids(movie_data) movie_data.update(data) yield Movie(**movie_data) else: # media_type == 'episode' ep_data = data.pop('episode') extract_ids(ep_data) sh_data = data.pop('show') ep_data.update(data, show=sh_data.get('title')) yield TVEpisode(**ep_data)
def lists(self): """All custom lists for this :class:`User`. Protected :class:`User`'s won't return any data unless you are friends. To view your own private lists, you will need to authenticate as yourself. """ if self._lists is None: data = yield 'users/{username}/lists'.format( username=slugify(self.username)) for ul in data: if "user" in ul: # user will be replaced with the self User object del ul["user"] self._lists = [ UserList(creator=slugify(self.username), user=self, **extract_ids(ul)) for ul in data ] yield self._lists
def get_items(self): """A list of the list items using class instances instance types: movie, show, season, episode, person """ data = yield 'users/{user}/lists/{id}/items'.format(user=slugify( self.creator), id=self.slug) for item in data: # match list item type if 'type' not in item: continue item_type = item['type'] item_data = item.pop(item_type) extract_ids(item_data) if item_type == 'movie': self._items.append( Movie(item_data['title'], item_data['year'], item_data['slug'])) elif item_type == 'show': self._items.append( TVShow(item_data['title'], item_data['slug'])) elif item_type == 'season': show_data = item.pop('show') extract_ids(show_data) season = TVSeason(show_data['title'], item_data['number'], show_data['slug']) self._items.append(season) elif item_type == 'episode': show_data = item.pop('show') extract_ids(show_data) episode = TVEpisode(show_data['title'], item_data['season'], item_data['number']) self._items.append(episode) elif item_type == 'person': self._items.append(Person(item_data['name'], item_data['slug'])) yield self._items
def get_items(self): """A list of the list items using class instances instance types: movie, show, season, episode, person """ data = yield 'users/{user}/lists/{id}/items'.format(user=self.creator, id=self.slug) for item in data: # match list item type if 'type' not in item: continue item_type = item['type'] item_data = item.pop(item_type) extract_ids(item_data) if item_type == 'movie': self._items.append(Movie(item_data['title'], item_data['year'], item_data['slug'])) elif item_type == 'show': self._items.append(TVShow(item_data['title'], item_data['slug'])) elif item_type == 'season': show_data = item.pop('show') extract_ids(show_data) season = TVSeason(show_data['title'], item_data['number'], show_data['slug']) self._items.append(season) elif item_type == 'episode': show_data = item.pop('show') extract_ids(show_data) episode = TVEpisode(show_data['title'], item_data['season'], item_data['number']) self._items.append(episode) elif item_type == 'person': self._items.append(Person(item_data['name'], item_data['slug'])) yield self._items
def get_items(self): """A list of the list items using class instances instance types: movie, show, season, episode, person """ data = yield 'users/{user}/lists/{id}/items'.format(user=self.creator, id=self.slug) for item in data: # match list item type if 'type' not in item: continue item_type = item['type'] item_data = item.pop(item_type) extract_ids(item_data) if item_type == 'movie': movie = Movie(item_data.pop('title'), item_data.pop('year'), item_data.pop('slug'), **item_data) self._items.append(movie) elif item_type == 'show': show = TVShow(item_data.pop('title'), slug=item_data.pop('slug'), **item_data) seasons = show.seasons show._seasons = [] for season in seasons: season._episodes = [] show._seasons.append(season) self._items.append(show) elif item_type == 'season': show_data = item.pop('show') extract_ids(show_data) show = TVShow(show_data.pop('title'), slug=show_data.pop('slug'), **show_data) _season = TVSeason(show=show.title, season=item_data.pop('number'), slug=show.slug, **item_data) for season in show.seasons: if season.trakt != _season.trakt: continue season._episodes = [] show._seasons = [season] self._items.append(show) break # season._episodes = [] # show._seasons = [season] # self._items.append(show) # extract_ids(show_data) # show=TVShow(show_data['title'], show_data['slug']) # season = TVSeason( # show=show.title, # season=item_data['number'], # slug=show.slug, # **item_data # ) # self._items.append(self.__class__.ListTVSeason(show=show, season=season)) elif item_type == 'episode': show_data = item.pop('show') extract_ids(show_data) show = TVShow(show_data.pop('title'), slug=show_data.pop('slug'), **show_data) episode = TVEpisode(show=show.title, season=item_data.pop('season'), slug=show.slug, **item_data) for season in show.seasons: if season.season != episode.season: continue season._episodes = [episode] show._seasons = [season] self._items.append(show) break # show=TVShow(show_data['title'], show_data['slug']) # show._seasons = None # for season in show.seasons: # if season.season != item_data['number']: # continue # episode = TVEpisode(show.title, season.season, item_data['number'], show.slug) # self._items.append(self.__class__.ListTVEpisode(show=show, season=season, episode=episode)) # break elif item_type == 'person': self._items.append(Person(item_data['name'], item_data['slug'])) yield self._items
def search_by_id(query, id_type='imdb', media_type=None, slugify_query=False): """Perform a search query by using a Trakt.tv ID or other external ID. :param query: Your search string, which should be an ID from your source :param id_type: The source of the ID you're looking for. Must be one of 'trakt', trakt-movie', 'trakt-show', 'trakt-episode', 'trakt-person', 'imdb', 'tmdb', or 'tvdb' :param media_type: The type of media you're looking for. May be one of 'movie', 'show', 'episode', or 'person', or a comma-separated list of any combination of those. Null by default, which will return all types of media that match the ID given. :param slugify_query: A boolean indicating whether or not the provided query should be slugified or not prior to executing the query. """ valids = ('trakt', 'trakt-movie', 'trakt-show', 'trakt-episode', 'trakt-person', 'imdb', 'tmdb', 'tvdb') id_types = {'trakt': 'trakt', 'trakt-movie': 'trakt', 'trakt-show': 'trakt', 'trakt-episode': 'trakt', 'trakt-person': 'trakt', 'imdb': 'imdb', 'tmdb': 'tmdb', 'tvdb': 'tvdb'} if id_type not in valids: raise ValueError('search_type must be one of {}'.format(valids)) source = id_types.get(id_type) media_types = {'trakt-movie': 'movie', 'trakt-show': 'show', 'trakt-episode': 'episode', 'trakt-person': 'person'} # If there was no media_type passed in, see if we can guess based off the # ID source. None is still an option here, as that will return all possible # types for a given source. if media_type is None: media_type = media_types.get(source, None) # If requested, slugify the query prior to running the search if slugify_query: query = slugify(query) # If media_type is still none, don't add it as a parameter to the search if media_type is None: uri = 'search/{source}/{query}'.format( query=query, source=source) else: uri = 'search/{source}/{query}?type={media_type}'.format( query=query, source=source, media_type=media_type) data = yield uri for media_item in data: extract_ids(media_item) results = [] for d in data: if 'episode' in d: from trakt.tv import TVEpisode show = d.pop('show') extract_ids(d['episode']) results.append(TVEpisode(show, **d['episode'])) elif 'movie' in d: from trakt.movies import Movie results.append(Movie(**d.pop('movie'))) elif 'show' in d: from trakt.tv import TVShow results.append(TVShow(**d.pop('show'))) elif 'person' in d: from trakt.people import Person results.append(Person(**d.pop('person'))) yield results