添加定时任务随机时间执行功能;修复手动执行任务不发送邮件通知

This commit is contained in:
Yu Yon
2025-12-12 10:12:27 +08:00
parent 8c8c708ce7
commit 1072e90070
3 changed files with 69 additions and 19 deletions

65
app.py
View File

@@ -132,6 +132,10 @@ log_cache_total_count = 0 # 全局日志总数,防止无限增长
batch_task_screenshots = {} # {batch_id: {'user_id': x, 'browse_type': y, 'screenshots': [{'account_name': a, 'path': p, 'items': n, 'attachments': m}], 'total_accounts': n, 'completed': n}}
batch_task_lock = threading.Lock()
# 随机延迟任务存储
pending_random_schedules = {}
pending_random_lock = threading.Lock()
# 日志缓存限制
MAX_LOGS_PER_USER = config.MAX_LOGS_PER_USER # 每个用户最多100条
MAX_TOTAL_LOGS = config.MAX_TOTAL_LOGS # 全局最多1000条,防止内存泄漏
@@ -2181,12 +2185,14 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
source=source
)
# 发送任务完成邮件通知(不截图时在此发送)
try:
user_info = database.get_user_by_id(user_id)
# 检查用户是否开启了邮件通知
if user_info and user_info.get('email') and database.get_user_email_notify(user_id):
account_name = account.remark if account.remark else account.username
email_service.send_task_complete_email_async(
# 只对定时任务发送邮件通知,手动执行不发送
if source and source.startswith('user_scheduled'):
try:
user_info = database.get_user_by_id(user_id)
# 检查用户是否开启了邮件通知
if user_info and user_info.get('email') and database.get_user_email_notify(user_id):
account_name = account.remark if account.remark else account.username
email_service.send_task_complete_email_async(
user_id=user_id,
email=user_info['email'],
username=user_info['username'],
@@ -2197,8 +2203,8 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
screenshot_path=None,
log_callback=lambda msg: log_to_client(msg, user_id, account_id)
)
except Exception as email_error:
logger.warning(f"发送任务完成邮件失败: {email_error}")
except Exception as email_error:
logger.warning(f"发送任务完成邮件失败: {email_error}")
# 成功则跳出重试循环
break
else:
@@ -2599,8 +2605,8 @@ def take_screenshot_for_account(user_id, account_id, browse_type="应读", sourc
print(f"[批次邮件] 已发送打包邮件,包含 {len(batch_info['screenshots'])} 个截图")
except Exception as batch_email_err:
print(f"[批次邮件] 发送失败: {batch_email_err}")
else:
# 非批次任务:直接发送邮件(保持原有逻辑
elif source and source.startswith('user_scheduled'):
# 非批次的定时任务:直接发送邮件(手动执行不发送邮件通知
user_info = database.get_user_by_id(user_id)
if user_info and user_info.get('email') and database.get_user_email_notify(user_id):
email_service.send_task_complete_email_async(
@@ -3683,8 +3689,43 @@ def scheduled_task_worker():
h, m = schedule_time.split(':')
schedule_time = f"{int(h):02d}:{int(m):02d}"
# 检查时间是否匹配
if schedule_time != current_time:
# 获取随机延迟设置
random_delay = schedule_config.get('random_delay', 0)
# 处理随机延迟逻辑
should_execute = False
if random_delay == 1:
import random as rand_module
with pending_random_lock:
if schedule_id in pending_random_schedules:
# 检查是否到达随机执行时间
pending_info = pending_random_schedules[schedule_id]
scheduled_for = pending_info['scheduled_for']
if now >= scheduled_for:
del pending_random_schedules[schedule_id]
should_execute = True
print(f"[定时任务] 任务#{schedule_id} 随机延迟到达,开始执行")
else:
# 计算窗口时间
set_hour, set_minute = map(int, schedule_time.split(':'))
set_time_today = now.replace(hour=set_hour, minute=set_minute, second=0, microsecond=0)
window_start = set_time_today - timedelta(minutes=15)
# 当前时间刚好到达窗口开始
if now.strftime('%H:%M') == window_start.strftime('%H:%M'):
random_minutes = rand_module.randint(0, 30)
random_time = window_start + timedelta(minutes=random_minutes)
pending_random_schedules[schedule_id] = {
'scheduled_for': random_time,
'config': schedule_config
}
print(f"[定时任务] 任务#{schedule_id} 安排随机时间: {random_time.strftime('%H:%M')}")
else:
# 精确时间匹配
if schedule_time == current_time:
should_execute = True
if not should_execute:
continue
# 检查星期是否匹配