mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-29 20:17:13 +08:00
83 lines
2.5 KiB
Python
83 lines
2.5 KiB
Python
"""手工订阅搜索应用用例。"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Callable, Protocol
|
|
|
|
from app.application.subscription.delete import SubscribeDeletionCandidate
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class SubscribeSearchActor:
|
|
"""执行手工订阅搜索的用户身份。"""
|
|
|
|
username: str
|
|
is_superuser: bool
|
|
|
|
|
|
class SubscribeSearchRepository(Protocol):
|
|
"""手工订阅搜索所需的最小读取端口。"""
|
|
|
|
async def get_candidate(
|
|
self,
|
|
subscribe_id: int,
|
|
) -> SubscribeDeletionCandidate | None:
|
|
"""读取单条订阅的归属信息。"""
|
|
...
|
|
|
|
async def list_search_ids(self, username: str, state: str) -> list[int]:
|
|
"""返回用户当前可搜索状态下的订阅编号。"""
|
|
...
|
|
|
|
|
|
SubscribeSearchScheduler = Callable[[tuple[int, ...] | None, str | None], None]
|
|
|
|
|
|
class SearchSubscriptionsCommand:
|
|
"""按用户权限生成并提交手工订阅搜索任务。"""
|
|
|
|
def __init__(
|
|
self,
|
|
repository: SubscribeSearchRepository,
|
|
schedule_search: SubscribeSearchScheduler,
|
|
) -> None:
|
|
"""注入订阅读取端口和后台任务提交端口。"""
|
|
self._repository = repository
|
|
self._schedule_search = schedule_search
|
|
|
|
async def execute(
|
|
self,
|
|
actor: SubscribeSearchActor,
|
|
subscribe_id: int | None = None,
|
|
) -> bool:
|
|
"""提交单条或当前用户全部可搜索订阅,返回目标是否存在。"""
|
|
if subscribe_id is not None:
|
|
candidate = await self._repository.get_candidate(subscribe_id)
|
|
if not self._can_access(candidate, actor):
|
|
return False
|
|
self._schedule_search((subscribe_id,), None)
|
|
return True
|
|
|
|
if actor.is_superuser:
|
|
self._schedule_search(None, "R")
|
|
return True
|
|
|
|
subscribe_ids = await self._repository.list_search_ids(
|
|
actor.username,
|
|
"R",
|
|
)
|
|
if subscribe_ids:
|
|
self._schedule_search(tuple(subscribe_ids), None)
|
|
return True
|
|
|
|
@staticmethod
|
|
def _can_access(
|
|
candidate: SubscribeDeletionCandidate | None,
|
|
actor: SubscribeSearchActor,
|
|
) -> bool:
|
|
"""沿用订阅读取接口的超级用户和归属用户权限语义。"""
|
|
if candidate is None:
|
|
return False
|
|
if actor.is_superuser:
|
|
return True
|
|
return bool(candidate.username) and candidate.username == actor.username
|