""" Topics Analyzer — анализ тем чата, облако тегов Только для администраторов """ import logging from aiogram import Router, F from aiogram.types import Message from aiogram.filters import Command from sqlalchemy.ext.asyncio import AsyncSession from database.db import AsyncSessionLocal from services.topics_analyzer import TopicsAnalyzer from utils.decorators import admin_only logger = logging.getLogger(__name__) router = Router() # ============================================================================= # ОБЛАКО ТЕГОВ # ============================================================================= @router.message(Command('topics')) @router.message(Command('темы')) @admin_only async def cmd_topics(message: Message): """ Показать облако тегов тем чата Использование: /topics [дни] """ args = message.text.split() days = int(args[1]) if len(args) > 1 and args[1].isdigit() else 7 async with AsyncSessionLocal() as session: analyzer = TopicsAnalyzer(session) cloud = await analyzer.get_topics_cloud(days) await message.answer(cloud, parse_mode='HTML') # ============================================================================= # ТОП ТЕМ # ============================================================================= @router.message(Command('top_topics')) @router.message(Command('топ_тем')) @admin_only async def cmd_top_topics(message: Message): """ Показать топ тем за период Использование: /top_topics [дни] [лимит] """ args = message.text.split() days = int(args[1]) if len(args) > 1 and args[1].isdigit() else 7 limit = int(args[2]) if len(args) > 2 and args[2].isdigit() else 5 async with AsyncSessionLocal() as session: analyzer = TopicsAnalyzer(session) top = await analyzer.get_top_topics(days, limit) if not top: await message.answer('ℹ️ Нет данных за указанный период') return text = f'🔥 Топ тем за {days} дн.\n\n' for i, (topic_name, data) in enumerate(top, 1): text += f'{i}. {data["emoji"]} {topic_name.capitalize()}: {data["percent"]}% ({data["count"]} сообщ.)\n' await message.answer(text, parse_mode='HTML') # ============================================================================= # СТАТИСТИКА ПО ТЕМЕ # ============================================================================= @router.message(Command('topic_stats')) @router.message(Command('статистика_темы')) @admin_only async def cmd_topic_stats(message: Message): """ Показать статистику по конкретной теме Использование: /topic_stats <тема> """ args = message.text.split() if len(args) < 2: await message.answer( '❌ Использование:\n' '/topic_stats <тема>\n\n' 'Пример: /topic_stats лифты', parse_mode='HTML' ) return topic = args[1].lower() async with AsyncSessionLocal() as session: analyzer = TopicsAnalyzer(session) # Получаем общую статистику stats = await analyzer.get_topics_stats(7) if topic not in stats['topics']: await message.answer(f'ℹ️ Тема "{topic}" не найдена') return topic_data = stats['topics'][topic] emoji = topic_data['emoji'] # Получаем тренд trend = await analyzer.get_topic_trend(topic, 14) text = ( f'{emoji} Статистика темы: {topic.capitalize()}\n\n' f'📊 За 7 дней:\n' f'├─ Сообщений: {topic_data["count"]}\n' f'└─ Доля: {topic_data["percent"]}%\n\n' f'📈 За 14 дней:\n' f'└─ Сообщений: {trend["total"]}\n' ) # Тренд по дням if trend['daily_counts']: text += '\n📅 По дням:\n' for date, count in list(trend['daily_counts'].items())[-7:]: text += f' {date}: {count} сообщ.\n' await message.answer(text, parse_mode='HTML') # ============================================================================= # ЕЖЕНЕДЕЛЬНЫЙ ОТЧЁТ # ============================================================================= @router.message(Command('weekly_report')) @router.message(Command('недельный_отчёт')) @admin_only async def cmd_weekly_report(message: Message): """Сформировать еженедельный отчёт по темам""" async with AsyncSessionLocal() as session: analyzer = TopicsAnalyzer(session) report = await analyzer.get_weekly_report() await message.answer(report, parse_mode='HTML') # ============================================================================= # СПИСОК ТЕМ # ============================================================================= @router.message(Command('topics_list')) @router.message(Command('список_тем')) @admin_only async def cmd_topics_list(message: Message): """Показать список всех доступных тем""" async with AsyncSessionLocal() as session: analyzer = TopicsAnalyzer(session) topics = analyzer.topics text = '📋 Список тем для классификации\n\n' for topic_name, data in sorted(topics.items()): text += f'{data["emoji"]} {topic_name.capitalize()}\n' text += f' └─ Ключевые слова: {", ".join(data["keywords"][:5])}...\n' text += f'\n💡 Всего тем: {len(topics)}' await message.answer(text, parse_mode='HTML')