diff --git a/package.v2.json b/package.v2.json index 67f8ed2..0908faa 100644 --- a/package.v2.json +++ b/package.v2.json @@ -432,11 +432,12 @@ "name": "绕过Trackers", "description": "提供tracker服务器IP地址列表,帮助IPv6连接绕过OpenClash。", "labels": "工具", - "version": "1.4.2", + "version": "1.4.3", "icon": "Clash_A.png", "author": "wumode", "level": 2, "history": { + "v1.4.3": "修复 bug", "v1.4.2": "修复插件动作", "v1.4.1": "修复通知类型错误", "v1.4": "异步查询DNS", @@ -450,11 +451,12 @@ "name": "IMDb源", "description": "让探索,推荐和媒体识别支持IMDb数据源。", "labels": "探索", - "version": "1.5.6", + "version": "1.5.7", "icon": "IMDb_IOS-OSX_App.png", "author": "wumode", "level": 1, "history": { + "v1.5.7": "改进异常处理", "v1.5.6": "固定仪表盘组件海报比例; 修复 bug", "v1.5.5": "修复初始化错误", "v1.5.4": "改进媒体识别", diff --git a/plugins.v2/imdbsource/__init__.py b/plugins.v2/imdbsource/__init__.py index 91674e8..0109683 100644 --- a/plugins.v2/imdbsource/__init__.py +++ b/plugins.v2/imdbsource/__init__.py @@ -29,7 +29,7 @@ class ImdbSource(_PluginBase): # 插件图标 plugin_icon = "IMDb_IOS-OSX_App.png" # 插件版本 - plugin_version = "1.5.6" + plugin_version = "1.5.7" # 插件作者 plugin_author = "wumode" # 作者主页 @@ -60,7 +60,7 @@ class ImdbSource(_PluginBase): def init_plugin(self, config: dict = None): - plugin_instance = self + plugin_instance: ImdbSource = self def patched_recognize_media(chain_self, meta: MetaBase = None, mtype: Optional[MediaType] = None, @@ -822,6 +822,14 @@ class ImdbSource(_PluginBase): ChainBase.async_recognize_media._patched_by == id(self) and self._original_async_method): ChainBase.async_recognize_media = self._original_async_method + if self._scheduler: + try: + self._scheduler.remove_all_jobs() + if self._scheduler.running: + self._scheduler.shutdown() + self._scheduler = None + except Exception as e: + logger.error(f"退出插件失败:{e}") def get_module(self) -> Dict[str, Any]: """ diff --git a/plugins.v2/imdbsource/imdbhelper.py b/plugins.v2/imdbsource/imdbhelper.py index 46bd1b8..13bab0d 100644 --- a/plugins.v2/imdbsource/imdbhelper.py +++ b/plugins.v2/imdbsource/imdbhelper.py @@ -484,7 +484,11 @@ class ImdbHelper: params = {"operationName": operation_name, "variables": variables} - data = await self._async_request(params, sha256) + 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 if not data: return None if 'error' in data: @@ -530,7 +534,11 @@ class ImdbHelper: 'videos': videos or [], 'isRegistered': is_registered, } - data = self._query_graphql(query, variables) + try: + data = self._query_graphql(query, variables) + except Exception as e: + logger.debug(f"An error occurred while querying VerticalListPageItems: {e}") + return None if 'error' in data: error = data['error'] if error: @@ -602,7 +610,11 @@ class ImdbHelper: 'videos': videos or [], 'isRegistered': is_registered, } - data = await self._async_query_graphql(query, variables) + try: + data = await self._async_query_graphql(query, variables) + except Exception as e: + logger.debug(f"An error occurred while querying VerticalListPageItems: {e}") + return None if 'error' in data: error = data['error'] if error: @@ -650,7 +662,11 @@ class ImdbHelper: params: Dict[str, Any] = {'query': query} if limit: params['limit'] = limit - r = self.__free_imdb_api(path=endpoint, params=params) + try: + r = self.__free_imdb_api(path=endpoint, params=params) + except Exception as e: + logger.debug(f"An error occurred while searching for titles: {e}") + return None if r is None: return None return r.get('titles') @@ -685,7 +701,11 @@ class ImdbHelper: See `curl -X 'GET' 'https://api.imdbapi.dev/titles/tt0944947' -H 'accept: application/json'` """ endpoint = '/titles/%s' - r = self.__free_imdb_api(path=endpoint % title_id) + try: + r = self.__free_imdb_api(path=endpoint % title_id) + except Exception as e: + logger.debug(f"An error occurred while retrieving details: {e}") + return None return r def episodes(self, title_id: str, season: Optional[str] = None, @@ -709,7 +729,11 @@ class ImdbHelper: param['pageSize'] = page_size if page_token is not None: param['pageToken'] = page_token - r = self.__free_imdb_api(path=endpoint % title_id, params=param) + try: + r = self.__free_imdb_api(path=endpoint % title_id, params=param) + except Exception as e: + logger.debug(f"An error occurred while retrieving episodes: {e}") + return None return r def seasons(self, title_id: str) -> Optional[List[dict]]: @@ -722,7 +746,11 @@ class ImdbHelper: {[{"season": "1", "episodeCount": 11}]} """ endpoint = '/titles/%s/seasons' - r = self.__free_imdb_api(path=endpoint % title_id) + try: + r = self.__free_imdb_api(path=endpoint % title_id) + except Exception as e: + logger.debug(f"An error occurred while retrieving seasons: {e}") + return None if r is None: return None return r.get('seasons') @@ -753,7 +781,11 @@ class ImdbHelper: param['pageSize'] = page_size if page_token is not None: param['pageToken'] = page_token - r = self.__free_imdb_api(path=endpoint % title_id, params=param) or {} + try: + r = self.__free_imdb_api(path=endpoint % title_id, params=param) or {} + except Exception as e: + logger.debug(f"An error occurred while retrieving credits: {e}") + return None return r.get('credits') def akas(self, title_id: str) -> Optional[list]: @@ -774,7 +806,11 @@ class ImdbHelper: },] """ endpoint = '/titles/%s/akas' - r = self.__free_imdb_api(path=endpoint % title_id) + try: + r = self.__free_imdb_api(path=endpoint % title_id) + except Exception as e: + logger.debug(f"An error occurred while retrieving alternative titles: {e}") + return None if r is None: return None return r.get('akas') @@ -968,7 +1004,11 @@ class ImdbHelper: params: Dict[str, Any] = {'query': query} if limit: params['limit'] = limit - r = await self._async_free_imdb_api(path=endpoint, params=params) + try: + r = await self._async_free_imdb_api(path=endpoint, params=params) + except Exception as e: + logger.debug(f"An error occurred while searching for titles: {e}") + return None if r is None: return None return r.get('titles') @@ -981,7 +1021,11 @@ class ImdbHelper: See `curl -X 'GET' 'https://api.imdbapi.dev/titles/tt0944947' -H 'accept: application/json'` """ endpoint = '/titles/%s' - r = await self._async_free_imdb_api(path=endpoint % title_id) + try: + r = await self._async_free_imdb_api(path=endpoint % title_id) + except Exception as e: + logger.debug(f"An error occurred while retrieving details: {e}") + return None return r async def async_episodes(self, title_id: str, season: Optional[str] = None, @@ -1005,7 +1049,11 @@ class ImdbHelper: param['pageSize'] = page_size if page_token is not None: param['pageToken'] = page_token - r = await self._async_free_imdb_api(path=endpoint % title_id, params=param) + try: + r = await self._async_free_imdb_api(path=endpoint % title_id, params=param) + except Exception as e: + logger.debug(f"An error occurred while retrieving episodes: {e}") + return None return r async def async_seasons(self, title_id: str) -> Optional[List[dict]]: @@ -1018,7 +1066,11 @@ class ImdbHelper: {[{"season": "1", "episodeCount": 11}]} """ endpoint = '/titles/%s/seasons' - r = await self._async_free_imdb_api(path=endpoint % title_id) + try: + r = await self._async_free_imdb_api(path=endpoint % title_id) + except Exception as e: + logger.debug(f"An error occurred while retrieving seasons: {e}") + return None if r is None: return None return r.get('seasons') @@ -1049,7 +1101,11 @@ class ImdbHelper: param['pageSize'] = page_size if page_token is not None: param['pageToken'] = page_token - r = await self._async_free_imdb_api(path=endpoint % title_id, params=param) or {} + try: + r = await self._async_free_imdb_api(path=endpoint % title_id, params=param) or {} + except Exception as e: + logger.debug(f"An error occurred while retrieving credits: {e}") + return None return r.get('credits') async def async_akas(self, title_id: str) -> Optional[list]: @@ -1070,7 +1126,11 @@ class ImdbHelper: },] """ endpoint = '/titles/%s/akas' - r = await self._async_free_imdb_api(path=endpoint % title_id) + try: + r = await self._async_free_imdb_api(path=endpoint % title_id) + except Exception as e: + logger.debug(f"An error occurred while retrieving alternative titles: {e}") + return None if r is None: return None return r.get('akas') diff --git a/plugins.v2/lexiannot/__init__.py b/plugins.v2/lexiannot/__init__.py index 78b5f63..92a34d6 100644 --- a/plugins.v2/lexiannot/__init__.py +++ b/plugins.v2/lexiannot/__init__.py @@ -17,7 +17,6 @@ from pysubs2 import SSAFile, SSAEvent import pymediainfo from langdetect import detect import spacy -from spacy.util import compile_infix_regex from spacy.tokenizer import Tokenizer from app.core.config import settings @@ -975,11 +974,12 @@ class LexiAnnot(_PluginBase): logger.error(f"字典加载失败") return try: + # 为减少内存占用,只在处理时加载 spaCy 模型 nlp = spacy.load(self._spacy_model) infixes = list(nlp.Defaults.infixes) infixes = [i for i in infixes if '-' not in i] # 使用修改后的正则表达式重新创建 tokenizer - infix_re = compile_infix_regex(infixes) + infix_re = spacy.util.compile_infix_regex(infixes) nlp.tokenizer = Tokenizer( nlp.vocab, prefix_search=nlp.tokenizer.prefix_search, @@ -1062,7 +1062,7 @@ class LexiAnnot(_PluginBase): lexicon = json.load(f) except Exception as e: logger.debug(f"词典文件读取失败: {e}") - lexicon_files = ('cefr', 'coca20k', 'swear_words', 'examinations') + lexicon_files = ('cefr', 'coca20k', 'swear_words', 'examinations', 'version') if any(file not in lexicon for file in lexicon_files): return None return lexicon @@ -1588,7 +1588,7 @@ class LexiAnnot(_PluginBase): 例如:"[Hi]" 会被替换成 " " (4个空格) """ pattern = r'(\[.*?\])' - return re.sub(pattern, lambda match: ' ' * len(match.group(1)), text) + return re.sub(pattern, lambda match: ' ' * len(match.group(1)), _text) simple_vocabulary = list(filter(lambda x: x < self._annot_level, ['A1', 'A2', 'B1', 'B2', 'C1', 'C2'])) patterns = [r'\d+th|\d?1st|\d?2nd|\d?3rd', r"\w+'s$", r"\w+'t$", "[Ii]'m$", r"\w+'re$", r"\w+'ve$", r"\w+'ll$"] diff --git a/plugins.v2/tobypasstrackers/__init__.py b/plugins.v2/tobypasstrackers/__init__.py index 419e48f..48cb58f 100644 --- a/plugins.v2/tobypasstrackers/__init__.py +++ b/plugins.v2/tobypasstrackers/__init__.py @@ -29,7 +29,7 @@ class ToBypassTrackers(_PluginBase): # 插件图标 plugin_icon = "Clash_A.png" # 插件版本 - plugin_version = "1.4.2" + plugin_version = "1.4.3" # 插件作者 plugin_author = "wumode" # 作者主页 @@ -68,7 +68,8 @@ class ToBypassTrackers(_PluginBase): self.ipv6_txt = self.get_data("ipv6_txt") if self.get_data("ipv6_txt") else "" self.ipv4_txt = self.get_data("ipv4_txt") if self.get_data("ipv4_txt") else "" try: - with open(f"{settings.ROOT_PATH}/app/plugins/tobypasstrackers/sites/trackers", "r", encoding="utf-8") as f: + site_file = settings.ROOT_PATH/'app'/'plugins'/'tobypasstrackers'/'sites'/'trackers' + with open(site_file, "r", encoding="utf-8") as f: base64_str = f.read() self.trackers = json.loads(base64.b64decode(base64_str).decode("utf-8")) except Exception as e: @@ -101,7 +102,6 @@ class ToBypassTrackers(_PluginBase): ) self._onlyonce = False self.__update_config() - # self._scheduler.print_jobs() self._scheduler.start() def get_state(self) -> bool: @@ -619,16 +619,14 @@ class ToBypassTrackers(_PluginBase): # Load Chnroute6 Lists res = RequestUtils().get_res(url=chnroute6_lists_url) if res is not None and res.status_code == 200: - chnroute6_lists = res.text[:-1].split('\n') - for ipr in chnroute6_lists: - ipv6_list.append(ipr) + chnroute6_lists = res.text.strip().split('\n') + ipv6_list = [*chnroute6_lists] if self._china_ip_route: # Load Chnroute Lists res = RequestUtils().get_res(url=chnroute_lists_url) if res is not None and res.status_code == 200: - chnroute_lists = res.text[:-1].split('\n') - for ipr in chnroute_lists: - ip_list.append(ipr) + chnroute_lists = res.text.strip().split('\n') + ip_list = [*chnroute_lists] do_sites = {site.domain: site.name for site in SiteOper().list_order_by_pri() if site.id in self._bypassed_sites} domain_name_map = {} diff --git a/plugins.v2/tobypasstrackers/sites/trackers b/plugins.v2/tobypasstrackers/sites/trackers index c48216e..4a15d62 100644 --- a/plugins.v2/tobypasstrackers/sites/trackers +++ b/plugins.v2/tobypasstrackers/sites/trackers @@ -1 +1 @@ -eyJoZGRvbGJ5LmNvbSI6IFsidC5oZGRvbGJ5LmNvbSJdLCAidGp1cHQub3JnIjogWyJ0cmFja2VyLXB1YmxpYy50anVwdC5vcmciXSwgIm5pY2VwdC5uZXQiOiBbInd3dy5uaWNlcHQubmV0Il0sICJyb3VzaS56aXAiOiBbImhpdHB0LmNvbSJdLCAicHRob21lLm5ldCI6IFsicHRob21lLm5ldCJdLCAiaGR0aW1lLm9yZyI6IFsiaGR0aW1lLm9yZyJdLCAiZWFzdGdhbWUub3JnIjogWyJwdC5lYXN0Z2FtZS5vcmciXSwgInB0dGltZS5vcmciOiBbInd3dy5wdHRpbWUub3JnIl0sICJtLXRlYW0uY2MiOiBbInRyYWNrZXIubS10ZWFtLmNjIiwgInRyYWNrZXIubS10ZWFtLmlvIl0sICI1MnB0LnNpdGUiOiBbIjUycHQuc2l0ZSJdLCAicWluZ3dhcHQuY29tIjogWyJ0cmFja2VyLnFpbmd3YS5wcm8iLCAidHJhY2tlci5xaW5nd2FwdC5jb20iXSwgImhka3lsLmluIjogWyJ0cmFja2VyLmhka3lsLmluIl0sICJyYWluZ2ZoLnRvcCI6IFsicmFpbmdmaC50b3AiXSwgImhkZmFucy5vcmciOiBbImhkZmFucy5vcmciXSwgInB0bGdzLm9yZyI6IFsicHRsLmdzIiwgInJlbGF5MDEucHRsLmdzIl0sICJtb25pa2FkZXNpZ24udWsiOiBbInRyYWNrZXIubW9uaWthZGVzaWduLnVrIiwgImRhaWtpcmFpLm1vbmlrYWRlc2lnbi51ayIsICJhbmltZS1uby1pbmRleC5jb20iXSwgInB0c2Jhby5jbHViIjogWyJwdHNiYW8uY2x1YiJdLCAidG90aGVnbG9yeS5pbSI6IFsidHJhY2tlci50b3RoZWdsb3J5LmltIl0sICJ1Mi5kbWh5Lm9yZyI6IFsiZGF5ZHJlYW0uZG1oeS5iZXN0Il0sICJieXIucHQiOiBbInRyYWNrZXIuYnlyLnB0Il0sICJodWRidC5odXN0LmVkdS5jbiI6IFsiaHVkYnQuaHVzdC5lZHUuY24iXSwgImlsb2xpY29uLmNvbSI6IFsidHJhY2tlci5pbG9saWNvbi5jYyJdLCAiaGl0cHQuY29tIjogWyJoaXRwdC5jb20iXSwgImJ0c2Nob29sLmNsdWIiOiBbInB0LmJ0c2Nob29sLmNsdWIiXSwgImhkYXJlYS5jbHViIjogWyJ0cmFja2VyLmhkYXJlYS5jbHViIl0sICJzcHJpbmdzdW5kYXkubmV0IjogWyJvbjYuc3ByaW5nc3VuZGF5Lm5ldCIsICJvbi5zcHJpbmdzdW5kYXkubmV0Il0sICJ6bXB0LmNjIjogWyJ6bXB0LmNjIl0sICJjYXJwdC5uZXQiOiBbInRyYWNrZXIuY2FycHQubmV0Il0sICJpY2MyMDIyLmNvbSI6IFsidHJhY2tlci5pY2MyMDIyLnh5eiJdLCAia2VlcGZyZHMuY29tIjogWyJ0cmFja2VyLmtlZXBmcmRzLmNvbSJdLCAicHR6b25lLnh5eiI6IFsicHR6b25lLnh5eiJdLCAiY3NwdC50b3AiOiBbInRyYWNrZXIuY3NwdC50b3AiLCAidHJhY2tlci5jc3B0LmNjIiwgInRyYWNrZXIuY3NwdC5kYXRlIl0sICJjcmFicHQudmlwIjogWyJjcmFicHQudmlwIl0sICJva3B0Lm5ldCI6IFsid3d3Lm9rcHQubmV0Il0sICJnYW1lZ2FtZXB0LmNvbSI6IFsid3d3LmdhbWVnYW1lcHQuY29tIl0sICJhdWRpZW5jZXMubWUiOiBbInQuYXVkaWVuY2VzLm1lIiwgInRyYWNrZXIuY2luZWZpbGVzLmluZm8iXSwgInhpbmd5dW5nZS50b3AiOiBbInRyYWNrZXIueGluZ3l1bmdlLnRvcCIsICJ0cmFja2VyLnhpbmd5dW5nZS5zYnMiXSwgImV0OC5vcmciOiBbImV0OC5vcmciLCAidC5ldDgub3JnIl0sICJkaXNjZmFuLm5ldCI6IFsiZGlzY2Zhbi54eXoiXX0= \ No newline at end of file +eyI1MnB0LnNpdGUiOiBbIjUycHQuc2l0ZSJdLCAiYXVkaWVuY2VzLm1lIjogWyJ0LmF1ZGllbmNlcy5tZSIsICJ0cmFja2VyLmNpbmVmaWxlcy5pbmZvIl0sICJidHNjaG9vbC5jbHViIjogWyJwdC5idHNjaG9vbC5jbHViIl0sICJieXIucHQiOiBbInRyYWNrZXIuYnlyLnB0Il0sICJjYXJwdC5uZXQiOiBbInRyYWNrZXIuY2FycHQubmV0Il0sICJjcmFicHQudmlwIjogWyJjcmFicHQudmlwIl0sICJjc3B0LnRvcCI6IFsidHJhY2tlci5jc3B0LnRvcCIsICJ0cmFja2VyLmNzcHQuY2MiLCAidHJhY2tlci5jc3B0LmRhdGUiXSwgImRpc2NmYW4ubmV0IjogWyJkaXNjZmFuLnh5eiJdLCAiZWFzdGdhbWUub3JnIjogWyJwdC5lYXN0Z2FtZS5vcmciXSwgImV0OC5vcmciOiBbImV0OC5vcmciLCAidC5ldDgub3JnIl0sICJnYW1lZ2FtZXB0LmNvbSI6IFsid3d3LmdhbWVnYW1lcHQuY29tIl0sICJoZGFyZWEuY2x1YiI6IFsidHJhY2tlci5oZGFyZWEuY2x1YiJdLCAiaGRkb2xieS5jb20iOiBbInQuaGRkb2xieS5jb20iXSwgImhkZmFucy5vcmciOiBbImhkZmFucy5vcmciXSwgImhka3lsLmluIjogWyJ0cmFja2VyLmhka3lsLmluIl0sICJoZHRpbWUub3JnIjogWyJoZHRpbWUub3JnIl0sICJoaXRwdC5jb20iOiBbImhpdHB0LmNvbSJdLCAiaHVkYnQuaHVzdC5lZHUuY24iOiBbImh1ZGJ0Lmh1c3QuZWR1LmNuIl0sICJpY2MyMDIyLmNvbSI6IFsidHJhY2tlci5pY2MyMDIyLnh5eiJdLCAiaWxvbGljb24uY29tIjogWyJ0cmFja2VyLmlsb2xpY29uLmNjIl0sICJrZWVwZnJkcy5jb20iOiBbInRyYWNrZXIua2VlcGZyZHMuY29tIl0sICJtLXRlYW0uY2MiOiBbInRyYWNrZXIubS10ZWFtLmNjIiwgInRyYWNrZXIubS10ZWFtLmlvIl0sICJtb25pa2FkZXNpZ24udWsiOiBbInRyYWNrZXIubW9uaWthZGVzaWduLnVrIiwgImRhaWtpcmFpLm1vbmlrYWRlc2lnbi51ayIsICJhbmltZS1uby1pbmRleC5jb20iXSwgIm5pY2VwdC5uZXQiOiBbInd3dy5uaWNlcHQubmV0Il0sICJva3B0Lm5ldCI6IFsid3d3Lm9rcHQubmV0Il0sICJwdGhvbWUubmV0IjogWyJwdGhvbWUubmV0Il0sICJwdGxncy5vcmciOiBbInB0bC5ncyIsICJyZWxheTAxLnB0bC5ncyJdLCAicHRzYmFvLmNsdWIiOiBbInB0c2Jhby5jbHViIl0sICJwdHRpbWUub3JnIjogWyJ3d3cucHR0aW1lLm9yZyJdLCAicHR6b25lLnh5eiI6IFsicHR6b25lLnh5eiJdLCAicWluZ3dhcHQuY29tIjogWyJ0cmFja2VyLnFpbmd3YS5wcm8iLCAidHJhY2tlci5xaW5nd2FwdC5jb20iXSwgInJhaW5nZmgudG9wIjogWyJyYWluZ2ZoLnRvcCJdLCAicm91c2kuemlwIjogWyJoaXRwdC5jb20iXSwgInNwcmluZ3N1bmRheS5uZXQiOiBbIm9uNi5zcHJpbmdzdW5kYXkubmV0IiwgIm9uLnNwcmluZ3N1bmRheS5uZXQiXSwgInRqdXB0Lm9yZyI6IFsidHJhY2tlci1wdWJsaWMudGp1cHQub3JnIl0sICJ0b3RoZWdsb3J5LmltIjogWyJ0cmFja2VyLnRvdGhlZ2xvcnkuaW0iXSwgInUyLmRtaHkub3JnIjogWyJkYXlkcmVhbS5kbWh5LmJlc3QiXSwgInhpbmd5dW5nZS50b3AiOiBbInRyYWNrZXIueGluZ3l1bmdlLnRvcCIsICJ0cmFja2VyLnhpbmd5dW5nZS5zYnMiXSwgInptcHQuY2MiOiBbInptcHQuY2MiXSwgImhoYW5jbHViLnRvcCI6IFsidHJhY2tlci5oaGFuY2x1Yi50b3AiXSwgImhkY2l0eS5jaXR5IjogWyJzeW5jLmxlbml0ZXIub3JnIl19 \ No newline at end of file