перед внедрением веб интерфейса и API для взаимодействием с gemini.

This commit is contained in:
2026-08-05 23:02:35 +03:00
parent 8f611ec41a
commit 9deca9ab34
10 changed files with 495 additions and 194 deletions
+19
View File
@@ -0,0 +1,19 @@
import sys
import os
# Добавляем корень проекта в путь поиска модулей Python
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from core.database import get_connection
rule_text = (
"Сотрудники, присутствующие в 1С:ЗУП, но отсутствующие в СКУД Орион Pro, "
"являются аномалией синхронизации профилей. ИИ должен запрашивать у СБ статус выдачи пропуска."
)
with get_connection() as conn:
cursor = conn.cursor()
cursor.execute("INSERT OR IGNORE INTO ai_knowledge_base (rule_text) VALUES (?)", (rule_text,))
conn.commit()
print("✓ Правило успешно внесено в SQLite БД!")
+80 -25
View File
@@ -35,23 +35,22 @@ def print_stats():
def print_snapshots_list(date_str=None):
"""Выводит реестр снапшотов с идеальным вертикальным выравниванием дефисов и цифр."""
"""Выводит реестр снапшотов с отображением даты и точного времени среза."""
rows = get_available_snapshots(date_str)
print("\n" + "=" * 95)
print("\n" + "=" * 105)
print(f"📸 РЕЕСТР СОХРАНЕННЫХ СНАПШОТОВ (СВЕРХУ СВЕЖИЕ) {'ЗА ЛОГИ ' + date_str if date_str else ''}:")
print("=" * 95)
print("=" * 105)
header = f"{'ID снапшота':<16} | {'Дата снапшота (создания)':<24} | {'Дата среза':<12} | {'Записей':<8}"
header = f"{'ID снапшота':<16} | {'Дата снапшота (создания)':<24} | {'Дата и время среза':<20} | {'Записей':<8}"
print(header)
print("-" * 95)
print("-" * 105)
if not rows:
print("Снапшотов пока нет.")
print("=" * 95 + "\n")
print("=" * 105 + "\n")
return
# Внутрипитоновская хронологическая сортировка: сначала snap_time DESC, затем seq_num DESC
def snapshot_sort_key(row):
snap_id = row[0] or ""
snap_time = row[2] or ""
@@ -72,15 +71,43 @@ def print_snapshots_list(date_str=None):
snap_time = r[2] if r[2] else '—'
count = r[3]
# 💡 ИДЕАЛЬНОЕ ВЫРАВНИВАНИЕ: если нет префикса Y, добавляем ведущий пробел
# Извлекаем время (ЧЧ:ММ:СС) из snapshot_time, если оно есть
time_part = "—"
if snap_time and " " in snap_time:
time_part = snap_time.split(" ")[1]
slice_datetime_str = f"{log_date} {time_part}" if time_part != "—" else log_date
if not snap_id.startswith("Y"):
formatted_snap_id = f" {snap_id}"
else:
formatted_snap_id = snap_id
print(f"{formatted_snap_id:<16} | {snap_time:<24} | {log_date:<12} | {count:<8}")
print(f"{formatted_snap_id:<16} | {snap_time:<24} | {slice_datetime_str:<20} | {count:<8}")
print("=" * 95 + "\n")
print("=" * 105 + "\n")
def delete_snapshot_by_id(snapshot_id: str):
"""Удаляет конкретный снапшот из таблицы scud_logs по его ID."""
with get_connection() as conn:
cursor = conn.cursor()
cursor.execute("DELETE FROM scud_logs WHERE snapshot_id = ?", (snapshot_id,))
deleted_count = cursor.rowcount
conn.commit()
print(f"\n[✓] Успешно удален снапшот [{snapshot_id}]. Удалено строк: {deleted_count}\n")
return deleted_count
def delete_snapshots_by_date(date_str: str):
"""Удаляет все снапшоты за указанную дату (например, '04.08.2026')."""
with get_connection() as conn:
cursor = conn.cursor()
cursor.execute("DELETE FROM scud_logs WHERE log_date = ? OR snapshot_id LIKE ?", (date_str, f"%{date_str.replace('.', '')}%"))
deleted_count = cursor.rowcount
conn.commit()
print(f"\n[✓] Успешно удалены все снапшоты за дату [{date_str}]. Удалено строк: {deleted_count}\n")
return deleted_count
def inspect_scud(snapshot_id=None, date_str=None, export_xlsx=None):
@@ -171,28 +198,42 @@ def main():
help_text = """
CLI-утилита инспекции и управления SQLite базой данных СКУД (scud_orion_ai.db)
ДОСТУПНЫЕ КОМАНДЫ:
stats -- Общая статистика строк по всем таблицам БД
snapshots [ДД.ММ.ГГГГ] -- Посмотреть список всех снапшотов (опционально за дату)
scud [--snapshot ID] [--export-xlsx NAME] -- Инспекция логов СКУД и опциональный экспорт в Excel
anomalies -- Посмотреть все найденные аномалии СКУД ⟷ 1С
rules -- Посмотреть правила Базы Знаний ИИ из SQLite
dump [output.xlsx] -- Полный дамп всех таблиц БД в многостраничный Excel
snapshot del [ID] или [--day ДД.ММ.ГГГГ] -- Удаление снапшотов по ID или за весь день
ПРИМЕРЫ ЗАПУСКА:
python scripts/db_cli.py scud -- Выгрузка СКУД за текущую дату (последний снапшот)
python scripts/db_cli.py scud --snapshot 20260805-001 -- Выгрузка СКУД строго по ID конкретного снапшота
python scripts/db_cli.py scud --export-xlsx debug_today -- Выгрузить срез СКУД в форматированный Excel-файл
python scripts/db_cli.py snapshots -- Посмотреть список всех снапшотов с их ID (от новых к старым)
python scripts/db_cli.py snapshots 04.08.2026 -- Посмотреть снапшоты за конкретную дату
python scripts/db_cli.py stats -- Общая статистика строк по всем таблицам БД
python scripts/db_cli.py anomalies -- Посмотреть все найденные аномалии СКУД ⟷ 1С
python scripts/db_cli.py rules -- Посмотреть правила Базы Знаний ИИ из SQLite
python scripts/db_cli.py dump [output.xlsx] -- Полный дамп всех таблиц БД в многостраничный Excel
python scripts/db_cli.py stats
python scripts/db_cli.py snapshots 04.08.2026
python scripts/db_cli.py scud --snapshot Y20260805-007 --export-xlsx вчера_1
python scripts/db_cli.py snapshot del Y20260805-007
python scripts/db_cli.py snapshot del --day 04.08.2026
"""
parser = argparse.ArgumentParser(
description=help_text,
formatter_class=argparse.RawDescriptionHelpFormatter
formatter_class=argparse.RawDescriptionHelpFormatter,
add_help=True
)
parser.add_argument('command', nargs='?', default='stats', choices=['stats', 'snapshots', 'scud', 'anomalies', 'rules', 'dump'], help="Команда: stats | snapshots | scud | anomalies | rules | dump")
parser.add_argument('param', nargs='?', default=None, help="Параметр команды (дата в формате ДД.ММ.ГГГГ или имя файла)")
parser.add_argument('--snapshot', type=str, default=None, help="Выбрать конкретный ID снапшота для инспекции (например, '20260805-001', 'Y20260805-001')")
parser.add_argument('--export-xlsx', type=str, default=None, help="Экспортировать выбранный срез СКУД в Excel-файл")
parser.add_argument('command', nargs='?', default=None, choices=['stats', 'snapshots', 'scud', 'anomalies', 'rules', 'dump', 'snapshot'], help="Основная команда")
parser.add_argument('action', nargs='?', default=None, help="Дополнительное действие (например, 'del')")
parser.add_argument('param', nargs='?', default=None, help="Параметр (дата, ID снапшота или имя файла)")
parser.add_argument('--snapshot', type=str, default=None, help="ID конкретного снапшота для инспекции")
parser.add_argument('--export-xlsx', type=str, default=None, help="Экспорт среза СКУД в Excel-файл")
parser.add_argument('--day', type=str, default=None, help="Удалить снапшоты за конкретный день (ДД.ММ.ГГГГ)")
# Если аргументы вообще не переданы, выводим статистику по умолчанию (или справку)
if len(sys.argv) == 1:
print_stats()
return
args = parser.parse_args()
# Валидация команд
if args.command == 'stats':
print_stats()
elif args.command == 'snapshots':
@@ -206,7 +247,21 @@ CLI-утилита инспекции и управления SQLite базой
elif args.command == 'dump':
filename = args.param if args.param else "db_dump_full.xlsx"
dump_all_to_excel(filename)
elif args.command == 'snapshot':
if args.action == 'del':
if args.day:
delete_snapshots_by_date(args.day)
elif args.param:
delete_snapshot_by_id(args.param)
else:
print("\n[❌] Ошибка: Не указан ID снапшота или параметр --day для удаления.")
print("Пример: python scripts/db_cli.py snapshot del Y20260805-007\n")
else:
print(f"\n[❌] Ошибка: Неизвестное действие '{args.action}' для команды snapshot.")
print("Используйте: python scripts/db_cli.py snapshot del [ID или --day 'ДД.ММ.ГГГГ']\n")
else:
print(f"\n[❌] Ошибка: Неизвестная команда.")
parser.print_help()
if __name__ == "__main__":
main()