add reading tags from pre-cached
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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. Создание и запуск приложения
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 определяет метод для скачивания файла.
|
||||||
|
|||||||
@@ -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})
|
||||||
|
|||||||
Reference in New Issue
Block a user