Ejemplo n.º 1
0
def test_get_quargs():
    client = Trakt("", "")
    p = Path("a", {}, filters={"query", "genres"}, extended=["metadata"])

    assert p.is_valid(client, extended=True, query="xyz", genres=["a", "b"])

    _, quargs = p.get_path_and_qargs()

    expected = {"genres": "a,b", "query": "xyz", "extended": "metadata"}

    assert quargs == expected
Ejemplo n.º 2
0
class RecommendationsI(SuiteInterface):
    name = "recommendations"

    paths = {
        "get_movie_recommendations": Path(
            "recommendations/movies",
            [Movie],
            validators=[AuthRequiredValidator(), IGNORE_COLLECTED_VALIDATOR],
            extended=["full"],
            qargs=["ignore_collected"],
        ),
        "hide_movie": Path(
            "recommendations/movies/!id",
            {},
            methods="DELETE",
            validators=[AuthRequiredValidator(), ID_VALIDATOR],
        ),
        "get_show_recommendations": Path(
            "recommendations/shows",
            [Show],
            validators=[AuthRequiredValidator(), IGNORE_COLLECTED_VALIDATOR],
            extended=["full"],
            qargs=["ignore_collected"],
        ),
        "hide_show": Path(
            "recommendations/shows/!id",
            {},
            methods="DELETE",
            validators=[AuthRequiredValidator(), ID_VALIDATOR],
        ),
    }

    def get_movie_recommendations(
        self, *, ignore_collected: bool = False, **kwargs
    ) -> List[Movie]:
        return self.run(
            "get_movie_recommendations", **kwargs, ignore_collected=ignore_collected
        )

    def hide_movie(self, *, movie: Union[Movie, str, int], **kwargs) -> None:
        id = self._generic_get_id(movie)
        self.run("hide_movie", **kwargs, id=id)

    def get_show_recommendations(
        self, *, ignore_collected: bool = False, **kwargs
    ) -> List[Show]:
        return self.run(
            "get_show_recommendations", **kwargs, ignore_collected=ignore_collected
        )

    def hide_show(self, *, show: Union[Movie, str, int], **kwargs) -> None:
        id = self._generic_get_id(show)
        self.run("hide_show", **kwargs, id=id)
Ejemplo n.º 3
0
def test_multiple_validators_for_field():
    p = Path(
        "?a",
        {},
        validators=[
            PerArgValidator("a", lambda x: x > 10),
            PerArgValidator("a", lambda x: x % 3 == 0),
        ],
    )

    assert p.is_valid(None, a=30)

    for val in [6, 13]:
        with pytest.raises(ArgumentError):
            p.is_valid(None, a=val)
Ejemplo n.º 4
0
class NetworksI(SuiteInterface):
    name = "networks"

    paths = {"get_networks": Path("networks", [Network], cache_level="basic")}

    def get_networks(self, **kwargs: Any) -> List[Network]:
        return self.run("get_networks", **kwargs)
Ejemplo n.º 5
0
    def exec_path_call(self,
                       path: Path,
                       extra_quargs: Optional[Dict[str, str]] = None,
                       **kwargs: Any) -> ApiResponse:
        caching_enabled = self._should_use_cache(path,
                                                 kwargs.get("no_cache", False))

        api_path, query_args = path.get_path_and_qargs()
        query_args.update(extra_quargs or {})

        api_response = self.client.http.request(
            api_path,
            method=path.method,
            query_args=query_args,
            data=kwargs.get("data"),
            use_cache=caching_enabled,
            **kwargs,
        )

        api_response.parsed = json_parser.parse_tree(api_response.json,
                                                     path.response_structure)

        if caching_enabled:
            # only runs if there were no errors
            last_request = cast(FrozenRequest, self.client.http.last_request)
            self.client.cache.set(last_request)

        return api_response
Ejemplo n.º 6
0
class ListsI(SuiteInterface):
    name = "lists"

    paths = {
        "get_trending": Path(
            "lists/trending", [ListResponse], extended=["full"], pagination=True
        ),
        "get_popular": Path(
            "lists/popular", [ListResponse], extended=["full"], pagination=True
        ),
    }

    def get_trending(self, **kwargs: Any) -> PaginationIterator[ListResponse]:
        return self.run("get_trending", **kwargs)

    def get_popular(self, **kwargs: Any) -> PaginationIterator[ListResponse]:
        return self.run("get_popular", **kwargs)
Ejemplo n.º 7
0
def test_add_quargs():
    client = mk_mock_client({".*": [[], 200]})
    path = Path("a", [None], qargs=["arg"])

    executor = Executor(client)

    _ = executor.run(path=path, arg="abc")

    req = client.http._requests.req_map["a"][0]

    assert req["path"].endswith(r"/a?arg=abc")
Ejemplo n.º 8
0
class GenresI(SuiteInterface):
    name = "genres"

    paths = {
        "get_genres": Path(
            "genres/!type", [Genre], validators=[TYPE_MOVIES_SHOWS], cache_level="basic"
        )
    }

    def get_genres(self, *, type: str, **kwargs: Any) -> List[Genre]:
        return self.run("get_genres", type=type, **kwargs)
Ejemplo n.º 9
0
    def _make_path(self, resource_path: str, return_type: Any) -> Path:
        extra_validators = [AuthRequiredValidator()
                            ] if "my/" in resource_path else []

        return Path(
            "calendars/" + resource_path,
            return_type,
            extended=["full"],
            filters=COMMON_FILTERS | SHOWS_FILTERS,
            validators=self.COMMON_VALIDATORS +
            extra_validators,  # type: ignore
        )
Ejemplo n.º 10
0
    def _make_path(self, resource_path: str, return_type: Any) -> Path:
        extra_validators: List[Validator] = []
        if "?period" in resource_path:
            extra_validators.append(
                PerArgValidator("period", lambda p: p in PERIOD_VALUES))

        return Path(
            self.name + "/" + resource_path,
            return_type,
            extended=["full"],
            filters=COMMON_FILTERS,
            pagination=True,
            validators=extra_validators,
        )
Ejemplo n.º 11
0
class CertificationsI(SuiteInterface):
    name = "certifications"

    paths = {
        "get_certifications": Path(
            "certifications/!type",
            {"us": [Certification]},
            validators=[TYPE_MOVIES_SHOWS],
            cache_level="basic",
        )
    }

    def get_certifications(self, *, type: str, **kwargs: Any) -> List[Certification]:
        ret = self.run("get_certifications", type=type, **kwargs)
        return ret["us"]
Ejemplo n.º 12
0
class CountriesI(SuiteInterface):
    name = "countries"

    paths = {
        "get_countries": Path(
            "countries/!type",
            [Country],
            aliases=["get_countries", ""],
            validators=[TYPE_MOVIES_SHOWS],
            cache_level="basic",
        )
    }

    def get_countries(self, *, type: str, **kwargs: Any) -> List[Country]:
        return self.run("get_countries", type=type, **kwargs)
Ejemplo n.º 13
0
def test_required_args():
    client = Trakt("", "")

    p = Path("aaa/!b/ccc/?d", [{"a": str}])

    assert p.methods == ["GET"]
    assert p.args == ["!b", "?d"]

    default_alias = "aaa.ccc"

    assert p.aliases == [default_alias]
    assert p.does_match(default_alias)

    with pytest.raises(ArgumentError):
        p.is_valid(client)

    with pytest.raises(
            ArgumentError):  # intentional, assert didn't bind any values
        p.is_valid(client)

    assert p.is_valid(client, b=10)
    assert p.get_path_and_qargs() == ("aaa/10/ccc", {})
Ejemplo n.º 14
0
def test_optional_args():
    client = Trakt("", "")

    p = Path("calendars/all/shows/new/?start_date/?days", [{"a": str}])

    assert p.methods == ["GET"]
    assert p.args == ["?start_date", "?days"]

    default_alias = "calendars.all.shows.new"

    assert p.aliases == [default_alias]
    assert p.does_match(default_alias)
    assert not p.does_match(default_alias[1:])

    assert p.is_valid(client)
    assert p.get_path_and_qargs() == ("calendars/all/shows/new", {})

    assert p.is_valid(client, start_date="2018-10-10")
    assert p.get_path_and_qargs() == ("calendars/all/shows/new/2018-10-10", {})
Ejemplo n.º 15
0
class CheckinI(SuiteInterface):
    name = "checkin"

    paths = {
        "delete_active_checkins": Path(
            "checkin", {}, methods="DELETE", validators=[AuthRequiredValidator()]
        ),
        "check_into_episode": Path(
            "checkin",
            EpisodeCheckin,
            methods="POST",
            validators=[AuthRequiredValidator(), MESSAGE_VALIDATOR],
        ),
        "check_into_movie": Path(
            "checkin",
            MovieCheckin,
            methods="POST",
            validators=[AuthRequiredValidator(), MESSAGE_VALIDATOR],
        ),
    }

    @auth_required
    def check_into(
        self,
        *,
        movie: Optional[Union[Movie, Dict[str, Any]]] = None,
        episode: Optional[Union[Episode, Dict[str, Any]]] = None,
        **kwargs: Any,
    ) -> Union[EpisodeCheckin, MovieCheckin]:
        if movie and episode:
            raise ArgumentError("you must provide exactly one of: [episode, movie]")

        if movie:
            return self.check_into_movie(movie=movie, **kwargs)
        elif episode:
            return self.check_into_episode(episode=episode, **kwargs)
        else:
            raise ArgumentError("you must provide exactly one of: [episode, movie]")

    def check_into_episode(
        self,
        *,
        episode: Union[Episode, Dict[str, Any]],
        message: Optional[str] = None,
        sharing: Optional[Union[Sharing, Dict[str, str]]] = None,
        **kwargs,
    ) -> EpisodeCheckin:
        data: Dict[str, Any] = self._prepare_common_data(
            **kwargs, message=message, sharing=sharing
        )

        if isinstance(episode, Episode):
            episode = {"ids": {"trakt": self._generic_get_id(episode)}}
        data["episode"] = episode

        if "show" in kwargs:
            show = kwargs["show"]
            if isinstance(show, Show):
                data["show"] = {"ids": {"trakt": self._generic_get_id(show)}}
            elif isinstance(show, dict):
                data["show"] = show
            else:
                raise ArgumentError("show: invalid argument value")

        return self.run("check_into_episode", **data, body=data)

    def check_into_movie(
        self,
        *,
        movie: Union[Movie, Dict[str, Any]],
        message: Optional[str] = None,
        sharing: Optional[Union[Sharing, Dict[str, str]]] = None,
        **kwargs,
    ) -> MovieCheckin:
        data = self._prepare_common_data(**kwargs, message=message, sharing=sharing)

        if isinstance(movie, Movie):
            movie = {"ids": {"trakt": self._generic_get_id(movie)}}
        data["movie"] = movie

        return self.run("check_into_movie", **data, body=data)

    def _prepare_common_data(
        self, **kwargs: Any
    ) -> Dict[str, Union[str, Dict[str, str]]]:
        d: Dict[str, Union[str, Dict[str, str]]] = {}

        if "sharing" in kwargs and kwargs["sharing"] is not None:
            if isinstance(kwargs["sharing"], Sharing):
                d["sharing"] = asdict(kwargs["sharing"])
            elif isinstance(kwargs["sharing"], dict):
                d["sharing"] = kwargs["sharing"]
            else:
                raise ArgumentError("sharing: invalid argument value")

        for f in ["message", "venue_id", "venue_name", "app_version", "app_date"]:
            if f in kwargs:
                v = kwargs[f]
                if v is not None:
                    d[f] = v

        return d

    def delete_active_checkins(self, **kwargs: Any) -> None:
        self.run("delete_active_checkins", **kwargs)
Ejemplo n.º 16
0
class SeasonsI(SuiteInterface):
    name = "seasons"

    paths = {
        "get_all_seasons":
        Path(
            "shows/!id/seasons",
            [Season],
            extended=["full", "episodes"],
            validators=[ID_VALIDATOR],
            cache_level="basic",
        ),
        "get_season":
        Path(
            "shows/!id/seasons/!season",
            [Episode],
            extended=["full", "episodes"],
            validators=[
                ID_VALIDATOR,
                SEASON_ID_VALIDATOR,
                PerArgValidator(
                    "translations",
                    lambda t: isinstance(t, str) and
                    (t == "all" or len(t) == 2),
                ),
            ],
            qargs=["translations"],
            cache_level="basic",
        ),
        "get_comments":
        Path(
            "shows/!id/seasons/!season/comments/?sort",
            [Comment],
            validators=[
                ID_VALIDATOR,
                SEASON_ID_VALIDATOR,
                PerArgValidator("sort", lambda s: s in COMMENT_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_lists":
        Path(
            "shows/!id/seasons/!season/lists/?type/?sort",
            [TraktList],
            validators=[
                ID_VALIDATOR,
                SEASON_ID_VALIDATOR,
                PerArgValidator("type", lambda t: t in LIST_TYPE_VALUES),
                PerArgValidator("sort", lambda s: s in LIST_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_ratings":
        Path(
            "shows/!id/seasons/!season/ratings",
            RatingsSummary,
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR],
        ),
        "get_stats":
        Path(
            "shows/!id/seasons/!season/stats",
            SeasonEpisodeStats,
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR],
        ),
        "get_users_watching":
        Path(
            "shows/!id/seasons/!season/watching",
            [User],
            extended=["full"],
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR],
        ),
    }

    def get_all_seasons(self, *, show: Union[Show, str, int],
                        season: Union[Season, str,
                                      int], **kwargs) -> List[Season]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_all_seasons", **kwargs, id=id, season=season)

    def get_season(self, *, show: Union[Show, str, int],
                   season: Union[Season, str, int], **kwargs) -> List[Episode]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_season", **kwargs, id=id, season=season)

    def get_comments(self,
                     *,
                     show: Union[Show, str, int],
                     season: Union[Season, str, int],
                     sort: str = "newest",
                     **kwargs) -> PaginationIterator[Comment]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_comments",
                        **kwargs,
                        sort=sort,
                        id=id,
                        season=season)

    def get_lists(self,
                  *,
                  show: Union[Show, str, int],
                  season: Union[Season, str, int],
                  type: str = "personal",
                  sort: str = "popular",
                  **kwargs) -> PaginationIterator[TraktList]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_lists",
                        **kwargs,
                        type=type,
                        sort=sort,
                        id=id,
                        season=season)

    def get_ratings(self, *, show: Union[Show, str,
                                         int], season: Union[Season, str, int],
                    **kwargs) -> RatingsSummary:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_ratings", **kwargs, id=id, season=season)

    def get_stats(self, *, show: Union[Show, str,
                                       int], season: Union[Season, str, int],
                  **kwargs) -> SeasonEpisodeStats:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_stats", **kwargs, id=id, season=season)

    def get_users_watching(self, *, show: Union[Show, str, int],
                           season: Union[Season, str,
                                         int], **kwargs) -> List[User]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        return self.run("get_users_watching", **kwargs, id=id, season=season)
Ejemplo n.º 17
0
class CommentsI(SuiteInterface):
    name = "comments"

    paths = {
        "post_comment": Path(
            "comments",
            CommentResponse,
            methods=["POST"],
            validators=[AuthRequiredValidator(), COMMENT_TEXT_VALIDATOR],
        ),
        "get_comment": Path("comments/!id", Comment, validators=[COMMENT_ID_VALIDATOR]),
        "update_comment": Path(
            "comments/!id",
            Comment,
            methods="PUT",
            validators=[COMMENT_ID_VALIDATOR, COMMENT_TEXT_VALIDATOR],
        ),
        "delete_comment": Path(
            "comments/!id", {}, methods="DELETE", validators=[COMMENT_ID_VALIDATOR]
        ),
        "get_replies": Path(
            "comments/!id/replies",
            [Comment],
            validators=[COMMENT_ID_VALIDATOR],
            pagination=True,
        ),
        "post_reply": Path(
            "comments/!id/replies",
            Comment,
            validators=[
                AuthRequiredValidator(),
                COMMENT_ID_VALIDATOR,
                COMMENT_TEXT_VALIDATOR,
            ],
        ),
        "get_item": Path(
            "comments/!id/item",
            CommentItemOnly,
            validators=[COMMENT_ID_VALIDATOR],
            extended=["full"],
        ),
        "get_likes": Path(
            "comments/!id/likes",
            [CommentLiker],
            validators=[COMMENT_ID_VALIDATOR],
            pagination=True,
        ),
        "like_comment": Path(
            "comments/!id/like",
            {},
            methods=["POST"],
            validators=[AuthRequiredValidator(), COMMENT_ID_VALIDATOR],
        ),
        "remove_like": Path(
            "comments/!id/like",
            {},
            methods=["DELETE"],
            validators=[AuthRequiredValidator(), COMMENT_ID_VALIDATOR],
        ),
        "get_trending": Path(
            "comments/trending/?comment_type/?type",
            [CommentAndItem],
            validators=TRENDING_RECENT_UPDATED_VALIDATORS,
            pagination=True,
            extended=["full"],
        ),
        "get_recently_created": Path(
            "comments/recent/?comment_type/?type",
            [CommentAndItem],
            validators=TRENDING_RECENT_UPDATED_VALIDATORS,
            pagination=True,
            extended=["full"],
        ),
        "get_recently_updated": Path(
            "comments/updates/?comment_type/?type",
            [CommentAndItem],
            validators=TRENDING_RECENT_UPDATED_VALIDATORS,
            pagination=True,
            extended=["full"],
        ),
    }

    def post_comment(
        self,
        *,
        item: Union[str, int, Movie, Season, Show, Episode],
        comment: str,
        spoiler: bool = False,
        sharing: Optional[Union[Sharing, Dict[str, bool]]] = None,
        **kwargs
    ) -> CommentResponse:
        body: Dict[str, Union[str, int, Dict[str, bool]]] = {
            "item_id": self._generic_get_id(item),
            "comment": comment,
            "spoiler": spoiler,
        }
        if sharing:
            if isinstance(sharing, Sharing):
                sharing = asdict(sharing)
            body["sharing"] = sharing

        return self.run("post_comment", **kwargs, body=body, comment=comment)

    def get_comment(self, *, id: Union[Comment, str, int], **kwargs) -> Comment:
        id = int(self._generic_get_id(id))
        return self.run("get_comment", **kwargs, id=id)

    def update_comment(
        self,
        *,
        id: Union[Comment, str, int],
        comment: str,
        spoiler: bool = False,
        **kwargs
    ) -> Comment:
        body = {"id": self._generic_get_id(id), "comment": comment, "spoiler": spoiler}
        return self.run("update_comment", **kwargs, body=body, id=id, comment=comment)

    def delete_comment(self, *, id: Union[Comment, str, int], **kwargs) -> None:
        id = int(self._generic_get_id(id))
        self.run("delete_comment", **kwargs, id=id)

    def get_replies(
        self, *, id: Union[Comment, str, int], **kwargs
    ) -> PaginationIterator[Comment]:
        id = int(self._generic_get_id(id))
        return self.run("get_replies", **kwargs, id=id)

    def post_reply(
        self,
        *,
        id: Union[Comment, str, int],
        comment: str,
        spoiler: bool = False,
        **kwargs
    ) -> PaginationIterator[Comment]:
        id = int(self._generic_get_id(id))

        body = {"comment": comment, "spoiler": spoiler}

        return self.run("post_reply", **kwargs, id=id, body=body, comment=comment)

    def get_item(self, *, id: Union[Comment, str, int], **kwargs) -> CommentItemOnly:
        id = int(self._generic_get_id(id))
        return self.run("get_item", **kwargs, id=id)

    def get_likes(
        self, *, id: Union[Comment, str, int], **kwargs
    ) -> List[CommentLiker]:
        id = int(self._generic_get_id(id))
        return self.run("get_likes", **kwargs, id=id)

    def like_comment(self, *, id: Union[Comment, str, int], **kwargs) -> None:
        id = int(self._generic_get_id(id))
        self.run("like_comment", **kwargs, id=id)

    def remove_like(self, *, id: Union[Comment, str, int], **kwargs) -> None:
        id = int(self._generic_get_id(id))
        self.run("remove_like", **kwargs, id=id)

    def get_trending(
        self,
        *,
        comment_type: str = "all",
        type: str = "all",
        include_replies: bool = False,
        **kwargs
    ) -> List[CommentAndItem]:
        return self.run(
            "get_trending",
            **kwargs,
            comment_type=comment_type,
            type=type,
            include_replies=include_replies
        )

    def get_recently_created(
        self,
        *,
        comment_type: str = "all",
        type: str = "all",
        include_replies: bool = False,
        **kwargs
    ) -> List[CommentAndItem]:
        return self.run(
            "get_recently_created",
            **kwargs,
            comment_type=comment_type,
            type=type,
            include_replies=include_replies
        )

    def get_recently_updated(
        self,
        *,
        comment_type: str = "all",
        type: str = "all",
        include_replies: bool = False,
        **kwargs
    ) -> List[CommentAndItem]:
        return self.run(
            "get_recently_updated",
            **kwargs,
            comment_type=comment_type,
            type=type,
            include_replies=include_replies
        )
Ejemplo n.º 18
0
 def _make_path(self, resource_path: str, return_type: Any) -> Path:
     return Path(
         self.name + "/" + resource_path,
         return_type,
         validators=[AuthRequiredValidator(), PROGRESS_VALIDATOR],
     )
Ejemplo n.º 19
0
class MoviesI(SuiteInterface):
    name = "movies"

    base_paths = {
        "get_trending": ["trending", [TrendingMovie]],
        "get_popular": ["popular", [Movie]],
        "get_most_played": ["played/?period", [MovieWithStats]],
        "get_most_watched": ["watched/?period", [MovieWithStats]],
        "get_most_collected": ["collected/?period", [MovieWithStats]],
        "get_most_anticipated": ["anticipated", [AnticipatedMovie]],
    }

    paths = {
        "get_box_office":
        Path("movies/boxoffice", [BoxOffice],
             extended=["full"],
             cache_level="basic"),
        "get_recently_updated":
        Path(
            "movies/updates/?start_date",
            [UpdatedMovie],
            extended=["full"],
            pagination=True,
            validators=[PerArgValidator("start_date", is_date)],
        ),
        "get_summary":
        Path("movies/!id", Movie, extended=["full"], cache_level="basic"),
        "get_aliases":
        Path("movies/!id/aliases", [Alias], cache_level="basic"),
        "get_releases":
        Path(
            "movies/!id/releases/?country",
            [MovieRelease],
            validators=[
                PerArgValidator("country",
                                lambda c: isinstance(c, str) and len(c) == 2)
            ],
            cache_level="basic",
        ),
        "get_translations":
        Path(
            "movies/!id/translations/?language",
            [MovieTranslation],
            validators=[
                PerArgValidator("language",
                                lambda c: isinstance(c, str) and len(c) == 2)
            ],
            cache_level="basic",
        ),
        "get_comments":
        Path(
            "movies/!id/comments/?sort",
            [Comment],
            validators=[
                PerArgValidator("sort", lambda s: s in COMMENT_SORT_VALUES)
            ],
            pagination=True,
        ),
        "get_lists":
        Path(
            "movies/!id/lists/?type/?sort",
            [TraktList],
            validators=[
                PerArgValidator("type", lambda t: t in LIST_TYPE_VALUES),
                PerArgValidator("sort", lambda s: s in LIST_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_people":
        Path("movies/!id/people",
             CastCrewList,
             extended=["full"],
             cache_level="basic"),
        "get_ratings":
        Path("movies/!id/ratings", RatingsSummary),
        "get_related":
        Path(
            "movies/!id/related",
            [Movie],
            extended=["full"],
            pagination=True,
            cache_level="basic",
        ),
        "get_stats":
        Path("movies/!id/stats", MovieStats),
        "get_users_watching":
        Path("movies/!id/watching", [User], extended=["full"]),
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for k, r in self.base_paths.items():
            self.paths[k] = self._make_path(*r)

    def _make_path(self, resource_path: str, return_type: Any) -> Path:
        extra_validators: List[Validator] = []
        if "?period" in resource_path:
            extra_validators.append(
                PerArgValidator("period", lambda p: p in PERIOD_VALUES))

        return Path(
            self.name + "/" + resource_path,
            return_type,
            extended=["full"],
            filters=COMMON_FILTERS,
            pagination=True,
            validators=extra_validators,
        )

    def get_trending(self, **kwargs) -> PaginationIterator[TrendingMovie]:
        return self.run("get_trending", **kwargs)

    def get_popular(self, **kwargs) -> PaginationIterator[Movie]:
        return self.run("get_popular", **kwargs)

    def get_most_played(self,
                        *,
                        period: str = "weekly",
                        **kwargs) -> PaginationIterator[MovieWithStats]:
        return self.run("get_most_played", **kwargs, period=period)

    def get_most_watched(self,
                         *,
                         period: str = "weekly",
                         **kwargs) -> PaginationIterator[MovieWithStats]:
        return self.run("get_most_watched", **kwargs, period=period)

    def get_most_collected(self,
                           *,
                           period: str = "weekly",
                           **kwargs) -> PaginationIterator[MovieWithStats]:
        return self.run("get_most_collected", **kwargs, period=period)

    def get_most_anticipated(self,
                             **kwargs) -> PaginationIterator[AnticipatedMovie]:
        return self.run("get_most_anticipated", **kwargs)

    def get_box_office(self, **kwargs) -> List[BoxOffice]:
        return self.run("get_box_office", **kwargs)

    def get_recently_updated(self,
                             *,
                             start_date: Optional[str] = None,
                             **kwargs) -> PaginationIterator[UpdatedMovie]:
        return self.run("get_recently_updated",
                        **kwargs,
                        start_date=start_date)

    def get_summary(self, *, movie: Union[Movie, str, int], **kwargs) -> Movie:
        movie_id = self._get_movie_id(movie)
        return self.run("get_summary", **kwargs, id=movie_id)

    def get_aliases(self, *, movie: Union[Movie, str, int],
                    **kwargs) -> List[Alias]:
        movie_id = self._get_movie_id(movie)
        return self.run("get_aliases", **kwargs, id=movie_id)

    def get_releases(self,
                     *,
                     movie: Union[Movie, str, int],
                     country: Optional[str] = None,
                     **kwargs) -> List[MovieRelease]:
        extra_kwargs = {"id": self._get_movie_id(movie)}
        if country:
            extra_kwargs["country"] = country

        return self.run("get_releases", **kwargs, **extra_kwargs)

    def get_translations(self,
                         *,
                         movie: Union[Movie, str, int],
                         language: Optional[str] = None,
                         **kwargs) -> List[MovieTranslation]:
        extra_kwargs = {"id": self._get_movie_id(movie)}
        if language:
            extra_kwargs["language"] = language

        return self.run("get_translations", **kwargs, **extra_kwargs)

    def get_comments(self,
                     *,
                     movie: Union[Movie, str, int],
                     sort: str = "newest",
                     **kwargs) -> PaginationIterator[Comment]:
        movie_id = self._get_movie_id(movie)
        return self.run("get_comments", **kwargs, sort=sort, id=movie_id)

    def get_lists(self,
                  *,
                  movie: Union[Movie, str, int],
                  type: str = "personal",
                  sort: str = "popular",
                  **kwargs) -> PaginationIterator[TraktList]:
        movie_id = self._get_movie_id(movie)
        return self.run("get_lists",
                        **kwargs,
                        type=type,
                        sort=sort,
                        id=movie_id)

    def get_people(self, *, movie: Union[Movie, str, int],
                   **kwargs) -> CastCrewList:
        return self.run("get_people", **kwargs, id=self._get_movie_id(movie))

    def get_ratings(self, *, movie: Union[Movie, str, int],
                    **kwargs) -> RatingsSummary:
        return self.run("get_ratings", **kwargs, id=self._get_movie_id(movie))

    def get_related(self, *, movie: Union[Movie, str, int],
                    **kwargs) -> PaginationIterator[Movie]:
        return self.run("get_related", **kwargs, id=self._get_movie_id(movie))

    def get_stats(self, *, movie: Union[Movie, str, int],
                  **kwargs) -> MovieStats:
        return self.run("get_stats", **kwargs, id=self._get_movie_id(movie))

    def get_users_watching(self, *, movie: Union[Movie, str, int],
                           **kwargs) -> List[User]:
        return self.run("get_users_watching",
                        **kwargs,
                        id=self._get_movie_id(movie))

    def _get_movie_id(self, movie: Union[Movie, str, int]) -> str:
        return str(self._generic_get_id(movie))
Ejemplo n.º 20
0
def test_aliases():
    p = Path("a/b/c", {}, aliases=["", "xyz"])

    assert p.does_match("xyz")
    assert p.does_match("")
    assert not p.does_match("a")
Ejemplo n.º 21
0
class ShowsI(SuiteInterface):
    name = "shows"

    base_paths = {
        "get_trending": ["trending", [TrendingShow]],
        "get_popular": ["popular", [Show]],
        "get_most_played": ["played/?period", [ShowWithStats]],
        "get_most_watched": ["watched/?period", [ShowWithStats]],
        "get_most_collected": ["collected/?period", [ShowWithStats]],
        "get_most_anticipated": ["anticipated", [AnticipatedShow]],
    }

    paths = {
        "get_recently_updated":
        Path(
            "shows/updates/?start_date",
            [UpdatedShow],
            extended=["full"],
            pagination=True,
            validators=[PerArgValidator("start_date", is_date)],
        ),
        "get_summary":
        Path(
            "shows/!id",
            Show,
            extended=["full"],
            validators=[ID_VALIDATOR],
            cache_level="basic",
        ),
        "get_aliases":
        Path("shows/!id/aliases", [Alias],
             validators=[ID_VALIDATOR],
             cache_level="basic"),
        "get_translations":
        Path(
            "shows/!id/translations/?language",
            [ShowTranslation],
            validators=[
                ID_VALIDATOR,
                PerArgValidator("language",
                                lambda c: isinstance(c, str) and len(c) == 2),
            ],
            cache_level="basic",
        ),
        "get_comments":
        Path(
            "shows/!id/comments/?sort",
            [Comment],
            validators=[
                ID_VALIDATOR,
                PerArgValidator("sort", lambda s: s in COMMENT_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_lists":
        Path(
            "shows/!id/lists/?type/?sort",
            [TraktList],
            validators=[
                ID_VALIDATOR,
                PerArgValidator("type", lambda t: t in LIST_TYPE_VALUES),
                PerArgValidator("sort", lambda s: s in LIST_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_collection_progress":
        Path(
            "shows/!id/progress/collection",
            ShowCollectionProgress,
            validators=PROGRESS_VALIDATORS,
            qargs=["hidden", "specials", "count_specials", "last_activity"],
        ),
        "get_watched_progress":
        Path(
            "shows/!id/progress/watched",
            ShowWatchedProgress,
            validators=PROGRESS_VALIDATORS,
            qargs=["hidden", "specials", "count_specials", "last_activity"],
        ),
        "get_people":
        Path(
            "shows/!id/people",
            CastCrewList,
            extended=["full"],
            validators=[ID_VALIDATOR],
            cache_level="basic",
        ),
        "get_ratings":
        Path("shows/!id/ratings", RatingsSummary, validators=[ID_VALIDATOR]),
        "get_related":
        Path(
            "shows/!id/related",
            [Show],
            extended=["full"],
            pagination=True,
            validators=[ID_VALIDATOR],
            cache_level="basic",
        ),
        "get_stats":
        Path("shows/!id/stats", ShowStats, validators=[ID_VALIDATOR]),
        "get_users_watching":
        Path("shows/!id/watching", [User],
             extended=["full"],
             validators=[ID_VALIDATOR]),
        "get_next_episode":
        Path(
            "shows/!id/next_episode",
            Union[Episode, Dict[str, Any]],
            extended=["full"],
            validators=[ID_VALIDATOR],
        ),
        "get_last_episode":
        Path(
            "shows/!id/last_episode",
            Union[Episode, Dict[str, Any]],
            extended=["full"],
            validators=[ID_VALIDATOR],
        ),
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for k, r in self.base_paths.items():
            self.paths[k] = self._make_path(*r)

    def _make_path(self, resource_path: str, return_type: Any) -> Path:
        extra_validators: List[Validator] = []
        if "?period" in resource_path:
            extra_validators.append(
                PerArgValidator("period", lambda p: p in PERIOD_VALUES))

        return Path(
            self.name + "/" + resource_path,
            return_type,
            extended=["full"],
            filters=COMMON_FILTERS | SHOWS_FILTERS,
            pagination=True,
            validators=extra_validators,
        )

    def get_trending(self, **kwargs) -> PaginationIterator[TrendingShow]:
        return self.run("get_trending", **kwargs)

    def get_popular(self, **kwargs) -> PaginationIterator[Show]:
        return self.run("get_popular", **kwargs)

    def get_most_played(self,
                        *,
                        period: str = "weekly",
                        **kwargs) -> PaginationIterator[ShowWithStats]:
        return self.run("get_most_played", **kwargs, period=period)

    def get_most_watched(self,
                         *,
                         period: str = "weekly",
                         **kwargs) -> PaginationIterator[ShowWithStats]:
        return self.run("get_most_watched", **kwargs, period=period)

    def get_most_collected(self,
                           *,
                           period: str = "weekly",
                           **kwargs) -> PaginationIterator[ShowWithStats]:
        return self.run("get_most_collected", **kwargs, period=period)

    def get_most_anticipated(self,
                             **kwargs) -> PaginationIterator[AnticipatedShow]:
        return self.run("get_most_anticipated", **kwargs)

    def get_recently_updated(self,
                             *,
                             start_date: Optional[str] = None,
                             **kwargs) -> PaginationIterator[UpdatedShow]:
        return self.run("get_recently_updated",
                        **kwargs,
                        start_date=start_date)

    def get_summary(self, *, show: Union[Show, str, int],
                    **kwargs) -> PaginationIterator[Show]:
        id = self._generic_get_id(show)
        return self.run("get_summary", **kwargs, id=id)

    def get_aliases(self, *, show: Union[Show, str, int],
                    **kwargs) -> List[Alias]:
        id = self._generic_get_id(show)
        return self.run("get_aliases", **kwargs, id=id)

    def get_translations(self,
                         *,
                         show: Union[Show, str, int],
                         language: Optional[str] = None,
                         **kwargs) -> List[ShowTranslation]:
        extra_kwargs = {"id": self._generic_get_id(show)}
        if language:
            extra_kwargs["language"] = language

        return self.run("get_translations", **kwargs, **extra_kwargs)

    def get_comments(self,
                     *,
                     show: Union[Show, str, int],
                     sort: str = "newest",
                     **kwargs) -> PaginationIterator[Comment]:
        id = self._generic_get_id(show)
        return self.run("get_comments", **kwargs, sort=sort, id=id)

    def get_lists(self,
                  *,
                  show: Union[Show, str, int],
                  type: str = "personal",
                  sort: str = "popular",
                  **kwargs) -> PaginationIterator[TraktList]:
        id = self._generic_get_id(show)
        return self.run("get_lists", **kwargs, type=type, sort=sort, id=id)

    def get_collection_progress(self,
                                *,
                                show: Union[Show, str, int],
                                hidden: bool = False,
                                specials: bool = False,
                                count_specials: bool = True,
                                **kwargs) -> ShowCollectionProgress:
        return self.run("get_collection_progress",
                        **kwargs,
                        id=self._generic_get_id(show),
                        hidden=hidden,
                        specials=specials,
                        count_specials=count_specials)

    def get_watched_progress(self,
                             *,
                             show: Union[Show, str, int],
                             hidden: bool = False,
                             specials: bool = False,
                             count_specials: bool = True,
                             **kwargs) -> ShowCollectionProgress:
        return self.run("get_watched_progress",
                        **kwargs,
                        id=self._generic_get_id(show),
                        hidden=hidden,
                        specials=specials,
                        count_specials=count_specials)

    def get_people(self, *, show: Union[Show, str, int],
                   **kwargs) -> CastCrewList:
        return self.run("get_people", **kwargs, id=self._generic_get_id(show))

    def get_ratings(self, *, show: Union[Show, str, int],
                    **kwargs) -> RatingsSummary:
        return self.run("get_ratings", **kwargs, id=self._generic_get_id(show))

    def get_related(self, *, show: Union[Show, str, int],
                    **kwargs) -> PaginationIterator[Show]:
        return self.run("get_related", **kwargs, id=self._generic_get_id(show))

    def get_stats(self, *, show: Union[Show, str, int], **kwargs) -> ShowStats:
        return self.run("get_stats", **kwargs, id=self._generic_get_id(show))

    def get_users_watching(self, *, show: Union[Show, str, int],
                           **kwargs) -> List[User]:
        return self.run("get_users_watching",
                        **kwargs,
                        id=self._generic_get_id(show))

    def get_next_episode(self, *, show: Union[Show, str, int],
                         **kwargs) -> Optional[Episode]:
        resp = self.run("get_next_episode",
                        **kwargs,
                        id=self._generic_get_id(show),
                        return_extras=True)

        return None if resp.code == 204 else resp.parsed

    def get_last_episode(self, *, show: Union[Show, str, int],
                         **kwargs) -> Optional[Episode]:
        resp = self.run("get_last_episode",
                        **kwargs,
                        id=self._generic_get_id(show),
                        return_extras=True)

        return None if resp.code == 204 else resp.parsed
Ejemplo n.º 22
0
class PeopleI(SuiteInterface):
    name = "people"

    paths = {
        "get_person":
        Path(
            "people/!id",
            Person,
            validators=[PERSON_ID_VALIDATOR],
            extended=["full"],
            cache_level="basic",
        ),
        "get_movie_credits":
        Path(
            "people/!id/movies",
            MovieCredits,
            validators=[PERSON_ID_VALIDATOR],
            extended=["full"],
            cache_level="basic",
        ),
        "get_show_credits":
        Path(
            "people/!id/shows",
            ShowCredits,
            validators=[PERSON_ID_VALIDATOR],
            extended=["full"],
            cache_level="basic",
        ),
        "get_lists":
        Path(
            "people/!id/lists/?type/?sort",
            [TraktList],
            validators=[
                PERSON_ID_VALIDATOR,
                PerArgValidator("type", lambda t: t in LIST_TYPE_VALUES),
                PerArgValidator("sort", lambda s: s in LIST_SORT_VALUES),
            ],
            extended=["full"],
            cache_level="basic",
        ),
    }

    def get_person(self, person: Union[Person, str, int], **kwargs) -> Person:
        id = self._get_person_id(person)
        return self.run("get_person", **kwargs, id=id)

    def get_movie_credits(self, person: Union[Person, str, int],
                          **kwargs) -> MovieCredits:
        id = self._get_person_id(person)
        return self.run("get_movie_credits", **kwargs, id=id)

    def get_show_credits(self, person: Union[Person, str, int],
                         **kwargs) -> ShowCredits:
        id = self._get_person_id(person)
        return self.run("get_show_credits", **kwargs, id=id)

    def get_lists(self, person: Union[Person, str, int],
                  **kwargs) -> List[TraktList]:
        id = self._get_person_id(person)
        return self.run("get_lists", **kwargs, id=id)

    def _get_person_id(self, p: Union[Person, int, str]) -> str:
        return str(self._generic_get_id(item=p))
Ejemplo n.º 23
0
def test_extended():
    client = Trakt("", "")

    p = Path("a", {}, extended=["full"])

    assert p.is_valid(client)
    assert p.is_valid(client, extended="full")
    assert p.is_valid(client, extended=True)

    with pytest.raises(ArgumentError):
        p.is_valid(client, extended="meta")

    p.is_valid(client, extended=True)
    _, quargs = p.get_path_and_qargs()
    assert "extended" in quargs and quargs["extended"] == "full"

    p = Path("a", {})
    p.is_valid(client)
    _, quargs = p.get_path_and_qargs()
    assert "extended" not in quargs
Ejemplo n.º 24
0
class SearchI(SuiteInterface):
    name = "search"

    paths = {
        "text_query":
        Path(  # type: ignore
            "search/!type",
            [SearchResult],
            extended=["full"],
            filters=ALL_FILTERS,
            pagination=True,
            validators=[
                PerArgValidator(
                    "type",
                    lambda t: all(x in MEDIA_TYPES for x in t.split(","))),
                PerArgValidator("query", lambda q: isinstance(q, str) and q),
                PerArgValidator(
                    "fields",
                    lambda f: all(x in POSSIBLE_FIELDS for x in f.split(","))),
            ],
            qargs=["fields"],
            cache_level="basic",
        ),
        "id_lookup":
        Path(  # type: ignore
            "search/!id_type/!id",
            [SearchResult],
            extended=["full"],
            filters=ALL_FILTERS,
            pagination=True,
            validators=[
                PerArgValidator("id", lambda t: isinstance(t, (int, str))),
                PerArgValidator("id_type", lambda it: it in ID_TYPES),
                PerArgValidator(
                    "type",
                    lambda f: all(x in MEDIA_TYPES for x in f.split(","))),
            ],
            qargs=["type"],
            cache_level="basic",
        ),
    }

    def text_query(self,
                   type: Union[str, List[str]],
                   query: str,
                   fields: Optional[Union[str, List[str]]] = None,
                   **kwargs) -> PaginationIterator[SearchResult]:
        type = [type] if isinstance(type, str) else type
        type = ",".join(type)
        req = {"type": type, "query": query}

        if fields:
            fields = [fields] if isinstance(fields, str) else fields
            req["fields"] = ",".join(fields)

        return self.run("text_query", **kwargs, **req)

    def id_lookup(self,
                  id_type: str,
                  id: Union[str, int],
                  type: Optional[Union[str, List[str]]] = None,
                  **kwargs) -> PaginationIterator[SearchResult]:
        req = {"id_type": id_type, "id": id}

        if type:
            type = [type] if isinstance(type, str) else type
            req["type"] = ",".join(type)

        return self.run("id_lookup", **kwargs, **req)
Ejemplo n.º 25
0
def test_filters():
    client = Trakt("", "")
    p = Path("a", {})

    with pytest.raises(ArgumentError):
        p.is_valid(client, genres="genre")

    p = Path("a", {}, filters={"query", "genres"})

    assert p.is_valid(client, query="xyz")

    with pytest.raises(ArgumentError):
        p.is_valid(client, query=["xyz", "abc"])

    assert p.is_valid(client, genres="genre")
    assert p.is_valid(client, genres=["abc", "xyz"])

    with pytest.raises(ArgumentError):
        p.is_valid(client, query=[100, "abc"])
Ejemplo n.º 26
0
class EpisodesI(SuiteInterface):
    name = "episodes"

    paths = {
        "get_episode": Path(
            "shows/!id/seasons/!season/episodes/!episode",
            Episode,
            extended=["full"],
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR, EPISODE_ID_VALIDATOR],
        ),
        "get_translations": Path(
            "shows/!id/seasons/!season/episodes/!episode/translations/?language",
            [EpisodeTranslation],
            validators=[
                ID_VALIDATOR,
                SEASON_ID_VALIDATOR,
                EPISODE_ID_VALIDATOR,
                PerArgValidator("language", lambda s: isinstance(s, str)),
            ],
        ),
        "get_comments": Path(
            "shows/!id/seasons/!season/episodes/!episode/comments/?sort",
            [Comment],
            validators=[
                ID_VALIDATOR,
                SEASON_ID_VALIDATOR,
                EPISODE_ID_VALIDATOR,
                PerArgValidator("sort", lambda s: s in COMMENT_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_lists": Path(
            "shows/!id/seasons/!season/episodes/!episode/lists/?type/?sort",
            [TraktList],
            validators=[
                ID_VALIDATOR,
                SEASON_ID_VALIDATOR,
                EPISODE_ID_VALIDATOR,
                PerArgValidator("type", lambda t: t in LIST_TYPE_VALUES),
                PerArgValidator("sort", lambda s: s in LIST_SORT_VALUES),
            ],
            pagination=True,
        ),
        "get_ratings": Path(
            "shows/!id/seasons/!season/episodes/!episode/ratings",
            RatingsSummary,
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR, EPISODE_ID_VALIDATOR],
        ),
        "get_stats": Path(
            "shows/!id/seasons/!season/episodes/!episode/stats",
            SeasonEpisodeStats,
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR, EPISODE_ID_VALIDATOR],
        ),
        "get_users_watching": Path(
            "shows/!id/seasons/!season/episodes/!episode/watching",
            [User],
            extended=["full"],
            validators=[ID_VALIDATOR, SEASON_ID_VALIDATOR, EPISODE_ID_VALIDATOR],
        ),
    }

    def get_episode(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        **kwargs
    ) -> Season:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run("get_episode", **kwargs, id=id, season=season, episode=episode)

    def get_comments(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        sort: str = "newest",
        **kwargs
    ) -> PaginationIterator[Comment]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run(
            "get_comments", **kwargs, sort=sort, id=id, season=season, episode=episode
        )

    def get_translations(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        sort: str = "newest",
        **kwargs
    ) -> List[Comment]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run(
            "get_translations",
            **kwargs,
            sort=sort,
            id=id,
            season=season,
            episode=episode
        )

    def get_lists(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        type: str = "personal",
        sort: str = "popular",
        **kwargs
    ) -> PaginationIterator[TraktList]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run(
            "get_lists",
            **kwargs,
            type=type,
            sort=sort,
            id=id,
            season=season,
            episode=episode
        )

    def get_ratings(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        **kwargs
    ) -> RatingsSummary:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run("get_ratings", **kwargs, id=id, season=season, episode=episode)

    def get_stats(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        **kwargs
    ) -> SeasonEpisodeStats:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run("get_stats", **kwargs, id=id, season=season, episode=episode)

    def get_users_watching(
        self,
        *,
        show: Union[Show, str, int],
        season: Union[Season, str, int],
        episode: Union[Episode, int, str],
        **kwargs
    ) -> List[User]:
        id = self._generic_get_id(show)
        season = self._generic_get_id(season)
        episode = self._generic_get_id(episode)
        return self.run(
            "get_users_watching", **kwargs, id=id, season=season, episode=episode
        )