diff --git a/internal/clients/musicbrainz/musicbrainz.go b/internal/clients/musicbrainz/musicbrainz.go index 595dc27..414a02d 100644 --- a/internal/clients/musicbrainz/musicbrainz.go +++ b/internal/clients/musicbrainz/musicbrainz.go @@ -15,14 +15,14 @@ const ( ) type MusicBrainzClient struct { - httpClient *http.Client - userAgent string + httpClient *http.Client + userAgent string } func NewMusicBrainzClient() *MusicBrainzClient { return &MusicBrainzClient{ - httpClient: &http.Client{Timeout: 15 * time.Second}, - userAgent: userAgent, + httpClient: &http.Client{Timeout: 30 * time.Second}, + userAgent: userAgent, } } @@ -224,5 +224,6 @@ func (c *MusicBrainzClient) get(endpoint string, out any) error { if err := json.Unmarshal(body, out); err != nil { return fmt.Errorf("decode JSON: %w", err) } + return nil } diff --git a/internal/metadata/metadata.go b/internal/metadata/metadata.go index 2025755..eab5c81 100644 --- a/internal/metadata/metadata.go +++ b/internal/metadata/metadata.go @@ -6,8 +6,11 @@ import ( "os" "path/filepath" "regexp" + "slices" + "sort" "strings" + "git.kapelle.org/niklas/ripsort/internal/clients/musicbrainz" "github.com/dhowden/tag" ) @@ -21,6 +24,7 @@ type Metadata struct { Comment *string ISRC *string Date *string + Genre []string SpotifyID *string } @@ -61,6 +65,7 @@ func readGenericAudioTags(filePath string) (*Metadata, error) { Track: track, TotalTracks: totalTracks, Comment: &comment, + Genre: []string{m.Genre()}, } commentToSpotifyid(info) @@ -110,3 +115,39 @@ func commentToSpotifyid(m *Metadata) { m.SpotifyID = &id } + +func SearchForGenre(mbc *musicbrainz.MusicBrainzClient, m *Metadata) ([]string, error) { + if m.ISRC == nil { + return []string{}, nil + } + + res, err := mbc.SearchByISRC(*m.ISRC, musicbrainz.SearchOptions{}) + if err != nil { + return []string{}, err + } + + if len(res.Recordings) == 0 { + return []string{}, nil + } + + allTags := []musicbrainz.Tag{} + + for _, rec := range res.Recordings { + allTags = append(allTags, rec.Tags...) + } + + sort.Slice(allTags[:], func(i int, j int) bool { + return allTags[i].Count > allTags[j].Count + }) + + allTags = slices.CompactFunc(allTags, func(lhs, rhs musicbrainz.Tag) bool { + return lhs.Name == rhs.Name + }) + + finalTags := []string{} + for _, tag := range allTags { + finalTags = append(finalTags, tag.Name) + } + + return finalTags, nil +} diff --git a/internal/ripsort.go b/internal/ripsort.go index a172f63..9ce3270 100644 --- a/internal/ripsort.go +++ b/internal/ripsort.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + "git.kapelle.org/niklas/ripsort/internal/clients/musicbrainz" "git.kapelle.org/niklas/ripsort/internal/metadata" ) @@ -18,12 +19,30 @@ func Scan(filePath string) error { return err } - fmt.Printf("Title: %s\n", info.Title) + mbc := musicbrainz.NewMusicBrainzClient() + + genre, err := metadata.SearchForGenre(mbc, info) + if err != nil { + slog.Error("Failed to search for genere", "err", err) + return err + } + + if info.Title != nil { + fmt.Printf("Title: %s\n", *info.Title) + } fmt.Printf("Artist: %s\n", info.Artist) - fmt.Printf("Album: %s\n", info.Album) + if info.Album != nil { + fmt.Printf("Album: %s\n", *info.Album) + } fmt.Printf("Album Artist: %s\n", info.AlbumArtist) fmt.Printf("Track: %d/%d\n", info.Track, info.TotalTracks) - fmt.Printf("Comment: %s\n", info.Comment) + if info.ISRC != nil { + fmt.Printf("ISRC: %s\n", *info.ISRC) + } + if info.Comment != nil { + fmt.Printf("Comment: %s\n", *info.Comment) + } + fmt.Printf("Genre: %s\n", genre) sortPath := pathForFile(filePath, *info) fmt.Printf("Sort path: %s\n", sortPath)