fix 精细化刷新,最新入库支持刷新单集演职人员中文

This commit is contained in:
thsrite
2024-08-15 13:39:51 +08:00
parent 155503895b
commit 6df775089b
4 changed files with 101 additions and 16 deletions

View File

@@ -35,7 +35,7 @@ MoviePilot三方插件市场https://github.com/thsrite/MoviePilot-Plugins/
- 插件彻底卸载 v1.0
- 实时软连接 v2.0.1
- 订阅规则自动填充 v2.7
- Emby元数据刷新 v1.6
- Emby元数据刷新 v1.7
- Emby媒体标签 v1.2
- 热门媒体订阅 v1.7
- [HomePage v1.2](docs%2FHomePage.md)

View File

@@ -447,11 +447,12 @@
"name": "Emby元数据刷新",
"description": "定时刷新Emby媒体库元数据演职人员中文。",
"labels": "Emby",
"version": "1.6",
"version": "1.7",
"icon": "https://raw.githubusercontent.com/thsrite/MoviePilot-Plugins/main/icons/emby-icon.png",
"author": "thsrite",
"level": 1,
"history": {
"v1.7": "精细化刷新,最新入库支持刷新单集演职人员中文",
"v1.6": "修复豆瓣查询bug丰富日志",
"v1.5": "支持刷新演员中文路径关键词多个英文逗号分隔。建议覆盖元数据修改为False防止演员中文被刷新覆盖",
"v1.4": "支持刷新演员中文",

View File

@@ -1068,8 +1068,8 @@ class CloudAssistant(_PluginBase):
"""
if not self._EMBY_HOST or not self._EMBY_APIKEY:
return False
req_url = "%semby/Items/%s/Refresh?MetadataRefreshMode=Default" \
"&ImageRefreshMode=Default&ReplaceAllMetadata=true&ReplaceAllImages=true&api_key=%s" % (
req_url = "%semby/Items/%s/Refresh?MetadataRefreshMode=FullRefresh" \
"&ImageRefreshMode=FullRefresh&ReplaceAllMetadata=true&ReplaceAllImages=true&api_key=%s" % (
self._EMBY_HOST, item_id, self._EMBY_APIKEY)
try:
with RequestUtils().post_res(req_url) as res:

View File

@@ -10,6 +10,7 @@ from typing import Optional, Any, List, Dict, Tuple
import pytz
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from dateutil.parser import isoparse
from requests import RequestException
from zhconv import zhconv
@@ -35,7 +36,7 @@ class EmbyMetaRefresh(_PluginBase):
# 插件图标
plugin_icon = "https://raw.githubusercontent.com/thsrite/MoviePilot-Plugins/main/icons/emby-icon.png"
# 插件版本
plugin_version = "1.6"
plugin_version = "1.7"
# 插件作者
plugin_author = "thsrite"
# 作者主页
@@ -158,28 +159,88 @@ class EmbyMetaRefresh(_PluginBase):
logger.error(f"{self._num}天内没有媒体库入库记录")
return
logger.info(f"开始刷新媒体库元数据,最近{self._num}天内入库媒体:{len(transferhistorys)}")
logger.info(f"开始刷新媒体库元数据,最近 {self._num} 天内入库媒体:{len(transferhistorys)}")
# 刷新媒体库
for transferinfo in transferhistorys:
self.__refresh_emby(transferinfo)
else:
latest = Emby().get_latest(num=int(self._num))
latest = self.__get_latest_media()
if not latest:
logger.error(f"Emby中没有最新媒体")
return
logger.info(f"开始刷新媒体库元数据,最新媒体:{len(latest)}")
logger.info(f"开始刷新媒体库元数据,{self._num} 天内最新媒体:{len(latest)} ")
# 已处理的媒体
handle_itmes = {}
# 刷新媒体库
for item in latest:
logger.info(f"开始刷新媒体库元数据,最新媒体:{item.type} {item.title} ({item.subtitle})")
self.__refresh_emby_library_by_id(item.id)
logger.info(
f"开始刷新媒体库元数据,最新媒体:{'电视剧' if str(item.get('Type')) == 'Episode' else '电影'} {'%s S%02dE%02d %s' % (item.get('SeriesName'), item.get('ParentIndexNumber'), item.get('IndexNumber'), item.get('Name')) if str(item.get('Type')) == 'Episode' else item.get('Name')} {item.get('Id')}")
self.__refresh_emby_library_by_id(item.get("Id"))
# 刮演员中文
if self._actor_chi:
self.__update_people_chi(item_id=item.id, title=item.title, type=MediaType(item.type))
key = f"{item.get('Type')}-{item.get('SeriesName') if str(item.get('Type')) == 'Episode' else item.get('Name')}"
if key in handle_itmes.keys():
continue
douban_actors = self.__update_people_chi(
item_id=item.get("SeriesId") if str(item.get('Type')) == 'Episode' else item.get("Id"),
title=item.get('SeriesName') if str(item.get('Type')) == 'Episode' else item.get('Name'),
type=MediaType('电视剧' if str(item.get('Type')) == 'Episode' else '电影'))
# 是否有豆瓣演员信息
if not douban_actors:
handle_itmes[key] = {}
else:
if str(item.get('Type')) == 'Episode':
item_dicts = handle_itmes.get(key, {})
item_ids = item_dicts.get('itemIds', [])
item_ids.append(item.get("Id"))
handle_itmes[key] = {
'itemIds': item_ids,
'actors': douban_actors
}
else:
handle_itmes[key] = {}
# 处理剧集
for key, value in handle_itmes.items():
if value:
item_ids = value.get('itemIds', [])
item_actors = value.get('actors', [])
for item_id in item_ids:
item_info = self.__get_item_info(item_id)
self.__update_peoples(itemid=item_id, iteminfo=item_info,
douban_actors=item_actors)
logger.info(f"刷新媒体库元数据完成")
def __get_latest_media(self) -> List[dict]:
"""
获取Emby中最新媒体
"""
refresh_date = datetime.utcnow() - timedelta(days=int(self._num))
refresh_date = refresh_date.replace(tzinfo=pytz.utc) # 添加UTC时区信息
try:
latest_medias = self.__get_latest(limit=1000)
if not latest_medias:
return []
_latest_medias = []
for media in latest_medias:
media_date = media.get("DateCreated")
# 截断微秒部分,使其长度为六位数
media_date = isoparse(media_date)
if media_date > refresh_date:
_latest_medias.append(media)
else:
break
return _latest_medias
except Exception as err:
logger.error(f"获取Emby中最新媒体失败{str(err)}")
return []
def __update_people_chi(self, item_id, title, type):
"""
刮削演员中文名
@@ -189,7 +250,7 @@ class EmbyMetaRefresh(_PluginBase):
if item_info:
if self._actor_path and not any(
str(actor_path) in item_info.get("Path") for actor_path in self._actor_path.split(",")):
return
return None
imdb_id = item_info.get("ProviderIds", {}).get("Imdb")
if imdb_id and self.__need_trans_actor(item_info):
@@ -202,8 +263,11 @@ class EmbyMetaRefresh(_PluginBase):
f"获取 {title} ({item_info.get('ProductionYear')}) 的豆瓣演员信息 完成,演员:{douban_actors}")
self.__update_peoples(itemid=item_id, iteminfo=item_info,
douban_actors=douban_actors)
return douban_actors
else:
logger.info(f"媒体 {title} ({item_info.get('ProductionYear')}) 演员信息无需更新")
return None
def __update_peoples(self, itemid: str, iteminfo: dict, douban_actors):
# 处理媒体项中的人物信息
@@ -234,7 +298,8 @@ class EmbyMetaRefresh(_PluginBase):
info = self.__update_people(people=people,
douban_actors=douban_actors)
if info:
logger.info(f"更新演职人员 {people.get('Name')} ({people.get('Role')}) 信息:{info.get('Name')} ({info.get('Role')})")
logger.info(
f"更新演职人员 {people.get('Name')} ({people.get('Role')}) 信息:{info.get('Name')} ({info.get('Role')})")
need_update_people = True
peoples.append(info)
else:
@@ -654,8 +719,8 @@ class EmbyMetaRefresh(_PluginBase):
"""
if not self._EMBY_HOST or not self._EMBY_APIKEY:
return False
req_url = "%semby/Items/%s/Refresh?Recursive=true&MetadataRefreshMode=Default" \
"&ImageRefreshMode=Default&ReplaceAllMetadata=%s&ReplaceAllImages=%s&api_key=%s" % (
req_url = "%semby/Items/%s/Refresh?Recursive=true&MetadataRefreshMode=FullRefresh" \
"&ImageRefreshMode=FullRefresh&ReplaceAllMetadata=%s&ReplaceAllImages=%s&api_key=%s" % (
self._EMBY_HOST, item_id, self._ReplaceAllMetadata, self._ReplaceAllImages, self._EMBY_APIKEY)
try:
with RequestUtils().post_res(req_url) as res:
@@ -668,6 +733,25 @@ class EmbyMetaRefresh(_PluginBase):
return False
return False
def __get_latest(self, limit) -> list:
"""
获取最新入库项目
"""
if not self._EMBY_HOST or not self._EMBY_APIKEY:
return False
req_url = "%semby/Users/%s/Items?Limit=%s&api_key=%s&SortBy=DateCreated,SortName&SortOrder=Descending&IncludeItemTypes=Episode,Movie&Recursive=true&Fields=DateCreated" % (
self._EMBY_HOST, self._EMBY_USER, limit, self._EMBY_APIKEY)
try:
with RequestUtils().get_res(req_url) as res:
if res:
return res.json().get("Items")
else:
logger.info(f"获取最新入库项目失败无法连接Emby")
except Exception as e:
logger.error(f"连接Items出错" + str(e))
return False
return False
def __get_emby_series_id_by_name(self, name: str, year: str) -> Optional[str]:
"""
根据名称查询Emby中剧集的SeriesId
@@ -828,7 +912,7 @@ class EmbyMetaRefresh(_PluginBase):
'component': 'VTextField',
'props': {
'model': 'num',
'label': '最新入库数/历史记录天数'
'label': '最新入库数/历史记录天数'
}
}
]