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>
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_0001vsINEX_TM_0001_SEC_0001 - skip-by-hash (incremental) — само в рамките на prefix-а
--purge-missing— изтрива orphans само в текущия prefixgenerate_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 пропуска.pdf—pdfplumber.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
- В Coolify: New Resource → Application → Public/Private Repository
- URL:
https://git.inex-project.net/sabo/rip-help-system.git - Build pack: Dockerfile
- Environment variables (в Coolify UI, не в git):
HELP_DB_CONN=host=... port=5432 dbname=rip_help_system user=... password=...OUTPUT_DIR=/data/help_outputHOME_IMAGE=/data/help_output/Bairaci.png(по избор)
- Persistent storage (volume):
/data/help_output(там качваш картинките с WinSCP/rsync) - Port: 8000
- 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-а директно.