- /rag/commands/expert.py - /core/services/__init__.py - /core/services/embedding_service.py - /core/services/file_service.py - /core/services/giga_client.py - /core/services/kb_service.py - /core/services/postgres_service.py - /core/services/qdrant_service.py - /core/services/reranker_service.py - /core/functions/__init__.py - /core/functions/check_consistency.py - /core/functions/check_spelling.py - /core/functions/critique_answer.py - /core/functions/expand_query.py - /core/functions/extract_metrics.py - /core/functions/file_processor.py - /core/functions/generate_document.py - /core/functions/intent_classify.py - /core/functions/rerank_context.py - /core/functions/summarize_document.py - /core/utils/__init__.py - /core/utils/arg_parser.py - /core/utils/config_loader.py - /core/utils/layout_converter.py - /core/utils/logger.py - /core/utils/text_utils.py - /core/utils/web_utils.py - /bots/commands/__init__.py - /bots/commands/base.py - /bots/commands/create.py - /core/commands/global_remove.py - /core/commands/help.py - /core/commands/info.py - /core/commands/kb.py - /core/commands/learn.py - /core/commands/other.py - /core/commands/registry.py - /core/commands/stats.py - /core/commands/template.py - /core/handlers/__init__.py - /core/handlers/message_handler.py - /core/workers/__init__.py - /core/workers/indexing_worker.py - /core/xmpp/__init__.py - /core/xmpp/client.py - /bots/commands/global_remove.py - /bots/commands/help.py - /bots/commands/info.py - /bots/commands/kb.py - /bots/commands/registry.py - /bots/commands/other.py - /bots/commands/template.py - /bots/commands/learn.py - /bots/commands/stats.py - /bots/handlers/message_handler.py - /bots/handlers/__init__.py - /bots/workers/__init__.py - /bots/workers/indexing_worker.py - /bots/xmpp/__init__.py - /bots/xmpp/client.py - /rag/services/qdrant_service.py - /rag/services/giga_client.py - /rag/services/embedding_service.py - /rag/services/reranker_service.py - /rag/services/__init__.py - /rag/services/file_service.py - /rag/services/postgres_service.py - /rag/services/kb_service.py - /rag/functions/check_spelling.py - /rag/functions/__init__.py - /rag/functions/extract_metrics.py - /rag/functions/generate_document.py - /rag/functions/expand_query.py - /rag/functions/critique_answer.py - /rag/functions/file_processor.py - /rag/functions/check_consistency.py - /rag/functions/summarize_document.py - /rag/functions/rerank_context.py - /rag/functions/intent_classify.py - /rag/utils/__init__.py - /rag/utils/layout_converter.py - /rag/utils/text_utils.py - /rag/utils/arg_parser.py - /rag/utils/config_loader.py - /rag/utils/logger.py - /rag/utils/web_utils.py
166 lines
6.9 KiB
Python
166 lines
6.9 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
Административные команды: !stats, !status, !clean.
|
||
- !stats – статистика работы бота (сообщения, файлы, AI-запросы, ошибки, uptime).
|
||
- !status – проверка состояния сервисов (GigaChat, PostgreSQL, Qdrant, диск).
|
||
- !clean – очистка временной директории.
|
||
|
||
Изменения для PostgreSQL:
|
||
- Замена `conn.ping()` на `conn.execute("SELECT 1")` в команде !status.
|
||
- Обновлены тексты сообщений (MariaDB → PostgreSQL).
|
||
"""
|
||
|
||
import os
|
||
import shutil
|
||
import logging
|
||
from datetime import datetime
|
||
|
||
from core.commands.base import Command
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class StatsCommand(Command):
|
||
"""Показывает статистику работы бота (только для администраторов)."""
|
||
|
||
name = "!stats"
|
||
aliases = ["/stats", "!статистика", "/статистика", "!стат", "/стат"]
|
||
permission = "admin"
|
||
|
||
async def execute(self, msg, args: str, user_jid: str, room_jid: str = None):
|
||
"""
|
||
Выводит:
|
||
- uptime бота
|
||
- количество обработанных сообщений
|
||
- количество AI-запросов
|
||
- количество обработанных файлов
|
||
- количество ошибок
|
||
- количество документов в базе знаний (с учётом контекста)
|
||
"""
|
||
if not self.check_permission(user_jid):
|
||
reply = msg.reply("⛔ Нет прав.")
|
||
if reply:
|
||
reply.send() # исправлено
|
||
else:
|
||
logger.error("Не удалось отправить сообщение о недостатке прав (stats)")
|
||
return
|
||
|
||
# Время работы бота
|
||
uptime = datetime.now() - self.bot.start_time
|
||
|
||
# Получение метрик из MetricsHandler
|
||
stats = self.bot.metrics_handler.get()
|
||
|
||
# Количество доступных документов в БЗ (личные/комнатные + глобальные)
|
||
sources = await self.bot.kb.get_available_sources(user_jid, room_jid)
|
||
|
||
response = (
|
||
f"📊 **Статистика бота {self.bot.config.name}**\n"
|
||
f"⏱ Uptime: {str(uptime).split('.')[0]}\n"
|
||
f"💬 Сообщений: {stats.get('messages_total', 0)}\n"
|
||
f"🤖 AI запросов: {stats.get('ai_requests', 0)}\n"
|
||
f"📁 Файлов обработано: {stats.get('files_processed', 0)}\n"
|
||
f"❌ Ошибок: {stats.get('errors_total', 0)}\n"
|
||
f"📚 Документов в БЗ: {len(sources)}"
|
||
)
|
||
reply = msg.reply(response)
|
||
if reply:
|
||
reply.send() # исправлено
|
||
else:
|
||
logger.error("Не удалось отправить статистику")
|
||
|
||
def get_help(self) -> str:
|
||
return "Показывает статистику работы бота (админ)."
|
||
|
||
|
||
class StatusCommand(Command):
|
||
"""Проверяет состояние всех внешних сервисов (административная команда)."""
|
||
|
||
name = "!status"
|
||
aliases = ["/status", "!статус", "/статус"]
|
||
permission = "admin"
|
||
|
||
async def execute(self, msg, args: str, user_jid: str, room_jid: str = None):
|
||
if not self.check_permission(user_jid):
|
||
reply = msg.reply("⛔ Нет прав.")
|
||
if reply:
|
||
reply.send() # исправлено
|
||
else:
|
||
logger.error("Не удалось отправить сообщение о недостатке прав (stats)")
|
||
return
|
||
|
||
# --- GigaChat ---
|
||
try:
|
||
# Простой запрос для проверки доступности API
|
||
await self.bot.giga.chat([], "ping", system_prompt=None, file_id=None, temperature=0.1)
|
||
ai_status = "✅ GigaChat Online"
|
||
except Exception as e:
|
||
ai_status = f"❌ GigaChat Offline: {e}"
|
||
|
||
# --- PostgreSQL (asyncpg) ---
|
||
try:
|
||
async with self.bot.db.pool.acquire() as conn:
|
||
# В asyncpg нет метода ping(), используем SELECT 1
|
||
await conn.execute("SELECT 1")
|
||
db_status = "✅ PostgreSQL Online"
|
||
except Exception as e:
|
||
db_status = f"❌ PostgreSQL Error: {e}"
|
||
|
||
# --- Qdrant ---
|
||
try:
|
||
self.bot.qdrant.client.get_collection(self.bot.qdrant.collection_name)
|
||
qd_status = "✅ Qdrant Online"
|
||
except Exception as e:
|
||
qd_status = f"❌ Qdrant Error: {e}"
|
||
|
||
# --- Дисковое пространство (временная директория) ---
|
||
total, used, free = shutil.disk_usage(self.bot.config.temp_dir)
|
||
disk_info = f"💾 Диск: {used // (2**20)}MB / {total // (2**20)}MB"
|
||
|
||
full_status = f"🛰 **СТАТУС БОТА**\n{ai_status}\n{db_status}\n{qd_status}\n{disk_info}"
|
||
reply = msg.reply(full_status)
|
||
if reply:
|
||
reply.send() # исправлено
|
||
else:
|
||
logger.error("Не удалось отправить статус")
|
||
|
||
def get_help(self) -> str:
|
||
return "Проверяет состояние сервисов (GigaChat, PostgreSQL, Qdrant, диск) – админ."
|
||
|
||
|
||
class CleanCommand(Command):
|
||
"""Очищает временную директорию бота (temp_dir)."""
|
||
|
||
name = "!clean"
|
||
aliases = ["/clean", "!очистка", "/очистка"]
|
||
permission = "admin"
|
||
|
||
async def execute(self, msg, args: str, user_jid: str, room_jid: str = None):
|
||
if not self.check_permission(user_jid):
|
||
reply = msg.reply("⛔ Нет прав.")
|
||
if reply:
|
||
reply.send() # исправлено
|
||
else:
|
||
logger.error("Не удалось отправить сообщение о недостатке прав (stats)")
|
||
return
|
||
|
||
count = 0
|
||
temp_dir = self.bot.config.temp_dir
|
||
for f in os.listdir(temp_dir):
|
||
try:
|
||
p = os.path.join(temp_dir, f)
|
||
if os.path.isfile(p):
|
||
os.unlink(p)
|
||
elif os.path.isdir(p):
|
||
shutil.rmtree(p)
|
||
count += 1
|
||
except Exception:
|
||
pass
|
||
reply = msg.reply(f"🧹 Удалено объектов из temp_dir: {count}")
|
||
if reply:
|
||
reply.send() # исправлено
|
||
else:
|
||
logger.error("Не удалось отправить отчёт об очистке")
|
||
|
||
def get_help(self) -> str:
|
||
return "Очищает временную директорию бота (админ)." |