fix 演员头像&中文名
This commit is contained in:
parent
01fd56a019
commit
a0ed228f4b
@ -1,5 +1,6 @@
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
|
||||||
class NfoReader:
|
class NfoReader:
|
||||||
@ -8,6 +9,9 @@ class NfoReader:
|
|||||||
self.tree = ET.parse(xml_file_path)
|
self.tree = ET.parse(xml_file_path)
|
||||||
self.root = self.tree.getroot()
|
self.root = self.tree.getroot()
|
||||||
|
|
||||||
def get_element_value(self, element_path):
|
def get_element_value(self, element_path) -> Optional[str]:
|
||||||
element = self.root.find(element_path)
|
element = self.root.find(element_path)
|
||||||
return element.text if element is not None else None
|
return element.text if element is not None else None
|
||||||
|
|
||||||
|
def get_elements(self, element_path) -> List[ET.Element]:
|
||||||
|
return self.root.findall(element_path)
|
||||||
|
@ -122,12 +122,7 @@ class TmdbScraper:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{file_path} 刮削失败:{e}")
|
logger.error(f"{file_path} 刮削失败:{e}")
|
||||||
|
|
||||||
def __gen_common_nfo(self, mediainfo: MediaInfo, doc, root):
|
def __get_chinese_name(self, person: dict):
|
||||||
"""
|
|
||||||
生成公共NFO
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __get_chinese_name(person: dict):
|
|
||||||
"""
|
"""
|
||||||
获取TMDB别名中的中文名
|
获取TMDB别名中的中文名
|
||||||
"""
|
"""
|
||||||
@ -145,6 +140,10 @@ class TmdbScraper:
|
|||||||
logger.error(f"获取人物中文名失败:{err}")
|
logger.error(f"获取人物中文名失败:{err}")
|
||||||
return person.get("name") or ""
|
return person.get("name") or ""
|
||||||
|
|
||||||
|
def __gen_common_nfo(self, mediainfo: MediaInfo, doc, root):
|
||||||
|
"""
|
||||||
|
生成公共NFO
|
||||||
|
"""
|
||||||
# 添加时间
|
# 添加时间
|
||||||
DomUtils.add_node(doc, root, "dateadded",
|
DomUtils.add_node(doc, root, "dateadded",
|
||||||
time.strftime('%Y-%m-%d %H:%M:%S',
|
time.strftime('%Y-%m-%d %H:%M:%S',
|
||||||
@ -175,21 +174,18 @@ class TmdbScraper:
|
|||||||
# 导演
|
# 导演
|
||||||
for director in mediainfo.directors:
|
for director in mediainfo.directors:
|
||||||
# 获取中文名
|
# 获取中文名
|
||||||
cn_name = __get_chinese_name(director)
|
cn_name = self.__get_chinese_name(director)
|
||||||
xdirector = DomUtils.add_node(doc, root, "director", cn_name)
|
xdirector = DomUtils.add_node(doc, root, "director", cn_name)
|
||||||
xdirector.setAttribute("tmdbid", str(director.get("id") or ""))
|
xdirector.setAttribute("tmdbid", str(director.get("id") or ""))
|
||||||
# 演员
|
# 演员
|
||||||
for actor in mediainfo.actors:
|
for actor in mediainfo.actors:
|
||||||
# 获取中文名
|
# 获取中文名
|
||||||
cn_name = __get_chinese_name(actor)
|
cn_name = self.__get_chinese_name(actor)
|
||||||
xactor = DomUtils.add_node(doc, root, "actor")
|
xactor = DomUtils.add_node(doc, root, "actor")
|
||||||
DomUtils.add_node(doc, xactor, "name", cn_name)
|
DomUtils.add_node(doc, xactor, "name", cn_name)
|
||||||
DomUtils.add_node(doc, xactor, "type", "Actor")
|
DomUtils.add_node(doc, xactor, "type", "Actor")
|
||||||
DomUtils.add_node(doc, xactor, "role", actor.get("character") or actor.get("role") or "")
|
DomUtils.add_node(doc, xactor, "role", actor.get("character") or actor.get("role") or "")
|
||||||
DomUtils.add_node(doc, xactor, "order", actor.get("order") if actor.get("order") is not None else "")
|
|
||||||
DomUtils.add_node(doc, xactor, "tmdbid", actor.get("id") or "")
|
DomUtils.add_node(doc, xactor, "tmdbid", actor.get("id") or "")
|
||||||
DomUtils.add_node(doc, xactor, "thumb", actor.get('image'))
|
|
||||||
DomUtils.add_node(doc, xactor, "profile", actor.get('profile'))
|
|
||||||
# 风格
|
# 风格
|
||||||
genres = mediainfo.genres or []
|
genres = mediainfo.genres or []
|
||||||
for genre in genres:
|
for genre in genres:
|
||||||
@ -330,14 +326,18 @@ class TmdbScraper:
|
|||||||
directors = episodeinfo.get("crew") or []
|
directors = episodeinfo.get("crew") or []
|
||||||
for director in directors:
|
for director in directors:
|
||||||
if director.get("known_for_department") == "Directing":
|
if director.get("known_for_department") == "Directing":
|
||||||
xdirector = DomUtils.add_node(doc, root, "director", director.get("name") or "")
|
# 获取中文名
|
||||||
|
cn_name = self.__get_chinese_name(director)
|
||||||
|
xdirector = DomUtils.add_node(doc, root, "director", cn_name)
|
||||||
xdirector.setAttribute("tmdbid", str(director.get("id") or ""))
|
xdirector.setAttribute("tmdbid", str(director.get("id") or ""))
|
||||||
# 演员
|
# 演员
|
||||||
actors = episodeinfo.get("guest_stars") or []
|
actors = episodeinfo.get("guest_stars") or []
|
||||||
for actor in actors:
|
for actor in actors:
|
||||||
if actor.get("known_for_department") == "Acting":
|
if actor.get("known_for_department") == "Acting":
|
||||||
|
# 获取中文名
|
||||||
|
cn_name = self.__get_chinese_name(actor)
|
||||||
xactor = DomUtils.add_node(doc, root, "actor")
|
xactor = DomUtils.add_node(doc, root, "actor")
|
||||||
DomUtils.add_node(doc, xactor, "name", actor.get("name") or "")
|
DomUtils.add_node(doc, xactor, "name", cn_name)
|
||||||
DomUtils.add_node(doc, xactor, "type", "Actor")
|
DomUtils.add_node(doc, xactor, "type", "Actor")
|
||||||
DomUtils.add_node(doc, xactor, "tmdbid", actor.get("id") or "")
|
DomUtils.add_node(doc, xactor, "tmdbid", actor.get("id") or "")
|
||||||
# 保存文件
|
# 保存文件
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
|
from pathlib import Path
|
||||||
from typing import Any, List, Dict, Tuple
|
from typing import Any, List, Dict, Tuple
|
||||||
|
|
||||||
|
from requests import RequestException
|
||||||
|
|
||||||
|
from app.chain.tmdb import TmdbChain
|
||||||
from app.core.event import eventmanager, Event
|
from app.core.event import eventmanager, Event
|
||||||
|
from app.helper.nfo import NfoReader
|
||||||
|
from app.log import logger
|
||||||
from app.plugins import _PluginBase
|
from app.plugins import _PluginBase
|
||||||
from app.schemas.types import EventType
|
from app.schemas import TransferInfo, MediaInfo
|
||||||
|
from app.schemas.types import EventType, MediaType
|
||||||
|
from app.utils.common import retry
|
||||||
|
from app.utils.http import RequestUtils
|
||||||
|
|
||||||
|
|
||||||
class PersonMeta(_PluginBase):
|
class PersonMeta(_PluginBase):
|
||||||
@ -28,11 +37,15 @@ class PersonMeta(_PluginBase):
|
|||||||
auth_level = 1
|
auth_level = 1
|
||||||
|
|
||||||
# 私有属性
|
# 私有属性
|
||||||
|
tmdbchain = None
|
||||||
_enabled = False
|
_enabled = False
|
||||||
|
_metadir = ""
|
||||||
|
|
||||||
def init_plugin(self, config: dict = None):
|
def init_plugin(self, config: dict = None):
|
||||||
|
self.tmdbchain = TmdbChain(self.db)
|
||||||
if config:
|
if config:
|
||||||
self._enabled = config.get("enabled")
|
self._enabled = config.get("enabled")
|
||||||
|
self._metadir = config.get("metadir")
|
||||||
|
|
||||||
def get_state(self) -> bool:
|
def get_state(self) -> bool:
|
||||||
return self._enabled
|
return self._enabled
|
||||||
@ -72,11 +85,33 @@ class PersonMeta(_PluginBase):
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'component': 'VRow',
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12,
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VTextField',
|
||||||
|
'props': {
|
||||||
|
'model': 'metadir',
|
||||||
|
'label': '人物元数据目录',
|
||||||
|
'placeholder': '/metadata/people'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
], {
|
], {
|
||||||
"enabled": False
|
"enabled": False,
|
||||||
|
"metadir": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_page(self) -> List[dict]:
|
def get_page(self) -> List[dict]:
|
||||||
@ -87,7 +122,78 @@ class PersonMeta(_PluginBase):
|
|||||||
"""
|
"""
|
||||||
根据事件实时刮削演员信息
|
根据事件实时刮削演员信息
|
||||||
"""
|
"""
|
||||||
pass
|
if not self._enabled:
|
||||||
|
return
|
||||||
|
# 下载人物头像
|
||||||
|
if not self._metadir:
|
||||||
|
logger.warning("人物元数据目录未配置,无法下载人物头像")
|
||||||
|
return
|
||||||
|
# 事件数据
|
||||||
|
mediainfo: MediaInfo = event.event_data.get("mediainfo")
|
||||||
|
transferinfo: TransferInfo = event.event_data.get("transferinfo")
|
||||||
|
if not mediainfo or not transferinfo:
|
||||||
|
return
|
||||||
|
# 文件路径
|
||||||
|
filepath = transferinfo.target_path
|
||||||
|
if not filepath:
|
||||||
|
return
|
||||||
|
# 电影
|
||||||
|
if mediainfo.type == MediaType.MOVIE:
|
||||||
|
# nfo文件
|
||||||
|
nfofile = filepath.with_name("movie.nfo")
|
||||||
|
if not nfofile.exists():
|
||||||
|
nfofile = filepath.parent / f"{filepath.stem}.nfo"
|
||||||
|
if not nfofile.exists():
|
||||||
|
logger.warning(f"电影nfo文件不存在:{nfofile}")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# nfo文件
|
||||||
|
nfofile = filepath.parent.with_name("tvshow.nfo")
|
||||||
|
if not nfofile.exists():
|
||||||
|
logger.warning(f"剧集nfo文件不存在:{nfofile}")
|
||||||
|
return
|
||||||
|
# 读取nfo文件
|
||||||
|
nfo = NfoReader(nfofile)
|
||||||
|
# 读取演员信息
|
||||||
|
actors = nfo.get_elements("actor") or []
|
||||||
|
for actor in actors:
|
||||||
|
# 演员ID
|
||||||
|
actor_id = actor.find("id").text
|
||||||
|
if not actor_id:
|
||||||
|
continue
|
||||||
|
# 演员名称
|
||||||
|
actor_name = actor.find("name").text
|
||||||
|
# 查询演员详情
|
||||||
|
actor_info = self.tmdbchain.person_detail(actor_id)
|
||||||
|
if not actor_info:
|
||||||
|
continue
|
||||||
|
# 演员头像
|
||||||
|
actor_image = actor_info.get("profile_path")
|
||||||
|
if not actor_image:
|
||||||
|
continue
|
||||||
|
# 计算保存路径
|
||||||
|
image_path = Path(self._metadir) / f"{actor_name}-tmdb-{actor_id}{Path(actor_image).suffix}"
|
||||||
|
if image_path.exists():
|
||||||
|
continue
|
||||||
|
# 下载图片
|
||||||
|
self.download_image(f"https://image.tmdb.org/t/p/original{actor_image}", image_path)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@retry(RequestException, logger=logger)
|
||||||
|
def download_image(image_url: str, path: Path):
|
||||||
|
"""
|
||||||
|
下载图片,保存到指定路径
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
logger.info(f"正在下载演职人员图片:{image_url} ...")
|
||||||
|
r = RequestUtils().get_res(url=image_url, raise_exception=True)
|
||||||
|
if r:
|
||||||
|
path.write_bytes(r.content)
|
||||||
|
logger.info(f"图片已保存:{path}")
|
||||||
|
else:
|
||||||
|
logger.info(f"图片下载失败,请检查网络连通性:{image_url}")
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(f"图片下载失败:{err}")
|
||||||
|
|
||||||
def stop_service(self):
|
def stop_service(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user