Files
rip-help-system/README.md
2026-09-14 12:01:04 +03:00

223 lines
11 KiB
Markdown
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.
# 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` и `.docx`: bold/цветове/картинки) |
| 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 → `r:embed` (related_parts) или `r:link` (UNC/`file:///` + sidecar `<stem>_media/` до .docx)
- `.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
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: **`https://rip.inex-project.net`** → Coolify прави HTTPS (Let's Encrypt) автоматично
Live: [https://rip.inex-project.net/?prefix=RIP](https://rip.inex-project.net/?prefix=RIP) · health: [/healthz](https://rip.inex-project.net/healthz)
## Visual Studio и Git
Това е Python/Docker репо, не .NET. Въпреки това се отваря във Visual Studio (2022/2026) за текстовия редактор и за **Commit + Push** — същият ритъм като при C++/.NET.
`.sln` стои **до** `.git` (корен на репото). Така Git Changes вижда `origin` → `https://git.inex-project.net/sabo/rip-help-system.git`, клон `master`.
### Отваряне
- Двоен клик на `RIP_Help_system.sln`, или
- `open-in-vs.bat` в тази папка, или
- File → Open → Project/Solution → `C:\~ip\cursor_projects\RIP_Help_system\RIP_Help_system.sln`
Алтернатива без `.sln`: File → Open → Folder → същата папка (пак трябва да има `.git`).
Други проекти под `c:\~ip\cursor_projects\`: `C:\~ip\cursor_projects\open-in-vs.bat <име-на-папка>`. Ако няма `.sln`, VS отваря папката (Open Folder) и пак вижда Git.
### Еднократно във VS
1. **Tools → Options → Source Control → Plug-in Selection → Git** (не VisualSVN).
2. Не натискай **Create Git Repository** — репото вече съществува.
3. При Push VS ще поиска вход за **git.inex-project.net** (Gitea), не GitHub.
### Commit + Push (Git Changes)
1. View → Git Changes (или Git → Commit or Stash).
2. Отметни файловете (не `.env`).
3. Съобщение → **Commit All**.
4. **Push** към `origin/master`.
5. Redeploy в Coolify остава ръчно.
Нови файлове, които още не са в `.sln`, пак се виждат в Git Changes. При нужда ги добави като Solution Items или ползвай Open Folder.
### Сравнение с production (`/healthz`)
След Push + Coolify redeploy сравни `git` от [https://rip.inex-project.net/healthz](https://rip.inex-project.net/healthz) с локалното: Solution Explorer → **scripts** → десен клик `show-version.bat` → **Open Containing Folder** → двоен клик (прозорецът чака Enter). Префиксът (`0.3.0`) е във **VERSION** (Solution Explorer → **deploy**). Production вижда SHA едва след commit + push + redeploy.
### Качване на картинки на сървъра
Локалният `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-а директно.