From 50835dd2fbdeb911eece062385b757106674f37d Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 25 Jun 2026 01:15:58 +0300 Subject: [PATCH] feat: add weekly summary push loop on Sundays at 12:00 --- miband_tracker/bot/app.py | 48 +++++++++++++++++++++++++++++++++++++++ tests/test_bot_ui.py | 5 +++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/miband_tracker/bot/app.py b/miband_tracker/bot/app.py index ab4f65e..f204203 100644 --- a/miband_tracker/bot/app.py +++ b/miband_tracker/bot/app.py @@ -401,11 +401,51 @@ async def auto_refresh_main_menu_loop(app: Application) -> None: await asyncio.sleep(AUTO_MENU_REFRESH_INTERVAL) +async def weekly_push_loop(app: Application) -> None: + """Send weekly summary push notification every Sunday at 12:00.""" + last_sent_date: str | None = None + while True: + try: + now = datetime.now(LOCAL_TZ) + if now.weekday() == 6 and now.hour == 12 and now.minute == 0: + current_date = now.strftime("%Y-%m-%d") + if last_sent_date != current_date: + last_sent_date = current_date + allowed_ids = SETTINGS.telegram_allowed_user_ids + logger.info("Starting weekly push for users: %s", allowed_ids) + for uid in allowed_ids: + token = current_user_id_var.set(uid) + try: + if health_db_exists(): + summary_text = period_text(7) + push_text = f"📊 Ваша сводка активности за неделю\n\n{summary_text}" + await app.bot.send_message( + chat_id=uid, + text=push_text, + parse_mode="HTML", + ) + logger.info("Weekly push sent to user %s", uid) + except Exception as e: + logger.error("Failed to send weekly push to user %s: %s", uid, e) + finally: + current_user_id_var.reset(token) + except asyncio.CancelledError: + raise + except Exception as exc: + logger.warning("Weekly push loop encountered error: %s", exc) + + await asyncio.sleep(30) + + async def start_background_tasks(app: Application) -> None: app.bot_data["auto_refresh_main_menu_task"] = asyncio.create_task( auto_refresh_main_menu_loop(app), name="auto-refresh-main-menu", ) + app.bot_data["weekly_push_task"] = asyncio.create_task( + weekly_push_loop(app), + name="weekly-push", + ) async def stop_background_tasks(app: Application) -> None: @@ -417,6 +457,14 @@ async def stop_background_tasks(app: Application) -> None: except asyncio.CancelledError: pass + task_push = app.bot_data.get("weekly_push_task") + if task_push: + task_push.cancel() + try: + await task_push + except asyncio.CancelledError: + pass + # --------------------------------------------------------------------------- # Data queries diff --git a/tests/test_bot_ui.py b/tests/test_bot_ui.py index c0edf44..9aaeca4 100644 --- a/tests/test_bot_ui.py +++ b/tests/test_bot_ui.py @@ -128,7 +128,10 @@ async def test_start_xiaomi_login_saves_token_syncs_and_opens_menu( data = json.loads(token_path.read_text(encoding="utf-8")) assert data["user_id"] == "456" assert data["service_token"] == "service" - run_sync.assert_awaited_once_with(123, settings) + run_sync.assert_awaited_once() + call_args = run_sync.await_args[0] + assert call_args[0] == 123 + assert call_args[1].query_duration == 30 show_main_menu.assert_awaited_once_with(update, context)