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

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

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

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

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

132 lines
5.2 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 main демонстрирует использование валидации метаданных через OpenRouter.
// Этот файл является примером и не включён в основной build.
// Для запуска: go run examples/validate_metadata_example.go
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/fofanov/genaudiobookinfo/internal/infrastructure"
)
func main() {
// Получаем API ключ из переменной окружения
apiKey := os.Getenv("OPENROUTER_API_KEY")
if apiKey == "" {
log.Fatal("Ошибка: установите переменную окружения OPENROUTER_API_KEY")
}
// Промпт для валидации метаданных
validationPrompt := `Ты — эксперт по метаданным русскоязычных аудиокниг. Твоя задача — проверить и исправить метаданные.
ПРАВИЛА ДЛЯ АВТОРА:
1. Автор ВСЕГДА должен быть в формате: "Фамилия Имя" (без отчества)
2. Если указано "Имя Фамилия" — переставь в правильный порядок
3. Если есть отчество (три слова) — убери его, оставь только "Фамилия Имя"
4. Если несколько авторов — обработай каждого по тем же правилам, раздели запятыми
ПРАВИЛА ДЛЯ НАЗВАНИЯ КНИГИ (title):
1. Убери номера серий, книг типа: "Книга 1", "01", "#1", "Том 2"
2. Убери название серии, если оно дублируется
3. Убери служебные слова: "Аудиокнига", "MP3", "читает"
4. Убери имя автора, если оно попало в название
5. Убери год издания из названия
6. Оставь только чистое название произведения
ФОРМАТ ОТВЕТА (строго JSON):
{
"author": "Исправленная Фамилия Имя",
"title": "Исправленное название без лишнего",
"author_fixed": true/false,
"title_fixed": true/false,
"changes": "краткое описание сделанных изменений"
}
Если исправления не требуются, верни исходные значения с флагами false.`
// Создаём клиент OpenRouter с промптом валидации
client := infrastructure.NewOpenRouterClient(infrastructure.OpenRouterConfig{
APIKey: apiKey,
BaseURL: "https://openrouter.ai/api/v1",
Timeout: 60 * time.Second,
Model: "openai/gpt-3.5-turbo",
Prompt: validationPrompt,
})
// Создаём контекст с таймаутом
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Примеры некорректных метаданных
testCases := []struct {
author string
title string
desc string
}{
{
author: "Иванов Петр Сергеевич",
title: "Путешествие в неизвестность. Книга 1",
desc: "Отчество в авторе, номер книги в названии",
},
{
author: "Александр Пушкин",
title: "Евгений Онегин (Аудиокнига MP3)",
desc: "Имя-Фамилия, служебные слова в названии",
},
{
author: "Лев Николаевич Толстой",
title: "Война и мир. Том 1. 2020",
desc: "Полное имя с отчеством, номер тома и год",
},
{
author: "Стругацкий Аркадий",
title: "Пикник на обочине #2",
desc: "Некорректный номер книги",
},
{
author: "Булгаков Михаил",
title: "Мастер и Маргарита",
desc: "Корректные данные (не требуют исправления)",
},
}
fmt.Println("=== Валидация метаданных аудиокниг ===\n")
for i, tc := range testCases {
fmt.Printf("Пример %d: %s\n", i+1, tc.desc)
fmt.Printf("Исходные данные:\n")
fmt.Printf(" Автор: %s\n", tc.author)
fmt.Printf(" Название: %s\n", tc.title)
result, err := client.ValidateMetadata(ctx, tc.author, tc.title)
if err != nil {
log.Printf(" ❌ Ошибка валидации: %v\n\n", err)
continue
}
if result == nil {
fmt.Println(" ⚠️ Валидация отключена (нет API ключа или промпта)\n")
continue
}
fmt.Printf("\nРезультат:\n")
if result.AuthorFixed || result.TitleFixed {
fmt.Printf(" ✅ Исправлено:\n")
if result.AuthorFixed {
fmt.Printf(" Автор: %s\n", result.Author)
}
if result.TitleFixed {
fmt.Printf(" Название: %s\n", result.Title)
}
fmt.Printf(" 📝 Изменения: %s\n", result.Changes)
} else {
fmt.Printf(" ✓ Данные корректны, исправления не требуются\n")
}
fmt.Println()
}
}