diff --git a/games/uwu.py b/games/uwu.py index 634e4f1..3a51d52 100644 --- a/games/uwu.py +++ b/games/uwu.py @@ -31,7 +31,7 @@ async def handle_uwu_cmd(message: types.Message): if len(args) > 1: tags = args[1].strip() - tags += " order:random" + tags += " order:random score:>300" url = "https://e621.net/posts.json" params = { diff --git a/main.py b/main.py index 7c8c1a0..82fc5d0 100644 --- a/main.py +++ b/main.py @@ -958,6 +958,17 @@ async def handle_start(message: Message): else: await message.answer("Соси") +async def handle_app_cmd(message: Message): + """Открыть Mini App — работает и в группах.""" + webapp_url = os.getenv("WEBAPP_URL", "") + if not webapp_url: + await message.answer("Mini App не настроен.") + return + kb = InlineKeyboardMarkup(inline_keyboard=[ + [InlineKeyboardButton(text="🎮 Открыть Mini App", web_app=WebAppInfo(url=webapp_url))] + ]) + await message.answer("⬇️ Жми кнопку чтобы открыть приложение", reply_markup=kb) + async def handle_schedule_cmd(message: Message): now = datetime.now(ZoneInfo(config.DEFAULT_TZ)) raw_text = message.text or "" @@ -1402,6 +1413,7 @@ def main(): # Регистрация хендлеров dp.message.register(handle_start, CommandStart()) + dp.message.register(handle_app_cmd, Command("app")) dp.message.register(handle_help, Command("help")) dp.message.register(handle_schedule_cmd, Command("schedule")) dp.message.register(handle_break_cmd, Command("break")) diff --git a/webapp/api.py b/webapp/api.py index 7ef872c..d8009d4 100644 --- a/webapp/api.py +++ b/webapp/api.py @@ -14,6 +14,7 @@ from typing import Annotated from fastapi import FastAPI, Depends, Header, HTTPException from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles from pydantic import BaseModel # Добавляем корень проекта в sys.path чтобы импортировать модули бота @@ -189,29 +190,22 @@ async def get_matches(league: str) -> list[MatchResponse]: result = [] for i, m in enumerate(matches): - # Извлекаем коэффициенты - odds_home = odds_draw = odds_away = None - bookmakers = m.get("bookmakers", []) - if bookmakers: - markets = bookmakers[0].get("markets", []) - for market in markets: - if market.get("key") == "h2h": - outcomes = market.get("outcomes", []) - for o in outcomes: - name = o.get("name", "") - price = o.get("price", 0) - if name == m.get("home_team"): - odds_home = price - elif name == m.get("away_team"): - odds_away = price - elif name == "Draw": - odds_draw = price + home = m.get("home", "?") + away = m.get("away", "?") + odds = m.get("odds", {}) + + odds_home = odds.get(home) + odds_away = odds.get(away) + + _DRAW_NAMES = {"draw", "tie", "ничья"} + draw_name = next((name for name in odds if name.casefold() in _DRAW_NAMES), None) + odds_draw = odds.get(draw_name) if draw_name else None result.append(MatchResponse( index=i + 1, - home=m.get("home_team", "?"), - away=m.get("away_team", "?"), - commence=m.get("commence_time", ""), + home=home, + away=away, + commence=m.get("commence", ""), odds_home=odds_home, odds_draw=odds_draw, odds_away=odds_away, @@ -386,6 +380,13 @@ async def talk_api( raise HTTPException(status_code=500, detail="LLM error") +# ──────────────────── Static files (для локального теста) ──────────────────── + +_frontend_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "frontend") +if os.path.isdir(_frontend_dir): + app.mount("/", StaticFiles(directory=_frontend_dir, html=True), name="frontend") + + # ──────────────────── Entry point ──────────────────── if __name__ == "__main__": diff --git a/webapp/ngrok_tunnel.py b/webapp/ngrok_tunnel.py new file mode 100644 index 0000000..96f33f9 --- /dev/null +++ b/webapp/ngrok_tunnel.py @@ -0,0 +1,18 @@ +"""Скрипт для локального тестирования Mini App с ngrok""" +import time +from pyngrok import conf, ngrok + +conf.get_default().auth_token = "39k4ojhN5UPUWQwb1ly84ORM2IE_5JnhMaKk5p8LFM3TCetyg" +tunnel = ngrok.connect(8080, "http") +print(f"\n{'='*50}") +print(f" NGROK URL: {tunnel.public_url}") +print(f"{'='*50}\n") +print("Туннель открыт. Не закрывай это окно!") +print("Ctrl+C чтобы остановить.\n") + +try: + while True: + time.sleep(1) +except KeyboardInterrupt: + ngrok.kill() + print("Туннель закрыт.")