mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-07 05:02:40 +08:00
重构插件页面,增加文件夹功能
This commit is contained in:
@@ -146,11 +146,32 @@ def all_plugins(_: schemas.TokenPayload = Depends(get_current_active_superuser),
|
||||
installed_plugins = [plugin for plugin in local_plugins if plugin.installed]
|
||||
# 未安装的本地插件
|
||||
not_installed_plugins = [plugin for plugin in local_plugins if not plugin.installed]
|
||||
if state == "installed":
|
||||
return installed_plugins
|
||||
|
||||
# 在线插件
|
||||
online_plugins = PluginManager().get_online_plugins()
|
||||
|
||||
# 为已安装插件补充标签信息
|
||||
if online_plugins:
|
||||
# 创建在线插件的ID到插件对象的映射
|
||||
online_plugin_map = {plugin.id: plugin for plugin in online_plugins}
|
||||
|
||||
# 为已安装插件补充标签信息
|
||||
updated_installed_plugins = []
|
||||
for installed_plugin in installed_plugins:
|
||||
if installed_plugin.id in online_plugin_map:
|
||||
online_plugin = online_plugin_map[installed_plugin.id]
|
||||
# 如果已安装插件没有标签但在线插件有标签,则补充标签信息
|
||||
if not installed_plugin.plugin_label and online_plugin.plugin_label:
|
||||
# 直接更新原对象的标签字段,避免创建新对象可能导致的状态丢失
|
||||
installed_plugin.plugin_label = online_plugin.plugin_label
|
||||
|
||||
updated_installed_plugins.append(installed_plugin)
|
||||
|
||||
installed_plugins = updated_installed_plugins
|
||||
|
||||
if state == "installed":
|
||||
return installed_plugins
|
||||
|
||||
if not online_plugins:
|
||||
# 没有获取在线插件
|
||||
if state == "market":
|
||||
@@ -374,6 +395,75 @@ def plugin_static_file(plugin_id: str, filepath: str):
|
||||
raise HTTPException(status_code=500, detail="Internal Server Error")
|
||||
|
||||
|
||||
@router.get("/folders", summary="获取插件文件夹配置", response_model=dict)
|
||||
def get_plugin_folders(_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> dict:
|
||||
"""
|
||||
获取插件文件夹分组配置
|
||||
"""
|
||||
try:
|
||||
result = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"[文件夹API] 获取文件夹配置失败: {str(e)}")
|
||||
return {}
|
||||
|
||||
|
||||
@router.post("/folders", summary="保存插件文件夹配置", response_model=schemas.Response)
|
||||
def save_plugin_folders(folders: dict, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
保存插件文件夹分组配置
|
||||
"""
|
||||
try:
|
||||
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
|
||||
|
||||
# 验证保存结果
|
||||
saved_result = SystemConfigOper().get(SystemConfigKey.PluginFolders)
|
||||
|
||||
return schemas.Response(success=True)
|
||||
except Exception as e:
|
||||
logger.error(f"[文件夹API] 保存文件夹配置失败: {str(e)}")
|
||||
return schemas.Response(success=False, message=str(e))
|
||||
|
||||
|
||||
@router.post("/folders/{folder_name}", summary="创建插件文件夹", response_model=schemas.Response)
|
||||
def create_plugin_folder(folder_name: str, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
创建新的插件文件夹
|
||||
"""
|
||||
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
if folder_name not in folders:
|
||||
folders[folder_name] = []
|
||||
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
|
||||
return schemas.Response(success=True, message=f"文件夹 '{folder_name}' 创建成功")
|
||||
else:
|
||||
return schemas.Response(success=False, message=f"文件夹 '{folder_name}' 已存在")
|
||||
|
||||
|
||||
@router.delete("/folders/{folder_name}", summary="删除插件文件夹", response_model=schemas.Response)
|
||||
def delete_plugin_folder(folder_name: str, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
删除插件文件夹
|
||||
"""
|
||||
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
if folder_name in folders:
|
||||
del folders[folder_name]
|
||||
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
|
||||
return schemas.Response(success=True, message=f"文件夹 '{folder_name}' 删除成功")
|
||||
else:
|
||||
return schemas.Response(success=False, message=f"文件夹 '{folder_name}' 不存在")
|
||||
|
||||
|
||||
@router.put("/folders/{folder_name}/plugins", summary="更新文件夹中的插件", response_model=schemas.Response)
|
||||
def update_folder_plugins(folder_name: str, plugin_ids: List[str], _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
更新指定文件夹中的插件列表
|
||||
"""
|
||||
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
folders[folder_name] = plugin_ids
|
||||
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
|
||||
return schemas.Response(success=True, message=f"文件夹 '{folder_name}' 中的插件已更新")
|
||||
|
||||
|
||||
@router.get("/{plugin_id}", summary="获取插件配置")
|
||||
def plugin_config(plugin_id: str,
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> dict:
|
||||
|
||||
@@ -141,6 +141,8 @@ class SystemConfigKey(Enum):
|
||||
UserInstalledPlugins = "UserInstalledPlugins"
|
||||
# 插件安装统计
|
||||
PluginInstallReport = "PluginInstallReport"
|
||||
# 插件文件夹分组配置
|
||||
PluginFolders = "PluginFolders"
|
||||
# 默认电影订阅规则
|
||||
DefaultMovieSubscribeConfig = "DefaultMovieSubscribeConfig"
|
||||
# 默认电视剧订阅规则
|
||||
|
||||
@@ -23,3 +23,4 @@ DB_MAX_OVERFLOW=500
|
||||
DB_TIMEOUT=60
|
||||
# 是否开发调试模式,仅开发人员使用,打开后将停止后台服务
|
||||
DEV=false
|
||||
API_TOKEN='WaCKavmns2gocsShB-jCdQ'
|
||||
|
||||
23
config/plugins/twofahelper/twofahelper_sites.json
Normal file
23
config/plugins/twofahelper/twofahelper_sites.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"Google": {
|
||||
"secret": "UHWDJQYTEY24FEPC",
|
||||
"urls": [
|
||||
"https://accounts.google.com"
|
||||
],
|
||||
"icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABWhJREFUWEe9V2lsVFUU/u55dGY67XRo2cpmsaLQCilSFVkkDY0WFTdwAYwRpCIKERAkNaYgEpCGkNCIibKESFg0JphoJAixJDaQYlFoUAxiC5WwlLIVOtPpdN65cod5M+9Np50paby/2jnb98757j3nCCR4pJRpAKYw8yQpZZ4QIhuAK2R+U0p5RghRQ0Q/A/hRCHEzEdcinpKUchgzlwCYTkSOePpKzswtAHbf1l8rhDjdmU2HAKSUTmZeBWAhEWmJBI7WYeYAgA1EtFwIoUC1OzEBSCkfYObviCj3bgLHAHKCiKYKIf6JlrUDIKUczcw/EVHvaGX94nm0HtyPtmNHEaivAzfdAKQEpbmhZWXDljca9sLJ0AYOboebmRuJ6EkhxHGz0AIg9OWHooPrly7As+kztFZWBAN2eoSAfXwBUuYthJY5wKIaAjHOnIkwACllCjP/Gp1234G9aC4vg/TFLGGHWESyE64lH8Fe8EQ0CFWOMQYnwgB0XV9PRO+btb1ffwXPls/vmgaOoilwfbA8VjnWaZq2TAmCAEJX7U8z29WX3yr7OGbwHtlDYXt0HLT+AwEhoF84D3/1YQRqIzfO8cyLcC0qCcpj3Q4iylGlCEp1Xd9GRLMMRUW268UzIFt9FlsVMHVRCWz5Y2IC8x+twq31q2GfUIDU+Us6zRwzb9U0rVhIKd3MfMn8yHjK34P3hyqLg6ScEXCvKYdwGY9fbP/S64FwpsQtGzN7iShTAZgJYKdhIVvqoFfmwlvRH61H+wR/poxeSN+8C+ROj+u4iwrTha7rW4hojmHIZz8F164I/uv/qye8e7OQunAFFKG6+zDzJhEIBKo1TXs4XP/fiyCvHwzH4puDYHv2b6BHj+6Or7h3RGXgKhFlGN4DlYMBf0M4mOj3ErQRuzoMXrjGkzCw0hfsKMiNfIh6mBQAPxElhQFUOADJYac0pAR03yfdAmBOgQ0zx4VDqa7p/18BvD4hCbMm2iLlDQG4QkS9OixB32nQRu7ulgzMK7Th5TGWDDS2J+GxyZDXKsIBG2w56Dv+NyRR10h4ppFRvNnaP1ZMtWPi8Igfg4RR17AMXFsaBLCvdRDKbuVh6SML8Hx2YcJkU4rfVLVhU4XfYrNzvhOZ7sjTHLyGUsoZAMI0ly1n4Tuciw3NudjjGxJ0kOFwY1fRevRy9EwIRLNPYvaXLbjmibTue3oTts1NjrZ/VQFICz3FYemGqlXYWV9jUR6eno2NBaVw2zp/itt0oPRbH6rrdIv924U2vGKtv3qK+xnNaCsRvWlYXPQ0Yvq+xfAGrM0o09kby/LfwuMD8mNm4vSNepT9UoUzfzwFIDJGZqQIbH8nGck2S/o3a5o212jH9zPzSaII0/bVV6K0qjxmoCFpAzE28yEMTs2EEAKXW67i2OWTqLlyChISmm8onA0LIAJ3esfKaQ5MGBYBxMxtoXZcax5I1hHRUnPEHae+R/nx7QnVPVpJ6C4kN7yL2fl5lruv9Jh5raZpH6q/zSOZGsOPENEIs7P9/x7C6uov4A10bSTThIbinNdQPPI5CzZmVsvLY0KIYH2jh9KhzHyYiO704dC55L2CjTU7cODcIXC8oRRAft8HsWjUG1DENR9mbiAiNZTWGb/HGstHMfP+aBDKQJFTgahuOIHapnO43toUHJLddheyXAMwqs9wFA4ai2Hp97YrWyh4kVrfzMKOFhOViT1ENPKuCBBlFEq7WkzCX95hBgyBlDKZmVcCWGy+HV0BpNh+e4FV0/ZKo+btyBrPoZRSZUMtpzOIyBlPP8RyrxrziKhMCFHbmU3c7diUEfUEPh21nrtD8iYpZZ1pPd8rhGhOBOx/iMlsM+yNfVQAAAAASUVORK5CYII="
|
||||
},
|
||||
"GitHub": {
|
||||
"secret": "IRVC2BVNZZ24I6TZ",
|
||||
"urls": [
|
||||
"https://github.com"
|
||||
],
|
||||
"icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABRFJREFUWEetl11sU2UYx//POV23sq18jHN61nZYxoQ4EjAqEC+UmZgI8TN6YaIRMV44MGpiYtAYZYgYNcavIBIuMH7EG2JiiIqJJMwYNAN3IcYNdcIYpT09ZRvpVmR07V9O6Zbu9HTdZOeiF32fj9/zvM/zvs8rmOHX2trqHT5//g4C94FsBRCkSNBWFzIGIAaRHgEOLly8+EhPT8/lmZiWSkIRTTMuiWwn+QgAfyX5wnpKRL6sIXf0J5PmdDplAVpaWqpHU6mXATxPsnaGjqeIiUj6CvS7dX7/rr6+vjE3G64Ahai/Jrnu/zh26ohIVw35gFs2SgDCur5qnPyWQHgunE/YECDqEbk7alkniu1OAchHDhyfa+fFEDXAmuJMTAIU9vzH4rQL0AvgBETuJNkwy4xcEOAHAMsI3DQJIdJV5/evn6iJSQBD118j+UqxE0Xkqbhl7Wtra/P09vZuArkLpAGRUQCnhRwGQIosBHkdgPkiMgRy+yJN22e3YqOuP5gjv5qSdpGdpmW9mm9h+6dQdH3OahdVXWua5vEJ5VZNqxtS1SXt7e0nOzo6csVGSUo4HL5eVdXkwMCADZb/AoHAUuRypxwA6Rqyxd6KPICh6x+TbHemWPF4bonH492zTP0U8WAwuCSbyZxx6Yy9pmVtEfuEG0wmk26HjCKyKW5Zn18LgGEYG5nNfudiI9WgaZo06vpdOfJ7F8K0qOrKeDxeQj8boFAo1JDNZE6SXFySYZENYuj6RyS3ugBsMy3r7dk4KydraNoTBPa7+NgjhqYdIdDmXKyqrl4ejUb/nguASCSy4N90erIwi86FThvgTwLLnVUaTyTqRYRzAVAo9DMkl0zxA/wlAV0fAVnnADhtWlbzXDnPA2jaMQJrptgUGbVrIE1ynsPZSCKZnOnVOyNOQ9dPkVzqCPSiDVCSmryQogQSiYQ1I+sVhCKRSM2lixcvkKx2AJyxAbpIrnVpkcfilvXFXABM0+pd0qhpH+SAZ0taBDget6x1c1GIhq4fIrmhJEjgQ/sgKrksJttE5AXTst65liwYmraZwCduNhSRh2TFihX1F4aGzgGodxGiiLweamra2d3dnZkNSEdHh7J3zx57nHsTgOqiO9IABCcuo90kn84LibynivyaJbeBXJX/CzgLkf0KcFTxeruj0eiQG0xzc/P8dDp9swLcmiM3g2wpBy2KsttMJJ7JA4Q1rWVc5A+SXgGGFZGHF5C/DIr8BPJGR+8e3bJ16+3O67jQ666nakl9iYxVASvPWtY/xQPJDpL5IeHKJJzyeL0rRcQ3fvnyz8UXiaoo98cSiYNukRmG0cZs9kilrRKRHaZldRSye1XcHslGUqljRWnfbyaTTxaGlUdJNikiPbV+/6flRuxwOLwoMzY2OC2AyIl6v39tyUhmKwWDwaZsJtMFoBFAVlT1XtM0D1WKqHg9oGl2sXrK6MTVqqp1sVjs7GSnOQVDur56nLSdXoUQOQzgsAAjBAK3rV+/68CBA9lyUAFNGy9T9XGPyMZzlvVbsa7rwyQUCoXHM5lvQK52OmrQtOrp3n0BTbPhFEfh/q56PPfEYrGBkoIsF0lhTH8JwIvFZ7ivttbX399/aZoM2MNqPjARsR+ob9XMm/dGOZ2Kj9MmXV+WEXmOudzjEFFuaG1d2NnZaafZ9TN0fZCA3c6febze9ysNNRUBJrzYI/moz1dVPHK7Edjb5/P5Un19famZFO9/2SAgrr8DEI4AAAAASUVORK5CYII="
|
||||
},
|
||||
"Microsoft": {
|
||||
"secret": "HEHTPMXGKKRQSA4N",
|
||||
"urls": [
|
||||
"https://account.microsoft.com"
|
||||
],
|
||||
"icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAAnpJREFUeF7t3W1RxDAYReHUADNYQBEC8IIZBPAXxGCBGQwsw0e22d06OA8Okl7y3nNSyvb1+HAasZ+714/taMnP7yO3F5sA7FEQgMhJ4ATYH7QTYAm9E8AJoAMUMmAEGAEo4D8DOoAOwAPMDCiBhQIwxtABdAAdQAe4Pe6MACOAByhkQAfQAXQAHUAH+NkBIogIIoKIoELzW9aoBCqBSqASqAQqgVcZYAIjXUAH0AF0AB1AB9ABdAAmcM2AEqgEug4uZAAFoAAUgAJQAApAASgABfhAxDkDMLCAAP4w5OIpeyXMK2FeCfNKWOTon8skgoggIogIIoKIICKICCKCiCAiKAYBvhCyPHAiiAgigoig2AwggoggIogIIoKIICKICCKCiCAiKAYBRBAR5J9GzQwwgUwgE8gExkoAE8gEMoFMIBPIBDKBTGDeBMb6n+Ve7cBhGbJLnR0QgM6zPlypAAhAfAfiy3cC5APw8pn7Nt54uj8M/ult5PZiGwJwPgMEoHIcOgHOT9oJsITeCeAE0AESGTACjICjoBsBiV//MWDg8kYQDNw3wwngBFACExlQApVAJfBvB4ggIshl0MyAEpgoADBwfcxGgBFgBBgBlaN/rhMGwkAYCANvMoACKqPACDACjAAjwAiggi8zoAPoAK6DExlQApVAJVAJVAKVQCXQbaDbQLeBbgMT1X9ZJApAASgABaAAFIACUAAKQAEoAAX87oDbwEoQYCAMhIEwEAbCQBgIA2EgDISBlfY/14kCUAAKQAEoAAWgABSAAlAACkABLoNSGYCBMBAGwkAYCANhIAyEgTAQBqYQwKdi18dtBBgBRoARYARkTeA3l4PYkqt6qqEAAAAASUVORK5CYII="
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ PyJWT~=2.7.0
|
||||
python-multipart~=0.0.9
|
||||
alembic~=1.11.1
|
||||
bcrypt~=4.0.1
|
||||
regex~=2023.6.3
|
||||
regex~=2024.11.6
|
||||
cn2an~=0.5.19
|
||||
dateparser~=1.1.8
|
||||
python-dateutil~=2.8.2
|
||||
|
||||
Reference in New Issue
Block a user