auto send to smoke
This commit is contained in:
parent
8bc905331c
commit
6afc30570f
2 changed files with 85 additions and 1 deletions
86
main.py
86
main.py
|
|
@ -83,6 +83,84 @@ def minutes_until_break(now: datetime | None = None) -> str:
|
|||
|
||||
return "Пары закончились, перекур только завтра."
|
||||
|
||||
|
||||
def next_break_window(now: datetime | None = None) -> tuple[datetime | None, datetime | None]:
|
||||
"""Возвращает (начало, конец) ближайшего перекура или (None, None)."""
|
||||
if now is None:
|
||||
now = datetime.now(ZoneInfo(config.DEFAULT_TZ))
|
||||
elif now.tzinfo is None:
|
||||
now = now.replace(tzinfo=ZoneInfo(config.DEFAULT_TZ))
|
||||
|
||||
day = now.weekday()
|
||||
today_schedule = config.SCHEDULE.get(day, [])
|
||||
if not today_schedule:
|
||||
return None, None
|
||||
|
||||
def dt_for(t: time) -> datetime:
|
||||
return now.replace(hour=t.hour, minute=t.minute, second=0, microsecond=0)
|
||||
|
||||
for start_t, end_t, br_minutes in today_schedule:
|
||||
if not br_minutes:
|
||||
continue
|
||||
end_dt = dt_for(end_t)
|
||||
br_start = end_dt
|
||||
br_end = end_dt + timedelta(minutes=br_minutes)
|
||||
# Ближайший будущий или текущий перекур
|
||||
if now < br_end:
|
||||
return br_start, br_end
|
||||
|
||||
return None, None
|
||||
|
||||
|
||||
# --- Авто-напоминание о перекуре ---
|
||||
_break_tasks: dict[int, tuple[datetime, asyncio.Task]] = {}
|
||||
_break_notified: dict[int, datetime] = {}
|
||||
|
||||
|
||||
async def _send_break_photo(chat_id: int, bot: Bot, start_dt: datetime) -> None:
|
||||
last = _break_notified.get(chat_id)
|
||||
if last and last == start_dt:
|
||||
return # Уже кидали уведомление для этого слота
|
||||
|
||||
photo_path = config.BASE_DIR / "vape.jpg"
|
||||
if not photo_path.exists():
|
||||
logger.warning("vape.jpg not found, skip break photo")
|
||||
return
|
||||
|
||||
try:
|
||||
await bot.send_photo(chat_id=chat_id, photo=FSInputFile(photo_path), caption="идем курить")
|
||||
_break_notified[chat_id] = start_dt
|
||||
except Exception:
|
||||
logger.exception("Failed to send break photo")
|
||||
|
||||
|
||||
async def _break_notification(chat_id: int, bot: Bot, start_dt: datetime) -> None:
|
||||
try:
|
||||
now = datetime.now(start_dt.tzinfo)
|
||||
delay = (start_dt - now).total_seconds()
|
||||
if delay > 0:
|
||||
await asyncio.sleep(delay)
|
||||
await _send_break_photo(chat_id, bot, start_dt)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
finally:
|
||||
stored = _break_tasks.get(chat_id)
|
||||
if stored and stored[0] == start_dt:
|
||||
_break_tasks.pop(chat_id, None)
|
||||
|
||||
|
||||
def schedule_break_notification(chat_id: int, bot: Bot, start_dt: datetime) -> None:
|
||||
existing = _break_tasks.get(chat_id)
|
||||
if existing:
|
||||
scheduled_start, task = existing
|
||||
if scheduled_start == start_dt and not task.done():
|
||||
return # Уже ждём этот же слот
|
||||
if not task.done():
|
||||
task.cancel()
|
||||
|
||||
task = asyncio.create_task(_break_notification(chat_id, bot, start_dt))
|
||||
_break_tasks[chat_id] = (start_dt, task)
|
||||
|
||||
# --- Работа с изображениями (Макеты и Мемы) ---
|
||||
|
||||
def load_font(size: int) -> ImageFont.FreeTypeFont:
|
||||
|
|
@ -414,7 +492,13 @@ async def handle_start(message: Message):
|
|||
await message.answer("Соси")
|
||||
|
||||
async def handle_break_cmd(message: Message):
|
||||
await message.answer(minutes_until_break())
|
||||
now = datetime.now(ZoneInfo(config.DEFAULT_TZ))
|
||||
await message.answer(minutes_until_break(now))
|
||||
|
||||
# Ставим будильник на ближайший перекур для этого чата
|
||||
start_dt, _ = next_break_window(now)
|
||||
if start_dt:
|
||||
schedule_break_notification(message.chat.id, message.bot, start_dt)
|
||||
|
||||
async def handle_penis_cmd(message: Message):
|
||||
if not message.from_user:
|
||||
|
|
|
|||
BIN
vape.jpg
Normal file
BIN
vape.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in a new issue