From ba180ea8474fec824cbd30467c2f915795827778 Mon Sep 17 00:00:00 2001 From: emeric Date: Sat, 2 Mar 2024 23:47:23 +0100 Subject: [PATCH] Added release_group_mbid field to listenbrainz, fixes #416 --- src/libs/database/impl/Migration.cpp | 11 ++++++++++- src/libs/database/include/database/Release.hpp | 4 ++++ src/libs/metadata/impl/Parser.cpp | 1 + src/libs/metadata/include/metadata/IParser.hpp | 1 + src/libs/metadata/test/Parser.cpp | 2 ++ src/libs/services/scanner/impl/ScanStepScanFiles.cpp | 2 ++ .../impl/listenbrainz/ListensSynchronizer.cpp | 6 ++++-- src/tools/metadata/LmsMetadata.cpp | 9 ++++++--- 8 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/libs/database/impl/Migration.cpp b/src/libs/database/impl/Migration.cpp index 9b006d58..746d222b 100644 --- a/src/libs/database/impl/Migration.cpp +++ b/src/libs/database/impl/Migration.cpp @@ -32,7 +32,7 @@ namespace Database { namespace { - static constexpr Version LMS_DATABASE_VERSION{ 53 }; + static constexpr Version LMS_DATABASE_VERSION{ 54 }; } VersionInfo::VersionInfo() @@ -419,6 +419,14 @@ SELECT session.getDboSession().execute("UPDATE scan_settings SET scan_version = scan_version + 1"); } + void migrateFromV53(Session& session) + { + // Add release group mbid + session.getDboSession().execute("ALTER TABLE release ADD group_mbid TEXT NOT NULL DEFAULT ''"); + + // Just increment the scan version of the settings to make the next scheduled scan rescan everything + session.getDboSession().execute("UPDATE scan_settings SET scan_version = scan_version + 1"); + } void doDbMigration(Session& session) { @@ -450,6 +458,7 @@ SELECT {50, migrateFromV50}, {51, migrateFromV51}, {52, migrateFromV52}, + {53, migrateFromV53}, }; { diff --git a/src/libs/database/include/database/Release.hpp b/src/libs/database/include/database/Release.hpp index e0cea3d0..52f5100d 100644 --- a/src/libs/database/include/database/Release.hpp +++ b/src/libs/database/include/database/Release.hpp @@ -146,6 +146,7 @@ namespace Database std::string_view getName() const { return _name; } std::string_view getSortName() const { return _sortName; } std::optional getMBID() const { return UUID::fromString(_MBID); } + std::optional getGroupMBID() const { return UUID::fromString(_groupMBID); } std::optional getTotalDisc() const { return _totalDisc; } std::size_t getDiscCount() const; // may not be total disc (if incomplete for example) std::vector getDiscs() const; @@ -160,6 +161,7 @@ namespace Database void setName(std::string_view name) { _name = name; } void setSortName(std::string_view sortName) { _sortName = sortName; } void setMBID(const std::optional& mbid) { _MBID = mbid ? mbid->getAsString() : ""; } + void setGroupMBID(const std::optional& mbid) { _groupMBID = mbid ? mbid->getAsString() : ""; } void setTotalDisc(std::optional totalDisc) { _totalDisc = totalDisc; } void setArtistDisplayName(std::string_view name) { _artistDisplayName = name; } void clearReleaseTypes(); @@ -177,6 +179,7 @@ namespace Database Wt::Dbo::field(a, _name, "name"); Wt::Dbo::field(a, _sortName, "sort_name"); Wt::Dbo::field(a, _MBID, "mbid"); + Wt::Dbo::field(a, _groupMBID, "group_mbid"); Wt::Dbo::field(a, _totalDisc, "total_disc"); Wt::Dbo::field(a, _artistDisplayName, "artist_display_name"); Wt::Dbo::hasMany(a, _tracks, Wt::Dbo::ManyToOne, "release"); @@ -196,6 +199,7 @@ namespace Database std::string _name; std::string _sortName; std::string _MBID; + std::string _groupMBID; std::optional _totalDisc{}; std::string _artistDisplayName; diff --git a/src/libs/metadata/impl/Parser.cpp b/src/libs/metadata/impl/Parser.cpp index 5ae90fd1..80a10e66 100644 --- a/src/libs/metadata/impl/Parser.cpp +++ b/src/libs/metadata/impl/Parser.cpp @@ -375,6 +375,7 @@ namespace MetaData release->sortName = getTagValueAs(tagReader, TagType::AlbumSortOrder).value_or(""); release->artistDisplayName = getTagValueAs(tagReader, TagType::AlbumArtist).value_or(""); // TODO try to join albumartists if present release->mbid = getTagValueAs(tagReader, TagType::MusicBrainzReleaseID); + release->groupMBID = getTagValueAs(tagReader, TagType::MusicBrainzReleaseGroupID); release->artists = getArtists(tagReader, { TagType::AlbumArtists, TagType::AlbumArtist }, { TagType::AlbumArtistsSortOrder, TagType::AlbumArtistSortOrder }, { TagType::MusicBrainzReleaseArtistID }, _artistTagDelimiters); release->mediumCount = getTagValueAs(tagReader, TagType::TotalDiscs); if (!release->mediumCount) diff --git a/src/libs/metadata/include/metadata/IParser.hpp b/src/libs/metadata/include/metadata/IParser.hpp index 412ad948..a5bcc29c 100644 --- a/src/libs/metadata/include/metadata/IParser.hpp +++ b/src/libs/metadata/include/metadata/IParser.hpp @@ -54,6 +54,7 @@ namespace MetaData struct Release { std::optional mbid; + std::optional groupMBID; std::string name; std::string sortName; std::string artistDisplayName; diff --git a/src/libs/metadata/test/Parser.cpp b/src/libs/metadata/test/Parser.cpp index 2e645639..e1e67ff3 100644 --- a/src/libs/metadata/test/Parser.cpp +++ b/src/libs/metadata/test/Parser.cpp @@ -57,6 +57,7 @@ namespace MetaData { TagType::MusicBrainzTrackID, { "0afb190a-6735-46df-a16d-199f48206e4a" } }, { TagType::MusicBrainzReleaseArtistID, { "6fbf097c-1487-43e8-874b-50dd074398a7", "5ed3d6b3-2aed-4a03-828c-3c4d4f7406e1" } }, { TagType::MusicBrainzReleaseID, { "3fa39992-b786-4585-a70e-85d5cc15ef69" } }, + { TagType::MusicBrainzReleaseGroupID, { "5b1a5a44-8420-4426-9b86-d25dc8d04838" } }, { TagType::MusicBrainzRecordingID, { "bd3fc666-89de-4ac8-93f6-2dbf028ad8d5" } }, { TagType::Producer, { "MyProducer1", "MyProducer2" } }, { TagType::Remixer, { "MyRemixer1", "MyRemixer2" } }, @@ -194,6 +195,7 @@ namespace MetaData EXPECT_EQ(track->medium->release->artists[1].mbid, UUID::fromString("5ed3d6b3-2aed-4a03-828c-3c4d4f7406e1")); ASSERT_TRUE(track->medium->release->mbid.has_value()); EXPECT_EQ(track->medium->release->mbid.value(), UUID::fromString("3fa39992-b786-4585-a70e-85d5cc15ef69")); + EXPECT_EQ(track->medium->release->groupMBID.value(), UUID::fromString("5b1a5a44-8420-4426-9b86-d25dc8d04838")); EXPECT_EQ(track->medium->release->mediumCount, 3); EXPECT_EQ(track->medium->release->name, "MyAlbum"); EXPECT_EQ(track->medium->release->sortName, "MyAlbumSortName"); diff --git a/src/libs/services/scanner/impl/ScanStepScanFiles.cpp b/src/libs/services/scanner/impl/ScanStepScanFiles.cpp index c975bd51..6212b32e 100644 --- a/src/libs/services/scanner/impl/ScanStepScanFiles.cpp +++ b/src/libs/services/scanner/impl/ScanStepScanFiles.cpp @@ -131,6 +131,8 @@ namespace Scanner release.modify()->setName(releaseInfo.name); if (release->getSortName() != releaseInfo.sortName) release.modify()->setSortName(releaseInfo.sortName); + if (release->getGroupMBID() != releaseInfo.groupMBID) + release.modify()->setGroupMBID(releaseInfo.groupMBID); if (release->getTotalDisc() != releaseInfo.mediumCount) release.modify()->setTotalDisc(releaseInfo.mediumCount); if (release->getArtistDisplayName() != releaseInfo.artistDisplayName) diff --git a/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.cpp b/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.cpp index ea04df81..d73c666b 100644 --- a/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.cpp +++ b/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.cpp @@ -65,10 +65,12 @@ namespace Scrobbling::ListenBrainz Wt::Json::Object additionalInfo; additionalInfo["listening_from"] = "LMS"; additionalInfo["duration_ms"] = std::chrono::duration_cast(track->getDuration()).count(); - if (track->getRelease()) + if (const auto release {track->getRelease()}) { - if (auto MBID{ track->getRelease()->getMBID() }) + if (auto MBID{ release->getMBID() }) additionalInfo["release_mbid"] = Wt::Json::Value{ std::string {MBID->getAsString()} }; + if (auto groupMBID{ release->getGroupMBID() }) + additionalInfo["release_group_mbid"] = Wt::Json::Value{ std::string {groupMBID->getAsString()} }; } { diff --git a/src/tools/metadata/LmsMetadata.cpp b/src/tools/metadata/LmsMetadata.cpp index bee33735..a6dab0a2 100644 --- a/src/tools/metadata/LmsMetadata.cpp +++ b/src/tools/metadata/LmsMetadata.cpp @@ -48,13 +48,16 @@ namespace std::ostream& operator<<(std::ostream& os, const MetaData::Release& release) { os << release.name; - - if (release.mbid) - os << " (" << release.mbid->getAsString() << ")"; if (!release.sortName.empty()) os << " '" << release.sortName << "'"; os << std::endl; + if (release.mbid) + os << "\tRelease MBID = " << release.mbid->getAsString() << std::endl; + + if (release.groupMBID) + os << "\tRelease Group MBID = " << release.groupMBID->getAsString() << std::endl; + if (release.mediumCount) std::cout << "\tMediumCount: " << *release.mediumCount << std::endl;