Files
rip-help-system/README.md
Sabo Sabev 9613420d1d Migrate to PostgreSQL + add FastAPI webapp for Coolify deploy
Backend migration:
- Replace pyodbc/SQL Server with psycopg2/PostgreSQL throughout
- Rewrite Database class with portable SQL: SERIAL, ON CONFLICT, NOW()
- Lowercase table names (rip_help_files, rip_help_sections) - Postgres convention
- libpq connection string format in HELP_DB_CONN

Webapp (webapp/):
- FastAPI app: GET /, GET /images/<f>, GET /home-image, GET /api/sections,
  POST /api/keywords/<code>, GET /healthz
- Jinja2 template extracted from generate_html.py with HTTP image URLs
- Direct keyword save to DB (no JSON download detour)
- Same prefix scoping as CLI tools (?prefix=RIP)

Deployment:
- Dockerfile (python:3.12-slim + uvicorn)
- docker-compose.yml for local dev
- requirements-webapp.txt (minimal, no Windows-only deps)
- .dockerignore excludes pipeline scripts and BAT files
- README updated with webapp section and Coolify deploy guide

Also: switch AI model to claude-haiku-4-5 (~3x cheaper, same quality for this task)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 17:00:44 +03:00

8.4 KiB
Raw Permalink Blame History

RIP Help System — Help-файл декомпозитор и viewer

Обработва help-файлове (.html, .htm, .docx, .doc, .pdf, .txt), декомпозира ги на секции, извлича картинки, класифицира секциите с Claude API (заглавие + ключови думи), и записва всичко в SQL Server. После генерира интерактивен HTML viewer.

Архитектура

Входни файлове  →  help_processor.py  →  SQL Server   →  generate_html.py  →  help_viewer.html
(.docx, .html,                          (RIP_help_*)                          (Home / Редактор /
 .pdf, .doc)                                                                   Търсене / Генератор)
                                              ↑
                                              │
                                       save_keywords.py  ←  keywords_changes.json
                                                          (от Редактора на viewer-а)

Инсталация

pip install -r requirements.txt

За стар .doc формат — едно от:

  • LibreOffice в PATH (кросплатформено)
  • MS Word (Windows, чрез pywin32 COM — автоматичен fallback)

Конфигурация

Копирай .env.example като .env и попълни:

ANTHROPIC_API_KEY=sk-ant-...
HELP_DB_CONN=DRIVER={ODBC Driver 18 for SQL Server};TrustServerCertificate=yes;SERVER=host,port;DATABASE=db;UID=user;PWD=password

.env е gitignore-нат. Bat файловете го зареждат автоматично през _load_env.bat.

Употреба (Windows)

Обработка на нов проект

Първо създай <PROJECT>_load.bat и <PROJECT>_view.bat (вж. RIP_load.bat, RIP_view.bat като образец).

BAT Какво прави
RIP_load.bat Incremental — обработва само нови/променени файлове по SHA-256 hash
RIP_load_force.bat --force --purge-missing — преобработва всичко, изтрива orphans
RIP_view.bat Генерира help_viewer.html за prefix=RIP и го отваря в браузъра

Директно от CLI

python help_processor.py --prefix=<PREFIX> <input_dir> <output_dir>
python help_processor.py --prefix=<PREFIX> --force --purge-missing <input_dir> <output_dir>

python generate_html.py --prefix=<PREFIX>                  # без Home таб
python generate_html.py --prefix=<PREFIX> --home img.png   # с Home таб

Prefix scoping

Всеки проект има свой --prefix (напр. RIP, INEX_TM). Прави следните неща изолирани между проектите:

  • Кодовете на секциите: RIP_0001_SEC_0001 vs INEX_TM_0001_SEC_0001
  • skip-by-hash (incremental) — само в рамките на prefix-а
  • --purge-missing — изтрива orphans само в текущия prefix
  • generate_html.py --prefix=X — viewer-а филтрира по prefix

Структура на базата

RIP_help_files

Поле Тип Описание
id INT IDENTITY PK
prefix NVARCHAR(50) Project scope
file_path NVARCHAR(1000) Пълен път до файла
file_hash CHAR(64) SHA-256 за incremental
processed_at DATETIME2 Последна обработка
section_count INT Брой секции

UNIQUE constraint: (prefix, file_path)

RIP_help_sections

Поле Тип Описание
id INT IDENTITY PK
prefix NVARCHAR(50) Project scope
code NVARCHAR(80) <PREFIX>_NNNN_SEC_NNNN (UNIQUE)
source_file NVARCHAR(1000) Източник
title NVARCHAR(500) AI-генерирано заглавие
keywords NVARCHAR(300) До 5 ключови думи
char_count INT Размер на чистия текст
output_path NVARCHAR(1000) Път до .txt файла
images NVARCHAR(MAX) JSON масив с относителни пътища
html_text NVARCHAR(MAX) Rich HTML с форматиране (само за .html източници)
created_at, updated_at DATETIME2

HTML Viewer — 3 / 4 таба

  • Home (опционален, ако --home <image> е подаден) — началов екран с изображение
  • Редактор — таблица със секции; inline редактиране на ключови думи; ✓ Save → JSON download → save_keywords.py → UPDATE в БД
  • Търсене — карти със секции; multi-keyword (intervals = AND, "phrase" = literal); preview с картинки
  • Генератор — drag & drop ordering → export като HTML (self-contained, всички картинки base64-embed-нати)

Картинки

Извличат се по време на парсване:

  • .docx<a:blip> в paragraph drawings → bytes от related_parts
  • .html — локални файлове и data: URLs; HTTP пропуска
  • .pdfpdfplumber.page.crop(bbox).to_image() като PNG
  • .doc — след LibreOffice/MS Word конверсия до .docx

Филтър ≥ 50×50 px (PIL детектва), за да отрязва иконки/булети.

Записват се в <output_dir>/images/<code>_img_NN.<ext>. В текста placeholder [IMG: images/...]. В DB images колоната съдържа JSON масив с пътищата.

Constants (в help_processor.py)

Константа Default Описание
MIN_SECTION_TOKENS 60 Под този праг секцията се слива с предишната
MAX_AI_CHARS 4000 Символи, пращани към Claude
AI_MODEL claude-haiku-4-5 Модел за класификация
MIN_IMAGE_PX 50 Картинки под NxN px се пропускат

Webapp (FastAPI)

webapp/ съдържа FastAPI app за server deploy (Coolify / Docker).

Endpoint-и

Метод Път Описание
GET / HTML viewer (Home/Editor/Search/Generator); query ?prefix=RIP&home=1
GET /images/<file> Сервира картинка от OUTPUT_DIR/images/
GET /home-image Home image (от HOME_IMAGE env var или Bairaci.png)
GET /api/sections JSON списък със секции; query ?prefix=
POST /api/keywords/<code> {keywords: "..."} → UPDATE в DB
GET /healthz Health check (DB ping)

Env vars

Var Default Описание
HELP_DB_CONN libpq формат за Postgres (задължително)
OUTPUT_DIR ./data Директория с images/ подпапка
HOME_IMAGE Абсолютен път към home картинка (опционален)

Локален dev

pip install -r requirements-webapp.txt
$env:HELP_DB_CONN="host=192.168.88.18 port=5432 dbname=rip_help_system user=sa password=..."
$env:OUTPUT_DIR="q:\RIP_Help_Source\Output"
python -m uvicorn webapp.main:app --reload
# отвори http://127.0.0.1:8000/?prefix=RIP&home=1

Coolify deploy

  1. В Coolify: New Resource → Application → Public/Private Repository
  2. URL: https://git.inex-project.net/sabo/rip-help-system.git
  3. Build pack: Dockerfile
  4. Environment variables (в Coolify UI, не в git):
    • HELP_DB_CONN=host=... port=5432 dbname=rip_help_system user=... password=...
    • OUTPUT_DIR=/data/help_output
    • HOME_IMAGE=/data/help_output/Bairaci.png (по избор)
  5. Persistent storage (volume): /data/help_output (там качваш картинките с WinSCP/rsync)
  6. Port: 8000
  7. Custom domain → Coolify прави HTTPS (Let's Encrypt) автоматично

Качване на картинки на сървъра

Локалният help_processor.py пише в q:\RIP_Help_Source\Output\ (включително images/ подпапка). За deploy:

# с WinSCP — sync на цялата директория
local:  q:\RIP_Help_Source\Output\
remote: /home/sabo/share/help_output/   ← Coolify volume mount

Базата (Postgres на 192.168.88.18) се ползва от webapp-а директно.