diff --git a/bot/__pycache__/main.cpython-312.pyc b/bot/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000..0007366 Binary files /dev/null and b/bot/__pycache__/main.cpython-312.pyc differ diff --git a/bot/core/__pycache__/bot.cpython-312.pyc b/bot/core/__pycache__/bot.cpython-312.pyc new file mode 100644 index 0000000..78dceb1 Binary files /dev/null and b/bot/core/__pycache__/bot.cpython-312.pyc differ diff --git a/bot/core/__pycache__/middlewares.cpython-312.pyc b/bot/core/__pycache__/middlewares.cpython-312.pyc new file mode 100644 index 0000000..280ce1f Binary files /dev/null and b/bot/core/__pycache__/middlewares.cpython-312.pyc differ diff --git a/bot/core/__pycache__/scheduler.cpython-312.pyc b/bot/core/__pycache__/scheduler.cpython-312.pyc new file mode 100644 index 0000000..4c21641 Binary files /dev/null and b/bot/core/__pycache__/scheduler.cpython-312.pyc differ diff --git a/bot/core/scheduler.py b/bot/core/scheduler.py index 4a298ef..583221b 100644 --- a/bot/core/scheduler.py +++ b/bot/core/scheduler.py @@ -49,12 +49,19 @@ async def check_and_send_reminders(bot: Bot) -> None: Args: bot: Bot instance """ + from bot.db.base import async_session_maker + from bot.db.operations import update_reminder + + if not async_session_maker: + logger.error("Session maker not initialized") + return + try: time_service = get_time_service() current_time = time_service.get_now() - # Get due reminders from database - async for session in get_session(): + # Get due reminders from database using proper async session + async with async_session_maker() as session: due_reminders = await get_due_reminders(session, current_time) if not due_reminders: @@ -74,16 +81,15 @@ async def check_and_send_reminders(bot: Bot) -> None: # Update next_run_at to prevent sending again # (it will be properly updated when user clicks "Done" or by periodic update) - from bot.db.operations import update_reminder - from datetime import timedelta - - # Temporarily set next_run_at to current + interval to avoid duplicate sends temp_next_run = time_service.calculate_next_occurrence( current_run=reminder.next_run_at, days_interval=reminder.days_interval, ) await update_reminder(session, reminder.id, next_run_at=temp_next_run) + # Commit all updates + await session.commit() + # Small delay to avoid rate limits await asyncio.sleep(0.5) diff --git a/bot/db/operations.py b/bot/db/operations.py index 3dca3c5..486a871 100644 --- a/bot/db/operations.py +++ b/bot/db/operations.py @@ -176,8 +176,11 @@ async def get_due_reminders(session: AsyncSession, current_time: datetime) -> Li Returns: List of due Reminder instances """ + from sqlalchemy.orm import selectinload + result = await session.execute( select(Reminder) + .options(selectinload(Reminder.user)) # Eager load user relationship .where(Reminder.is_active == True) .where(Reminder.next_run_at <= current_time) .order_by(Reminder.next_run_at) diff --git a/bot/handlers/__pycache__/__init__.cpython-312.pyc b/bot/handlers/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..df769ee Binary files /dev/null and b/bot/handlers/__pycache__/__init__.cpython-312.pyc differ diff --git a/bot/handlers/__pycache__/callbacks.cpython-312.pyc b/bot/handlers/__pycache__/callbacks.cpython-312.pyc new file mode 100644 index 0000000..ce2b300 Binary files /dev/null and b/bot/handlers/__pycache__/callbacks.cpython-312.pyc differ diff --git a/bot/handlers/__pycache__/common.cpython-312.pyc b/bot/handlers/__pycache__/common.cpython-312.pyc new file mode 100644 index 0000000..9c916a0 Binary files /dev/null and b/bot/handlers/__pycache__/common.cpython-312.pyc differ diff --git a/bot/handlers/__pycache__/errors.cpython-312.pyc b/bot/handlers/__pycache__/errors.cpython-312.pyc new file mode 100644 index 0000000..558a073 Binary files /dev/null and b/bot/handlers/__pycache__/errors.cpython-312.pyc differ diff --git a/bot/handlers/__pycache__/reminders_create.cpython-312.pyc b/bot/handlers/__pycache__/reminders_create.cpython-312.pyc new file mode 100644 index 0000000..267a881 Binary files /dev/null and b/bot/handlers/__pycache__/reminders_create.cpython-312.pyc differ diff --git a/bot/handlers/__pycache__/reminders_manage.cpython-312.pyc b/bot/handlers/__pycache__/reminders_manage.cpython-312.pyc new file mode 100644 index 0000000..fc73270 Binary files /dev/null and b/bot/handlers/__pycache__/reminders_manage.cpython-312.pyc differ diff --git a/bot/main.py b/bot/main.py index 5e52129..a37e23f 100644 --- a/bot/main.py +++ b/bot/main.py @@ -38,14 +38,23 @@ async def on_shutdown() -> None: logger.info("Shutting down reminder bot...") # Stop scheduler - stop_scheduler() + try: + stop_scheduler() + except Exception as e: + logger.error(f"Error stopping scheduler: {e}") # Close database - await close_db() + try: + await close_db() + except Exception as e: + logger.error(f"Error closing database: {e}") # Close bot session - if bot: - await bot.session.close() + if bot and hasattr(bot, 'session'): + try: + await bot.session.close() + except Exception as e: + logger.error(f"Error closing bot session: {e}") logger.info("Bot shutdown completed") diff --git a/bot/utils/validators.py b/bot/utils/validators.py index 281c145..0482f29 100644 --- a/bot/utils/validators.py +++ b/bot/utils/validators.py @@ -45,11 +45,11 @@ def validate_days_interval(days_str: str) -> Optional[int]: days_str: Days interval string to validate Returns: - Integer days if valid (>0), None otherwise + Integer days if valid (>0 and <=365), None otherwise """ try: days = int(days_str.strip()) - if days > 0: + if 0 < days <= 365: # Max 1 year return days except (ValueError, AttributeError): pass