"""
Пользовательские команды LKM37 REBORN
Доступны всем жильцам.
"""
import logging
from aiogram import Router, F
from aiogram.types import Message, CallbackQuery
from aiogram.filters import Command, CommandStart
from sqlalchemy import select
from database.db import AsyncSessionLocal
from database.models import User, InitiativeGroup
from keyboards.inline import get_main_menu, get_phones_menu
import config
logger = logging.getLogger(__name__)
router = Router()
@router.message(CommandStart())
async def cmd_start(message: Message):
"""Команда /start"""
from utils.ui_styles import fmt_msg, get_level_badge, get_user_level_key
if message.chat.type != 'private': return
user_id = message.from_user.id
async with AsyncSessionLocal() as session:
stmt = select(User).where(User.user_id == user_id)
result = await session.execute(stmt)
user = result.scalar_one_or_none()
if not user:
user = User(user_id=user_id, username=message.from_user.username, first_name=message.from_user.first_name, last_name=message.from_user.last_name)
session.add(user)
await session.commit()
welcome_text = (f"{fmt_msg('Инициализация протокола связи...', 'system')}\n"
f"{fmt_msg('Обнаружен новый субъект.', 'system')}\n\n"
"Добро пожаловать в цифровую экосистему ЛКМ37.\n"
"Я твой проводник и помощник по дому.\n\n"
"🛡️ Для доступа ко всем функциям нажми кнопку верификации в меню.")
is_ig = False
else:
ig_stmt = select(InitiativeGroup).where(InitiativeGroup.user_id == user_id, InitiativeGroup.is_active == True)
is_ig = (await session.execute(ig_stmt)).scalar_one_or_none() is not None
level_key = get_user_level_key(user_id, user.is_admin, user.verified, is_ig)
welcome_text = (f"{fmt_msg('Доступ разрешен.', 'system')}\n"
f"{fmt_msg(f'Статус: {get_level_badge(level_key)}', 'system')}\n\n"
f"Рад видеть тебя снова, {message.from_user.first_name}!\n"
"Чем могу помочь сегодня?")
await message.answer(welcome_text, reply_markup=get_main_menu(verified=user.verified, is_ig=is_ig, is_admin=(user.is_admin or user_id == config.ADMIN_USER_ID), is_superadmin=(user_id == config.ADMIN_USER_ID)), parse_mode='HTML')
@router.message(Command('phones'))
@router.callback_query(F.data == 'phones')
async def cb_phones(event):
msg = event if isinstance(event, Message) else event.message
if isinstance(event, CallbackQuery): await event.answer()
await msg.answer('📞 ЭКСТРЕННЫЕ ТЕЛЕФОНЫ\n\nВыберите категорию ниже:', reply_markup=get_phones_menu())
@router.callback_query(F.data.startswith('phones_'))
async def cb_phone_category(callback: CallbackQuery):
"""Выдача телефонов по категориям"""
from database.models import Service
from aiogram.types import FSInputFile
import os
category_map = {
'phones_emergency': 'emergency',
'phones_utility': 'utility',
'phones_police': 'police',
'phones_masters': 'masters'
}
cat_code = category_map.get(callback.data)
if not cat_code: return await callback.answer()
async with AsyncSessionLocal() as session:
stmt = select(Service).where(Service.category == cat_code).order_by(Service.name)
services = list((await session.execute(stmt)).scalars().all())
if not services:
return await callback.message.answer("👷 Данные для этой категории еще не заполнены.", reply_markup=get_main_menu())
# Формируем текст
text = f"📞 СПИСОК ТЕЛЕФОНОВ: {cat_code.upper()}\n\n"
for s in services:
text += f"🔹 {s.name}\n └ 📱 {s.phone}\n"
if s.description: text += f" └ 📝 {s.description}\n"
text += "\n"
# Ищем картинку (берем от первой службы в категории, если есть)
photo_path = services[0].image_path if services[0].image_path else None
try:
if photo_path and os.path.exists(photo_path):
await callback.message.answer_photo(FSInputFile(photo_path), caption=text, parse_mode='HTML')
else:
await callback.message.answer(text, parse_mode='HTML')
except Exception as e:
logger.error(f"Error sending phones: {e}")
await callback.message.answer(text, parse_mode='HTML')
await callback.answer()
@router.message(Command('rules'))
@router.callback_query(F.data == 'rules')
async def cb_rules(event):
msg = event if isinstance(event, Message) else event.message
if isinstance(event, CallbackQuery): await event.answer()
text = "📜 ПРАВИЛА ЧАТА ЛКМ37\n\n1. Уважение к соседям\n2. Никакого спама и рекламы\n3. Мат запрещен\n4. Обсуждаем только дела дома."
await msg.answer(text, parse_mode='HTML')
@router.message(Command('about'))
@router.callback_query(F.data == 'about_house')
async def cb_about(event):
msg = event if isinstance(event, Message) else event.message
if isinstance(event, CallbackQuery): await event.answer()
text = ("🏢 О НАШЕМ ДОМЕ (ЛКМ37)\n\n"
"📍 Адрес: пр-т Ленинского Комсомола, д. 37\n"
"🏗️ Тип дома: Многоквартирный жилой дом\n"
"🛠️ Управляющая компания: (укажите вашу УК)\n\n"
"Этот бот создан для объединения жильцов и быстрого решения проблем.")
await msg.answer(text, parse_mode='HTML')
@router.callback_query(F.data == 'my_profile')
async def cb_profile(event):
from utils.ui_styles import get_level_badge, get_user_level_key
user_id = event.from_user.id
msg = event if isinstance(event, Message) else event.message
if isinstance(event, CallbackQuery): await event.answer()
async with AsyncSessionLocal() as session:
user = await session.get(User, user_id)
ig_stmt = select(InitiativeGroup).where(InitiativeGroup.user_id == user_id, InitiativeGroup.is_active == True)
is_ig = (await session.execute(ig_stmt)).scalar_one_or_none() is not None
badge = get_level_badge(get_user_level_key(user_id, user.is_admin, user.verified, is_ig))
text = (f"👤 ТВОЙ ПРОФИЛЬ\n\n"
f"ID: {user_id}\n"
f"Статус: {badge}\n"
f"Квартира: {user.apartment or 'Не указана'}\n"
f"Подъезд: {user.staircase or '—'} | Этаж: {user.floor or '—'}\n"
f"Рейтинг: {user.rating} 🏆")
kb = InlineKeyboardBuilder()
kb.row(InlineKeyboardButton(text="📍 Указать подъезд/этаж", callback_data="edit_location"))
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
await msg.answer(text, reply_markup=kb.as_markup(), parse_mode='HTML')
@router.callback_query(F.data == "edit_location")
async def edit_location_start(callback: CallbackQuery):
await callback.message.answer("Введите ваш подъезд и этаж через пробел\nНапример: '3 5' (3 подъезд, 5 этаж)")
await callback.answer()
@router.message(F.text.regexp(r"^\d+\s+\d+$"))
async def process_location(message: Message):
staircase, floor = map(int, message.text.split())
async with AsyncSessionLocal() as session:
await session.execute(update(User).where(User.user_id == message.from_user.id).values(staircase=staircase, floor=floor))
await session.commit()
await message.answer(f"✅ Данные обновлены: Подъезд {staircase}, Этаж {floor}")
@router.message(Command('help'))
@router.callback_query(F.data == 'help')
async def cb_help(event):
msg = event if isinstance(event, Message) else event.message
if isinstance(event, CallbackQuery): await event.answer()
await msg.answer("❓ СПРАВКА\n\n/start — Главное меню\n/phones — Телефоны\n/about — О доме\n/profile — Твой профиль\n/rules — Правила")