domovoy_bot/handlers/topics.py
Admin ba4676b0af v1.0 MVP - Инициализация проекта 🏠
 Регистрация и верификация жильцов
 Рейтинг активности (уровни)
 Детект шпионов (Score 0-100)
 Анти-мат система (3 предупреждения → бан)
 Админ-панель с рассылкой
 Учёт квартир (несколько жильцов)
 Телефоны экстренных служб и мастеров
 Еженедельный экспорт JSON
 Прокси (socks5) для обхода РКН

Бекап: backups/versions/v1.0_mvp_2026-02-26/

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-02-27 10:54:16 +00:00

168 lines
5.9 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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'🔥 <b>Топ тем за {days} дн.</b>\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(
'❌ <b>Использование:</b>\n'
'<code>/topic_stats &lt;тема&gt;</code>\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} <b>Статистика темы: {topic.capitalize()}</b>\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 = '📋 <b>Список тем для классификации</b>\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')