Files
MoviePilot/app/api/endpoints/subexecution.py

99 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""订阅执行批次状态与取消端点。"""
from typing import Any, List, Optional
from fastapi import Depends, HTTPException
from app.api.dependencies.auth import get_current_active_user_async
from app.api.dependencies.subscription import (
get_subscription_execution_status_service,
get_subscription_query_service,
)
from app.api.principal import ApiPrincipal
from app.api.response import ResponseAPIRouter
from app.application.subscription.query import SubscriptionQueryService
from app.application.subscription.status import SubscriptionExecutionStatusService
from app.schemas.response import Response as _SchemaResponse
from app.schemas.subscribe import SubscriptionBatchStatus as _SchemaSubscriptionBatchStatus
router = ResponseAPIRouter()
async def _accessible_subscription_ids(
query: SubscriptionQueryService,
current_user: ApiPrincipal,
) -> Optional[set[int]]:
"""返回普通用户可访问订阅 ID超级用户以 None 表示不限制。"""
if current_user.is_superuser:
return None
subscribes = await query.list_public(current_user.name)
return {item.id for item in subscribes if item.id is not None}
@router.get( # type: ignore[misc]
"/execution/batches",
summary="查看订阅搜索进度",
response_model=List[_SchemaSubscriptionBatchStatus],
)
async def list_subscription_execution_batches(
limit: int = 10,
status_service: SubscriptionExecutionStatusService = Depends(get_subscription_execution_status_service),
query: SubscriptionQueryService = Depends(get_subscription_query_service),
current_user: ApiPrincipal = Depends(get_current_active_user_async),
) -> Any:
"""返回当前用户完整可见的最近搜索批次。"""
accessible_ids = await _accessible_subscription_ids(query, current_user)
batches = await status_service.list_batches(
accessible_subscription_ids=accessible_ids,
limit=limit,
)
return [_SchemaSubscriptionBatchStatus.model_validate(batch) for batch in batches]
@router.get( # type: ignore[misc]
"/execution/batches/{batch_id}",
summary="查看一次订阅搜索",
response_model=_SchemaSubscriptionBatchStatus,
)
async def get_subscription_execution_batch(
batch_id: str,
status_service: SubscriptionExecutionStatusService = Depends(get_subscription_execution_status_service),
query: SubscriptionQueryService = Depends(get_subscription_query_service),
current_user: ApiPrincipal = Depends(get_current_active_user_async),
) -> Any:
"""按稳定 ID 返回当前用户可访问的搜索批次。"""
accessible_ids = await _accessible_subscription_ids(query, current_user)
batch = await status_service.get_batch(
batch_id,
accessible_subscription_ids=accessible_ids,
)
if batch is None:
raise HTTPException(status_code=404, detail="没有找到这次搜索,请刷新后重试")
return _SchemaSubscriptionBatchStatus.model_validate(batch)
@router.put( # type: ignore[misc]
"/execution/batches/{batch_id}/cancel",
summary="停止一次订阅搜索",
response_model=_SchemaResponse[None],
)
async def cancel_subscription_execution_batch(
batch_id: str,
status_service: SubscriptionExecutionStatusService = Depends(get_subscription_execution_status_service),
query: SubscriptionQueryService = Depends(get_subscription_query_service),
current_user: ApiPrincipal = Depends(get_current_active_user_async),
) -> Any:
"""在权限校验后请求取消尚未越过下载副作用边界的任务。"""
accessible_ids = await _accessible_subscription_ids(query, current_user)
batch = await status_service.get_batch(
batch_id,
accessible_subscription_ids=accessible_ids,
)
if batch is None:
return _SchemaResponse(success=False, message="没有找到这次搜索,请刷新后重试")
cancelled = await status_service.request_cancel(batch_id)
return _SchemaResponse(
success=bool(cancelled),
message="" if cancelled else "这次搜索已经结束,暂时无法停止",
)