Files
MoviePilot/app/db/oper/__init__.py
DDSRem 2de976f6b3 Merge pull request #7050 from DDSRem-Dev/codex-comment-migration
docs: 统一全项目中文注释和结构化契约说明
2026-10-17 19:26:29 +08:00

91 lines
3.4 KiB
Python
Raw Permalink 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.
"""
数据访问层(Oper)。
与 app/db/models 一一对应:models 声明表结构,oper 承载针对该表的读写。
两个包同名文件互为镜像(models/subscribe.py ↔ oper/subscribe.py),
文件名只写实体,角色由包名表达,因此这里不再有 `_oper` 后缀。
本文件只做符号解析,不在 import 期执行任何动作——没有建引擎、没有连库、
也不会把其余 Oper 模块一并拉起。包根仅保留尚未迁移的 canonical Oper;
已迁移符号由 runtime compat 精确叠加,不在这里重复导出。
这一点不是洁癖:多处测试靠往 sys.modules 塞桩来隔离单个 Oper(例如
app.db.oper.systemconfig),若本文件改成 models/__init__.py 那样的即时
re-export,导入任意一个 Oper 都会连带把其余十五个真正拉起来,桩就被绕过了。
按模块直连(from app.db.oper.subscribe import SubscribeOper)仍是仓库内的
首选写法,本入口是给「只想要一个类名」的调用方备的门面。
"""
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
# 运行期由 __getattr__ 解析,模块 __dict__ 里并不存在这些名字;
# 这里为静态检查补上真实类型,同时消掉 __all__ 的未定义告警。
from app.db.oper.agentchat import AgentChatOper
from app.db.oper.agenttask import AgentTaskOper
from app.db.oper.downloadfailure import DownloadFailureOper
from app.db.oper.downloadhistory import DownloadHistoryOper
from app.db.oper.mediaserver import MediaServerOper
from app.db.oper.message import MessageOper
from app.db.oper.plugindata import PluginDataOper
from app.db.oper.systemconfig import SystemConfigOper
from app.db.oper.transferpending import TransferPendingOper
from app.db.oper.transfersettlementreceipt import TransferSettlementReceiptOper
from app.db.oper.user import UserOper
from app.db.oper.userconfig import UserConfigOper
# 类名 -> 所在子模块。子模块名即实体名,与 app/db/models 对齐。
_OPER_MODULES = {
"AgentChatOper": "agentchat",
"AgentTaskOper": "agenttask",
"DownloadFailureOper": "downloadfailure",
"DownloadHistoryOper": "downloadhistory",
"MediaServerOper": "mediaserver",
"MessageOper": "message",
"PluginDataOper": "plugindata",
"SystemConfigOper": "systemconfig",
"TransferPendingOper": "transferpending",
"TransferSettlementReceiptOper": "transfersettlementreceipt",
"UserConfigOper": "userconfig",
"UserOper": "user",
}
def __getattr__(name: str) -> Any:
"""
惰性解析 Oper 类,只导入被点名的那个子模块。
:param name: 属性名
:return: 对应的 Oper 类
"""
module_name = _OPER_MODULES.get(name)
if module_name is None:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
from importlib import import_module
return getattr(import_module(f"{__name__}.{module_name}"), name)
def __dir__() -> list[str]:
"""
让 dir() 与自动补全看得见惰性名字。
:return: 属性名列表
"""
return sorted({*globals(), *_OPER_MODULES})
__all__ = [
"AgentChatOper",
"AgentTaskOper",
"DownloadFailureOper",
"DownloadHistoryOper",
"MediaServerOper",
"MessageOper",
"PluginDataOper",
"SystemConfigOper",
"TransferPendingOper",
"TransferSettlementReceiptOper",
"UserConfigOper",
"UserOper",
]