add WEB_PORT

This commit is contained in:
2026-04-17 14:20:43 +03:00
parent bb371e1b71
commit fe13a5e3a7
4 changed files with 331 additions and 109 deletions

420
README.md
View File

@@ -6,38 +6,56 @@
</p>
<!-- markdownlint-enable MD033 -->
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Rust](https://img.shields.io/badge/Rust-1.70%2B-orange.svg)](https://www.rust-lang.org/) [![Status](https://img.shields.io/badge/status-production-green.svg)](https://git.tvstart.ru/lexx/AE_Anons)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Rust](https://img.shields.io/badge/Rust-1.70%2B-orange.svg)](https://www.rust-lang.org/)
[![Status](https://img.shields.io/badge/status-production-green.svg)](https://git.tvstart.ru/lexx/AE_Anons)
Автоматизированная система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender, с данными из электронных таблиц Synology Office.
## Новое в версии 0.2.2
- **Веб-интерфейс**: Удобное управление заданиями через браузер
- **Мониторинг в реальном времени**: Отслеживание статуса всех заданий
- **Управление очередью**: Остановка, очистка и генерация заданий из веб-интерфейса
- **Тёмная/светлая тема**: Автоматическое определение системной темы
- **Сортировка и фильтрация**: Удобная работа с большим количеством заданий
## Обзор
AE Anons — это CLI-утилита на Rust, которая выступает как **интеллектуальный генератор заданий**
AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий**
для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга
After Effects (лицензия MIT).
1. Подключения к NAS Synology для получения данных расписания из файлов офисных таблиц (.osheet)
2. Парсинга Excel данных, содержащих информацию о спортивных событиях, командах, каналах и временных интервалах
3. Генерации заданий Nexrender с соответствующими шаблонами и ресурсами
4. Мониторинга завершения рендеринга и управления выходными файлами
### Режимы работы
1. **Однократная обработка** (`--once` или без флагов):
- Подключение к NAS Synology
- Парсинг Excel данных
- Генерация и отправка заданий Nexrender
- Мониторинг завершения и выход
2. **Веб-сервер** (`--web`):
- Запуск веб-интерфейса на порту `:3000`
- Управление заданиями через браузер
- Автообновление статуса каждую минуту
## Особенности
- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology
- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel
- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий для каждого анонса
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов на основе хэштегов `#` в имени команды
- **Оркестрация заданий Nexrender**: Автоматическая отправка, мониторинг и очистка заданий
- **Профессиональное логирование**: Структурированный журнал с возможностью настройки уровня детализации
- **Конфигурация через переменные окружения**: Все параметры управляются через файл `.env`
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов
- **Веб-интерфейс**: Удобное управление и мониторинг заданий
- **REST API**: Программный доступ к управлению заданиями
- **Профессиональное логирование**: Структурированный журнал с настройкой уровня
## Предварительные требования
- Rust 1.70 или выше
- Доступ к NAS Synology с установленными и включенными пакетами File Station и Office
- Доступ к NAS Synology с пакетами File Station и Office
- Экземпляр _server_ и _worker_(не менее одного) Nexrender
- Шаблоны After Effects, настроенные на _worker_ (формат Adobe After Effects 2024 .aepx)
- Шаблоны After Effects (формат Adobe After Effects 2024 .aepx)
## Установка
@@ -54,8 +72,6 @@ cd ae_anons
cargo build --release
```
Бинарный файл будет доступен по пути `target/release/ae_anons`
### 3. Настройка окружения
Скопируйте пример конфигурации и заполните своими данными:
@@ -66,35 +82,47 @@ cp .env.example .env
Затем отредактируйте файл .env:
```env
# Synology NAS
NAS_FQDN=https://your-nas.domain.com
NAS_USER=your_username
NAS_PASS=your_password
NAS_FILE=/team-folders/path/to/your/file.osheet
# Nexrender
NEXRENDER_API_URL=http://your-nexrender-server:3000/api/v1/jobs
OUTPUT_FOLDER=//your-storage/path/to/output
# Logging
RUST_LOG=info
```
См. раздел Конфигурация для подробной информации.
## Использование
### Базовое выполнение
### Однократная обработка
```bash
# Запуск с настройками по умолчанию
./target/release/ae_anons
# Запуск с пользовательским уровнем логирования
# Явно указать однократный режим
./target/release/ae_anons --once
# С отладочным логированием
RUST_LOG=debug ./target/release/ae_anons
```
### Веб-сервер
```bash
# Запуск веб-интерфейса на порту по умолчанию (3000)
./target/release/ae_anons --web
# Или с указанием другого порта через .env файл
# WEB_PORT=8080 ./target/release/ae_anons --web
# Сервер будет доступен по адресу http://localhost:3000 (или указанному порту)
## Веб-интерфейс
```
После запуска веб-сервера откройте браузер:
- Главная страница: <http://localhost:3000>
- API эндпоинты:
- `GET /api/jobs` - список всех заданий
- `POST /api/generate` - запуск генерации
- `POST /api/cleanup` - очистка завершённых
- `POST /api/jobs/stop-all` - остановка активных
- `GET /api/status` - статус сервера
## Уровни логирования
Управляйте детализацией вывода через переменную окружения `RUST_LOG`:
@@ -121,12 +149,13 @@ RUST_LOG=debug cargo run
| `NAS_FILE` | Да | Полный путь к файлу .osheet на NAS |
| `NEXRENDER_API_URL` | Да | Конечная точка API сервера Nexrender |
| `OUTPUT_FOLDER` | Да | Сетевой путь для рендеренных видео |
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
| `TEMPLATE_DOUBLE_SRC` | Да | Путь к AEP-шаблону для двух команд |
| `TEMPLATE_SINGLE_SRC` | Да | Путь к AEP-шаблону для одной команды |
| `TEMPLATE_COMPOSITION` | Да | Имя композиции в проекте AE (например, `main`) |
| `TEMPLATE_OUTPUT_MODULE`| Да | Имя модуля вывода в AE (например, `h264`) |
| `TEMPLATE_OUTPUT_EXT` | Да | Расширение выходного файла (например, `mp4`) |
| `WEB_PORT` | Нет | Порт для веб-сервера (по умолчанию: 3000) |
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
### Пример файла `.env`
@@ -137,9 +166,12 @@ NAS_USER="your_username"
NAS_PASS="your_password"
NAS_FILE="/Team Folder/path/to/file.osheet"
#Loging
# Logging
RUST_LOG="info"
# Web Server
WEB_PORT="3000"
# Nexrender
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
OUTPUT_FOLDER="/path/to/output"
@@ -183,7 +215,7 @@ TEMPLATE_OUTPUT_EXT="mp4"
Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков.
| CHANEL | LINK |
| CHANELL | LINK |
|---------|-----------------------------------------|
| КАНАЛ | \\server\share\path\to\channel_logo.png |
| TRIUMPH | \\server\share\path\to\triumph_logo.png |
@@ -192,14 +224,17 @@ TEMPLATE_OUTPUT_EXT="mp4"
Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах.
Обязательные колонки: DATA, TIME, CHANEL, SPORT, LEAGUE, TEAM A, TEAM B
Обязательные колонки: DATA, TIME, CHANELL, SPORT, LEAGUE, TEAM A, TEAM B
**Примечание**: Колонка LEAGUE обязательна для заполнения, но не имеет выпадающего списка. Проверка орфографии и опечаток отсутствует!
**Примечания:**
| STATE | TRIPPLE | DATA | TIME | SPORT | LEAGUE | CHANEL | TEAM A | TEAM B |
|--------|---------|-----------|-------|----------|---------------------------|---------|-----------------|-------------------|
| TRUE | TRUE | 27.2.2026 | 23:40 | Футбол | Чемпионат Португалии | START | Спортинг#ll#550 | Эшторил#ll#550 |
| FALSE | TRUE | 28.2.2026 | 12:55 | Волейбол | Чемпионат Турции. Женщины | TRIUMPH | Бешикташ | Галатасарай#Turki |
- Колонка LEAGUE обязательна для заполнения, но не имеет выпадающего списка. Проверка орфографии и опечаток отсутствует!
- Колонка DATA должна содержать дату в формате `ДД.ММ.ГГГГ` (например, `28.2.2026`).
| STATE | TRIPPLE | DATA | TIME | SPORT | LEAGUE | CHANELL | TEAM A | TEAM B |
|-------|---------|-----------|-------|---------|---------------------------|---------|-----------------|------------------|
| TRUE | TRUE | 27.2.2026 | 23:40 | Футбол | Чемпионат Португалии | START | Спортинг#ll#550 | Эшторил#ll#550 |
| FALSE | TRUE | 28.2.2026 | 12:55 | Волейбол| Чемпионат Турции. Женщины | TRIUMPH | Бешикташ | Галатасарай#Turki|
### Формат имен команд
@@ -233,7 +268,8 @@ TEMPLATE_OUTPUT_EXT="mp4"
YYYYMMDD_Sport_League_TeamA_TeamB_Channel[_Variant].mp4
```
Имена файлов транслитерируются в латиницу. Примеры:
Имена файлов транслитерируются в латиницу.
**Примеры:**
- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH.mp4`
- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Today.mp4`
@@ -253,35 +289,174 @@ YYYYMMDD_Sport_League_TeamA_TeamB_Channel[_Variant].mp4
## Требования к шаблонам After Effects
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоев:
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв.
### Типы шаблонов
### Файлы шаблонов
| Файл шаблона | Назначение |
|------------------------|---------------------------------|
| `PackShot_DOUBLE.aepx` | Сопоставление с двумя командами |
| `PackShot_SINGLE.aepx` | Анонсы для одной команды |
Настраиваются через переменные окружения:
### Обязательные слои
| Переменная | Назначение | Пример значения |
|-------------------------|-------------------------------------|------------------------------------|
| `TEMPLATE_DOUBLE_SRC` | Шаблон для матчей с двумя командами | `file:///path/to/double.aepx` |
| `TEMPLATE_SINGLE_SRC` | Шаблон для анонсов с одной командой | `file:///path/to/single.aepx` |
| `TEMPLATE_COMPOSITION` | Имя главной композиции | `main` |
| `TEMPLATE_OUTPUT_MODULE`| Имя модуля вывода | `h264` |
| `TEMPLATE_OUTPUT_EXT` | Расширение выходного файла | `mp4` |
| Имя слоя | Тип | Описание |
|------------------------|-------|-------------------------------------------------|
| DATA | Text | Отображение даты (автоматически подстраивается) |
| TIME / TIME_H / TIME_M | Text | Отображение времени |
| LEAGUE | Text | Название лиги |
| SPORT | Text | Категория спорта |
| TEAMS | Text | Скомбинированные имена команд |
| TEAM_A_LOGO | Image | Логотип домашней команды |
| TEAM_B_LOGO | Image | Логотип гостевой команды |
| CHANEL | Image | Логотип канала |
| TOP | Video | Наложение видео оформления |
### Обязательные слои в шаблонах
#### Текстовые слои
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|-----------|:-------------:|:-------------:|-------------------------------------------------|
| `DATA` | ✅ | ✅ | Отображение даты (автоматически подстраивается) |
| `TIME_H` | ✅ | ❌ | Часы (отдельный слой) |
| `TIME_M` | ✅ | ❌ | Минуты (отдельный слой) |
| `TIME` | ❌ | ✅ | Полное время (единый слой) |
| `LEAGUE` | ✅ | ✅ | Название лиги/турнира |
| `SPORT` | ✅ | ✅ | Категория спорта |
| `TEAMS` | ✅ | ✅ | Скомбинированные имена команд |
#### Слои с изображениями
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|----------------|:-------------:|:-------------:|-----------------------------|
| `TEAM_A_LOGO` | ✅ | ✅ | Логотип команды A |
| `TEAM_B_LOGO` | ✅ | ❌ | Логотип команды B |
| `CHANELL` | ✅ | ✅ | Логотип канала (две буквы L)|
#### Видео слои
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|-----------|:-------------:|:-------------:|----------------------------|
| `TOP` | ✅ | ✅ | Наложение видео оформления |
### Особенности шаблонов
#### Шаблон DOUBLE (две команды)
Используется когда в строке Excel заполнены оба поля `TEAM A` и `TEAM B`.
Обязательные слои:
- Все текстовые слои с `TIME_H` и `TIME_M` вместо `TIME`
- Оба логотипа команд: `TEAM_A_LOGO` и `TEAM_B_LOGO`
#### Шаблон SINGLE (одна команда)
Используется когда заполнено только одно поле команды.
Обязательные слои:
- Текстовый слой `TIME` вместо `TIME_H` и `TIME_M`
- Только логотип `TEAM_A_LOGO`
### Автоматические корректировки
AE Anons автоматически применяет следующие настройки к слоям:
#### Слой DATA
В зависимости от отображаемого текста и типа шаблона:
| Текст | Шаблон | Font Size | Anchor Point |
|------------|----------|-----------|--------------|
| "сегодня" | DOUBLE | 105 | [0, 5] |
| "завтра" | DOUBLE | 115 | [0, 25] |
| дата (<6) | DOUBLE | 120 | [0, 20] |
#### Слои TIME_H, TIME_M, TIME
Корректировка Anchor Point в зависимости от длины текста:
| Условие | Anchor Point |
|-------------------|--------------|
| 1 символ | [60, 0] |
| 2 символа, <20 | [20, 0] |
#### Слой LEAGUE
Если длина текста превышает 16 символов, размер шрифта уменьшается до 73.
#### Слой TEAMS
Если суммарная длина имён команд 32 символов, размер шрифта уменьшается до 55.
#### Логотипы (TEAM_A_LOGO, TEAM_B_LOGO)
Если в имени команды указан целевой размер через `#` (например, `Спортинг##550`), применяется выражение масштабирования:
```javascript
if (width > height) {
max_size = width;
} else {
max_size = height;
}
var real_size = 550 / max_size * 100;
[real_size, real_size]
```
### Пример структуры слоёв в After Effects
Ниже представлен рекомендуемый порядок слоёв в композиции. Порядок важен для правильного наложения элементов.
```text
📁 main (композиция)
├── 🎬 TOP (видео слой) # Видео-оверлей (обязательный)
├── 📝 TEAMS (текстовый слой) # Имена команд (обязательный)
├── 📝 LEAGUE (текстовый слой) # Название лиги (обязательный)
├── 📝 SPORT (текстовый слой) # Вид спорта (обязательный)
├── 📝 DATA (текстовый слой) # Дата (обязательный)
├── 📝 TIME (текстовый слой) # Время (только SINGLE)
├── 📝 TIME_H (текстовый слой) # Часы (только DOUBLE)
├── 📝 TIME_M (текстовый слой) # Минуты (только DOUBLE)
├── 🖼️ CHANELL (слой изображения) # Логотип канала (обязательный)
├── 🖼️ TEAM_A_LOGO (слой изображения) # Логотип команды A (обязательный)
├── 🖼️ TEAM_B_LOGO (слой изображения) # Логотип команды B (только DOUBLE)
└── 🖼️ BOTTOM (слой изображения) # Фоновый слой (опционально)
```
### Формат проекта и совместимость с After Effects
**Поддерживаемые форматы проектов:**
- `.aep` стандартный бинарный формат After Effects (рекомендуется)
- `.aepx` XML-формат проекта (поддерживается с AE CC 2015)
**Совместимость версий After Effects:**
| Версия After Effects | Поддерживаемые форматы | Особенности |
|----------------------|------------------------|-------------------------------------------------|
| CS 5.5 | `.aep` | Базовая поддержка |
| CC / CC 2014 | `.aep` | Полная поддержка |
| CC 2015 - CC 2019 | `.aep`, `.aepx` | Добавлена поддержка XML формата `.aepx` |
| CC 2020 - CC 2022 | `.aep`, `.aepx` | Рекомендуется использовать `.aep` |
| CC 2023 и новее | `.aep`, `.aepx` | **Требуется настройка Output Module** (см. ниже)|
> **⚠️ Важно для After Effects 2023+:**
>
> В версиях After Effects 2023 и новее критически важно настроить **Output Module** в шаблоне проекта. Бинарный файл рендеринга (`aerender`) не будет обрабатывать композицию без явно указанного модуля вывода, даже если в проекте используется модуль по умолчанию.
>
> AE Anons автоматически решает эту проблему, используя параметры `TEMPLATE_OUTPUT_MODULE` и `TEMPLATE_OUTPUT_EXT` из `.env` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона.
### Настройки композиции
- Имя композиции: `pack`
- Выходной модуль: `Start_h264`
- Формат вывода: `mp4`
- Формат проекта: Adobe After Effects 2024 .aepx
| Параметр | Переменная окружения | Пример значения | Описание |
|---------------------------|--------------------------|-----------------|---------------------------------------------|
| Имя композиции | `TEMPLATE_COMPOSITION` | `main` | Имя главной композиции в проекте AE |
| Выходной модуль | `TEMPLATE_OUTPUT_MODULE` | `h264` | Имя модуля вывода в AE |
| Расширение выходного файла| `TEMPLATE_OUTPUT_EXT` | `mp4` | Расширение выходного файла |
**Рекомендации по выбору формата:**
1. Используйте `.aep` для максимальной совместимости со всеми версиями AE
2. Версия After Effects на worker-машине должна быть не ниже версии, в которой создан проект
3. Для AE 2023+ убедитесь, что в шаблоне настроен Output Module с именем, указанным в `TEMPLATE_OUTPUT_MODULE`
**Источники:**
- [Nexrender - Tested with After Effects versions](https://github.com/inlife/nexrender#tested-with)
- [Adobe Aerender documentation](https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html)
## Устранение неисправностей
@@ -325,7 +500,6 @@ RUST_LOG=debug ./target/release/ae_anons
- **Большие таблицы**: Ограничение обработки до 10,000 строк на лист
- **Задержка сети**: Загрузка файлов с NAS может занимать время для больших файлов
- **Параллельные задания**: Nexrender управляет очередью заданий внутренне
- **Использование памяти**: Парсинг Excel сохраняет всю книгу в памяти
## Примечания по безопасности
@@ -340,45 +514,60 @@ RUST_LOG=debug ./target/release/ae_anons
```shell
ae_anons/
├── .gitignore
├── .env.example
├── Cargo.toml
├── LICENSE
├── README.md
├── .env.example
├── src/
│ ├── main.rs
├── config.rs
├── nexrender.rs
├── synology.rs
├── processor.rs
── web.rs
├── static/
── index.html
── style.css
└── assets/
└── logo.png
├── assets/
│ └── logo.png
└── src/
├── main.rs # Точка входа, CLI
├── config.rs # Конфигурация из .env
├── nexrender.rs # Модели заданий Nexrender
├── synology.rs # Клиент Synology API
── processor.rs # Логика обработки
├── web.rs # Веб-сервер и API
── static/
── index.html # Веб-интерфейс
└── style.css # Стили
```
## Зависимости
### Основные зависимости
| Crate | Версия | Назначение |
|--------------------|---------|-----------------------------------------|
| reqwest | 0.12 | HTTP клиент для коммуникации с API |
| serde / serde_json | 1.0 | Сериализация и десериализация JSON |
| calamine | 0.26 | Парсинг файлов Excel (.xlsx, .xls) |
| chrono | 0.4 | Обработка дат и времени |
| tokio | 1.0 | Асинхронная среда выполнения |
| dotenv | 0.15 | Загрузка конфигурации из .env файла |
| log / env_logger | 0.4/0.11| Система логирования с уровнями |
| thiserror | 2.0 | Эргономичные определения типов ошибок |
| anyhow | 1.0 | Упрощённая обработка ошибок |
| regex | 1.11 | Регулярные выражения |
| urlencoding | 2.1 | Кодирование URL для API запросов |
| bytes | 1.9 | Работа с байтовыми данными |
| futures | 0.3 | Асинхронные примитивы |
### Веб-сервер и CLI
| Crate | Версия | Назначение |
|--------------------|--------|-----------------------------------------|
| reqwest | 0.12 | HTTP клиент для коммуникации API |
| serde / serde_json | 1.0 | Сериализация JSON |
| calamine | 0.26 | Парсинг файлов Excel |
| chrono | 0.4 | Обработка дат и времени |
| tokio | 1.0 | Асинхронная среда выполнения |
| dotenv | 0.15 | Конфигурация через переменные окружения |
| log / env_logger | 0.11 | Инфраструктура логирования |
| thiserror | 2.0 | Определение типов ошибок |
| anyhow | 1.0 | Обработка ошибок |
| axum | 0.8 | Веб-фреймворк для REST API |
| tower | 0.5 | Промежуточное ПО для веб-сервера |
| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)|
| askama | 0.15 | Шаблонизация (опционально) |
| clap | 4.5 | Парсинг аргументов командной строки |
### Планируемые новые возможности
### Платформозависимые зависимости
1. Расширить `JobData` в `nexrender.rs` для новых полей данных
2. Обновить логику парсинга листов при необходимости добавления новых колонок
3. Добавить соответствующие слои After Effects в шаблоны
4. Обновите метод `to_nexrender_job()` с новыми сопоставлениями ресурсов
| Crate | Версия | Платформа | Назначение |
|--------------------|--------|-----------|----------------------------------|
| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)|
## 🙏 Благодарности
@@ -388,7 +577,7 @@ ae_anons/
## Лицензия
**AE Anons** — [MIT License](LICENSE)
**AE Anons** [License](LICENSE)
**Nexrender** [MIT License](https://github.com/inlife/nexrender/blob/master/LICENSE)
Обе лицензии MIT обеспечивают полную свободу использования и модификации кода.
@@ -413,20 +602,43 @@ ae_anons/
## История изменений
### v0.1.0
### v0.2.2 (текущая)
- Первый выпуск
- Интеграция с Synology Office
- Базовая генерация заданий Nexrender
- Парсинг Excel с динамическим обнаружением листов
- Создание множественных вариантов
- Автоматические настройки размера шрифта и позиции
- Умное масштабирование логотипов по целевому размеру
- Исправлено отображение имён выходных файлов в веб-интерфейсе
- Улучшена цветовая схема
- Добавлена сортировка по всем колонкам
- Вынесены стили в отдельный CSS файл
### v0.2.0
- Добавлен веб-интерфейс для управления заданиями
- Реализован REST API
- Добавлена поддержка тёмной/светлой темы
- Автообновление статуса заданий
- Возможность остановки всех активных заданий
### v0.1.1
- Оптимизированна работат с памятью
- Убрана функция создания `.json`
- Оптимизирована работа с памятью
- Убрана функция создания .json
### v0.1.0
- Первый выпуск
- Интеграция с Synology Office
- Базовая генерация заданий Nexrender
- Парсинг Excel с динамическим обнаружением листов
---