diff --git a/app/modules/emby/emby.py b/app/modules/emby/emby.py index 0672af70..b9581735 100644 --- a/app/modules/emby/emby.py +++ b/app/modules/emby/emby.py @@ -770,6 +770,7 @@ class Emby(metaclass=Singleton): } """ message = json.loads(message_str) + logger.info(f"接收到emby webhook:{message}") eventItem = WebhookEventInfo(event=message.get('Event', ''), channel="emby") if message.get('Item'): if message.get('Item', {}).get('Type') == 'Episode': @@ -798,9 +799,9 @@ class Emby(metaclass=Singleton): eventItem.item_type = "MOV" eventItem.item_name = "%s %s" % ( message.get('Item', {}).get('Name'), "(" + str(message.get('Item', {}).get('ProductionYear')) + ")") - eventItem.item_path = message.get('Item', {}).get('Path') eventItem.item_id = message.get('Item', {}).get('Id') + eventItem.item_path = message.get('Item', {}).get('Path') eventItem.tmdb_id = message.get('Item', {}).get('ProviderIds', {}).get('Tmdb') if message.get('Item', {}).get('Overview') and len(message.get('Item', {}).get('Overview')) > 100: eventItem.overview = str(message.get('Item', {}).get('Overview'))[:100] + "..." diff --git a/app/plugins/mediasyncdel/__init__.py b/app/plugins/mediasyncdel/__init__.py index cef0e95e..1e7e334d 100644 --- a/app/plugins/mediasyncdel/__init__.py +++ b/app/plugins/mediasyncdel/__init__.py @@ -36,7 +36,7 @@ class MediaSyncDel(_PluginBase): # 主题色 plugin_color = "#ff1a1a" # 插件版本 - plugin_version = "1.0" + plugin_version = "1.1" # 插件作者 plugin_author = "thsrite" # 作者主页 @@ -250,7 +250,8 @@ class MediaSyncDel(_PluginBase): 'component': 'VAlert', 'props': { 'text': '同步方式分为webhook、日志同步和Scripter X。' - 'webhook需要Emby4.8.0.45及以上开启媒体删除的webhook。' + 'webhook需要Emby4.8.0.45及以上开启媒体删除的webhook' + '(建议使用媒体库刮削插件覆盖元数据重新刮削剧集路径)。' '日志同步需要配置执行周期,默认30分钟执行一次。' 'Scripter X方式需要emby安装并配置Scripter X插件,无需配置执行周期。' } @@ -423,47 +424,21 @@ class MediaSyncDel(_PluginBase): ] @eventmanager.register(EventType.WebhookMessage) - def sync_del_by_plugin_or_webhook(self, event): + def sync_del_by_webhook(self, event): """ emby删除媒体库同步删除历史记录 - Scripter X插件 | webhook + webhook """ - if not self._enabled or (str(self._sync_type) != "plugin" and str(self._sync_type) != "webhook"): + if not self._enabled or str(self._sync_type) != "webhook": return event_data = event.event_data event_type = event_data.event - # Scripter X插件 event_type = media_del - if str(self._sync_type) == "plugin" and (not event_type or str(event_type) != 'media_del'): - return - # Emby Webhook event_type = library.deleted - if str(self._sync_type) == "webhook" and (not event_type or str(event_type) != 'library.deleted'): + if not event_type or str(event_type) != 'library.deleted': return - # Scripter X插件 需要是否虚拟标识 - if str(self._sync_type) == "plugin": - item_isvirtual = event_data.item_isvirtual - if not item_isvirtual: - logger.error("Scripter X插件方式,item_isvirtual参数未配置,为防止误删除,暂停插件运行") - self.update_config({ - "enabled": False, - "del_source": self._del_source, - "exclude_path": self._exclude_path, - "notify": self._notify, - "cron": self._cron, - "sync_type": self._sync_type, - }) - return - - # 如果是虚拟item,则直接return,不进行删除 - if item_isvirtual == 'True': - return - - # 读取历史记录 - history = self.get_data('history') or [] - # 媒体类型 media_type = event_data.item_type # 媒体名称 @@ -474,13 +449,74 @@ class MediaSyncDel(_PluginBase): tmdb_id = event_data.tmdb_id # 季数 season_num = event_data.season_id - if season_num and str(season_num).isdigit() and int(season_num) < 10: - season_num = f'0{season_num}' # 集数 episode_num = event_data.episode_id - if episode_num and str(episode_num).isdigit() and int(episode_num) < 10: - episode_num = f'0{episode_num}' + self.__sync_del(media_type=media_type, + media_name=media_name, + media_path=media_path, + tmdb_id=tmdb_id, + season_num=season_num, + episode_num=episode_num) + + @eventmanager.register(EventType.WebhookMessage) + def sync_del_by_plugin(self, event): + """ + emby删除媒体库同步删除历史记录 + Scripter X插件 + """ + if not self._enabled or str(self._sync_type) != "plugin": + return + + event_data = event.event_data + event_type = event_data.event + + # Scripter X插件 event_type = media_del + if not event_type or str(event_type) != 'media_del': + return + + # Scripter X插件 需要是否虚拟标识 + item_isvirtual = event_data.item_isvirtual + if not item_isvirtual: + logger.error("Scripter X插件方式,item_isvirtual参数未配置,为防止误删除,暂停插件运行") + self.update_config({ + "enabled": False, + "del_source": self._del_source, + "exclude_path": self._exclude_path, + "notify": self._notify, + "cron": self._cron, + "sync_type": self._sync_type, + }) + return + + # 如果是虚拟item,则直接return,不进行删除 + if item_isvirtual == 'True': + return + + # 媒体类型 + media_type = event_data.item_type + # 媒体名称 + media_name = event_data.item_name + # 媒体路径 + media_path = event_data.item_path + # tmdb_id + tmdb_id = event_data.tmdb_id + # 季数 + season_num = event_data.season_id + # 集数 + episode_num = event_data.episode_id + + self.__sync_del(media_type=media_type, + media_name=media_name, + media_path=media_path, + tmdb_id=tmdb_id, + season_num=season_num, + episode_num=episode_num) + + def __sync_del(self, media_type, media_name, media_path, tmdb_id, season_num, episode_num): + """ + 执行删除逻辑 + """ if not media_type: logger.error(f"{media_name} 同步删除失败,未获取到媒体类型") return @@ -494,38 +530,24 @@ class MediaSyncDel(_PluginBase): logger.info(f"媒体路径 {media_path} 已被排除,暂不处理") return - # 删除电影 - if media_type == "Movie" or media_type == "MOV": - msg = f'电影 {media_name} {tmdb_id}' - transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id) - # 删除电视剧 - elif (media_type == "Series" or media_type == "TV") and not season_num and not episode_num: - msg = f'剧集 {media_name} {tmdb_id}' - transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id) - # 删除季 S02 - elif (media_type == "Season" or media_type == "TV") and season_num and not episode_num: - if not season_num or not str(season_num).isdigit(): - logger.error(f"{media_name} 季同步删除失败,未获取到具体季") - return - msg = f'剧集 {media_name} S{season_num} {tmdb_id}' - transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, - season=f'S{season_num}') - # 删除剧集S02E02 - elif (media_type == "Episode" or media_type == "TV") and season_num and episode_num: - if not season_num or not str(season_num).isdigit() or not episode_num or not str(episode_num).isdigit(): - logger.error(f"{media_name} 集同步删除失败,未获取到具体集") - return - msg = f'剧集 {media_name} S{season_num}E{episode_num} {tmdb_id}' - transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, - season=f'S{season_num}', - episode=f'E{episode_num}') - else: - return + # 季数 + if season_num and str(season_num).isdigit() and int(season_num) < 10: + season_num = f'0{season_num}' + # 集数 + if episode_num and str(episode_num).isdigit() and int(episode_num) < 10: + episode_num = f'0{episode_num}' + + # 查询转移记录 + msg, transfer_history = self.__get_transfer_his(media_type=media_type, + media_name=media_name, + tmdb_id=tmdb_id, + season_num=season_num, + episode_num=episode_num) logger.info(f"正在同步删除{msg}") if not transfer_history: - logger.warn(f"{media_type} {media_name} 未获取到可删除数据") + logger.warn(f"{media_type} {media_name} 未获取到可删除数据,可使用媒体库刮削插件覆盖所有元数据") return # 开始删除 @@ -587,8 +609,11 @@ class MediaSyncDel(_PluginBase): f"时间 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))}" ) + # 读取历史记录 + history = self.get_data('history') or [] + history.append({ - "type": "电影" if media_type == "Movie" else "电视剧", + "type": "电影" if media_type == "Movie" or media_type == "MOV" else "电视剧", "title": media_name, "year": year, "path": media_path, @@ -601,6 +626,40 @@ class MediaSyncDel(_PluginBase): # 保存历史 self.save_data("history", history) + def __get_transfer_his(self, media_type, media_name, tmdb_id, season_num, episode_num): + """ + 查询转移记录 + """ + # 删除电影 + if media_type == "Movie" or media_type == "MOV": + msg = f'电影 {media_name} {tmdb_id}' + transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id) + # 删除电视剧 + elif (media_type == "Series" or media_type == "TV") and not season_num and not episode_num: + msg = f'剧集 {media_name} {tmdb_id}' + transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id) + # 删除季 S02 + elif (media_type == "Season" or media_type == "TV") and season_num and not episode_num: + if not season_num or not str(season_num).isdigit(): + logger.error(f"{media_name} 季同步删除失败,未获取到具体季") + return + msg = f'剧集 {media_name} S{season_num} {tmdb_id}' + transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, + season=f'S{season_num}') + # 删除剧集S02E02 + elif (media_type == "Episode" or media_type == "TV") and season_num and episode_num: + if not season_num or not str(season_num).isdigit() or not episode_num or not str(episode_num).isdigit(): + logger.error(f"{media_name} 集同步删除失败,未获取到具体集") + return + msg = f'剧集 {media_name} S{season_num}E{episode_num} {tmdb_id}' + transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, + season=f'S{season_num}', + episode=f'E{episode_num}') + else: + return "", [] + + return msg, transfer_history + def sync_del_by_log(self): """ emby删除媒体库同步删除历史记录