from utils.texts import ( UNKNOWN_MAIN_CMD_TEXT, EMOJI_DIGITS, INSTRUCT_MAIN_MENU_TEXT, INSTRUCT_TRUECONF_TEXT, INSTRUCT_TRUECONF_WITH_AD, INSTRUCT_EMAIL_TEXT, ) import logging import asyncio import os from trueconf import Router, Message from trueconf.types import FSInputFile from utils.states import get_state, set_state, clear_state # πŸ”Œ Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ сбора статистики ΠΈΠ· main from utils.stats_logger import log_menu_stats logger = logging.getLogger(__name__) router = Router() # ΠŸΡƒΡ‚ΡŒ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ инструкции Trueconf TRUECONF_INSTRUCT_PATH = os.path.join(os.path.dirname(__file__), "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°_наличия_ΠΈ_авторизация_Π½Π°_мобильном_устройствС_Trueconf.docx") def get_user_cn(user_id: str) -> str | None: """ ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ CN ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈΠ· AD ΠΏΠΎ Π΅Π³ΠΎ user_id (email ΠΈΠ»ΠΈ Π»ΠΎΠ³ΠΈΠ½). user_id ΠΈΠ· TrueConf β€” это ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ email, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 'ds.krivochenko@tcs.sibcem.ru' ЗамСняСт tcs.sibcem.ru Π½Π° sibcem.ru для поиска Π² AD. Π˜Ρ‰Π΅Ρ‚ ΠΏΠΎ всСм OU ΠΈΠ· AD_BASES. """ from utils.ad_search import search_by_user_id try: # ЗамСняСм tcs.sibcem.ru Π½Π° sibcem.ru search_id = user_id.replace("@tcs.sibcem.ru", "@sibcem.ru") short_username = search_id.split("@")[0] if "@" in search_id else user_id logger.info(f"AD lookup: user_id={user_id}, search_id={search_id}, short={short_username}") entries = search_by_user_id(search_id, ["cn", "sAMAccountName", "mail", "userPrincipalName"]) if entries: entry = entries[0] cn = str(entry.cn) mail = str(entry.mail) if 'mail' in entry else "N/A" sam = str(entry.sAMAccountName) if 'sAMAccountName' in entry else "N/A" upn = str(entry.userPrincipalName) if 'userPrincipalName' in entry else "N/A" logger.info(f"AD found: cn={cn}, mail={mail}, sam={sam}, upn={upn}") return cn logger.warning(f"AD not found for user_id={user_id}, search_id={search_id}, short={short_username}") except Exception as e: logger.error(f"Ошибка получСния CN ΠΈΠ· AD для {user_id}: {e}", exc_info=True) return user_id # fallback β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ user_id ΠΊΠ°ΠΊ CN @router.message() async def instruct_router_handler(msg: Message): user_id = msg.from_user.id user_name = getattr(msg.from_user, 'name', 'N/A') user_username = getattr(msg.from_user, 'username', 'N/A') logger.info(f"Instruct: user_id={user_id}, name={user_name}, username={user_username}") current_state = get_state(user_id) if not msg.text: return cmd = msg.text.strip().lower() for raw_num, emoji_num in EMOJI_DIGITS.items(): if cmd == emoji_num: cmd = raw_num break if current_state is None: from utils.menu import MENU_MAP if MENU_MAP.get(cmd) == "INSTRUCT": msg.handled = True set_state(user_id, "INSTRUCT_MODE") await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html") return return if current_state == "INSTRUCT_MODE": msg.handled = True if cmd == "0": log_menu_stats(user_id, "Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ", "Π’Ρ‹Ρ…ΠΎΠ΄ Π² Π³Π»Π°Π²Π½ΠΎΠ΅ мСню") clear_state(user_id) from utils.menu import MENU_TEXT await msg.answer(MENU_TEXT, parse_mode="html") elif cmd == "1": log_menu_stats(user_id, "Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ", "Trueconf") set_state(user_id, "INSTRUCT_TRUECONF_VIEW") cn = get_user_cn(user_id) text = INSTRUCT_TRUECONF_WITH_AD(EMOJI_DIGITS, cn) await msg.answer(text, parse_mode="html") if os.path.isfile(TRUECONF_INSTRUCT_PATH): await msg.answer_document(FSInputFile(TRUECONF_INSTRUCT_PATH)) elif cmd == "2": log_menu_stats(user_id, "Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ", "ΠŸΠΎΡ‡Ρ‚Π°") set_state(user_id, "INSTRUCT_EMAIL_VIEW") await msg.answer(INSTRUCT_EMAIL_TEXT, parse_mode="html") else: await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html") elif current_state in ["INSTRUCT_TRUECONF_VIEW", "INSTRUCT_EMAIL_VIEW"]: msg.handled = True if cmd == "0": clear_state(user_id) from utils.menu import MENU_TEXT await msg.answer(MENU_TEXT, parse_mode="html") elif cmd == "9": set_state(user_id, "INSTRUCT_MODE") await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html") else: await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")