def _get(cls, title, creator): data = yield 'users/{user}/lists/{id}'.format(user=slugify(creator), id=slugify(title)) extract_ids(data) ulist = LazyUserList(creator=creator, **data) ulist.get_items() yield ulist
def search_by_id(query, id_type='imdb', media_type=None): """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. """ 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 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=slugify(query), source=source) else: uri = 'search/{source}/{query}?type={media_type}'.format( query=slugify(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['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 slug(self): if self._slug is not None: return self._slug if self.year is None: return slugify(self.title) return slugify(self.title + ' ' + str(self.year))
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=slugify(creator), id=slugify(title)) extract_ids(data) ulist = UserList(creator=creator, **data) ulist.get_items() yield ulist
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=slugify(creator)), args extract_ids(data) yield UserList(creator=creator, user=creator, **data)
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 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=slugify(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 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 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 __init__(self, name, slug=None, **kwargs): super(Person, self).__init__() self.name = name self.biography = self.birthplace = self.tmdb_id = self.birthday = None self.job = self.character = self._images = None self.slug = slug or slugify(self.name) if len(kwargs) > 0: self._build(kwargs) else: self._get()
def add_items(self, *items): """Add *items* to this :class:`UserList`, where items is an iterable""" movies = [m.ids for m in items if isinstance(m, Movie)] shows = [s.ids for s in items if isinstance(s, TVShow)] people = [p.ids for p in items if isinstance(p, Person)] self._items = items args = {'movies': movies, 'shows': shows, 'people': people} uri = 'users/{user}/lists/{id}/items'.format(user=slugify( self.creator), id=self.trakt) yield uri, args
def test_slugify(): """Verify that the slugify function works as expected""" test_data = [ ('IM AN ALL CAPS STRING', 'im-an-all-caps-string'), ('IM A BAD A$$ STRING!@', 'im-a-bad-a-string'), (' LOOK AT MY WHITESPACE ', 'look-at-my-whitespace'), ] for inp, expected in test_data: observed = slugify(inp) assert observed == expected
def __init__(self, name, slug=None, **kwargs): super(Person, self).__init__() self.name = name self.biography = self.birthplace = self.tmdb_id = self.birthday = None self.job = self.character = self._images = self._movie_credits = None self._tv_credits = None self.slug = slug or slugify(self.name) if len(kwargs) > 0: self._build(kwargs) else: self._get()
def get_items(self): data = yield 'users/{user}/lists/{id}/items'.format(user=slugify( self.creator), id=self.slug) for item in data: if 'type' not in item: continue item_type = item['type'] item_data = item.pop(item_type) extract_ids(item_data) self._items.append((item_type + 's', item_data['trakt'])) yield self._items
def get_items(self): data = yield "users/{user}/lists/{id}/items".format(user=slugify( self.creator), id=self.slug) for item in data: if "type" not in item: continue item_type = item["type"] item_data = item.pop(item_type) extract_ids(item_data) self._items.append((item_type + "s", item_data["trakt"])) yield self._items
def __init__(self, show, season=1, slug=None, **kwargs): super(TVSeason, self).__init__() self.show = show self.season = season self.slug = slug or slugify(show) self._episodes = self._comments = self._ratings = None self.ext = 'shows/{id}/seasons/{season}'.format(id=self.slug, season=season) if len(kwargs) > 0: self._build(kwargs) else: self._get()
def test_slugify(): """Verify that the slugify function works as expected""" test_data = [ ('IM AN ALL CAPS STRING', 'im-an-all-caps-string'), ('IM A BAD A$$ STRING!@', 'im-a-bad-a-string'), (' LOOK AT MY WHITESPACE ', 'look-at-my-whitespace'), ("Marvel's Agents of S.H.I.E.L.D.", 'marvel-s-agents-of-s-h-i-e-l-d'), ('Naruto Shippūden', 'naruto-shippuden'), ] for inp, expected in test_data: observed = slugify(inp) assert observed == expected
def __init__(self, title, year=None, slug=None, **kwargs): super(Movie, self).__init__() self.media_type = 'movies' self.title = title self.year = int(year) if year is not None else year if self.year is not None and slug is None: self.slug = slugify('-'.join([self.title, str(self.year)])) else: self.slug = slug or slugify(self.title) self.released = self.tmdb_id = self.imdb_id = self.duration = None self.trakt_id = self.tagline = self.overview = self.runtime = None self.updated_at = self.trailer = self.homepage = self.rating = None self.votes = self.language = self.available_translations = None self.genres = self.certification = None self._comments = self._images = self._aliases = self._people = None self._ratings = self._releases = self._translations = None if len(kwargs) > 0: self._build(kwargs) else: self._get()
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=slugify(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 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=slugify(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 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=slugify(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 watchlist_shows(self): """Returns all watchlist shows of :class:`User`. """ if self._show_watchlist is None: data = yield 'users/{username}/watchlist/shows'.format( username=slugify(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 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=slugify(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 __init__(self, title='', **kwargs): super(TVShow, self).__init__() self.media_type = 'shows' self.top_watchers = self.top_episodes = self.year = self.tvdb_id = None self.imdb_id = self.genres = self.certification = self.network = None self.trakt_id = self.tmdb_id = self._aliases = self._comments = None self._images = self._people = self._ratings = self._translations = None self._seasons = None self.title = title self.slug = slugify(self.title) if len(kwargs) > 0: self._build(kwargs) else: self._get()
def __init__(self, title='', slug=None, **kwargs): super(TVShow, self).__init__() self.media_type = 'shows' self.top_watchers = self.top_episodes = self.year = self.tvdb = None self.imdb = self.genres = self.certification = self.network = None self.trakt = self.tmdb = self._aliases = self._comments = None self._images = self._people = self._ratings = self._translations = None self._seasons = None self.title = title self.slug = slug or slugify(self.title) if len(kwargs) > 0: self._build(kwargs) else: self._get()
def get_ratings(self, media_type='movies', rating=None): """Get a user's ratings filtered by type. You can optionally filter for a specific rating between 1 and 10. :param media_type: The type of media to search for. Must be one of 'movies', 'shows', 'seasons', 'episodes' :param rating: Optional rating between 1 and 10 """ uri = 'users/{user}/ratings/{type}'.format(user=slugify(self.username), type=media_type) if rating is not None: uri += '/{rating}'.format(rating=rating) data = yield uri # TODO (moogar0880) - return as objects yield data
def following(self): """A list of all user's this :class:`User` follows including the since timestamp which is when the relationship began. Protected users won't return any data unless you are friends. Any friends of the main user that are protected won't display data either. """ if self._following is None: data = yield 'users/{user}/following'.format( user=slugify(self.username)) self._following = [] for user in data: user_data = user.pop('user') date = user.pop('followed_at') self._following.append(User(followed_at=date, **user_data)) yield self._following
def friends(self): """A list of this :class:`User`'s friends (a 2 way relationship where each user follows the other) including the since timestamp which is when the friendship began. Protected users won't return any data unless you are friends. Any friends of the main user that are protected won't display data either. """ if self._friends is None: self._friends = [] data = yield 'users/{user}/friends'.format( user=slugify(self.username)) for user in data: user_data = user.pop('user') date = user.pop('friends_at') self._friends.append(User(followed_at=date, **user_data)) yield self._friends
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', 'movie,show', 'episode', or 'person' """ valids = ('movie', 'show', 'episode', 'person', 'movie,show') 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['score'], **d.pop('movie')) for d in data] elif search_type == 'show': from trakt.tv import TVShow yield [TVShow(d['score'], **d.pop('show')) for d in data] elif search_type == 'movie,show': from trakt.movies import Movie from trakt.tv import TVShow yield [Movie(d['score'], **d.pop('movie')) if d['type'] == 'movie' else TVShow(d['score'], **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 __init__(self, show, season, number=-1, slug=None, **kwargs): super(TVEpisode, self).__init__() self.media_type = 'episodes' self.show = show self.season = season self.number = number self.slug = slug or slugify(show) self.overview = self.title = self.year = self.number_abs = None self.first_aired = self.last_updated = None self.trakt = self.tmdb = self.tvdb = self.imdb = None self.tvrage = self._stats = self._images = self._comments = None self._translations = self._ratings = None if len(kwargs) > 0: self._build(kwargs) else: self._get() self.episode = self.number # Backwards compatability
def get_search_results(query, search_type=None, slugify_query=False): """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'. :param slugify_query: A boolean indicating whether or not the provided query should be slugified or not prior to executing the query. """ # if no search type was specified, then search everything if search_type is None: search_type = ['movie', 'show', 'episode', 'person'] # If requested, slugify the query prior to running the search if slugify_query: query = slugify(query) uri = 'search/{type}?query={query}'.format( query=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 _search(self, query): """Search Trakt for a TV episode matching *query*""" results = TVShow.search(query) self.filter_key = slugify(query) result = self.filter_results(query, results) if result is None: return self.context show = TVShow(result.slug) LOGGER.info('Trakt Search Result: %s', str(show)) self._apply_mapping(show) # Get general information about the show # Get episode specific data season_num = self.context.get('TV Season', None) if season_num is None: return self.context episode_num = self.context.get('TV Episode #') episode = TVEpisode(result.slug, season_num, episode_num) return self._get_episode(episode)
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=slugify(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 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 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 dismiss_recommendation(title): """Dismiss the movie matching the specified criteria from showing up in recommendations. """ yield 'recommendations/movies/{title}'.format(title=slugify(str(title)))
def ext(self): return 'shows/{id}/seasons/{season}/episodes/{episode}'.format( id=slugify(self.show), season=self.season, episode=self.number )
def ext(self): return 'shows/{id}/seasons/{season}/episodes/{episode}'.format( id=slugify(self.show), season=self.season, episode=self.number)
def ext(self): return 'people/{id}'.format(id=slugify(self.name))