feat: listenbrainz import

This commit is contained in:
Gabe Farrell 2025-06-12 23:35:17 -04:00
parent 63517c0a03
commit d0d7bd9a4a
9 changed files with 248 additions and 6 deletions

View file

@ -224,6 +224,12 @@ func RunImporter(l *zerolog.Logger, store db.DB, mbzc mbz.MusicBrainzCaller) {
if err != nil {
l.Err(err).Msgf("Failed to import file: %s", file.Name())
}
} else if strings.Contains(file.Name(), "listenbrainz") {
l.Info().Msgf("Import file %s detecting as being ListenBrainz export", file.Name())
err := importer.ImportListenBrainzExport(logger.NewContext(l), store, mbzc, file.Name())
if err != nil {
l.Err(err).Msgf("Failed to import file: %s", file.Name())
}
} else {
l.Warn().Msgf("File %s not recognized as a valid import file; make sure it is valid and named correctly", file.Name())
}

View file

@ -79,12 +79,29 @@ func TestImportLastFM(t *testing.T) {
require.NoError(t, os.WriteFile(dest, input, os.ModePerm))
engine.RunImporter(logger.Get(), store, &mbz.MbzErrorCaller{})
mbzcMock := &mbz.MbzMockCaller{
Artists: map[uuid.UUID]*mbz.MusicBrainzArtist{
uuid.MustParse("4b00640f-3be6-43f8-9b34-ff81bd89320a"): &mbz.MusicBrainzArtist{
Name: "OurR",
Aliases: []mbz.MusicBrainzArtistAlias{
{
Name: "OurR",
Primary: true,
},
},
},
},
}
engine.RunImporter(logger.Get(), store, mbzcMock)
album, err := store.GetAlbum(context.Background(), db.GetAlbumOpts{MusicBrainzID: uuid.MustParse("e9e78802-0bf8-4ca3-9655-1d943d2d2fa0")})
require.NoError(t, err)
assert.Equal(t, "ZOO!!", album.Title)
artist, err := store.GetArtist(context.Background(), db.GetArtistOpts{Name: "CHUU"})
artist, err := store.GetArtist(context.Background(), db.GetArtistOpts{MusicBrainzID: uuid.MustParse("4b00640f-3be6-43f8-9b34-ff81bd89320a")})
require.NoError(t, err)
assert.Equal(t, "OurR", artist.Name)
artist, err = store.GetArtist(context.Background(), db.GetArtistOpts{Name: "CHUU"})
require.NoError(t, err)
track, err := store.GetTrack(context.Background(), db.GetTrackOpts{Title: "because I'm stupid?", ArtistIDs: []int32{artist.ID}})
require.NoError(t, err)
@ -93,3 +110,71 @@ func TestImportLastFM(t *testing.T) {
assert.Len(t, listens.Items, 1)
assert.WithinDuration(t, time.Unix(1749776100, 0), listens.Items[0].Time, 1*time.Second)
}
func TestImportListenBrainz(t *testing.T) {
src := "../static/listenbrainz_shoko1_1749780844.zip"
destDir := filepath.Join(cfg.ConfigDir(), "import")
dest := filepath.Join(destDir, "listenbrainz_shoko1_1749780844.zip")
// not going to make the dest dir because engine should make it already
input, err := os.ReadFile(src)
require.NoError(t, err)
require.NoError(t, os.WriteFile(dest, input, os.ModePerm))
mbzcMock := &mbz.MbzMockCaller{
Artists: map[uuid.UUID]*mbz.MusicBrainzArtist{
uuid.MustParse("4b00640f-3be6-43f8-9b34-ff81bd89320a"): {
Name: "OurR",
Aliases: []mbz.MusicBrainzArtistAlias{
{
Name: "OurR",
Primary: true,
},
},
},
uuid.MustParse("09887aa7-226e-4ecc-9a0c-02d2ae5777e1"): {
Name: "Carly Rae Jepsen",
Aliases: []mbz.MusicBrainzArtistAlias{
{
Name: "Carly Rae Jepsen",
Primary: true,
},
},
},
uuid.MustParse("78e46ae5-9bfd-433b-be3f-19e993d67ecc"): &mbz.MusicBrainzArtist{
Name: "Rufus Wainwright",
Aliases: []mbz.MusicBrainzArtistAlias{
{
Name: "OurR",
Primary: true,
},
},
},
},
}
engine.RunImporter(logger.Get(), store, mbzcMock)
album, err := store.GetAlbum(context.Background(), db.GetAlbumOpts{MusicBrainzID: uuid.MustParse("ce330d67-9c46-4a3b-9d62-08406370f234")})
require.NoError(t, err)
assert.Equal(t, "酸欠少女", album.Title)
artist, err := store.GetArtist(context.Background(), db.GetArtistOpts{MusicBrainzID: uuid.MustParse("4b00640f-3be6-43f8-9b34-ff81bd89320a")})
require.NoError(t, err)
assert.Equal(t, "OurR", artist.Name)
artist, err = store.GetArtist(context.Background(), db.GetArtistOpts{MusicBrainzID: uuid.MustParse("09887aa7-226e-4ecc-9a0c-02d2ae5777e1")})
require.NoError(t, err)
assert.Equal(t, "Carly Rae Jepsen", artist.Name)
artist, err = store.GetArtist(context.Background(), db.GetArtistOpts{MusicBrainzID: uuid.MustParse("78e46ae5-9bfd-433b-be3f-19e993d67ecc")})
require.NoError(t, err)
assert.Equal(t, "Rufus Wainwright", artist.Name)
track, err := store.GetTrack(context.Background(), db.GetTrackOpts{MusicBrainzID: uuid.MustParse("08e8f55b-f1a4-46b8-b2d1-fab4c592165c")})
require.NoError(t, err)
assert.Equal(t, "Desert", track.Title)
listens, err := store.GetListensPaginated(context.Background(), db.GetItemsOpts{TrackID: int(track.ID)})
require.NoError(t, err)
assert.Len(t, listens.Items, 1)
assert.WithinDuration(t, time.Unix(1749780612, 0), listens.Items[0].Time, 1*time.Second)
}