Files
GenAudioBookInfo/internal/presentation/console_logger.go
Dmitriy Fofanov 41fb62f62e Добавлены страницы вики для GenAudioBookInfo: Home, Installation, Makefile, OpenRouter, Output Structure, TorrAPI и Sidebar.
Создана структура документации, описывающая функциональность, установку, использование CLI, архитектуру и интеграции с TorrAPI и OpenRouter.
Добавлены примеры конфигурации и метаданных, а также описание структуры выходных данных.
2026-02-23 13:19:39 +03:00

163 lines
4.8 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}
}
// LogInfo логирует информационное сообщение (штатное событие, не ошибка).
func (l *ConsoleLogger) LogInfo(message string) {
l.mu.Lock()
defer l.mu.Unlock()
if l.bar != nil {
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)