from aiogram import types, Dispatcher, Bot from aiogram.types import Message from aiogram.filters import Command from config import Config from models.state import BotState from utils.antispam import admin_required, saving from services.watcher_service import WatcherService from storage.message_storage import load_messages, save_message, clear_messages from logging import getLogger from utils.analytics import create_statistics_text logger = getLogger(__name__) def register_handlers(dp: Dispatcher, state: BotState, bot: Bot): @dp.message(Command("log")) @saving @admin_required(3) async def send_log(message: Message): if Config.DISABLE_LOGGING: await message.answer("📝 Логирование отключено (DISABLE_LOGGING=1).") return if Config.DISABLE_STORAGE: await message.answer("📝 Файл логов не ведётся (DISABLE_STORAGE=1).") return try: log_file = types.FSInputFile(str(Config.LOG_FILE)) await message.answer_document(log_file, caption="📑 Логи бота") except FileNotFoundError: await message.answer("Файл логов пока не создан.") @dp.message(Command("status")) @saving @admin_required(3) async def send_status(message: Message): from utils.analytics import analyze_bot_logs from utils.mac_metrics import get_macbook_battery_level, get_process_usage try: if Config.DISABLE_LOGGING or Config.DISABLE_STORAGE: await message.answer( "📊 Аналитика по логам недоступна: логирование или хранение отключено в .env" ) return stats = analyze_bot_logs(str(Config.LOG_FILE)) batt = await get_macbook_battery_level() usage = await get_process_usage() status_text = ( "🤖 СТАТУС БОТА\n" "══════════════\n" f"✅ Uptime: {stats.get('uptime_percentage', 0)}%\n" f"⏱️ Слежка расписания: {'ВКЛ' if state.watcher_work else 'ВЫКЛ'}\n" f"🔋 Уровень заряда: {batt}%\n" f"🖥️ Загрузка цп: {usage['cpu_percent']}\n" f"🧠 Загрузка оперативки: {usage['rss_mb']:.2f} MB\n" ) await message.answer(status_text) except Exception as e: await message.answer(f"❌ Ошибка при проверке статуса: {str(e)}") @dp.message(Command("analytics")) @saving @admin_required(1) async def stat(message: Message): from utils.analytics import analyze_bot_logs if Config.DISABLE_LOGGING or Config.DISABLE_STORAGE: await message.answer( "📊 Аналитика по логам недоступна: логирование или хранение отключено в .env" ) return stats = analyze_bot_logs(str(Config.LOG_FILE)) await message.answer( create_statistics_text(stats), reply_to_message_id=message.message_id ) @dp.message(Command("del")) @admin_required(1) async def delete_all_messages(message: Message): if Config.DISABLE_STORAGE: await message.answer( "📭 Хранение сообщений отключено (DISABLE_STORAGE=1).", reply_to_message_id=message.message_id, ) return messages = load_messages() if not messages: sent = await message.answer( "📭 Нет сохранённых сообщений для удаления.", reply_to_message_id=message.message_id, ) save_message(sent.chat.id, sent.message_id) return deleted = 0 for chat_id, msg_id in messages: try: await bot.delete_message(chat_id, msg_id) deleted += 1 except Exception as e: logger.warning(f"Не удалось удалить {msg_id} в чате {chat_id}: {e}") clear_messages() sent = await message.answer( f"✅ Удалено {deleted} сообщений (включая /rasp).", reply_to_message_id=message.message_id, ) save_message(sent.chat.id, sent.message_id) @dp.message(Command("power")) @saving @admin_required(2) async def power_control(message: types.Message): args = message.text.split() if len(args) < 2: days = state.watcher_days_ahead status = "включена" if state.watcher_work else "выключена" await message.answer(f"⏱️ Слежка расписания: {status} (на {days} дн.)") return command = args[1].lower() watcher_service = WatcherService(state, bot) if command == "on": # Проверяем, есть ли параметр количества дней days = 1 if len(args) > 2: try: days = int(args[2]) if days < 1: await message.answer("❌ Количество дней должно быть >= 1") return except ValueError: await message.answer("❌ Неверный формат дней. Используйте: /power on 3") return state.watcher_days_ahead = days if not state.watcher_work: await watcher_service.start() await message.answer(f"✅ Слежка расписания включена (на {days} дн.)") else: await message.answer(f"✅ Количество дней изменено на {days} дн.") elif command == "off" and state.watcher_work: await watcher_service.stop() await message.answer("❌ Слежка расписания выключена") else: await message.answer("❌ Неверная команда")