Migrating to Postgres from sqlite3
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import logging
|
||||
import json
|
||||
from typing import Callable, Dict, Any, Awaitable, Union, Optional
|
||||
from typing import Callable, Dict, Any, Awaitable, Optional
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.types import Update, Message, CallbackQuery, User
|
||||
from aiogram.types import Update, User, Message, CallbackQuery
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from db.database import log_user_action
|
||||
from db.dal import message_log_dal, user_dal
|
||||
from config.settings import Settings
|
||||
|
||||
|
||||
@@ -19,72 +20,82 @@ class ActionLoggerMiddleware(BaseMiddleware):
|
||||
Awaitable[Any]], event: Update,
|
||||
data: Dict[str, Any]) -> Any:
|
||||
|
||||
result = await handler(event, data)
|
||||
|
||||
session: AsyncSession = data["session"]
|
||||
event_user: Optional[User] = data.get("event_from_user")
|
||||
bot: Optional[Bot] = data.get("bot")
|
||||
|
||||
user_id: Optional[int] = None
|
||||
telegram_username: Optional[str] = None
|
||||
telegram_first_name: Optional[str] = None
|
||||
event_type: str = event.event_type
|
||||
content: Optional[str] = None
|
||||
is_admin_event_flag: bool = False
|
||||
target_user_id_for_log: Optional[int] = None
|
||||
|
||||
if event_user:
|
||||
user_id = event_user.id
|
||||
telegram_username = event_user.username
|
||||
telegram_first_name = event_user.first_name
|
||||
if user_id == self.settings.ADMIN_IDS:
|
||||
if user_id in self.settings.ADMIN_IDS:
|
||||
is_admin_event_flag = True
|
||||
|
||||
raw_update_snippet = None
|
||||
try:
|
||||
|
||||
raw_update_snippet = event.model_dump_json(exclude_none=True,
|
||||
indent=None)[:1000]
|
||||
except AttributeError:
|
||||
raw_update_snippet = str(event)[:1000]
|
||||
except Exception:
|
||||
raw_update_snippet = str(event)[:1000]
|
||||
|
||||
current_event_type = event.event_type
|
||||
|
||||
if event.message:
|
||||
msg = event.message
|
||||
msg: Message = event.message
|
||||
if msg.text:
|
||||
content = msg.text
|
||||
if msg.text.startswith('/'):
|
||||
event_type = "command"
|
||||
elif msg.caption:
|
||||
content = f"[{msg.content_type}] {msg.caption}"
|
||||
current_event_type = f"command:{msg.text.split()[0]}"
|
||||
|
||||
else:
|
||||
content = f"[{msg.content_type}]"
|
||||
|
||||
content = f"[{msg.content_type or 'unknown_content_type'}]"
|
||||
current_event_type = f"message:{msg.content_type or 'unknown'}"
|
||||
elif event.callback_query:
|
||||
cb = event.callback_query
|
||||
event_type = "callback_query"
|
||||
cb: CallbackQuery = event.callback_query
|
||||
content = cb.data
|
||||
action_part = cb.data.split(
|
||||
":")[0] if cb.data and ":" in cb.data else cb.data
|
||||
current_event_type = f"callback:{action_part}"
|
||||
|
||||
if user_id and event_type and content:
|
||||
if user_id or current_event_type not in ["update"]:
|
||||
|
||||
log_user_id_for_db = user_id
|
||||
if user_id:
|
||||
user_exists = await user_dal.get_user_by_id(session, user_id)
|
||||
if not user_exists:
|
||||
logging.warning(
|
||||
f"ActionLoggerMiddleware: User {user_id} not found in DB. Logging action with user_id=NULL."
|
||||
)
|
||||
log_user_id_for_db = None
|
||||
|
||||
log_payload = {
|
||||
"user_id": log_user_id_for_db,
|
||||
"telegram_username": telegram_username,
|
||||
"telegram_first_name": telegram_first_name,
|
||||
"event_type": current_event_type,
|
||||
"content": content[:1000] if content else "N/A",
|
||||
"raw_update_preview": raw_update_snippet,
|
||||
"is_admin_event": is_admin_event_flag,
|
||||
"target_user_id": target_user_id_for_log,
|
||||
"timestamp": datetime.now(timezone.utc)
|
||||
}
|
||||
try:
|
||||
await log_user_action(user_id=user_id,
|
||||
telegram_username=telegram_username,
|
||||
telegram_first_name=telegram_first_name,
|
||||
event_type=event_type,
|
||||
content=content[:1000],
|
||||
raw_update_preview=raw_update_snippet,
|
||||
is_admin_event=is_admin_event_flag)
|
||||
|
||||
await message_log_dal.create_message_log_no_commit(
|
||||
session, log_payload)
|
||||
except Exception as e_log:
|
||||
logging.error(
|
||||
f"ActionLoggerMiddleware: Failed to log event for user {user_id}: {e_log}",
|
||||
exc_info=True)
|
||||
elif user_id and event_type:
|
||||
try:
|
||||
await log_user_action(user_id=user_id,
|
||||
telegram_username=telegram_username,
|
||||
telegram_first_name=telegram_first_name,
|
||||
event_type=event_type,
|
||||
content="N/A",
|
||||
raw_update_preview=raw_update_snippet,
|
||||
is_admin_event=is_admin_event_flag)
|
||||
except Exception as e_log:
|
||||
logging.error(
|
||||
f"ActionLoggerMiddleware: Failed to log event (no content) for user {user_id}: {e_log}",
|
||||
f"ActionLoggerMiddleware: Failed to add log to session for user {user_id}, type {current_event_type}: {e_log}",
|
||||
exc_info=True)
|
||||
|
||||
return await handler(event, data)
|
||||
return result
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import logging
|
||||
from typing import Callable, Dict, Any, Awaitable, Union, Optional
|
||||
from typing import Callable, Dict, Any, Awaitable, Optional, Union
|
||||
|
||||
from aiogram import BaseMiddleware, Bot
|
||||
from aiogram.types import Message, CallbackQuery, User, InlineKeyboardMarkup, Update
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
from aiogram.types import Message, CallbackQuery, User, Update, InlineKeyboardMarkup
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from aiogram.exceptions import TelegramAPIError, TelegramForbiddenError, TelegramBadRequest, AiogramError
|
||||
|
||||
from config.settings import Settings
|
||||
from db.database import get_user
|
||||
from bot.middlewares.i18n import JsonI18n
|
||||
from bot.keyboards.inline.user_keyboards import get_user_banned_keyboard
|
||||
from db.dal import user_dal
|
||||
|
||||
from .i18n import JsonI18n
|
||||
from ..keyboards.inline.user_keyboards import get_user_banned_keyboard
|
||||
|
||||
|
||||
class BanCheckMiddleware(BaseMiddleware):
|
||||
@@ -22,191 +23,88 @@ class BanCheckMiddleware(BaseMiddleware):
|
||||
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")
|
||||
if not event_user: return await handler(event, data)
|
||||
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_data = await get_user(user_id=event_user.id)
|
||||
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_data and db_user_data['is_banned'] == 1:
|
||||
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 and preparing notification."
|
||||
f"User {event_user.id} ({event_user.username or 'NoUsername'}) is banned. Blocking access."
|
||||
)
|
||||
|
||||
ban_message_text = "You are blocked. Please contact support."
|
||||
keyboard: Optional[InlineKeyboardMarkup] = None
|
||||
current_lang = self.settings.DEFAULT_LANGUAGE
|
||||
i18n_to_use: Optional[JsonI18n] = None
|
||||
actual_event_object: Optional[Union[Message, CallbackQuery]] = None
|
||||
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)
|
||||
|
||||
if event.message:
|
||||
actual_event_object = event.message
|
||||
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
|
||||
|
||||
if not actual_event_object:
|
||||
logging.warning(
|
||||
f"BanCheck: Could not determine specific event type (Message/CallbackQuery) for banned user {event_user.id} from Update object. Update type: {event.type}"
|
||||
)
|
||||
|
||||
try:
|
||||
bot_instance: Bot = data["bot"]
|
||||
await bot_instance.send_message(event_user.id,
|
||||
ban_message_text)
|
||||
except Exception as e_direct_send:
|
||||
logging.error(
|
||||
f"BanCheck: Failed to send direct ban message to {event_user.id}: {e_direct_send}"
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
logging.debug(
|
||||
"BanCheck: [A] Inside main try block for banned user notification."
|
||||
)
|
||||
i18n_data_from_event = data.get("i18n_data", {})
|
||||
current_lang = i18n_data_from_event.get(
|
||||
"current_language", self.settings.DEFAULT_LANGUAGE)
|
||||
i18n_to_use = i18n_data_from_event.get("i18n_instance")
|
||||
logging.debug(
|
||||
f"BanCheck: [B] i18n_instance from event_data: {type(i18n_to_use)}. Current lang: {current_lang}"
|
||||
)
|
||||
|
||||
if not i18n_to_use:
|
||||
i18n_to_use = self.i18n_main_instance
|
||||
logging.warning(
|
||||
f"BanCheck: [B_fallback] Using fallback i18n instance for banned user {event_user.id}. Type: {type(i18n_to_use)}"
|
||||
)
|
||||
|
||||
if i18n_to_use:
|
||||
_ = lambda k, **kw: i18n_to_use.gettext(
|
||||
current_lang, k, **kw)
|
||||
logging.debug(
|
||||
"BanCheck: [D] Attempting to get 'user_is_banned' text."
|
||||
)
|
||||
ban_message_text = _("user_is_banned")
|
||||
logging.debug(
|
||||
f"BanCheck: [E] Ban message text: '{ban_message_text}'"
|
||||
)
|
||||
if self.settings.SUPPORT_LINK:
|
||||
logging.debug(
|
||||
"BanCheck: [F] Support link found. Attempting to get user_banned_keyboard."
|
||||
)
|
||||
keyboard = get_user_banned_keyboard(
|
||||
self.settings.SUPPORT_LINK, current_lang,
|
||||
i18n_to_use)
|
||||
logging.debug(
|
||||
f"BanCheck: [G] Keyboard created: {keyboard is not None}"
|
||||
)
|
||||
else:
|
||||
logging.debug(
|
||||
"BanCheck: [F_alt] No support link configured.")
|
||||
else:
|
||||
logging.error(
|
||||
f"BanCheck: [CRITICAL] No i18n instance for user {event_user.id}. Using hardcoded text."
|
||||
)
|
||||
if self.settings.SUPPORT_LINK:
|
||||
kb_temp = InlineKeyboardBuilder()
|
||||
kb_temp.button(text="Support",
|
||||
url=self.settings.SUPPORT_LINK)
|
||||
keyboard = kb_temp.as_markup()
|
||||
logging.debug(
|
||||
"BanCheck: [G_alt] Fallback keyboard created due to no i18n."
|
||||
)
|
||||
|
||||
logging.debug(
|
||||
f"BanCheck: [H] Final pre-send check. Message: '{ban_message_text}', Keyboard: {keyboard is not None}"
|
||||
)
|
||||
|
||||
if isinstance(actual_event_object, Message):
|
||||
logging.debug(
|
||||
f"BanCheck: [I_Msg] Attempting actual_event_object.answer for Message to user {event_user.id}"
|
||||
)
|
||||
await actual_event_object.answer(ban_message_text,
|
||||
reply_markup=keyboard)
|
||||
logging.info(
|
||||
f"BanCheck: [J_Msg] Ban notification 'actual_event_object.answer' attempted for user {event_user.id} (Message)."
|
||||
)
|
||||
elif isinstance(actual_event_object, CallbackQuery):
|
||||
logging.debug(
|
||||
f"BanCheck: [I_CB] Attempting actual_event_object.answer (alert) for CallbackQuery to user {event_user.id}"
|
||||
)
|
||||
await actual_event_object.answer(ban_message_text,
|
||||
show_alert=True)
|
||||
logging.info(
|
||||
f"BanCheck: [J_CB] Ban alert 'actual_event_object.answer' attempted for user {event_user.id} (CallbackQuery)."
|
||||
)
|
||||
|
||||
target_message_obj = actual_event_object.message
|
||||
if target_message_obj:
|
||||
target_chat_id = target_message_obj.chat.id
|
||||
if actual_event_object.message:
|
||||
try:
|
||||
logging.debug(
|
||||
f"BanCheck: [K_CB_Edit] Attempting target_message_obj.edit_text for user {event_user.id}"
|
||||
)
|
||||
await target_message_obj.edit_text(
|
||||
await actual_event_object.message.edit_text(
|
||||
ban_message_text, reply_markup=keyboard)
|
||||
logging.info(
|
||||
f"BanCheck: [L_CB_Edit] Ban msg 'target_message_obj.edit_text' attempted for user {event_user.id} (Callback)."
|
||||
)
|
||||
except Exception as e_edit:
|
||||
logging.warning(
|
||||
f"BanCheck: [M_CB_EditFail] Failed to edit message for banned user {event_user.id}: {type(e_edit).__name__} - {e_edit}. Sending new message."
|
||||
)
|
||||
await actual_event_object.bot.send_message(
|
||||
target_chat_id,
|
||||
except (TelegramAPIError, AiogramError):
|
||||
await bot_instance.send_message(
|
||||
actual_event_object.from_user.id,
|
||||
ban_message_text,
|
||||
reply_markup=keyboard)
|
||||
logging.info(
|
||||
f"BanCheck: [N_CB_NewMsg] Ban msg 'actual_event_object.bot.send_message' (after edit fail) attempted for user {event_user.id} (Callback)."
|
||||
)
|
||||
else:
|
||||
logging.warning(
|
||||
f"BanCheck: [K_CB_NoMsg] CallbackQuery from {event_user.id} has no .message attribute. Sending new message directly."
|
||||
)
|
||||
await actual_event_object.bot.send_message(
|
||||
await bot_instance.send_message(
|
||||
actual_event_object.from_user.id,
|
||||
ban_message_text,
|
||||
reply_markup=keyboard)
|
||||
logging.info(
|
||||
f"BanCheck: [L_CB_NoMsg_NewMsg] Ban msg 'actual_event_object.bot.send_message' (no .message) attempted for user {event_user.id} (Callback)."
|
||||
)
|
||||
else:
|
||||
logging.error(
|
||||
f"BanCheck: [UNHANDLED_EVENT_TYPE_INTERNAL] actual_event_object type {type(actual_event_object)} was not Message or CallbackQuery."
|
||||
)
|
||||
|
||||
except TelegramForbiddenError as e_forbidden:
|
||||
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: TelegramForbiddenError sending ban msg to {event_user.id}: {e_forbidden}"
|
||||
)
|
||||
except TelegramBadRequest as e_bad_req:
|
||||
f"BanCheck: Bot is blocked by user {event_user.id}.")
|
||||
except Exception as e_send:
|
||||
logging.error(
|
||||
f"BanCheck: TelegramBadRequest sending ban msg to {event_user.id}: {e_bad_req}",
|
||||
exc_info=True)
|
||||
except TelegramAPIError as e_api:
|
||||
logging.error(
|
||||
f"BanCheck: TelegramAPIError sending ban msg to {event_user.id}: {e_api}",
|
||||
exc_info=True)
|
||||
except AiogramError as e_aio:
|
||||
logging.error(
|
||||
f"BanCheck: AiogramError sending ban msg to {event_user.id}: {e_aio}",
|
||||
exc_info=True)
|
||||
except Exception as e_general:
|
||||
logging.error(
|
||||
f"BanCheck: Generic failure preparing or sending ban notification to user {event_user.id}: {e_general}",
|
||||
f"BanCheck: Failed to notify banned user {event_user.id}: {type(e_send).__name__} - {e_send}",
|
||||
exc_info=True)
|
||||
|
||||
logging.debug(
|
||||
f"BanCheck: [Z] End of ban processing for user {event_user.id}. Returning to stop further handlers."
|
||||
)
|
||||
return
|
||||
|
||||
return await handler(event, data)
|
||||
|
||||
+66
-69
@@ -1,13 +1,13 @@
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
import aiosqlite
|
||||
from typing import Any, Awaitable, Callable, Dict, Optional
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.types import TelegramObject, User, Update
|
||||
from aiogram.types import User, Update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from db.database import get_user, get_db_connection_manager, _setup_db_connection
|
||||
from db.dal import user_dal
|
||||
from config.settings import Settings
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ class JsonI18n:
|
||||
|
||||
def _load_locales(self):
|
||||
if not os.path.isdir(self.path):
|
||||
logging.error(f"Locales path not found: {self.path}")
|
||||
logging.error(
|
||||
f"Locales path not found or not a directory: {self.path}")
|
||||
return
|
||||
for item in os.listdir(self.path):
|
||||
if item.endswith(".json"):
|
||||
@@ -34,52 +35,73 @@ class JsonI18n:
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
self.locales_data[lang_code] = json.load(f)
|
||||
except Exception as e:
|
||||
except json.JSONDecodeError as e_json_load:
|
||||
logging.error(
|
||||
f"Error loading locale {lang_code} from {file_path}: {e}"
|
||||
f"Error loading locale {lang_code} from {file_path} (JSON Decode Error): {e_json_load}"
|
||||
)
|
||||
except Exception as e_load:
|
||||
logging.error(
|
||||
f"Error loading locale {lang_code} from {file_path}: {e_load}",
|
||||
exc_info=True)
|
||||
|
||||
def gettext(self, lang_code: Optional[str], key: str, **kwargs) -> str:
|
||||
effective_lang_code = lang_code
|
||||
if not effective_lang_code or effective_lang_code not in self.locales_data:
|
||||
effective_lang_code = self.default_lang
|
||||
effective_lang_code = lang_code if lang_code and lang_code in self.locales_data else self.default_lang
|
||||
|
||||
lang_data = self.locales_data.get(effective_lang_code)
|
||||
if lang_data is None:
|
||||
logging.warning(
|
||||
f"No language data for '{effective_lang_code}' (default: '{self.default_lang}'). Key '{key}'."
|
||||
f"No language data for '{effective_lang_code}' (default '{self.default_lang}' also missing). Key '{key}' will be returned as is."
|
||||
)
|
||||
return key.format(**kwargs) if kwargs else key
|
||||
|
||||
text = lang_data.get(key)
|
||||
if text is None:
|
||||
if effective_lang_code != self.default_lang:
|
||||
default_lang_data = self.locales_data.get(
|
||||
self.default_lang, {})
|
||||
text = default_lang_data.get(key)
|
||||
if text is None: return key.format(**kwargs) if kwargs else key
|
||||
|
||||
if text is None:
|
||||
logging.warning(
|
||||
f"Translation key '{key}' not found for lang '{effective_lang_code}' or default '{self.default_lang}'. Returning key."
|
||||
)
|
||||
return key.format(**kwargs) if kwargs else key
|
||||
try:
|
||||
return text.format(**kwargs) if kwargs else text
|
||||
except KeyError as e:
|
||||
except KeyError as e_format:
|
||||
logging.warning(
|
||||
f"Missing format key {e} for key '{key}' (lang: {effective_lang_code}). Text: '{text}'"
|
||||
f"Missing format key '{e_format}' for i18n key '{key}' (lang: {effective_lang_code}). Original text: '{text}'"
|
||||
)
|
||||
return text
|
||||
except Exception as e:
|
||||
except Exception as e_general_format:
|
||||
logging.error(
|
||||
f"Error formatting key '{key}' (lang: {effective_lang_code}): {e}. Text: '{text}'"
|
||||
)
|
||||
f"General error formatting i18n key '{key}' (lang: {effective_lang_code}): {e_general_format}. Original text: '{text}'",
|
||||
exc_info=True)
|
||||
return text
|
||||
|
||||
|
||||
_i18n_instance: Optional[JsonI18n] = None
|
||||
_i18n_instance_singleton: Optional[JsonI18n] = None
|
||||
|
||||
|
||||
def get_i18n_instance(path: str = "locales",
|
||||
default: str = "en",
|
||||
domain: str = "bot") -> JsonI18n:
|
||||
global _i18n_instance
|
||||
if _i18n_instance is None:
|
||||
_i18n_instance = JsonI18n(path=path, default=default, domain=domain)
|
||||
return _i18n_instance
|
||||
global _i18n_instance_singleton
|
||||
if _i18n_instance_singleton is None:
|
||||
|
||||
if not os.path.exists(path) or not os.path.isdir(path):
|
||||
logging.error(
|
||||
f"CRITICAL: Locales directory '{path}' not found. i18n will not work correctly."
|
||||
)
|
||||
|
||||
_i18n_instance_singleton = JsonI18n(path=path,
|
||||
default=default,
|
||||
domain=domain)
|
||||
else:
|
||||
_i18n_instance_singleton = JsonI18n(path=path,
|
||||
default=default,
|
||||
domain=domain)
|
||||
return _i18n_instance_singleton
|
||||
|
||||
|
||||
class I18nMiddleware(BaseMiddleware):
|
||||
@@ -92,65 +114,40 @@ class I18nMiddleware(BaseMiddleware):
|
||||
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")
|
||||
|
||||
current_language = self.i18n.default_lang
|
||||
|
||||
if event_user:
|
||||
logging.debug(
|
||||
f"I18nMiddleware: Processing for user {event_user.id}")
|
||||
|
||||
try:
|
||||
|
||||
user_db_data = await get_user(event_user.id)
|
||||
if user_db_data and user_db_data[
|
||||
'language_code'] and user_db_data[
|
||||
'language_code'] in self.i18n.locales_data:
|
||||
current_language = user_db_data['language_code']
|
||||
logging.debug(
|
||||
f"I18nMiddleware: User {event_user.id} language loaded from DB: {current_language}"
|
||||
)
|
||||
else:
|
||||
|
||||
if event_user.language_code:
|
||||
lang_prefix = event_user.language_code.split('-')[0]
|
||||
if lang_prefix in self.i18n.locales_data:
|
||||
current_language = lang_prefix
|
||||
logging.debug(
|
||||
f"I18nMiddleware: User {event_user.id} language set from Telegram client (prefix): {current_language}"
|
||||
)
|
||||
elif event_user.language_code in self.i18n.locales_data:
|
||||
current_language = event_user.language_code
|
||||
logging.debug(
|
||||
f"I18nMiddleware: User {event_user.id} language set from Telegram client (full): {current_language}"
|
||||
)
|
||||
else:
|
||||
|
||||
logging.debug(
|
||||
f"I18nMiddleware: User {event_user.id} Telegram client language '{event_user.language_code}' not supported. Using default: {current_language}"
|
||||
)
|
||||
else:
|
||||
logging.debug(
|
||||
f"I18nMiddleware: User {event_user.id} has no language_code from Telegram. Using default: {current_language}"
|
||||
)
|
||||
except Exception as e_db_lang:
|
||||
|
||||
logging.error(
|
||||
f"I18nMiddleware: Error fetching user language from DB for user {event_user.id}: {e_db_lang}. Falling back."
|
||||
)
|
||||
if event_user.language_code:
|
||||
lang_prefix = event_user.language_code.split('-')[0]
|
||||
user_db_model = await user_dal.get_user_by_id(
|
||||
session, event_user.id)
|
||||
if user_db_model and user_db_model.language_code and user_db_model.language_code in self.i18n.locales_data:
|
||||
current_language = user_db_model.language_code
|
||||
elif event_user.language_code:
|
||||
lang_prefix = event_user.language_code.split(
|
||||
'-')[0].lower()
|
||||
if lang_prefix in self.i18n.locales_data:
|
||||
current_language = lang_prefix
|
||||
elif event_user.language_code in self.i18n.locales_data:
|
||||
current_language = event_user.language_code
|
||||
elif event_user.language_code.lower(
|
||||
) in self.i18n.locales_data:
|
||||
current_language = event_user.language_code.lower()
|
||||
except Exception as e_db_lang:
|
||||
logging.error(
|
||||
f"I18nMiddleware: Error fetching user lang from DB for {event_user.id}: {e_db_lang}. Falling back.",
|
||||
exc_info=True)
|
||||
if event_user.language_code:
|
||||
lang_prefix = event_user.language_code.split(
|
||||
'-')[0].lower()
|
||||
if lang_prefix in self.i18n.locales_data:
|
||||
current_language = lang_prefix
|
||||
elif event_user.language_code.lower(
|
||||
) in self.i18n.locales_data:
|
||||
current_language = event_user.language_code.lower()
|
||||
|
||||
data["i18n_data"] = {
|
||||
"i18n_instance": self.i18n,
|
||||
"current_language": current_language
|
||||
}
|
||||
logging.debug(
|
||||
f"I18nMiddleware: Final current_language for event: {current_language}"
|
||||
)
|
||||
|
||||
return await handler(event, data)
|
||||
|
||||
Reference in New Issue
Block a user