Skip to content

Commit a59c011

Browse files
authored
Merge branch 'jxxghp:v2' into v2
2 parents d9be6a6 + b6720a1 commit a59c011

File tree

13 files changed

+577
-164
lines changed

13 files changed

+577
-164
lines changed

app/api/endpoints/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ async def search_latest(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
2020
"""
2121
查询搜索结果
2222
"""
23-
torrents = await SearchChain().async_last_search_results()
23+
torrents = await SearchChain().async_last_search_results() or []
2424
return [torrent.to_dict() for torrent in torrents]
2525

2626

app/chain/search.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ def search_by_title(self, title: str, page: Optional[int] = 0,
8686
self.save_cache(contexts, self.__result_temp_file)
8787
return contexts
8888

89-
def last_search_results(self) -> List[Context]:
89+
def last_search_results(self) -> Optional[List[Context]]:
9090
"""
9191
获取上次搜索结果
9292
"""
9393
return self.load_cache(self.__result_temp_file)
9494

95-
async def async_last_search_results(self) -> List[Context]:
95+
async def async_last_search_results(self) -> Optional[List[Context]]:
9696
"""
9797
异步获取上次搜索结果
9898
"""

app/core/plugin.py

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from app.log import logger
2828
from app.schemas.types import EventType, SystemConfigKey
2929
from app.utils.crypto import RSAUtils
30-
from app.utils.limit import rate_limit_window
30+
from app.utils.debounce import debounce
3131
from app.utils.object import ObjectUtils
3232
from app.utils.singleton import Singleton
3333
from app.utils.string import StringUtils
@@ -47,33 +47,62 @@ def on_modified(self, event):
4747
if not event_path.name.endswith(".py") or "pycache" in event_path.parts:
4848
return
4949

50-
# 读取插件根目录下的__init__.py文件,读取class XXXX(_PluginBase)的类名
50+
# 防抖模式下处理文件修改事件
51+
self._handle_modification(event_path)
52+
53+
@debounce(interval=1.0, leading=False, source="PluginMonitorHandler", enable_logging=False)
54+
def _handle_modification(self, event_path: Path):
55+
"""
56+
处理文件修改事件
57+
:param event_path:
58+
:return:
59+
"""
60+
logger.debug(f"防抖计时结束,开始处理文件修改事件: {event_path}")
61+
# 解析插件ID
62+
pid = self._get_plugin_id_from_path(event_path)
63+
if not pid:
64+
logger.debug(f"文件不属于任何有效插件,已忽略: {event_path}")
65+
return
66+
67+
# 触发重载
68+
self.__reload_plugin(pid)
69+
70+
@staticmethod
71+
def _get_plugin_id_from_path(event_path: Path) -> Optional[str]:
72+
"""
73+
根据文件路径解析出插件的ID。
74+
:param event_path: 被修改文件的 Path 对象。
75+
:return: 插件ID字符串,如果不是有效插件文件则返回 None。
76+
"""
5177
try:
5278
plugins_root = settings.ROOT_PATH / "app" / "plugins"
5379
# 确保修改的文件在 plugins 目录下
5480
if plugins_root not in event_path.parents:
55-
return
56-
# 获取插件目录路径,没有找到__init__.py时,说明不是有效包,跳过插件重载
57-
# 插件重载目前没有支持app/plugins/plugin/package/__init__.py的场景,这里也不做支持
81+
return None
82+
83+
# 找到插件的根目录
5884
plugin_dir = event_path.parent
85+
while plugin_dir.parent != plugins_root:
86+
plugin_dir = plugin_dir.parent
87+
if plugin_dir == plugins_root: # 防止无限循环
88+
break
89+
5990
init_file = plugin_dir / "__init__.py"
6091
if not init_file.exists():
61-
logger.debug(f"{plugin_dir} 下没有找到 __init__.py,跳过插件重载")
62-
return
92+
return None
6393

94+
# 读取 __init__.py 文件,查找插件主类名
6495
with open(init_file, "r", encoding="utf-8") as f:
65-
lines = f.readlines()
66-
pid = None
67-
for line in lines:
68-
if line.startswith("class") and "(_PluginBase)" in line:
69-
pid = line.split("class ")[1].split("(_PluginBase)")[0].strip()
70-
if pid:
71-
self.__reload_plugin(pid)
96+
for line in f:
97+
if line.startswith("class") and "(_PluginBase)" in line:
98+
# 解析出类名作为插件ID
99+
return line.split("class ")[1].split("(_PluginBase)")[0].strip()
100+
return None
72101
except Exception as e:
73-
logger.error(f"插件文件修改后重载出错:{str(e)}")
102+
logger.error(f"从路径解析插件ID时出错: {e}")
103+
return None
74104

75105
@staticmethod
76-
@rate_limit_window(max_calls=1, window_seconds=2, source="PluginMonitor", enable_logging=False)
77106
def __reload_plugin(pid):
78107
"""
79108
重新加载插件
@@ -265,7 +294,6 @@ def _load_selective_plugins(pid: Optional[str], installed_plugins: List[str],
265294

266295
# 导入模块
267296
module = importlib.import_module(module_name)
268-
importlib.reload(module)
269297

270298
# 检查模块中的类
271299
for name, obj in module.__dict__.items():
@@ -411,6 +439,10 @@ def _clear_plugin_modules(plugin_id: Optional[str] = None):
411439
except KeyError:
412440
# 模块可能已经被删除
413441
pass
442+
443+
importlib.invalidate_caches()
444+
logger.debug("已清除查找器的缓存")
445+
414446
if plugin_id:
415447
if modules_to_remove:
416448
logger.info(f"插件 {plugin_id} 共清除 {len(modules_to_remove)} 个模块缓存:{modules_to_remove}")

0 commit comments

Comments
 (0)