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

124 lines
4.1 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.
"""
旧插件导入路径使用的只读分类兼容适配器。
"""
from collections.abc import Mapping
from typing import Any
from app.application.classification.reference import (
classification_category_resolver_snapshot,
)
from app.domain.context import MediaInfo
from app.foundation.singleton import WeakSingleton
from app.runtime.log import logger
from app.schemas.category import CategoryConfig
from app.schemas.types import MediaType
from app.sdk.classification import classify_media
class CategoryHelper(metaclass=WeakSingleton):
"""
兼容旧插件的只读分类门面,不再读取、创建或写入 category.yaml。
"""
def __init__(self) -> None:
"""
创建无状态兼容门面,不触发文件或网络访问。
"""
def init(self) -> None:
"""
保留旧插件重载调用;活动策略由宿主统一管理,无需重新加载。
"""
def load(self) -> CategoryConfig:
"""
投影当前活动策略的分类路径,供旧插件只读展示。
:return: 电影和电视剧分类名称映射,规则值均为 None
"""
return CategoryConfig(
movie={name: None for name in self.movie_categorys},
tv={name: None for name in self.tv_categorys},
)
def save(self, config: CategoryConfig) -> bool:
"""
拒绝旧分类 YAML 写入,调用方应改用版本化分类策略 API。
:param config: 为兼容旧接口保留的配置参数,当前忽略
:return: 始终返回 False,并记录停用提示
"""
del config
logger.warning("CategoryHelper.save 已停用,请使用 /api/v1/media/classification/policy 发布版本化策略")
return False
@property
def is_movie_category(self) -> bool:
"""
返回活动策略是否包含启用的电影分类。
"""
return bool(self.movie_categorys)
@property
def is_tv_category(self) -> bool:
"""
返回活动策略是否包含启用的电视剧分类。
"""
return bool(self.tv_categorys)
@property
def movie_categorys(self) -> list[str]:
"""
返回活动策略中的电影分类路径文本。
"""
return self._category_paths(MediaType.MOVIE)
@property
def tv_categorys(self) -> list[str]:
"""
返回活动策略中的电视剧分类路径文本。
"""
return self._category_paths(MediaType.TV)
def get_movie_category(self, tmdb_info: Mapping[str, Any] | None) -> str:
"""
通过统一分类服务计算 TMDB 电影的目录分类。
:param tmdb_info: TMDB 原始媒体数据;输入字典不会被修改
:return: 去除首尾空白的分类路径;无输入或无分类结果时为空字符串
"""
return self._classify_tmdb_info(tmdb_info, MediaType.MOVIE)
def get_tv_category(self, tmdb_info: Mapping[str, Any] | None) -> str:
"""
通过统一分类服务计算 TMDB 电视剧的目录分类。
:param tmdb_info: TMDB 原始媒体数据;输入字典不会被修改
:return: 去除首尾空白的分类路径;无输入或无分类结果时为空字符串
"""
return self._classify_tmdb_info(tmdb_info, MediaType.TV)
@staticmethod
def _category_paths(media_type: MediaType) -> list[str]:
"""
把活动策略的安全路径转换为旧插件可消费的文本列表。
"""
resolver = classification_category_resolver_snapshot()
return ["/".join(path) for path in resolver.category_paths(media_type) if path]
@staticmethod
def _classify_tmdb_info(
tmdb_info: Mapping[str, Any] | None,
media_type: MediaType,
) -> str:
"""
构造规范媒体副本并返回统一分类结果,不修改输入 TMDB 字典。
"""
if not tmdb_info:
return ""
payload = dict(tmdb_info)
payload["media_type"] = media_type
classified = classify_media(MediaInfo(tmdb_info=payload))
return str(classified.library_category or "").strip()