mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-03-20 03:57:30 +08:00
Merge pull request #5531 from WongWang/feat-plugin-priority
This commit is contained in:
@@ -5,6 +5,7 @@ from fastapi import APIRouter, Depends, Body
|
||||
from app import schemas
|
||||
from app.chain.download import DownloadChain
|
||||
from app.chain.media import MediaChain
|
||||
from app.core.config import settings
|
||||
from app.core.context import MediaInfo, Context, TorrentInfo
|
||||
from app.core.event import eventmanager
|
||||
from app.core.metainfo import MetaInfo
|
||||
@@ -77,13 +78,14 @@ def add(
|
||||
# 元数据
|
||||
metainfo = MetaInfo(title=torrent_in.title, subtitle=torrent_in.description)
|
||||
# 媒体信息
|
||||
mediainfo = MediaChain().recognize_media(meta=metainfo, tmdbid=tmdbid, doubanid=doubanid)
|
||||
mediainfo = MediaChain().select_recognize_source(
|
||||
log_name=torrent_in.title,
|
||||
log_context=torrent_in.title,
|
||||
native_fn=lambda: MediaChain().recognize_media(meta=metainfo, tmdbid=tmdbid, doubanid=doubanid),
|
||||
plugin_fn=lambda: MediaChain().recognize_help(title=torrent_in.title, org_meta=metainfo)
|
||||
)
|
||||
if not mediainfo:
|
||||
# 尝试使用辅助识别,如果有注册响应事件的话
|
||||
if eventmanager.check(ChainEventType.NameRecognize):
|
||||
mediainfo = MediaChain().recognize_help(title=torrent_in.title, org_meta=metainfo)
|
||||
if not mediainfo:
|
||||
return schemas.Response(success=False, message="无法识别媒体信息")
|
||||
return schemas.Response(success=False, message="无法识别媒体信息")
|
||||
# 种子信息
|
||||
torrentinfo = TorrentInfo()
|
||||
torrentinfo.from_dict(torrent_in.model_dump())
|
||||
|
||||
@@ -85,21 +85,48 @@ class MediaChain(ChainBase):
|
||||
"""
|
||||
return self.run_module("metadata_nfo", meta=meta, mediainfo=mediainfo, season=season, episode=episode)
|
||||
|
||||
def select_recognize_source(self, log_name: str, log_context: str,
|
||||
native_fn, plugin_fn) -> Optional[MediaInfo]:
|
||||
"""
|
||||
选择识别模式,插件优先或原生优先
|
||||
:param log_name: 用于日志“标题:...”处的名称(如 file_path.name 或 title)
|
||||
:param log_context: 用于日志“未识别到...的媒体信息”处的上下文(如 path 或 title)
|
||||
:param native_fn: 原生识别函数
|
||||
:param plugin_fn: 插件识别函数
|
||||
"""
|
||||
mediainfo = None
|
||||
plugin_available = eventmanager.check(ChainEventType.NameRecognize)
|
||||
if settings.RECOGNIZE_PLUGIN_FIRST and plugin_available:
|
||||
# 插件优先
|
||||
logger.info(f"插件优先模式已开启。请求辅助识别,标题:{log_name} ...")
|
||||
mediainfo = plugin_fn()
|
||||
if not mediainfo:
|
||||
logger.info(f'辅助识别未识别到 {log_context} 的媒体信息,尝试使用原生识别')
|
||||
mediainfo = native_fn()
|
||||
else:
|
||||
# 原生优先
|
||||
logger.info(f"插件优先模式未开启。尝试原生识别,标题:{log_name} ...")
|
||||
mediainfo = native_fn()
|
||||
if not mediainfo and plugin_available:
|
||||
logger.info(f'原生识别未识别到 {log_context} 的媒体信息,尝试使用辅助识别')
|
||||
mediainfo = plugin_fn()
|
||||
return mediainfo
|
||||
|
||||
def recognize_by_meta(self, metainfo: MetaBase, episode_group: Optional[str] = None) -> Optional[MediaInfo]:
|
||||
"""
|
||||
根据主副标题识别媒体信息
|
||||
"""
|
||||
title = metainfo.title
|
||||
# 识别媒体信息
|
||||
mediainfo: MediaInfo = self.recognize_media(meta=metainfo, episode_group=episode_group)
|
||||
# 按 config 中设置的识别顺序识别
|
||||
mediainfo = self.select_recognize_source(
|
||||
log_name=title,
|
||||
log_context=title,
|
||||
native_fn=lambda: self.recognize_media(meta=metainfo, episode_group=episode_group),
|
||||
plugin_fn=lambda: self.recognize_help(title=title, org_meta=metainfo)
|
||||
)
|
||||
if not mediainfo:
|
||||
# 尝试使用辅助识别,如果有注册响应事件的话
|
||||
if eventmanager.check(ChainEventType.NameRecognize):
|
||||
logger.info(f'请求辅助识别,标题:{title} ...')
|
||||
mediainfo = self.recognize_help(title=title, org_meta=metainfo)
|
||||
if not mediainfo:
|
||||
logger.warn(f'{title} 未识别到媒体信息')
|
||||
return None
|
||||
logger.warn(f'{title} 未识别到媒体信息')
|
||||
return None
|
||||
# 识别成功
|
||||
logger.info(f'{title} 识别到媒体信息:{mediainfo.type.value} {mediainfo.title_year}')
|
||||
# 更新媒体图片
|
||||
@@ -163,16 +190,16 @@ class MediaChain(ChainBase):
|
||||
file_path = Path(path)
|
||||
# 元数据
|
||||
file_meta = MetaInfoPath(file_path)
|
||||
# 识别媒体信息
|
||||
mediainfo = self.recognize_media(meta=file_meta, episode_group=episode_group)
|
||||
# 按 config 中设置的识别顺序识别
|
||||
mediainfo = self.select_recognize_source(
|
||||
log_name=file_path.name,
|
||||
log_context=path,
|
||||
native_fn=lambda: self.recognize_media(meta=file_meta, episode_group=episode_group),
|
||||
plugin_fn=lambda: self.recognize_help(title=path, org_meta=file_meta)
|
||||
)
|
||||
if not mediainfo:
|
||||
# 尝试使用辅助识别,如果有注册响应事件的话
|
||||
if eventmanager.check(ChainEventType.NameRecognize):
|
||||
logger.info(f'请求辅助识别,标题:{file_path.name} ...')
|
||||
mediainfo = self.recognize_help(title=path, org_meta=file_meta)
|
||||
if not mediainfo:
|
||||
logger.warn(f'{path} 未识别到媒体信息')
|
||||
return Context(meta_info=file_meta)
|
||||
logger.warn(f'{path} 未识别到媒体信息')
|
||||
return Context(meta_info=file_meta)
|
||||
logger.info(f'{path} 识别到媒体信息:{mediainfo.type.value} {mediainfo.title_year}')
|
||||
# 更新媒体图片
|
||||
self.obtain_images(mediainfo=mediainfo)
|
||||
@@ -820,22 +847,54 @@ class MediaChain(ChainBase):
|
||||
logger.warn("无法识别元数据,跳过")
|
||||
logger.info(f"{filepath.name} 刮削完成")
|
||||
|
||||
async def async_select_recognize_source(self, log_name: str, log_context: str,
|
||||
native_fn, plugin_fn) -> Optional[MediaInfo]:
|
||||
"""
|
||||
选择识别模式,插件优先或原生优先(异步版本)
|
||||
:param log_name: 用于日志“标题:...”处的名称(如 file_path.name 或 title)
|
||||
:param log_context: 用于日志“未识别到...的媒体信息”处的上下文(如 path 或 title)
|
||||
:param native_fn: 原生识别函数
|
||||
:param plugin_fn: 插件识别函数
|
||||
"""
|
||||
mediainfo = None
|
||||
plugin_available = eventmanager.check(ChainEventType.NameRecognize)
|
||||
if settings.RECOGNIZE_PLUGIN_FIRST and plugin_available:
|
||||
# 插件优先
|
||||
logger.info(f"插件优先模式已开启。请求辅助识别,标题:{log_name} ...")
|
||||
mediainfo = await plugin_fn()
|
||||
if not mediainfo:
|
||||
logger.info(f'辅助识别未识别到 {log_context} 的媒体信息,尝试使用原生识别')
|
||||
mediainfo = await native_fn()
|
||||
else:
|
||||
# 原生优先
|
||||
logger.info(f"插件优先模式未开启。尝试原生识别,标题:{log_name} ...")
|
||||
mediainfo = await native_fn()
|
||||
if not mediainfo and plugin_available:
|
||||
logger.info(f'原生识别未识别到 {log_context} 的媒体信息,尝试使用辅助识别')
|
||||
mediainfo = await plugin_fn()
|
||||
return mediainfo
|
||||
|
||||
async def async_recognize_by_meta(self, metainfo: MetaBase,
|
||||
episode_group: Optional[str] = None) -> Optional[MediaInfo]:
|
||||
"""
|
||||
根据主副标题识别媒体信息(异步版本)
|
||||
"""
|
||||
title = metainfo.title
|
||||
# 识别媒体信息
|
||||
mediainfo: MediaInfo = await self.async_recognize_media(meta=metainfo, episode_group=episode_group)
|
||||
# 定义识别函数
|
||||
async def native_recognize():
|
||||
return await self.async_recognize_media(meta=metainfo, episode_group=episode_group)
|
||||
async def plugin_recognize():
|
||||
return await self.async_recognize_help(title=title, org_meta=metainfo)
|
||||
# 按 config 中设置的识别顺序识别
|
||||
mediainfo = await self.async_select_recognize_source(
|
||||
log_name=title,
|
||||
log_context=title,
|
||||
native_fn=native_recognize,
|
||||
plugin_fn=plugin_recognize
|
||||
)
|
||||
if not mediainfo:
|
||||
# 尝试使用辅助识别,如果有注册响应事件的话
|
||||
if eventmanager.check(ChainEventType.NameRecognize):
|
||||
logger.info(f'请求辅助识别,标题:{title} ...')
|
||||
mediainfo = await self.async_recognize_help(title=title, org_meta=metainfo)
|
||||
if not mediainfo:
|
||||
logger.warn(f'{title} 未识别到媒体信息')
|
||||
return None
|
||||
logger.warn(f'{title} 未识别到媒体信息')
|
||||
return None
|
||||
# 识别成功
|
||||
logger.info(f'{title} 识别到媒体信息:{mediainfo.type.value} {mediainfo.title_year}')
|
||||
# 更新媒体图片
|
||||
@@ -899,16 +958,21 @@ class MediaChain(ChainBase):
|
||||
file_path = Path(path)
|
||||
# 元数据
|
||||
file_meta = MetaInfoPath(file_path)
|
||||
# 识别媒体信息
|
||||
mediainfo = await self.async_recognize_media(meta=file_meta, episode_group=episode_group)
|
||||
# 定义识别函数
|
||||
async def native_recognize():
|
||||
return await self.async_recognize_media(meta=file_meta, episode_group=episode_group)
|
||||
async def plugin_recognize():
|
||||
return await self.async_recognize_help(title=path, org_meta=file_meta)
|
||||
# 按 config 中设置的识别顺序识别
|
||||
mediainfo = await self.async_select_recognize_source(
|
||||
log_name=file_path.name,
|
||||
log_context=path,
|
||||
native_fn=native_recognize,
|
||||
plugin_fn=plugin_recognize
|
||||
)
|
||||
if not mediainfo:
|
||||
# 尝试使用辅助识别,如果有注册响应事件的话
|
||||
if eventmanager.check(ChainEventType.NameRecognize):
|
||||
logger.info(f'请求辅助识别,标题:{file_path.name} ...')
|
||||
mediainfo = await self.async_recognize_help(title=path, org_meta=file_meta)
|
||||
if not mediainfo:
|
||||
logger.warn(f'{path} 未识别到媒体信息')
|
||||
return Context(meta_info=file_meta)
|
||||
logger.warn(f'{path} 未识别到媒体信息')
|
||||
return Context(meta_info=file_meta)
|
||||
logger.info(f'{path} 识别到媒体信息:{mediainfo.type.value} {mediainfo.title_year}')
|
||||
# 更新媒体图片
|
||||
await self.async_obtain_images(mediainfo=mediainfo)
|
||||
|
||||
@@ -322,6 +322,8 @@ class ConfigModel(BaseModel):
|
||||
DEFAULT_SUB: Optional[str] = "zh-cn"
|
||||
# 新增已入库媒体是否跟随TMDB信息变化
|
||||
SCRAP_FOLLOW_TMDB: bool = True
|
||||
# 优先使用辅助识别
|
||||
RECOGNIZE_PLUGIN_FIRST: bool = False
|
||||
|
||||
# ==================== 服务地址配置 ====================
|
||||
# 服务器地址,对应 https://github.com/jxxghp/MoviePilot-Server 项目
|
||||
|
||||
Reference in New Issue
Block a user