mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-06 07:56:52 +08:00
refactor: 推进后端分层架构治理
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""手工订阅搜索应用用例。"""
|
||||
|
||||
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[[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",
|
||||
)
|
||||
for current_id in subscribe_ids:
|
||||
self._schedule_search(current_id, 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
|
||||
Reference in New Issue
Block a user