Merge pull request #929 from thsrite/main
This commit is contained in:
224
app/plugins/autologin/__init__.py
Normal file
224
app/plugins/autologin/__init__.py
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
from typing import Any, List, Dict, Tuple
|
||||||
|
|
||||||
|
from app.chain.site import SiteChain
|
||||||
|
from app.core.event import eventmanager
|
||||||
|
from app.db.site_oper import SiteOper
|
||||||
|
from app.log import logger
|
||||||
|
from app.plugins import _PluginBase
|
||||||
|
from app.schemas.types import EventType, NotificationType
|
||||||
|
from app.utils.string import StringUtils
|
||||||
|
|
||||||
|
|
||||||
|
class AutoLogin(_PluginBase):
|
||||||
|
# 插件名称
|
||||||
|
plugin_name = "自动登录"
|
||||||
|
# 插件描述
|
||||||
|
plugin_desc = "配置站点用户名和密码、Cookie过期自动登录刷新Cookie和Ua。"
|
||||||
|
# 插件图标
|
||||||
|
plugin_icon = "login.png"
|
||||||
|
# 主题色
|
||||||
|
plugin_color = "#99b3ff"
|
||||||
|
# 插件版本
|
||||||
|
plugin_version = "1.0"
|
||||||
|
# 插件作者
|
||||||
|
plugin_author = "thsrite"
|
||||||
|
# 作者主页
|
||||||
|
author_url = "https://github.com/thsrite"
|
||||||
|
# 插件配置项ID前缀
|
||||||
|
plugin_config_prefix = "autologin_"
|
||||||
|
# 加载顺序
|
||||||
|
plugin_order = 2
|
||||||
|
# 可使用的用户级别
|
||||||
|
auth_level = 2
|
||||||
|
|
||||||
|
# 私有属性
|
||||||
|
siteoper: SiteOper = None
|
||||||
|
|
||||||
|
# 配置属性
|
||||||
|
_enabled: bool = False
|
||||||
|
_notify: bool = False
|
||||||
|
"""
|
||||||
|
格式
|
||||||
|
站点domain|用户名|用户密码
|
||||||
|
"""
|
||||||
|
_siteconf: list = []
|
||||||
|
|
||||||
|
def init_plugin(self, config: dict = None):
|
||||||
|
self.siteoper = SiteOper()
|
||||||
|
# 配置
|
||||||
|
if config:
|
||||||
|
self._enabled = config.get("enabled")
|
||||||
|
self._notify = config.get("notify")
|
||||||
|
self._siteconf = str(config.get("siteconf")).split('\n')
|
||||||
|
|
||||||
|
def get_state(self) -> bool:
|
||||||
|
return self._enabled
|
||||||
|
|
||||||
|
@eventmanager.register(EventType.SiteLogin)
|
||||||
|
def site_login(self, event):
|
||||||
|
"""
|
||||||
|
开始站点登录
|
||||||
|
"""
|
||||||
|
if not self.get_state():
|
||||||
|
return
|
||||||
|
|
||||||
|
# 站点id
|
||||||
|
site_id = event.event_data.get("site_id")
|
||||||
|
if not site_id:
|
||||||
|
logger.error(f"未获取到site_id")
|
||||||
|
return
|
||||||
|
|
||||||
|
site = self.siteoper.get(site_id)
|
||||||
|
if not site:
|
||||||
|
logger.error(f"未获取到site_id {site_id} 对应的站点数据")
|
||||||
|
return
|
||||||
|
|
||||||
|
site_name = site.name
|
||||||
|
logger.info(f"开始尝试登录站点 {site_name}")
|
||||||
|
siteurl, siteuser, sitepwd = None, None, None
|
||||||
|
# 判断site是否已配置用户名密码
|
||||||
|
for site_conf in self._siteconf:
|
||||||
|
if not site_conf:
|
||||||
|
continue
|
||||||
|
site_confs = str(site_conf).split("|")
|
||||||
|
if len(site_confs) == 3:
|
||||||
|
siteurl = site_confs[0]
|
||||||
|
siteuser = site_confs[1]
|
||||||
|
sitepwd = site_confs[2]
|
||||||
|
else:
|
||||||
|
logger.error(f"{site_conf}配置有误,已跳过")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 判断是否是目标域名
|
||||||
|
if str(siteurl) in StringUtils.get_url_domain(site.url):
|
||||||
|
# 找到目标域名配置,跳出循环
|
||||||
|
break
|
||||||
|
|
||||||
|
# 开始登录更新cookie和ua
|
||||||
|
if siteurl and siteuser and sitepwd:
|
||||||
|
state, messages = SiteChain().update_cookie(site_info=site,
|
||||||
|
username=siteuser,
|
||||||
|
password=sitepwd)
|
||||||
|
if state:
|
||||||
|
logger.info(f"站点{site_name}自动更新Cookie和Ua成功")
|
||||||
|
else:
|
||||||
|
logger.error(f"站点{site_name}自动更新Cookie和Ua失败")
|
||||||
|
|
||||||
|
if self._notify:
|
||||||
|
self.post_message(mtype=NotificationType.SiteMessage,
|
||||||
|
title=f"站点 {site_name} 自动更新Cookie和Ua{'成功' if state else '失败'}")
|
||||||
|
else:
|
||||||
|
logger.error(f"未获取到站点{site_name}配置,已跳过")
|
||||||
|
|
||||||
|
@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]]:
|
||||||
|
"""
|
||||||
|
拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'component': 'VForm',
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VRow',
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12,
|
||||||
|
'md': 6
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VSwitch',
|
||||||
|
'props': {
|
||||||
|
'model': 'enabled',
|
||||||
|
'label': '启用插件',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12,
|
||||||
|
'md': 6
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VSwitch',
|
||||||
|
'props': {
|
||||||
|
'model': 'notify',
|
||||||
|
'label': '开启通知',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'component': 'VRow',
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VTextarea',
|
||||||
|
'props': {
|
||||||
|
'model': 'siteconf',
|
||||||
|
'label': '站点配置',
|
||||||
|
'rows': 5,
|
||||||
|
'placeholder': '每一行一个站点,配置方式:\n'
|
||||||
|
'域名domain|用户名|用户密码\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'component': 'VRow',
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12,
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VAlert',
|
||||||
|
'props': {
|
||||||
|
'text': '站点签到提示Cookie过期时自动触发。'
|
||||||
|
'不支持开启两步认证的站点。'
|
||||||
|
'不是所有站点都支持,失败请手动更新。'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
], {
|
||||||
|
"enabled": False,
|
||||||
|
"notify": False,
|
||||||
|
"siteconf": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_page(self) -> List[dict]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stop_service(self):
|
||||||
|
"""
|
||||||
|
退出插件
|
||||||
|
"""
|
||||||
|
pass
|
@ -72,6 +72,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
_clean: bool = False
|
_clean: bool = False
|
||||||
_start_time: int = None
|
_start_time: int = None
|
||||||
_end_time: int = None
|
_end_time: int = None
|
||||||
|
_auto_cf: int = 0
|
||||||
|
|
||||||
def init_plugin(self, config: dict = None):
|
def init_plugin(self, config: dict = None):
|
||||||
self.sites = SitesHelper()
|
self.sites = SitesHelper()
|
||||||
@ -91,6 +92,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
self._sign_sites = config.get("sign_sites") or []
|
self._sign_sites = config.get("sign_sites") or []
|
||||||
self._login_sites = config.get("login_sites") or []
|
self._login_sites = config.get("login_sites") or []
|
||||||
self._retry_keyword = config.get("retry_keyword")
|
self._retry_keyword = config.get("retry_keyword")
|
||||||
|
self._auto_cf = config.get("auto_cf")
|
||||||
self._clean = config.get("clean")
|
self._clean = config.get("clean")
|
||||||
|
|
||||||
# 过滤掉已删除的站点
|
# 过滤掉已删除的站点
|
||||||
@ -206,6 +208,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
"sign_sites": self._sign_sites,
|
"sign_sites": self._sign_sites,
|
||||||
"login_sites": self._login_sites,
|
"login_sites": self._login_sites,
|
||||||
"retry_keyword": self._retry_keyword,
|
"retry_keyword": self._retry_keyword,
|
||||||
|
"auto_cf": self._auto_cf,
|
||||||
"clean": self._clean,
|
"clean": self._clean,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -333,7 +336,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 4
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
@ -350,7 +353,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 4
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
@ -366,7 +369,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
'component': 'VCol',
|
'component': 'VCol',
|
||||||
'props': {
|
'props': {
|
||||||
'cols': 12,
|
'cols': 12,
|
||||||
'md': 4
|
'md': 3
|
||||||
},
|
},
|
||||||
'content': [
|
'content': [
|
||||||
{
|
{
|
||||||
@ -378,6 +381,23 @@ class AutoSignIn(_PluginBase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12,
|
||||||
|
'md': 3
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VTextField',
|
||||||
|
'props': {
|
||||||
|
'model': 'auto_cf',
|
||||||
|
'label': '自动优选',
|
||||||
|
'placeholder': '0为不开启,命中重试关键词达到数量自动进行Cloudflare IP优选'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -443,6 +463,25 @@ class AutoSignIn(_PluginBase):
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'component': 'VRow',
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VCol',
|
||||||
|
'props': {
|
||||||
|
'cols': 12,
|
||||||
|
},
|
||||||
|
'content': [
|
||||||
|
{
|
||||||
|
'component': 'VAlert',
|
||||||
|
'props': {
|
||||||
|
'text': '自动Cloudflare IP优选,0=不开启,命中重试关键词数量大于该数量时自动执行Cloudflare IP优选。(需要开启且则正确配置Cloudflare IP优选插件和自定义Hosts插件)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -450,6 +489,7 @@ class AutoSignIn(_PluginBase):
|
|||||||
"enabled": False,
|
"enabled": False,
|
||||||
"notify": True,
|
"notify": True,
|
||||||
"cron": "",
|
"cron": "",
|
||||||
|
"auto_cf": 0,
|
||||||
"onlyonce": False,
|
"onlyonce": False,
|
||||||
"clean": False,
|
"clean": False,
|
||||||
"queue_cnt": 5,
|
"queue_cnt": 5,
|
||||||
@ -710,6 +750,15 @@ class AutoSignIn(_PluginBase):
|
|||||||
elif '已签到' in s:
|
elif '已签到' in s:
|
||||||
already_sign_msg.append(s)
|
already_sign_msg.append(s)
|
||||||
else:
|
else:
|
||||||
|
if 'Cookie已失效' in s and site_id:
|
||||||
|
# 触发自动登录插件登录
|
||||||
|
autologin = self.get_config("AutoLogin")
|
||||||
|
if autologin and autologin.get("enabled") and autologin.get("siteconf"):
|
||||||
|
logger.info(f"触发站点 {site_name} 自动登录更新Cookie和Ua")
|
||||||
|
self.eventmanager.send_event(EventType.SiteLogin,
|
||||||
|
{
|
||||||
|
"site_id": site_id
|
||||||
|
})
|
||||||
failed_msg.append(s)
|
failed_msg.append(s)
|
||||||
|
|
||||||
if not self._retry_keyword:
|
if not self._retry_keyword:
|
||||||
@ -724,6 +773,10 @@ class AutoSignIn(_PluginBase):
|
|||||||
"retry": retry_sites
|
"retry": retry_sites
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# 自动Cloudflare IP优选
|
||||||
|
if self._auto_cf and self._auto_cf > 0 and retry_msg and len(retry_msg) > self._auto_cf:
|
||||||
|
EventManager().send_event(EventType.CloudFlareSpeedTest, {})
|
||||||
|
|
||||||
# 发送通知
|
# 发送通知
|
||||||
if self._notify:
|
if self._notify:
|
||||||
# 签到详细信息 登录成功、签到成功、已签到、仿真签到成功、失败--命中重试
|
# 签到详细信息 登录成功、签到成功、已签到、仿真签到成功、失败--命中重试
|
||||||
|
@ -59,8 +59,8 @@ class Pt52(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
regexs=self._sign_regex)
|
regexs=self._sign_regex)
|
||||||
|
@ -51,8 +51,8 @@ class BTSchool(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
# 已签到
|
# 已签到
|
||||||
if self._sign_text not in html_text:
|
if self._sign_text not in html_text:
|
||||||
|
@ -60,8 +60,8 @@ class CHDBits(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
regexs=self._sign_regex)
|
regexs=self._sign_regex)
|
||||||
|
@ -49,8 +49,8 @@ class HaiDan(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
regexs=self._succeed_regex)
|
regexs=self._succeed_regex)
|
||||||
|
@ -53,8 +53,8 @@ class Hares(_ISiteSigninHandler):
|
|||||||
return False, '模拟访问失败,请检查站点连通性'
|
return False, '模拟访问失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 模拟访问失败,Cookie失效")
|
logger.error(f"{site} 模拟访问失败,Cookie已失效")
|
||||||
return False, '模拟访问失败,Cookie失效'
|
return False, '模拟访问失败,Cookie已失效'
|
||||||
|
|
||||||
# if self._sign_text in html_res.text:
|
# if self._sign_text in html_res.text:
|
||||||
# logger.info(f"今日已签到")
|
# logger.info(f"今日已签到")
|
||||||
|
@ -53,8 +53,8 @@ class HD4fans(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
# 判断是否已签到
|
# 判断是否已签到
|
||||||
if self._repeat_text in html_text:
|
if self._repeat_text in html_text:
|
||||||
|
@ -54,8 +54,8 @@ class HDArea(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_res.text:
|
if "login.php" in html_res.text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
# 判断是否已签到
|
# 判断是否已签到
|
||||||
# '已连续签到278天,此次签到您获得了100魔力值奖励!'
|
# '已连续签到278天,此次签到您获得了100魔力值奖励!'
|
||||||
|
@ -52,8 +52,8 @@ class HDChina(_ISiteSigninHandler):
|
|||||||
cookie += sub_str + ";"
|
cookie += sub_str + ";"
|
||||||
|
|
||||||
if "hdchina=" not in cookie:
|
if "hdchina=" not in cookie:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
site_cookie = cookie
|
site_cookie = cookie
|
||||||
# 获取页面html
|
# 获取页面html
|
||||||
|
@ -51,8 +51,8 @@ class HDCity(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login" in html_text:
|
if "login" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
# 判断是否已签到
|
# 判断是否已签到
|
||||||
# '已连续签到278天,此次签到您获得了100魔力值奖励!'
|
# '已连续签到278天,此次签到您获得了100魔力值奖励!'
|
||||||
|
@ -54,8 +54,8 @@ class HDSky(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
regexs=self._sign_regex)
|
regexs=self._sign_regex)
|
||||||
|
@ -53,8 +53,8 @@ class HDUpt(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
regexs=self._sign_regex)
|
regexs=self._sign_regex)
|
||||||
|
@ -55,8 +55,8 @@ class Opencd(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
if self._repeat_text in html_text:
|
if self._repeat_text in html_text:
|
||||||
logger.info(f"{site} 今日已签到")
|
logger.info(f"{site} 今日已签到")
|
||||||
|
@ -43,8 +43,12 @@ class PTerClub(_ISiteSigninHandler):
|
|||||||
proxy=proxy,
|
proxy=proxy,
|
||||||
render=render)
|
render=render)
|
||||||
if not html_text:
|
if not html_text:
|
||||||
logger.error(f"{site} 签到失败,签到接口请求失败")
|
logger.error(f"{site} 签到失败,请检查站点连通性")
|
||||||
return False, '签到失败,请检查cookie是否失效'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
|
if "login.php" in html_text:
|
||||||
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
|
return False, '签到失败,Cookie已失效'
|
||||||
try:
|
try:
|
||||||
sign_dict = json.loads(html_text)
|
sign_dict = json.loads(html_text)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -75,8 +75,8 @@ class Tjupt(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
regexs=self._sign_regex)
|
regexs=self._sign_regex)
|
||||||
|
@ -56,8 +56,8 @@ class TTG(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
# 判断是否已签到
|
# 判断是否已签到
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
|
@ -68,8 +68,8 @@ class U2(_ISiteSigninHandler):
|
|||||||
return False, '签到失败,请检查站点连通性'
|
return False, '签到失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 签到失败,Cookie失效")
|
logger.error(f"{site} 签到失败,Cookie已失效")
|
||||||
return False, '签到失败,Cookie失效'
|
return False, '签到失败,Cookie已失效'
|
||||||
|
|
||||||
# 判断是否已签到
|
# 判断是否已签到
|
||||||
sign_status = self.sign_in_result(html_res=html_text,
|
sign_status = self.sign_in_result(html_res=html_text,
|
||||||
|
@ -50,8 +50,8 @@ class ZhuQue(_ISiteSigninHandler):
|
|||||||
return False, '模拟登录失败,请检查站点连通性'
|
return False, '模拟登录失败,请检查站点连通性'
|
||||||
|
|
||||||
if "login.php" in html_text:
|
if "login.php" in html_text:
|
||||||
logger.error(f"{site} 模拟登录失败,Cookie失效")
|
logger.error(f"{site} 模拟登录失败,Cookie已失效")
|
||||||
return False, '模拟登录失败,Cookie失效'
|
return False, '模拟登录失败,Cookie已失效'
|
||||||
|
|
||||||
html = etree.HTML(html_text)
|
html = etree.HTML(html_text)
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ from python_hosts import Hosts, HostsEntry
|
|||||||
from requests import Response
|
from requests import Response
|
||||||
|
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
|
from app.core.event import eventmanager, Event
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.plugins import _PluginBase
|
from app.plugins import _PluginBase
|
||||||
from app.schemas.types import EventType, NotificationType
|
from app.schemas.types import EventType, NotificationType
|
||||||
@ -109,7 +110,8 @@ class CloudflareSpeedTest(_PluginBase):
|
|||||||
self._scheduler.print_jobs()
|
self._scheduler.print_jobs()
|
||||||
self._scheduler.start()
|
self._scheduler.start()
|
||||||
|
|
||||||
def __cloudflareSpeedTest(self):
|
@eventmanager.register(EventType.CloudFlareSpeedTest)
|
||||||
|
def __cloudflareSpeedTest(self, event: Event = None):
|
||||||
"""
|
"""
|
||||||
CloudflareSpeedTest优选
|
CloudflareSpeedTest优选
|
||||||
"""
|
"""
|
||||||
@ -129,6 +131,12 @@ class CloudflareSpeedTest(_PluginBase):
|
|||||||
logger.error("CloudflareSpeedTest加载成功,首次运行,需要配置优选ip")
|
logger.error("CloudflareSpeedTest加载成功,首次运行,需要配置优选ip")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if event and event.event_data:
|
||||||
|
logger.info("收到命令,开始Cloudflare IP优选 ...")
|
||||||
|
self.post_message(channel=event.event_data.get("channel"),
|
||||||
|
title="开始Cloudflare IP优选 ...",
|
||||||
|
userid=event.event_data.get("user"))
|
||||||
|
|
||||||
# ipv4和ipv6必须其一
|
# ipv4和ipv6必须其一
|
||||||
if not self._ipv4 and not self._ipv6:
|
if not self._ipv4 and not self._ipv6:
|
||||||
self._ipv4 = True
|
self._ipv4 = True
|
||||||
@ -154,7 +162,8 @@ class CloudflareSpeedTest(_PluginBase):
|
|||||||
# 执行优选命令,-dd不测速
|
# 执行优选命令,-dd不测速
|
||||||
if SystemUtils.is_windows():
|
if SystemUtils.is_windows():
|
||||||
cf_command = f'cd \"{self._cf_path}\" && CloudflareST {self._additional_args} -o \"{self._result_file}\"' + (
|
cf_command = f'cd \"{self._cf_path}\" && CloudflareST {self._additional_args} -o \"{self._result_file}\"' + (
|
||||||
f' -f \"{self._cf_ipv4}\"' if self._ipv4 else '') + (f' -f \"{self._cf_ipv6}\"' if self._ipv6 else '')
|
f' -f \"{self._cf_ipv4}\"' if self._ipv4 else '') + (
|
||||||
|
f' -f \"{self._cf_ipv6}\"' if self._ipv6 else '')
|
||||||
else:
|
else:
|
||||||
cf_command = f'cd {self._cf_path} && chmod a+x {self._binary_name} && ./{self._binary_name} {self._additional_args} -o {self._result_file}' + (
|
cf_command = f'cd {self._cf_path} && chmod a+x {self._binary_name} && ./{self._binary_name} {self._additional_args} -o {self._result_file}' + (
|
||||||
f' -f {self._cf_ipv4}' if self._ipv4 else '') + (f' -f {self._cf_ipv6}' if self._ipv6 else '')
|
f' -f {self._cf_ipv4}' if self._ipv4 else '') + (f' -f {self._cf_ipv6}' if self._ipv6 else '')
|
||||||
@ -313,7 +322,7 @@ class CloudflareSpeedTest(_PluginBase):
|
|||||||
# 重装后数据库有版本数据,但是本地没有则重装
|
# 重装后数据库有版本数据,但是本地没有则重装
|
||||||
if not install_flag and release_version == self._version and not Path(
|
if not install_flag and release_version == self._version and not Path(
|
||||||
f'{self._cf_path}/{self._binary_name}').exists() and not Path(
|
f'{self._cf_path}/{self._binary_name}').exists() and not Path(
|
||||||
f'{self._cf_path}/CloudflareST.exe').exists():
|
f'{self._cf_path}/CloudflareST.exe').exists():
|
||||||
logger.warn(f"未检测到CloudflareSpeedTest本地版本,重新安装")
|
logger.warn(f"未检测到CloudflareSpeedTest本地版本,重新安装")
|
||||||
install_flag = True
|
install_flag = True
|
||||||
|
|
||||||
@ -468,7 +477,16 @@ class CloudflareSpeedTest(_PluginBase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_command() -> List[Dict[str, Any]]:
|
def get_command() -> List[Dict[str, Any]]:
|
||||||
pass
|
"""
|
||||||
|
定义远程控制命令
|
||||||
|
:return: 命令关键字、事件、描述、附带数据
|
||||||
|
"""
|
||||||
|
return [{
|
||||||
|
"cmd": "/cloudflare_speedtest",
|
||||||
|
"event": EventType.CloudFlareSpeedTest,
|
||||||
|
"desc": "Cloudflare IP优选",
|
||||||
|
"data": {}
|
||||||
|
}]
|
||||||
|
|
||||||
def get_api(self) -> List[Dict[str, Any]]:
|
def get_api(self) -> List[Dict[str, Any]]:
|
||||||
pass
|
pass
|
||||||
|
@ -567,8 +567,8 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 开始删除
|
# 开始删除
|
||||||
image = 'https://emby.media/notificationicon.png'
|
image = 'https://emby.media/notificationicon.png'
|
||||||
year = None
|
year = None
|
||||||
del_cnt = 0
|
del_torrent_hashs = []
|
||||||
stop_cnt = 0
|
stop_torrent_hashs = []
|
||||||
error_cnt = 0
|
error_cnt = 0
|
||||||
for transferhis in transfer_history:
|
for transferhis in transfer_history:
|
||||||
title = transferhis.title
|
title = transferhis.title
|
||||||
@ -590,15 +590,16 @@ class MediaSyncDel(_PluginBase):
|
|||||||
if transferhis.download_hash:
|
if transferhis.download_hash:
|
||||||
try:
|
try:
|
||||||
# 2、判断种子是否被删除完
|
# 2、判断种子是否被删除完
|
||||||
delete_flag, success_flag, handle_cnt = self.handle_torrent(src=transferhis.src,
|
delete_flag, success_flag, handle_torrent_hashs = self.handle_torrent(
|
||||||
torrent_hash=transferhis.download_hash)
|
src=transferhis.src,
|
||||||
|
torrent_hash=transferhis.download_hash)
|
||||||
if not success_flag:
|
if not success_flag:
|
||||||
error_cnt += 1
|
error_cnt += 1
|
||||||
else:
|
else:
|
||||||
if delete_flag:
|
if delete_flag:
|
||||||
del_cnt += handle_cnt
|
del_torrent_hashs += handle_torrent_hashs
|
||||||
else:
|
else:
|
||||||
stop_cnt += handle_cnt
|
stop_torrent_hashs += handle_torrent_hashs
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("删除种子失败,尝试删除源文件:%s" % str(e))
|
logger.error("删除种子失败,尝试删除源文件:%s" % str(e))
|
||||||
|
|
||||||
@ -615,10 +616,16 @@ class MediaSyncDel(_PluginBase):
|
|||||||
image = self.get_tmdbimage_url(images[-1].get("file_path"), prefix="original")
|
image = self.get_tmdbimage_url(images[-1].get("file_path"), prefix="original")
|
||||||
|
|
||||||
torrent_cnt_msg = ""
|
torrent_cnt_msg = ""
|
||||||
if del_cnt:
|
if del_torrent_hashs:
|
||||||
torrent_cnt_msg += f"删除种子{del_cnt}个\n"
|
torrent_cnt_msg += f"删除种子{len(set(del_torrent_hashs))}个\n"
|
||||||
if stop_cnt:
|
if stop_torrent_hashs:
|
||||||
torrent_cnt_msg += f"暂停种子{stop_cnt}个\n"
|
stop_cnt = 0
|
||||||
|
# 排除已删除
|
||||||
|
for stop_hash in set(stop_torrent_hashs):
|
||||||
|
if stop_hash not in set(del_torrent_hashs):
|
||||||
|
stop_cnt += 1
|
||||||
|
if stop_cnt > 0:
|
||||||
|
torrent_cnt_msg += f"暂停种子{stop_cnt}个\n"
|
||||||
if error_cnt:
|
if error_cnt:
|
||||||
torrent_cnt_msg += f"删种失败{error_cnt}个\n"
|
torrent_cnt_msg += f"删种失败{error_cnt}个\n"
|
||||||
# 发送通知
|
# 发送通知
|
||||||
@ -818,8 +825,8 @@ class MediaSyncDel(_PluginBase):
|
|||||||
|
|
||||||
# 开始删除
|
# 开始删除
|
||||||
image = 'https://emby.media/notificationicon.png'
|
image = 'https://emby.media/notificationicon.png'
|
||||||
del_cnt = 0
|
del_torrent_hashs = []
|
||||||
stop_cnt = 0
|
stop_torrent_hashs = []
|
||||||
error_cnt = 0
|
error_cnt = 0
|
||||||
for transferhis in transfer_history:
|
for transferhis in transfer_history:
|
||||||
title = transferhis.title
|
title = transferhis.title
|
||||||
@ -839,15 +846,16 @@ class MediaSyncDel(_PluginBase):
|
|||||||
if transferhis.download_hash:
|
if transferhis.download_hash:
|
||||||
try:
|
try:
|
||||||
# 2、判断种子是否被删除完
|
# 2、判断种子是否被删除完
|
||||||
delete_flag, success_flag, handle_cnt = self.handle_torrent(src=transferhis.src,
|
delete_flag, success_flag, handle_torrent_hashs = self.handle_torrent(
|
||||||
torrent_hash=transferhis.download_hash)
|
src=transferhis.src,
|
||||||
|
torrent_hash=transferhis.download_hash)
|
||||||
if not success_flag:
|
if not success_flag:
|
||||||
error_cnt += 1
|
error_cnt += 1
|
||||||
else:
|
else:
|
||||||
if delete_flag:
|
if delete_flag:
|
||||||
del_cnt += handle_cnt
|
del_torrent_hashs += handle_torrent_hashs
|
||||||
else:
|
else:
|
||||||
stop_cnt += handle_cnt
|
stop_torrent_hashs += handle_torrent_hashs
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("删除种子失败,尝试删除源文件:%s" % str(e))
|
logger.error("删除种子失败,尝试删除源文件:%s" % str(e))
|
||||||
|
|
||||||
@ -856,12 +864,16 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 发送消息
|
# 发送消息
|
||||||
if self._notify:
|
if self._notify:
|
||||||
torrent_cnt_msg = ""
|
torrent_cnt_msg = ""
|
||||||
if del_cnt:
|
if del_torrent_hashs:
|
||||||
torrent_cnt_msg += f"删除种子{del_cnt}个\n"
|
torrent_cnt_msg += f"删除种子{len(set(del_torrent_hashs))}个\n"
|
||||||
if stop_cnt:
|
if stop_torrent_hashs:
|
||||||
torrent_cnt_msg += f"暂停种子{stop_cnt}个\n"
|
stop_cnt = 0
|
||||||
if error_cnt:
|
# 排除已删除
|
||||||
torrent_cnt_msg += f"删种失败{error_cnt}个\n"
|
for stop_hash in set(stop_torrent_hashs):
|
||||||
|
if stop_hash not in set(del_torrent_hashs):
|
||||||
|
stop_cnt += 1
|
||||||
|
if stop_cnt > 0:
|
||||||
|
torrent_cnt_msg += f"暂停种子{stop_cnt}个\n"
|
||||||
self.post_message(
|
self.post_message(
|
||||||
mtype=NotificationType.MediaServer,
|
mtype=NotificationType.MediaServer,
|
||||||
title="媒体库同步删除任务完成",
|
title="媒体库同步删除任务完成",
|
||||||
@ -901,7 +913,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
plugin_id=plugin_id)
|
plugin_id=plugin_id)
|
||||||
logger.info(f"查询到 {history_key} 转种历史 {transfer_history}")
|
logger.info(f"查询到 {history_key} 转种历史 {transfer_history}")
|
||||||
|
|
||||||
handle_cnt = 0
|
handle_torrent_hashs = []
|
||||||
try:
|
try:
|
||||||
# 删除本次种子记录
|
# 删除本次种子记录
|
||||||
self._downloadhis.delete_file_by_fullpath(fullpath=src)
|
self._downloadhis.delete_file_by_fullpath(fullpath=src)
|
||||||
@ -946,7 +958,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 删除源种子
|
# 删除源种子
|
||||||
logger.info(f"删除源下载器下载任务:{settings.DOWNLOADER} - {torrent_hash}")
|
logger.info(f"删除源下载器下载任务:{settings.DOWNLOADER} - {torrent_hash}")
|
||||||
self.chain.remove_torrents(torrent_hash)
|
self.chain.remove_torrents(torrent_hash)
|
||||||
handle_cnt += 1
|
handle_torrent_hashs.append(torrent_hash)
|
||||||
|
|
||||||
# 删除转种后任务
|
# 删除转种后任务
|
||||||
logger.info(f"删除转种后下载任务:{download} - {download_id}")
|
logger.info(f"删除转种后下载任务:{download} - {download_id}")
|
||||||
@ -957,7 +969,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
else:
|
else:
|
||||||
self.qb.delete_torrents(delete_file=True,
|
self.qb.delete_torrents(delete_file=True,
|
||||||
ids=download_id)
|
ids=download_id)
|
||||||
handle_cnt += 1
|
handle_torrent_hashs.append(download_id)
|
||||||
else:
|
else:
|
||||||
# 暂停种子
|
# 暂停种子
|
||||||
# 转种后未删除源种时,同步暂停源种
|
# 转种后未删除源种时,同步暂停源种
|
||||||
@ -967,7 +979,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 暂停源种子
|
# 暂停源种子
|
||||||
logger.info(f"暂停源下载器下载任务:{settings.DOWNLOADER} - {torrent_hash}")
|
logger.info(f"暂停源下载器下载任务:{settings.DOWNLOADER} - {torrent_hash}")
|
||||||
self.chain.stop_torrents(torrent_hash)
|
self.chain.stop_torrents(torrent_hash)
|
||||||
handle_cnt += 1
|
handle_torrent_hashs.append(torrent_hash)
|
||||||
|
|
||||||
logger.info(f"暂停转种后下载任务:{download} - {download_id}")
|
logger.info(f"暂停转种后下载任务:{download} - {download_id}")
|
||||||
# 删除转种后下载任务
|
# 删除转种后下载任务
|
||||||
@ -975,7 +987,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
self.tr.stop_torrents(ids=download_id)
|
self.tr.stop_torrents(ids=download_id)
|
||||||
else:
|
else:
|
||||||
self.qb.stop_torrents(ids=download_id)
|
self.qb.stop_torrents(ids=download_id)
|
||||||
handle_cnt += 1
|
handle_torrent_hashs.append(download_id)
|
||||||
else:
|
else:
|
||||||
# 未转种de情况
|
# 未转种de情况
|
||||||
if delete_flag:
|
if delete_flag:
|
||||||
@ -986,20 +998,20 @@ class MediaSyncDel(_PluginBase):
|
|||||||
# 暂停源种子
|
# 暂停源种子
|
||||||
logger.info(f"暂停源下载器下载任务:{download} - {download_id}")
|
logger.info(f"暂停源下载器下载任务:{download} - {download_id}")
|
||||||
self.chain.stop_torrents(download_id)
|
self.chain.stop_torrents(download_id)
|
||||||
handle_cnt += 1
|
handle_torrent_hashs.append(download_id)
|
||||||
|
|
||||||
# 处理辅种
|
# 处理辅种
|
||||||
handle_cnt = self.__del_seed(download=download,
|
handle_cnt = self.__del_seed(download=download,
|
||||||
download_id=download_id,
|
download_id=download_id,
|
||||||
action_flag="del" if delete_flag else 'stop',
|
action_flag="del" if delete_flag else 'stop',
|
||||||
handle_cnt=handle_cnt)
|
handle_torrent_hashs=handle_torrent_hashs)
|
||||||
|
|
||||||
return delete_flag, True, handle_cnt
|
return delete_flag, True, handle_cnt
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"删种失败: {str(e)}")
|
logger.error(f"删种失败: {str(e)}")
|
||||||
return False, False, 0
|
return False, False, 0
|
||||||
|
|
||||||
def __del_seed(self, download, download_id, action_flag, handle_cnt):
|
def __del_seed(self, download, download_id, action_flag, handle_torrent_hashs):
|
||||||
"""
|
"""
|
||||||
删除辅种
|
删除辅种
|
||||||
"""
|
"""
|
||||||
@ -1022,7 +1034,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
|
|
||||||
# 删除辅种历史
|
# 删除辅种历史
|
||||||
for torrent in torrents:
|
for torrent in torrents:
|
||||||
handle_cnt += 1
|
handle_torrent_hashs.append(torrent)
|
||||||
if str(download) == "qbittorrent":
|
if str(download) == "qbittorrent":
|
||||||
# 删除辅种
|
# 删除辅种
|
||||||
if action_flag == "del":
|
if action_flag == "del":
|
||||||
@ -1056,7 +1068,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
else:
|
else:
|
||||||
self.del_data(key=history_key,
|
self.del_data(key=history_key,
|
||||||
plugin_id=plugin_id)
|
plugin_id=plugin_id)
|
||||||
return handle_cnt
|
return handle_torrent_hashs
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_emby_log(last_time):
|
def parse_emby_log(last_time):
|
||||||
|
@ -46,7 +46,10 @@ class EventType(Enum):
|
|||||||
NameRecognizeResult = "name.recognize.result"
|
NameRecognizeResult = "name.recognize.result"
|
||||||
# 目录监控同步
|
# 目录监控同步
|
||||||
DirectorySync = "directory.sync"
|
DirectorySync = "directory.sync"
|
||||||
|
# Cloudflare IP优选
|
||||||
|
CloudFlareSpeedTest = "cloudflare.speedtest"
|
||||||
|
# 站点自动登录更新Cookie、Ua
|
||||||
|
SiteLogin = "site.login"
|
||||||
|
|
||||||
# 系统配置Key字典
|
# 系统配置Key字典
|
||||||
class SystemConfigKey(Enum):
|
class SystemConfigKey(Enum):
|
||||||
|
Reference in New Issue
Block a user