Files
sber-med-wordpress/README.md
T
apuc 90d9576425 Версия 1.2.2: JSON-ошибки как на бэкенде, лимиты 100 МБ, овал-подсказка, безопасный парсинг ответов
- med_diag_json_error() — ошибки в формате {'error': '...'} (WP_REST_Response)
- 4 проверки лимита 100 МБ (CONTENT_LENGTH, UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, size)
- Проверка расширения файла (mp4/avi/mov/mkv/webm/m4v)
- Имя файла только ASCII (med-diag-upload.ext) — защита multipart
- filename скачивания из Content-Disposition бэкенда
- Овал .med-scan-oval (inset 12%, затемнение вне зоны)
- escapeHtml() + parseJson() — безопасная обработка ответов (XSS, HTML-ошибки)
- README: nginx лимиты, таблица ошибок
2026-09-18 11:16:40 +03:00

136 lines
9.0 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.
# Med Diagnostics — WordPress-плагин
Репозиторий: https://git.itguild.info/apuc/sber-med-wordpress
Интеграция сервиса «Диагностика по видео» (API-бэкенд med.my-dpr.ru) в WordPress.
Плагин выводит вёрстку сервиса (загрузка видео, сканирование с камеры, результат) прямо на странице сайта — без iframe.
## Установка
### Вариант 1: через админку (zip)
```bash
# из корня репозитория (папка репозитория = папка плагина)
zip -r med-diagnostics.zip . -x README.md
```
1. В админке WordPress: **Плагины → Добавить новый → Загрузить плагин** → выберите `med-diagnostics.zip` → **Установить** → **Активировать**.
### Вариант 2: копированием файлов
1. Скопируйте содержимое репозитория в `wp-content/plugins/med-diagnostics/` вашего WordPress.
2. В админке: **Плагины → Установленные** → активируйте **Med Diagnostics**.
### Использование
Вставьте шорткод в нужную страницу/запись:
```
[med_diagnostics]
```
Дополнительно можно задать заголовок:
```
[med_diagnostics title="Проверь своё здоровье"]
```
## Настройки
**Настройки → Med Diagnostics**:
| Поле | Описание |
|---|---|
| **Режим подключения** | `Через сервер (внутренний IP)` — браузер шлёт видео на этот WordPress, PHP проксирует запрос на внутренний IP бэкенда (по умолчанию, рекомендуется когда WordPress и API на одном сервере). `Напрямую из браузера (CORS)` — браузер обращается к публичному URL API. |
| **Внутренний URL бэкенда** | Адрес API, доступный с этого сервера (по умолчанию `http://127.0.0.1:18018`). Используется в режиме «Через сервер». |
| **Публичный URL API-бэкенда** | Публичный адрес Flask-приложения (по умолчанию `https://med.my-dpr.ru`). Используется в режиме «Напрямую» и для ссылки «Поделиться». |
Можно также переопределить кодом:
```php
add_filter('med_diag_api_url', fn() => 'https://другой-домен.ru');
add_filter('med_diag_internal_url', fn() => 'http://10.0.0.5:18018');
add_filter('med_diag_mode', fn() => 'direct');
```
## Как это работает
- **Режим «Через сервер» (по умолчанию)**: JS отправляет видео на REST-эндпоинт этого же WordPress (`/wp-json/med-diag/v1/analyze`), PHP пересылает его на внутренний IP бэкенда (`http://127.0.0.1:18018/analyze`). Скачивания PDF/DOCX/видео идут через `/wp-json/med-diag/v1/download/<id>/<type>`. CORS не нужен — все запросы same-origin.
- **Режим «Напрямую»**: JS отправляет видео на публичный URL API (`POST /analyze`) — тогда нужен CORS на стороне Flask.
- Результат (сводка, показатели, рекомендации, кнопки PDF/DOCX/видео/поделиться) рендерится на странице WordPress.
- Сканирование с камеры работает на мобильных (canvas 720×720 + MediaRecorder).
## Требования к серверу WordPress (режим «Через сервер»)
Видео сначала загружается в PHP, поэтому в `php.ini` должны быть подняты лимиты:
```ini
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300
```
Проверить текущие значения: `php -i | grep -E "upload_max_filesize|post_max_size|max_execution_time"`.
Если WordPress стоит за nginx, поднимите лимит и там — иначе nginx вернёт HTML-страницу `413 Request Entity Too Large`:
```nginx
client_max_body_size 100M;
client_body_timeout 300s;
proxy_read_timeout 300s;
```
## Обработка ошибок и лимитов
Серверная часть и плагин отдают ошибки **всегда в JSON** (`{"error": "..."}`), поэтому фронтенд никогда не получает HTML-страницу
вместо данных и не падает с `Unexpected token '<'` (аналог обработчиков `413/404/500` во Flask-бэкенде):
| Ситуация | Ответ | Сообщение |
|---|---|---|
| Файл больше 100 МБ (в т.ч. тело отброшено из-за `post_max_size`, `UPLOAD_ERR_INI_SIZE`) | `413` | «Видео слишком большое (максимум 100 МБ)» |
| Файл не передан | `400` | «Видео не загружено» |
| Формат не из списка `mp4/avi/mov/mkv/webm/m4v` | `400` | «Неподдерживаемый формат…» |
| Бэкенд недоступен | `502` | «Бэкенд недоступен: …» |
| Бэкенд вернул не JSON (HTML-страница ошибки nginx/Flask) | `502` | «Бэкенд вернул некорректный ответ (HTTP …)» |
| Ошибка анализа на бэкенде | статус бэкенда | текст бэкенда + `video_url` (ссылка «Скачать записанное видео») |
На стороне браузера ответ разбирается безопасно: если вместо JSON пришёл HTML, из него вырезаются теги и показывается короткое
текстовое сообщение (и оно экранируется перед вставкой в страницу).
## Требования к бэкенду (Flask)
В `app.py` серверного репозитория уже добавлена поддержка CORS (нужна только в режиме «Напрямую»):
- `Access-Control-Allow-Origin` — по умолчанию `*`, можно ограничить через env `CORS_ORIGINS` (список через запятую, например `https://site1.ru,https://site2.ru`).
- Preflight `OPTIONS /analyze` возвращает `204`.
Также во Flask добавлены обработчики ошибок `413/404/500`, всегда возвращающие JSON, и `try/except` вокруг сохранения видео —
поэтому и `POST /analyze`, и `/download/...` отдают ошибки в виде `{"error": "..."}`. Плагин ожидает такой же формат
(см. «Обработка ошибок и лимитов»), а на не-JSON (HTML) ответы реагирует безопасно.
## Локальное тестирование
1. Поднимите API-бэкенд локально (см. README серверного репозитория) или используйте прод `https://med.my-dpr.ru`.
2. Установите плагин в локальный WordPress (например, на `http://wp.loc` через Apache vhost).
3. Создайте страницу с шорткодом `[med_diagnostics]` и откройте её.
4. Проверьте в консоли браузера, что `MED_DIAG.apiUrl` указывает на нужный бэкенд, и что запрос `POST /analyze` проходит (CORS).
## Ограничения
- Шорткод используйте **один раз на странице** (id элементов фиксированы).
- Для работы сканирования с камеры нужен HTTPS на сайте WordPress (getUserMedia требует secure context).
- В режиме «Через сервер» видео загружается в PHP — следите за лимитами `upload_max_filesize`/`post_max_size`/`max_execution_time` (см. выше).
- Ссылка «Поделиться» всегда ведёт на публичный URL API (`/r/<share_id>`).
## Структура
Корень репозитория = папка плагина:
```
med-diagnostics/
├── med-diagnostics.php — главный файл плагина (шорткод, настройки, ассеты)
├── README.md — этот файл (в zip не попадает)
└── assets/
├── css/med-diag.css — стили сервиса (префикс med-)
└── js/med-diag.js — логика (fetch на API, сканирование, рендер результата)
```