同步本地更改
This commit is contained in:
@@ -91,8 +91,18 @@ def compute_next_run_at(
|
||||
|
||||
if random_delay:
|
||||
window_start = candidate_base - timedelta(minutes=15)
|
||||
random_minutes = random.randint(0, 30)
|
||||
candidate = window_start + timedelta(minutes=random_minutes)
|
||||
window_end = candidate_base + timedelta(minutes=15)
|
||||
|
||||
# 只从“未来窗口”中抽样,避免抽到过去时间导致整天被跳过
|
||||
delta_seconds = (now - window_start).total_seconds()
|
||||
if delta_seconds < 0:
|
||||
min_offset = 0
|
||||
else:
|
||||
min_offset = int(delta_seconds // 60) + 1
|
||||
max_offset = int((window_end - window_start).total_seconds() // 60)
|
||||
if min_offset > max_offset:
|
||||
continue
|
||||
candidate = window_start + timedelta(minutes=random.randint(min_offset, max_offset))
|
||||
else:
|
||||
candidate = candidate_base
|
||||
|
||||
@@ -110,4 +120,3 @@ def format_cst(dt: datetime) -> str:
|
||||
dt = BEIJING_TZ.localize(dt)
|
||||
dt = dt.astimezone(BEIJING_TZ)
|
||||
return dt.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
@@ -30,6 +30,30 @@ config = get_config()
|
||||
SCREENSHOTS_DIR = config.SCREENSHOTS_DIR
|
||||
os.makedirs(SCREENSHOTS_DIR, exist_ok=True)
|
||||
|
||||
_HHMM_RE = None
|
||||
|
||||
|
||||
def _normalize_hhmm(value: object, *, default: str) -> str:
|
||||
"""Normalize scheduler time to HH:MM; fallback to default when invalid."""
|
||||
global _HHMM_RE
|
||||
if _HHMM_RE is None:
|
||||
import re
|
||||
|
||||
_HHMM_RE = re.compile(r"^(\d{1,2}):(\d{2})$")
|
||||
|
||||
text = str(value or "").strip()
|
||||
match = _HHMM_RE.match(text)
|
||||
if not match:
|
||||
return default
|
||||
try:
|
||||
hour = int(match.group(1))
|
||||
minute = int(match.group(2))
|
||||
except Exception:
|
||||
return default
|
||||
if hour < 0 or hour > 23 or minute < 0 or minute > 59:
|
||||
return default
|
||||
return f"{hour:02d}:{minute:02d}"
|
||||
|
||||
|
||||
def run_scheduled_task(skip_weekday_check: bool = False) -> None:
|
||||
"""执行所有账号的浏览任务(可被手动调用,过滤重复账号)"""
|
||||
@@ -333,7 +357,10 @@ def scheduled_task_worker() -> None:
|
||||
def check_and_schedule(force: bool = False):
|
||||
config_data = database.get_system_config()
|
||||
schedule_enabled = bool(config_data.get("schedule_enabled"))
|
||||
schedule_time_cst = config_data.get("schedule_time", "02:00")
|
||||
schedule_time_raw = config_data.get("schedule_time", "02:00")
|
||||
schedule_time_cst = _normalize_hhmm(schedule_time_raw, default="02:00")
|
||||
if schedule_time_cst != str(schedule_time_raw or "").strip():
|
||||
logger.warning(f"[定时任务] 系统定时时间格式无效,已回退到 {schedule_time_cst} (原值: {schedule_time_raw!r})")
|
||||
|
||||
signature = (schedule_enabled, schedule_time_cst)
|
||||
config_changed = schedule_state.get("signature") != signature
|
||||
@@ -364,18 +391,28 @@ def scheduled_task_worker() -> None:
|
||||
elif config_changed and not is_first_run:
|
||||
logger.info("[定时任务] 浏览任务已禁用")
|
||||
|
||||
check_and_schedule(force=True)
|
||||
try:
|
||||
check_and_schedule(force=True)
|
||||
except Exception as e:
|
||||
logger.exception(f"[定时任务] 初始化系统定时任务失败: {e}")
|
||||
last_config_check = time.time()
|
||||
last_user_schedule_minute = None
|
||||
|
||||
while True:
|
||||
try:
|
||||
schedule.run_pending()
|
||||
try:
|
||||
schedule.run_pending()
|
||||
except Exception as e:
|
||||
logger.exception(f"[定时任务] 系统调度执行出错: {e}")
|
||||
|
||||
now_ts = time.time()
|
||||
if now_ts - last_config_check >= config_check_interval:
|
||||
check_and_schedule()
|
||||
last_config_check = now_ts
|
||||
try:
|
||||
check_and_schedule()
|
||||
except Exception as e:
|
||||
logger.exception(f"[定时任务] 系统调度配置刷新失败: {e}")
|
||||
finally:
|
||||
last_config_check = now_ts
|
||||
|
||||
now_beijing = get_beijing_now()
|
||||
minute_key = now_beijing.strftime("%Y-%m-%d %H:%M")
|
||||
@@ -385,5 +422,5 @@ def scheduled_task_worker() -> None:
|
||||
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
logger.exception(f"[定时任务] 调度器出错: {str(e)}")
|
||||
logger.exception(f"[定时任务] 调度器主循环出错: {e}")
|
||||
time.sleep(5)
|
||||
|
||||
Reference in New Issue
Block a user