commit
adff3b22e9
@ -770,6 +770,7 @@ class Emby(metaclass=Singleton):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
message = json.loads(message_str)
|
message = json.loads(message_str)
|
||||||
|
logger.info(f"接收到emby webhook:{message}")
|
||||||
eventItem = WebhookEventInfo(event=message.get('Event', ''), channel="emby")
|
eventItem = WebhookEventInfo(event=message.get('Event', ''), channel="emby")
|
||||||
if message.get('Item'):
|
if message.get('Item'):
|
||||||
if message.get('Item', {}).get('Type') == 'Episode':
|
if message.get('Item', {}).get('Type') == 'Episode':
|
||||||
@ -798,9 +799,9 @@ class Emby(metaclass=Singleton):
|
|||||||
eventItem.item_type = "MOV"
|
eventItem.item_type = "MOV"
|
||||||
eventItem.item_name = "%s %s" % (
|
eventItem.item_name = "%s %s" % (
|
||||||
message.get('Item', {}).get('Name'), "(" + str(message.get('Item', {}).get('ProductionYear')) + ")")
|
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_id = message.get('Item', {}).get('Id')
|
||||||
|
|
||||||
|
eventItem.item_path = message.get('Item', {}).get('Path')
|
||||||
eventItem.tmdb_id = message.get('Item', {}).get('ProviderIds', {}).get('Tmdb')
|
eventItem.tmdb_id = message.get('Item', {}).get('ProviderIds', {}).get('Tmdb')
|
||||||
if message.get('Item', {}).get('Overview') and len(message.get('Item', {}).get('Overview')) > 100:
|
if message.get('Item', {}).get('Overview') and len(message.get('Item', {}).get('Overview')) > 100:
|
||||||
eventItem.overview = str(message.get('Item', {}).get('Overview'))[:100] + "..."
|
eventItem.overview = str(message.get('Item', {}).get('Overview'))[:100] + "..."
|
||||||
|
@ -36,7 +36,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 主题色
|
# 主题色
|
||||||
plugin_color = "#ff1a1a"
|
plugin_color = "#ff1a1a"
|
||||||
# 插件版本
|
# 插件版本
|
||||||
plugin_version = "1.0"
|
plugin_version = "1.1"
|
||||||
# 插件作者
|
# 插件作者
|
||||||
plugin_author = "thsrite"
|
plugin_author = "thsrite"
|
||||||
# 作者主页
|
# 作者主页
|
||||||
@ -106,13 +106,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
定义远程控制命令
|
定义远程控制命令
|
||||||
:return: 命令关键字、事件、描述、附带数据
|
:return: 命令关键字、事件、描述、附带数据
|
||||||
"""
|
"""
|
||||||
return [{
|
pass
|
||||||
"cmd": "/sync_del",
|
|
||||||
"event": EventType.HistoryDeleted,
|
|
||||||
"desc": "媒体库同步删除",
|
|
||||||
"category": "管理",
|
|
||||||
"data": {}
|
|
||||||
}]
|
|
||||||
|
|
||||||
def get_api(self) -> List[Dict[str, Any]]:
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
pass
|
pass
|
||||||
@ -250,7 +244,8 @@ class MediaSyncDel(_PluginBase):
|
|||||||
'component': 'VAlert',
|
'component': 'VAlert',
|
||||||
'props': {
|
'props': {
|
||||||
'text': '同步方式分为webhook、日志同步和Scripter X。'
|
'text': '同步方式分为webhook、日志同步和Scripter X。'
|
||||||
'webhook需要Emby4.8.0.45及以上开启媒体删除的webhook。'
|
'webhook需要Emby4.8.0.45及以上开启媒体删除的webhook'
|
||||||
|
'(建议使用媒体库刮削插件覆盖元数据重新刮削剧集路径)。'
|
||||||
'日志同步需要配置执行周期,默认30分钟执行一次。'
|
'日志同步需要配置执行周期,默认30分钟执行一次。'
|
||||||
'Scripter X方式需要emby安装并配置Scripter X插件,无需配置执行周期。'
|
'Scripter X方式需要emby安装并配置Scripter X插件,无需配置执行周期。'
|
||||||
}
|
}
|
||||||
@ -423,47 +418,21 @@ class MediaSyncDel(_PluginBase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@eventmanager.register(EventType.WebhookMessage)
|
@eventmanager.register(EventType.WebhookMessage)
|
||||||
def sync_del_by_plugin_or_webhook(self, event):
|
def sync_del_by_webhook(self, event):
|
||||||
"""
|
"""
|
||||||
emby删除媒体库同步删除历史记录
|
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
|
return
|
||||||
|
|
||||||
event_data = event.event_data
|
event_data = event.event_data
|
||||||
event_type = event_data.event
|
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
|
# 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
|
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
|
media_type = event_data.item_type
|
||||||
# 媒体名称
|
# 媒体名称
|
||||||
@ -474,13 +443,74 @@ class MediaSyncDel(_PluginBase):
|
|||||||
tmdb_id = event_data.tmdb_id
|
tmdb_id = event_data.tmdb_id
|
||||||
# 季数
|
# 季数
|
||||||
season_num = event_data.season_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
|
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:
|
if not media_type:
|
||||||
logger.error(f"{media_name} 同步删除失败,未获取到媒体类型")
|
logger.error(f"{media_name} 同步删除失败,未获取到媒体类型")
|
||||||
return
|
return
|
||||||
@ -494,38 +524,24 @@ class MediaSyncDel(_PluginBase):
|
|||||||
logger.info(f"媒体路径 {media_path} 已被排除,暂不处理")
|
logger.info(f"媒体路径 {media_path} 已被排除,暂不处理")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 删除电影
|
# 季数
|
||||||
if media_type == "Movie" or media_type == "MOV":
|
if season_num and str(season_num).isdigit() and int(season_num) < 10:
|
||||||
msg = f'电影 {media_name} {tmdb_id}'
|
season_num = f'0{season_num}'
|
||||||
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id)
|
# 集数
|
||||||
# 删除电视剧
|
if episode_num and str(episode_num).isdigit() and int(episode_num) < 10:
|
||||||
elif (media_type == "Series" or media_type == "TV") and not season_num and not episode_num:
|
episode_num = f'0{episode_num}'
|
||||||
msg = f'剧集 {media_name} {tmdb_id}'
|
|
||||||
transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id)
|
# 查询转移记录
|
||||||
# 删除季 S02
|
msg, transfer_history = self.__get_transfer_his(media_type=media_type,
|
||||||
elif (media_type == "Season" or media_type == "TV") and season_num and not episode_num:
|
media_name=media_name,
|
||||||
if not season_num or not str(season_num).isdigit():
|
tmdb_id=tmdb_id,
|
||||||
logger.error(f"{media_name} 季同步删除失败,未获取到具体季")
|
season_num=season_num,
|
||||||
return
|
episode_num=episode_num)
|
||||||
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
|
|
||||||
|
|
||||||
logger.info(f"正在同步删除{msg}")
|
logger.info(f"正在同步删除{msg}")
|
||||||
|
|
||||||
if not transfer_history:
|
if not transfer_history:
|
||||||
logger.warn(f"{media_type} {media_name} 未获取到可删除数据")
|
logger.warn(f"{media_type} {media_name} 未获取到可删除数据,可使用媒体库刮削插件覆盖所有元数据")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 开始删除
|
# 开始删除
|
||||||
@ -535,6 +551,11 @@ class MediaSyncDel(_PluginBase):
|
|||||||
stop_cnt = 0
|
stop_cnt = 0
|
||||||
error_cnt = 0
|
error_cnt = 0
|
||||||
for transferhis in transfer_history:
|
for transferhis in transfer_history:
|
||||||
|
title = transferhis.title
|
||||||
|
if title not in media_name:
|
||||||
|
logger.warn(
|
||||||
|
f"当前转移记录 {transferhis.id} {title} {transferhis.tmdbid} 与删除媒体{media_name}不符,防误删,暂不自动删除")
|
||||||
|
continue
|
||||||
image = transferhis.image
|
image = transferhis.image
|
||||||
year = transferhis.year
|
year = transferhis.year
|
||||||
|
|
||||||
@ -587,8 +608,11 @@ class MediaSyncDel(_PluginBase):
|
|||||||
f"时间 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))}"
|
f"时间 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 读取历史记录
|
||||||
|
history = self.get_data('history') or []
|
||||||
|
|
||||||
history.append({
|
history.append({
|
||||||
"type": "电影" if media_type == "Movie" else "电视剧",
|
"type": "电影" if media_type == "Movie" or media_type == "MOV" else "电视剧",
|
||||||
"title": media_name,
|
"title": media_name,
|
||||||
"year": year,
|
"year": year,
|
||||||
"path": media_path,
|
"path": media_path,
|
||||||
@ -601,6 +625,40 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 保存历史
|
# 保存历史
|
||||||
self.save_data("history", history)
|
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):
|
def sync_del_by_log(self):
|
||||||
"""
|
"""
|
||||||
emby删除媒体库同步删除历史记录
|
emby删除媒体库同步删除历史记录
|
||||||
@ -693,6 +751,11 @@ class MediaSyncDel(_PluginBase):
|
|||||||
stop_cnt = 0
|
stop_cnt = 0
|
||||||
error_cnt = 0
|
error_cnt = 0
|
||||||
for transferhis in transfer_history:
|
for transferhis in transfer_history:
|
||||||
|
title = transferhis.title
|
||||||
|
if title not in media_name:
|
||||||
|
logger.warn(
|
||||||
|
f"当前转移记录 {transferhis.id} {title} {transferhis.tmdbid} 与删除媒体{media_name}不符,防误删,暂不自动删除")
|
||||||
|
continue
|
||||||
image = transferhis.image
|
image = transferhis.image
|
||||||
# 0、删除转移记录
|
# 0、删除转移记录
|
||||||
self._transferhis.delete(transferhis.id)
|
self._transferhis.delete(transferhis.id)
|
||||||
@ -768,11 +831,22 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 删除本次种子记录
|
# 删除本次种子记录
|
||||||
self._downloadhis.delete_file_by_fullpath(fullpath=src)
|
self._downloadhis.delete_file_by_fullpath(fullpath=src)
|
||||||
|
|
||||||
# 根据种子hash查询剩余未删除的记录
|
# 根据种子hash查询所有下载器文件记录
|
||||||
downloadHisNoDel = self._downloadhis.get_files_by_hash(download_hash=torrent_hash, state=1)
|
download_files = self._downloadhis.get_files_by_hash(download_hash=torrent_hash)
|
||||||
if downloadHisNoDel and len(downloadHisNoDel) > 0:
|
if not download_files:
|
||||||
|
logger.error(
|
||||||
|
f"未查询到种子任务 {torrent_hash} 存在文件记录,未执行下载器文件同步或该种子已被删除")
|
||||||
|
return False, False
|
||||||
|
|
||||||
|
# 查询未删除数
|
||||||
|
no_del_cnt = 0
|
||||||
|
for download_file in download_files:
|
||||||
|
if download_file and download_file.state and int(download_file.state) == 1:
|
||||||
|
no_del_cnt += 1
|
||||||
|
|
||||||
|
if no_del_cnt > 0:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"查询种子任务 {torrent_hash} 存在 {len(downloadHisNoDel)} 个未删除文件,执行暂停种子操作")
|
f"查询种子任务 {torrent_hash} 存在 {no_del_cnt} 个未删除文件,执行暂停种子操作")
|
||||||
delete_flag = False
|
delete_flag = False
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
|
@ -4,11 +4,8 @@ import sqlite3
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from app.db.downloadhistory_oper import DownloadHistoryOper
|
from app.db.downloadhistory_oper import DownloadHistoryOper
|
||||||
from app.db.models.plugin import PluginData
|
|
||||||
from app.db.plugindata_oper import PluginDataOper
|
from app.db.plugindata_oper import PluginDataOper
|
||||||
from app.db.transferhistory_oper import TransferHistoryOper
|
from app.db.transferhistory_oper import TransferHistoryOper
|
||||||
from app.modules.qbittorrent import Qbittorrent
|
|
||||||
from app.modules.transmission import Transmission
|
|
||||||
from app.plugins import _PluginBase
|
from app.plugins import _PluginBase
|
||||||
from typing import Any, List, Dict, Tuple
|
from typing import Any, List, Dict, Tuple
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
@ -45,10 +42,7 @@ class NAStoolSync(_PluginBase):
|
|||||||
_path = None
|
_path = None
|
||||||
_site = None
|
_site = None
|
||||||
_downloader = None
|
_downloader = None
|
||||||
_supp = False
|
|
||||||
_transfer = False
|
_transfer = False
|
||||||
qb = None
|
|
||||||
tr = None
|
|
||||||
|
|
||||||
def init_plugin(self, config: dict = None):
|
def init_plugin(self, config: dict = None):
|
||||||
self._transferhistory = TransferHistoryOper(self.db)
|
self._transferhistory = TransferHistoryOper(self.db)
|
||||||
@ -61,13 +55,9 @@ class NAStoolSync(_PluginBase):
|
|||||||
self._path = config.get("path")
|
self._path = config.get("path")
|
||||||
self._site = config.get("site")
|
self._site = config.get("site")
|
||||||
self._downloader = config.get("downloader")
|
self._downloader = config.get("downloader")
|
||||||
self._supp = config.get("supp")
|
|
||||||
self._transfer = config.get("transfer")
|
self._transfer = config.get("transfer")
|
||||||
|
|
||||||
if self._nt_db_path and self._transfer:
|
if self._nt_db_path and self._transfer:
|
||||||
self.qb = Qbittorrent()
|
|
||||||
self.tr = Transmission()
|
|
||||||
|
|
||||||
# 读取sqlite数据
|
# 读取sqlite数据
|
||||||
try:
|
try:
|
||||||
gradedb = sqlite3.connect(self._nt_db_path)
|
gradedb = sqlite3.connect(self._nt_db_path)
|
||||||
@ -80,7 +70,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
"path": self._path,
|
"path": self._path,
|
||||||
"downloader": self._downloader,
|
"downloader": self._downloader,
|
||||||
"site": self._site,
|
"site": self._site,
|
||||||
"supp": self._supp,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
logger.error(f"无法打开数据库文件 {self._nt_db_path},请检查路径是否正确:{e}")
|
logger.error(f"无法打开数据库文件 {self._nt_db_path},请检查路径是否正确:{e}")
|
||||||
@ -116,7 +105,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
"path": self._path,
|
"path": self._path,
|
||||||
"downloader": self._downloader,
|
"downloader": self._downloader,
|
||||||
"site": self._site,
|
"site": self._site,
|
||||||
"supp": self._supp,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -270,35 +258,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
logger.info("MoviePilot转移记录已清空")
|
logger.info("MoviePilot转移记录已清空")
|
||||||
self._transferhistory.truncate()
|
self._transferhistory.truncate()
|
||||||
|
|
||||||
# 转种后种子hash
|
|
||||||
transfer_hash = []
|
|
||||||
qb_torrents = []
|
|
||||||
tr_torrents = []
|
|
||||||
tr_torrents_all = []
|
|
||||||
if self._supp:
|
|
||||||
# 获取所有的转种数据
|
|
||||||
transfer_datas = self._plugindata.get_data_all("TorrentTransfer")
|
|
||||||
if transfer_datas:
|
|
||||||
if not isinstance(transfer_datas, list):
|
|
||||||
transfer_datas = [transfer_datas]
|
|
||||||
|
|
||||||
for transfer_data in transfer_datas:
|
|
||||||
if not transfer_data or not isinstance(transfer_data, PluginData):
|
|
||||||
continue
|
|
||||||
# 转移后种子hash
|
|
||||||
transfer_value = transfer_data.value
|
|
||||||
transfer_value = json.loads(transfer_value)
|
|
||||||
if not isinstance(transfer_value, dict):
|
|
||||||
transfer_value = json.loads(transfer_value)
|
|
||||||
to_hash = transfer_value.get("to_download_id")
|
|
||||||
# 转移前种子hash
|
|
||||||
transfer_hash.append(to_hash)
|
|
||||||
|
|
||||||
# 获取tr、qb所有种子
|
|
||||||
qb_torrents, _ = self.qb.get_torrents()
|
|
||||||
tr_torrents, _ = self.tr.get_torrents(ids=transfer_hash)
|
|
||||||
tr_torrents_all, _ = self.tr.get_torrents()
|
|
||||||
|
|
||||||
# 处理数据,存入mp数据库
|
# 处理数据,存入mp数据库
|
||||||
cnt = 0
|
cnt = 0
|
||||||
for history in transfer_history:
|
for history in transfer_history:
|
||||||
@ -315,8 +274,7 @@ class NAStoolSync(_PluginBase):
|
|||||||
mseasons = history[10]
|
mseasons = history[10]
|
||||||
mepisodes = history[11]
|
mepisodes = history[11]
|
||||||
mimage = history[12]
|
mimage = history[12]
|
||||||
mdownload_hash = history[13]
|
mdate = history[13]
|
||||||
mdate = history[14]
|
|
||||||
|
|
||||||
if not msrc_path or not mdest_path:
|
if not msrc_path or not mdest_path:
|
||||||
continue
|
continue
|
||||||
@ -324,78 +282,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
msrc = msrc_path + "/" + msrc_filename
|
msrc = msrc_path + "/" + msrc_filename
|
||||||
mdest = mdest_path + "/" + mdest_filename
|
mdest = mdest_path + "/" + mdest_filename
|
||||||
|
|
||||||
# 尝试补充download_id
|
|
||||||
if self._supp and not mdownload_hash:
|
|
||||||
logger.debug(f"转移记录 {mtitle} 缺失download_hash,尝试补充……")
|
|
||||||
# 种子名称
|
|
||||||
torrent_name = str(msrc_path).split("/")[-1]
|
|
||||||
torrent_name2 = str(msrc_path).split("/")[-2]
|
|
||||||
|
|
||||||
# 处理下载器
|
|
||||||
for torrent in qb_torrents:
|
|
||||||
if str(torrent.get("name")) == str(torrent_name) \
|
|
||||||
or str(torrent.get("name")) == str(torrent_name2):
|
|
||||||
mdownload_hash = torrent.get("hash")
|
|
||||||
torrent_name = str(torrent.get("name"))
|
|
||||||
break
|
|
||||||
|
|
||||||
# 处理辅种器
|
|
||||||
if not mdownload_hash:
|
|
||||||
for torrent in tr_torrents:
|
|
||||||
if str(torrent.get("name")) == str(torrent_name) \
|
|
||||||
or str(torrent.get("name")) == str(torrent_name2):
|
|
||||||
mdownload_hash = torrent.get("hashString")
|
|
||||||
torrent_name = str(torrent.get("name"))
|
|
||||||
break
|
|
||||||
|
|
||||||
# 继续补充 遍历所有种子,按照添加升序升序,第一个种子是初始种子
|
|
||||||
if not mdownload_hash:
|
|
||||||
mate_torrents = []
|
|
||||||
for torrent in tr_torrents_all:
|
|
||||||
if str(torrent.get("name")) == str(torrent_name) \
|
|
||||||
or str(torrent.get("name")) == str(torrent_name2):
|
|
||||||
mate_torrents.append(torrent)
|
|
||||||
|
|
||||||
# 匹配上则按照时间升序
|
|
||||||
if mate_torrents:
|
|
||||||
if len(mate_torrents) > 1:
|
|
||||||
mate_torrents = sorted(mate_torrents, key=lambda x: x.added_date)
|
|
||||||
# 最早添加的hash是下载的hash
|
|
||||||
mdownload_hash = mate_torrents[0].get("hashString")
|
|
||||||
torrent_name = str(mate_torrents[0].get("name"))
|
|
||||||
# 补充转种记录
|
|
||||||
self._plugindata.save(plugin_id="TorrentTransfer",
|
|
||||||
key=f"qbittorrent-{mdownload_hash}",
|
|
||||||
value={
|
|
||||||
"to_download": "transmission",
|
|
||||||
"to_download_id": mdownload_hash,
|
|
||||||
"delete_source": True}
|
|
||||||
)
|
|
||||||
# 补充辅种记录
|
|
||||||
if len(mate_torrents) > 1:
|
|
||||||
self._plugindata.save(plugin_id="IYUUAutoSeed",
|
|
||||||
key=mdownload_hash,
|
|
||||||
value=[{"downloader": "transmission",
|
|
||||||
"torrents": [torrent.get("hashString") for torrent in
|
|
||||||
mate_torrents[1:]]}]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 补充下载历史
|
|
||||||
self._downloadhistory.add(
|
|
||||||
path=msrc_filename,
|
|
||||||
type=mtype,
|
|
||||||
title=mtitle,
|
|
||||||
year=myear,
|
|
||||||
tmdbid=mtmdbid,
|
|
||||||
seasons=mseasons,
|
|
||||||
episodes=mepisodes,
|
|
||||||
image=mimage,
|
|
||||||
download_hash=mdownload_hash,
|
|
||||||
torrent_name=torrent_name,
|
|
||||||
torrent_description="",
|
|
||||||
torrent_site=""
|
|
||||||
)
|
|
||||||
|
|
||||||
# 处理路径映射
|
# 处理路径映射
|
||||||
if self._path:
|
if self._path:
|
||||||
paths = self._path.split("\n")
|
paths = self._path.split("\n")
|
||||||
@ -417,7 +303,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
seasons=mseasons,
|
seasons=mseasons,
|
||||||
episodes=mepisodes,
|
episodes=mepisodes,
|
||||||
image=mimage,
|
image=mimage,
|
||||||
download_hash=mdownload_hash,
|
|
||||||
date=mdate
|
date=mdate
|
||||||
)
|
)
|
||||||
logger.debug(f"{mtitle} {myear} {mtmdbid} {mseasons} {mepisodes} 已同步")
|
logger.debug(f"{mtitle} {myear} {mtmdbid} {mseasons} {mepisodes} 已同步")
|
||||||
@ -529,7 +414,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
NULL ELSE substr( t.SEASON_EPISODE, instr ( t.SEASON_EPISODE, ' ' ) + 1 )
|
NULL ELSE substr( t.SEASON_EPISODE, instr ( t.SEASON_EPISODE, ' ' ) + 1 )
|
||||||
END AS episodes,
|
END AS episodes,
|
||||||
d.POSTER AS image,
|
d.POSTER AS image,
|
||||||
d.DOWNLOAD_ID AS download_hash,
|
|
||||||
t.DATE AS date
|
t.DATE AS date
|
||||||
FROM
|
FROM
|
||||||
TRANSFER_HISTORY t
|
TRANSFER_HISTORY t
|
||||||
@ -571,7 +455,7 @@ class NAStoolSync(_PluginBase):
|
|||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 4
|
'md': 6
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
@ -587,7 +471,7 @@ class NAStoolSync(_PluginBase):
|
|||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 4
|
'md': 6
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
@ -598,22 +482,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
'component': 'VCol',
|
|
||||||
'props': {
|
|
||||||
'cols': 12,
|
|
||||||
'md': 4
|
|
||||||
},
|
|
||||||
'content': [
|
|
||||||
{
|
|
||||||
'component': 'VSwitch',
|
|
||||||
'props': {
|
|
||||||
'model': 'supp',
|
|
||||||
'label': '补充数据'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -717,7 +585,6 @@ class NAStoolSync(_PluginBase):
|
|||||||
'text': '开启清空记录时,会在导入历史数据之前删除MoviePilot之前的记录。'
|
'text': '开启清空记录时,会在导入历史数据之前删除MoviePilot之前的记录。'
|
||||||
'如果转移记录很多,同步时间可能会长(3-10分钟),'
|
'如果转移记录很多,同步时间可能会长(3-10分钟),'
|
||||||
'所以点击确定后页面没反应是正常现象,后台正在处理。'
|
'所以点击确定后页面没反应是正常现象,后台正在处理。'
|
||||||
'如果开启补充数据,会获取tr、qb种子,补充转移记录中download_hash缺失的情况(同步删除需要)。'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user