Files
fckbot/bots/commands/global_remove.py
Markov Andrey 63900feece Update 86 files
- /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
2026-06-30 10:33:28 +00:00

107 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
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.
# -*- coding: utf-8 -*-
"""
Команда !global_remove удаление документа из глобальной базы знаний по его названию.
Только для администраторов, работает только в личном чате.
Изменения для PostgreSQL (asyncpg):
- Замена курсоров на прямые запросы conn.fetch / conn.execute.
- Использование параметризованных запросов с $1, $2 и ANY($1) для массовых операций.
- Удаление синтаксиса, специфичного для MySQL/MariaDB.
"""
import logging
from core.commands.base import Command
logger = logging.getLogger(__name__)
class GlobalRemoveCommand(Command):
"""Удаляет глобальный документ по точному совпадению source_name."""
name = "!global_remove"
aliases = ["/global_remove"]
permission = "admin"
async def execute(self, msg, args: str, user_jid: str, room_jid: str = None):
"""
Алгоритм:
1. Проверка прав администратора.
2. Проверка, что команда вызвана в личном чате (room_jid is None).
3. Разбор аргументов, извлечение названия документа (в кавычках или без).
4. Поиск всех глобальных документов с таким source_name.
5. Удаление найденных документов из Qdrant (по doc_id).
6. Удаление записей из таблиц document_access и documents в PostgreSQL.
"""
# 1. Проверка прав администратора
if not self.check_permission(user_jid):
reply = msg.reply("У вас нет прав на удаление глобальных документов.")
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить сообщение о недостатке прав для global_remove")
return
# 2. Команда работает только в личном чате
if room_jid:
reply = msg.reply("⚠️ Команда !global_remove работает только в личном чате.")
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить сообщение об ограничении !global_remove")
return
# 3. Разбор аргументов команды
_, flags, pos = self.parse_args(args)
if not pos:
reply = msg.reply("❌ Укажите название документа для удаления. Пример: `!global_remove \"ГОСТ Р 12345\"`")
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить сообщение о необходимости указать название документа")
return
source_name = " ".join(pos).strip()
# Удаляем возможные кавычки, если пользователь заключил название в них
if source_name.startswith('"') and source_name.endswith('"'):
source_name = source_name[1:-1]
# 4. Поиск глобальных документов с указанным названием
async with self.bot.db.pool.acquire() as conn:
rows = await conn.fetch(
"SELECT id FROM documents WHERE is_global = TRUE AND source_name = $1",
source_name
)
doc_ids = [row['id'] for row in rows]
if not doc_ids:
reply = msg.reply(f"📭 Глобальный документ с названием '{source_name}' не найден.")
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить сообщение о ненайденном глобальном документе")
return
# 5. Удаление из Qdrant (по каждому doc_id)
for doc_id in doc_ids:
self.bot.qdrant.delete_by_doc_id(doc_id)
logger.debug(f"Удалён из Qdrant doc_id={doc_id}")
# 6. Удаление из PostgreSQL (сначала связанные права доступа, затем сам документ)
async with self.bot.db.pool.acquire() as conn:
# Удаляем записи о доступе (если есть)
await conn.execute("DELETE FROM document_access WHERE doc_id = ANY($1)", doc_ids)
# Удаляем сами документы
await conn.execute("DELETE FROM documents WHERE id = ANY($1)", doc_ids)
logger.info(f"Администратор {user_jid} удалил глобальный документ '{source_name}' (doc_ids: {doc_ids})")
reply = msg.reply(f"✅ Глобальный документ '{source_name}' удалён из базы знаний.")
if reply:
reply.send() # исправлено
else:
logger.error("Не удалось отправить подтверждение удаления глобального документа")
def get_help(self) -> str:
return (
"Удаляет глобальный документ по названию (админ, только в личном чате). "
"Использование: `!global_remove \"Название документа\"`"
)