more plugins
This commit is contained in:
parent
54ffacf743
commit
0c2dbd5c2d
154
app/plugins/chinesesubfinder/__init__.py
Normal file
154
app/plugins/chinesesubfinder/__init__.py
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
from functools import lru_cache
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Tuple, Dict, Any
|
||||||
|
|
||||||
|
from app.core.config import settings
|
||||||
|
from app.core.event import eventmanager
|
||||||
|
from app.log import logger
|
||||||
|
from app.plugins import _PluginBase
|
||||||
|
from app.schemas.types import EventType, MediaType
|
||||||
|
from app.utils.http import RequestUtils
|
||||||
|
|
||||||
|
|
||||||
|
class ChineseSubFinder(_PluginBase):
|
||||||
|
# 插件名称
|
||||||
|
plugin_name = "ChineseSubFinder"
|
||||||
|
# 插件描述
|
||||||
|
plugin_desc = "通知ChineseSubFinder下载字幕。"
|
||||||
|
# 插件图标
|
||||||
|
plugin_icon = "chinesesubfinder.png"
|
||||||
|
# 主题色
|
||||||
|
plugin_color = "#83BE39"
|
||||||
|
# 插件版本
|
||||||
|
plugin_version = "1.0"
|
||||||
|
# 插件作者
|
||||||
|
plugin_author = "jxxghp"
|
||||||
|
# 作者主页
|
||||||
|
author_url = "https://github.com/jxxghp"
|
||||||
|
# 插件配置项ID前缀
|
||||||
|
plugin_config_prefix = "chinesesubfinder_"
|
||||||
|
# 加载顺序
|
||||||
|
plugin_order = 3
|
||||||
|
# 可使用的用户级别
|
||||||
|
auth_level = 1
|
||||||
|
|
||||||
|
# 私有属性
|
||||||
|
_save_tmp_path = None
|
||||||
|
_enable = False
|
||||||
|
_host = None
|
||||||
|
_api_key = None
|
||||||
|
_remote_path = None
|
||||||
|
_local_path = None
|
||||||
|
_remote_path2 = None
|
||||||
|
_local_path2 = None
|
||||||
|
_remote_path3 = None
|
||||||
|
_local_path3 = None
|
||||||
|
|
||||||
|
def init_plugin(self, config: dict = None):
|
||||||
|
self._save_tmp_path = settings.TEMP_PATH
|
||||||
|
if config:
|
||||||
|
self._enable = config.get("enable")
|
||||||
|
self._api_key = config.get("api_key")
|
||||||
|
self._host = config.get('host')
|
||||||
|
if self._host:
|
||||||
|
if not self._host.startswith('http'):
|
||||||
|
self._host = "http://" + self._host
|
||||||
|
if not self._host.endswith('/'):
|
||||||
|
self._host = self._host + "/"
|
||||||
|
self._local_path = config.get("local_path")
|
||||||
|
self._remote_path = config.get("remote_path")
|
||||||
|
self._local_path2 = config.get("local_path2")
|
||||||
|
self._remote_path2 = config.get("remote_path2")
|
||||||
|
self._local_path3 = config.get("local_path3")
|
||||||
|
self._remote_path3 = config.get("remote_path3")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_command() -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_page(self) -> List[dict]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop_service(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@eventmanager.register(EventType.TransferComplete)
|
||||||
|
def download(self, event):
|
||||||
|
"""
|
||||||
|
调用ChineseSubFinder下载字幕
|
||||||
|
"""
|
||||||
|
if not self._host or not self._api_key:
|
||||||
|
return
|
||||||
|
item = event.event_data
|
||||||
|
if not item:
|
||||||
|
return
|
||||||
|
# FIXME
|
||||||
|
req_url = "%sapi/v1/add-job" % self._host
|
||||||
|
|
||||||
|
item_media = item.get("media_info")
|
||||||
|
item_type = item_media.get("type")
|
||||||
|
item_bluray = item.get("bluray")
|
||||||
|
item_file = item.get("file")
|
||||||
|
item_file_ext = item.get("file_ext")
|
||||||
|
|
||||||
|
if item_bluray:
|
||||||
|
file_path = "%s.mp4" % item_file
|
||||||
|
else:
|
||||||
|
if Path(item_file).suffix != item_file_ext:
|
||||||
|
file_path = "%s%s" % (item_file, item_file_ext)
|
||||||
|
else:
|
||||||
|
file_path = item_file
|
||||||
|
|
||||||
|
# 路径替换
|
||||||
|
if self._local_path and self._remote_path and file_path.startswith(self._local_path):
|
||||||
|
file_path = file_path.replace(self._local_path, self._remote_path).replace('\\', '/')
|
||||||
|
|
||||||
|
if self._local_path2 and self._remote_path2 and file_path.startswith(self._local_path2):
|
||||||
|
file_path = file_path.replace(self._local_path2, self._remote_path2).replace('\\', '/')
|
||||||
|
|
||||||
|
if self._local_path3 and self._remote_path3 and file_path.startswith(self._local_path3):
|
||||||
|
file_path = file_path.replace(self._local_path3, self._remote_path3).replace('\\', '/')
|
||||||
|
|
||||||
|
# 调用CSF下载字幕
|
||||||
|
self.__request_csf(req_url=req_url,
|
||||||
|
file_path=file_path,
|
||||||
|
item_type=0 if item_type == MediaType.MOVIE.value else 1,
|
||||||
|
item_bluray=item_bluray)
|
||||||
|
|
||||||
|
@lru_cache(maxsize=128)
|
||||||
|
def __request_csf(self, req_url, file_path, item_type, item_bluray):
|
||||||
|
# 一个名称只建一个任务
|
||||||
|
logger.info("通知ChineseSubFinder下载字幕: %s" % file_path)
|
||||||
|
params = {
|
||||||
|
"video_type": item_type,
|
||||||
|
"physical_video_file_full_path": file_path,
|
||||||
|
"task_priority_level": 3,
|
||||||
|
"media_server_inside_video_id": "",
|
||||||
|
"is_bluray": item_bluray
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
res = RequestUtils(headers={
|
||||||
|
"Authorization": "Bearer %s" % self._api_key
|
||||||
|
}).post(req_url, json=params)
|
||||||
|
if not res or res.status_code != 200:
|
||||||
|
logger.error("调用ChineseSubFinder API失败!")
|
||||||
|
else:
|
||||||
|
# 如果文件目录没有识别的nfo元数据, 此接口会返回控制符,推测是ChineseSubFinder的原因
|
||||||
|
# emby refresh元数据时异步的
|
||||||
|
if res.text:
|
||||||
|
job_id = res.json().get("job_id")
|
||||||
|
message = res.json().get("message")
|
||||||
|
if not job_id:
|
||||||
|
logger.warn("ChineseSubFinder下载字幕出错:%s" % message)
|
||||||
|
else:
|
||||||
|
logger.info("ChineseSubFinder任务添加成功:%s" % job_id)
|
||||||
|
else:
|
||||||
|
logger.error("%s 目录缺失nfo元数据" % file_path)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("连接ChineseSubFinder出错:" + str(e))
|
143
app/plugins/customhosts/__init__.py
Normal file
143
app/plugins/customhosts/__init__.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
from typing import List, Tuple, Dict, Any
|
||||||
|
|
||||||
|
from app.core.event import eventmanager
|
||||||
|
from app.log import logger
|
||||||
|
from app.plugins import _PluginBase
|
||||||
|
from app.schemas.types import EventType
|
||||||
|
from app.utils.ip import IpUtils
|
||||||
|
from app.utils.system import SystemUtils
|
||||||
|
|
||||||
|
from python_hosts import Hosts, HostsEntry
|
||||||
|
|
||||||
|
|
||||||
|
class CustomHosts(_PluginBase):
|
||||||
|
# 插件名称
|
||||||
|
plugin_name = "自定义Hosts"
|
||||||
|
# 插件描述
|
||||||
|
plugin_desc = "修改系统hosts文件,加速网络访问。"
|
||||||
|
# 插件图标
|
||||||
|
plugin_icon = "hosts.png"
|
||||||
|
# 主题色
|
||||||
|
plugin_color = "#02C4E0"
|
||||||
|
# 插件版本
|
||||||
|
plugin_version = "1.0"
|
||||||
|
# 插件作者
|
||||||
|
plugin_author = "thsrite"
|
||||||
|
# 作者主页
|
||||||
|
author_url = "https://github.com/thsrite"
|
||||||
|
# 插件配置项ID前缀
|
||||||
|
plugin_config_prefix = "customhosts_"
|
||||||
|
# 加载顺序
|
||||||
|
plugin_order = 11
|
||||||
|
# 可使用的用户级别
|
||||||
|
auth_level = 1
|
||||||
|
|
||||||
|
# 私有属性
|
||||||
|
_hosts = []
|
||||||
|
_enable = False
|
||||||
|
|
||||||
|
def init_plugin(self, config: dict = None):
|
||||||
|
# 读取配置
|
||||||
|
if config:
|
||||||
|
self._enable = config.get("enable")
|
||||||
|
self._hosts = config.get("hosts")
|
||||||
|
if isinstance(self._hosts, str):
|
||||||
|
self._hosts = str(self._hosts).split('\n')
|
||||||
|
if self._enable and self._hosts:
|
||||||
|
# 排除空的host
|
||||||
|
new_hosts = []
|
||||||
|
for host in self._hosts:
|
||||||
|
if host and host != '\n':
|
||||||
|
new_hosts.append(host.replace("\n", "") + "\n")
|
||||||
|
self._hosts = new_hosts
|
||||||
|
|
||||||
|
# 添加到系统
|
||||||
|
error_flag, error_hosts = self.__add_hosts_to_system(self._hosts)
|
||||||
|
self._enable = self._enable and not error_flag
|
||||||
|
|
||||||
|
# 更新错误Hosts
|
||||||
|
self.update_config({
|
||||||
|
"hosts": self._hosts,
|
||||||
|
"err_hosts": error_hosts,
|
||||||
|
"enable": self._enable
|
||||||
|
})
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_command() -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_page(self) -> List[dict]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __read_system_hosts():
|
||||||
|
"""
|
||||||
|
读取系统hosts对象
|
||||||
|
"""
|
||||||
|
# 获取本机hosts路径
|
||||||
|
if SystemUtils.is_windows():
|
||||||
|
hosts_path = r"c:\windows\system32\drivers\etc\hosts"
|
||||||
|
else:
|
||||||
|
hosts_path = '/etc/hosts'
|
||||||
|
# 读取系统hosts
|
||||||
|
return Hosts(path=hosts_path)
|
||||||
|
|
||||||
|
def __add_hosts_to_system(self, hosts):
|
||||||
|
"""
|
||||||
|
添加hosts到系统
|
||||||
|
"""
|
||||||
|
# 系统hosts对象
|
||||||
|
system_hosts = self.__read_system_hosts()
|
||||||
|
# 过滤掉插件添加的hosts
|
||||||
|
orgin_entries = []
|
||||||
|
for entry in system_hosts.entries:
|
||||||
|
if entry.entry_type == "comment" and entry.comment == "# CustomHostsPlugin":
|
||||||
|
break
|
||||||
|
orgin_entries.append(entry)
|
||||||
|
system_hosts.entries = orgin_entries
|
||||||
|
# 新的有效hosts
|
||||||
|
new_entrys = []
|
||||||
|
# 新的错误的hosts
|
||||||
|
err_hosts = []
|
||||||
|
err_flag = False
|
||||||
|
for host in hosts:
|
||||||
|
if not host:
|
||||||
|
continue
|
||||||
|
host_arr = str(host).split()
|
||||||
|
try:
|
||||||
|
host_entry = HostsEntry(entry_type='ipv4' if IpUtils.is_ipv4(str(host_arr[0])) else 'ipv6',
|
||||||
|
address=host_arr[0],
|
||||||
|
names=host_arr[1:])
|
||||||
|
new_entrys.append(host_entry)
|
||||||
|
except Exception as err:
|
||||||
|
err_hosts.append(host + "\n")
|
||||||
|
logger.error(f"{host} 格式转换错误:{str(err)}")
|
||||||
|
|
||||||
|
# 写入系统hosts
|
||||||
|
if new_entrys:
|
||||||
|
try:
|
||||||
|
# 添加分隔标识
|
||||||
|
system_hosts.add([HostsEntry(entry_type='comment', comment="# CustomHostsPlugin")])
|
||||||
|
# 添加新的Hosts
|
||||||
|
system_hosts.add(new_entrys)
|
||||||
|
system_hosts.write()
|
||||||
|
logger.info("更新系统hosts文件成功")
|
||||||
|
except Exception as err:
|
||||||
|
err_flag = True
|
||||||
|
logger.error(f"更新系统hosts文件失败:{str(err) or '请检查权限'}")
|
||||||
|
return err_flag, err_hosts
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return self._enable and self._hosts and self._hosts[0]
|
||||||
|
|
||||||
|
def stop_service(self):
|
||||||
|
"""
|
||||||
|
退出插件
|
||||||
|
"""
|
||||||
|
pass
|
59
app/plugins/dirmonitor/__init__.py
Normal file
59
app/plugins/dirmonitor/__init__.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from typing import List, Tuple, Dict, Any
|
||||||
|
|
||||||
|
from app.plugins import _PluginBase
|
||||||
|
|
||||||
|
|
||||||
|
class DirMonitor(_PluginBase):
|
||||||
|
# 插件名称
|
||||||
|
plugin_name = "目录监控"
|
||||||
|
# 插件描述
|
||||||
|
plugin_desc = "监控目录,文件发生变化时实时整理到媒体库。"
|
||||||
|
# 插件图标
|
||||||
|
plugin_icon = "synctimer.png"
|
||||||
|
# 主题色
|
||||||
|
plugin_color = "#53BA48"
|
||||||
|
# 插件版本
|
||||||
|
plugin_version = "1.0"
|
||||||
|
# 插件作者
|
||||||
|
plugin_author = "jxxghp"
|
||||||
|
# 作者主页
|
||||||
|
author_url = "https://github.com/jxxghp"
|
||||||
|
# 插件配置项ID前缀
|
||||||
|
plugin_config_prefix = "dirmonitor_"
|
||||||
|
# 加载顺序
|
||||||
|
plugin_order = 5
|
||||||
|
# 可使用的用户级别
|
||||||
|
user_level = 1
|
||||||
|
|
||||||
|
# 私有属性
|
||||||
|
_monitor = None
|
||||||
|
_enable = False
|
||||||
|
|
||||||
|
def init_plugin(self, config: dict = None):
|
||||||
|
# 读取配置
|
||||||
|
if config:
|
||||||
|
self._enable = config.get("enable")
|
||||||
|
|
||||||
|
# 停止现有任务
|
||||||
|
self.stop_service()
|
||||||
|
|
||||||
|
# TODO 启动任务
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_command() -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_page(self) -> List[dict]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop_service(self):
|
||||||
|
"""
|
||||||
|
退出插件
|
||||||
|
"""
|
||||||
|
pass
|
210
app/plugins/doubanrank/__init__.py
Normal file
210
app/plugins/doubanrank/__init__.py
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
import re
|
||||||
|
import xml.dom.minidom
|
||||||
|
from threading import Event
|
||||||
|
from typing import Tuple, List, Dict, Any
|
||||||
|
|
||||||
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
|
from apscheduler.triggers.cron import CronTrigger
|
||||||
|
|
||||||
|
from app.core.config import settings
|
||||||
|
from app.log import logger
|
||||||
|
from app.plugins import _PluginBase
|
||||||
|
from app.utils.dom import DomUtils
|
||||||
|
from app.utils.http import RequestUtils
|
||||||
|
|
||||||
|
|
||||||
|
class DoubanRank(_PluginBase):
|
||||||
|
|
||||||
|
# 插件名称
|
||||||
|
plugin_name = "豆瓣榜单订阅"
|
||||||
|
# 插件描述
|
||||||
|
plugin_desc = "监控豆瓣热门榜单,自动添加订阅。"
|
||||||
|
# 插件图标
|
||||||
|
plugin_icon = "movie.jpg"
|
||||||
|
# 主题色
|
||||||
|
plugin_color = "#01B3E3"
|
||||||
|
# 插件版本
|
||||||
|
plugin_version = "1.0"
|
||||||
|
# 插件作者
|
||||||
|
plugin_author = "jxxghp"
|
||||||
|
# 作者主页
|
||||||
|
author_url = "https://github.com/jxxghp"
|
||||||
|
# 插件配置项ID前缀
|
||||||
|
plugin_config_prefix = "doubanrank_"
|
||||||
|
# 加载顺序
|
||||||
|
plugin_order = 16
|
||||||
|
# 可使用的用户级别
|
||||||
|
auth_level = 2
|
||||||
|
|
||||||
|
# 退出事件
|
||||||
|
_event = Event()
|
||||||
|
# 私有属性
|
||||||
|
mediaserver = None
|
||||||
|
subscribe = None
|
||||||
|
rsshelper = None
|
||||||
|
media = None
|
||||||
|
_douban_address = {
|
||||||
|
'movie-ustop': 'https://rsshub.app/douban/movie/ustop',
|
||||||
|
'movie-weekly': 'https://rsshub.app/douban/movie/weekly',
|
||||||
|
'movie-real-time': 'https://rsshub.app/douban/movie/weekly/subject_real_time_hotest',
|
||||||
|
'show-domestic': 'https://rsshub.app/douban/movie/weekly/show_domestic',
|
||||||
|
'movie-hot-gaia': 'https://rsshub.app/douban/movie/weekly/movie_hot_gaia',
|
||||||
|
'tv-hot': 'https://rsshub.app/douban/movie/weekly/tv_hot',
|
||||||
|
'movie-top250': 'https://rsshub.app/douban/movie/weekly/movie_top250',
|
||||||
|
}
|
||||||
|
_enable = False
|
||||||
|
_cron = ""
|
||||||
|
_rss_addrs = []
|
||||||
|
_ranks = []
|
||||||
|
_vote = 0
|
||||||
|
_scheduler = None
|
||||||
|
|
||||||
|
def init_plugin(self, config: dict = None):
|
||||||
|
if config:
|
||||||
|
self._enable = config.get("enable")
|
||||||
|
self._cron = config.get("cron")
|
||||||
|
self._vote = float(config.get("vote")) if config.get("vote") else 0
|
||||||
|
rss_addrs = config.get("rss_addrs")
|
||||||
|
if rss_addrs:
|
||||||
|
if isinstance(rss_addrs, str):
|
||||||
|
self._rss_addrs = rss_addrs.split('\n')
|
||||||
|
else:
|
||||||
|
self._rss_addrs = rss_addrs
|
||||||
|
else:
|
||||||
|
self._rss_addrs = []
|
||||||
|
self._ranks = config.get("ranks") or []
|
||||||
|
|
||||||
|
# 停止现有任务
|
||||||
|
self.stop_service()
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
if self._enable:
|
||||||
|
self._scheduler = BackgroundScheduler(timezone=settings.TZ)
|
||||||
|
if self._cron:
|
||||||
|
logger.info(f"豆瓣榜单订阅服务启动,周期:{self._cron}")
|
||||||
|
self._scheduler.add_job(self.__refresh_rss,
|
||||||
|
CronTrigger.from_crontab(self._cron))
|
||||||
|
|
||||||
|
if self._scheduler.get_jobs():
|
||||||
|
# 启动服务
|
||||||
|
self._scheduler.print_jobs()
|
||||||
|
self._scheduler.start()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_command() -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_page(self) -> List[dict]:
|
||||||
|
"""
|
||||||
|
拼装插件详情页面,需要返回页面配置,同时附带数据
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop_service(self):
|
||||||
|
"""
|
||||||
|
停止服务
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if self._scheduler:
|
||||||
|
self._scheduler.remove_all_jobs()
|
||||||
|
if self._scheduler.running:
|
||||||
|
self._event.set()
|
||||||
|
self._scheduler.shutdown()
|
||||||
|
self._event.clear()
|
||||||
|
self._scheduler = None
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
|
||||||
|
def __refresh_rss(self):
|
||||||
|
"""
|
||||||
|
刷新RSS
|
||||||
|
"""
|
||||||
|
logger.info(f"开始刷新RSS ...")
|
||||||
|
addr_list = self._rss_addrs + [self._douban_address.get(rank) for rank in self._ranks]
|
||||||
|
if not addr_list:
|
||||||
|
logger.info(f"未设置RSS地址")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
logger.info(f"共 {len(addr_list)} 个RSS地址需要刷新")
|
||||||
|
for addr in addr_list:
|
||||||
|
if not addr:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
logger.info(f"获取RSS:{addr} ...")
|
||||||
|
rss_infos = self.__get_rss_info(addr)
|
||||||
|
if not rss_infos:
|
||||||
|
logger.error(f"RSS地址:{addr} ,未查询到数据")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
logger.info(f"RSS地址:{addr} ,共 {len(rss_infos)} 条数据")
|
||||||
|
for rss_info in rss_infos:
|
||||||
|
if self._event.is_set():
|
||||||
|
logger.info(f"订阅服务停止")
|
||||||
|
return
|
||||||
|
|
||||||
|
title = rss_info.get('title')
|
||||||
|
douban_id = rss_info.get('doubanid')
|
||||||
|
mtype = rss_info.get('type')
|
||||||
|
unique_flag = f"doubanrank: {title} (DB:{douban_id})"
|
||||||
|
# TODO 检查是否已处理过
|
||||||
|
# TODO 识别媒体信息
|
||||||
|
# TODO 检查媒体服务器是否存在
|
||||||
|
# TODO 检查是否已订阅过
|
||||||
|
# TODO 添加处理历史
|
||||||
|
# TODO 添加订阅
|
||||||
|
# TODO 发送通知
|
||||||
|
# TODO 更新历史记录
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(str(e))
|
||||||
|
logger.info(f"所有榜单RSS刷新完成")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_rss_info(addr):
|
||||||
|
"""
|
||||||
|
获取RSS
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
ret = RequestUtils().get_res(addr)
|
||||||
|
if not ret:
|
||||||
|
return []
|
||||||
|
ret.encoding = ret.apparent_encoding
|
||||||
|
ret_xml = ret.text
|
||||||
|
ret_array = []
|
||||||
|
# 解析XML
|
||||||
|
dom_tree = xml.dom.minidom.parseString(ret_xml)
|
||||||
|
rootNode = dom_tree.documentElement
|
||||||
|
items = rootNode.getElementsByTagName("item")
|
||||||
|
for item in items:
|
||||||
|
try:
|
||||||
|
# 标题
|
||||||
|
title = DomUtils.tag_value(item, "title", default="")
|
||||||
|
# 链接
|
||||||
|
link = DomUtils.tag_value(item, "link", default="")
|
||||||
|
if not title and not link:
|
||||||
|
logger.warn(f"条目标题和链接均为空,无法处理")
|
||||||
|
continue
|
||||||
|
doubanid = re.findall(r"/(\d+)/", link)
|
||||||
|
if doubanid:
|
||||||
|
doubanid = doubanid[0]
|
||||||
|
if doubanid and not str(doubanid).isdigit():
|
||||||
|
logger.warn(f"解析的豆瓣ID格式不正确:{doubanid}")
|
||||||
|
continue
|
||||||
|
# 返回对象
|
||||||
|
ret_array.append({
|
||||||
|
'title': title,
|
||||||
|
'link': link,
|
||||||
|
'doubanid': doubanid
|
||||||
|
})
|
||||||
|
except Exception as e1:
|
||||||
|
logger.error("解析RSS条目失败:" + str(e1))
|
||||||
|
continue
|
||||||
|
return ret_array
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("获取RSS失败:" + str(e))
|
||||||
|
return []
|
65
app/plugins/torrentremover/__init__.py
Normal file
65
app/plugins/torrentremover/__init__.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
from typing import List, Tuple, Dict, Any
|
||||||
|
|
||||||
|
from app.core.event import eventmanager
|
||||||
|
from app.plugins import _PluginBase
|
||||||
|
from app.schemas.types import EventType
|
||||||
|
|
||||||
|
|
||||||
|
class TorrentRemover(_PluginBase):
|
||||||
|
# 插件名称
|
||||||
|
plugin_name = "下载任务联动删除"
|
||||||
|
# 插件描述
|
||||||
|
plugin_desc = "历史记录被删除时,同步删除下载器中的下载任务。"
|
||||||
|
# 插件图标
|
||||||
|
plugin_icon = "torrentremover.png"
|
||||||
|
# 主题色
|
||||||
|
plugin_color = "#F44336"
|
||||||
|
# 插件版本
|
||||||
|
plugin_version = "1.0"
|
||||||
|
# 插件作者
|
||||||
|
plugin_author = "jxxghp"
|
||||||
|
# 作者主页
|
||||||
|
author_url = "https://github.com/jxxghp"
|
||||||
|
# 插件配置项ID前缀
|
||||||
|
plugin_config_prefix = "torrentremover_"
|
||||||
|
# 加载顺序
|
||||||
|
plugin_order = 9
|
||||||
|
# 可使用的用户级别
|
||||||
|
auth_level = 2
|
||||||
|
|
||||||
|
# 私有属性
|
||||||
|
downloader = None
|
||||||
|
_enable = False
|
||||||
|
|
||||||
|
def init_plugin(self, config: dict = None):
|
||||||
|
if config:
|
||||||
|
self._enable = config.get("enable")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_command() -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_page(self) -> List[dict]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop_service(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@eventmanager.register(EventType.HistoryDeleted)
|
||||||
|
def deletetorrent(self, event):
|
||||||
|
"""
|
||||||
|
联动删除下载器中的下载任务
|
||||||
|
"""
|
||||||
|
if not self._enable:
|
||||||
|
return
|
||||||
|
event_info = event.event_data
|
||||||
|
if not event_info:
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO 删除所有下载任务
|
@ -30,6 +30,8 @@ class EventType(Enum):
|
|||||||
TransferComplete = "transfer.complete"
|
TransferComplete = "transfer.complete"
|
||||||
# 添加下载
|
# 添加下载
|
||||||
DownloadAdded = "download.added"
|
DownloadAdded = "download.added"
|
||||||
|
# 删除历史记录
|
||||||
|
HistoryDeleted = "history.deleted"
|
||||||
|
|
||||||
|
|
||||||
# 系统配置Key字典
|
# 系统配置Key字典
|
||||||
|
@ -42,4 +42,5 @@ starlette~=0.27.0
|
|||||||
PyVirtualDisplay~=3.0
|
PyVirtualDisplay~=3.0
|
||||||
Cython~=0.29.35
|
Cython~=0.29.35
|
||||||
tvdb_api~=3.1
|
tvdb_api~=3.1
|
||||||
psutil==5.9.4
|
psutil~=5.9.4
|
||||||
|
python_hosts~=1.0.3
|
Loading…
x
Reference in New Issue
Block a user