mirror of
https://github.com/thsrite/MoviePilot-Plugins.git
synced 2026-03-27 10:05:57 +00:00
feat Emby弹幕下载 v2.0
支持 `/danmu 媒体库名` 通知emby下载媒体库所有媒体弹幕
This commit is contained in:
@@ -137,11 +137,12 @@
|
||||
"name": "Emby弹幕下载",
|
||||
"description": "通知Emby Danmu插件下载弹幕。",
|
||||
"labels": "Emby,媒体库",
|
||||
"version": "1.8",
|
||||
"version": "2.0",
|
||||
"icon": "https://raw.githubusercontent.com/thsrite/MoviePilot-Plugins/main/icons/danmu.png",
|
||||
"author": "thsrite",
|
||||
"level": 1,
|
||||
"history": {
|
||||
"v2.0": "支持 `/danmu 媒体库名` 通知emby下载媒体库所有媒体弹幕",
|
||||
"v1.8": "没有弹幕新增超过3次直接跳过检查",
|
||||
"v1.7": "增加是否自动禁用媒体库danmu插件开关(默认False)",
|
||||
"v1.6": "增加Emby、MoviePilot目录映射(相同可不填)",
|
||||
|
||||
@@ -20,7 +20,7 @@ class EmbyDanmu(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "https://raw.githubusercontent.com/thsrite/MoviePilot-Plugins/main/icons/danmu.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.8"
|
||||
plugin_version = "2.0"
|
||||
# 插件作者
|
||||
plugin_author = "thsrite"
|
||||
# 作者主页
|
||||
@@ -76,10 +76,11 @@ class EmbyDanmu(_PluginBase):
|
||||
return
|
||||
|
||||
args_list = args.split(" ")
|
||||
if len(args_list) != 2 and len(args_list) != 3:
|
||||
# 检查参数数量是否正确 (2, 3个参数 或 特殊库名)
|
||||
if len(args_list) < 1 or len(args_list) > 3:
|
||||
logger.error(f"参数错误:{args_list}")
|
||||
self.post_message(channel=event.event_data.get("channel"),
|
||||
title=f"参数错误! /danmu 媒体库名 媒体名 (季)",
|
||||
title=f"参数错误! /danmu 媒体库名 媒体名 (季) 或 /danmu 华语电影 或 /danmu 国产剧",
|
||||
userid=event.event_data.get("user"))
|
||||
return
|
||||
|
||||
@@ -109,12 +110,27 @@ class EmbyDanmu(_PluginBase):
|
||||
return
|
||||
|
||||
library_name = args_list[0]
|
||||
library_item_name = args_list[1]
|
||||
library_item_name = None
|
||||
library_item_season = None
|
||||
if len(args_list) == 3:
|
||||
library_item_season = int(args_list[2])
|
||||
logger.info(
|
||||
f"开始下载弹幕文件:{library_name} - {library_item_name} {f'(季{library_item_season})' if library_item_season else ''}")
|
||||
if len(args_list) > 1:
|
||||
library_item_name = args_list[1]
|
||||
library_item_season = None
|
||||
if len(args_list) == 3:
|
||||
library_item_season = int(args_list[2])
|
||||
logger.info(
|
||||
f"开始下载弹幕文件:{library_name} - {library_item_name} {f'(季{library_item_season})' if library_item_season else ''}")
|
||||
|
||||
is_special_library = False
|
||||
if library_name and not library_item_name:
|
||||
is_special_library = True
|
||||
logger.info(f"开始处理媒体库:{library_name}")
|
||||
# else:
|
||||
# if len(args_list) < 2:
|
||||
# logger.error(f"缺少媒体名参数:{args_list}")
|
||||
# self.post_message(channel=event.event_data.get("channel"),
|
||||
# title=f"缺少媒体名参数! /danmu 媒体库名 媒体名 (季)",
|
||||
# userid=event.event_data.get("user"))
|
||||
# return
|
||||
|
||||
# 获取媒体库信息
|
||||
librarys = self.__get_librarys()
|
||||
@@ -165,12 +181,21 @@ class EmbyDanmu(_PluginBase):
|
||||
|
||||
# 媒体库设置为正在任务,不关闭弹幕插件
|
||||
_library_task = self._library_task.get(library_id, [])
|
||||
_library_task.append(library_item_name)
|
||||
if not is_special_library:
|
||||
_library_task.append(library_item_name)
|
||||
else:
|
||||
# 对于特殊库,使用库名作为任务标识
|
||||
_library_task.append(library_name)
|
||||
self._library_task[library_id] = _library_task
|
||||
|
||||
try:
|
||||
# 获取媒体库媒体列表
|
||||
library_items = self.__get_items(library_id, nameStartsWith=library_item_name)
|
||||
if is_special_library:
|
||||
# 对于特殊库,获取所有媒体项
|
||||
library_items = self.__get_items(library_id)
|
||||
else:
|
||||
# 根据媒体名获取媒体项
|
||||
library_items = self.__get_items(library_id, nameStartsWith=library_item_name)
|
||||
if not library_items:
|
||||
logger.error(f"{emby_name} 获取媒体库:{library_name}的媒体列表失败")
|
||||
self.post_message(channel=event.event_data.get("channel"),
|
||||
@@ -183,9 +208,11 @@ class EmbyDanmu(_PluginBase):
|
||||
logger.debug(
|
||||
f"服务器:{emby_name} 媒体库:{library_name} 媒体库类型:{library_type} 媒体:{item}")
|
||||
if library_type == "tvshows":
|
||||
if item.get("Name") == library_item_name:
|
||||
if is_special_library or item.get("Name") == library_item_name:
|
||||
if is_special_library:
|
||||
library_item_name = item.get("Name")
|
||||
found_item = True
|
||||
logger.info(f"{emby_name} 找到媒体:{library_item_name},ID:{item.get('Id')}")
|
||||
logger.info(f"{emby_name} 找到媒体:{item.get('Name')},ID:{item.get('Id')}")
|
||||
|
||||
# 电视剧弹幕
|
||||
seasons = self.__get_items(item.get("Id"))
|
||||
@@ -353,23 +380,27 @@ class EmbyDanmu(_PluginBase):
|
||||
else:
|
||||
# 电影弹幕
|
||||
matches = re.findall(r'^(.*?)(?= ?\(\d{4}\)?|$)', item.get("Name"), re.MULTILINE)
|
||||
if matches and str(matches[0]) == library_item_name:
|
||||
logger.info(f"{emby_name} 开始检查电影:{library_name} {library_item_name}")
|
||||
if is_special_library or (matches and str(matches[0]) == library_item_name):
|
||||
logger.info(f"{emby_name} 开始检查电影:{library_name} {item.get('Name')}")
|
||||
found_item = True
|
||||
movie_id = item.get("Id")
|
||||
# 获取媒体详情
|
||||
item_info = self.__get_item_info(movie_id)
|
||||
item_path = item_info.get("Path")
|
||||
parent_path = Path(self.__get_path(str(Path(item_path).parent)))
|
||||
logger.info(f"{emby_name} 电影 {library_name} {item.get('Name')} 路径:{item_path}")
|
||||
if is_special_library:
|
||||
parent_path = Path(self.__get_path(str(Path(item_path))))
|
||||
else:
|
||||
parent_path = Path(self.__get_path(str(Path(item_path).parent)))
|
||||
logger.info(f"{emby_name} 开始检查MoviePilot路径 {parent_path} 下是是否有弹幕文件")
|
||||
# 检查是否有弹幕文件
|
||||
danmu_path_pattern = Path(item_path).stem + "*.xml"
|
||||
danmu_path_pattern = "*.xml"
|
||||
|
||||
if len(list(parent_path.glob(danmu_path_pattern))) >= 1:
|
||||
logger.info(
|
||||
f"{emby_name} {parent_path} 下已存在弹幕文件:{danmu_path_pattern}")
|
||||
self.post_message(channel=event.event_data.get("channel"),
|
||||
title=f"{emby_name} {library_name} {item.get('Name')} 弹幕已存在",
|
||||
title=f"{emby_name} {library_name} {item.get('Name')} 弹幕已下载完成",
|
||||
userid=event.event_data.get("user"))
|
||||
else:
|
||||
# 通知Danmu插件获取弹幕
|
||||
@@ -392,10 +423,10 @@ class EmbyDanmu(_PluginBase):
|
||||
f"{emby_name} 解析日志判断已配置弹幕源全部匹配弹幕失败")
|
||||
retry_cnt = -1
|
||||
else:
|
||||
retry_cnt -= 1
|
||||
logger.warn(
|
||||
f"{emby_name} {parent_path} 下未找到弹幕文件:{danmu_path_pattern},等待60秒后重试 ({retry_cnt}次)")
|
||||
time.sleep(60)
|
||||
f"{emby_name} {parent_path} 下未找到弹幕文件:{danmu_path_pattern},等待10秒后重试 ({retry_cnt}次)")
|
||||
retry_cnt -= 1
|
||||
time.sleep(10)
|
||||
|
||||
if len(list(parent_path.glob(danmu_path_pattern))) >= 1:
|
||||
logger.info(
|
||||
@@ -417,20 +448,23 @@ class EmbyDanmu(_PluginBase):
|
||||
userid=event.event_data.get("user"))
|
||||
if not found_item:
|
||||
logger.error(
|
||||
f"{emby_name} 未找到媒体:{library_name} {library_item_name} {f'第{library_item_season}季 ' if library_item_season else ''}")
|
||||
f"{emby_name} 未找到媒体:{library_name} {library_item_name if not is_special_library else ''}")
|
||||
self.post_message(channel=event.event_data.get("channel"),
|
||||
title=f"{emby_name} 未找到媒体:{library_name} {library_item_name} {f'第{library_item_season}季 ' if library_item_season else ''}",
|
||||
title=f"{emby_name} 未找到媒体:{library_name} {library_item_name if not is_special_library else ''}",
|
||||
userid=event.event_data.get("user"))
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"{emby_name} {library_name} {library_item_name} {f'第{library_item_season}季 ' if library_item_season else ''}获取弹幕任务出错:{str(e)}")
|
||||
f"{emby_name} {library_name} {library_item_name if not is_special_library else ''} 获取弹幕任务出错:{str(e)}")
|
||||
|
||||
# 判断当前媒体库是否有其他任务在执行
|
||||
self._library_task[library_id].remove(library_item_name)
|
||||
if not is_special_library:
|
||||
self._library_task[library_id].remove(library_item_name)
|
||||
else:
|
||||
self._library_task[library_id].remove(library_name)
|
||||
if len(self._library_task[library_id]) == 0 and self._disabled:
|
||||
# 关闭弹幕插件
|
||||
logger.info(
|
||||
f"{emby_name} {library_name} {library_item_name} {f'第{library_item_season}季 ' if library_item_season else ''}获取弹幕任务完成,关闭弹幕插件")
|
||||
f"{emby_name} {library_name} {library_item_name if not is_special_library else ''} 获取弹幕任务完成,关闭弹幕插件")
|
||||
# 禁用媒体库的Danmu插件
|
||||
library_disabled_subtitle_fetchers = library_options.get("DisabledSubtitleFetchers", [])
|
||||
library_disabled_subtitle_fetchers.append("Danmu")
|
||||
@@ -607,19 +641,18 @@ class EmbyDanmu(_PluginBase):
|
||||
retry_cnt = -1
|
||||
else:
|
||||
danmu_files = list(parent_path.glob(danmu_path_pattern))
|
||||
_no_incre_cnt += 1
|
||||
for danmu_file in danmu_files:
|
||||
if danmu_file.name not in _downloaded_danmu_files:
|
||||
_downloaded_danmu_files.append(danmu_file.name)
|
||||
logger.info(f"已下载弹幕文件:{danmu_file.name}")
|
||||
_no_incre_cnt = 0
|
||||
else:
|
||||
_no_incre_cnt += 1
|
||||
# 判断是否完成任务
|
||||
if len(_downloaded_danmu_files) != len(season_items):
|
||||
retry_cnt -= 1
|
||||
logger.warn(
|
||||
f"{parent_path} 下弹幕文件:{danmu_path_pattern} 未下载完成,等待60秒后重试 ({retry_cnt}次)")
|
||||
time.sleep(60)
|
||||
f"{parent_path} 下弹幕文件:{danmu_path_pattern} 未下载完成,等待10秒后重试 ({retry_cnt}次)")
|
||||
retry_cnt -= 1
|
||||
time.sleep(10)
|
||||
|
||||
return len(_downloaded_danmu_files), len(season_items)
|
||||
|
||||
@@ -849,7 +882,7 @@ class EmbyDanmu(_PluginBase):
|
||||
'props': {
|
||||
'type': 'info',
|
||||
'variant': 'tonal',
|
||||
'text': '仅支持交互命令运行: /danmu 媒体库名 媒体名 (季)。 季可选,不填则获取全部季度。'
|
||||
'text': '支持交互命令运行: /danmu 媒体库名 媒体名 (季) 或 /danmu 华语电影 或 /danmu 国产剧。 季可选,不填则获取全部季度。'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user