- help_processor.py: parses .docx/.html/.pdf/.doc/.txt, extracts images, classifies sections via Claude API, writes to SQL Server - generate_html.py: builds interactive HTML viewer (Home/Editor/Search/Generator) - save_keywords.py: applies keyword edits back to DB - Prefix-scoped DB schema (RIP_help_files, RIP_help_sections) so multiple projects share the same database without collision - BAT launchers per project (RIP_load.bat, INEX_TM_load.bat, ...) load credentials from gitignored .env via _load_env.bat - Rich HTML preservation for .html sources (html_text column) - Image extraction for all formats with MS Word / LibreOffice fallback for .doc Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
125 lines
6.1 KiB
Markdown
125 lines
6.1 KiB
Markdown
# 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 пропуска
|
||
- `.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-sonnet-4-6 | Модел за класификация |
|
||
| `MIN_IMAGE_PX` | 50 | Картинки под NxN px се пропускат |
|