mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-28 19:47:41 +08:00
refactor: 收口 V3 分层架构与插件兼容边界
This commit is contained in:
@@ -140,6 +140,14 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
return DownloadHistory.list_by_page(self._db, page, count)
|
||||
|
||||
async def async_list_by_page(
|
||||
self,
|
||||
page: int = 1,
|
||||
count: int = 30,
|
||||
) -> List[DownloadHistory]:
|
||||
"""异步分页查询下载历史。"""
|
||||
return await DownloadHistory.async_list_by_page(self._db, page, count)
|
||||
|
||||
async def async_delete_history(self, historyid: int):
|
||||
"""
|
||||
异步删除下载记录。
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
"""PassKey 数据访问适配器。"""
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from app.db.base import DbOper
|
||||
from app.db.models.passkey import PassKey
|
||||
|
||||
|
||||
class PassKeyOper(DbOper):
|
||||
"""封装 PassKey 查询和维护,避免 API 层直接引用模型静态方法。"""
|
||||
|
||||
def list_by_user_id(self, user_id: int) -> list[PassKey]:
|
||||
"""读取用户启用的 PassKey。"""
|
||||
return PassKey.get_by_user_id(self._db, user_id)
|
||||
|
||||
def list(self) -> list[PassKey]:
|
||||
"""读取全部 PassKey,用于判断系统是否已配置通行密钥。"""
|
||||
return PassKey.list(self._db)
|
||||
|
||||
def get_by_credential_id(self, credential_id: str) -> Optional[PassKey]:
|
||||
"""按凭证 ID 读取启用的 PassKey。"""
|
||||
return PassKey.get_by_credential_id(self._db, credential_id)
|
||||
|
||||
def create(self, payload: dict[str, Any]) -> PassKey:
|
||||
"""创建 PassKey 凭证。"""
|
||||
passkey = PassKey(**payload)
|
||||
passkey.create(self._db)
|
||||
return passkey
|
||||
|
||||
def update_last_used(self, passkey: PassKey, sign_count: int) -> bool:
|
||||
"""更新凭证最后使用时间和签名计数。"""
|
||||
return bool(passkey.update_last_used(self._db, sign_count))
|
||||
|
||||
def delete_by_id(self, passkey_id: int, user_id: int) -> bool:
|
||||
"""删除指定用户的凭证。"""
|
||||
return bool(PassKey.delete_by_id(self._db, passkey_id, user_id))
|
||||
@@ -91,6 +91,10 @@ class SiteOper(DbOper):
|
||||
"""
|
||||
return await Site.async_list(self._db)
|
||||
|
||||
async def async_list_order_by_pri(self) -> List[Site]:
|
||||
"""异步按优先级获取站点,供站点查询应用服务使用。"""
|
||||
return await Site.async_list_order_by_pri(self._db)
|
||||
|
||||
def list_order_by_pri(self) -> List[Site]:
|
||||
"""
|
||||
获取站点列表
|
||||
@@ -115,6 +119,14 @@ class SiteOper(DbOper):
|
||||
"""
|
||||
Site.delete(self._db, sid)
|
||||
|
||||
def reset(self) -> None:
|
||||
"""清空站点表,保留站点模型细节在数据库适配层。"""
|
||||
Site.reset(self._db)
|
||||
|
||||
async def stage_reset(self) -> None:
|
||||
"""暂存清空站点表,由应用事务统一提交。"""
|
||||
await self._db.execute(sqlalchemy_delete(Site))
|
||||
|
||||
def update(self, sid: int, payload: dict) -> Optional[Site]:
|
||||
"""
|
||||
更新站点
|
||||
@@ -235,6 +247,25 @@ class SiteOper(DbOper):
|
||||
self._db, domain=domain, workdate=workdate
|
||||
)
|
||||
|
||||
async def async_get_userdata_latest(self) -> List[SiteUserData]:
|
||||
"""异步获取各站点最新用户数据。"""
|
||||
return await SiteUserData.async_get_latest(self._db)
|
||||
|
||||
async def async_get_icon_by_domain(self, domain: str) -> Optional[SiteIcon]:
|
||||
"""异步按域名获取站点图标。"""
|
||||
return await SiteIcon.async_get_by_domain(self._db, domain)
|
||||
|
||||
async def async_get_statistic_by_domain(
|
||||
self,
|
||||
domain: str,
|
||||
) -> Optional[SiteStatistic]:
|
||||
"""异步按域名获取站点统计。"""
|
||||
return await SiteStatistic.async_get_by_domain(self._db, domain)
|
||||
|
||||
async def async_list_statistics(self) -> List[SiteStatistic]:
|
||||
"""异步获取所有站点统计。"""
|
||||
return await SiteStatistic.async_list(self._db)
|
||||
|
||||
def get_userdata_by_date(self, date: str) -> List[SiteUserData]:
|
||||
"""
|
||||
获取站点用户数据
|
||||
|
||||
@@ -145,6 +145,21 @@ class SubscribeOper(DbOper):
|
||||
}
|
||||
return bool(Subscribe.exists(self._db, **identity_params))
|
||||
|
||||
async def async_exists(
|
||||
self, media_source: MediaSource, media_id: str,
|
||||
season: Optional[int] = None, episode_group: Optional[str] = None,
|
||||
music_type: Optional[str] = None,
|
||||
) -> Optional[Subscribe]:
|
||||
"""异步按媒体身份、季号及可选剧集组读取命中的订阅。"""
|
||||
return await Subscribe.async_exists(
|
||||
self._db,
|
||||
media_source=media_source,
|
||||
media_id=media_id,
|
||||
music_type=music_type,
|
||||
season=season,
|
||||
episode_group=episode_group,
|
||||
)
|
||||
|
||||
def get(self, sid: int) -> Optional[Subscribe]:
|
||||
"""
|
||||
获取订阅
|
||||
@@ -157,6 +172,34 @@ class SubscribeOper(DbOper):
|
||||
"""
|
||||
return await Subscribe.async_get(self._db, rid=sid)
|
||||
|
||||
async def async_list_by_media_identity(
|
||||
self,
|
||||
media_source: MediaSource,
|
||||
media_id: str,
|
||||
music_type: Optional[str] = None,
|
||||
) -> List[Subscribe]:
|
||||
"""异步按规范媒体身份读取订阅。"""
|
||||
return await Subscribe.async_list_by_media_identity(
|
||||
self._db,
|
||||
media_source=media_source,
|
||||
media_id=media_id,
|
||||
music_type=music_type,
|
||||
)
|
||||
|
||||
def list_by_media_identity(
|
||||
self,
|
||||
media_source: MediaSource,
|
||||
media_id: str,
|
||||
music_type: Optional[str] = None,
|
||||
) -> List[Subscribe]:
|
||||
"""同步按规范媒体身份读取订阅。"""
|
||||
return Subscribe.list_by_media_identity(
|
||||
self._db,
|
||||
media_source=media_source,
|
||||
media_id=media_id,
|
||||
music_type=music_type,
|
||||
)
|
||||
|
||||
async def get_candidate(
|
||||
self,
|
||||
subscribe_id: int,
|
||||
@@ -266,6 +309,32 @@ class SubscribeOper(DbOper):
|
||||
return await Subscribe.async_get_by_state(self._db, state)
|
||||
return await Subscribe.async_list(self._db)
|
||||
|
||||
async def async_list_by_username(
|
||||
self,
|
||||
username: str,
|
||||
state: Optional[str] = None,
|
||||
mtype: Optional[str] = None,
|
||||
) -> List[Subscribe]:
|
||||
"""异步按用户获取订阅。"""
|
||||
return await Subscribe.async_list_by_username(
|
||||
self._db,
|
||||
username=username,
|
||||
state=state,
|
||||
mtype=mtype,
|
||||
)
|
||||
|
||||
async def async_list_by_title(
|
||||
self,
|
||||
title: str,
|
||||
season: Optional[int] = None,
|
||||
) -> List[Subscribe]:
|
||||
"""异步按标题获取订阅,供旧查询测试和迁移调用兼容。"""
|
||||
return await Subscribe.async_list_by_title(
|
||||
self._db,
|
||||
title=title,
|
||||
season=season,
|
||||
)
|
||||
|
||||
def delete(self, sid: int):
|
||||
"""
|
||||
删除订阅
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from app.db.base import DbOper
|
||||
from app.db.models.subscribehistory import SubscribeHistory
|
||||
@@ -24,3 +24,27 @@ class SubscribeHistoryOper(DbOper):
|
||||
page=page,
|
||||
count=count,
|
||||
)
|
||||
|
||||
async def async_list_by_type_and_username(
|
||||
self,
|
||||
mtype: str,
|
||||
username: str,
|
||||
page: int = 1,
|
||||
count: int = 30,
|
||||
) -> List[SubscribeHistory]:
|
||||
"""异步按媒体类型和用户分页查询订阅历史。"""
|
||||
return await SubscribeHistory.async_list_by_type_and_username(
|
||||
self._db,
|
||||
mtype=mtype,
|
||||
username=username,
|
||||
page=page,
|
||||
count=count,
|
||||
)
|
||||
|
||||
async def async_get(self, history_id: int) -> Optional[SubscribeHistory]:
|
||||
"""异步按 ID 查询订阅历史。"""
|
||||
return await SubscribeHistory.async_get(self._db, history_id)
|
||||
|
||||
async def async_delete(self, history_id: int) -> None:
|
||||
"""异步删除订阅历史。"""
|
||||
await SubscribeHistory.async_delete(self._db, history_id)
|
||||
|
||||
@@ -32,12 +32,18 @@ class TransferHistoryOper(DbOper):
|
||||
page: int = 1,
|
||||
count: int = 30,
|
||||
status: Optional[bool] = None,
|
||||
wildcard: bool = False,
|
||||
) -> List[TransferHistory]:
|
||||
"""
|
||||
异步按标题分页查询转移记录。
|
||||
"""
|
||||
return await TransferHistory.async_list_by_title(
|
||||
self._db, title=title, page=page, count=count, status=status
|
||||
self._db,
|
||||
title=title,
|
||||
page=page,
|
||||
count=count,
|
||||
status=status,
|
||||
wildcard=wildcard,
|
||||
)
|
||||
|
||||
async def async_list_by_page(
|
||||
@@ -63,12 +69,16 @@ class TransferHistoryOper(DbOper):
|
||||
self,
|
||||
title: str,
|
||||
status: Optional[bool] = None,
|
||||
wildcard: bool = False,
|
||||
) -> Optional[int]:
|
||||
"""
|
||||
异步按标题统计转移记录数量。
|
||||
"""
|
||||
return await TransferHistory.async_count_by_title(
|
||||
self._db, title=title, status=status
|
||||
self._db,
|
||||
title=title,
|
||||
status=status,
|
||||
wildcard=wildcard,
|
||||
)
|
||||
|
||||
def get_by_title(self, title: str) -> List[TransferHistory]:
|
||||
@@ -174,6 +184,14 @@ class TransferHistoryOper(DbOper):
|
||||
"""
|
||||
return TransferHistory.statistic(self._db, days)
|
||||
|
||||
async def async_statistic(self, days: int = 7) -> List[Any]:
|
||||
"""异步统计最近若干天的整理历史数量。"""
|
||||
return await TransferHistory.async_statistic(self._db, days)
|
||||
|
||||
def monthly_media_statistics(self) -> tuple[int, int, int, int]:
|
||||
"""统计本月成功整理的电影、剧集、单集和音乐数量。"""
|
||||
return TransferHistory.monthly_media_statistics(self._db)
|
||||
|
||||
def get_by(self, title: Optional[str] = None, year: Optional[str] = None, mtype: Optional[str] = None,
|
||||
season: Optional[str] = None, episode: Optional[str] = None,
|
||||
media_source: Optional[MediaSource] = None, media_id: Optional[str] = None,
|
||||
|
||||
@@ -39,6 +39,38 @@ class UserOper(DbOper):
|
||||
"""
|
||||
return User.get_by_name(self._db, name)
|
||||
|
||||
def get_by_id(self, user_id: int) -> Optional[User]:
|
||||
"""按 ID 获取用户。"""
|
||||
return User.get_by_id(self._db, user_id)
|
||||
|
||||
async def async_list(self) -> List[User]:
|
||||
"""异步获取用户列表。"""
|
||||
return await User.async_list(self._db)
|
||||
|
||||
async def async_create(self, payload: dict) -> Optional[User]:
|
||||
"""异步创建用户。"""
|
||||
return await User(**payload).async_create(self._db)
|
||||
|
||||
async def async_update(self, user_id: int, payload: dict) -> Optional[User]:
|
||||
"""异步更新用户。"""
|
||||
user = await self.async_get_by_id(user_id)
|
||||
if user:
|
||||
await user.async_update(self._db, payload)
|
||||
return user
|
||||
|
||||
async def async_delete(self, user_id: int) -> None:
|
||||
"""异步删除用户。"""
|
||||
await User.async_delete_by_id(self._db, user_id)
|
||||
|
||||
async def async_update_otp_by_name(
|
||||
self,
|
||||
name: str,
|
||||
otp: bool,
|
||||
secret: str,
|
||||
) -> None:
|
||||
"""异步更新用户 OTP 状态。"""
|
||||
await User.async_update_otp_by_name(self._db, name, otp, secret)
|
||||
|
||||
async def async_get_by_name(self, name: str) -> Optional[User]:
|
||||
"""
|
||||
异步根据用户名获取用户。
|
||||
|
||||
Reference in New Issue
Block a user