Init project

This commit is contained in:
2026-01-15 09:47:43 +03:00
commit 3e515c66ec
59 changed files with 5101 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
from .auth import AuthMiddleware
from .depends import DependsMiddleware
from .typing import TypingMiddleware
__all__ = (
# auth
"AuthMiddleware",
# depends
"DependsMiddleware",
# typing
"TypingMiddleware",
)

View File

@@ -0,0 +1,47 @@
from typing import Any, Awaitable, Callable
import aiogram
from aiogram.types import TelegramObject, User as TelegramUser
from birthday_pool_bot.dto import User
from birthday_pool_bot.repositories.repositories import UsersRepository
from birthday_pool_bot.telegram_bot.ui.utils import get_telegram_user_full_name
class AuthMiddleware(aiogram.BaseMiddleware):
def __init__(self, users_repository: UsersRepository):
self._users_repository = users_repository
async def __call__(
self,
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
event: TelegramObject,
data: dict[str, Any],
):
telegram_user = self.get_telegram_user(event=event)
if telegram_user is None:
return await handler(event, data)
async with self._users_repository.transaction():
user = await self._users_repository.get_user_by_telegram_id(
telegram_id=telegram_user.id,
)
if user is None:
user = User(
name=get_telegram_user_full_name(user=telegram_user),
telegram_id=telegram_user.id,
)
user = await self._users_repository.create_user(user=user)
data["user"] = user
return await handler(event, data)
def get_telegram_user(self, event: TelegramObject) -> TelegramUser | None:
if hasattr(event, "from_user") and isinstance(event.from_user, TelegramUser):
return event.from_user
if hasattr(event, "user") and isinstance(event.user, TelegramUser):
return event.user
if hasattr(event, "new_chat_member") and event.new_chat_member:
return event.new_chat_member.user

View File

@@ -0,0 +1,19 @@
from typing import Any, Awaitable, Callable
import aiogram
from aiogram.types import TelegramObject
class DependsMiddleware(aiogram.BaseMiddleware):
def __init__(self, name: str, object_: Any):
self._name = name
self._object = object_
async def __call__(
self,
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
event: TelegramObject,
data: dict[str, Any],
):
data[self._name] = self._object
return await handler(event, data)

View File

@@ -0,0 +1,36 @@
import asyncio
import contextlib
from typing import Any, Awaitable, Callable
import aiogram
from aiogram import types
class TypingMiddleware(aiogram.BaseMiddleware):
async def __call__(
self,
handler: Callable[[types.TelegramObject, dict[str, Any]], Awaitable[Any]],
event: types.TelegramObject,
data: dict[str, Any],
):
if not isinstance(event, types.Message):
return await handler(event, data)
bot = data.get("bot")
chat_id = event.chat.id
async with send_typing_action(bot=bot, chat_id=chat_id):
return await handler(event, data)
@contextlib.asynccontextmanager
async def send_typing_action(bot: aiogram.Bot, chat_id: int):
async def background_task():
while True:
await bot.send_chat_action(chat_id=chat_id, action="typing")
await asyncio.sleep(3)
task = asyncio.create_task(background_task())
try:
yield
finally:
task.cancel()