Files
XC_VM/docs/ru/info/watch_folder.md
T
Divarion-D 76844fef11 docs: restructure, fix PSR-4 drift, and unify en/ru
Overhaul the Docsify documentation (English + Russian) so it matches the current
codebase and follows one consistent pattern.

Content accuracy (post-migration):
- Rewrite development/autoloader.md to PSR-4 / Composer (the old XC_Autoloader
  scanner, igbinary tmp/cache/autoload_map and registerDirectories are gone).
- PascalCase every source path (src/core -> src/Core, domain/Stream, cli/Commands,
  public/Controllers, Infrastructure/Redis, ...) across all docs.
- Replace the removed autoload.php references with vendor/autoload.php
  (build_system, bootstrap-contexts, error-handling, modules).
- ssl-generation: note that the installer now auto-generates a unique self-signed
  certificate before Nginx starts.

Common pattern (Clean & uniform):
- Strip emoji from headings; remove the in-page Navigation blocks (the Docsify
  sidebar already provides navigation).
- One H1 + intro per doc; uniform "Related files" / "Связанные файлы" section,
  added to the code-centric docs that lacked it.

Structure:
- Remove the empty stray docs/api/; move updates_checklist.md into builds/;
  link the previously-orphaned ucs-integration.md.
- Regroup the sidebars (split the oversized guides group into Developer Guides /
  Security & Access / Integrations; fold builds into Build & Release).

Augment:
- dev-workflow: Local Setup (make dev-tools) + Quality Checks (phpstan, cs, gates).
- build_system: Composer Dependencies section (committed prod-only vendor,
  committed lock, dev tools via composer install, no build-time vendor step).

en/ru parity:
- Apply the same structure, fixes and pattern to docs/ru/ (translated), including
  a new Russian ucs-integration.md. The en and ru file sets are now identical.
2026-06-26 15:56:15 +03:00

220 lines
14 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.
# Watch Folder — Автоматический импорт медиа
Watch Folder — система автоматического импорта контента. Она мониторит локальные директории (или rclone-ремоуты) на наличие новых видеофайлов, парсит имена для извлечения метаданных (название, год, сезон, эпизод), запрашивает TMDB для получения обложек и описаний, и создаёт записи фильмов/сериалов в базе данных — без ручного вмешательства.
---
## Как это работает
```
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Watch Folder │────▶│ WatchCron │────▶│ WatchItem │
│ (директория │ │ сканирует новые │ │ парсит имя │
│ на диске / │ │ файлы, фильтрует │ │ запрашивает TMDB│
│ rclone) │ │ уже импортирован.│ │ создаёт запись │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Обновление │
│ букетов │
│ (авто-привязка) │
└──────────────────┘
```
### Пошагово
1. **Админ создаёт Watch Folder** в admin-панели (Watch Folder → Add) или через API (`create_watch_folder`). Конфигурация включает: путь к директории, тип контента (movie/series), целевую категорию, букеты, парсер и назначенный сервер.
2. **Крон `cron:watch`** запускается периодически (интервал контролируется `scan_offset` — секунды между сканами). Он выбирает из `watch_folders` активные папки, у которых `last_run` превысил offset.
3. **Обнаружение файлов** — крон использует `find` для локальных директорий или `rclone lsjson` для облачных/удалённых хранилищ. Файлы фильтруются по разрешённым расширениям (по умолчанию: `mp4, mkv, avi, mpg, flv, 3gp, m4v, wmv, mov, ts`). Файлы, уже присутствующие в `streams.stream_source`, пропускаются.
4. **Проверка стабильности** — файлы, изменённые менее 30 секунд назад, пропускаются (чтобы не импортировать частично загруженные файлы).
5. **Параллельная обработка** — каждый новый файл отправляется в команду `watch_item` (через `shell_exec`), до `thread_count` элементов запускается параллельно через `Multithread`.
6. **WatchItem** парсит имя файла с помощью PTN или guessit (см. документацию парсеров ниже), запрашивает метаданные через TMDB API и вставляет запись в `streams` (для фильмов) или `streams_series` + `streams_episodes` (для сериалов).
7. **Привязка к букетам** — импортированные элементы автоматически добавляются в заданные букеты.
---
## Конфигурация
### Настройки Watch Folder (для каждой папки)
| Настройка | Описание |
|-----------|----------|
| `directory` | Локальный путь для сканирования (напр., `/mnt/media/movies/`) |
| `rclone_dir` | Путь rclone-ремоута (альтернатива локальной директории) |
| `type` | Тип контента: `movie` или `series` |
| `server_id` | Сервер, на котором запускается сканирование |
| `category_id` | Целевая категория для импортированного контента |
| `bouquets` | Автоматическая привязка к этим букетам |
| `fb_category_id` | Фолбэк-категория (если маппинг жанров TMDB не сработает) |
| `fb_bouquets` | Фолбэк-букеты |
| `allowed_extensions` | Расширения файлов для сканирования (пусто = список по умолчанию) |
| `language` | Предпочитаемый язык TMDB для метаданных |
| `active` | Включить/выключить эту папку |
### Булевые опции
| Опция | Описание |
|-------|----------|
| `disable_tmdb` | Пропустить запрос к TMDB — импортировать только с parsed-названием |
| `ignore_no_match` | Импортировать, даже если TMDB не вернул результат |
| `auto_subtitles` | Автоматически обнаруживать `.srt`, `.sub`, `.sbv` рядом с видео |
| `fallback_title` | Использовать имя папки как название, если парсер не извлёк его |
| `read_native` | Читать оригинальное название из TMDB |
| `movie_symlink` | Создавать симлинки вместо ссылки на оригинальный путь |
| `auto_encode` | Автоматически перекодировать импортированный контент |
| `auto_upgrade` | Заменить существующую версию худшего качества при совпадении TMDB ID |
| `duplicate_tmdb` | Разрешить множественный импорт с одинаковым TMDB ID |
| `ffprobe_input` | Запустить ffprobe на файле для извлечения метаданных кодека |
| `extract_metadata` | Извлечь дополнительные метаданные из файла |
### Глобальные настройки
| Настройка | Где | Описание |
|-----------|-----|----------|
| `tmdb_api_key` | Админка → Настройки | **Обязательно** — ключ TMDB API. Без него Watch не запустится |
| `fallback_parser` | Админка → Настройки | Парсер, используемый при отказе основного |
| `alternative_titles` | Админка → Настройки | Искать альтернативные названия в TMDB |
| `max_genres` | Админка → Настройки | Максимум жанров для привязки к элементу |
---
## Админ-панель и API
### Страницы в админ-панели
| Страница | Описание |
|----------|----------|
| Watch Folder → List | Список всех настроенных папок со статусом |
| Watch Folder → Add | Создание/редактирование watch folder |
| Watch Folder → Settings | Глобальные настройки (парсер, TMDB) |
| Watch Folder → Logs | Просмотр логов сканирования и ошибок |
### API-действия
| Действие | Описание |
|----------|----------|
| `get_watch_folders` | Список всех watch folders |
| `get_watch_folder` | Получить папку по ID |
| `create_watch_folder` | Создать новую watch folder |
| `edit_watch_folder` | Обновить существующую |
| `delete_watch_folder` | Удалить watch folder |
| `reload_watch_folder` | Принудительное пересканирование |
| `enable_watch` | Включить все watch folders |
| `disable_watch` | Выключить все watch folders |
| `kill_watch` | Убить все запущенные watch-процессы |
### CLI
```bash
# Обычный запуск крона (обычно запускается автоматически)
sudo -u xc_vm /home/xc_vm/console.php cron:watch
# Принудительное сканирование конкретной папки (по ID)
sudo -u xc_vm /home/xc_vm/console.php cron:watch 5
```
---
## Парсеры
Доступны два парсера имён файлов. Парсер извлекает структурированные метаданные (название, год, сезон, эпизод, разрешение, кодек) из имени видеофайла.
### Выбор парсера
| Парсер | Лучше подходит для |
|--------|-------------------|
| **PTN** | Простые имена с пробелами: `San Andreas 2015 720p.mkv` |
| **guessit** | Имена с точками: `The.Matrix.1999.1080p.BluRay.mkv` |
Основной парсер задаётся для каждой watch folder. Глобальная настройка `fallback_parser` используется, когда основной парсер не находит совпадение.
---
## 1️⃣ PTN Parser
PTN parser поддерживает разбор файлов фильмов и сериалов с типичными именами.
### Фильмы
| Пример имени файла | Разбор |
|------------------|-------|
| `San Andreas 2015 720p WEB-DL x264 AAC-JYK.mkv` | Название: *San Andreas*, Год: 2015, Разрешение: 720p, Видео: x264, Аудио: AAC, Группа: JYK |
| `The Martian 2015 540p HDRip KORSUB x264 AAC2 0-FGT.mp4` | Название: *The Martian*, Год: 2015, Разрешение: 540p, Видео: x264, Аудио: AAC2.0, Группа: FGT |
### Сериалы
| Пример имени файла | Разбор |
|------------------|-------|
| `friends.s02e01.720p.bluray-sujaidr.mkv` | Название: *Friends*, Сезон: 2, Эпизод: 1, Разрешение: 720p, Формат: bluray, Группа: sujaidr |
| `Mr Robot S01E05 HDTV x264-KILLERS[ettv].mp4` | Название: *Mr Robot*, Сезон: 1, Эпизод: 5, Формат: HDTV, Видео: x264, Группа: KILLERS |
---
## 2️⃣ guessit Parser
Guessit поддерживает сложные форматы, включая точечные разделители и мультиязычные названия.
### Фильмы
| Пример имени файла | Разбор |
|------------------|-------|
| `The.Matrix.1999.1080p.BluRay.x264.DTS-FGT.mkv` | Название: *The Matrix*, Год: 1999, Разрешение: 1080p, Видео: x264, Аудио: DTS, Группа: FGT |
| `Inception.2010.720p.BRRip.x264.AAC-ETRG.mkv` | Название: *Inception*, Год: 2010, Разрешение: 720p, Видео: x264, Аудио: AAC, Группа: ETRG |
### Сериалы
| Пример имени файла | Разбор |
|------------------|-------|
| `Breaking.Bad.S03E07.720p.BluRay.x264-REWARD.mkv` | Название: *Breaking Bad*, Сезон: 3, Эпизод: 7, Разрешение: 720p, Видео: x264, Группа: REWARD |
| `Game.of.Thrones.S05E09.1080p.WEB-DL.DD5.1.H.264-NTb.mkv` | Название: *Game of Thrones*, Сезон: 5, Эпизод: 9, Разрешение: 1080p, Видео: H.264, Аудио: DD5.1, Группа: NTb |
---
### Fallback to Folder Name
Если имя файла не содержит название сериала, включите опцию **Fallback to Folder Name**:
| Пример пути | Разбор |
|-------------|-------|
| `/path/to/Show Name/S01E01 720p WEB-DL.mkv` | Название: *Show Name*, Сезон: 1, Эпизод: 1 |
| `/path/to/Show.Name/S01E01.720p.WEB-DL.mkv` | Название: *Show Name*, Сезон: 1, Эпизод: 1 |
#### Разделение по папкам с сезонами
Если нужно разложить эпизоды по папкам:
| Пример пути | Разбор |
|-------------|-------|
| `/path/to/Show Name/Season 01/Show Name S01E01 720p WEB-DL.mkv` | Название: *Show Name*, Сезон: 1, Эпизод: 1 |
| `/path/to/Show.Name/Season.01/Show.Name.S01E01.720p.WEB-DL.mkv` | Название: *Show Name*, Сезон: 1, Эпизод: 1 |
---
### RTL-языки
Для сериалов на RTL-языках:
- Имя файла **не должно содержать название сериала**
- Включите опцию **Fallback to Folder Name**
| Пример пути | Разбор |
|-------------|-------|
| `/path/to/Show Name/S01E01 (year).mp4` | Название: *Show Name*, Сезон: 1, Эпизод: 1, Год: `year` |
| `/path/to/Show Name/Season 01/S01E01 (year).mp4` | Название: *Season 01*, Сезон: 1, Эпизод: 1, Год: `year` |
> ⚠️ Важно: для RTL-языков название сериала берется только из имени папки.
---
### Резюме
- **PTN Parser** — простые имена файлов, локальные форматы
- **guessit Parser** — поддержка точечных разделителей, мультиязычных названий, Fallback к имени папки
- **RTL-языки** — обязательно использовать Fallback к имени папки
- **Разделение по сезонам** — название сериала должно присутствовать в имени файла
---
💡 **Совет:** используйте однородные имена файлов и папок для корректного парсинга и автоматической сортировки сериалов по сезонам.