package brainz import ( "encoding/json" "fmt" "io" u "net/url" h "codeberg.org/danjones000/strip-beats/utils/http" "github.com/google/uuid" ) type Recording struct { Id uuid.UUID AcousticId uuid.UUID Isrcs []string FirstReleaseDate string `json:"first-release-date"` Length int Title string Video bool Releases []Release Genres []Genre ArtistCredit []ArtistCredit `json:"artist-credit"` } func (r Recording) FirstArtist() Artist { var a Artist for _, ac := range r.ArtistCredit { if ac.Artist.Name != "" { return ac.Artist } } for _, rel := range r.Releases { for _, ac := range rel.ArtistCredit { if ac.Artist.Name != "" { return ac.Artist } } } if a.Name == "" { a.Name = "Unknown Artist" } return a } func (r Recording) FirstGenre() Genre { var g Genre for _, g = range r.Genres { if g.Name != "" { return g } } for _, rel := range r.Releases { for _, g = range rel.Genres { if g.Name != "" { return g } } } return g } type Genre struct { Id uuid.UUID Name string } type Release struct { Id uuid.UUID Asin string Barcode string Country string Date string Disambiguation string Media []Media Packaging string PackagingId uuid.UUID `json:"packaging-id"` Quality string Status string StatusId uuid.UUID `json:"status-id"` ArtistCredit []ArtistCredit `json:"artist-credit"` Title string Genres []Genre ReleaseGroup ReleaseGroup `json:"release-group"` LabelInfo []LabelInfo `json:"label-info"` // ReleaseEvents []ReleaseEvent `json:"release-events"` } type LabelInfo struct { CatalogNumber string `json:"catalog-number"` Label Label } type Label struct { Id uuid.UUID Name string SortName string `json:"sort-name"` Disambiguation string TypeId string `json:"type-id"` Type string LabelCode int `json:"label-code"` } type ReleaseGroup struct { Id uuid.UUID Title string ArtistCredit []ArtistCredit `json:"artist-credit"` Disambiguation string FirstReleaseDate string `json:"first-release-date"` PrimaryType string `json:"primary-type"` PrimaryTypeId uuid.UUID `json:"primary-type-id"` SecondaryTypes []string `json:"secondary-types"` SecondaryTypeIds []uuid.UUID `json:"secondary-type-ids"` } type ArtistCredit struct { Name string Artist Artist JoinPhrase string } type Artist struct { Id uuid.UUID Name string TypeId string `json:"type-id"` Type string SortName string `json:"sort-name"` Genres []Genre } type Media struct { FormatId uuid.UUID `json:"format-id"` Position int Title string TrackOffset int `json:"track-offset"` Format string TrackCount int `json:"track-count"` Tracks []Track } type Track struct { Id uuid.UUID Number string Title string Position int Length int } func GetReleaseWithMedia(id uuid.UUID) (Release, error) { rel := Release{Id: id} url := fmt.Sprintf("https://musicbrainz.org/ws/2/release/%s", id) resp, err := h.GetWithQuery(url, u.Values{ "fmt": []string{"json"}, "inc": []string{"artist-credits+discids+labels+release-groups"}}) if err != nil { return rel, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return rel, err } err = json.Unmarshal(body, &rel) return rel, err } func GetRecording(id string) (Recording, error) { u, err := uuid.Parse(id) rec := Recording{Id: u} if err != nil { return rec, err } err = FillRecording(&rec) return rec, err } func FillRecording(rec *Recording) error { url := fmt.Sprintf("https://musicbrainz.org/ws/2/recording/%s", rec.Id) resp, err := h.GetWithQuery(url, u.Values{ "fmt": []string{"json"}, "inc": []string{"releases+media+artist-credits+isrcs+genres"}}) if err != nil { return err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return err } err = json.Unmarshal(body, rec) return err }