diff --git a/README.md b/README.md index 9e091c5..9ce3b58 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@

![fastanime](https://github.com/user-attachments/assets/9ab09f26-e4a8-4b70-a315-7def998cec63) +
V3 teaser diff --git a/fastanime/assets/graphql/anilist/queries/media-recommendations.gql b/fastanime/assets/graphql/anilist/queries/media-recommendations.gql index 71ffacf..efe62c4 100644 --- a/fastanime/assets/graphql/anilist/queries/media-recommendations.gql +++ b/fastanime/assets/graphql/anilist/queries/media-recommendations.gql @@ -21,7 +21,7 @@ query ($id: Int, $page: Int, $per_page: Int) { } description episodes - duration # Added duration here + duration trailer { site id diff --git a/fastanime/assets/graphql/anilist/queries/media-relations.gql b/fastanime/assets/graphql/anilist/queries/media-relations.gql index 2bf038f..484c83f 100644 --- a/fastanime/assets/graphql/anilist/queries/media-relations.gql +++ b/fastanime/assets/graphql/anilist/queries/media-relations.gql @@ -1,5 +1,5 @@ -query ($id: Int) { - Media(id: $id) { +query ($id: Int, $format_not_in: [MediaFormat]) { + Media(id: $id, format_not_in: $format_not_in) { relations { nodes { id diff --git a/fastanime/libs/media_api/anilist/api.py b/fastanime/libs/media_api/anilist/api.py index a935956..ca0483f 100644 --- a/fastanime/libs/media_api/anilist/api.py +++ b/fastanime/libs/media_api/anilist/api.py @@ -1,6 +1,6 @@ import logging from enum import Enum -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional from httpx import Client @@ -214,42 +214,29 @@ class AniListApi(BaseApiClient): variables = { "id": params.id, "page": params.page, - "per_page": params.per_page or self.config.per_page, + "per_page": params.per_page or 50, } response = execute_graphql( ANILIST_ENDPOINT, self.http_client, gql.GET_MEDIA_RECOMMENDATIONS, variables ) - if response and response.json(): - try: - return mapper.to_generic_recommendations(response.json()) - except Exception as e: - logger.error( - f"Error mapping recommendations for media {params.id}: {e}" - ) - return None - return None + return mapper.to_generic_recommendations(response.json()) def get_characters_of(self, params: MediaCharactersParams) -> Optional[Dict]: variables = {"id": params.id, "type": "ANIME"} response = execute_graphql( ANILIST_ENDPOINT, self.http_client, gql.GET_MEDIA_CHARACTERS, variables ) - return response.json() if response else None + # TODO: standardize character type + return response.json() def get_related_anime_for( self, params: MediaRelationsParams ) -> Optional[List[MediaItem]]: - variables = {"id": params.id} + variables = {"id": params.id, "format_in": None} response = execute_graphql( ANILIST_ENDPOINT, self.http_client, gql.GET_MEDIA_RELATIONS, variables ) - if response and response.json(): - try: - return mapper.to_generic_relations(response.json()) - except Exception as e: - logger.error(f"Error mapping relations: {e}") - return None - return None + return mapper.to_generic_relations(response.json()) def get_airing_schedule_for( self, params: MediaAiringScheduleParams @@ -258,15 +245,16 @@ class AniListApi(BaseApiClient): response = execute_graphql( ANILIST_ENDPOINT, self.http_client, gql.GET_AIRING_SCHEDULE, variables ) - return response.json() if response else None + # TODO: standardize airing schedule type + return response.json() - def transform_raw_search_data(self, raw_data: Dict) -> Optional[MediaSearchResult]: + def transform_raw_search_data(self, raw_data: Any) -> Optional[MediaSearchResult]: """ Transform raw AniList API response data into a MediaSearchResult. - + Args: raw_data: Raw response data from the AniList GraphQL API - + Returns: MediaSearchResult object or None if transformation fails """ diff --git a/fastanime/libs/media_api/anilist/mapper.py b/fastanime/libs/media_api/anilist/mapper.py index 695a2fe..43cb6c8 100644 --- a/fastanime/libs/media_api/anilist/mapper.py +++ b/fastanime/libs/media_api/anilist/mapper.py @@ -222,7 +222,7 @@ def _to_generic_media_item( type=data.get("type", "ANIME"), title=_to_generic_media_title(data["title"]), status=status_map[data["status"]], - format=MediaFormat(data["format"]), + format=MediaFormat(data["format"]) if data["format"] else None, cover_image=_to_generic_media_image(data["coverImage"]), banner_image=data.get("bannerImage"), trailer=_to_generic_media_trailer(data["trailer"]), diff --git a/fastanime/libs/media_api/types.py b/fastanime/libs/media_api/types.py index 72a749c..99aaeb2 100644 --- a/fastanime/libs/media_api/types.py +++ b/fastanime/libs/media_api/types.py @@ -56,6 +56,7 @@ class MediaFormat(Enum): TV = "TV" TV_SHORT = "TV_SHORT" MOVIE = "MOVIE" + MANGA = "MANGA" SPECIAL = "SPECIAL" OVA = "OVA" ONA = "ONA" @@ -143,7 +144,7 @@ class MediaItem(BaseMediaApiModel): id_mal: Optional[int] = None type: MediaType = MediaType.ANIME status: MediaStatus = MediaStatus.FINISHED - format: MediaFormat = MediaFormat.TV + format: Optional[MediaFormat] = MediaFormat.TV cover_image: Optional[MediaImage] = None banner_image: Optional[str] = None