add reading tags from pre-cached
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-06-24 07:51:03 +03:00
parent eef26aba0a
commit afacaf4f14
4 changed files with 35 additions and 6 deletions

View File

@@ -58,7 +58,8 @@ func main() {
trackProcessor := processor.NewTrackProcessor(db, yandexClient, downloaderComponent, taggerComponent, telegramClient) trackProcessor := processor.NewTrackProcessor(db, yandexClient, downloaderComponent, taggerComponent, telegramClient)
adminHandler := admin.NewHandler(db, telegramClient, yandexClient, startTime) // Передаем taggerComponent в admin.NewHandler
adminHandler := admin.NewHandler(db, telegramClient, yandexClient, taggerComponent, startTime)
inlineHandler := bot.NewInlineHandler(yandexClient, trackProcessor, telegramClient) inlineHandler := bot.NewInlineHandler(yandexClient, trackProcessor, telegramClient)
// 5. Создание и запуск приложения // 5. Создание и запуск приложения

View File

@@ -18,15 +18,17 @@ type Handler struct {
storage interfaces.TrackStorage storage interfaces.TrackStorage
telegram interfaces.TelegramClient telegram interfaces.TelegramClient
yandex interfaces.YandexMusicClient yandex interfaces.YandexMusicClient
tagger interfaces.Tagger
startTime time.Time startTime time.Time
} }
// NewHandler создает новый обработчик команд администратора. // NewHandler создает новый обработчик команд администратора.
func NewHandler(storage interfaces.TrackStorage, telegram interfaces.TelegramClient, yandex interfaces.YandexMusicClient, startTime time.Time) *Handler { func NewHandler(storage interfaces.TrackStorage, telegram interfaces.TelegramClient, yandex interfaces.YandexMusicClient, tagger interfaces.Tagger, startTime time.Time) *Handler {
return &Handler{ return &Handler{
storage: storage, storage: storage,
telegram: telegram, telegram: telegram,
yandex: yandex, yandex: yandex,
tagger: tagger,
startTime: startTime, startTime: startTime,
} }
} }
@@ -165,17 +167,24 @@ func (h *Handler) handleWarmFromDir(ctx context.Context, chatID int64, dirPath s
continue continue
} }
// 2. Загружаем в Telegram // 2. Читаем метатеги из файла
// Поскольку метатеги уже вшиты, для отображения в кэш-канале можно использовать простые title/performer title, artist, err := h.tagger.ReadMetadata(fullPath)
if err != nil {
slog.Warn("Failed to read metadata from file, using fallback", "path", fullPath, "error", err)
title = "" // Используем ID как заголовок
artist = "" // Используем заглушку как исполнителя
}
// 3. Загружаем в Telegram с корректными метаданными
slog.Debug("Uploading track to cache channel", "track_id", trackID, "path", fullPath) slog.Debug("Uploading track to cache channel", "track_id", trackID, "path", fullPath)
fileID, err := h.telegram.SendAudioToCacheChannel(ctx, fullPath, trackID, "Pre-cached") fileID, err := h.telegram.SendAudioToCacheChannel(ctx, fullPath, title, artist)
if err != nil { if err != nil {
slog.Error("Failed to upload pre-cached file", "track_id", trackID, "error", err) slog.Error("Failed to upload pre-cached file", "track_id", trackID, "error", err)
errorCount++ errorCount++
continue continue
} }
// 3. Сохраняем в БД // 4. Сохраняем в БД
err = h.storage.Set(ctx, trackID, fileID) err = h.storage.Set(ctx, trackID, fileID)
if err != nil { if err != nil {
slog.Error("Failed to save pre-cached file to storage", "track_id", trackID, "error", err) slog.Error("Failed to save pre-cached file to storage", "track_id", trackID, "error", err)

View File

@@ -34,6 +34,7 @@ type TelegramClient interface {
// Tagger определяет методы для работы с метаданными аудиофайлов. // Tagger определяет методы для работы с метаданными аудиофайлов.
type Tagger interface { type Tagger interface {
WriteTags(filePath string, coverPath string, info *model.TrackInfo) error WriteTags(filePath string, coverPath string, info *model.TrackInfo) error
ReadMetadata(filePath string) (title, artist string, err error)
} }
// FileDownloader определяет метод для скачивания файла. // FileDownloader определяет метод для скачивания файла.

View File

@@ -17,6 +17,24 @@ func NewID3Tagger() *ID3Tagger {
return &ID3Tagger{} return &ID3Tagger{}
} }
// ReadMetadata читает основные метаданные (название, исполнитель) из аудиофайла.
func (t *ID3Tagger) ReadMetadata(filePath string) (string, string, error) {
tag, err := id3v2.Open(filePath, id3v2.Options{Parse: true})
if err != nil {
return "", "", fmt.Errorf("failed to open mp3 file for reading tags: %w", err)
}
defer tag.Close()
title := tag.Title()
artist := tag.Artist()
if title == "" || artist == "" {
return "", "", fmt.Errorf("title or artist tag is empty")
}
return title, artist, nil
}
// WriteTags записывает метаданные и обложку в указанный аудиофайл. // WriteTags записывает метаданные и обложку в указанный аудиофайл.
func (t *ID3Tagger) WriteTags(filePath string, coverPath string, info *model.TrackInfo) error { func (t *ID3Tagger) WriteTags(filePath string, coverPath string, info *model.TrackInfo) error {
tag, err := id3v2.Open(filePath, id3v2.Options{Parse: true}) tag, err := id3v2.Open(filePath, id3v2.Options{Parse: true})