refactor: project architecture refactor, container splitting
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import logging
|
||||
from typing import Any, Awaitable, Callable, Dict, Optional, Union
|
||||
|
||||
from aiogram import BaseMiddleware, Bot
|
||||
from aiogram.exceptions import (
|
||||
AiogramError,
|
||||
TelegramAPIError,
|
||||
TelegramForbiddenError,
|
||||
)
|
||||
from aiogram.types import CallbackQuery, InlineKeyboardMarkup, Message, Update, User
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from config.settings import Settings
|
||||
from db.dal import user_dal
|
||||
|
||||
from ..keyboards.inline.user_keyboards import get_user_banned_keyboard
|
||||
from .i18n import JsonI18n
|
||||
|
||||
|
||||
class BanCheckMiddleware(BaseMiddleware):
|
||||
def __init__(self, settings: Settings, i18n_instance: JsonI18n):
|
||||
super().__init__()
|
||||
self.settings = settings
|
||||
self.i18n_main_instance = i18n_instance
|
||||
|
||||
async def __call__(
|
||||
self,
|
||||
handler: Callable[[Update, Dict[str, Any]], Awaitable[Any]],
|
||||
event: Update,
|
||||
data: Dict[str, Any],
|
||||
) -> Any:
|
||||
session: AsyncSession = data["session"]
|
||||
event_user: Optional[User] = data.get("event_from_user")
|
||||
bot_instance: Bot = data["bot"]
|
||||
|
||||
if not event_user:
|
||||
return await handler(event, data)
|
||||
|
||||
if event_user.id in self.settings.ADMIN_IDS:
|
||||
return await handler(event, data)
|
||||
|
||||
try:
|
||||
db_user_model = await user_dal.get_user_by_id(session, event_user.id)
|
||||
except Exception as e_db:
|
||||
logging.error(
|
||||
f"BanCheckMiddleware: DB error fetching user {event_user.id}: {e_db}", exc_info=True
|
||||
)
|
||||
return await handler(event, data)
|
||||
|
||||
if db_user_model and db_user_model.is_banned:
|
||||
logging.info(
|
||||
f"User {event_user.id} ({event_user.username or 'NoUsername'}) is banned. Blocking access." # noqa: E501
|
||||
)
|
||||
|
||||
i18n_data_from_event = data.get("i18n_data", {})
|
||||
current_lang = i18n_data_from_event.get(
|
||||
"current_language", self.settings.DEFAULT_LANGUAGE
|
||||
)
|
||||
i18n_to_use: Optional[JsonI18n] = i18n_data_from_event.get(
|
||||
"i18n_instance", self.i18n_main_instance
|
||||
)
|
||||
|
||||
ban_message_text = "You are banned. Please contact support."
|
||||
keyboard: Optional[InlineKeyboardMarkup] = None
|
||||
|
||||
if i18n_to_use:
|
||||
_ = lambda k, **kw: i18n_to_use.gettext(current_lang, k, **kw)
|
||||
ban_message_text = _("user_is_banned")
|
||||
keyboard = get_user_banned_keyboard(
|
||||
self.settings.SUPPORT_LINK, current_lang, i18n_to_use
|
||||
)
|
||||
elif self.settings.SUPPORT_LINK:
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.button(text="Support", url=self.settings.SUPPORT_LINK)
|
||||
keyboard = builder.as_markup()
|
||||
|
||||
actual_event_object: Optional[Union[Message, CallbackQuery]] = None
|
||||
if event.message:
|
||||
actual_event_object = event.message
|
||||
elif event.callback_query:
|
||||
actual_event_object = event.callback_query
|
||||
|
||||
try:
|
||||
if isinstance(actual_event_object, Message):
|
||||
await actual_event_object.answer(ban_message_text, reply_markup=keyboard)
|
||||
elif isinstance(actual_event_object, CallbackQuery):
|
||||
await actual_event_object.answer(ban_message_text, show_alert=True)
|
||||
if actual_event_object.message:
|
||||
try:
|
||||
await actual_event_object.message.edit_text(
|
||||
ban_message_text, reply_markup=keyboard
|
||||
)
|
||||
except (TelegramAPIError, AiogramError):
|
||||
await bot_instance.send_message(
|
||||
actual_event_object.from_user.id,
|
||||
ban_message_text,
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
else:
|
||||
await bot_instance.send_message(
|
||||
actual_event_object.from_user.id,
|
||||
ban_message_text,
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
else:
|
||||
await bot_instance.send_message(
|
||||
event_user.id, ban_message_text, reply_markup=keyboard
|
||||
)
|
||||
logging.info(f"Ban notification sent to user {event_user.id}.")
|
||||
except TelegramForbiddenError:
|
||||
logging.warning(f"BanCheck: Bot is blocked by user {event_user.id}.")
|
||||
except Exception as e_send:
|
||||
logging.error(
|
||||
f"BanCheck: Failed to notify banned user {event_user.id}: {type(e_send).__name__} - {e_send}", # noqa: E501
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
return
|
||||
return await handler(event, data)
|
||||
Reference in New Issue
Block a user