Fix listenbrainz submission and clarify MusicBrainz recording ID field (#2279)
* Fix MB recording ID parameter name for ListenBrainz submission This follows the ListenBrainz API documentation. Fixes #1657 * Rename MediaFile.MbzTrackID to MbzRecordingID This better reflects the actual data. That the MusicBrainz recording ID is stored in file metadata as musicbrainz_trackid is a historical artifact. * Rename database column mbz_track_id to mbz_recording_id
This commit is contained in:
parent
36eda871f6
commit
c8608956be
|
@ -257,7 +257,7 @@ func (l *lastfmAgent) NowPlaying(ctx context.Context, userId string, track *mode
|
||||||
track: track.Title,
|
track: track.Title,
|
||||||
album: track.Album,
|
album: track.Album,
|
||||||
trackNumber: track.TrackNumber,
|
trackNumber: track.TrackNumber,
|
||||||
mbid: track.MbzTrackID,
|
mbid: track.MbzRecordingID,
|
||||||
duration: int(track.Duration),
|
duration: int(track.Duration),
|
||||||
albumArtist: track.AlbumArtist,
|
albumArtist: track.AlbumArtist,
|
||||||
})
|
})
|
||||||
|
@ -283,7 +283,7 @@ func (l *lastfmAgent) Scrobble(ctx context.Context, userId string, s scrobbler.S
|
||||||
track: s.Title,
|
track: s.Title,
|
||||||
album: s.Album,
|
album: s.Album,
|
||||||
trackNumber: s.TrackNumber,
|
trackNumber: s.TrackNumber,
|
||||||
mbid: s.MbzTrackID,
|
mbid: s.MbzRecordingID,
|
||||||
duration: int(s.Duration),
|
duration: int(s.Duration),
|
||||||
albumArtist: s.AlbumArtist,
|
albumArtist: s.AlbumArtist,
|
||||||
timestamp: s.TimeStamp,
|
timestamp: s.TimeStamp,
|
||||||
|
|
|
@ -234,14 +234,14 @@ var _ = Describe("lastfmAgent", func() {
|
||||||
agent = lastFMConstructor(ds)
|
agent = lastFMConstructor(ds)
|
||||||
agent.client = client
|
agent.client = client
|
||||||
track = &model.MediaFile{
|
track = &model.MediaFile{
|
||||||
ID: "123",
|
ID: "123",
|
||||||
Title: "Track Title",
|
Title: "Track Title",
|
||||||
Album: "Track Album",
|
Album: "Track Album",
|
||||||
Artist: "Track Artist",
|
Artist: "Track Artist",
|
||||||
AlbumArtist: "Track AlbumArtist",
|
AlbumArtist: "Track AlbumArtist",
|
||||||
TrackNumber: 1,
|
TrackNumber: 1,
|
||||||
Duration: 180,
|
Duration: 180,
|
||||||
MbzTrackID: "mbz-123",
|
MbzRecordingID: "mbz-123",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ var _ = Describe("lastfmAgent", func() {
|
||||||
Expect(sentParams.Get("albumArtist")).To(Equal(track.AlbumArtist))
|
Expect(sentParams.Get("albumArtist")).To(Equal(track.AlbumArtist))
|
||||||
Expect(sentParams.Get("trackNumber")).To(Equal(strconv.Itoa(track.TrackNumber)))
|
Expect(sentParams.Get("trackNumber")).To(Equal(strconv.Itoa(track.TrackNumber)))
|
||||||
Expect(sentParams.Get("duration")).To(Equal(strconv.FormatFloat(float64(track.Duration), 'G', -1, 32)))
|
Expect(sentParams.Get("duration")).To(Equal(strconv.FormatFloat(float64(track.Duration), 'G', -1, 32)))
|
||||||
Expect(sentParams.Get("mbid")).To(Equal(track.MbzTrackID))
|
Expect(sentParams.Get("mbid")).To(Equal(track.MbzRecordingID))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns ErrNotAuthorized if user is not linked", func() {
|
It("returns ErrNotAuthorized if user is not linked", func() {
|
||||||
|
@ -289,7 +289,7 @@ var _ = Describe("lastfmAgent", func() {
|
||||||
Expect(sentParams.Get("albumArtist")).To(Equal(track.AlbumArtist))
|
Expect(sentParams.Get("albumArtist")).To(Equal(track.AlbumArtist))
|
||||||
Expect(sentParams.Get("trackNumber")).To(Equal(strconv.Itoa(track.TrackNumber)))
|
Expect(sentParams.Get("trackNumber")).To(Equal(strconv.Itoa(track.TrackNumber)))
|
||||||
Expect(sentParams.Get("duration")).To(Equal(strconv.FormatFloat(float64(track.Duration), 'G', -1, 32)))
|
Expect(sentParams.Get("duration")).To(Equal(strconv.FormatFloat(float64(track.Duration), 'G', -1, 32)))
|
||||||
Expect(sentParams.Get("mbid")).To(Equal(track.MbzTrackID))
|
Expect(sentParams.Get("mbid")).To(Equal(track.MbzRecordingID))
|
||||||
Expect(sentParams.Get("timestamp")).To(Equal(strconv.FormatInt(ts.Unix(), 10)))
|
Expect(sentParams.Get("timestamp")).To(Equal(strconv.FormatInt(ts.Unix(), 10)))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ func (l *listenBrainzAgent) formatListen(track *model.MediaFile) listenInfo {
|
||||||
SubmissionClientVersion: consts.Version,
|
SubmissionClientVersion: consts.Version,
|
||||||
TrackNumber: track.TrackNumber,
|
TrackNumber: track.TrackNumber,
|
||||||
ArtistMbzIDs: []string{track.MbzArtistID},
|
ArtistMbzIDs: []string{track.MbzArtistID},
|
||||||
TrackMbzID: track.MbzTrackID,
|
RecordingMbzID: track.MbzRecordingID,
|
||||||
ReleaseMbID: track.MbzAlbumID,
|
ReleaseMbID: track.MbzAlbumID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,14 +32,14 @@ var _ = Describe("listenBrainzAgent", func() {
|
||||||
agent = listenBrainzConstructor(ds)
|
agent = listenBrainzConstructor(ds)
|
||||||
agent.client = newClient("http://localhost:8080", httpClient)
|
agent.client = newClient("http://localhost:8080", httpClient)
|
||||||
track = &model.MediaFile{
|
track = &model.MediaFile{
|
||||||
ID: "123",
|
ID: "123",
|
||||||
Title: "Track Title",
|
Title: "Track Title",
|
||||||
Album: "Track Album",
|
Album: "Track Album",
|
||||||
Artist: "Track Artist",
|
Artist: "Track Artist",
|
||||||
TrackNumber: 1,
|
TrackNumber: 1,
|
||||||
MbzTrackID: "mbz-123",
|
MbzRecordingID: "mbz-123",
|
||||||
MbzAlbumID: "mbz-456",
|
MbzAlbumID: "mbz-456",
|
||||||
MbzArtistID: "mbz-789",
|
MbzArtistID: "mbz-789",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ var _ = Describe("listenBrainzAgent", func() {
|
||||||
"SubmissionClient": Equal(consts.AppName),
|
"SubmissionClient": Equal(consts.AppName),
|
||||||
"SubmissionClientVersion": Equal(consts.Version),
|
"SubmissionClientVersion": Equal(consts.Version),
|
||||||
"TrackNumber": Equal(track.TrackNumber),
|
"TrackNumber": Equal(track.TrackNumber),
|
||||||
"TrackMbzID": Equal(track.MbzTrackID),
|
"RecordingMbzID": Equal(track.MbzRecordingID),
|
||||||
"ReleaseMbID": Equal(track.MbzAlbumID),
|
"ReleaseMbID": Equal(track.MbzAlbumID),
|
||||||
"ArtistMbzIDs": MatchAllElements(idArtistId, Elements{
|
"ArtistMbzIDs": MatchAllElements(idArtistId, Elements{
|
||||||
"mbz-789": Equal(track.MbzArtistID),
|
"mbz-789": Equal(track.MbzArtistID),
|
||||||
|
|
|
@ -76,7 +76,7 @@ type additionalInfo struct {
|
||||||
SubmissionClient string `json:"submission_client,omitempty"`
|
SubmissionClient string `json:"submission_client,omitempty"`
|
||||||
SubmissionClientVersion string `json:"submission_client_version,omitempty"`
|
SubmissionClientVersion string `json:"submission_client_version,omitempty"`
|
||||||
TrackNumber int `json:"tracknumber,omitempty"`
|
TrackNumber int `json:"tracknumber,omitempty"`
|
||||||
TrackMbzID string `json:"track_mbid,omitempty"`
|
RecordingMbzID string `json:"recording_mbid,omitempty"`
|
||||||
ArtistMbzIDs []string `json:"artist_mbids,omitempty"`
|
ArtistMbzIDs []string `json:"artist_mbids,omitempty"`
|
||||||
ReleaseMbID string `json:"release_mbid,omitempty"`
|
ReleaseMbID string `json:"release_mbid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,10 @@ var _ = Describe("client", func() {
|
||||||
TrackName: "Track Title",
|
TrackName: "Track Title",
|
||||||
ReleaseName: "Track Album",
|
ReleaseName: "Track Album",
|
||||||
AdditionalInfo: additionalInfo{
|
AdditionalInfo: additionalInfo{
|
||||||
TrackNumber: 1,
|
TrackNumber: 1,
|
||||||
TrackMbzID: "mbz-123",
|
RecordingMbzID: "mbz-123",
|
||||||
ArtistMbzIDs: []string{"mbz-789"},
|
ArtistMbzIDs: []string{"mbz-789"},
|
||||||
ReleaseMbID: "mbz-456",
|
ReleaseMbID: "mbz-456",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,7 +399,7 @@ func (e *externalMetadata) getMatchingTopSongs(ctx context.Context, agent agents
|
||||||
func (e *externalMetadata) findMatchingTrack(ctx context.Context, mbid string, artistID, title string) (*model.MediaFile, error) {
|
func (e *externalMetadata) findMatchingTrack(ctx context.Context, mbid string, artistID, title string) (*model.MediaFile, error) {
|
||||||
if mbid != "" {
|
if mbid != "" {
|
||||||
mfs, err := e.ds.MediaFile(ctx).GetAll(model.QueryOptions{
|
mfs, err := e.ds.MediaFile(ctx).GetAll(model.QueryOptions{
|
||||||
Filters: squirrel.Eq{"mbz_track_id": mbid},
|
Filters: squirrel.Eq{"mbz_recording_id": mbid},
|
||||||
})
|
})
|
||||||
if err == nil && len(mfs) > 0 {
|
if err == nil && len(mfs) > 0 {
|
||||||
return &mfs[0], nil
|
return &mfs[0], nil
|
||||||
|
|
|
@ -40,16 +40,16 @@ var _ = Describe("PlayTracker", func() {
|
||||||
tracker = newPlayTracker(ds, events.GetBroker())
|
tracker = newPlayTracker(ds, events.GetBroker())
|
||||||
|
|
||||||
track = model.MediaFile{
|
track = model.MediaFile{
|
||||||
ID: "123",
|
ID: "123",
|
||||||
Title: "Track Title",
|
Title: "Track Title",
|
||||||
Album: "Track Album",
|
Album: "Track Album",
|
||||||
AlbumID: "al-1",
|
AlbumID: "al-1",
|
||||||
Artist: "Track Artist",
|
Artist: "Track Artist",
|
||||||
ArtistID: "ar-1",
|
ArtistID: "ar-1",
|
||||||
AlbumArtist: "Track AlbumArtist",
|
AlbumArtist: "Track AlbumArtist",
|
||||||
TrackNumber: 1,
|
TrackNumber: 1,
|
||||||
Duration: 180,
|
Duration: 180,
|
||||||
MbzTrackID: "mbz-123",
|
MbzRecordingID: "mbz-123",
|
||||||
}
|
}
|
||||||
_ = ds.MediaFile(ctx).Put(&track)
|
_ = ds.MediaFile(ctx).Put(&track)
|
||||||
artist = model.Artist{ID: "ar-1"}
|
artist = model.Artist{ID: "ar-1"}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
"github.com/pressly/goose/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
goose.AddMigration(upRenameMusicbrainzRecordingId, downRenameMusicbrainzRecordingId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func upRenameMusicbrainzRecordingId(tx *sql.Tx) error {
|
||||||
|
_, err := tx.Exec(`
|
||||||
|
alter table media_file
|
||||||
|
rename column mbz_track_id to mbz_recording_id;
|
||||||
|
`)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func downRenameMusicbrainzRecordingId(tx *sql.Tx) error {
|
||||||
|
_, err := tx.Exec(`
|
||||||
|
alter table media_file
|
||||||
|
rename column mbz_recording_id to mbz_track_id;
|
||||||
|
`)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -59,7 +59,7 @@ type MediaFile struct {
|
||||||
Lyrics string `structs:"lyrics" json:"lyrics,omitempty"`
|
Lyrics string `structs:"lyrics" json:"lyrics,omitempty"`
|
||||||
Bpm int `structs:"bpm" json:"bpm,omitempty"`
|
Bpm int `structs:"bpm" json:"bpm,omitempty"`
|
||||||
CatalogNum string `structs:"catalog_num" json:"catalogNum,omitempty"`
|
CatalogNum string `structs:"catalog_num" json:"catalogNum,omitempty"`
|
||||||
MbzTrackID string `structs:"mbz_track_id" json:"mbzTrackId,omitempty" orm:"column(mbz_track_id)"`
|
MbzRecordingID string `structs:"mbz_recording_id" json:"mbzRecordingID,omitempty" orm:"column(mbz_recording_id)"`
|
||||||
MbzReleaseTrackID string `structs:"mbz_release_track_id" json:"mbzReleaseTrackId,omitempty" orm:"column(mbz_release_track_id)"`
|
MbzReleaseTrackID string `structs:"mbz_release_track_id" json:"mbzReleaseTrackId,omitempty" orm:"column(mbz_release_track_id)"`
|
||||||
MbzAlbumID string `structs:"mbz_album_id" json:"mbzAlbumId,omitempty" orm:"column(mbz_album_id)"`
|
MbzAlbumID string `structs:"mbz_album_id" json:"mbzAlbumId,omitempty" orm:"column(mbz_album_id)"`
|
||||||
MbzArtistID string `structs:"mbz_artist_id" json:"mbzArtistId,omitempty" orm:"column(mbz_artist_id)"`
|
MbzArtistID string `structs:"mbz_artist_id" json:"mbzArtistId,omitempty" orm:"column(mbz_artist_id)"`
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (s mediaFileMapper) toMediaFile(md metadata.Tags) model.MediaFile {
|
||||||
mf.OrderArtistName = sanitizeFieldForSorting(mf.Artist)
|
mf.OrderArtistName = sanitizeFieldForSorting(mf.Artist)
|
||||||
mf.OrderAlbumArtistName = sanitizeFieldForSorting(mf.AlbumArtist)
|
mf.OrderAlbumArtistName = sanitizeFieldForSorting(mf.AlbumArtist)
|
||||||
mf.CatalogNum = md.CatalogNum()
|
mf.CatalogNum = md.CatalogNum()
|
||||||
mf.MbzTrackID = md.MbzTrackID()
|
mf.MbzRecordingID = md.MbzRecordingID()
|
||||||
mf.MbzReleaseTrackID = md.MbzReleaseTrackID()
|
mf.MbzReleaseTrackID = md.MbzReleaseTrackID()
|
||||||
mf.MbzAlbumID = md.MbzAlbumID()
|
mf.MbzAlbumID = md.MbzAlbumID()
|
||||||
mf.MbzArtistID = md.MbzArtistID()
|
mf.MbzArtistID = md.MbzArtistID()
|
||||||
|
|
|
@ -120,7 +120,9 @@ func (t Tags) MbzReleaseTrackID() string {
|
||||||
return t.getMbzID("musicbrainz_releasetrackid", "musicbrainz release track id")
|
return t.getMbzID("musicbrainz_releasetrackid", "musicbrainz release track id")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Tags) MbzTrackID() string { return t.getMbzID("musicbrainz_trackid", "musicbrainz track id") }
|
func (t Tags) MbzRecordingID() string {
|
||||||
|
return t.getMbzID("musicbrainz_trackid", "musicbrainz track id")
|
||||||
|
}
|
||||||
func (t Tags) MbzAlbumID() string { return t.getMbzID("musicbrainz_albumid", "musicbrainz album id") }
|
func (t Tags) MbzAlbumID() string { return t.getMbzID("musicbrainz_albumid", "musicbrainz album id") }
|
||||||
func (t Tags) MbzArtistID() string {
|
func (t Tags) MbzArtistID() string {
|
||||||
return t.getMbzID("musicbrainz_artistid", "musicbrainz artist id")
|
return t.getMbzID("musicbrainz_artistid", "musicbrainz artist id")
|
||||||
|
|
|
@ -36,7 +36,7 @@ var _ = Describe("Tags", func() {
|
||||||
"musicbrainz_artistid": {"89ad4ac3-39f7-470e-963a-56509c546377"},
|
"musicbrainz_artistid": {"89ad4ac3-39f7-470e-963a-56509c546377"},
|
||||||
"musicbrainz_albumartistid": {"ada7a83c-e3e1-40f1-93f9-3e73dbc9298a"},
|
"musicbrainz_albumartistid": {"ada7a83c-e3e1-40f1-93f9-3e73dbc9298a"},
|
||||||
}
|
}
|
||||||
Expect(md.MbzTrackID()).To(Equal("8f84da07-09a0-477b-b216-cc982dabcde1"))
|
Expect(md.MbzRecordingID()).To(Equal("8f84da07-09a0-477b-b216-cc982dabcde1"))
|
||||||
Expect(md.MbzReleaseTrackID()).To(Equal("6caf16d3-0b20-3fe6-8020-52e31831bc11"))
|
Expect(md.MbzReleaseTrackID()).To(Equal("6caf16d3-0b20-3fe6-8020-52e31831bc11"))
|
||||||
Expect(md.MbzAlbumID()).To(Equal("f68c985d-f18b-4f4a-b7f0-87837cf3fbf9"))
|
Expect(md.MbzAlbumID()).To(Equal("f68c985d-f18b-4f4a-b7f0-87837cf3fbf9"))
|
||||||
Expect(md.MbzArtistID()).To(Equal("89ad4ac3-39f7-470e-963a-56509c546377"))
|
Expect(md.MbzArtistID()).To(Equal("89ad4ac3-39f7-470e-963a-56509c546377"))
|
||||||
|
@ -50,7 +50,7 @@ var _ = Describe("Tags", func() {
|
||||||
"musicbrainz_artistid": {"200455"},
|
"musicbrainz_artistid": {"200455"},
|
||||||
"musicbrainz_albumartistid": {"194"},
|
"musicbrainz_albumartistid": {"194"},
|
||||||
}
|
}
|
||||||
Expect(md.MbzTrackID()).To(Equal(""))
|
Expect(md.MbzRecordingID()).To(Equal(""))
|
||||||
Expect(md.MbzAlbumID()).To(Equal(""))
|
Expect(md.MbzAlbumID()).To(Equal(""))
|
||||||
Expect(md.MbzArtistID()).To(Equal(""))
|
Expect(md.MbzArtistID()).To(Equal(""))
|
||||||
Expect(md.MbzAlbumArtistID()).To(Equal(""))
|
Expect(md.MbzAlbumArtistID()).To(Equal(""))
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"listen_type": "playing_now", "payload": [{"track_metadata": { "artist_name": "Track Artist", "track_name": "Track Title", "release_name": "Track Album", "additional_info": { "tracknumber": 1, "track_mbid": "mbz-123", "artist_mbids": ["mbz-789"], "release_mbid": "mbz-456"}}}]}
|
{"listen_type": "playing_now", "payload": [{"track_metadata": { "artist_name": "Track Artist", "track_name": "Track Title", "release_name": "Track Album", "additional_info": { "tracknumber": 1, "recording_mbid": "mbz-123", "artist_mbids": ["mbz-789"], "release_mbid": "mbz-456"}}}]}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"listen_type": "single", "payload": [{"listened_at": 1635000000, "track_metadata": { "artist_name": "Track Artist", "track_name": "Track Title", "release_name": "Track Album", "additional_info": { "tracknumber": 1, "track_mbid": "mbz-123", "artist_mbids": ["mbz-789"], "release_mbid": "mbz-456"}}}]}
|
{"listen_type": "single", "payload": [{"listened_at": 1635000000, "track_metadata": { "artist_name": "Track Artist", "track_name": "Track Title", "release_name": "Track Album", "additional_info": { "tracknumber": 1, "recording_mbid": "mbz-123", "artist_mbids": ["mbz-789"], "release_mbid": "mbz-456"}}}]}
|
||||||
|
|
Loading…
Reference in New Issue