Spaces:
Running on Zero
Running on Zero
Download app/main.py from cipher-attacks/Dbu-central-bot: direct link, hf CLI and curl.
- Browser
- Download file 2.68 kB
-
https://huggingface.co/spaces/cipher-attacks/Dbu-central-bot/resolve/main/app/main.py
- Command line
-
hf download hf://spaces/cipher-attacks/Dbu-central-bot/app/main.py
-
curl -L -o main.py https://huggingface.co/spaces/cipher-attacks/Dbu-central-bot/resolve/main/app/main.py
2.68 kB
| import asyncio | |
| import logging | |
| from aiogram import Bot | |
| from aiogram.client.default import DefaultBotProperties | |
| from aiogram.enums import ParseMode | |
| from app.bot.loader import build_dispatcher | |
| from app.config import get_settings | |
| from app.core.logging import setup_logging | |
| from app.db.session import init_db, keepalive, warm_up | |
| from app.tasks.jobs import close_previous_week, notify_pending_submissions, periodic, qualify_referrals | |
| log = logging.getLogger(__name__) | |
| async def set_command_menus(bot: Bot) -> None: | |
| """Telegram's "/" suggestions: short for students, complete for admins.""" | |
| from aiogram.types import ( | |
| BotCommand, BotCommandScopeAllGroupChats, BotCommandScopeAllPrivateChats, BotCommandScopeChat, | |
| ) | |
| from app.bot import manual | |
| def commands(names: set[str]) -> list[BotCommand]: | |
| return [BotCommand(command=n, description=d) for n, d in manual.menu_commands(names)] | |
| try: | |
| await bot.set_my_commands(commands({"start", "help", "rules"}), scope=BotCommandScopeAllPrivateChats()) | |
| await bot.set_my_commands(commands({"find"}), scope=BotCommandScopeAllGroupChats()) | |
| everything = commands(manual.all_command_names() - {"admin"}) | |
| for admin_id in get_settings().admin_id_set: | |
| await bot.set_my_commands(everything, scope=BotCommandScopeChat(chat_id=admin_id)) | |
| except Exception: | |
| log.exception("Could not set the command menus (not fatal)") | |
| async def run_bot_forever() -> None: | |
| setup_logging() | |
| await init_db() | |
| await warm_up() | |
| bot = Bot( | |
| token=get_settings().bot_token, | |
| default=DefaultBotProperties(parse_mode=ParseMode.HTML), | |
| ) | |
| await set_command_menus(bot) | |
| await bot.me() # cache bot info (used by the invite link) before the first user arrives | |
| background = [ # keep references so the tasks aren't garbage-collected | |
| asyncio.create_task(keepalive()), | |
| asyncio.create_task(periodic("referrals", 1800, qualify_referrals, bot)), | |
| asyncio.create_task(periodic("season", 600, close_previous_week, bot)), | |
| asyncio.create_task(periodic("submissions", 120, notify_pending_submissions, bot, first_delay=90)), | |
| ] | |
| try: | |
| while True: | |
| try: | |
| # handle_signals=False because we run in a non-main thread | |
| await build_dispatcher().start_polling(bot, handle_signals=False) | |
| break | |
| except Exception: | |
| log.exception("Polling crashed; restarting in 5s") | |
| await asyncio.sleep(5) | |
| finally: | |
| for task in background: | |
| task.cancel() | |
| if __name__ == "__main__": | |
| asyncio.run(run_bot_forever()) | |