fix personmeta

This commit is contained in:
jxxghp 2023-10-01 07:53:50 +08:00
parent ba27d02854
commit ea998b4e41
8 changed files with 364 additions and 34 deletions

View File

@ -866,16 +866,33 @@ class Emby(metaclass=Singleton):
def get_data(self, url: str) -> Optional[Response]: def get_data(self, url: str) -> Optional[Response]:
""" """
自定义URL从媒体服务器获取数据其中{HOST}{APIKEY}{USER}会被替换成实际的值 自定义URL从媒体服务器获取数据其中[HOST][APIKEY][USER]会被替换成实际的值
:param url: 请求地址 :param url: 请求地址
""" """
if not self._host or not self._apikey: if not self._host or not self._apikey:
return None return None
url = url.replace("{HOST}", self._host) \ url = url.replace("[HOST]", self._host) \
.replace("{APIKEY}", self._apikey) \ .replace("[APIKEY]", self._apikey) \
.replace("{USER}", self.user) .replace("[USER]", self.user)
try: try:
return RequestUtils().get_res(url=url) return RequestUtils(content_type="application/json").get_res(url=url)
except Exception as e:
logger.error(f"连接Emby出错" + str(e))
return None
def post_data(self, url: str, data: str = None):
"""
自定义URL从媒体服务器获取数据其中[HOST][APIKEY][USER]会被替换成实际的值
:param url: 请求地址
:param data: 请求数据
"""
if not self._host or not self._apikey:
return None
url = url.replace("[HOST]", self._host) \
.replace("[APIKEY]", self._apikey) \
.replace("[USER]", self.user)
try:
return RequestUtils(content_type="application/json").post_res(url=url, data=data)
except Exception as e: except Exception as e:
logger.error(f"连接Emby出错" + str(e)) logger.error(f"连接Emby出错" + str(e))
return None return None

View File

@ -74,7 +74,7 @@ class Jellyfin(metaclass=Singleton):
continue continue
libraries.append( libraries.append(
schemas.MediaServerLibrary( schemas.MediaServerLibrary(
server="emby", server="jellyfin",
id=library.get("Id"), id=library.get("Id"),
name=library.get("Name"), name=library.get("Name"),
path=library.get("Path"), path=library.get("Path"),
@ -252,7 +252,7 @@ class Jellyfin(metaclass=Singleton):
for item in res_items: for item in res_items:
item_tmdbid = item.get("ProviderIds", {}).get("Tmdb") item_tmdbid = item.get("ProviderIds", {}).get("Tmdb")
mediaserver_item = schemas.MediaServerItem( mediaserver_item = schemas.MediaServerItem(
server="emby", server="jellyfin",
library=item.get("ParentId"), library=item.get("ParentId"),
item_id=item.get("Id"), item_id=item.get("Id"),
item_type=item.get("Type"), item_type=item.get("Type"),
@ -509,7 +509,7 @@ class Jellyfin(metaclass=Singleton):
item = res.json() item = res.json()
tmdbid = item.get("ProviderIds", {}).get("Tmdb") tmdbid = item.get("ProviderIds", {}).get("Tmdb")
return schemas.MediaServerItem( return schemas.MediaServerItem(
server="emby", server="jellyfin",
library=item.get("ParentId"), library=item.get("ParentId"),
item_id=item.get("Id"), item_id=item.get("Id"),
item_type=item.get("Type"), item_type=item.get("Type"),
@ -552,16 +552,33 @@ class Jellyfin(metaclass=Singleton):
def get_data(self, url: str) -> Optional[Response]: def get_data(self, url: str) -> Optional[Response]:
""" """
自定义URL从媒体服务器获取数据其中{HOST}{APIKEY}{USER}会被替换成实际的值 自定义URL从媒体服务器获取数据其中[HOST][APIKEY][USER]会被替换成实际的值
:param url: 请求地址 :param url: 请求地址
""" """
if not self._host or not self._apikey: if not self._host or not self._apikey:
return None return None
url = url.replace("{HOST}", self._host) \ url = url.replace("[HOST]", self._host) \
.replace("{APIKEY}", self._apikey) \ .replace("[APIKEY]", self._apikey) \
.replace("{USER}", self.user) .replace("[USER]", self.user)
try: try:
return RequestUtils().get_res(url=url) return RequestUtils().get_res(url=url)
except Exception as e: except Exception as e:
logger.error(f"连接Jellyfin出错" + str(e)) logger.error(f"连接Jellyfin出错" + str(e))
return None return None
def post_data(self, url: str, data: str = None):
"""
自定义URL从媒体服务器获取数据其中[HOST][APIKEY][USER]会被替换成实际的值
:param url: 请求地址
:param data: 请求数据
"""
if not self._host or not self._apikey:
return None
url = url.replace("[HOST]", self._host) \
.replace("[APIKEY]", self._apikey) \
.replace("[USER]", self.user)
try:
return RequestUtils().post_res(url=url, data=data)
except Exception as e:
logger.error(f"连接Jellyfin出错" + str(e))
return None

View File

@ -467,7 +467,7 @@ class BestFilmVersion(_PluginBase):
def jellyfin_get_items(self) -> List[dict]: def jellyfin_get_items(self) -> List[dict]:
# 获取所有user # 获取所有user
users_url = "{HOST}Users?&apikey={APIKEY}" users_url = "[HOST]Users?&apikey=[APIKEY]"
users = self.get_users(Jellyfin().get_data(users_url)) users = self.get_users(Jellyfin().get_data(users_url))
if not users: if not users:
logger.info(f"bestfilmversion/users_url: {users_url}") logger.info(f"bestfilmversion/users_url: {users_url}")
@ -475,7 +475,7 @@ class BestFilmVersion(_PluginBase):
all_items = [] all_items = []
for user in users: for user in users:
# 根据加入日期 降序排序 # 根据加入日期 降序排序
url = "{HOST}Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \ url = "[HOST]Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
"&SortOrder=Descending" \ "&SortOrder=Descending" \
"&Filters=IsFavorite" \ "&Filters=IsFavorite" \
"&Recursive=true" \ "&Recursive=true" \
@ -484,7 +484,7 @@ class BestFilmVersion(_PluginBase):
"&ExcludeLocationTypes=Virtual" \ "&ExcludeLocationTypes=Virtual" \
"&EnableTotalRecordCount=false" \ "&EnableTotalRecordCount=false" \
"&Limit=20" \ "&Limit=20" \
"&apikey={APIKEY}" "&apikey=[APIKEY]"
resp = self.get_items(Jellyfin().get_data(url)) resp = self.get_items(Jellyfin().get_data(url))
if not resp: if not resp:
continue continue
@ -493,14 +493,14 @@ class BestFilmVersion(_PluginBase):
def emby_get_items(self) -> List[dict]: def emby_get_items(self) -> List[dict]:
# 获取所有user # 获取所有user
get_users_url = "{HOST}Users?&api_key={APIKEY}" get_users_url = "[HOST]Users?&api_key=[APIKEY]"
users = self.get_users(Emby().get_data(get_users_url)) users = self.get_users(Emby().get_data(get_users_url))
if not users: if not users:
return [] return []
all_items = [] all_items = []
for user in users: for user in users:
# 根据加入日期 降序排序 # 根据加入日期 降序排序
url = "{HOST}emby/Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \ url = "[HOST]emby/Users/" + user + "/Items?SortBy=DateCreated%2CSortName" \
"&SortOrder=Descending" \ "&SortOrder=Descending" \
"&Filters=IsFavorite" \ "&Filters=IsFavorite" \
"&Recursive=true" \ "&Recursive=true" \
@ -508,7 +508,7 @@ class BestFilmVersion(_PluginBase):
"&CollapseBoxSetItems=false" \ "&CollapseBoxSetItems=false" \
"&ExcludeLocationTypes=Virtual" \ "&ExcludeLocationTypes=Virtual" \
"&EnableTotalRecordCount=false" \ "&EnableTotalRecordCount=false" \
"&Limit=20&api_key={APIKEY}" "&Limit=20&api_key=[APIKEY]"
resp = self.get_items(Emby().get_data(url)) resp = self.get_items(Emby().get_data(url))
if not resp: if not resp:
continue continue

View File

@ -725,9 +725,9 @@ class CloudflareSpeedTest(_PluginBase):
new_entrys.append(host_entry) new_entrys.append(host_entry)
except Exception as err: except Exception as err:
err_hosts.append(host + "\n") err_hosts.append(host + "\n")
logger.error(f"{host} 格式转换错误:{str(err)}") logger.error(f"[HOST] 格式转换错误:{str(err)}")
# 推送实时消息 # 推送实时消息
self.systemmessage.put(f"{host} 格式转换错误:{str(err)}") self.systemmessage.put(f"[HOST] 格式转换错误:{str(err)}")
# 写入系统hosts # 写入系统hosts
if new_entrys: if new_entrys:

View File

@ -199,9 +199,9 @@ class CustomHosts(_PluginBase):
new_entrys.append(host_entry) new_entrys.append(host_entry)
except Exception as err: except Exception as err:
err_hosts.append(host + "\n") err_hosts.append(host + "\n")
logger.error(f"{host} 格式转换错误:{str(err)}") logger.error(f"[HOST] 格式转换错误:{str(err)}")
# 推送实时消息 # 推送实时消息
self.systemmessage.put(f"{host} 格式转换错误:{str(err)}") self.systemmessage.put(f"[HOST] 格式转换错误:{str(err)}")
# 写入系统hosts # 写入系统hosts
if new_entrys: if new_entrys:

View File

@ -1043,7 +1043,7 @@ class MediaSyncDel(_PluginBase):
@staticmethod @staticmethod
def parse_emby_log(last_time): def parse_emby_log(last_time):
log_url = "{HOST}System/Logs/embyserver.txt?api_key={APIKEY}" log_url = "[HOST]System/Logs/embyserver.txt?api_key=[APIKEY]"
log_res = Emby().get_data(log_url) log_res = Emby().get_data(log_url)
if not log_res or log_res.status_code != 200: if not log_res or log_res.status_code != 200:
logger.error("获取emby日志失败请检查服务器配置") logger.error("获取emby日志失败请检查服务器配置")
@ -1116,7 +1116,7 @@ class MediaSyncDel(_PluginBase):
@staticmethod @staticmethod
def parse_jellyfin_log(last_time: datetime): def parse_jellyfin_log(last_time: datetime):
# 根据加入日期 降序排序 # 根据加入日期 降序排序
log_url = "{HOST}System/Logs/Log?name=log_%s.log&api_key={APIKEY}" % datetime.date.today().strftime("%Y%m%d") log_url = "[HOST]System/Logs/Log?name=log_%s.log&api_key=[APIKEY]" % datetime.date.today().strftime("%Y%m%d")
log_res = Jellyfin().get_data(log_url) log_res = Jellyfin().get_data(log_url)
if not log_res or log_res.status_code != 200: if not log_res or log_res.status_code != 200:
logger.error("获取jellyfin日志失败请检查服务器配置") logger.error("获取jellyfin日志失败请检查服务器配置")

View File

@ -1,5 +1,7 @@
import json
import threading import threading
import time import time
from pathlib import Path
from typing import Any, List, Dict, Tuple from typing import Any, List, Dict, Tuple
import zhconv import zhconv
@ -11,6 +13,9 @@ from app.chain.tmdb import TmdbChain
from app.core.config import settings from app.core.config import settings
from app.core.event import eventmanager, Event from app.core.event import eventmanager, Event
from app.log import logger from app.log import logger
from app.modules.emby import Emby
from app.modules.jellyfin import Jellyfin
from app.modules.plex import Plex
from app.plugins import _PluginBase from app.plugins import _PluginBase
from app.schemas import MediaInfo, MediaServerItem from app.schemas import MediaInfo, MediaServerItem
from app.schemas.types import EventType, MediaType from app.schemas.types import EventType, MediaType
@ -223,10 +228,6 @@ class PersonMeta(_PluginBase):
if not existsinfo or not existsinfo.itemid: if not existsinfo or not existsinfo.itemid:
logger.warn(f"演职人员刮削 {mediainfo.title_year} 在媒体库中不存在") logger.warn(f"演职人员刮削 {mediainfo.title_year} 在媒体库中不存在")
return return
# 初始化媒体服务器
if existsinfo.server == "plex":
logger.warn(f"演职人员刮削 不支持{existsinfo.server}媒体服务器")
return
# 查询条目详情 # 查询条目详情
iteminfo = self.mschain.iteminfo(server=existsinfo.server, item_id=existsinfo.itemid) iteminfo = self.mschain.iteminfo(server=existsinfo.server, item_id=existsinfo.itemid)
if not iteminfo: if not iteminfo:
@ -243,9 +244,6 @@ class PersonMeta(_PluginBase):
if not settings.MEDIASERVER: if not settings.MEDIASERVER:
return return
for server in settings.MEDIASERVER.split(","): for server in settings.MEDIASERVER.split(","):
if server == "plex":
logger.warn(f"演职人员刮削 不支持{server}媒体服务器")
continue
# 扫描所有媒体库 # 扫描所有媒体库
logger.info(f"开始刮削服务器 {server} 的演员信息 ...") logger.info(f"开始刮削服务器 {server} 的演员信息 ...")
for library in self.mschain.librarys(server): for library in self.mschain.librarys(server):
@ -291,9 +289,307 @@ class PersonMeta(_PluginBase):
# 下载图片 # 下载图片
# 更新演员图片 # 更新演员图片
@staticmethod
def get_iteminfo(server: str, itemid: str) -> dict:
"""
获得媒体项详情
"""
def __get_emby_iteminfo() -> dict:
"""
获得Emby媒体项详情
"""
try:
url = f'[HOST]emby/Users/[USER]/Items/{itemid}?' \
f'Fields=ChannelMappingInfo&api_key=[APIKEY]'
res = Emby().get_data(url=url)
if res:
return res.json()
except Exception as err:
logger.error(f"获取Emby媒体项详情失败{err}")
return {}
def __get_jellyfin_iteminfo() -> dict:
"""
获得Jellyfin媒体项详情
"""
try:
url = f'[HOST]Users/[USER]/Items/{itemid}?Fields=ChannelMappingInfo&api_key=[APIKEY]'
res = Jellyfin().get_data(url=url)
if res:
result = res.json()
if result:
result['FileName'] = Path(result['Path']).name
return result
except Exception as err:
logger.error(f"获取Jellyfin媒体项详情失败{err}")
return {}
def __get_plex_iteminfo() -> dict:
"""
获得Plex媒体项详情
"""
iteminfo = {}
try:
plexitem = Plex().get_plex().library.fetchItem(ekey=itemid)
if 'movie' in plexitem.METADATA_TYPE:
iteminfo['Type'] = 'Movie'
iteminfo['IsFolder'] = False
elif 'episode' in plexitem.METADATA_TYPE:
iteminfo['Type'] = 'Series'
iteminfo['IsFolder'] = False
if 'show' in plexitem.TYPE:
iteminfo['ChildCount'] = plexitem.childCount
iteminfo['Name'] = plexitem.title
iteminfo['Id'] = plexitem.key
iteminfo['ProductionYear'] = plexitem.year
iteminfo['ProviderIds'] = {}
for guid in plexitem.guids:
idlist = str(guid.id).split(sep='://')
if len(idlist) < 2:
continue
iteminfo['ProviderIds'][idlist[0]] = idlist[1]
for location in plexitem.locations:
iteminfo['Path'] = location
iteminfo['FileName'] = Path(location).name
iteminfo['Overview'] = plexitem.summary
iteminfo['CommunityRating'] = plexitem.audienceRating
return iteminfo
except Exception as err:
logger.error(f"获取Plex媒体项详情失败{err}")
return {}
if server == "emby":
return __get_emby_iteminfo()
elif server == "jellyfin":
return __get_jellyfin_iteminfo()
else:
return __get_plex_iteminfo()
@staticmethod
def get_items(server: str, parentid: str) -> dict:
"""
获得媒体的所有子媒体项
"""
pass pass
def __get_chinese_name(self, person: dict): def __get_emby_items() -> dict:
"""
获得Emby媒体的所有子媒体项
"""
try:
if parentid:
url = f'[HOST]emby/Users/[USER]/Items?ParentId={parentid}&api_key=[APIKEY]'
else:
url = '[HOST]emby/Users/[USER]/Items?api_key=[APIKEY]'
res = Emby().get_data(url=url)
if res:
return res.json()
except Exception as err:
logger.error(f"获取Emby媒体的所有子媒体项失败{err}")
return {}
def __get_jellyfin_items() -> dict:
"""
获得Jellyfin媒体的所有子媒体项
"""
try:
if parentid:
url = f'[HOST]Users/[USER]/Items?ParentId={parentid}&api_key=[APIKEY]'
else:
url = '[HOST]Users/[USER]/Items?api_key=[APIKEY]'
res = Jellyfin().get_data(url=url)
if res:
return res.json()
except Exception as err:
logger.error(f"获取Jellyfin媒体的所有子媒体项失败{err}")
return {}
def __get_plex_items() -> dict:
"""
获得Plex媒体的所有子媒体项
"""
items = {}
try:
plex = Plex().get_plex()
items['Items'] = []
if parentid:
if type and 'Season' in type:
plexitem = plex.library.fetchItem(ekey=parentid)
items['Items'] = []
for season in plexitem.seasons():
item = {
'Name': season.title,
'Id': season.key,
'IndexNumber': season.seasonNumber,
'Overview': season.summary
}
items['Items'].append(item)
elif type and 'Episode' in type:
plexitem = plex.library.fetchItem(ekey=parentid)
items['Items'] = []
for episode in plexitem.episodes():
item = {
'Name': episode.title,
'Id': episode.key,
'IndexNumber': episode.episodeNumber,
'Overview': episode.summary,
'CommunityRating': episode.audienceRating
}
items['Items'].append(item)
else:
plexitems = plex.library.sectionByID(sectionID=parentid)
for plexitem in plexitems.all():
item = {}
if 'movie' in plexitem.METADATA_TYPE:
item['Type'] = 'Movie'
item['IsFolder'] = False
elif 'episode' in plexitem.METADATA_TYPE:
item['Type'] = 'Series'
item['IsFolder'] = False
item['Name'] = plexitem.title
item['Id'] = plexitem.key
items['Items'].append(item)
else:
plexitems = plex.library.sections()
for plexitem in plexitems:
item = {}
if 'Directory' in plexitem.TAG:
item['Type'] = 'Folder'
item['IsFolder'] = True
elif 'movie' in plexitem.METADATA_TYPE:
item['Type'] = 'Movie'
item['IsFolder'] = False
elif 'episode' in plexitem.METADATA_TYPE:
item['Type'] = 'Series'
item['IsFolder'] = False
item['Name'] = plexitem.title
item['Id'] = plexitem.key
items['Items'].append(item)
return items
except Exception as err:
logger.error(f"获取Plex媒体的所有子媒体项失败{err}")
return {}
if server == "emby":
return __get_emby_items()
elif server == "jellyfin":
return __get_jellyfin_items()
else:
return __get_plex_items()
@staticmethod
def set_iteminfo(server: str, itemid: str, iteminfo: dict):
"""
更新媒体项详情
"""
def __set_emby_iteminfo():
"""
更新Emby媒体项详情
"""
try:
res = Emby().post_data(
url=f'[HOST]emby/Items/{itemid}?api_key=[APIKEY]',
data=json.dumps(iteminfo)
)
return True if res else False
except Exception as err:
logger.error(f"更新Emby媒体项详情失败{err}")
return False
def __set_jellyfin_iteminfo():
"""
更新Jellyfin媒体项详情
"""
try:
res = Jellyfin().post_data(
url=f'[HOST]Items/{itemid}?api_key=[APIKEY]',
data=json.dumps(iteminfo)
)
return True if res else False
except Exception as err:
logger.error(f"更新Jellyfin媒体项详情失败{err}")
return False
def __set_plex_iteminfo():
"""
更新Plex媒体项详情
"""
try:
plexitem = Plex().get_plex().library.fetchItem(ekey=itemid)
if 'CommunityRating' in iteminfo:
edits = {
'audienceRating.value': iteminfo['CommunityRating'],
'audienceRating.locked': 1
}
plexitem.edit(**edits)
plexitem.editTitle(iteminfo['Name']).editSummary(iteminfo['Overview']).reload()
return True
except Exception as err:
logger.error(f"更新Plex媒体项详情失败{err}")
return False
if server == "emby":
return __set_emby_iteminfo()
elif server == "jellyfin":
return __set_jellyfin_iteminfo()
else:
return __set_plex_iteminfo()
@staticmethod
def __set_item_image(server: str, itemid: str, imageurl: str):
"""
更新媒体项图片
"""
def __set_emby_item_image():
"""
更新Emby媒体项图片
"""
try:
url = f'[HOST]emby/Items/{itemid}/Images/Primary/0/Url?api_key=[APIKEY]'
data = json.dumps({'Url': imageurl})
res = Emby().post_data(url=url, data=data)
return True if res else False
except Exception as result:
logger.error(f"更新Emby媒体项图片失败{result}")
return False
def __set_jellyfin_item_image():
"""
更新Jellyfin媒体项图片
"""
try:
url = f'[HOST]Items/{itemid}/RemoteImages/Download?' \
f'Type=Primary&ImageUrl={imageurl}&ProviderName=TheMovieDb&api_key=[APIKEY]'
res = Jellyfin().post_data(url=url)
return True if res else None
except Exception as err:
logger.error(f"更新Jellyfin媒体项图片失败{err}")
return False
def __set_plex_item_image():
"""
更新Plex媒体项图片
"""
try:
plexitem = Plex().get_plex().library.fetchItem(ekey=itemid)
plexitem.uploadPoster(url=imageurl)
return True
except Exception as err:
logger.error(f"更新Plex媒体项图片失败{err}")
return False
if server == "emby":
return __set_emby_item_image()
elif server == "jellyfin":
return __set_jellyfin_item_image()
else:
return __set_plex_item_image()
def __get_chinese_name(self, person: dict) -> str:
""" """
获取TMDB别名中的中文名 获取TMDB别名中的中文名
""" """

View File

@ -396,7 +396,7 @@ class SpeedLimiter(_PluginBase):
# 查询播放中会话 # 查询播放中会话
playing_sessions = [] playing_sessions = []
if media_server == "emby": if media_server == "emby":
req_url = "{HOST}emby/Sessions?api_key={APIKEY}" req_url = "[HOST]emby/Sessions?api_key=[APIKEY]"
try: try:
res = Emby().get_data(req_url) res = Emby().get_data(req_url)
if res and res.status_code == 200: if res and res.status_code == 200:
@ -419,7 +419,7 @@ class SpeedLimiter(_PluginBase):
and session.get("NowPlayingItem", {}).get("MediaType") == "Video": and session.get("NowPlayingItem", {}).get("MediaType") == "Video":
total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0) total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0)
elif media_server == "jellyfin": elif media_server == "jellyfin":
req_url = "{HOST}Sessions?api_key={APIKEY}" req_url = "[HOST]Sessions?api_key=[APIKEY]"
try: try:
res = Jellyfin().get_data(req_url) res = Jellyfin().get_data(req_url)
if res and res.status_code == 200: if res and res.status_code == 200: