Merge pull request #43 from thsrite/main

This commit is contained in:
jxxghp 2023-08-08 13:22:21 +08:00 committed by GitHub
commit 2d79044350
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 345 additions and 65 deletions

View File

@ -36,3 +36,9 @@ class DownloadHistoryOper(DbOper):
分页查询下载历史 分页查询下载历史
""" """
return DownloadHistory.list_by_page(self._db, page, count) return DownloadHistory.list_by_page(self._db, page, count)
def truncate(self):
"""
清空转移记录
"""
DownloadHistory.truncate(self._db)

View File

@ -43,3 +43,9 @@ class PluginDataOper(DbOper):
if ObjectUtils.is_obj(data.value): if ObjectUtils.is_obj(data.value):
return json.loads(data.value) return json.loads(data.value)
return data.value return data.value
def truncate(self):
"""
清空转移记录
"""
PluginData.truncate(self._db)

View File

@ -187,7 +187,7 @@ class ChineseSubFinder(_PluginBase):
""" """
调用ChineseSubFinder下载字幕 调用ChineseSubFinder下载字幕
""" """
if not self._host or not self._api_key: if not self._enabled or not self._host or not self._api_key:
return return
item = event.event_data item = event.event_data
if not item: if not item:

View File

@ -1,6 +1,9 @@
import os
import sqlite3 import sqlite3
from datetime import datetime from datetime import datetime
from app.db.downloadhistory_oper import DownloadHistoryOper
from app.db.plugindata_oper import PluginDataOper
from app.db.transferhistory_oper import TransferHistoryOper from app.db.transferhistory_oper import TransferHistoryOper
from app.plugins import _PluginBase from app.plugins import _PluginBase
from typing import Any, List, Dict, Tuple from typing import Any, List, Dict, Tuple
@ -11,7 +14,7 @@ class NAStoolSync(_PluginBase):
# 插件名称 # 插件名称
plugin_name = "历史记录同步" plugin_name = "历史记录同步"
# 插件描述 # 插件描述
plugin_desc = "同步NAStool历史记录到MoviePilot。" plugin_desc = "同步NAStool历史记录、下载记录、插件记录到MoviePilot。"
# 插件图标 # 插件图标
plugin_icon = "sync.png" plugin_icon = "sync.png"
# 主题色 # 主题色
@ -31,29 +34,153 @@ class NAStoolSync(_PluginBase):
# 私有属性 # 私有属性
_transferhistory = None _transferhistory = None
_plugindata = None
_downloadhistory = None
_clear = None _clear = None
_nt_db_path = None _nt_db_path = None
_path = None _path = None
_site = None
_transfer = None
_plugin = None
_download = None
def init_plugin(self, config: dict = None): def init_plugin(self, config: dict = None):
self._transferhistory = TransferHistoryOper() self._transferhistory = TransferHistoryOper()
self._plugindata = PluginDataOper()
self._downloadhistory = DownloadHistoryOper()
if config: if config:
self._clear = config.get("clear") self._clear = config.get("clear")
self._nt_db_path = config.get("nt_db_path") self._nt_db_path = config.get("nt_db_path")
self._path = config.get("path") self._path = config.get("path")
self._site = config.get("site")
self._transfer = config.get("transfer")
self._plugin = config.get("plugin")
self._download = config.get("download")
if self._nt_db_path: if self._nt_db_path and (self._transfer or self._plugin or self._download):
# 导入转移历史 # 读取sqlite数据
self.sync_transfer_history() gradedb = sqlite3.connect(self._nt_db_path)
# 创建游标cursor来执行execute语句
cursor = gradedb.cursor()
def sync_transfer_history(self): # 转移历史记录
if self._transfer:
transfer_history = self.get_nt_transfer_history(cursor)
# 导入历史记录
self.sync_transfer_history(transfer_history)
# 插件历史记录
if self._plugin:
plugin_history = self.get_nt_plugin_history(cursor)
# 导入插件记录
self.sync_plugin_history(plugin_history)
# 下载历史记录
if self._download:
download_history = self.get_nt_download_history(cursor)
# 导入下载记录
self.sync_download_history(download_history)
# 关闭游标
cursor.close()
self.update_config(
{
"clear": False,
"nt_db_path": "",
"path": self._path,
"site": self._site,
"transfer": self._transfer,
"plugin": self._plugin,
"download": self._download,
}
)
def sync_plugin_history(self, plugin_history):
"""
导入插件记录
"""
# 开始计时
start_time = datetime.now()
logger.info("开始同步NAStool插件历史记录到MoviePilot")
# 清空MoviePilot插件记录
if self._clear:
logger.info("MoviePilot插件记录已清空")
self._plugindata.truncate()
for history in plugin_history:
plugin_id = history[1]
plugin_key = history[2]
plugin_value = history[3]
self._plugindata.save(plugin_id=plugin_id,
key=plugin_key,
value=plugin_value)
# 计算耗时
end_time = datetime.now()
logger.info(f"插件记录已同步完成。总耗时 {(end_time - start_time).seconds}")
def sync_download_history(self, download_history):
"""
导入下载记录
"""
# 开始计时
start_time = datetime.now()
logger.info("开始同步NAStool下载历史记录到MoviePilot")
# 清空MoviePilot下载记录
if self._clear:
logger.info("MoviePilot下载记录已清空")
self._downloadhistory.truncate()
for history in download_history:
mpath = history[0]
mtype = history[1]
mtitle = history[2]
myear = history[3]
mtmdbid = history[4]
mseasons = history[5]
mepisodes = history[6]
mimages = history[7]
mdownload_hash = history[8]
mtorrent = history[9]
mdesc = history[10]
msite = history[11]
# 处理站点映射
if self._site:
sites = self._site.split("\n")
for site in sites:
sub_sites = site.split(":")
if str(msite) == str(sub_sites[0]):
msite = str(sub_sites[1])
self._downloadhistory.add(
path=os.path.basename(mpath),
type=mtype,
title=mtitle,
year=myear,
tmdbid=mtmdbid,
seasons=mseasons,
episodes=mepisodes,
image=mimages,
download_hash=mdownload_hash,
torrent_name=mtorrent,
torrent_description=mdesc,
torrent_site=msite
)
# 计算耗时
end_time = datetime.now()
logger.info(f"下载记录已同步完成。总耗时 {(end_time - start_time).seconds}")
def sync_transfer_history(self, transfer_history):
""" """
导入nt转移记录 导入nt转移记录
""" """
# 开始计时 # 开始计时
start_time = datetime.now() start_time = datetime.now()
logger.info("开始同步NAStool转移历史记录到MoviePilot")
nt_historys = self.get_nt_transfer_history()
# 清空MoviePilot转移记录 # 清空MoviePilot转移记录
if self._clear: if self._clear:
@ -61,7 +188,7 @@ class NAStoolSync(_PluginBase):
self._transferhistory.truncate() self._transferhistory.truncate()
# 处理数据存入mp数据库 # 处理数据存入mp数据库
for history in nt_historys: for history in transfer_history:
msrc = history[0] msrc = history[0]
mdest = history[1] mdest = history[1]
mmode = history[2] mmode = history[2]
@ -105,68 +232,113 @@ class NAStoolSync(_PluginBase):
) )
logger.debug(f"{mtitle} {myear} {mtmdbid} {mseasons} {mepisodes} 已同步") logger.debug(f"{mtitle} {myear} {mtmdbid} {mseasons} {mepisodes} 已同步")
self.update_config(
{
"clear": False,
"nt_db_path": "",
"path": self._path
}
)
# 计算耗时 # 计算耗时
end_time = datetime.now() end_time = datetime.now()
logger.info(f"转移记录已同步完成。总耗时 {(end_time - start_time).seconds}") logger.info(f"转移记录已同步完成。总耗时 {(end_time - start_time).seconds}")
def get_nt_transfer_history(self): def get_nt_plugin_history(self, cursor):
"""
获取插件历史记录
"""
sql = 'select * from PLUGIN_HISTORY;'
cursor.execute(sql)
plugin_history = cursor.fetchall()
if not plugin_history:
logger.error("未获取到NAStool数据库文件中的插件历史请检查数据库路径是正确")
return
logger.info(f"获取到NAStool插件记录 {len(plugin_history)}")
return plugin_history
def get_nt_download_history(self, cursor):
"""
获取下载历史记录
"""
sql = '''
SELECT
SAVE_PATH,
TYPE,
TITLE,
YEAR,
TMDBID,
CASE
SE
WHEN NULL THEN
NULL ELSE substr( SE, 1, instr ( SE, ' ' ) - 1 )
END AS seasons,
CASE
SE
WHEN NULL THEN
NULL ELSE substr( SE, instr ( SE, ' ' ) + 1 )
END AS episodes,
POSTER,
DOWNLOAD_ID,
TORRENT,
DESC,
SITE
FROM
DOWNLOAD_HISTORY
WHERE
SAVE_PATH IS NOT NULL;
'''
cursor.execute(sql)
download_history = cursor.fetchall()
if not download_history:
logger.error("未获取到NAStool数据库文件中的下载历史请检查数据库路径是正确")
return
logger.info(f"获取到NAStool下载记录 {len(download_history)}")
return download_history
def get_nt_transfer_history(self, cursor):
""" """
获取nt转移记录 获取nt转移记录
""" """
# 读取sqlite数据 sql = '''
gradedb = sqlite3.connect(self._nt_db_path) SELECT
# 创建游标cursor来执行execute语句 t.SOURCE_PATH || '/' || t.SOURCE_FILENAME AS src,
cursor = gradedb.cursor() t.DEST_PATH || '/' || t.DEST_FILENAME AS dest,
sql = '''SELECT CASE
t.SOURCE_PATH || '/' || t.SOURCE_FILENAME AS src, t.MODE
t.DEST_PATH || '/' || t.DEST_FILENAME AS dest, WHEN '硬链接' THEN
CASE 'link'
t.MODE WHEN '移动' THEN
WHEN '硬链接' THEN 'move'
'link' WHEN '复制' THEN
WHEN '移动' THEN 'copy'
'move' END AS mode,
WHEN '复制' THEN CASE
'copy' t.TYPE
END AS mode, WHEN '动漫' THEN
CASE '电视剧' ELSE t.TYPE
t.TYPE END AS type,
WHEN '动漫' THEN t.CATEGORY AS category,
'电视剧' ELSE t.TYPE t.TITLE AS title,
END AS type, t.YEAR AS year,
t.CATEGORY AS category, t.TMDBID AS tmdbid,
t.TITLE AS title, CASE
t.YEAR AS year, t.SEASON_EPISODE
t.TMDBID AS tmdbid, WHEN NULL THEN
CASE NULL ELSE substr( t.SEASON_EPISODE, 1, instr ( t.SEASON_EPISODE, ' ' ) - 1 )
t.SEASON_EPISODE END AS seasons,
WHEN NULL THEN CASE
NULL ELSE substr( t.SEASON_EPISODE, 1, instr ( t.SEASON_EPISODE, ' ' ) - 1 ) t.SEASON_EPISODE
END AS seasons, WHEN NULL THEN
CASE NULL ELSE substr( t.SEASON_EPISODE, instr ( t.SEASON_EPISODE, ' ' ) + 1 )
t.SEASON_EPISODE END AS episodes,
WHEN NULL THEN d.POSTER AS image,
NULL ELSE substr( t.SEASON_EPISODE, instr ( t.SEASON_EPISODE, ' ' ) + 1 ) d.DOWNLOAD_ID AS download_hash,
END AS episodes, t.DATE AS date
d.POSTER AS image, FROM
d.DOWNLOAD_ID AS download_hash, TRANSFER_HISTORY t
t.DATE AS date LEFT JOIN ( SELECT * FROM DOWNLOAD_HISTORY GROUP BY TMDBID ) d ON t.TITLE = d.TITLE
FROM AND t.TYPE = d.TYPE;
TRANSFER_HISTORY t '''
LEFT JOIN ( SELECT * FROM DOWNLOAD_HISTORY GROUP BY TMDBID ) d ON t.TITLE = d.TITLE
AND t.TYPE = d.TYPE;'''
cursor.execute(sql) cursor.execute(sql)
nt_historys = cursor.fetchall() nt_historys = cursor.fetchall()
cursor.close()
if not nt_historys: if not nt_historys:
logger.error("未获取到NAStool数据库文件中的转移历史请检查数据库路径是正确") logger.error("未获取到NAStool数据库文件中的转移历史请检查数据库路径是正确")
@ -200,19 +372,66 @@ class NAStoolSync(_PluginBase):
'component': 'VCol', 'component': 'VCol',
'props': { 'props': {
'cols': 12, 'cols': 12,
'md': 6 'md': 3
}, },
'content': [ 'content': [
{ {
'component': 'VSwitch', 'component': 'VSwitch',
'props': { 'props': {
'model': 'clear', 'model': 'clear',
'label': '清空记录', 'label': '清空记录'
'placeholder': '开启会清空MoviePilot历史记录'
} }
} }
] ]
} },
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 3
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'transfer',
'label': '转移记录'
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 3
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'plugin',
'label': '插件记录'
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 3
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'download',
'label': '下载记录'
}
}
]
},
] ]
}, },
{ {
@ -248,6 +467,7 @@ class NAStoolSync(_PluginBase):
'component': 'VTextarea', 'component': 'VTextarea',
'props': { 'props': {
'model': 'path', 'model': 'path',
'rows': '2',
'label': '路径映射', 'label': '路径映射',
'placeholder': 'NAStool路径:MoviePilot路径一行一个' 'placeholder': 'NAStool路径:MoviePilot路径一行一个'
} }
@ -256,12 +476,60 @@ class NAStoolSync(_PluginBase):
} }
] ]
}, },
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
},
'content': [
{
'component': 'VTextarea',
'props': {
'model': 'site',
'label': '站点映射',
'placeholder': 'NAStool站点名:MoviePilot站点名一行一个'
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
},
'content': [
{
'component': 'VAlert',
'props': {
'text': '只有开启转移记录、插件记录、下载记录其中之一插件才会启用。'
'开启清空记录时会在导入历史数据之前删除MoviePilot之前的记录。'
'如果转移记录很多,同步时间可能会长,'
'所以点击确定后页面没反应是正常现象,后台正在处理。'
'路径映射在同步转移记录时有效、站点映射在同步下载记录时有效。'
}
}
]
}
]
}
] ]
} }
], { ], {
"clear": False, "clear": False,
"transfer": False,
"plugin": False,
"download": False,
"nt_db_path": "", "nt_db_path": "",
"path": "", "path": "",
"site": "",
} }
def get_page(self) -> List[dict]: def get_page(self) -> List[dict]: