Code Refactoring

This commit is contained in:
machka
2025-05-14 08:43:23 +00:00
parent 7f94d794d6
commit d406baf0c1
33 changed files with 6015 additions and 3571 deletions
+167 -135
View File
@@ -1,172 +1,204 @@
import logging
import asyncio
from aiogram import Router ,F ,types ,Bot
from aiogram .filters import Command
from aiogram .fsm .context import FSMContext
from aiogram import Router, F, types, Bot
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from typing import Optional
from config .settings import Settings
from config.settings import Settings
from db .database import get_all_users_for_broadcast ,log_user_action
from bot .states .admin_states import AdminStates
from bot .keyboards .inline .admin_keyboards import get_broadcast_confirmation_keyboard ,get_back_to_admin_panel_keyboard
from bot .middlewares .i18n import JsonI18n
from db.database import get_all_users_for_broadcast, log_user_action
from bot.states.admin_states import AdminStates
from bot.keyboards.inline.admin_keyboards import get_broadcast_confirmation_keyboard, get_back_to_admin_panel_keyboard
from bot.middlewares.i18n import JsonI18n
router =Router (name ="admin_broadcast_router")
router = Router(name="admin_broadcast_router")
async def broadcast_message_prompt_handler (
callback :types .CallbackQuery ,
state :FSMContext ,
i18n_data :dict ,
settings :Settings
):
current_lang =i18n_data .get ("current_language",getattr (settings ,'DEFAULT_LANGUAGE','en'))
i18n :Optional [JsonI18n ]=i18n_data .get ("i18n_instance")
if not i18n :
logging .error ("i18n missing in broadcast_message_prompt_handler")
await callback .answer ("Language service error.",show_alert =True )
async def broadcast_message_prompt_handler(callback: types.CallbackQuery,
state: FSMContext, i18n_data: dict,
settings: Settings):
current_lang = i18n_data.get("current_language",
getattr(settings, 'DEFAULT_LANGUAGE', 'en'))
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
if not i18n:
logging.error("i18n missing in broadcast_message_prompt_handler")
await callback.answer("Language service error.", show_alert=True)
return
_ =lambda key ,**kwargs :i18n .gettext (current_lang ,key ,**kwargs )
prompt_text =_ ("admin_broadcast_enter_message")
_ = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs)
prompt_text = _("admin_broadcast_enter_message")
if callback .message :
try :
await callback .message .edit_text (prompt_text ,reply_markup =get_back_to_admin_panel_keyboard (current_lang ,i18n ))
except Exception as e :
logging .warning (f"Could not edit message for broadcast prompt: {e}")
await callback .message .answer (prompt_text ,reply_markup =get_back_to_admin_panel_keyboard (current_lang ,i18n ))
await callback .answer ()
await state .set_state (AdminStates .waiting_for_broadcast_message )
if callback.message:
try:
await callback.message.edit_text(
prompt_text,
reply_markup=get_back_to_admin_panel_keyboard(
current_lang, i18n))
except Exception as e:
logging.warning(
f"Could not edit message for broadcast prompt: {e}")
await callback.message.answer(
prompt_text,
reply_markup=get_back_to_admin_panel_keyboard(
current_lang, i18n))
await callback.answer()
await state.set_state(AdminStates.waiting_for_broadcast_message)
@router .message (AdminStates .waiting_for_broadcast_message ,F .text )
async def process_broadcast_message_handler (
message :types .Message ,
state :FSMContext ,
i18n_data :dict ,
settings :Settings
):
current_lang =i18n_data .get ("current_language",getattr (settings ,'DEFAULT_LANGUAGE','en'))
i18n :Optional [JsonI18n ]=i18n_data .get ("i18n_instance")
if not i18n :
logging .error ("i18n missing in process_broadcast_message_handler")
await message .reply ("Language service error.")
@router.message(AdminStates.waiting_for_broadcast_message, F.text)
async def process_broadcast_message_handler(message: types.Message,
state: FSMContext, i18n_data: dict,
settings: Settings):
current_lang = i18n_data.get("current_language",
getattr(settings, 'DEFAULT_LANGUAGE', 'en'))
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
if not i18n:
logging.error("i18n missing in process_broadcast_message_handler")
await message.reply("Language service error.")
return
_ =lambda key ,**kwargs :i18n .gettext (current_lang ,key ,**kwargs )
_ = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs)
broadcast_message_text =message .html_text
await state .update_data (broadcast_message =broadcast_message_text )
broadcast_message_text = message.html_text
await state.update_data(broadcast_message=broadcast_message_text)
preview_snippet =broadcast_message_text [:200 ]+"..."if len (broadcast_message_text )>200 else broadcast_message_text
confirmation_prompt =_ ("admin_broadcast_confirm_prompt",message_preview =preview_snippet )
preview_snippet = broadcast_message_text[:200] + "..." if len(
broadcast_message_text) > 200 else broadcast_message_text
confirmation_prompt = _("admin_broadcast_confirm_prompt",
message_preview=preview_snippet)
await message .answer (
confirmation_prompt ,
reply_markup =get_broadcast_confirmation_keyboard (current_lang ,i18n ),
parse_mode ="HTML"
)
await state .set_state (AdminStates .confirming_broadcast )
await message.answer(confirmation_prompt,
reply_markup=get_broadcast_confirmation_keyboard(
current_lang, i18n),
parse_mode="HTML")
await state.set_state(AdminStates.confirming_broadcast)
@router .callback_query (F .data =="admin_action:main",AdminStates .waiting_for_broadcast_message )
async def cancel_broadcast_at_prompt_stage (callback :types .CallbackQuery ,state :FSMContext ,settings :Settings ,i18n_data :dict ):
@router.callback_query(F.data == "admin_action:main",
AdminStates.waiting_for_broadcast_message)
async def cancel_broadcast_at_prompt_stage(callback: types.CallbackQuery,
state: FSMContext,
settings: Settings,
i18n_data: dict):
from .common import admin_panel_actions_callback_handler
current_lang =i18n_data .get ("current_language",getattr (settings ,'DEFAULT_LANGUAGE','en'))
i18n :Optional [JsonI18n ]=i18n_data .get ("i18n_instance")
if not i18n :logging .error ("i18n missing");await callback .answer ("Language error.",show_alert =True );return
_ =lambda key ,**kwargs :i18n .gettext (current_lang ,key ,**kwargs )
current_lang = i18n_data.get("current_language",
getattr(settings, 'DEFAULT_LANGUAGE', 'en'))
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
if not i18n:
logging.error("i18n missing")
await callback.answer("Language error.", show_alert=True)
return
_ = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs)
if callback .message :
try :await callback .message .edit_text (_ ("admin_broadcast_cancelled"),reply_markup =None )
except Exception :await callback .message .answer (_ ("admin_broadcast_cancelled"))
await callback .answer (_ ("admin_broadcast_cancelled"))
await state .clear ()
if callback.message:
try:
await callback.message.edit_text(_("admin_broadcast_cancelled"),
reply_markup=None)
except Exception:
await callback.message.answer(_("admin_broadcast_cancelled"))
await callback.answer(_("admin_broadcast_cancelled"))
await state.clear()
callback.data = "admin_action:main"
from bot.keyboards.inline.admin_keyboards import get_admin_panel_keyboard
if callback.message:
await callback.message.answer(_("admin_panel_title"),
reply_markup=get_admin_panel_keyboard(
i18n, current_lang))
callback .data ="admin_action:main"
@router.callback_query(F.data.startswith("broadcast_final_action:"),
AdminStates.confirming_broadcast)
async def confirm_broadcast_callback_handler(callback: types.CallbackQuery,
state: FSMContext,
i18n_data: dict, bot: Bot,
settings: Settings):
current_lang = i18n_data.get("current_language",
getattr(settings, 'DEFAULT_LANGUAGE', 'en'))
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
if not i18n:
logging.error("i18n missing")
await callback.answer("Language error.", show_alert=True)
return
_ = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs)
action = callback.data.split(":")[1]
user_fsm_data = await state.get_data()
broadcast_message = user_fsm_data.get("broadcast_message")
if not callback.message:
await callback.answer("Error: message context lost.", show_alert=True)
await state.clear()
return
if action == "send":
if not broadcast_message:
await callback.message.edit_text(
_("admin_broadcast_error_no_message"))
await state.clear()
await callback.answer(show_alert=True)
return
from bot .keyboards .inline .admin_keyboards import get_admin_panel_keyboard
if callback .message :
await callback .message .answer (_ ("admin_panel_title"),reply_markup =get_admin_panel_keyboard (i18n ,current_lang ))
await callback.message.edit_text(_("admin_broadcast_sending_started"),
reply_markup=None)
await callback.answer()
users_to_broadcast = await get_all_users_for_broadcast()
sent_count = 0
failed_count = 0
logging.info(
f"Starting broadcast: '{broadcast_message[:50]}...' to {len(users_to_broadcast)} users."
)
@router .callback_query (F .data .startswith ("broadcast_final_action:"),AdminStates .confirming_broadcast )
async def confirm_broadcast_callback_handler (
callback :types .CallbackQuery ,
state :FSMContext ,
i18n_data :dict ,
bot :Bot ,
settings :Settings
):
current_lang =i18n_data .get ("current_language",getattr (settings ,'DEFAULT_LANGUAGE','en'))
i18n :Optional [JsonI18n ]=i18n_data .get ("i18n_instance")
if not i18n :logging .error ("i18n missing");await callback .answer ("Language error.",show_alert =True );return
admin_user = callback.from_user
_ =lambda key ,**kwargs :i18n .gettext (current_lang ,key ,**kwargs )
for user_row in users_to_broadcast:
user_id = user_row['user_id']
try:
await bot.send_message(user_id,
broadcast_message,
parse_mode="HTML")
sent_count += 1
action =callback .data .split (":")[1 ]
user_fsm_data =await state .get_data ()
broadcast_message =user_fsm_data .get ("broadcast_message")
if not callback .message :
await callback .answer ("Error: message context lost.",show_alert =True )
await state .clear ();return
if action =="send":
if not broadcast_message :
await callback .message .edit_text (_ ("admin_broadcast_error_no_message"))
await state .clear ();await callback .answer (show_alert =True );return
await callback .message .edit_text (_ ("admin_broadcast_sending_started"),reply_markup =None )
await callback .answer ()
users_to_broadcast =await get_all_users_for_broadcast ()
sent_count =0 ;failed_count =0
logging .info (f"Starting broadcast: '{broadcast_message[:50]}...' to {len(users_to_broadcast)} users.")
admin_user =callback .from_user
for user_row in users_to_broadcast :
user_id =user_row ['user_id']
try :
await bot .send_message (user_id ,broadcast_message ,parse_mode ="HTML")
sent_count +=1
await log_user_action (
user_id =admin_user .id ,
telegram_username =admin_user .username ,
telegram_first_name =admin_user .first_name ,
event_type ="admin_broadcast_sent",
content =f"To user {user_id}: {broadcast_message[:70]}...",
is_admin_event =True ,
target_user_id =user_id
await log_user_action(
user_id=admin_user.id,
telegram_username=admin_user.username,
telegram_first_name=admin_user.first_name,
event_type="admin_broadcast_sent",
content=f"To user {user_id}: {broadcast_message[:70]}...",
is_admin_event=True,
target_user_id=user_id)
except Exception as e:
failed_count += 1
logging.warning(
f"Failed to send broadcast to user {user_id}: {type(e).__name__} - {e}"
)
except Exception as e :
failed_count +=1
logging .warning (f"Failed to send broadcast to user {user_id}: {type(e).__name__} - {e}")
await log_user_action (
user_id =admin_user .id ,
telegram_username =admin_user .username ,
telegram_first_name =admin_user .first_name ,
event_type ="admin_broadcast_failed",
content =f"For user {user_id}: {type(e).__name__} - {str(e)[:70]}...",
is_admin_event =True ,
target_user_id =user_id
)
await asyncio .sleep (0.1 )
await log_user_action(
user_id=admin_user.id,
telegram_username=admin_user.username,
telegram_first_name=admin_user.first_name,
event_type="admin_broadcast_failed",
content=
f"For user {user_id}: {type(e).__name__} - {str(e)[:70]}...",
is_admin_event=True,
target_user_id=user_id)
await asyncio.sleep(0.1)
result_message =_ ("admin_broadcast_finished_stats",sent_count =sent_count ,failed_count =failed_count )
await callback .message .answer (result_message ,reply_markup =get_back_to_admin_panel_keyboard (current_lang ,i18n ))
result_message = _("admin_broadcast_finished_stats",
sent_count=sent_count,
failed_count=failed_count)
await callback.message.answer(
result_message,
reply_markup=get_back_to_admin_panel_keyboard(current_lang, i18n))
elif action =="cancel":
await callback .message .edit_text (_ ("admin_broadcast_cancelled"),reply_markup =get_back_to_admin_panel_keyboard (current_lang ,i18n ))
await callback .answer ()
elif action == "cancel":
await callback.message.edit_text(
_("admin_broadcast_cancelled"),
reply_markup=get_back_to_admin_panel_keyboard(current_lang, i18n))
await callback.answer()
await state .clear ()
await state.clear()