mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-09 09:26:55 +08:00
feat(sdk): expose custom separator configuration
This commit is contained in:
@@ -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):
|
||||
"""
|
||||
识别自定义占位符
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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
@@ -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": [
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user