76e426c5d3
- Add internal/musicfs package: gRPC client, TriggerRescan (stream consumer), EnrichFiles (BatchUpdateMetadata), DeriveSubdir helper - Add MusicFS config section (enabled, endpoint, origin_id, origin_root, timeout) - Wire MusicFSClient into PollDownloadWorker: on download completion, trigger scoped rescan then push enriched metadata - Fix album auto-persist in monitor workflow: persist artist+album from metadata-agregator before saving torrent/download - Add filterByActiveSeeders: skip torrents where magnet resolution found 0 real active seeders - Add musicfs proto to buf.gen.yaml inputs - Enricher only sends non-empty fields to avoid overwriting existing file tag data with empty values
93 lines
1.8 KiB
Go
93 lines
1.8 KiB
Go
package musicfs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
metadataPb "homelab.lan/music-agregator/gen/metadata/v1"
|
|
pb "homelab.lan/music-agregator/gen/musicfs/v1"
|
|
)
|
|
|
|
func (c *Client) EnrichFiles(ctx context.Context, files []SyncedFile, album *metadataPb.Album) error {
|
|
if len(files) == 0 || album == nil {
|
|
return nil
|
|
}
|
|
|
|
genre := firstGenreName(album.GetGenres())
|
|
label := labelName(album.GetLabel())
|
|
albumType := album.GetAlbumType()
|
|
coverURL := album.GetCoverUrl()
|
|
|
|
var items []*pb.BatchUpdateItem
|
|
for _, f := range files {
|
|
meta := &pb.UpdateMetadataRequest{
|
|
FileId: f.FileID,
|
|
}
|
|
if genre != "" {
|
|
meta.Genre = &genre
|
|
}
|
|
if label != "" {
|
|
meta.Label = &label
|
|
}
|
|
if albumType != "" {
|
|
meta.AlbumType = &albumType
|
|
}
|
|
if coverURL != "" {
|
|
meta.CoverUrl = &coverURL
|
|
}
|
|
items = append(items, &pb.BatchUpdateItem{
|
|
FileId: f.FileID,
|
|
Metadata: meta,
|
|
})
|
|
}
|
|
|
|
stream, err := c.Metadata.BatchUpdateMetadata(ctx, &pb.BatchUpdateRequest{Items: items})
|
|
if err != nil {
|
|
return fmt.Errorf("batch update: %w", err)
|
|
}
|
|
|
|
var updated, failed int
|
|
for {
|
|
progress, err := stream.Recv()
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return fmt.Errorf("batch update stream: %w", err)
|
|
}
|
|
if progress.ErrorMessage != nil {
|
|
log.Warn().
|
|
Int64("file_id", progress.GetCurrentFileId()).
|
|
Str("error", progress.GetErrorMessage()).
|
|
Msg("batch update item failed")
|
|
failed++
|
|
} else {
|
|
updated++
|
|
}
|
|
}
|
|
|
|
log.Info().
|
|
Int("updated", updated).
|
|
Int("failed", failed).
|
|
Msg("enrichment batch complete")
|
|
|
|
return nil
|
|
}
|
|
|
|
func firstGenreName(genres []*metadataPb.Genre) string {
|
|
if len(genres) == 0 {
|
|
return ""
|
|
}
|
|
return genres[0].GetName()
|
|
}
|
|
|
|
func labelName(label *metadataPb.Label) string {
|
|
if label == nil {
|
|
return ""
|
|
}
|
|
return label.GetName()
|
|
}
|