修改通知时间为晚上10点,添加cookie保存功能,按用户和域名区分保存
This commit is contained in:
+15
-150
@@ -1,6 +1,5 @@
|
||||
"""消息通知模块 - 通过爱语飞飞发送通知"""
|
||||
import requests
|
||||
from typing import Optional
|
||||
from applogger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
@@ -10,26 +9,17 @@ class IYUUNotifier:
|
||||
"""爱语飞飞通知客户端"""
|
||||
|
||||
def __init__(self, token: str):
|
||||
"""
|
||||
初始化爱语飞飞通知客户端
|
||||
|
||||
Args:
|
||||
token: 爱语飞飞令牌
|
||||
"""
|
||||
self.token = token
|
||||
self.api_url = f"https://iyuu.cn/{token}.send"
|
||||
|
||||
def send(self, title: str, content: str) -> bool:
|
||||
"""
|
||||
发送通知
|
||||
|
||||
Args:
|
||||
title: 通知标题
|
||||
content: 通知内容
|
||||
|
||||
Returns:
|
||||
是否发送成功
|
||||
"""
|
||||
print(f"\n{'='*50}")
|
||||
print(f"[测试] 准备发送通知")
|
||||
print(f"[测试] API URL: {self.api_url}")
|
||||
print(f"[测试] Title: {title}")
|
||||
print(f"[测试] Content: {content[:100]}...")
|
||||
print(f"{'='*50}\n")
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
self.api_url,
|
||||
@@ -39,12 +29,20 @@ class IYUUNotifier:
|
||||
},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
print(f"[测试] 响应状态码: {response.status_code}")
|
||||
print(f"[测试] 响应内容: {response.text}")
|
||||
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
print(f"[测试] 解析结果: {result}")
|
||||
|
||||
if result.get('errcode') == 0:
|
||||
print(f"[测试] ✓ 发送成功!")
|
||||
return True
|
||||
else:
|
||||
print(f"[测试] ✗ 发送失败: {result.get('errmsg')}")
|
||||
logger.error(f"发送通知失败: {result.get('errmsg')}")
|
||||
return False
|
||||
|
||||
@@ -54,136 +52,3 @@ class IYUUNotifier:
|
||||
except Exception as e:
|
||||
logger.error(f"发送通知异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
class FailureTracker:
|
||||
"""失败次数追踪器"""
|
||||
|
||||
def __init__(self, state_file: str):
|
||||
"""
|
||||
初始化失败次数追踪器
|
||||
|
||||
Args:
|
||||
state_file: 状态文件路径
|
||||
"""
|
||||
self.state_file = state_file
|
||||
self.state = self._load_state()
|
||||
|
||||
def _load_state(self) -> dict:
|
||||
"""加载状态文件"""
|
||||
import json
|
||||
import os
|
||||
|
||||
if os.path.exists(self.state_file):
|
||||
try:
|
||||
with open(self.state_file, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
logger.error(f"加载状态文件失败: {e}")
|
||||
|
||||
return {}
|
||||
|
||||
def _save_state(self):
|
||||
"""保存状态文件"""
|
||||
import json
|
||||
|
||||
try:
|
||||
with open(self.state_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(self.state, f, indent=2, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"保存状态文件失败: {e}")
|
||||
|
||||
def get_fail_count(self, user_name: str, website_name: str) -> int:
|
||||
"""
|
||||
获取指定网站的失败次数
|
||||
|
||||
Args:
|
||||
user_name: 用户名
|
||||
website_name: 网站名
|
||||
|
||||
Returns:
|
||||
失败次数
|
||||
"""
|
||||
key = f"{user_name}_{website_name}"
|
||||
return self.state.get(key, 0)
|
||||
|
||||
def increment_fail_count(self, user_name: str, website_name: str) -> int:
|
||||
"""
|
||||
增加失败次数
|
||||
|
||||
Args:
|
||||
user_name: 用户名
|
||||
website_name: 网站名
|
||||
|
||||
Returns:
|
||||
增加后的失败次数
|
||||
"""
|
||||
key = f"{user_name}_{website_name}"
|
||||
self.state[key] = self.state.get(key, 0) + 1
|
||||
self._save_state()
|
||||
return self.state[key]
|
||||
|
||||
def reset_fail_count(self, user_name: str, website_name: str):
|
||||
"""
|
||||
重置失败次数
|
||||
|
||||
Args:
|
||||
user_name: 用户名
|
||||
website_name: 网站名
|
||||
"""
|
||||
key = f"{user_name}_{website_name}"
|
||||
self.state[key] = 0
|
||||
self._save_state()
|
||||
|
||||
def check_and_notify(
|
||||
self,
|
||||
user_name: str,
|
||||
website_name: str,
|
||||
max_fail_count: int,
|
||||
notifier: Optional[IYUUNotifier],
|
||||
error_msg: str
|
||||
) -> bool:
|
||||
"""
|
||||
检查失败次数并在达到阈值时发送通知
|
||||
|
||||
Args:
|
||||
user_name: 用户名
|
||||
website_name: 网站名
|
||||
max_fail_count: 最大失败次数
|
||||
notifier: 爱语飞飞通知客户端
|
||||
error_msg: 错误信息
|
||||
|
||||
Returns:
|
||||
是否应该停止重试
|
||||
"""
|
||||
fail_count = self.increment_fail_count(user_name, website_name)
|
||||
|
||||
if fail_count >= max_fail_count:
|
||||
# 发送通知
|
||||
if notifier:
|
||||
title = f"【Cookie监控】{user_name} - {website_name} 登录失败"
|
||||
content = f"网站: {website_name}\n用户: {user_name}\n连续失败次数: {fail_count}\n错误信息: {error_msg}"
|
||||
|
||||
if notifier.send(title, content):
|
||||
logger.info(f"已发送失败通知: {user_name} - {website_name}")
|
||||
else:
|
||||
logger.error(f"发送失败通知失败: {user_name} - {website_name}")
|
||||
|
||||
# 重置失败计数
|
||||
self.reset_fail_count(user_name, website_name)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试代码
|
||||
tracker = FailureTracker("state.json")
|
||||
|
||||
# 增加失败次数
|
||||
count = tracker.increment_fail_count("测试用户", "测试网站")
|
||||
logger.info(f"当前失败次数: {count}")
|
||||
|
||||
# 检查并发送通知(需要真实的爱语飞飞令牌)
|
||||
# notifier = IYUUNotifier("您的爱语飞飞令牌")
|
||||
# tracker.check_and_notify("测试用户", "测试网站", 3, notifier, "测试错误信息")
|
||||
Reference in New Issue
Block a user