From 7e1da4393e0abf1ad084c3ef9e06aa7b681934be Mon Sep 17 00:00:00 2001 From: wumode Date: Mon, 26 May 2025 00:32:29 +0800 Subject: [PATCH] =?UTF-8?q?imdbsource:=20=E4=BC=98=E5=8C=96=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.v2.json | 1 + plugins.v2/imdbsource/__init__.py | 33 ++++++++++++++++++---------- plugins.v2/imdbsource/imdb_helper.py | 33 +++++++++++++++++++--------- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/package.v2.json b/package.v2.json index 8abacc5..4a12315 100644 --- a/package.v2.json +++ b/package.v2.json @@ -429,6 +429,7 @@ "author": "wumode", "level": 1, "history": { + "v1.3": "优化网络连接", "v1.2": "推荐热门纪录片", "v1.1": "推荐支持IMDB数据源; 优化海报尺寸,减少卡顿", "v1.0": "探索支持IMDb数据源" diff --git a/plugins.v2/imdbsource/__init__.py b/plugins.v2/imdbsource/__init__.py index 2466cd2..817dd45 100644 --- a/plugins.v2/imdbsource/__init__.py +++ b/plugins.v2/imdbsource/__init__.py @@ -24,7 +24,7 @@ class ImdbSource(_PluginBase): plugin_icon = ("https://raw.githubusercontent.com/jxxghp/" "MoviePilot-Plugins/refs/heads/main/icons/IMDb_IOS-OSX_App.png") # 插件版本 - plugin_version = "1.2" + plugin_version = "1.3" # 插件作者 plugin_author = "wumode" # 作者主页 @@ -347,7 +347,7 @@ class ImdbSource(_PluginBase): return [] if not self._imdb_helper: return [] - title_types = ("tvSeries", "tvMiniSeries", "tvShort", "tvEpisode", 'movie') + title_types = ("tvSeries", "tvMiniSeries", "tvShort", 'movie') first_page = False if page == 1: first_page = True @@ -403,8 +403,8 @@ class ImdbSource(_PluginBase): self._cache["imdb_top_250"] = [] # 清空缓存 data = self._imdb_helper.advanced_title_search(first_page=first_page, title_types=title_types, - sort_by="POPULARITY", - sort_order="ASC", + sort_by="USER_RATING", + sort_order="DESC", ranked=("TOP_RATED_MOVIES-250",) ) if not data: @@ -427,7 +427,7 @@ class ImdbSource(_PluginBase): return [] if not self._imdb_helper: return [] - title_types = ("tvSeries", "tvMiniSeries", "tvShort", "tvEpisode") + title_types = ("tvSeries", "tvMiniSeries", "tvShort") first_page = False if page == 1: first_page = True @@ -466,7 +466,7 @@ class ImdbSource(_PluginBase): return [] if not self._imdb_helper: return [] - title_types = ("tvSeries", "tvMiniSeries", "tvShort", "tvEpisode", 'movie') + title_types = ("tvSeries", "tvMiniSeries", "tvShort", 'movie') first_page = False if page == 1: first_page = True @@ -507,7 +507,7 @@ class ImdbSource(_PluginBase): return [] if not self._imdb_helper: return [] - title_types = ("tvSeries", "tvMiniSeries", "tvShort", "tvEpisode", 'movie') + title_types = ("tvSeries", "tvMiniSeries", "tvShort", 'movie') first_page = False if page == 1: first_page = True @@ -559,7 +559,7 @@ class ImdbSource(_PluginBase): return [] if not self._imdb_helper: return [] - title_type = ("tvSeries", "tvMiniSeries", "tvShort", "tvEpisode") + title_type = ("tvSeries", "tvMiniSeries", "tvShort") if mtype == 'movies': title_type = ("movie",) if user_rating and using_rating: @@ -640,11 +640,22 @@ class ImdbSource(_PluginBase): if new_results: results.extend(new_results[:remaining]) self._cache["discover"] = new_results[remaining:] + res = [] if mtype == "movies": - results = [self.__movie_to_media(movie.get('node').get("title")) for movie in results] + for movie in results: + movie_info = movie.get('node').get("title") + pub_status = movie_info.get("productionStatus") + if pub_status and pub_status.get("currentProductionStage"): + if pub_status.get("currentProductionStage", {}).get("id") == 'released': + res.append(self.__movie_to_media(movie_info)) else: - results = [self.__series_to_media(series.get('node').get("title")) for series in results] - return results + for tv in results: + tv_info = tv.get('node').get('title') + pub_status = tv_info.get("productionStatus") + if pub_status and pub_status.get("currentProductionStage"): + if pub_status.get("currentProductionStage", {}).get("id") == 'released': + res.append(self.__series_to_media(tv_info)) + return res def get_api(self) -> List[Dict[str, Any]]: """ diff --git a/plugins.v2/imdbsource/imdb_helper.py b/plugins.v2/imdbsource/imdb_helper.py index 26c39c4..12c1c09 100644 --- a/plugins.v2/imdbsource/imdb_helper.py +++ b/plugins.v2/imdbsource/imdb_helper.py @@ -5,6 +5,7 @@ from collections import OrderedDict from dataclasses import dataclass import graphene +import requests from requests_html import HTMLSession import ijson import json @@ -13,6 +14,7 @@ import base64 from app.log import logger from app.utils.http import RequestUtils from app.utils.string import StringUtils +from app.utils.common import retry from app.schemas.types import MediaType from app.core.cache import cached @@ -35,8 +37,9 @@ class SearchParams: class SearchState: - def __init__(self, last_cursor: str): - self.last_cursor = last_cursor + def __init__(self, pageinfo: dict, total: int): + self.pageinfo = pageinfo + self.total = total class ImdbHelper: @@ -148,8 +151,12 @@ class ImdbHelper: self._proxies = proxies self._session = HTMLSession() self._req_utils = RequestUtils(headers=self._imdb_headers, session=self._session, timeout=10, proxies=proxies) - self._imdb_req = RequestUtils(accept_type="application/json", content_type="application/json", - headers=self._imdb_headers, timeout=10, proxies=proxies) + self._imdb_req = RequestUtils(accept_type="application/json", + content_type="application/json", + headers=self._imdb_headers, + timeout=10, + proxies=proxies, + session=requests.Session()) self._imdb_api_hash = {"AdvancedTitleSearch": None, "TitleAkasPaginated": None} self._search_states = OrderedDict() self._max_states = 30 @@ -231,10 +238,11 @@ class ImdbHelper: section["episodes"]["total"] += section_next.get("episodes", {}).get("total", 0) return section + @retry(Exception, logger=logger) @cached(maxsize=32, ttl=1800) def __request(self, params: Dict, sha256) -> Optional[Dict]: params["extensions"] = {"persistedQuery": {"sha256Hash": sha256, "version": 1}} - ret = self._imdb_req.post_res(f"{self._official_endpoint}", json=params) + ret = self._imdb_req.post_res(f"{self._official_endpoint}", json=params, raise_exception=True) if not ret: return None data = ret.json() @@ -341,11 +349,16 @@ class ImdbHelper: # 获取或创建搜索状态 last_cursor = None if not first_page and params in self._search_states: - search_state = self._search_states.pop(params) # 移除并获取 + search_state: SearchState = self._search_states.pop(params) # 移除并获取 self._search_states[params] = search_state # 不是第一页且已有状态 - 使用上次的结果 - if search_state.last_cursor: - last_cursor = search_state.last_cursor + if not search_state.pageinfo.get("hasNextPage"): + return {'pageInfo': {'endCursor': None, 'hasNextPage': False, 'hasPreviousPage': True, + 'startCursor': None}, + 'edges': [], 'total': search_state.total, 'genres': [], 'keywords': [], + 'titleTypes': [], 'jobCategories': []} + if search_state.pageinfo.get('endCursor'): + last_cursor = search_state.pageinfo.get('endCursor') # 这里实现基于上次结果的逻辑 else: # 重新搜索 @@ -355,8 +368,8 @@ class ImdbHelper: result = self.__advanced_title_search(params, sha256, first_page, last_cursor) if result: page_info = result.get("pageInfo", {}) - end_cursor = page_info.get("endCursor", "") - search_state = SearchState(end_cursor) + total = result.get("total", 0) + search_state = SearchState(page_info, total) self._search_states[params] = search_state if len(self._search_states) > self._max_states: self._search_states.popitem(last=False) # 移除最旧的条目