member_context: split daily weekly monthly digest scheduling

This commit is contained in:
liuwei
2026-04-14 10:53:46 +08:00
parent 1800ae585a
commit 28e038a25c
7 changed files with 1339 additions and 240 deletions

View File

@@ -71,6 +71,70 @@ class AsyncJob:
return decorator
def every_week_time(self, weekday: int, time_str: str):
"""
每周 weekday0=周一6=周日) 的 time_str 时间执行
"""
def decorator(func: Callable):
async def wrapper():
while True:
now = datetime.now()
target_time = datetime.strptime(time_str, "%H:%M").time()
days_ahead = (weekday - now.weekday() + 7) % 7
target_date = now.date() + timedelta(days=days_ahead)
target_dt = datetime.combine(target_date, target_time)
if target_dt <= now:
target_dt += timedelta(days=7)
sleep_secs = (target_dt - now).total_seconds()
await asyncio.sleep(sleep_secs)
await func()
self.tasks.append(wrapper)
return func
return decorator
def every_month_last_day_time(self, time_str: str):
"""
每月最后一天的 time_str 时间执行
"""
def decorator(func: Callable):
async def wrapper():
while True:
now = datetime.now()
target_time = datetime.strptime(time_str, "%H:%M").time()
if now.month == 12:
next_month = datetime(now.year + 1, 1, 1)
else:
next_month = datetime(now.year, now.month + 1, 1)
last_day = next_month - timedelta(days=1)
target_dt = datetime.combine(last_day.date(), target_time)
if target_dt <= now:
if now.month == 12:
next_month = datetime(now.year + 1, 2, 1)
elif now.month == 11:
next_month = datetime(now.year + 1, 1, 1)
else:
next_month = datetime(now.year, now.month + 2, 1)
last_day = next_month - timedelta(days=1)
target_dt = datetime.combine(last_day.date(), target_time)
sleep_secs = (target_dt - now).total_seconds()
await asyncio.sleep(sleep_secs)
await func()
self.tasks.append(wrapper)
return func
return decorator
async def run_all(self):
await asyncio.gather(*(task() for task in self.tasks))