# Изменено расписание
# Добавлена логика создания
This commit is contained in:
73
scheduler.py
73
scheduler.py
@@ -6,49 +6,79 @@ from disnake.ext import tasks
|
|||||||
|
|
||||||
MOSCOW_TZ = pytz.timezone("Europe/Moscow")
|
MOSCOW_TZ = pytz.timezone("Europe/Moscow")
|
||||||
|
|
||||||
|
# 0 = Monday ... 6 = Sunday (datetime.weekday)
|
||||||
SCHEDULED_EVENTS = [
|
SCHEDULED_EVENTS = [
|
||||||
|
# 1) ECHO TTvT — создавать в пятницу 07:00, начало в пятницу 19:30
|
||||||
{
|
{
|
||||||
"name": "ECHO TTvT",
|
"name": "ECHO TTvT",
|
||||||
"day": 4,
|
"day": 4, # Friday
|
||||||
"create_hour": 8,
|
"create_hour": 7,
|
||||||
"create_minute": 0,
|
"create_minute": 0,
|
||||||
"event_hour": 19,
|
"event_hour": 19,
|
||||||
"event_minute": 30,
|
"event_minute": 30,
|
||||||
"key": "echottvt"
|
"key": "echottvt",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# 2) AS VDV PSG — создавать в пятницу 22:00, начало в субботу 16:30
|
||||||
|
# ВАЖНО: create_day = Friday (4), event_day = Saturday (5)
|
||||||
{
|
{
|
||||||
"name": "AS VDV PSG",
|
"name": "AS VDV PSG",
|
||||||
"day": 4,
|
"day": 4, # Friday for create
|
||||||
"create_hour": 22,
|
"create_hour": 22,
|
||||||
"create_minute": 0,
|
"create_minute": 0,
|
||||||
|
|
||||||
|
# событие в субботу 16:30
|
||||||
|
"event_day": 5, # Saturday
|
||||||
"event_hour": 16,
|
"event_hour": 16,
|
||||||
"event_minute": 30,
|
"event_minute": 30,
|
||||||
"key": "asvdvpsg"
|
|
||||||
|
"key": "asvdvpsg",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# 3) ECHO TvT — создавать в субботу 08:00, начало в субботу 19:30
|
||||||
{
|
{
|
||||||
"name": "ECHO TvT",
|
"name": "ECHO TvT",
|
||||||
"day": 5,
|
"day": 4, # Friday for create
|
||||||
"create_hour": 8,
|
"create_hour": 22,
|
||||||
"create_minute": 0,
|
"create_minute": 0,
|
||||||
|
|
||||||
|
# событие в субботу 19:30
|
||||||
|
"event_day": 5, # Saturday
|
||||||
"event_hour": 19,
|
"event_hour": 19,
|
||||||
"event_minute": 30,
|
"event_minute": 30,
|
||||||
"key": "echotvt_saturday"
|
"key": "echotvt_saturday",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_next_datetime(now, target_day, hour, minute):
|
|
||||||
|
def get_next_datetime(now: datetime.datetime, target_day: int, hour: int, minute: int) -> datetime.datetime:
|
||||||
|
"""
|
||||||
|
Возвращает ближайшую дату/время (timezone-aware, MSK) для target_day/hour/minute,
|
||||||
|
начиная от 'now'.
|
||||||
|
"""
|
||||||
days_ahead = (target_day - now.weekday()) % 7
|
days_ahead = (target_day - now.weekday()) % 7
|
||||||
next_date = now + datetime.timedelta(days=days_ahead)
|
target_date = (now + datetime.timedelta(days=days_ahead)).date()
|
||||||
return MOSCOW_TZ.localize(datetime.datetime.combine(next_date.date(), datetime.time(hour, minute)))
|
return datetime.datetime(
|
||||||
|
target_date.year,
|
||||||
|
target_date.month,
|
||||||
|
target_date.day,
|
||||||
|
hour,
|
||||||
|
minute,
|
||||||
|
tzinfo=MOSCOW_TZ
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Этот объект будет заполнен из main.py
|
# Этот объект будет заполнен из main.py
|
||||||
event_loop_context = {}
|
event_loop_context = {}
|
||||||
|
|
||||||
|
# Включается из main.py (командой или on_ready)
|
||||||
AUTO_EVENTS_ENABLED = False
|
AUTO_EVENTS_ENABLED = False
|
||||||
|
|
||||||
|
|
||||||
@tasks.loop(minutes=1)
|
@tasks.loop(minutes=1)
|
||||||
async def scheduled_event_loop():
|
async def scheduled_event_loop():
|
||||||
if not AUTO_EVENTS_ENABLED:
|
if not AUTO_EVENTS_ENABLED:
|
||||||
return # ⛔ автосоздание запрещено командой
|
return # ⛔ автосоздание запрещено командой/состоянием
|
||||||
|
|
||||||
now = datetime.datetime.now(MOSCOW_TZ)
|
now = datetime.datetime.now(MOSCOW_TZ)
|
||||||
|
|
||||||
@@ -57,11 +87,23 @@ async def scheduled_event_loop():
|
|||||||
generate_event_id = event_loop_context["generate_event_id"]
|
generate_event_id = event_loop_context["generate_event_id"]
|
||||||
|
|
||||||
for event in SCHEDULED_EVENTS:
|
for event in SCHEDULED_EVENTS:
|
||||||
create_time = get_next_datetime(now, event["day"], event["create_hour"], event["create_minute"])
|
# День и время создания
|
||||||
if abs((now - create_time).total_seconds()) < 60:
|
create_day = event["day"]
|
||||||
start_time = get_next_datetime(now, event["day"], event["event_hour"], event["event_minute"])
|
create_time = get_next_datetime(now, create_day, event["create_hour"], event["create_minute"])
|
||||||
|
|
||||||
|
# День и время старта (если не указан event_day — считаем что тот же день)
|
||||||
|
start_day = event.get("event_day", event["day"])
|
||||||
|
start_time = get_next_datetime(now, start_day, event["event_hour"], event["event_minute"])
|
||||||
|
|
||||||
|
# ✅ Догоняющее окно:
|
||||||
|
# если уже пора создать голосование (create_time наступило),
|
||||||
|
# но событие ещё не началось
|
||||||
|
if create_time <= now < start_time:
|
||||||
event_id = generate_event_id(event["name"], start_time)
|
event_id = generate_event_id(event["name"], start_time)
|
||||||
|
|
||||||
|
# 🔒 Защита от дублей: если есть в event_tasks — значит уже создано
|
||||||
if event_id in event_tasks:
|
if event_id in event_tasks:
|
||||||
|
# Можно оставить принт — удобно для диагностики
|
||||||
print(f"⏩ Уже существует: {event_id}")
|
print(f"⏩ Уже существует: {event_id}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -74,7 +116,6 @@ async def scheduled_event_loop():
|
|||||||
await create_poll(info, message_id=event["key"])
|
await create_poll(info, message_id=event["key"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def init_scheduler(create_poll_func, event_tasks_dict, generate_event_id_func):
|
def init_scheduler(create_poll_func, event_tasks_dict, generate_event_id_func):
|
||||||
event_loop_context["create_poll"] = create_poll_func
|
event_loop_context["create_poll"] = create_poll_func
|
||||||
event_loop_context["event_tasks"] = event_tasks_dict
|
event_loop_context["event_tasks"] = event_tasks_dict
|
||||||
|
|||||||
Reference in New Issue
Block a user