mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-10-30 20:05:42 +08:00
106 lines
3.9 KiB
Python
106 lines
3.9 KiB
Python
"""
|
|
插件实例的启停与默认调用目标接口。
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from fastapi import Depends, HTTPException
|
|
from sqlalchemy.exc import IntegrityError
|
|
|
|
from app.api.dependencies.auth import get_current_active_superuser
|
|
from app.api.principal import ApiPrincipal
|
|
from app.api.response import ResponseAPIRouter
|
|
from app.application.plugin.runtime import get_plugin_manager
|
|
from app.schemas.exception import PluginMutationRejectedError
|
|
from app.schemas.plugin import (
|
|
PluginInstanceEnabledRequest as _SchemaPluginInstanceEnabledRequest,
|
|
)
|
|
from app.schemas.response import Response as _SchemaResponse
|
|
|
|
router = ResponseAPIRouter()
|
|
|
|
|
|
@router.post(
|
|
"/instance/{instance_id}/enabled",
|
|
summary="启用或停用插件实例",
|
|
response_model=_SchemaResponse[None],
|
|
)
|
|
def set_plugin_instance_enabled(
|
|
instance_id: str,
|
|
request: _SchemaPluginInstanceEnabledRequest,
|
|
_: ApiPrincipal = Depends(get_current_active_superuser),
|
|
) -> Any:
|
|
"""
|
|
启用或停用一个实例,本体与分身共用这一个入口
|
|
|
|
停用只把启用位置假:业务参数与展示信息原样留在那一行,再次启用即恢复,因而它
|
|
与彻底清理是两件事——删行才会把配置一并抹掉。
|
|
"""
|
|
plugin_manager = get_plugin_manager()
|
|
try:
|
|
changed = plugin_manager.set_plugin_instance_enabled(instance_id, request.enabled)
|
|
except PluginMutationRejectedError as error:
|
|
return _SchemaResponse(success=False, message=str(error))
|
|
if not changed:
|
|
# 两条完整句子而不是拼接中文片段:片段会被当成占位值,翻译时落不到模式上
|
|
return _SchemaResponse(
|
|
success=False,
|
|
message=(
|
|
f"实例 {instance_id} 不存在或已处于启用状态"
|
|
if request.enabled
|
|
else f"实例 {instance_id} 不存在或已处于停用状态"
|
|
),
|
|
)
|
|
return _SchemaResponse(success=True)
|
|
|
|
|
|
@router.put(
|
|
"/instances/{plugin_id}/{instance_id}/default_target",
|
|
summary="设置插件实例的默认调用目标",
|
|
response_model=_SchemaResponse[None],
|
|
)
|
|
def set_plugin_instance_default_target(
|
|
plugin_id: str,
|
|
instance_id: str,
|
|
_: ApiPrincipal = Depends(get_current_active_superuser),
|
|
) -> Any:
|
|
"""
|
|
设置指定插件实例为默认调用目标,并自动清除同插件的旧默认
|
|
"""
|
|
try:
|
|
matched = get_plugin_manager().set_plugin_instance_default_target(
|
|
plugin_id, instance_id
|
|
)
|
|
except LookupError as error:
|
|
raise HTTPException(status_code=404, detail=str(error)) from error
|
|
except IntegrityError as error:
|
|
# 「同一源插件至多一个默认目标」由条件唯一索引在库层强制。并发把不同实例
|
|
# 各自设为默认时,后提交的那个会撞上索引;这是可重试的竞争,不是服务端故障。
|
|
raise HTTPException(
|
|
status_code=409,
|
|
detail="默认调用目标正被并发修改,请重试",
|
|
) from error
|
|
if not matched:
|
|
raise HTTPException(status_code=404, detail=f"插件实例 {instance_id} 不存在")
|
|
return _SchemaResponse(success=True)
|
|
|
|
|
|
@router.delete(
|
|
"/instances/{plugin_id}/{instance_id}/default_target",
|
|
summary="清除插件实例的默认调用目标",
|
|
response_model=_SchemaResponse[None],
|
|
)
|
|
def clear_plugin_instance_default_target(
|
|
plugin_id: str,
|
|
instance_id: str,
|
|
_: ApiPrincipal = Depends(get_current_active_superuser),
|
|
) -> Any:
|
|
"""
|
|
清除指定插件实例的默认调用目标置位,仅当当前置位的正是该实例时才动作,重复调用保持幂等
|
|
"""
|
|
try:
|
|
get_plugin_manager().clear_plugin_instance_default_target(plugin_id, instance_id)
|
|
except LookupError as error:
|
|
raise HTTPException(status_code=404, detail=str(error)) from error
|
|
return _SchemaResponse(success=True)
|