diff --git a/.gitignore b/.gitignore index ed7232a..a1079ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .DS_Store *.xlsx *.txt -makefile # Файлы окружения .env diff --git a/Cargo.toml b/Cargo.toml index be64cec..c068a49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ name = "ae_anons" version = "0.2.3" edition = "2021" license = "MIT" -license-file = "LICENSE" authors = ["Alexey Barabanov "] description = "Automated Nexrender job generator from Synology Office spreadsheets" repository = "https://git.tvstart.ru/lexx/AE_Anons" diff --git a/ae_anons-v0.2.3-all.tar.gz b/ae_anons-v0.2.3-all.tar.gz new file mode 100644 index 0000000..8c1ac5c Binary files /dev/null and b/ae_anons-v0.2.3-all.tar.gz differ diff --git a/makefile b/makefile new file mode 100644 index 0000000..6f3e9ef --- /dev/null +++ b/makefile @@ -0,0 +1,250 @@ +.PHONY: all clean build-mac build-windows build-linux build-linux-musl package help quick package-single + +# Название проекта +PROJECT_NAME := ae_anons +RELEASE_DIR := target/release +BINARIES_DIR := releases +VERSION := $(shell grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') + +# Определение текущей ОС +UNAME_S := $(shell uname -s) +UNAME_M := $(shell uname -m) + +# Цвета для вывода +GREEN := \033[0;32m +RED := \033[0;31m +YELLOW := \033[1;33m +BLUE := \033[0;34m +CYAN := \033[0;36m +MAGENTA := \033[0;35m +BOLD := \033[1m +NC := \033[0m # No Color + +# Файл для хранения времени сборки +TIMING_FILE := .build_timing + +help: + @echo "$(BOLD)$(CYAN)AE Anons - Makefile команды$(NC)" + @echo "" + @echo "$(GREEN)Сборка под конкретную платформу:$(NC)" + @echo " make build-mac - Собрать для macOS (Apple Silicon)" + @echo " make build-windows - Собрать для Windows x86_64" + @echo " make build-linux - Собрать для Linux x86_64 (GNU)" + @echo " make build-linux-musl - Собрать для Linux x86_64 (musl static)" + @echo "" + @echo "$(GREEN)Быстрая сборка:$(NC)" + @echo " make quick - Собрать под текущую платформу с упаковкой" + @echo " make quick-release - Собрать под текущую платформу (release, без упаковки)" + @echo "" + @echo "$(GREEN)Полная сборка:$(NC)" + @echo " make build-all - Собрать для всех платформ" + @echo " make package - Создать пакеты для всех платформ" + @echo " make package-single - Создать пакет для текущей платформы" + @echo "" + @echo "$(GREEN)Очистка:$(NC)" + @echo " make clean - Очистить все сборки" + @echo " make clean-timing - Очистить файл с временами сборки" + +# ============================================ +# ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ +# ============================================ + +# Копирование общих файлов в пакет +define copy_common_files + @cp .env.example $(1)/ 2>/dev/null || true + @cp README.md $(1)/ 2>/dev/null || true + @if [ -f LICENSE ]; then cp LICENSE $(1)/; else echo "$(YELLOW)⚠️ LICENSE не найден, пропускаем$(NC)"; fi +endef + +# Функция для замера времени +define measure_time + @start=$$(date +%s); \ + $(2); \ + end=$$(date +%s); \ + duration=$$((end - start)); \ + echo "$(1): $$duration сек" >> $(TIMING_FILE); \ + echo "$(GREEN)✓ $(1) завершён за $$duration сек$(NC)" +endef + +# Функция для вывода итоговой таблицы +define print_timing_summary + @echo "" + @echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)" + @echo "$(BOLD)$(CYAN) ВРЕМЯ СБОРКИ $(NC)" + @echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)" + @if [ -f $(TIMING_FILE) ]; then \ + total=0; \ + while IFS=':' read -r platform duration; do \ + sec=$$(echo $$duration | sed 's/ сек//'); \ + total=$$((total + sec)); \ + printf "$(YELLOW)%-20s$(NC) : $(GREEN)%5d сек$(NC)\n" "$$platform" "$$sec"; \ + done < $(TIMING_FILE); \ + echo "$(BOLD)$(CYAN)───────────────────────────────────────────────────────────────$(NC)"; \ + printf "$(BOLD)$(MAGENTA)%-20s$(NC) : $(BOLD)$(GREEN)%5d сек$(NC) (%.2f мин)\n" "ВСЕГО" "$$total" "$$(echo "scale=2; $$total/60" | bc 2>/dev/null || echo "$$total/60" | awk '{printf "%.2f", $$1/60}')"; \ + else \ + echo "$(YELLOW)Нет данных о времени сборки$(NC)"; \ + fi + @echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)" + @rm -f $(TIMING_FILE) +endef + +# ============================================ +# ОПРЕДЕЛЕНИЕ ПЛАТФОРМЫ +# ============================================ + +detect-platform: +ifeq ($(UNAME_S),Darwin) + @echo "$(BLUE)🍎 macOS $(UNAME_M)$(NC)" + @$(MAKE) quick-mac +else ifeq ($(UNAME_S),Linux) + @echo "$(BLUE)🐧 Linux $(UNAME_M)$(NC)" + @$(MAKE) quick-linux +else ifeq ($(OS),Windows_NT) + @echo "$(BLUE)🪟 Windows$(NC)" + @$(MAKE) quick-windows +else + @echo "$(RED)❌ Неизвестная платформа: $(UNAME_S)$(NC)" + @exit 1 +endif + +# ============================================ +# БЫСТРАЯ СБОРКА (ТЕКУЩАЯ ПЛАТФОРМА) +# ============================================ + +quick: detect-platform + +# Быстрая сборка без упаковки (только бинарник) +quick-release: +ifeq ($(UNAME_S),Darwin) + @echo "$(GREEN)🍎 Сборка для macOS...$(NC)" + @time cargo build --release +else ifeq ($(UNAME_S),Linux) + @echo "$(GREEN)🐧 Сборка для Linux (musl)...$(NC)" + @time cargo build --target x86_64-unknown-linux-musl --release +else ifeq ($(OS),Windows_NT) + @echo "$(GREEN)🪟 Сборка для Windows...$(NC)" + @time cargo build --release +else + @echo "$(RED)❌ Неизвестная платформа$(NC)" + @exit 1 +endif + +quick-mac: + @rm -f $(TIMING_FILE) + @$(call measure_time,"🍎 macOS $(UNAME_M)",cargo build --release) + @mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M) + @cp $(RELEASE_DIR)/$(PROJECT_NAME) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)/ + $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)) + @echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)/$(NC)" + @$(call print_timing_summary) + +quick-linux: + @rm -f $(TIMING_FILE) + @$(call measure_time,"🐧 Linux $(UNAME_M)",cargo build --target x86_64-unknown-linux-musl --release) + @mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M) + @cp target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/ + $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)) + @echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/$(NC)" + @$(call print_timing_summary) + +quick-windows: + @rm -f $(TIMING_FILE) + @if command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1; then \ + $(call measure_time,"🪟 Windows x64",cargo build --target x86_64-pc-windows-gnu --release); \ + mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64; \ + cp target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64/; \ + $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64); \ + echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64/$(NC)"; \ + $(call print_timing_summary); \ + else \ + echo "$(RED)❌ Для кросс-компиляции Windows установите mingw-w64:$(NC)"; \ + echo " brew install mingw-w64"; \ + exit 1; \ + fi + +# ============================================ +# СБОРКА ПОД КОНКРЕТНЫЕ ПЛАТФОРМЫ +# ============================================ + +build-mac: + @echo "$(GREEN)🍎 Сборка для macOS...$(NC)" + @time cargo build --release + +build-windows: + @echo "$(GREEN)🪟 Сборка для Windows x86_64...$(NC)" + @time cargo build --target x86_64-pc-windows-gnu --release + +build-linux: + @echo "$(GREEN)🐧 Сборка для Linux x86_64 (GNU)...$(NC)" + @time cargo build --target x86_64-unknown-linux-gnu --release + +build-linux-musl: + @echo "$(GREEN)🐧 Сборка для Linux x86_64 (musl static)...$(NC)" + @time cargo build --target x86_64-unknown-linux-musl --release + +# ============================================ +# СБОРКА ВСЕХ ПЛАТФОРМ С ТАЙМИНГОМ +# ============================================ + +build-all: + @rm -f $(TIMING_FILE) + @echo "$(BOLD)$(CYAN)🚀 Сборка для всех платформ...$(NC)" + @echo "" + @$(call measure_time,"🍎 macOS",cargo build --release) + @echo "" + @$(call measure_time,"🐧 Linux GNU",cargo build --target x86_64-unknown-linux-gnu --release) + @echo "" + @$(call measure_time,"🐧 Linux Musl",cargo build --target x86_64-unknown-linux-musl --release) + @echo "" + @-$(call measure_time,"🪟 Windows",cargo build --target x86_64-pc-windows-gnu --release) + @echo "" + @$(call print_timing_summary) + +# ============================================ +# УПАКОВКА РЕЛИЗОВ +# ============================================ + +define create_release_package + @echo "$(YELLOW)📦 Упаковка для $(1)...$(NC)" + @mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1) + @cp $(2) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1)/$(3) 2>/dev/null || true + $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1)) + @echo "$(GREEN) ✓ $(PROJECT_NAME)-v$(VERSION)-$(1)$(NC)" +endef + +package: build-all + @echo "" + @echo "$(BOLD)$(CYAN)📦 Создание пакетов...$(NC)" + @mkdir -p $(BINARIES_DIR) + + @$(call create_release_package,macos-arm64,$(RELEASE_DIR)/$(PROJECT_NAME),$(PROJECT_NAME)) + @$(call create_release_package,windows-x64,target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe,$(PROJECT_NAME).exe) + @$(call create_release_package,linux-gnu,target/x86_64-unknown-linux-gnu/release/$(PROJECT_NAME),$(PROJECT_NAME)) + @$(call create_release_package,linux-musl,target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME),$(PROJECT_NAME)) + + @echo "" + @echo "$(GREEN)🗜️ Создание общего архива...$(NC)" + @tar -czf $(PROJECT_NAME)-v$(VERSION)-all.tar.gz -C $(BINARIES_DIR) . + @echo "$(GREEN)✅ Архив: $(PROJECT_NAME)-v$(VERSION)-all.tar.gz$(NC)" + @echo "" + @echo "$(BOLD)$(GREEN)🎉 Релиз v$(VERSION) готов!$(NC)" + @echo "$(BOLD)📁 Папка: $(BINARIES_DIR)/$(NC)" + @ls -lh $(BINARIES_DIR)/ | grep "^d" + +package-single: detect-platform + +# ============================================ +# ОЧИСТКА +# ============================================ + +clean: + @echo "$(RED)🧹 Очистка...$(NC)" + cargo clean + @rm -rf $(BINARIES_DIR) + @rm -f *.tar.gz + @rm -f $(TIMING_FILE) + @echo "$(GREEN)✅ Очищено$(NC)" + +clean-timing: + @rm -f $(TIMING_FILE) + @echo "$(GREEN)✅ Файл с временами сборки удалён$(NC)" \ No newline at end of file diff --git a/releases/ae_anons-v0.2.3-linux-gnu/.env.example b/releases/ae_anons-v0.2.3-linux-gnu/.env.example new file mode 100644 index 0000000..34e2330 --- /dev/null +++ b/releases/ae_anons-v0.2.3-linux-gnu/.env.example @@ -0,0 +1,22 @@ +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# Logging (optional, defaults to info) +RUST_LOG="info" + +# Web Server (optional, defaults to 3000) +WEB_PORT="3000" + +# Nexrender +NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs" +OUTPUT_FOLDER="/path/to/output" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" \ No newline at end of file diff --git a/releases/ae_anons-v0.2.3-linux-gnu/LICENSE b/releases/ae_anons-v0.2.3-linux-gnu/LICENSE new file mode 100644 index 0000000..f6da942 --- /dev/null +++ b/releases/ae_anons-v0.2.3-linux-gnu/LICENSE @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2026 [Your Name or Company] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/releases/ae_anons-v0.2.3-linux-gnu/README.md b/releases/ae_anons-v0.2.3-linux-gnu/README.md new file mode 100644 index 0000000..df2d69b --- /dev/null +++ b/releases/ae_anons-v0.2.3-linux-gnu/README.md @@ -0,0 +1,656 @@ +# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects + + +

+ AE Anons Logo +

+ + +[![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.3 + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Тёмная/светлая тема с автоопределением ОС +- Сортировка по всем колонкам +- Фильтрация по имени файла/UID +- Остановка всех активных заданий +- Автообновление каждые 60 секунд +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +## Обзор + +AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий** +для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга +After Effects (лицензия MIT). + +### Режимы работы + +1. **Однократная обработка** (`--once` или без флагов): + - Подключение к NAS Synology + - Парсинг Excel данных + - Генерация и отправка заданий Nexrender + - Мониторинг завершения и выход + +2. **Веб-сервер** (`--web`): + - Запуск веб-интерфейса на порту `:3000` + - Управление заданиями через браузер + - Автообновление статуса каждую минуту + +## Особенности + +- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology +- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel +- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков +- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий +- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов +- **Веб-интерфейс**: Удобное управление и мониторинг заданий +- **REST API**: Программный доступ к управлению заданиями +- **Профессиональное логирование**: Структурированный журнал с настройкой уровня + +## Предварительные требования + +- Rust 1.70 или выше +- Доступ к NAS Synology с пакетами File Station и Office +- Экземпляр _server_ и _worker_(не менее одного) Nexrender +- Шаблоны After Effects (формат Adobe After Effects 2024 .aepx) + +## Установка + +### 1. Клонирование репозитория + +```bash +git clone https://git.tvstart.ru/lexx/AE_Anons.git +cd ae_anons +``` + +### 2. Сборка проекта + +```bash +cargo build --release +``` + +### 3. Настройка окружения + +Скопируйте пример конфигурации и заполните своими данными: + +```bash +cp .env.example .env +``` + +Затем отредактируйте файл .env: + +См. раздел Конфигурация для подробной информации. + +## Использование + +### Однократная обработка + +```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 + +``` + +## Веб-интерфейс + +После запуска веб-сервера откройте браузер: + +- Главная страница: + +- API эндпоинты: + - `GET /api/jobs` - список всех заданий + - `POST /api/generate` - запуск генерации + - `POST /api/cleanup` - очистка завершённых + - `POST /api/jobs/stop-all` - остановка активных + - `GET /api/status` - статус сервера + +## Уровни логирования + +Управляйте детализацией вывода через переменную окружения `RUST_LOG`: + +- **error** - Только критические ошибки +- **warn** - Предупреждения и ошибки +- **info** - Общие операционные сообщения (по умолчанию) +- **debug** - Детальная информация о процессе обработки +- **trace** - Полное отладочное логирование с деталями API вызовов + +```bash +RUST_LOG=debug cargo run +``` + +## Конфигурация + +### Переменные окружения + +| Переменная | Обязательна | Описание | +|-------------------------|-------------|------------------------------------------------------| +| `NAS_FQDN` | Да | URL NAS Synology с протоколом и портом | +| `NAS_USER` | Да | Имя пользователя учетной записи Synology | +| `NAS_PASS` | Да | Пароль учетной записи Synology | +| `NAS_FILE` | Да | Полный путь к файлу .osheet на NAS | +| `NEXRENDER_API_URL` | Да | Конечная точка API сервера Nexrender | +| `OUTPUT_FOLDER` | Да | Сетевой путь для рендеренных видео | +| `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` + +```env +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# 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" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" +``` + +## Структура электронной таблицы + +Файл Excel должен содержать следующие листы со специфичными структурами: + +### Лист "SPORT" + +Связывает названия видов спорта с соответствующими видео пакетами. + +| SPORT | LINK | +|----------------|---------------------------------------------| +| Без оформления | \\server\share\path\to\null.mov | +| Футбол | \\server\share\path\to\football_pack.mov | +| Волейбол | \\server\share\path\to\volleyball_pack.mov | + +### Лист "TEAMS" + +Сопоставляет имена команд с их видами спорта и логотипами. Колонка SPORT заполняется из выпадающего списка (заполнена из листа SPORT). + +Если несколько команд в одном виде спорта имеют одинаковые названия, но разные логотипы, используется разделитель хеш # для уникальной идентификации. + +| TEAM | SPORT | LINK | +|-------------------|-----------|---------------------------------------------------| +| Галатасарай#Turki | Футбол | \\server\share\path\to\galatasaray_football.png | +| Галатасарай | Волейбол | \\server\share\path\to\galatasaray_volleyball.png | +| Галатасарай#UCL | Волейбол | \\server\share\path\to\galatasaray_ucl.png | +| Сомбатей##400 | Футбол | \\server\share\path\to\szombathely.png | + +### Лист "CHANELL" + +Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков. + +| CHANELL | LINK | +|---------|-----------------------------------------| +| КАНАЛ | \\server\share\path\to\channel_logo.png | +| TRIUMPH | \\server\share\path\to\triumph_logo.png | + +### Лист "Start" + +Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах. + +Обязательные колонки: DATA, TIME, CHANELL, SPORT, LEAGUE, TEAM A, TEAM B + +**Примечания:** + +- Колонка 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| + +### Формат имен команд + +Имена команд поддерживают два типа разделителей хэш #: + +1. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта. +Примеры: + +- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта +- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта + +1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа + +Формат: `DisplayName#UniqueID#TargetSize` + +Примеры: + +- `Галатасарай#Turki` - только уникальный идентификатор +- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш) +- `Спортинг#ll#550` - оба идентификатор и целевой размер + +**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером. + +## Выходные файлы + +### Рендеренные видео + +Рендерные видео сохраняются в `OUTPUT_FOLDER` по следующему шаблону именования: + +```shell +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` +- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Tomorrow.mp4` + +## Рабочий процесс + +1. **Аутентификация**: Подключение к NAS Synology с использованием предоставленных учетных данных +2. **Получение файла**: Поиск и экспорт указанного файла .osheet в Excel +3. **Парсинг данных**: Чтение всех листов и структурирование данных +4. **Разрешение ресурсов**: Сопоставление видов спорта, команд и каналов с визуальными элементами +5. **Генерация заданий**: Создание заданий Nexrender для каждой активной строки с вариантами +6. **Очистка**: Удаление завершенных/неудачных заданий из предыдущих запусков +7. **Отправка**: Отправка заданий на API Nexrender +8. **Мониторинг**: Слежение за прогрессом выполнения до завершения +9. **Завершение сеанса**: Закрытие сессии Synology + +## Требования к шаблонам After Effects + +Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв. + +### Файлы шаблонов + +Настраиваются через переменные окружения: + +| Переменная | Назначение | Пример значения | +|-------------------------|-------------------------------------|------------------------------------| +| `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` | + +### Обязательные слои в шаблонах + +#### Текстовые слои + +| Имя слоя | Шаблон 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` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона. + +### Настройки композиции + +| Параметр | Переменная окружения | Пример значения | Описание | +|---------------------------|--------------------------|-----------------|---------------------------------------------| +| Имя композиции | `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) + +## Устранение неисправностей + +### Частые проблемы + +#### Ошибка подключения к NAS + +- Проверьте, что `NAS_FQDN` включает протокол и порт (например, `https://nas.example.com:5001`) +- Проверьте сетевую связность с NAS +- Убедитесь, что сервисы File Station и Office включены + +#### Файл не найден + +- Убедитесь, что путь в `NAS_FILE` точно соответствует пути в Synology Drive +- Путь должен начинаться с `/Team Folder/` для рабочих папок +- Проверьте права доступа к файлу для учетной записи сервиса + +#### Ошибка отправки задания Nexrender + +- Подтвердите доступность сервера Nexrender +- Убедитесь, что `NEXRENDER_API_URL` правильный +- Проверьте существование файлов шаблонов на узлах рендеринга + +### Режим отладки + +Включите подробное логирование для детального анализа: + +```bash +RUST_LOG=debug ./target/release/ae_anons +``` + +Это выведет: + +- Детали API запросов/ответов +- Информацию о парсинге листов +- Детали создания заданий +- Процесс разрешения ресурсов + +## Возможные ограничения по производительности + +- **Большие таблицы**: Ограничение обработки до 10,000 строк на лист +- **Задержка сети**: Загрузка файлов с NAS может занимать время для больших файлов +- **Параллельные задания**: Nexrender управляет очередью заданий внутренне + +## Примечания по безопасности + +- Храните учетные данные только в файле `.env` (исключен из git) +- Используйте специальные аккаунты с минимально необходимыми правами +- Сессии Synology завершаются после выполнения +- HTTPS рекомендуется для подключений NAS в продакшене + +## Разработка + +### Структура кода + +```shell +ae_anons/ +├── .gitignore +├── .env.example +├── Cargo.toml +├── LICENSE +├── README.md +├── 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 | Версия | Назначение | +|--------------------|--------|-----------------------------------------| +| axum | 0.8 | Веб-фреймворк для REST API | +| tower | 0.5 | Промежуточное ПО для веб-сервера | +| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)| +| askama | 0.15 | Шаблонизация (опционально) | +| clap | 4.5 | Парсинг аргументов командной строки | + +### Платформозависимые зависимости + +| Crate | Версия | Платформа | Назначение | +|--------------------|--------|-----------|----------------------------------| +| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)| + +## 🙏 Благодарности + +Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)** +([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы +для автоматизации After Effects. + +## Лицензия + +**AE Anons** — [License](LICENSE) +**Nexrender** — [MIT License](https://github.com/inlife/nexrender/blob/master/LICENSE) + +Обе лицензии MIT обеспечивают полную свободу использования и модификации кода. + +**Разрешается:** + +- ✅ Использовать в коммерческих целях +- ✅ Изменять исходный код +- ✅ Распространять копии +- ✅ Использовать приватно + +**Требуется:** + +- Сохранять копирайт и текст лицензии + +## Поддержка + +Для вопросов и запросов функций обращайтесь: + +- +- [README.md](https://git.tvstart.ru/lexx/AE_Anons) + +## История изменений + +### v0.2.3 (текущая) + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +### v0.2.2 + +- Исправлено отображение имён выходных файлов в веб-интерфейсе + +- Улучшена цветовая схема + +- Добавлена сортировка по всем колонкам + +- Вынесены стили в отдельный CSS файл + +### v0.2.0 + +- Добавлен веб-интерфейс для управления заданиями + +- Реализован REST API + +- Добавлена поддержка тёмной/светлой темы + +- Автообновление статуса заданий + +- Возможность остановки всех активных заданий + +### v0.1.1 + +- Оптимизирована работа с памятью + +- Убрана функция создания .json + +### v0.1.0 + +- Первый выпуск + +- Интеграция с Synology Office + +- Базовая генерация заданий Nexrender + +- Парсинг Excel с динамическим обнаружением листов + +--- + +Made with 🦀 Rust and ☕ coffee diff --git a/releases/ae_anons-v0.2.3-linux-gnu/ae_anons b/releases/ae_anons-v0.2.3-linux-gnu/ae_anons new file mode 100755 index 0000000..90931e6 Binary files /dev/null and b/releases/ae_anons-v0.2.3-linux-gnu/ae_anons differ diff --git a/releases/ae_anons-v0.2.3-linux-musl/.env.example b/releases/ae_anons-v0.2.3-linux-musl/.env.example new file mode 100644 index 0000000..34e2330 --- /dev/null +++ b/releases/ae_anons-v0.2.3-linux-musl/.env.example @@ -0,0 +1,22 @@ +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# Logging (optional, defaults to info) +RUST_LOG="info" + +# Web Server (optional, defaults to 3000) +WEB_PORT="3000" + +# Nexrender +NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs" +OUTPUT_FOLDER="/path/to/output" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" \ No newline at end of file diff --git a/releases/ae_anons-v0.2.3-linux-musl/LICENSE b/releases/ae_anons-v0.2.3-linux-musl/LICENSE new file mode 100644 index 0000000..f6da942 --- /dev/null +++ b/releases/ae_anons-v0.2.3-linux-musl/LICENSE @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2026 [Your Name or Company] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/releases/ae_anons-v0.2.3-linux-musl/README.md b/releases/ae_anons-v0.2.3-linux-musl/README.md new file mode 100644 index 0000000..df2d69b --- /dev/null +++ b/releases/ae_anons-v0.2.3-linux-musl/README.md @@ -0,0 +1,656 @@ +# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects + + +

+ AE Anons Logo +

+ + +[![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.3 + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Тёмная/светлая тема с автоопределением ОС +- Сортировка по всем колонкам +- Фильтрация по имени файла/UID +- Остановка всех активных заданий +- Автообновление каждые 60 секунд +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +## Обзор + +AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий** +для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга +After Effects (лицензия MIT). + +### Режимы работы + +1. **Однократная обработка** (`--once` или без флагов): + - Подключение к NAS Synology + - Парсинг Excel данных + - Генерация и отправка заданий Nexrender + - Мониторинг завершения и выход + +2. **Веб-сервер** (`--web`): + - Запуск веб-интерфейса на порту `:3000` + - Управление заданиями через браузер + - Автообновление статуса каждую минуту + +## Особенности + +- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology +- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel +- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков +- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий +- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов +- **Веб-интерфейс**: Удобное управление и мониторинг заданий +- **REST API**: Программный доступ к управлению заданиями +- **Профессиональное логирование**: Структурированный журнал с настройкой уровня + +## Предварительные требования + +- Rust 1.70 или выше +- Доступ к NAS Synology с пакетами File Station и Office +- Экземпляр _server_ и _worker_(не менее одного) Nexrender +- Шаблоны After Effects (формат Adobe After Effects 2024 .aepx) + +## Установка + +### 1. Клонирование репозитория + +```bash +git clone https://git.tvstart.ru/lexx/AE_Anons.git +cd ae_anons +``` + +### 2. Сборка проекта + +```bash +cargo build --release +``` + +### 3. Настройка окружения + +Скопируйте пример конфигурации и заполните своими данными: + +```bash +cp .env.example .env +``` + +Затем отредактируйте файл .env: + +См. раздел Конфигурация для подробной информации. + +## Использование + +### Однократная обработка + +```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 + +``` + +## Веб-интерфейс + +После запуска веб-сервера откройте браузер: + +- Главная страница: + +- API эндпоинты: + - `GET /api/jobs` - список всех заданий + - `POST /api/generate` - запуск генерации + - `POST /api/cleanup` - очистка завершённых + - `POST /api/jobs/stop-all` - остановка активных + - `GET /api/status` - статус сервера + +## Уровни логирования + +Управляйте детализацией вывода через переменную окружения `RUST_LOG`: + +- **error** - Только критические ошибки +- **warn** - Предупреждения и ошибки +- **info** - Общие операционные сообщения (по умолчанию) +- **debug** - Детальная информация о процессе обработки +- **trace** - Полное отладочное логирование с деталями API вызовов + +```bash +RUST_LOG=debug cargo run +``` + +## Конфигурация + +### Переменные окружения + +| Переменная | Обязательна | Описание | +|-------------------------|-------------|------------------------------------------------------| +| `NAS_FQDN` | Да | URL NAS Synology с протоколом и портом | +| `NAS_USER` | Да | Имя пользователя учетной записи Synology | +| `NAS_PASS` | Да | Пароль учетной записи Synology | +| `NAS_FILE` | Да | Полный путь к файлу .osheet на NAS | +| `NEXRENDER_API_URL` | Да | Конечная точка API сервера Nexrender | +| `OUTPUT_FOLDER` | Да | Сетевой путь для рендеренных видео | +| `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` + +```env +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# 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" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" +``` + +## Структура электронной таблицы + +Файл Excel должен содержать следующие листы со специфичными структурами: + +### Лист "SPORT" + +Связывает названия видов спорта с соответствующими видео пакетами. + +| SPORT | LINK | +|----------------|---------------------------------------------| +| Без оформления | \\server\share\path\to\null.mov | +| Футбол | \\server\share\path\to\football_pack.mov | +| Волейбол | \\server\share\path\to\volleyball_pack.mov | + +### Лист "TEAMS" + +Сопоставляет имена команд с их видами спорта и логотипами. Колонка SPORT заполняется из выпадающего списка (заполнена из листа SPORT). + +Если несколько команд в одном виде спорта имеют одинаковые названия, но разные логотипы, используется разделитель хеш # для уникальной идентификации. + +| TEAM | SPORT | LINK | +|-------------------|-----------|---------------------------------------------------| +| Галатасарай#Turki | Футбол | \\server\share\path\to\galatasaray_football.png | +| Галатасарай | Волейбол | \\server\share\path\to\galatasaray_volleyball.png | +| Галатасарай#UCL | Волейбол | \\server\share\path\to\galatasaray_ucl.png | +| Сомбатей##400 | Футбол | \\server\share\path\to\szombathely.png | + +### Лист "CHANELL" + +Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков. + +| CHANELL | LINK | +|---------|-----------------------------------------| +| КАНАЛ | \\server\share\path\to\channel_logo.png | +| TRIUMPH | \\server\share\path\to\triumph_logo.png | + +### Лист "Start" + +Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах. + +Обязательные колонки: DATA, TIME, CHANELL, SPORT, LEAGUE, TEAM A, TEAM B + +**Примечания:** + +- Колонка 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| + +### Формат имен команд + +Имена команд поддерживают два типа разделителей хэш #: + +1. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта. +Примеры: + +- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта +- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта + +1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа + +Формат: `DisplayName#UniqueID#TargetSize` + +Примеры: + +- `Галатасарай#Turki` - только уникальный идентификатор +- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш) +- `Спортинг#ll#550` - оба идентификатор и целевой размер + +**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером. + +## Выходные файлы + +### Рендеренные видео + +Рендерные видео сохраняются в `OUTPUT_FOLDER` по следующему шаблону именования: + +```shell +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` +- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Tomorrow.mp4` + +## Рабочий процесс + +1. **Аутентификация**: Подключение к NAS Synology с использованием предоставленных учетных данных +2. **Получение файла**: Поиск и экспорт указанного файла .osheet в Excel +3. **Парсинг данных**: Чтение всех листов и структурирование данных +4. **Разрешение ресурсов**: Сопоставление видов спорта, команд и каналов с визуальными элементами +5. **Генерация заданий**: Создание заданий Nexrender для каждой активной строки с вариантами +6. **Очистка**: Удаление завершенных/неудачных заданий из предыдущих запусков +7. **Отправка**: Отправка заданий на API Nexrender +8. **Мониторинг**: Слежение за прогрессом выполнения до завершения +9. **Завершение сеанса**: Закрытие сессии Synology + +## Требования к шаблонам After Effects + +Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв. + +### Файлы шаблонов + +Настраиваются через переменные окружения: + +| Переменная | Назначение | Пример значения | +|-------------------------|-------------------------------------|------------------------------------| +| `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` | + +### Обязательные слои в шаблонах + +#### Текстовые слои + +| Имя слоя | Шаблон 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` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона. + +### Настройки композиции + +| Параметр | Переменная окружения | Пример значения | Описание | +|---------------------------|--------------------------|-----------------|---------------------------------------------| +| Имя композиции | `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) + +## Устранение неисправностей + +### Частые проблемы + +#### Ошибка подключения к NAS + +- Проверьте, что `NAS_FQDN` включает протокол и порт (например, `https://nas.example.com:5001`) +- Проверьте сетевую связность с NAS +- Убедитесь, что сервисы File Station и Office включены + +#### Файл не найден + +- Убедитесь, что путь в `NAS_FILE` точно соответствует пути в Synology Drive +- Путь должен начинаться с `/Team Folder/` для рабочих папок +- Проверьте права доступа к файлу для учетной записи сервиса + +#### Ошибка отправки задания Nexrender + +- Подтвердите доступность сервера Nexrender +- Убедитесь, что `NEXRENDER_API_URL` правильный +- Проверьте существование файлов шаблонов на узлах рендеринга + +### Режим отладки + +Включите подробное логирование для детального анализа: + +```bash +RUST_LOG=debug ./target/release/ae_anons +``` + +Это выведет: + +- Детали API запросов/ответов +- Информацию о парсинге листов +- Детали создания заданий +- Процесс разрешения ресурсов + +## Возможные ограничения по производительности + +- **Большие таблицы**: Ограничение обработки до 10,000 строк на лист +- **Задержка сети**: Загрузка файлов с NAS может занимать время для больших файлов +- **Параллельные задания**: Nexrender управляет очередью заданий внутренне + +## Примечания по безопасности + +- Храните учетные данные только в файле `.env` (исключен из git) +- Используйте специальные аккаунты с минимально необходимыми правами +- Сессии Synology завершаются после выполнения +- HTTPS рекомендуется для подключений NAS в продакшене + +## Разработка + +### Структура кода + +```shell +ae_anons/ +├── .gitignore +├── .env.example +├── Cargo.toml +├── LICENSE +├── README.md +├── 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 | Версия | Назначение | +|--------------------|--------|-----------------------------------------| +| axum | 0.8 | Веб-фреймворк для REST API | +| tower | 0.5 | Промежуточное ПО для веб-сервера | +| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)| +| askama | 0.15 | Шаблонизация (опционально) | +| clap | 4.5 | Парсинг аргументов командной строки | + +### Платформозависимые зависимости + +| Crate | Версия | Платформа | Назначение | +|--------------------|--------|-----------|----------------------------------| +| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)| + +## 🙏 Благодарности + +Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)** +([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы +для автоматизации After Effects. + +## Лицензия + +**AE Anons** — [License](LICENSE) +**Nexrender** — [MIT License](https://github.com/inlife/nexrender/blob/master/LICENSE) + +Обе лицензии MIT обеспечивают полную свободу использования и модификации кода. + +**Разрешается:** + +- ✅ Использовать в коммерческих целях +- ✅ Изменять исходный код +- ✅ Распространять копии +- ✅ Использовать приватно + +**Требуется:** + +- Сохранять копирайт и текст лицензии + +## Поддержка + +Для вопросов и запросов функций обращайтесь: + +- +- [README.md](https://git.tvstart.ru/lexx/AE_Anons) + +## История изменений + +### v0.2.3 (текущая) + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +### v0.2.2 + +- Исправлено отображение имён выходных файлов в веб-интерфейсе + +- Улучшена цветовая схема + +- Добавлена сортировка по всем колонкам + +- Вынесены стили в отдельный CSS файл + +### v0.2.0 + +- Добавлен веб-интерфейс для управления заданиями + +- Реализован REST API + +- Добавлена поддержка тёмной/светлой темы + +- Автообновление статуса заданий + +- Возможность остановки всех активных заданий + +### v0.1.1 + +- Оптимизирована работа с памятью + +- Убрана функция создания .json + +### v0.1.0 + +- Первый выпуск + +- Интеграция с Synology Office + +- Базовая генерация заданий Nexrender + +- Парсинг Excel с динамическим обнаружением листов + +--- + +Made with 🦀 Rust and ☕ coffee diff --git a/releases/ae_anons-v0.2.3-linux-musl/ae_anons b/releases/ae_anons-v0.2.3-linux-musl/ae_anons new file mode 100755 index 0000000..f06aa7d Binary files /dev/null and b/releases/ae_anons-v0.2.3-linux-musl/ae_anons differ diff --git a/releases/ae_anons-v0.2.3-macos-arm64/.env.example b/releases/ae_anons-v0.2.3-macos-arm64/.env.example new file mode 100644 index 0000000..34e2330 --- /dev/null +++ b/releases/ae_anons-v0.2.3-macos-arm64/.env.example @@ -0,0 +1,22 @@ +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# Logging (optional, defaults to info) +RUST_LOG="info" + +# Web Server (optional, defaults to 3000) +WEB_PORT="3000" + +# Nexrender +NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs" +OUTPUT_FOLDER="/path/to/output" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" \ No newline at end of file diff --git a/releases/ae_anons-v0.2.3-macos-arm64/LICENSE b/releases/ae_anons-v0.2.3-macos-arm64/LICENSE new file mode 100644 index 0000000..f6da942 --- /dev/null +++ b/releases/ae_anons-v0.2.3-macos-arm64/LICENSE @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2026 [Your Name or Company] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/releases/ae_anons-v0.2.3-macos-arm64/README.md b/releases/ae_anons-v0.2.3-macos-arm64/README.md new file mode 100644 index 0000000..df2d69b --- /dev/null +++ b/releases/ae_anons-v0.2.3-macos-arm64/README.md @@ -0,0 +1,656 @@ +# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects + + +

+ AE Anons Logo +

+ + +[![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.3 + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Тёмная/светлая тема с автоопределением ОС +- Сортировка по всем колонкам +- Фильтрация по имени файла/UID +- Остановка всех активных заданий +- Автообновление каждые 60 секунд +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +## Обзор + +AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий** +для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга +After Effects (лицензия MIT). + +### Режимы работы + +1. **Однократная обработка** (`--once` или без флагов): + - Подключение к NAS Synology + - Парсинг Excel данных + - Генерация и отправка заданий Nexrender + - Мониторинг завершения и выход + +2. **Веб-сервер** (`--web`): + - Запуск веб-интерфейса на порту `:3000` + - Управление заданиями через браузер + - Автообновление статуса каждую минуту + +## Особенности + +- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology +- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel +- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков +- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий +- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов +- **Веб-интерфейс**: Удобное управление и мониторинг заданий +- **REST API**: Программный доступ к управлению заданиями +- **Профессиональное логирование**: Структурированный журнал с настройкой уровня + +## Предварительные требования + +- Rust 1.70 или выше +- Доступ к NAS Synology с пакетами File Station и Office +- Экземпляр _server_ и _worker_(не менее одного) Nexrender +- Шаблоны After Effects (формат Adobe After Effects 2024 .aepx) + +## Установка + +### 1. Клонирование репозитория + +```bash +git clone https://git.tvstart.ru/lexx/AE_Anons.git +cd ae_anons +``` + +### 2. Сборка проекта + +```bash +cargo build --release +``` + +### 3. Настройка окружения + +Скопируйте пример конфигурации и заполните своими данными: + +```bash +cp .env.example .env +``` + +Затем отредактируйте файл .env: + +См. раздел Конфигурация для подробной информации. + +## Использование + +### Однократная обработка + +```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 + +``` + +## Веб-интерфейс + +После запуска веб-сервера откройте браузер: + +- Главная страница: + +- API эндпоинты: + - `GET /api/jobs` - список всех заданий + - `POST /api/generate` - запуск генерации + - `POST /api/cleanup` - очистка завершённых + - `POST /api/jobs/stop-all` - остановка активных + - `GET /api/status` - статус сервера + +## Уровни логирования + +Управляйте детализацией вывода через переменную окружения `RUST_LOG`: + +- **error** - Только критические ошибки +- **warn** - Предупреждения и ошибки +- **info** - Общие операционные сообщения (по умолчанию) +- **debug** - Детальная информация о процессе обработки +- **trace** - Полное отладочное логирование с деталями API вызовов + +```bash +RUST_LOG=debug cargo run +``` + +## Конфигурация + +### Переменные окружения + +| Переменная | Обязательна | Описание | +|-------------------------|-------------|------------------------------------------------------| +| `NAS_FQDN` | Да | URL NAS Synology с протоколом и портом | +| `NAS_USER` | Да | Имя пользователя учетной записи Synology | +| `NAS_PASS` | Да | Пароль учетной записи Synology | +| `NAS_FILE` | Да | Полный путь к файлу .osheet на NAS | +| `NEXRENDER_API_URL` | Да | Конечная точка API сервера Nexrender | +| `OUTPUT_FOLDER` | Да | Сетевой путь для рендеренных видео | +| `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` + +```env +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# 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" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" +``` + +## Структура электронной таблицы + +Файл Excel должен содержать следующие листы со специфичными структурами: + +### Лист "SPORT" + +Связывает названия видов спорта с соответствующими видео пакетами. + +| SPORT | LINK | +|----------------|---------------------------------------------| +| Без оформления | \\server\share\path\to\null.mov | +| Футбол | \\server\share\path\to\football_pack.mov | +| Волейбол | \\server\share\path\to\volleyball_pack.mov | + +### Лист "TEAMS" + +Сопоставляет имена команд с их видами спорта и логотипами. Колонка SPORT заполняется из выпадающего списка (заполнена из листа SPORT). + +Если несколько команд в одном виде спорта имеют одинаковые названия, но разные логотипы, используется разделитель хеш # для уникальной идентификации. + +| TEAM | SPORT | LINK | +|-------------------|-----------|---------------------------------------------------| +| Галатасарай#Turki | Футбол | \\server\share\path\to\galatasaray_football.png | +| Галатасарай | Волейбол | \\server\share\path\to\galatasaray_volleyball.png | +| Галатасарай#UCL | Волейбол | \\server\share\path\to\galatasaray_ucl.png | +| Сомбатей##400 | Футбол | \\server\share\path\to\szombathely.png | + +### Лист "CHANELL" + +Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков. + +| CHANELL | LINK | +|---------|-----------------------------------------| +| КАНАЛ | \\server\share\path\to\channel_logo.png | +| TRIUMPH | \\server\share\path\to\triumph_logo.png | + +### Лист "Start" + +Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах. + +Обязательные колонки: DATA, TIME, CHANELL, SPORT, LEAGUE, TEAM A, TEAM B + +**Примечания:** + +- Колонка 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| + +### Формат имен команд + +Имена команд поддерживают два типа разделителей хэш #: + +1. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта. +Примеры: + +- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта +- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта + +1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа + +Формат: `DisplayName#UniqueID#TargetSize` + +Примеры: + +- `Галатасарай#Turki` - только уникальный идентификатор +- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш) +- `Спортинг#ll#550` - оба идентификатор и целевой размер + +**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером. + +## Выходные файлы + +### Рендеренные видео + +Рендерные видео сохраняются в `OUTPUT_FOLDER` по следующему шаблону именования: + +```shell +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` +- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Tomorrow.mp4` + +## Рабочий процесс + +1. **Аутентификация**: Подключение к NAS Synology с использованием предоставленных учетных данных +2. **Получение файла**: Поиск и экспорт указанного файла .osheet в Excel +3. **Парсинг данных**: Чтение всех листов и структурирование данных +4. **Разрешение ресурсов**: Сопоставление видов спорта, команд и каналов с визуальными элементами +5. **Генерация заданий**: Создание заданий Nexrender для каждой активной строки с вариантами +6. **Очистка**: Удаление завершенных/неудачных заданий из предыдущих запусков +7. **Отправка**: Отправка заданий на API Nexrender +8. **Мониторинг**: Слежение за прогрессом выполнения до завершения +9. **Завершение сеанса**: Закрытие сессии Synology + +## Требования к шаблонам After Effects + +Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв. + +### Файлы шаблонов + +Настраиваются через переменные окружения: + +| Переменная | Назначение | Пример значения | +|-------------------------|-------------------------------------|------------------------------------| +| `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` | + +### Обязательные слои в шаблонах + +#### Текстовые слои + +| Имя слоя | Шаблон 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` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона. + +### Настройки композиции + +| Параметр | Переменная окружения | Пример значения | Описание | +|---------------------------|--------------------------|-----------------|---------------------------------------------| +| Имя композиции | `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) + +## Устранение неисправностей + +### Частые проблемы + +#### Ошибка подключения к NAS + +- Проверьте, что `NAS_FQDN` включает протокол и порт (например, `https://nas.example.com:5001`) +- Проверьте сетевую связность с NAS +- Убедитесь, что сервисы File Station и Office включены + +#### Файл не найден + +- Убедитесь, что путь в `NAS_FILE` точно соответствует пути в Synology Drive +- Путь должен начинаться с `/Team Folder/` для рабочих папок +- Проверьте права доступа к файлу для учетной записи сервиса + +#### Ошибка отправки задания Nexrender + +- Подтвердите доступность сервера Nexrender +- Убедитесь, что `NEXRENDER_API_URL` правильный +- Проверьте существование файлов шаблонов на узлах рендеринга + +### Режим отладки + +Включите подробное логирование для детального анализа: + +```bash +RUST_LOG=debug ./target/release/ae_anons +``` + +Это выведет: + +- Детали API запросов/ответов +- Информацию о парсинге листов +- Детали создания заданий +- Процесс разрешения ресурсов + +## Возможные ограничения по производительности + +- **Большие таблицы**: Ограничение обработки до 10,000 строк на лист +- **Задержка сети**: Загрузка файлов с NAS может занимать время для больших файлов +- **Параллельные задания**: Nexrender управляет очередью заданий внутренне + +## Примечания по безопасности + +- Храните учетные данные только в файле `.env` (исключен из git) +- Используйте специальные аккаунты с минимально необходимыми правами +- Сессии Synology завершаются после выполнения +- HTTPS рекомендуется для подключений NAS в продакшене + +## Разработка + +### Структура кода + +```shell +ae_anons/ +├── .gitignore +├── .env.example +├── Cargo.toml +├── LICENSE +├── README.md +├── 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 | Версия | Назначение | +|--------------------|--------|-----------------------------------------| +| axum | 0.8 | Веб-фреймворк для REST API | +| tower | 0.5 | Промежуточное ПО для веб-сервера | +| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)| +| askama | 0.15 | Шаблонизация (опционально) | +| clap | 4.5 | Парсинг аргументов командной строки | + +### Платформозависимые зависимости + +| Crate | Версия | Платформа | Назначение | +|--------------------|--------|-----------|----------------------------------| +| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)| + +## 🙏 Благодарности + +Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)** +([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы +для автоматизации After Effects. + +## Лицензия + +**AE Anons** — [License](LICENSE) +**Nexrender** — [MIT License](https://github.com/inlife/nexrender/blob/master/LICENSE) + +Обе лицензии MIT обеспечивают полную свободу использования и модификации кода. + +**Разрешается:** + +- ✅ Использовать в коммерческих целях +- ✅ Изменять исходный код +- ✅ Распространять копии +- ✅ Использовать приватно + +**Требуется:** + +- Сохранять копирайт и текст лицензии + +## Поддержка + +Для вопросов и запросов функций обращайтесь: + +- +- [README.md](https://git.tvstart.ru/lexx/AE_Anons) + +## История изменений + +### v0.2.3 (текущая) + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +### v0.2.2 + +- Исправлено отображение имён выходных файлов в веб-интерфейсе + +- Улучшена цветовая схема + +- Добавлена сортировка по всем колонкам + +- Вынесены стили в отдельный CSS файл + +### v0.2.0 + +- Добавлен веб-интерфейс для управления заданиями + +- Реализован REST API + +- Добавлена поддержка тёмной/светлой темы + +- Автообновление статуса заданий + +- Возможность остановки всех активных заданий + +### v0.1.1 + +- Оптимизирована работа с памятью + +- Убрана функция создания .json + +### v0.1.0 + +- Первый выпуск + +- Интеграция с Synology Office + +- Базовая генерация заданий Nexrender + +- Парсинг Excel с динамическим обнаружением листов + +--- + +Made with 🦀 Rust and ☕ coffee diff --git a/releases/ae_anons-v0.2.3-macos-arm64/ae_anons b/releases/ae_anons-v0.2.3-macos-arm64/ae_anons new file mode 100755 index 0000000..ed0f18c Binary files /dev/null and b/releases/ae_anons-v0.2.3-macos-arm64/ae_anons differ diff --git a/releases/ae_anons-v0.2.3-windows-x64/.env.example b/releases/ae_anons-v0.2.3-windows-x64/.env.example new file mode 100644 index 0000000..34e2330 --- /dev/null +++ b/releases/ae_anons-v0.2.3-windows-x64/.env.example @@ -0,0 +1,22 @@ +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# Logging (optional, defaults to info) +RUST_LOG="info" + +# Web Server (optional, defaults to 3000) +WEB_PORT="3000" + +# Nexrender +NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs" +OUTPUT_FOLDER="/path/to/output" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" \ No newline at end of file diff --git a/releases/ae_anons-v0.2.3-windows-x64/LICENSE b/releases/ae_anons-v0.2.3-windows-x64/LICENSE new file mode 100644 index 0000000..f6da942 --- /dev/null +++ b/releases/ae_anons-v0.2.3-windows-x64/LICENSE @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2026 [Your Name or Company] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/releases/ae_anons-v0.2.3-windows-x64/README.md b/releases/ae_anons-v0.2.3-windows-x64/README.md new file mode 100644 index 0000000..df2d69b --- /dev/null +++ b/releases/ae_anons-v0.2.3-windows-x64/README.md @@ -0,0 +1,656 @@ +# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects + + +

+ AE Anons Logo +

+ + +[![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.3 + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Тёмная/светлая тема с автоопределением ОС +- Сортировка по всем колонкам +- Фильтрация по имени файла/UID +- Остановка всех активных заданий +- Автообновление каждые 60 секунд +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +## Обзор + +AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий** +для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга +After Effects (лицензия MIT). + +### Режимы работы + +1. **Однократная обработка** (`--once` или без флагов): + - Подключение к NAS Synology + - Парсинг Excel данных + - Генерация и отправка заданий Nexrender + - Мониторинг завершения и выход + +2. **Веб-сервер** (`--web`): + - Запуск веб-интерфейса на порту `:3000` + - Управление заданиями через браузер + - Автообновление статуса каждую минуту + +## Особенности + +- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology +- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel +- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков +- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий +- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов +- **Веб-интерфейс**: Удобное управление и мониторинг заданий +- **REST API**: Программный доступ к управлению заданиями +- **Профессиональное логирование**: Структурированный журнал с настройкой уровня + +## Предварительные требования + +- Rust 1.70 или выше +- Доступ к NAS Synology с пакетами File Station и Office +- Экземпляр _server_ и _worker_(не менее одного) Nexrender +- Шаблоны After Effects (формат Adobe After Effects 2024 .aepx) + +## Установка + +### 1. Клонирование репозитория + +```bash +git clone https://git.tvstart.ru/lexx/AE_Anons.git +cd ae_anons +``` + +### 2. Сборка проекта + +```bash +cargo build --release +``` + +### 3. Настройка окружения + +Скопируйте пример конфигурации и заполните своими данными: + +```bash +cp .env.example .env +``` + +Затем отредактируйте файл .env: + +См. раздел Конфигурация для подробной информации. + +## Использование + +### Однократная обработка + +```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 + +``` + +## Веб-интерфейс + +После запуска веб-сервера откройте браузер: + +- Главная страница: + +- API эндпоинты: + - `GET /api/jobs` - список всех заданий + - `POST /api/generate` - запуск генерации + - `POST /api/cleanup` - очистка завершённых + - `POST /api/jobs/stop-all` - остановка активных + - `GET /api/status` - статус сервера + +## Уровни логирования + +Управляйте детализацией вывода через переменную окружения `RUST_LOG`: + +- **error** - Только критические ошибки +- **warn** - Предупреждения и ошибки +- **info** - Общие операционные сообщения (по умолчанию) +- **debug** - Детальная информация о процессе обработки +- **trace** - Полное отладочное логирование с деталями API вызовов + +```bash +RUST_LOG=debug cargo run +``` + +## Конфигурация + +### Переменные окружения + +| Переменная | Обязательна | Описание | +|-------------------------|-------------|------------------------------------------------------| +| `NAS_FQDN` | Да | URL NAS Synology с протоколом и портом | +| `NAS_USER` | Да | Имя пользователя учетной записи Synology | +| `NAS_PASS` | Да | Пароль учетной записи Synology | +| `NAS_FILE` | Да | Полный путь к файлу .osheet на NAS | +| `NEXRENDER_API_URL` | Да | Конечная точка API сервера Nexrender | +| `OUTPUT_FOLDER` | Да | Сетевой путь для рендеренных видео | +| `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` + +```env +# Synology NAS +NAS_FQDN="https://your-nas.example.com" +NAS_USER="your_username" +NAS_PASS="your_password" +NAS_FILE="/Team Folder/path/to/file.osheet" + +# 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" + +# After Effects Templates +TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx" +TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx" +TEMPLATE_COMPOSITION="main" +TEMPLATE_OUTPUT_MODULE="h264" +TEMPLATE_OUTPUT_EXT="mp4" +``` + +## Структура электронной таблицы + +Файл Excel должен содержать следующие листы со специфичными структурами: + +### Лист "SPORT" + +Связывает названия видов спорта с соответствующими видео пакетами. + +| SPORT | LINK | +|----------------|---------------------------------------------| +| Без оформления | \\server\share\path\to\null.mov | +| Футбол | \\server\share\path\to\football_pack.mov | +| Волейбол | \\server\share\path\to\volleyball_pack.mov | + +### Лист "TEAMS" + +Сопоставляет имена команд с их видами спорта и логотипами. Колонка SPORT заполняется из выпадающего списка (заполнена из листа SPORT). + +Если несколько команд в одном виде спорта имеют одинаковые названия, но разные логотипы, используется разделитель хеш # для уникальной идентификации. + +| TEAM | SPORT | LINK | +|-------------------|-----------|---------------------------------------------------| +| Галатасарай#Turki | Футбол | \\server\share\path\to\galatasaray_football.png | +| Галатасарай | Волейбол | \\server\share\path\to\galatasaray_volleyball.png | +| Галатасарай#UCL | Волейбол | \\server\share\path\to\galatasaray_ucl.png | +| Сомбатей##400 | Футбол | \\server\share\path\to\szombathely.png | + +### Лист "CHANELL" + +Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков. + +| CHANELL | LINK | +|---------|-----------------------------------------| +| КАНАЛ | \\server\share\path\to\channel_logo.png | +| TRIUMPH | \\server\share\path\to\triumph_logo.png | + +### Лист "Start" + +Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах. + +Обязательные колонки: DATA, TIME, CHANELL, SPORT, LEAGUE, TEAM A, TEAM B + +**Примечания:** + +- Колонка 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| + +### Формат имен команд + +Имена команд поддерживают два типа разделителей хэш #: + +1. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта. +Примеры: + +- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта +- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта + +1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа + +Формат: `DisplayName#UniqueID#TargetSize` + +Примеры: + +- `Галатасарай#Turki` - только уникальный идентификатор +- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш) +- `Спортинг#ll#550` - оба идентификатор и целевой размер + +**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером. + +## Выходные файлы + +### Рендеренные видео + +Рендерные видео сохраняются в `OUTPUT_FOLDER` по следующему шаблону именования: + +```shell +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` +- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Tomorrow.mp4` + +## Рабочий процесс + +1. **Аутентификация**: Подключение к NAS Synology с использованием предоставленных учетных данных +2. **Получение файла**: Поиск и экспорт указанного файла .osheet в Excel +3. **Парсинг данных**: Чтение всех листов и структурирование данных +4. **Разрешение ресурсов**: Сопоставление видов спорта, команд и каналов с визуальными элементами +5. **Генерация заданий**: Создание заданий Nexrender для каждой активной строки с вариантами +6. **Очистка**: Удаление завершенных/неудачных заданий из предыдущих запусков +7. **Отправка**: Отправка заданий на API Nexrender +8. **Мониторинг**: Слежение за прогрессом выполнения до завершения +9. **Завершение сеанса**: Закрытие сессии Synology + +## Требования к шаблонам After Effects + +Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв. + +### Файлы шаблонов + +Настраиваются через переменные окружения: + +| Переменная | Назначение | Пример значения | +|-------------------------|-------------------------------------|------------------------------------| +| `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` | + +### Обязательные слои в шаблонах + +#### Текстовые слои + +| Имя слоя | Шаблон 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` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона. + +### Настройки композиции + +| Параметр | Переменная окружения | Пример значения | Описание | +|---------------------------|--------------------------|-----------------|---------------------------------------------| +| Имя композиции | `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) + +## Устранение неисправностей + +### Частые проблемы + +#### Ошибка подключения к NAS + +- Проверьте, что `NAS_FQDN` включает протокол и порт (например, `https://nas.example.com:5001`) +- Проверьте сетевую связность с NAS +- Убедитесь, что сервисы File Station и Office включены + +#### Файл не найден + +- Убедитесь, что путь в `NAS_FILE` точно соответствует пути в Synology Drive +- Путь должен начинаться с `/Team Folder/` для рабочих папок +- Проверьте права доступа к файлу для учетной записи сервиса + +#### Ошибка отправки задания Nexrender + +- Подтвердите доступность сервера Nexrender +- Убедитесь, что `NEXRENDER_API_URL` правильный +- Проверьте существование файлов шаблонов на узлах рендеринга + +### Режим отладки + +Включите подробное логирование для детального анализа: + +```bash +RUST_LOG=debug ./target/release/ae_anons +``` + +Это выведет: + +- Детали API запросов/ответов +- Информацию о парсинге листов +- Детали создания заданий +- Процесс разрешения ресурсов + +## Возможные ограничения по производительности + +- **Большие таблицы**: Ограничение обработки до 10,000 строк на лист +- **Задержка сети**: Загрузка файлов с NAS может занимать время для больших файлов +- **Параллельные задания**: Nexrender управляет очередью заданий внутренне + +## Примечания по безопасности + +- Храните учетные данные только в файле `.env` (исключен из git) +- Используйте специальные аккаунты с минимально необходимыми правами +- Сессии Synology завершаются после выполнения +- HTTPS рекомендуется для подключений NAS в продакшене + +## Разработка + +### Структура кода + +```shell +ae_anons/ +├── .gitignore +├── .env.example +├── Cargo.toml +├── LICENSE +├── README.md +├── 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 | Версия | Назначение | +|--------------------|--------|-----------------------------------------| +| axum | 0.8 | Веб-фреймворк для REST API | +| tower | 0.5 | Промежуточное ПО для веб-сервера | +| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)| +| askama | 0.15 | Шаблонизация (опционально) | +| clap | 4.5 | Парсинг аргументов командной строки | + +### Платформозависимые зависимости + +| Crate | Версия | Платформа | Назначение | +|--------------------|--------|-----------|----------------------------------| +| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)| + +## 🙏 Благодарности + +Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)** +([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы +для автоматизации After Effects. + +## Лицензия + +**AE Anons** — [License](LICENSE) +**Nexrender** — [MIT License](https://github.com/inlife/nexrender/blob/master/LICENSE) + +Обе лицензии MIT обеспечивают полную свободу использования и модификации кода. + +**Разрешается:** + +- ✅ Использовать в коммерческих целях +- ✅ Изменять исходный код +- ✅ Распространять копии +- ✅ Использовать приватно + +**Требуется:** + +- Сохранять копирайт и текст лицензии + +## Поддержка + +Для вопросов и запросов функций обращайтесь: + +- +- [README.md](https://git.tvstart.ru/lexx/AE_Anons) + +## История изменений + +### v0.2.3 (текущая) + +- Веб-интерфейс с настраиваемым портом (WEB_PORT) +- Улучшенное debug-логирование +- Исправлена обработка UNC/SMB путей +- Нормализация множественных пробелов в именах файлов" + +### v0.2.2 + +- Исправлено отображение имён выходных файлов в веб-интерфейсе + +- Улучшена цветовая схема + +- Добавлена сортировка по всем колонкам + +- Вынесены стили в отдельный CSS файл + +### v0.2.0 + +- Добавлен веб-интерфейс для управления заданиями + +- Реализован REST API + +- Добавлена поддержка тёмной/светлой темы + +- Автообновление статуса заданий + +- Возможность остановки всех активных заданий + +### v0.1.1 + +- Оптимизирована работа с памятью + +- Убрана функция создания .json + +### v0.1.0 + +- Первый выпуск + +- Интеграция с Synology Office + +- Базовая генерация заданий Nexrender + +- Парсинг Excel с динамическим обнаружением листов + +--- + +Made with 🦀 Rust and ☕ coffee diff --git a/releases/ae_anons-v0.2.3-windows-x64/ae_anons.exe b/releases/ae_anons-v0.2.3-windows-x64/ae_anons.exe new file mode 100755 index 0000000..fe4fe18 Binary files /dev/null and b/releases/ae_anons-v0.2.3-windows-x64/ae_anons.exe differ