diff --git a/package.v2.json b/package.v2.json index e676a30..e9c1aba 100644 --- a/package.v2.json +++ b/package.v2.json @@ -453,11 +453,12 @@ "name": "IMDb源", "description": "让探索,推荐和媒体识别支持IMDb数据源。", "labels": "探索", - "version": "1.6.1", + "version": "1.6.2", "icon": "IMDb_IOS-OSX_App.png", "author": "wumode", "level": 1, "history": { + "v1.6.2": "修复 API 查询错误重试问题", "v1.6.1": "添加中文主屏幕组件; 修复 bug", "v1.5.8": "修改UA", "v1.5.7": "改进异常处理", diff --git a/plugins.v2/imdbsource/__init__.py b/plugins.v2/imdbsource/__init__.py index cff85c1..67e7395 100644 --- a/plugins.v2/imdbsource/__init__.py +++ b/plugins.v2/imdbsource/__init__.py @@ -30,7 +30,7 @@ class ImdbSource(_PluginBase): # 插件图标 plugin_icon = "IMDb_IOS-OSX_App.png" # 插件版本 - plugin_version = "1.6.1" + plugin_version = "1.6.2" # 插件作者 plugin_author = "wumode" # 作者主页 diff --git a/plugins.v2/imdbsource/imdbapi.py b/plugins.v2/imdbsource/imdbapi.py index f2ff4f5..b4f79f4 100644 --- a/plugins.v2/imdbsource/imdbapi.py +++ b/plugins.v2/imdbsource/imdbapi.py @@ -35,7 +35,7 @@ class ImdbApiClient: client=self._free_api_client ) - @retry(Exception, logger=logger) + @retry(Exception, logger=logger, delay=1) @cached(maxsize=1024, ttl=CACHE_LIFESPAN) def _free_imdb_api(self, path: str, params: Optional[dict] = None) -> Optional[dict]: r = self._req.get_res(url=f"{self.BASE_URL}{path}", params=params, raise_exception=True) @@ -49,7 +49,7 @@ class ImdbApiClient: return None return r.json() - @retry(Exception, logger=logger) + @retry(Exception, logger=logger, delay=1) @cached(maxsize=1024, ttl=CACHE_LIFESPAN) async def _async_free_imdb_api(self, path: str, params: Optional[dict] = None) -> Optional[dict]: r = await self._async_req.get_res(url=f"{self.BASE_URL}{path}", params=params, raise_exception=True) diff --git a/plugins.v2/imdbsource/officialapi.py b/plugins.v2/imdbsource/officialapi.py index 6ffbb26..0292d5e 100644 --- a/plugins.v2/imdbsource/officialapi.py +++ b/plugins.v2/imdbsource/officialapi.py @@ -13,7 +13,6 @@ from app.utils.http import RequestUtils, AsyncRequestUtils from .schema.imdbtypes import ImdbType from .schema import VerticalList, AdvancedTitleSearchResponse, AdvancedTitleSearch, TitleEdge, SearchParams - INTERESTS_ID: Final[Dict[str, Dict[str, str]]] = { "Action": { "Action": "in0000001", @@ -277,45 +276,45 @@ INTERESTS_ID: Final[Dict[str, Dict[str, str]]] = { } CACHE_LIFETIME: Final[int] = 86400 IMDB_GRAPHQL_QUERY: Final[str] = \ -"""query VerticalListPageItems( $titles: [ID!]! $names: [ID!]! $images: [ID!]! $videos: [ID!]!) { - titles(ids: $titles) { ...TitleParts meterRanking { currentRank meterType rankChange {changeDirection difference} } ratingsSummary { aggregateRating } } - names(ids: $names) { ...NameParts } - videos(ids: $videos) { ...VideoParts } - images(ids: $images) { ...ImageParts } -} -fragment TitleParts on Title { - id - titleText { text } - titleType { id } - releaseYear { year } - akas(first: 50) { edges { node { text country { id text } language { text } } } } - plot { plotText {plainText}} - primaryImage { id url width height } - releaseDate {day month year} - titleGenres {genres {genre { text }}} - certificate { rating } - originalTitleText{ text } - runtime { seconds } -} -fragment NameParts on Name { - id - nameText { text } - primaryImage { id url width height } -} -fragment ImageParts on Image { - id - height - width - url -} -fragment VideoParts on Video { - id - name { value } - contentType { displayName { value } id } - previewURLs { displayName { value } url videoDefinition videoMimeType } - playbackURLs { displayName { value } url videoDefinition videoMimeType } - thumbnail { height url width } -}""" + """query VerticalListPageItems( $titles: [ID!]! $names: [ID!]! $images: [ID!]! $videos: [ID!]!) { + titles(ids: $titles) { ...TitleParts meterRanking { currentRank meterType rankChange {changeDirection difference} } ratingsSummary { aggregateRating } } + names(ids: $names) { ...NameParts } + videos(ids: $videos) { ...VideoParts } + images(ids: $images) { ...ImageParts } + } + fragment TitleParts on Title { + id + titleText { text } + titleType { id } + releaseYear { year } + akas(first: 50) { edges { node { text country { id text } language { text } } } } + plot { plotText {plainText}} + primaryImage { id url width height } + releaseDate {day month year} + titleGenres {genres {genre { text }}} + certificate { rating } + originalTitleText{ text } + runtime { seconds } + } + fragment NameParts on Name { + id + nameText { text } + primaryImage { id url width height } + } + fragment ImageParts on Image { + id + height + width + url + } + fragment VideoParts on Video { + id + name { value } + contentType { displayName { value } id } + previewURLs { displayName { value } url videoDefinition videoMimeType } + playbackURLs { displayName { value } url videoDefinition videoMimeType } + thumbnail { height url width } + }""" class PersistedQueryNotFound(Exception): @@ -332,7 +331,7 @@ class OfficialApiClient: self._req = RequestUtils(accept_type="application/json", content_type="application/json", timeout=10, - ua=None, + ua=ua, proxies=proxies, session=requests.Session()) if proxies: @@ -358,7 +357,7 @@ class OfficialApiClient: return {'error': error} return data.get("data") - @retry(Exception, logger=logger) + @retry(Exception, logger=logger, delay=1) @cached(maxsize=1024, ttl=CACHE_LIFETIME) def _query_graphql(self, query: str, variables: Dict[str, Any]) -> Optional[dict]: params = {'query': query, 'variables': variables} @@ -370,7 +369,7 @@ class OfficialApiClient: return {'error': error} return data.get("data") - @retry(Exception, logger=logger) + @retry(Exception, logger=logger, delay=1) @cached(maxsize=1024, ttl=CACHE_LIFETIME) async def _async_query_graphql(self, query: str, variables: Dict[str, Any]) -> Optional[Dict]: params = {'query': query, 'variables': variables} @@ -438,12 +437,12 @@ class OfficialApiClient: return ret - @retry(Exception, logger=logger) + @retry(Exception, logger=logger, delay=1) async def async_advanced_title_search(self, - params: SearchParams, - sha256: str, - last_cursor: Optional[str] = None, - ) -> Optional[AdvancedTitleSearch]: + params: SearchParams, + sha256: str, + last_cursor: Optional[str] = None, + ) -> Optional[AdvancedTitleSearch]: variables: Dict[str, Any] = {"first": 50, "locale": "en-US", @@ -457,7 +456,7 @@ class OfficialApiClient: if title_type in ImdbType._value2member_map_: title_type_ids.append(title_type) if len(title_type_ids): - variables["titleTypeConstraint"] = {"anyTitleTypeIds": params.title_types} + variables["titleTypeConstraint"] = {"anyTitleTypeIds": title_type_ids} if params.genres: variables["genreConstraint"] = {"allGenreIds": params.genres, "excludeGenreIds": []} if params.countries: @@ -504,11 +503,7 @@ class OfficialApiClient: params = {"operationName": operation_name, "variables": variables} - try: - data = await self._async_request(params, sha256) - except Exception as e: - logger.debug(f"An error occurred while querying {operation_name}: {e}") - return None + data = await self._async_request(params, sha256) if not data: return None if 'error' in data: @@ -525,7 +520,8 @@ class OfficialApiClient: return None return ret.advanced_title_search - async def advanced_title_search_generator(self, params: SearchParams, sha256: str) -> AsyncGenerator[TitleEdge, None]: + async def advanced_title_search_generator(self, params: SearchParams, sha256: str) -> AsyncGenerator[ + TitleEdge, None]: last_cursor = None while True: response = await self.async_advanced_title_search(params, sha256, last_cursor=last_cursor)