feat(sdk): expose custom separator configuration

This commit is contained in:
InfinityPacer
2026-08-31 18:00:27 +08:00
committed by GitHub
parent 3876119375
commit e9313c6644
8 changed files with 50 additions and 5 deletions
+9
View File
@@ -18,6 +18,15 @@ def get_customization() -> object:
return _customization_provider()
def set_custom_separator(separator: str | None) -> None:
"""设置自定义占位符输出分隔符;传入空值恢复宿主默认行为。"""
if separator == "":
separator = None
if separator is not None and not isinstance(separator, str):
raise TypeError("custom separator must be a string or None")
CustomizationMatcher().custom_separator = separator
class CustomizationMatcher(metaclass=Singleton):
"""
识别自定义占位符
+2
View File
@@ -1,6 +1,7 @@
"""插件使用的媒体上下文、标题解析、识别类型和媒体身份规则。"""
from app.domain.context import Context, MediaInfo, TorrentInfo
from app.domain.meta.customization import set_custom_separator
from app.domain.meta.metaanime import MetaAnime
from app.domain.meta.metabase import MetaBase
from app.domain.meta.metamusic import (
@@ -72,4 +73,5 @@ __all__ = [
"parse_media_key",
"parse_media_source_selection",
"resolve_media_identity",
"set_custom_separator",
]
+1 -1
View File
@@ -755,7 +755,7 @@ flowchart LR
| 指标 | 当前值 |
|---|---:|
| Python 模块 | 917 |
| 内部导入边 | 7,671 |
| 内部导入边 | 7,672 |
| 非平凡 SCC | 1(精确 containment 的 TMDB 移植包环) |
| Application / Chain 具体 Adapter 直连 | 0 / 0 |
| Direct egress | 53(债务已清零,53 条精确 containment |
+1 -1
View File
@@ -93,7 +93,7 @@ ARCH-201 至 ARCH-204 均达到实现、验证、提交、推送和远端门禁
| 指标 | 当前值 | 解释 |
|---|---:|---|
| 宿主 Python 模块 / 内部依赖边 | 917 / 7,671 | `dependency-baseline.json` 当前快照 |
| 宿主 Python 模块 / 内部依赖边 | 917 / 7,672 | `dependency-baseline.json` 当前快照 |
| 非平凡 SCC | 1 | 仅保留精确 containment 的 29 模块 TMDB 移植包环 |
| 跨层 DB 边界债务 | 0 | Application、Chain、API、Agent、Runtime、Workflow 到 DB 的受控债务均为零 |
| Model/Oper 事务债务 | 0 | 自建 Session、自动事务装饰器、直接 commit/rollback 等基线均为零 |
+3 -2
View File
@@ -1089,8 +1089,8 @@
"runtime_only": true
}
},
"edge_count": 7671,
"edge_sha256": "04c20dbde6f746e2467064f2999efed4b25b9e6ccaa7042e94e96b39662522e7",
"edge_count": 7672,
"edge_sha256": "0d21d2307e4cc2d5d9f3c3373786d33a68bf816ec5d28b18e8d4b8519314cd14",
"edges": [
"app -> app.foundation",
"app -> app.foundation.environment",
@@ -7838,6 +7838,7 @@
"app.sdk.media -> app.domain.context",
"app.sdk.media -> app.domain.media",
"app.sdk.media -> app.domain.meta",
"app.sdk.media -> app.domain.meta.customization",
"app.sdk.media -> app.domain.meta.metaanime",
"app.sdk.media -> app.domain.meta.metabase",
"app.sdk.media -> app.domain.meta.metamusic",
@@ -10112,6 +10112,11 @@
"kind": "import",
"name": "resolve_media_identity",
"target": "app.schemas.media.resolve_media_identity"
},
{
"kind": "import",
"name": "set_custom_separator",
"target": "app.domain.meta.customization.set_custom_separator"
}
],
"app.sdk.network": [
+17
View File
@@ -1,5 +1,6 @@
from app.domain.meta import customization as customization_module
from app.domain.meta.customization import CustomizationMatcher
from app.sdk.media import set_custom_separator
def test_match_uses_latest_customization_setting(monkeypatch):
@@ -15,3 +16,19 @@ def test_match_uses_latest_customization_setting(monkeypatch):
assert matcher.match("[GROUP][TEAM] Movie") == "GROUP"
values[0] = ["TEAM"]
assert matcher.match("[GROUP][TEAM] Movie") == "TEAM"
def test_sdk_set_custom_separator_updates_matcher_and_restores_default(monkeypatch):
"""插件只能通过 SDK 设置分隔符,清空后恢复宿主默认值。"""
matcher = CustomizationMatcher()
monkeypatch.setattr(
customization_module,
"_customization_provider",
lambda: ["GROUP", "TEAM"],
)
set_custom_separator("#")
assert matcher.match("[GROUP][TEAM] Movie") == "GROUP#TEAM"
set_custom_separator(None)
assert matcher.match("[GROUP][TEAM] Movie") == "GROUP@TEAM"
+12 -1
View File
@@ -8,7 +8,14 @@ from app.sdk.cache import Cache, cached
from app.sdk.config import settings
from app.sdk.events import Event, eventmanager
from app.sdk.logging import logger
from app.sdk.media import MediaInfo, MetaBase, MetaInfo, MetaMusic, NfoReader
from app.sdk.media import (
MediaInfo,
MetaBase,
MetaInfo,
MetaMusic,
NfoReader,
set_custom_separator,
)
from app.sdk.network import RequestUtils, RssHelper, SitesHelper
from app.sdk.plugins import ModuleManager, PluginManager
from app.sdk.services import NotificationHelper
@@ -22,6 +29,9 @@ PROJECT_ROOT = Path(__file__).parents[1]
def test_sdk_exports_canonical_plugin_interfaces():
"""SDK 应复用 canonical 对象,不复制实现或制造第二套单例。"""
from app.domain.context import MediaInfo as CanonicalMediaInfo
from app.domain.meta.customization import (
set_custom_separator as canonical_set_custom_separator,
)
from app.domain.meta.metabase import MetaBase as CanonicalMetaBase
from app.domain.meta.metamusic import MetaMusic as CanonicalMetaMusic
from app.domain.metainfo import MetaInfo as CanonicalMetaInfo
@@ -51,6 +61,7 @@ def test_sdk_exports_canonical_plugin_interfaces():
assert eventmanager is canonical_eventmanager
assert logger is canonical_logger
assert MediaInfo is CanonicalMediaInfo
assert set_custom_separator is canonical_set_custom_separator
assert MetaBase is CanonicalMetaBase
assert MetaInfo is CanonicalMetaInfo
assert MetaMusic is CanonicalMetaMusic