From b49e4d6b126d61e465d980fc2dde0cb24ab7134c Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 10 Jun 2024 08:36:23 +0200 Subject: [PATCH] Reconstruct the artist display name using comma instead of custom separators (nicer display), fixes #445 --- src/libs/metadata/impl/AvFormatTagReader.cpp | 9 +++++++++ src/libs/metadata/impl/AvFormatTagReader.hpp | 1 + src/libs/metadata/impl/ITagReader.hpp | 1 + src/libs/metadata/impl/Parser.cpp | 14 +++++++++++++- src/libs/metadata/impl/TagLibTagReader.cpp | 9 +++++++++ src/libs/metadata/impl/TagLibTagReader.hpp | 1 + src/libs/metadata/test/Parser.cpp | 2 +- src/libs/metadata/test/TestTagReader.hpp | 9 +++++++++ 8 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/libs/metadata/impl/AvFormatTagReader.cpp b/src/libs/metadata/impl/AvFormatTagReader.cpp index f9ba4655..f0f5ca3d 100644 --- a/src/libs/metadata/impl/AvFormatTagReader.cpp +++ b/src/libs/metadata/impl/AvFormatTagReader.cpp @@ -172,6 +172,15 @@ namespace lms::metadata } } + size_t AvFormatTagReader::countTagValues(TagType tag) const + { + size_t count{}; + visitTagValues(tag, [&](std::string_view) { + count++; + }); + return count; + } + void AvFormatTagReader::visitTagValues(TagType tag, TagValueVisitor visitor) const { auto itTagNames{ tagMapping.find(tag) }; diff --git a/src/libs/metadata/impl/AvFormatTagReader.hpp b/src/libs/metadata/impl/AvFormatTagReader.hpp index 15b806b0..3645fc33 100644 --- a/src/libs/metadata/impl/AvFormatTagReader.hpp +++ b/src/libs/metadata/impl/AvFormatTagReader.hpp @@ -37,6 +37,7 @@ namespace lms::metadata AvFormatTagReader(const AvFormatTagReader&) = delete; AvFormatTagReader& operator=(const AvFormatTagReader&) = delete; + size_t countTagValues(TagType tag) const override; void visitTagValues(TagType tag, TagValueVisitor visitor) const override; void visitTagValues(std::string_view tag, TagValueVisitor visitor) const override; void visitPerformerTags(PerformerVisitor visitor) const override; diff --git a/src/libs/metadata/impl/ITagReader.hpp b/src/libs/metadata/impl/ITagReader.hpp index da1a0d8b..44d016da 100644 --- a/src/libs/metadata/impl/ITagReader.hpp +++ b/src/libs/metadata/impl/ITagReader.hpp @@ -148,6 +148,7 @@ namespace lms::metadata virtual ~ITagReader() = default; using TagValueVisitor = std::function; + virtual size_t countTagValues(TagType tag) const = 0; virtual void visitTagValues(TagType tag, TagValueVisitor visitor) const = 0; virtual void visitTagValues(std::string_view tag, TagValueVisitor visitor) const = 0; diff --git a/src/libs/metadata/impl/Parser.cpp b/src/libs/metadata/impl/Parser.cpp index 7d7e3b89..b1a66c39 100644 --- a/src/libs/metadata/impl/Parser.cpp +++ b/src/libs/metadata/impl/Parser.cpp @@ -276,7 +276,6 @@ namespace lms::metadata track.copyright = getTagValueAs(tagReader, TagType::Copyright).value_or(""); track.copyrightURL = getTagValueAs(tagReader, TagType::CopyrightURL).value_or(""); track.replayGain = getTagValueAs(tagReader, TagType::ReplayGainTrackGain); - track.artistDisplayName = getTagValueAs(tagReader, TagType::Artist).value_or(""); // TODO join on artists if present for (const std::string& userExtraTag : _userExtraTags) { @@ -297,6 +296,19 @@ namespace lms::metadata track.medium = getMedium(tagReader); track.artists = getArtists(tagReader, { TagType::Artists, TagType::Artist }, { TagType::ArtistSortOrder }, { TagType::MusicBrainzArtistID }, _artistTagDelimiters); + if (!_artistTagDelimiters.empty() + && track.artists.size() > 1 + && tagReader.countTagValues(TagType::Artist) <= 1 + && tagReader.countTagValues(TagType::Artists) <= 1) + { + std::vector artistNames; + std::transform(std::cbegin(track.artists), std::cend(track.artists), std::back_inserter(artistNames), [](const Artist& artist) -> std::string_view { return artist.name; }); + track.artistDisplayName = core::stringUtils::joinStrings(artistNames, ", "); + } + else + { + track.artistDisplayName = getTagValueAs(tagReader, TagType::Artist).value_or(""); + } track.conductorArtists = getArtists(tagReader, { TagType::Conductors, TagType::Conductor }, { TagType::ConductorsSortOrder, TagType::ConductorSortOrder }, {}, _artistTagDelimiters); track.composerArtists = getArtists(tagReader, { TagType::Composers, TagType::Composer }, { TagType::ComposersSortOrder, TagType::ComposerSortOrder }, {}, _artistTagDelimiters); track.lyricistArtists = getArtists(tagReader, { TagType::Lyricists, TagType::Lyricist }, { TagType::LyricistsSortOrder, TagType::LyricistSortOrder }, {}, _artistTagDelimiters); diff --git a/src/libs/metadata/impl/TagLibTagReader.cpp b/src/libs/metadata/impl/TagLibTagReader.cpp index cdf176fc..822b3cc0 100644 --- a/src/libs/metadata/impl/TagLibTagReader.cpp +++ b/src/libs/metadata/impl/TagLibTagReader.cpp @@ -340,6 +340,15 @@ namespace lms::metadata #endif } + size_t TagLibTagReader::countTagValues(TagType tag) const + { + size_t count{}; + visitTagValues(tag, [&](std::string_view) { + count++; + }); + return count; + } + void TagLibTagReader::visitTagValues(TagType tag, TagValueVisitor visitor) const { auto itTagNames{ tagMapping.find(tag) }; diff --git a/src/libs/metadata/impl/TagLibTagReader.hpp b/src/libs/metadata/impl/TagLibTagReader.hpp index 0b13853d..90fe57ef 100644 --- a/src/libs/metadata/impl/TagLibTagReader.hpp +++ b/src/libs/metadata/impl/TagLibTagReader.hpp @@ -40,6 +40,7 @@ namespace lms::metadata TagLibTagReader& operator=(const TagLibTagReader&) = delete; void computeAudioProperties(); + size_t countTagValues(TagType tag) const override; void visitTagValues(TagType tag, TagValueVisitor visitor) const override; void visitTagValues(std::string_view tag, TagValueVisitor visitor) const override; void visitPerformerTags(PerformerVisitor visitor) const override; diff --git a/src/libs/metadata/test/Parser.cpp b/src/libs/metadata/test/Parser.cpp index 38f0d3d3..0b4833b9 100644 --- a/src/libs/metadata/test/Parser.cpp +++ b/src/libs/metadata/test/Parser.cpp @@ -250,6 +250,6 @@ namespace lms::metadata ASSERT_EQ(track->artists.size(), 2); EXPECT_EQ(track->artists[0].name, "This / is ; One Artist"); EXPECT_EQ(track->artists[1].name, "Other Artist"); - EXPECT_EQ(track->artistDisplayName, "This / is ; One Artist \\ Other Artist"); + EXPECT_EQ(track->artistDisplayName, "This / is ; One Artist, Other Artist"); // reconstruct artist display name since a custom delimiter is hit } } // namespace lms::metadata diff --git a/src/libs/metadata/test/TestTagReader.hpp b/src/libs/metadata/test/TestTagReader.hpp index d27acfaf..647a6c13 100644 --- a/src/libs/metadata/test/TestTagReader.hpp +++ b/src/libs/metadata/test/TestTagReader.hpp @@ -47,6 +47,15 @@ namespace lms::metadata { } + size_t countTagValues(TagType tag) const + { + auto itValues{ _tags.find(tag) }; + if (itValues != std::cend(_tags)) + return itValues->second.size(); + + return 0; + } + void visitTagValues(TagType tag, TagValueVisitor visitor) const override { auto itValues{ _tags.find(tag) };