- Добавлен release-body.md для подробных заметок о релизе на русском языке. - Реализован release-gitea.ps1 для автоматизированного релиза Gitea с помощью PowerShell. - Создан release-gitea.sh для автоматизированного релиза Gitea с помощью Bash. - Добавлен release.sh для сборки и маркировки релизов с поддержкой нескольких платформ. - Улучшен пользовательский интерфейс благодаря информативному логированию и обработке ошибок. - Добавлена поддержка переменных окружения и управления конфигурацией. - Добавлена функция создания архивов и загрузки ресурсов в Gitea.
308 lines
17 KiB
Markdown
308 lines
17 KiB
Markdown
# Universal File Compressor
|
||
|
||
Высокопроизводительный инструмент на Go для массового сжатия PDF и изображений (JPEG/PNG) с удобным TUI-интерфейсом, гибкой конфигурацией и модульной архитектурой (Clean Architecture). Поддерживает выбор алгоритма сжатия (PDFCPU / UniPDF), параметрическое управление качеством, рекурсивную обработку директорий, параллельное выполнение, расширяемость через дополнительные компрессоры.
|
||
|
||
---
|
||
## Содержание
|
||
1. Обзор и ключевые особенности
|
||
2. Быстрый старт
|
||
3. Конфигурация (полный справочник)
|
||
4. Алгоритмы сжатия (PDFCPU vs UniPDF)
|
||
5. Сжатие изображений (JPEG / PNG)
|
||
6. Архитектура и внутреннее устройство
|
||
7. Поток обработки (Pipeline)
|
||
8. Параллельность и производительность
|
||
9. Логирование и мониторинг
|
||
10. Расширяемость (как добавить новый компрессор)
|
||
11. Сценарии использования и рекомендации
|
||
12. Устранение неполадок
|
||
13. План развития / Roadmap
|
||
14. Лицензия (если применимо)
|
||
|
||
---
|
||
## 1. Обзор и ключевые особенности
|
||
|
||
| Возможность | Описание |
|
||
|-------------|----------|
|
||
| Сжатие PDF | Алгоритмы PDFCPU (скорость) и UniPDF (качество) |
|
||
| Сжатие изображений | JPEG (10–50% качество), PNG (адаптивная оптимизация) |
|
||
| Рекурсивная обработка | Поиск файлов во всех поддиректориях |
|
||
| Сохранение структуры | **Полное сохранение иерархии папок** в целевой директории |
|
||
| Параллельность | Несколько воркеров, управляемые через конфигурацию |
|
||
| Замена или сохранение | Перезапись оригиналов или вывод в целевую папку |
|
||
| Интеллектуальное сжатие | Автоматический выбор оригинала при неэффективном сжатии |
|
||
| TUI интерфейс | Настройка, запуск, мониторинг прогресса и логов |
|
||
| Логирование | В файл и/или на экран, ротация по размеру |
|
||
| Универсальная конфигурация | YAML + динамическая загрузка в рантайме |
|
||
| Расширяемость | Чистые интерфейсы для добавления новых компрессоров |
|
||
| Обработка ошибок | Повторы (retry), таймауты, агрегирование статистики |
|
||
|
||
---
|
||
## 2. Быстрый старт
|
||
|
||
### Установка из исходников
|
||
```bash
|
||
git clone https://github.com/your-username/compressor.git
|
||
cd compressor
|
||
go mod tidy
|
||
go build -o compressor cmd/main.go
|
||
./compressor # (Windows: compressor.exe)
|
||
```
|
||
|
||
### Минимальный сценарий
|
||
1. Поместите файлы в директорию `./pdfs` (или измените путь в `config.yaml`).
|
||
2. Запустите программу.
|
||
3. В TUI выберите «Конфигурация», настройте параметры.
|
||
4. Сохраните и запустите обработку.
|
||
5. Результаты появятся в выбранной целевой директории или заменят оригиналы.
|
||
|
||
---
|
||
## 3. Конфигурация (config.yaml)
|
||
|
||
```yaml
|
||
scanner:
|
||
source_directory: "./pdfs" # Папка с исходными файлами
|
||
target_directory: "./compressed" # Если пусто и replace_original=true — замена
|
||
replace_original: false # true — перезаписывать исходники
|
||
|
||
compression:
|
||
level: 50 # Общий уровень (10–90) влияет на стратегию
|
||
algorithm: "pdfcpu" # pdfcpu | unipdf
|
||
auto_start: false # Автозапуск при старте приложения
|
||
unipdf_license_key: "" # Ключ для UniPDF (опционально)
|
||
|
||
# Сжатие изображений
|
||
enable_jpeg: true # Включить JPEG
|
||
enable_png: true # Включить PNG
|
||
jpeg_quality: 30 # 10–50 (шаг 5)
|
||
png_quality: 25 # 10–50 (шаг 5)
|
||
|
||
processing:
|
||
parallel_workers: 2 # Количество воркеров
|
||
timeout_seconds: 30 # Таймаут на файл
|
||
retry_attempts: 3 # Повторы при падениях
|
||
|
||
output:
|
||
log_level: "info" # debug|info|warning|error
|
||
progress_bar: true
|
||
log_to_file: true
|
||
log_file_name: "compressor.log"
|
||
log_max_size_mb: 10
|
||
```
|
||
|
||
### Валидация параметров
|
||
| Параметр | Диапазон | Ошибка при нарушении |
|
||
|----------|----------|----------------------|
|
||
| compression.level | 10–90 | ErrInvalidCompressionLevel |
|
||
| jpeg_quality | 10–50 (шаг 5) | ErrInvalidJPEGQuality |
|
||
| png_quality | 10–50 (шаг 5) | ErrInvalidPNGQuality |
|
||
|
||
---
|
||
## 4. Алгоритмы сжатия PDF
|
||
|
||
| Критерий | PDFCPU | UniPDF |
|
||
|----------|--------|--------|
|
||
| Основной фокус | Скорость | Максимальное сжатие |
|
||
| Сжатие изображений | Базовое | Продвинутое (перекодирование) |
|
||
| Скорость (относит.) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
|
||
| Степень сжатия | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
||
| Стабильность | Высокая | Высокая |
|
||
| Зависимости | Легковесный | Более тяжелая библиотека |
|
||
|
||
Рекомендации:
|
||
- Выберите PDFCPU, если: массовая обработка, преобладает текст, важна скорость.
|
||
- Выберите UniPDF, если: критичен размер, много изображений, важна агрессивная оптимизация.
|
||
|
||
Переключение: `compression.algorithm: "unipdf"`.
|
||
|
||
---
|
||
## 5. Сжатие изображений (JPEG / PNG)
|
||
|
||
### Поддерживаемые форматы
|
||
- JPEG: `.jpg`, `.jpeg`
|
||
- PNG: `.png`
|
||
|
||
### Параметры
|
||
| Параметр | Назначение |
|
||
|----------|------------|
|
||
| enable_jpeg | Включает проход по JPEG файлам |
|
||
| enable_png | Включает проход по PNG файлам |
|
||
| jpeg_quality | Управляет степенью перекодирования и масштабирования |
|
||
| png_quality | Управляет коэффициентом масштабирования и уровнем компрессии |
|
||
|
||
### Алгоритм JPEG (улучшенный с защитой от увеличения)
|
||
1. **Декодирование** исходного JPEG.
|
||
2. **Адаптивное масштабирование**: quality 10→50%, quality 50→90% размера.
|
||
3. **Консервативное качество**: маппинг 10→30, 30→55, 50→75 (вместо агрессивного 20-100).
|
||
4. **Кодирование во временный файл** с проверкой размера.
|
||
5. **Интеллектуальный выбор**:
|
||
- Если результат ≥95% от оригинала → копируется оригинал (без потери качества)
|
||
- Если результат меньше → используется сжатая версия
|
||
6. **Гарантия**: выходной файл никогда не будет больше исходного.
|
||
|
||
### Алгоритм PNG (улучшенный с защитой от увеличения)
|
||
1. **Декодирование** исходного PNG.
|
||
2. **Консервативное масштабирование**: quality 10→60%, quality 50→90% размера.
|
||
3. **Адаптивная обработка**: маленькие изображения (<400px) не изменяются в размерах.
|
||
4. **Кодирование во временный файл** с максимальным сжатием (`png.BestCompression`).
|
||
5. **Интеллектуальный выбор**:
|
||
- Если результат ≥95% от оригинала → копируется оригинал
|
||
- Если результат меньше → используется сжатая версия
|
||
6. **Гарантия**: выходной файл никогда не будет больше исходного.
|
||
|
||
**Важно**: PNG — lossless формат. Для уже оптимизированных файлов алгоритм автоматически сохраняет оригинал, предотвращая увеличение размера.
|
||
|
||
---
|
||
## 6. Архитектура
|
||
|
||
Следует принципам Clean Architecture.
|
||
|
||
Слои:
|
||
- `domain` — сущности, ошибки, интерфейсы (`PDFCompressor`, `FileRepository`, `Logger`).
|
||
- `usecase` — сценарии: `ProcessPDFsUseCase`, `CompressImageUseCase`, `ProcessAllFilesUseCase`.
|
||
- `infrastructure` — реализации (компрессоры, файловый репозиторий, конфигурация, логирование).
|
||
- `presentation/tui` — UI слой, отображение прогресса, ввод настроек.
|
||
- `cmd/main.go` — композиция.
|
||
|
||
Преимущества: тестируемость, независимость от фреймворков, лёгкая замена реализаций.
|
||
|
||
---
|
||
## 7. Поток обработки (Pipeline)
|
||
1. Загрузка `config.yaml` через `config.Repository`.
|
||
2. Инициализация логирования и TUI.
|
||
3. Выбор реализации компрессора PDF.
|
||
4. Создание UseCases.
|
||
5. Пользователь подтверждает запуск (или auto_start).
|
||
6. Сканирование директорий — фильтрация поддерживаемых файлов.
|
||
7. Постановка задач в воркеры.
|
||
8. Сжатие + повторы при сбоях.
|
||
9. Обновление прогресса через callback → TUI.
|
||
10. Запись статистики, логов, замена/вывод файлов.
|
||
|
||
---
|
||
## 8. Параллельность и производительность
|
||
- Модель: пул воркеров (число — `parallel_workers`).
|
||
- Ограничение таймаутом: `timeout_seconds`.
|
||
- Повторы: `retry_attempts` (экспоненциальную стратегию можно внедрить дополнительно).
|
||
- Потенциальные оптимизации: кэширование размеров, отложенное пересохранение, batch-операции.
|
||
|
||
---
|
||
## 9. Логирование и мониторинг
|
||
| Тип | Назначение |
|
||
|-----|------------|
|
||
| Console/TUI | Интерактивное наблюдение за процессом |
|
||
| File logger | История и аудит |
|
||
| Уровни | debug, info, warning, error, success |
|
||
|
||
Ротация — по максимальному размеру (MB).
|
||
|
||
---
|
||
## 10. Расширяемость
|
||
|
||
### Добавление нового PDF компрессора
|
||
1. Создайте файл в `internal/infrastructure/compressors/` (например, `myengine_compressor.go`).
|
||
2. Реализуйте интерфейс `PDFCompressor`.
|
||
3. Добавьте значение в конфигурацию (`compression.algorithm`).
|
||
4. Расширьте `main.go` switch.
|
||
|
||
### Добавление формата изображений
|
||
1. Дополните `IsImageFile` и `GetImageFormat`.
|
||
2. Реализуйте метод в `ImageCompressor`.
|
||
3. Добавьте поля в `AppCompressionConfig`, валидацию, TUI форму.
|
||
|
||
---
|
||
## 11. Сценарии и рекомендации
|
||
| Сценарий | Рекомендации |
|
||
|----------|--------------|
|
||
| Архивирование большого массива офисных PDF | PDFCPU + level 40–60 |
|
||
| Максимальное уменьшение для рассылки | UniPDF + level 70–85 |
|
||
| Много цветных сканов | UniPDF + включить сжатие JPEG 25–35% |
|
||
| Оптимизация сайта (изображения + PDF) | PDFCPU + JPEG/PNG 30% |
|
||
| Быстрая предпрод. обработка | PDFCPU + low retries |
|
||
|
||
---
|
||
## 12. Устранение неполадок
|
||
| Проблема | Причина | Решение |
|
||
|----------|---------|---------|
|
||
| UniPDF ошибка лицензии | Нет ключа | Установите `UNIDOC_LICENSE_API_KEY` или в config |
|
||
| PNG вырос в размере | Уже оптимален | Повышайте качество или отключите PNG |
|
||
| Нет файлов найдено | Неверный путь | Проверьте `scanner.source_directory` |
|
||
| Высокая нагрузка CPU | Слишком много воркеров | Уменьшите `parallel_workers` |
|
||
| Медленно при больших изображениях | Масштабирование | Увеличьте качество или отключите уменьшение |
|
||
|
||
---
|
||
## 13. Тестирование
|
||
|
||
### Комплексное тестирование всех алгоритмов
|
||
|
||
Проект включает единый комплексный тест, который проверяет все основные алгоритмы и компоненты:
|
||
|
||
```powershell
|
||
# Запуск через скрипт (рекомендуется)
|
||
cd tests
|
||
.\run-tests.ps1
|
||
|
||
# Или вручную
|
||
cd tests
|
||
go build -o comprehensive_test.exe comprehensive.go
|
||
.\comprehensive_test.exe
|
||
```
|
||
|
||
### Покрытие тестами
|
||
|
||
Комплексный тест проверяет:
|
||
|
||
✅ **Валидация конфигурации** (5 тестов)
|
||
- Корректность настроек JPEG/PNG качества
|
||
- Граничные значения (10-50%)
|
||
- Обнаружение невалидных параметров
|
||
|
||
✅ **Сжатие JPEG** (4 теста)
|
||
- Различные уровни качества (10%, 30%, 50%)
|
||
- Защита от увеличения размера файла
|
||
|
||
✅ **Сжатие PNG** (4 теста)
|
||
- Различные уровни качества
|
||
- Защита от увеличения размера файла
|
||
|
||
✅ **Сжатие PDF** (1 тест)
|
||
- Алгоритм PDFCPU
|
||
|
||
✅ **Структура папок** (1 тест)
|
||
- Сохранение иерархии при обработке
|
||
|
||
✅ **Вычисления** (3 теста)
|
||
- Коэффициент сжатия
|
||
- Экономия места
|
||
|
||
**Результаты:** Автоматический отчёт с детальной статистикой, время выполнения каждого теста, коды возврата для CI/CD.
|
||
|
||
Подробности: [tests/README.md](tests/README.md)
|
||
|
||
---
|
||
## 14. План развития (Roadmap)
|
||
- [ ] Поддержка WebP / AVIF
|
||
- [ ] Асинхронное журналирование с буферизацией
|
||
- [ ] REST API слой / gRPC
|
||
- [ ] Пакетный режим без TUI (`--headless`)
|
||
- [ ] Экспорт отчётов (JSON / HTML)
|
||
- [ ] Более точные эвристики выбора стратегии сжатия
|
||
- [ ] Плагинная система компрессоров
|
||
- [x] Комплексное тестирование всех алгоритмов
|
||
|
||
---
|
||
## 15. Лицензия
|
||
(Добавьте информацию о лицензии проекта при необходимости.)
|
||
|
||
---
|
||
## Приложение A. Пример расширенного запуска
|
||
```bash
|
||
PDF_CONFIG=./config.yaml ./pdf-compressor
|
||
```
|
||
|
||
## Приложение B. Метрики качества (пример)
|
||
| Показатель | PDFCPU (сред.) | UniPDF (сред.) |
|
||
|------------|----------------|----------------|
|
||
| Снижение размера | 30–45% | 50–70% |
|
||
| Время (100 файлов) | 1× | 2–3× |
|
||
| Ошибки повторной попытки | Низко | Низко | |