mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
refactor: split api dependencies by domain
This commit is contained in:
+41
-78
@@ -33,6 +33,7 @@ from app.schemas.message import AgentWebChoiceRequest as _SchemaAgentWebChoiceRe
|
||||
from app.schemas.message import Message as _SchemaMessage
|
||||
from app.schemas.response import Response as _SchemaResponse
|
||||
from app.api.response import ResponseAPIRouter
|
||||
from app.api.presentation.sse import build_sse_error_response, build_sse_response
|
||||
from app.agent.contracts import ReplyMode, build_display_message
|
||||
from app.agent.llm.capability import AgentCapabilityManager
|
||||
from app.agent.mcp import agent_mcp_manager
|
||||
@@ -45,7 +46,8 @@ from app.command import Command
|
||||
from app.runtime.config import global_vars, settings
|
||||
from app.runtime.events import Event, EventManager
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.api.deps import get_agent_chat_service, get_current_active_user
|
||||
from app.api.dependencies.agent import get_agent_chat_service
|
||||
from app.api.dependencies.auth import get_current_active_user
|
||||
from app.application.messaging.chat import (
|
||||
AgentChatRecord,
|
||||
AgentChatService,
|
||||
@@ -694,6 +696,21 @@ def _build_web_agent_sse(
|
||||
return f"data: {json.dumps(payload, ensure_ascii=False)}\n\n"
|
||||
|
||||
|
||||
def _build_web_agent_error_response(
|
||||
message: str,
|
||||
*,
|
||||
locale: Optional[str],
|
||||
) -> StreamingResponse:
|
||||
"""Map a rejected WebAgent request to one terminal SSE error event."""
|
||||
return build_sse_error_response(
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": message},
|
||||
locale=locale,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _sanitize_web_agent_upload_name(
|
||||
filename: Optional[str], mime_type: Optional[str] = None
|
||||
) -> str:
|
||||
@@ -1965,15 +1982,9 @@ async def web_agent_stream(
|
||||
getattr(request, "headers", {}).get("X-MoviePilot-Agent-Interaction") == "1"
|
||||
)
|
||||
if is_secret_confirmation_control and not protected_transport_supported:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": "当前客户端不支持安全交付敏感设置,未执行操作。"},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
"当前客户端不支持安全交付敏感设置,未执行操作。",
|
||||
locale=locale,
|
||||
)
|
||||
is_traditional_message = (
|
||||
_is_web_agent_traditional_message(prompt)
|
||||
@@ -1982,27 +1993,15 @@ async def web_agent_stream(
|
||||
if is_traditional_message:
|
||||
denied_message = _ensure_web_agent_command_allowed(current_user)
|
||||
if denied_message:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": denied_message},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
denied_message,
|
||||
locale=locale,
|
||||
)
|
||||
unknown_command_message = _get_web_agent_unknown_command_message(prompt)
|
||||
if unknown_command_message:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": unknown_command_message},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
unknown_command_message,
|
||||
locale=locale,
|
||||
)
|
||||
|
||||
user_attachments = _build_web_agent_input_attachments(
|
||||
@@ -2089,39 +2088,19 @@ async def web_agent_stream(
|
||||
return
|
||||
yield _build_web_agent_sse("done", {}, locale=locale)
|
||||
|
||||
return StreamingResponse(
|
||||
traditional_event_generator(),
|
||||
media_type="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache, no-transform",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no",
|
||||
},
|
||||
)
|
||||
return build_sse_response(traditional_event_generator())
|
||||
|
||||
if not settings.AI_AGENT_ENABLE:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": "智能助手未启用,请先在系统设置中开启。"},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
"智能助手未启用,请先在系统设置中开启。",
|
||||
locale=locale,
|
||||
)
|
||||
|
||||
manager = get_running_agent_manager()
|
||||
if manager is None:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": "智能助手服务尚未就绪,请稍后重试。"},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
"智能助手服务尚未就绪,请稍后重试。",
|
||||
locale=locale,
|
||||
)
|
||||
|
||||
transcript = _transcribe_web_agent_audio_refs(payload.audio_refs or [])
|
||||
@@ -2129,26 +2108,14 @@ async def web_agent_stream(
|
||||
display_prompt = _merge_web_agent_prompt_with_transcript(display_prompt, transcript)
|
||||
has_audio_input = bool(transcript)
|
||||
if not prompt and payload.audio_refs and not payload.images and not payload.files:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": "语音识别失败,请稍后重试。"},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
"语音识别失败,请稍后重试。",
|
||||
locale=locale,
|
||||
)
|
||||
if not prompt and not payload.images and not payload.files and not payload.audio_refs:
|
||||
return StreamingResponse(
|
||||
iter([
|
||||
_build_web_agent_sse(
|
||||
"error",
|
||||
{"message": "请输入要发送给智能助手的内容或选择附件。"},
|
||||
locale=locale,
|
||||
)
|
||||
]),
|
||||
media_type="text/event-stream",
|
||||
return _build_web_agent_error_response(
|
||||
"请输入要发送给智能助手的内容或选择附件。",
|
||||
locale=locale,
|
||||
)
|
||||
|
||||
MessageChain().bind_user_session(str(current_user.id), session_id)
|
||||
@@ -2314,13 +2281,9 @@ async def web_agent_stream(
|
||||
await event_publisher.aclose()
|
||||
# 客户端断线后保留 Agent 继续执行;发布器关闭后不再接受受保护结果。
|
||||
|
||||
return StreamingResponse(
|
||||
return build_sse_response(
|
||||
event_generator(),
|
||||
media_type="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache, no-transform",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no",
|
||||
**(
|
||||
{"X-MoviePilot-Agent-Control": "secret-confirmation"}
|
||||
if is_secret_confirmation_control
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from typing import AsyncIterator, List, Optional
|
||||
|
||||
from fastapi import APIRouter, Header, Security
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.schemas.openai import AnthropicErrorDetail as _SchemaAnthropicErrorDetail
|
||||
from app.schemas.openai import AnthropicErrorResponse as _SchemaAnthropicErrorResponse
|
||||
@@ -21,6 +20,7 @@ from app.api.openai_utils import (
|
||||
build_prompt,
|
||||
build_session_id,
|
||||
)
|
||||
from app.api.presentation.sse import build_sse_response, encode_named_event
|
||||
from app.agent.runtime_loader import get_running_agent_manager
|
||||
from app.runtime.config import settings
|
||||
from app.adapters.web.security.access import anthropic_api_key_header
|
||||
@@ -97,26 +97,71 @@ async def _stream_anthropic_response(
|
||||
|
||||
task = asyncio.create_task(_run_agent())
|
||||
try:
|
||||
yield f"event: message_start\ndata: {json.dumps({'type': 'message_start', 'message': {'id': message_id, 'type': 'message', 'role': 'assistant', 'content': [], 'model': MODEL_ID, 'stop_reason': None, 'stop_sequence': None, 'usage': {'input_tokens': 0, 'output_tokens': 0}}}, ensure_ascii=False)}\n\n"
|
||||
yield f"event: content_block_start\ndata: {json.dumps({'type': 'content_block_start', 'index': 0, 'content_block': {'type': 'text', 'text': ''}}, ensure_ascii=False)}\n\n"
|
||||
yield encode_named_event(
|
||||
"message_start",
|
||||
{
|
||||
"type": "message_start",
|
||||
"message": {
|
||||
"id": message_id,
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"content": [],
|
||||
"model": MODEL_ID,
|
||||
"stop_reason": None,
|
||||
"stop_sequence": None,
|
||||
"usage": {"input_tokens": 0, "output_tokens": 0},
|
||||
},
|
||||
},
|
||||
)
|
||||
yield encode_named_event(
|
||||
"content_block_start",
|
||||
{
|
||||
"type": "content_block_start",
|
||||
"index": 0,
|
||||
"content_block": {"type": "text", "text": ""},
|
||||
},
|
||||
)
|
||||
while True:
|
||||
item = await event_queue.get()
|
||||
if item is None:
|
||||
break
|
||||
if isinstance(item, dict) and item.get("error"):
|
||||
yield (
|
||||
"event: error\n"
|
||||
f"data: {json.dumps({'type': 'error', 'error': {'type': 'api_error', 'message': str(item['error'])}}, ensure_ascii=False)}\n\n"
|
||||
yield encode_named_event(
|
||||
"error",
|
||||
{
|
||||
"type": "error",
|
||||
"error": {
|
||||
"type": "api_error",
|
||||
"message": str(item["error"]),
|
||||
},
|
||||
},
|
||||
)
|
||||
yield f"event: message_stop\ndata: {json.dumps({'type': 'message_stop'}, ensure_ascii=False)}\n\n"
|
||||
yield encode_named_event("message_stop", {"type": "message_stop"})
|
||||
return
|
||||
text = str(item or "")
|
||||
if not text:
|
||||
continue
|
||||
yield f"event: content_block_delta\ndata: {json.dumps({'type': 'content_block_delta', 'index': 0, 'delta': {'type': 'text_delta', 'text': text}}, ensure_ascii=False)}\n\n"
|
||||
yield f"event: content_block_stop\ndata: {json.dumps({'type': 'content_block_stop', 'index': 0}, ensure_ascii=False)}\n\n"
|
||||
yield f"event: message_delta\ndata: {json.dumps({'type': 'message_delta', 'delta': {'stop_reason': 'end_turn', 'stop_sequence': None}, 'usage': {'output_tokens': 0}}, ensure_ascii=False)}\n\n"
|
||||
yield f"event: message_stop\ndata: {json.dumps({'type': 'message_stop'}, ensure_ascii=False)}\n\n"
|
||||
yield encode_named_event(
|
||||
"content_block_delta",
|
||||
{
|
||||
"type": "content_block_delta",
|
||||
"index": 0,
|
||||
"delta": {"type": "text_delta", "text": text},
|
||||
},
|
||||
)
|
||||
yield encode_named_event(
|
||||
"content_block_stop",
|
||||
{"type": "content_block_stop", "index": 0},
|
||||
)
|
||||
yield encode_named_event(
|
||||
"message_delta",
|
||||
{
|
||||
"type": "message_delta",
|
||||
"delta": {"stop_reason": "end_turn", "stop_sequence": None},
|
||||
"usage": {"output_tokens": 0},
|
||||
},
|
||||
)
|
||||
yield encode_named_event("message_stop", {"type": "message_stop"})
|
||||
finally:
|
||||
await manager.clear_session(session_id=session_id, user_id=user_id)
|
||||
if not task.done():
|
||||
@@ -172,7 +217,7 @@ async def messages(
|
||||
session_seed = anthropic_version or "anthropic"
|
||||
session_id = build_session_id(f"{session_seed}:{uuid.uuid4().hex}", SESSION_PREFIX)
|
||||
if payload.stream:
|
||||
return StreamingResponse(
|
||||
return build_sse_response(
|
||||
_stream_anthropic_response(
|
||||
manager=manager,
|
||||
session_id=session_id,
|
||||
@@ -180,12 +225,6 @@ async def messages(
|
||||
prompt=prompt,
|
||||
images=images,
|
||||
),
|
||||
media_type="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no",
|
||||
},
|
||||
)
|
||||
|
||||
collected_messages = []
|
||||
|
||||
@@ -8,7 +8,7 @@ from app.schemas.user import AuthProviderInfo as _SchemaAuthProviderInfo
|
||||
from app.api.response import RAW_RESPONSE_OPENAPI_KEY, ResponseAPIRouter
|
||||
from app.application.security.auth import AuthService, consume_plugin_auth_ticket
|
||||
from app.application.plugin.runtime import get_plugin_manager as PluginManager
|
||||
from app.api.deps import get_auth_service
|
||||
from app.api.dependencies.auth import get_auth_service
|
||||
|
||||
router = ResponseAPIRouter()
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ from app.chain.dashboard import DashboardChain
|
||||
from app.chain.storage import StorageChain
|
||||
from app.runtime.config import settings
|
||||
from app.adapters.web.security.access import verify_apitoken
|
||||
from app.api.deps import get_current_active_superuser, get_dashboard_query_service
|
||||
from app.api.dependencies.auth import get_current_active_superuser
|
||||
from app.api.dependencies.history import get_dashboard_query_service
|
||||
from app.application.dashboard import DashboardQueryService
|
||||
from app.schemas.types import StorageAction
|
||||
from app.application.directory import DirectoryHelper
|
||||
|
||||
@@ -28,7 +28,8 @@ from app.application.site.query import (
|
||||
SiteQueryService,
|
||||
get_configured_site_query_service,
|
||||
)
|
||||
from app.api.deps import get_current_active_user, get_site_sync_query_service
|
||||
from app.api.dependencies.auth import get_current_active_user
|
||||
from app.api.dependencies.site import get_site_sync_query_service
|
||||
from app.application.directory import DirectoryHelper
|
||||
from app.schemas.types import (
|
||||
MUSIC_ENTITY_RECORDING,
|
||||
|
||||
@@ -21,9 +21,11 @@ from app.agent.prompt.transfer_redo import (
|
||||
)
|
||||
from app.runtime.config import settings, global_vars
|
||||
from app.adapters.web.security.access import verify_token
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_manage_user,
|
||||
get_current_active_superuser,
|
||||
)
|
||||
from app.api.dependencies.history import (
|
||||
get_download_history_mutation_command,
|
||||
get_history_query_service,
|
||||
get_transfer_history_mutation_command,
|
||||
|
||||
@@ -6,7 +6,7 @@ from fastapi.responses import HTMLResponse
|
||||
from app.schemas.common import ManageRequest as _SchemaManageRequest
|
||||
from app.schemas.response import Response as _SchemaResponse
|
||||
from app.api.response import ResponseAPIRouter
|
||||
from app.api.deps import get_current_active_superuser_async
|
||||
from app.api.dependencies.auth import get_current_active_superuser_async
|
||||
|
||||
router = ResponseAPIRouter()
|
||||
|
||||
|
||||
@@ -26,7 +26,10 @@ from app.domain.meta.metabase import MetaBase
|
||||
from app.domain.meta.metamusic import MetaMusic
|
||||
from app.domain.metainfo import MetaInfo, MetaInfoPath
|
||||
from app.adapters.web.security.access import verify_token, verify_apitoken
|
||||
from app.api.deps import get_current_active_user, get_current_active_superuser
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_superuser,
|
||||
get_current_active_user,
|
||||
)
|
||||
from app.schemas.category import CategoryConfig
|
||||
from app.schemas.event import MediaSourceInfo as _SchemaMediaSourceInfo
|
||||
from app.schemas.types import MUSIC_ENTITY_RECORDING, MediaSource, MediaType
|
||||
|
||||
@@ -21,7 +21,7 @@ from app.domain.metainfo import MetaInfo
|
||||
from app.adapters.web.security.access import verify_token
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.application.mediaserver import MediaServerHelper, MediaServerQueryService
|
||||
from app.api.deps import get_mediaserver_query_service
|
||||
from app.api.dependencies.history import get_mediaserver_query_service
|
||||
from app.schemas.mediaserver import NotExistMediaInfo
|
||||
from app.schemas.types import MediaSource, MediaType, SystemConfigKey
|
||||
from app.schemas.media import build_media_key, resolve_media_identity
|
||||
|
||||
@@ -22,7 +22,8 @@ from app.runtime.config import settings, global_vars
|
||||
from app.adapters.web.security.access import verify_token, verify_apitoken
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import get_current_active_superuser, get_message_query_service
|
||||
from app.api.dependencies.agent import get_message_query_service
|
||||
from app.api.dependencies.auth import get_current_active_superuser
|
||||
from app.application.messaging.message import MessageQueryService
|
||||
from app.runtime.extensions.service_config import ServiceConfigHelper
|
||||
from app.runtime.log import logger
|
||||
|
||||
@@ -30,7 +30,7 @@ from app.application.security.passkeys import (
|
||||
PasskeyService,
|
||||
)
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_user,
|
||||
get_current_active_user_async,
|
||||
get_user_service,
|
||||
|
||||
@@ -15,7 +15,7 @@ from app.chain.recommend import RecommendChain
|
||||
from app.schemas.types import MediaSource, MediaType
|
||||
from app.domain.context import MusicAlbumInfo, MusicArtistInfo, MusicInfo
|
||||
from app.adapters.web.security.access import verify_token
|
||||
from app.api.deps import get_current_active_superuser_async
|
||||
from app.api.dependencies.auth import get_current_active_superuser_async
|
||||
from app.chain.listenbrainz import (
|
||||
LISTENBRAINZ_CHART_RANGES,
|
||||
LISTENBRAINZ_FRESH_MAX_DAYS,
|
||||
|
||||
@@ -6,7 +6,7 @@ from app.schemas.common import ManageRequest as _SchemaManageRequest
|
||||
from app.schemas.response import Response as _SchemaResponse
|
||||
from app.api.response import ResponseAPIRouter
|
||||
from app.chain.notification import NotificationChain
|
||||
from app.api.deps import get_current_active_superuser
|
||||
from app.api.dependencies.auth import get_current_active_superuser
|
||||
|
||||
router = ResponseAPIRouter()
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import asyncio
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
from threading import Lock
|
||||
from typing import AsyncIterator, List, Optional, Tuple
|
||||
|
||||
from fastapi import APIRouter, Request, Security
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.security import HTTPAuthorizationCredentials
|
||||
|
||||
from app.schemas.openai import OpenAIChatCompletionResponse as _SchemaOpenAIChatCompletionResponse
|
||||
@@ -26,6 +25,7 @@ from app.api.openai_utils import (
|
||||
build_responses_input,
|
||||
build_session_id,
|
||||
)
|
||||
from app.api.presentation.sse import build_sse_response, encode_data_event
|
||||
from app.agent.runtime_loader import (
|
||||
get_moviepilot_agent_type,
|
||||
get_running_agent_manager,
|
||||
@@ -216,7 +216,8 @@ def _get_collecting_agent_type() -> type:
|
||||
|
||||
|
||||
def _sse_payload(data: dict) -> str:
|
||||
return f"data: {json.dumps(data, ensure_ascii=False)}\n\n"
|
||||
"""保留旧测试入口并委托独立 OpenAI SSE wire mapper。"""
|
||||
return encode_data_event(data)
|
||||
|
||||
|
||||
async def _stream_response(
|
||||
@@ -519,7 +520,7 @@ async def chat_completions(
|
||||
session_id = build_session_id(session_key, SESSION_PREFIX)
|
||||
username = str(payload.user or "openai-client")
|
||||
if payload.stream:
|
||||
return StreamingResponse(
|
||||
return build_sse_response(
|
||||
_stream_response(
|
||||
manager=manager,
|
||||
session_id=session_id,
|
||||
@@ -529,12 +530,6 @@ async def chat_completions(
|
||||
images=images,
|
||||
cleanup_session=not use_server_session,
|
||||
),
|
||||
media_type="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no",
|
||||
},
|
||||
)
|
||||
|
||||
collected_messages = []
|
||||
|
||||
@@ -46,9 +46,11 @@ from app.adapters.web.security.access import (
|
||||
)
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_superuser,
|
||||
get_current_active_superuser_async,
|
||||
)
|
||||
from app.api.dependencies.plugin import (
|
||||
get_plugin_config_command,
|
||||
)
|
||||
from app.adapters.external.server import MoviePilotServerHelper
|
||||
|
||||
@@ -26,11 +26,13 @@ from app.application.plugin.runtime import get_plugin_manager as PluginManager
|
||||
from app.adapters.web.security.access import verify_token
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_manage_user,
|
||||
get_current_active_manage_user_async,
|
||||
get_current_active_superuser,
|
||||
get_current_active_superuser_async,
|
||||
)
|
||||
from app.api.dependencies.site import (
|
||||
get_site_mutation_command,
|
||||
get_site_query_service,
|
||||
get_site_sync_query_service,
|
||||
|
||||
@@ -16,7 +16,7 @@ from app.chain.storage import StorageChain
|
||||
from app.chain.transfer import TransferChain
|
||||
from app.runtime.config import settings
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_manage_user,
|
||||
get_current_active_superuser,
|
||||
)
|
||||
|
||||
@@ -36,9 +36,11 @@ from app.application.subscription.mutation import (
|
||||
SubscriptionMutationService,
|
||||
)
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_user,
|
||||
get_current_active_user_async,
|
||||
)
|
||||
from app.api.dependencies.subscription import (
|
||||
get_delete_subscribe_command,
|
||||
get_delete_subscriptions_by_identity_command,
|
||||
get_search_subscriptions_command,
|
||||
|
||||
@@ -42,7 +42,11 @@ from app.application.module import ModuleManager
|
||||
from app.adapters.web.security.access import verify_apitoken, verify_resource_token, verify_token
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import get_current_active_superuser, get_current_active_superuser_async, get_current_active_user_async
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_superuser,
|
||||
get_current_active_superuser_async,
|
||||
get_current_active_user_async,
|
||||
)
|
||||
from app.application.image import ImageHelper
|
||||
from app.runtime.localization import LocaleHelper
|
||||
from app.adapters.external.market import (
|
||||
|
||||
@@ -14,7 +14,7 @@ from app.chain.tmdb import TmdbChain
|
||||
from app.runtime.config import settings
|
||||
from app.adapters.web.security.access import verify_token
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import get_current_active_superuser_async
|
||||
from app.api.dependencies.auth import get_current_active_superuser_async
|
||||
from app.schemas.types import MediaType, SystemConfigKey
|
||||
|
||||
router = ResponseAPIRouter()
|
||||
|
||||
@@ -12,7 +12,10 @@ from app.runtime.config import settings
|
||||
from app.domain.context import MediaInfo, MusicInfo
|
||||
from app.domain.meta.metamusic import MetaMusic
|
||||
from app.domain.metainfo import MetaInfo
|
||||
from app.api.deps import get_current_active_superuser, get_current_active_superuser_async
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_superuser,
|
||||
get_current_active_superuser_async,
|
||||
)
|
||||
from app.schemas.types import (
|
||||
MUSIC_ENTITY_RECORDING,
|
||||
MediaSource,
|
||||
|
||||
@@ -19,10 +19,8 @@ from app.chain.media import MediaChain
|
||||
from app.chain.transfer import TransferChain
|
||||
from app.runtime.config import settings, global_vars
|
||||
from app.adapters.web.security.access import verify_token, verify_apitoken
|
||||
from app.api.deps import (
|
||||
get_current_active_manage_user,
|
||||
get_transfer_history_lookup_service,
|
||||
)
|
||||
from app.api.dependencies.auth import get_current_active_manage_user
|
||||
from app.api.dependencies.history import get_transfer_history_lookup_service
|
||||
from app.application.directory import DirectoryHelper
|
||||
from app.application.history import TransferHistoryLookupService
|
||||
from app.runtime.log import logger
|
||||
@@ -304,12 +302,26 @@ def manual_transfer(
|
||||
_: object = Depends(get_current_active_manage_user),
|
||||
) -> Any:
|
||||
"""
|
||||
手动转移,文件或历史记录,支持自定义剧集识别格式
|
||||
解析手动整理 HTTP 请求并委托兼容用例处理器。
|
||||
|
||||
:param transer_item: 手工整理项
|
||||
:param background: 后台运行
|
||||
:param history_query: 整理历史投影服务
|
||||
:param _: Token校验
|
||||
"""
|
||||
return _execute_manual_transfer(
|
||||
transer_item=transer_item,
|
||||
background=background,
|
||||
history_query=history_query,
|
||||
)
|
||||
|
||||
|
||||
def _execute_manual_transfer(
|
||||
transer_item: ManualTransferItem,
|
||||
background: Optional[bool],
|
||||
history_query: TransferHistoryLookupService,
|
||||
) -> Any:
|
||||
"""执行历史恢复、批量预览与 TransferChain 兼容编排。"""
|
||||
force = False
|
||||
downloader = None
|
||||
download_hash = None
|
||||
|
||||
@@ -13,7 +13,7 @@ from app.schemas.user import UserUpdate as _SchemaUserUpdate
|
||||
from app.api.response import ResponseAPIRouter
|
||||
from app.application.security.token import PasswordTooLongError, get_password_hash
|
||||
from app.application.security.user import UserService
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_superuser_async,
|
||||
get_current_active_user_async,
|
||||
get_current_active_user,
|
||||
|
||||
@@ -17,9 +17,11 @@ from app.application.workflow import (
|
||||
from app.chain.workflow import WorkflowChain
|
||||
from app.application.plugin.runtime import get_plugin_manager as PluginManager
|
||||
from app.workflow import WorkFlowManager
|
||||
from app.api.deps import (
|
||||
from app.api.dependencies.auth import (
|
||||
get_current_active_manage_user,
|
||||
get_current_active_manage_user_async,
|
||||
)
|
||||
from app.api.dependencies.workflow import (
|
||||
get_workflow_definition_command,
|
||||
get_workflow_mutation_command,
|
||||
get_workflow_query_service,
|
||||
|
||||
Reference in New Issue
Block a user