Функция: реализованы консольный логгер и презентер для обработки аудиокниг
- Добавлен ConsoleLogger для подробного логирования этапов обработки аудиокниг в консоли. - Введен ConsolePresenter для форматированного вывода результатов сканирования в консоль. - Создан ProcessAudioBooksUseCase для обработки полного конвейера обработки аудиокниг, включая сканирование папок, извлечение метаданных, поиск торрентов и запись результатов. - Реализована проверка LLM для улучшения метаданных. - Добавлена обработка ошибок и логирование на всех этапах обработки.
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
// 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)
|
||||
|
||||
Reference in New Issue
Block a user