Files
GenAudioBookInfo/internal/presentation/console_logger.go
Dmitriy Fofanov 402ce7f4f1 Функция: реализованы консольный логгер и презентер для обработки аудиокниг
- Добавлен ConsoleLogger для подробного логирования этапов обработки аудиокниг в консоли.

- Введен ConsolePresenter для форматированного вывода результатов сканирования в консоль.

- Создан ProcessAudioBooksUseCase для обработки полного конвейера обработки аудиокниг, включая сканирование папок, извлечение метаданных, поиск торрентов и запись результатов.

- Реализована проверка LLM для улучшения метаданных.

- Добавлена ​​обработка ошибок и логирование на всех этапах обработки.
2026-02-20 00:35:43 +03:00

153 lines
4.5 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 presentation реализует порт ProcessLogger —
// детальное логирование процесса обработки аудиокниг в консоль.
package presentation
import (
"fmt"
"os"
"sync"
"github.com/fofanov/genaudiobookinfo/internal/domain"
"github.com/schollz/progressbar/v3"
)
// ConsoleLogger реализует domain.ProcessLogger для вывода логов в консоль.
type ConsoleLogger struct {
mu sync.Mutex // защита от гонок при параллельном логировании
bar *progressbar.ProgressBar
}
// NewConsoleLogger создаёт новый экземпляр логгера.
func NewConsoleLogger() *ConsoleLogger {
return &ConsoleLogger{}
}
// NewConsoleLoggerWithProgress создаёт логгер с progress bar.
func NewConsoleLoggerWithProgress(total int) *ConsoleLogger {
bar := progressbar.NewOptions(total,
progressbar.OptionSetDescription("Обработка аудиокниг"),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionSetWidth(40),
progressbar.OptionShowCount(),
progressbar.OptionShowIts(),
progressbar.OptionSetPredictTime(true),
progressbar.OptionSetTheme(progressbar.Theme{
Saucer: "=",
SaucerHead: ">",
SaucerPadding: " ",
BarStart: "[",
BarEnd: "]",
}),
progressbar.OptionOnCompletion(func() {
fmt.Fprintln(os.Stderr)
}),
)
return &ConsoleLogger{
bar: bar,
}
}
// LogStart логирует начало обработки книги.
func (l *ConsoleLogger) LogStart(folderName string) {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar == nil {
fmt.Printf("\n📁 Обработка: %s\n", folderName)
}
// С progressbar не меняем описание — с N воркерами оно мерцает
}
// LogExtraction логирует этап извлечения метаданных.
func (l *ConsoleLogger) LogExtraction() {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar == nil {
fmt.Println(" 🎵 Извлечение метаданных...")
}
}
// LogLLMValidation логирует этап валидации через LLM.
func (l *ConsoleLogger) LogLLMValidation() {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar == nil {
fmt.Println(" 🤖 Валидация через LLM...")
}
}
// LogSearch логирует этап поиска на трекерах.
func (l *ConsoleLogger) LogSearch() {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar == nil {
fmt.Println(" 🔍 Поиск на трекерах...")
}
}
// LogWrite логирует этап записи результата.
func (l *ConsoleLogger) LogWrite() {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar == nil {
fmt.Println(" 💾 Запись результата...")
}
}
// LogCoverDownload логирует этап скачивания обложки.
func (l *ConsoleLogger) LogCoverDownload() {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar == nil {
fmt.Println(" 🖼️ Скачивание обложки...")
}
}
// LogComplete логирует успешное завершение обработки книги.
func (l *ConsoleLogger) LogComplete(folderName string) {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar != nil {
l.bar.Add(1)
} else {
fmt.Printf(" ✅ Завершено: %s\n", folderName)
}
}
// LogError логирует ошибку обработки.
func (l *ConsoleLogger) LogError(folderName string, err error) {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar != nil {
l.bar.Add(1)
// Пишем ошибку в stderr (туда же, куда и progressbar), чтобы не ломать вывод
fmt.Fprintf(os.Stderr, "\n ❌ Ошибка [%s]: %v\n", folderName, err)
} else {
fmt.Printf(" ❌ Ошибка [%s]: %v\n", folderName, err)
}
}
// LogWarning логирует предупреждение.
func (l *ConsoleLogger) LogWarning(message string) {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar != nil {
// Выводим предупреждения в stderr, чтобы они не терялись
fmt.Fprintf(os.Stderr, "\n ⚠️ %s\n", message)
} else {
fmt.Printf(" ⚠️ %s\n", message)
}
}
// Finish завершает работу progressbar (если есть).
func (l *ConsoleLogger) Finish() {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar != nil {
l.bar.Finish()
}
}
// Проверка во время компиляции, что ConsoleLogger реализует domain.ProcessLogger
var _ domain.ProcessLogger = (*ConsoleLogger)(nil)