fix(compat): preserve legacy plugin imports

This commit is contained in:
jxxghp
2026-08-15 07:15:03 +08:00
parent 8a11214a43
commit a2117bafc8
13 changed files with 831 additions and 17 deletions
+1
View File
@@ -0,0 +1 @@
"""只供旧导入映射使用的插件兼容门面;新插件不得直接依赖本包。"""
+70
View File
@@ -0,0 +1,70 @@
"""把旧整理历史 Oper 的业务写入方法转交给应用服务。"""
from typing import Optional
from app.application.history import add_transfer_fail, add_transfer_success
from app.db.models.transferhistory import TransferHistory
from app.db.oper.transferhistory import TransferHistoryOper as CanonicalTransferHistoryOper
from app.domain.context import MediaInfo, MusicInfo
from app.domain.meta.metabase import MetaBase
from app.schemas.file import FileItem
from app.schemas.transfer import TransferInfo
class TransferHistoryOper(CanonicalTransferHistoryOper):
"""继承新的查询接口,并保留旧的成功/失败历史写入方法。"""
def add_success(
self,
fileitem: FileItem,
mode: str,
meta: MetaBase,
mediainfo: MediaInfo | MusicInfo,
transferinfo: TransferInfo,
downloader: Optional[str] = None,
download_hash: Optional[str] = None,
) -> Optional[TransferHistory]:
"""
按旧签名新增整理成功历史。
:return: 落库后的整理记录
"""
return add_transfer_success(
fileitem=fileitem,
mode=mode,
meta=meta,
mediainfo=mediainfo,
transferinfo=transferinfo,
downloader=downloader,
download_hash=download_hash,
transfer_history_oper=self,
)
def add_fail(
self,
fileitem: FileItem,
mode: str,
meta: MetaBase,
mediainfo: Optional[MediaInfo | MusicInfo] = None,
transferinfo: Optional[TransferInfo] = None,
downloader: Optional[str] = None,
download_hash: Optional[str] = None,
) -> Optional[TransferHistory]:
"""
按旧签名新增整理失败历史。
:return: 落库后的整理记录
"""
return add_transfer_fail(
fileitem=fileitem,
mode=mode,
meta=meta,
mediainfo=mediainfo,
transferinfo=transferinfo,
downloader=downloader,
download_hash=download_hash,
transfer_history_oper=self,
)
__all__ = ["TransferHistoryOper"]
+75
View File
@@ -0,0 +1,75 @@
"""把旧订阅 Oper 写入调用转交给新的应用服务。"""
from typing import Any, Optional
from app.application.subscribe import add_subscribe, async_add_subscribe
from app.db.models.subscribe import Subscribe
from app.db.oper.subscribe import SubscribeOper as CanonicalSubscribeOper
from app.domain.context import MediaInfo, MusicInfo
class SubscribeOper(CanonicalSubscribeOper):
"""保留旧 ``mediainfo`` 写入签名,同时继承新的查询接口。"""
def add(
self,
mediainfo: Optional[MediaInfo | MusicInfo] = None,
**kwargs: Any,
):
"""
兼容旧订阅写入;应用服务回调的新字典签名直接交给 canonical Oper。
:param mediainfo: 旧调用传入的媒体识别结果
:param kwargs: 旧订阅配置,或新 Oper 的 identity/payload/username
:return: 订阅 ID 与结果说明
"""
if mediainfo is None and "identity" in kwargs and "payload" in kwargs:
identity = kwargs.pop("identity")
payload = kwargs.pop("payload")
username = kwargs.pop("username", None)
if kwargs:
unexpected = ", ".join(sorted(kwargs))
raise TypeError(f"SubscribeOper.add 收到未知参数:{unexpected}")
return super().add(
identity=identity,
payload=payload,
username=username,
)
return add_subscribe(
mediainfo=mediainfo,
subscribe_oper=self,
**kwargs,
)
async def async_add(
self,
mediainfo: Optional[MediaInfo | MusicInfo] = None,
**kwargs: Any,
):
"""
异步兼容旧订阅写入;新字典签名直接交给 canonical Oper。
:param mediainfo: 旧调用传入的媒体识别结果
:param kwargs: 旧订阅配置,或新 Oper 的 identity/payload/username
:return: 订阅 ID 与结果说明
"""
if mediainfo is None and "identity" in kwargs and "payload" in kwargs:
identity = kwargs.pop("identity")
payload = kwargs.pop("payload")
username = kwargs.pop("username", None)
if kwargs:
unexpected = ", ".join(sorted(kwargs))
raise TypeError(f"SubscribeOper.async_add 收到未知参数:{unexpected}")
return await super().async_add(
identity=identity,
payload=payload,
username=username,
)
return await async_add_subscribe(
mediainfo=mediainfo,
subscribe_oper=self,
**kwargs,
)
__all__ = ["Subscribe", "SubscribeOper"]
+44
View File
@@ -0,0 +1,44 @@
"""保留旧 schemas 整理工作项的宽松构造契约。"""
from typing import Any, Optional
from app.application.transfer import (
TransferQueue as CanonicalTransferQueue,
TransferTask as CanonicalTransferTask,
)
def _serialize_legacy_value(value: Any) -> Any:
"""同时支持旧 Pydantic 对象与新的领域对象序列化接口。"""
if value is None:
return None
if callable(getattr(value, "to_dict", None)):
return value.to_dict()
if callable(getattr(value, "model_dump", None)):
return value.model_dump()
return value
class TransferTask(CanonicalTransferTask):
"""兼容旧任务允许插件传入自定义 meta/mediainfo 对象的行为。"""
meta: Optional[Any] = None
mediainfo: Optional[Any] = None
def to_dict(self):
"""返回兼容领域对象和旧 Pydantic 对象的任务字典。"""
values = vars(self).copy()
values["fileitem"] = _serialize_legacy_value(self.fileitem)
values["meta"] = _serialize_legacy_value(self.meta)
values["mediainfo"] = _serialize_legacy_value(self.mediainfo)
values["target_directory"] = _serialize_legacy_value(self.target_directory)
return values
class TransferQueue(CanonicalTransferQueue):
"""让旧宽松任务可以继续进入新的整理队列。"""
task: Optional[TransferTask] = None
__all__ = ["TransferQueue", "TransferTask"]
+28
View File
@@ -0,0 +1,28 @@
"""兼容旧 ``app.db.user_oper`` 中混合的数据访问与认证依赖。"""
from app.api.deps import (
get_current_active_manage_user,
get_current_active_manage_user_async,
get_current_active_superuser,
get_current_active_superuser_async,
get_current_active_user,
get_current_active_user_async,
get_current_user,
get_current_user_async,
)
from app.db.oper.user import UserOper
from app.db.models.user import User
__all__ = [
"UserOper",
"User",
"get_current_active_manage_user",
"get_current_active_manage_user_async",
"get_current_active_superuser",
"get_current_active_superuser_async",
"get_current_active_user",
"get_current_active_user_async",
"get_current_user",
"get_current_user_async",
]
+35 -1
View File
@@ -1,4 +1,4 @@
"""插件使用的媒体上下文、标题解析识别类型。"""
"""插件使用的媒体上下文、标题解析识别类型和媒体身份规则"""
from app.domain.context import Context, MediaInfo, TorrentInfo
from app.domain.meta.metaanime import MetaAnime
@@ -17,10 +17,33 @@ from app.domain.meta.words import WordsMatcher
from app.domain.metainfo import MetaInfo, MetaInfoPath
from app.domain.scraper import NfoReader
from app.domain.tokens import Tokens
from app.domain.media import (
MUSIC_MEDIA_SOURCE_ORDER,
MUSIC_MEDIA_SOURCES,
configure_search_source_provider,
is_media_source_enabled,
is_media_source_selected,
is_music_media_source,
normalize_music_type,
parse_media_source_selection,
)
from app.schemas.media import (
MEDIA_SOURCE_ALIASES,
MEDIA_SOURCE_PREFIXES,
build_media_key,
normalize_media_identity_payload,
normalize_media_source,
parse_media_key,
resolve_media_identity,
)
__all__ = [
"Context",
"MEDIA_SOURCE_ALIASES",
"MEDIA_SOURCE_PREFIXES",
"MUSIC_MEDIA_SOURCE_ORDER",
"MUSIC_MEDIA_SOURCES",
"MediaInfo",
"MetaAnime",
"MetaBase",
@@ -38,4 +61,15 @@ __all__ = [
"MusicNameRegistry",
"TorrentInfo",
"WordsMatcher",
"build_media_key",
"configure_search_source_provider",
"is_media_source_enabled",
"is_media_source_selected",
"is_music_media_source",
"normalize_media_identity_payload",
"normalize_media_source",
"normalize_music_type",
"parse_media_key",
"parse_media_source_selection",
"resolve_media_identity",
]