Files
compress/internal/infrastructure/compressors/unipdf_compressor.go
Dmitriy Fofanov ec65cfd05a Достижение: Добавлены скрипты и документация для релиза PDF Compressor.
- Добавлен release-body.md для подробных заметок о релизе на русском языке.
- Реализован release-gitea.ps1 для автоматизированного релиза Gitea с помощью PowerShell.
- Создан release-gitea.sh для автоматизированного релиза Gitea с помощью Bash.
- Добавлен release.sh для сборки и маркировки релизов с поддержкой нескольких платформ.
- Улучшен пользовательский интерфейс благодаря информативному логированию и обработке ошибок.
- Добавлена ​​поддержка переменных окружения и управления конфигурацией.
- Добавлена ​​функция создания архивов и загрузки ресурсов в Gitea.
2025-11-05 09:33:12 +03:00

146 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package compressors
import (
"fmt"
"os"
"github.com/unidoc/unipdf/v3/common"
"github.com/unidoc/unipdf/v3/model"
"github.com/unidoc/unipdf/v3/model/optimize"
"compressor/internal/domain/entities"
)
// UniPDFCompressor реализация компрессора с использованием UniPDF
type UniPDFCompressor struct{}
// NewUniPDFCompressor создает новый UniPDF компрессор
func NewUniPDFCompressor() *UniPDFCompressor {
return &UniPDFCompressor{}
}
// Compress сжимает PDF файл используя UniPDF библиотеку
func (u *UniPDFCompressor) Compress(inputPath, outputPath string, config *entities.CompressionConfig) (*entities.CompressionResult, error) {
fmt.Printf("🔄 Сжатие PDF с уровнем %d%% (UniPDF)...\n", config.Level)
// Инициализируем логгер
common.SetLogger(common.NewConsoleLogger(common.LogLevelInfo))
// Проверяем лицензионный ключ из конфигурации или переменной окружения
licenseKey := config.UniPDFLicenseKey
if licenseKey == "" {
licenseKey = os.Getenv("UNIDOC_LICENSE_API_KEY")
}
if licenseKey == "" {
return &entities.CompressionResult{
OriginalSize: 0,
Success: false,
Error: fmt.Errorf("UniPDF требует лицензионный ключ. Установите его в конфигурации или в переменной UNIDOC_LICENSE_API_KEY. Используйте алгоритм 'pdfcpu' для бесплатной обработки или получите ключ на https://cloud.unidoc.io"),
}, fmt.Errorf("UniPDF лицензия не настроена. Установите лицензионный ключ в конфигурации или используйте алгоритм 'pdfcpu'")
}
// Устанавливаем лицензионный ключ
fmt.Printf("🔑 Устанавливаем лицензионный ключ UniPDF...\n")
os.Setenv("UNIDOC_LICENSE_API_KEY", licenseKey) // Получаем исходный размер файла
originalInfo, err := os.Stat(inputPath)
if err != nil {
return nil, fmt.Errorf("ошибка получения информации об исходном файле: %w", err)
}
// Открываем исходный PDF файл
pdfReader, file, err := model.NewPdfReaderFromFile(inputPath, nil)
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка открытия файла: %w", err)
}
defer file.Close()
// Создаем writer с оптимизацией
pdfWriter := model.NewPdfWriter()
// Настраиваем оптимизацию в зависимости от уровня сжатия
optimizer := optimize.New(optimize.Options{
CombineDuplicateDirectObjects: true,
CombineIdenticalIndirectObjects: true,
ImageUpperPPI: float64(150 - config.Level), // чем выше уровень, тем ниже PPI
ImageQuality: 100 - config.Level, // чем выше уровень, тем ниже качество
})
pdfWriter.SetOptimizer(optimizer)
// Копируем страницы
numPages, err := pdfReader.GetNumPages()
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка получения количества страниц: %w", err)
}
for i := 1; i <= numPages; i++ {
page, err := pdfReader.GetPage(i)
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка получения страницы %d: %w", i, err)
}
err = pdfWriter.AddPage(page)
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка добавления страницы %d: %w", i, err)
}
}
// Сохраняем оптимизированный файл
outputFile, err := os.Create(outputPath)
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка создания выходного файла: %w", err)
}
defer outputFile.Close()
err = pdfWriter.Write(outputFile)
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка записи файла: %w", err)
}
// Получаем размер сжатого файла
compressedInfo, err := os.Stat(outputPath)
if err != nil {
return &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
Success: false,
Error: err,
}, fmt.Errorf("ошибка получения информации о сжатом файле: %w", err)
}
result := &entities.CompressionResult{
OriginalSize: originalInfo.Size(),
CompressedSize: compressedInfo.Size(),
Success: true,
}
result.CalculateCompressionRatio()
fmt.Printf("✅ Сжатие завершено: %s\n", outputPath)
return result, nil
}