Added support for release type in metadata parser

This commit is contained in:
emeric
2023-04-04 23:22:27 +02:00
parent 05e746ab3b
commit 4ba7aff628
7 changed files with 207 additions and 3 deletions
+9 -2
View File
@@ -225,6 +225,13 @@ getRelease(const TagMap& tags)
}
}
release->primaryType = getPropertyValueFirstMatchAs<MetaData::Release::PrimaryType>(tags, {"MUSICBRAINZ_ALBUMTYPE", "RELEASETYPE", "MUSICBRAINZ ALBUM TYPE", "MUSICBRAINZ/ALBUM TYPE"});
if (release->primaryType)
{
const auto secondaryTypes {getPropertyValuesFirstMatchAs<MetaData::Release::SecondaryType>(tags, {"MUSICBRAINZ_ALBUMTYPE", "RELEASETYPE", "MUSICBRAINZ ALBUM TYPE", "MUSICBRAINZ/ALBUM TYPE"})};
release->secondaryTypes.assign(std::cbegin(secondaryTypes), std::cend(secondaryTypes));
}
return release;
}
@@ -445,7 +452,7 @@ TagLibParser::parse(const std::filesystem::path& p, bool debug)
for (const auto& [name, attributeList] : tag->attributeListMap())
{
std::string strName {name.to8Bit(true)};
std::string strName {StringUtils::stringToUpper(name.to8Bit(true))};
if (strName.find("WM/") == 0 || tags.find(strName) != std::cend(tags))
continue;
@@ -461,7 +468,7 @@ TagLibParser::parse(const std::filesystem::path& p, bool debug)
if (debug)
std::cout << "ASF property: '" << name << "'" << std::endl;
tags[strName] = std::move(attributes);
tags.emplace(strName, std::move(attributes));
}
}
}
+45
View File
@@ -119,3 +119,48 @@ namespace MetaData::Utils
}
}
namespace StringUtils
{
static bool iequals(std::string_view a, std::string_view b)
{
return std::equal(std::cbegin(a), std::cend(a),
std::cbegin(b), std::cend(b),
[](char a, char b) { return tolower(a) == tolower(b);}
);
}
template<>
std::optional<MetaData::Release::PrimaryType> readAs(std::string_view str)
{
str = stringTrim(str);
if (iequals(str, "album"))
return MetaData::Release::PrimaryType::Album;
else if (iequals(str, "single"))
return MetaData::Release::PrimaryType::Single;
else if (iequals(str, "EP"))
return MetaData::Release::PrimaryType::EP;
else if (iequals(str, "broadcast"))
return MetaData::Release::PrimaryType::Broadcast;
else if (iequals(str, "other"))
return MetaData::Release::PrimaryType::Other;
return std::nullopt;
}
template<>
std::optional<MetaData::Release::SecondaryType> readAs(std::string_view str)
{
str = stringTrim(str);
if (iequals(str, "compilation"))
return MetaData::Release::SecondaryType::Compilation;
else if (iequals(str, "soundtrack"))
return MetaData::Release::SecondaryType::Soundtrack;
else if (iequals(str, "live"))
return MetaData::Release::SecondaryType::Live;
return std::nullopt;
}
}
+9 -1
View File
@@ -38,6 +38,14 @@ namespace MetaData::Utils
// format is "artist name (role)"
PerformerArtist extractPerformerAndRole(std::string_view entry);
}
namespace StringUtils
{
template<>
std::optional<MetaData::Release::PrimaryType> readAs(std::string_view str);
template<>
std::optional<MetaData::Release::SecondaryType> readAs(std::string_view str);
}
@@ -29,6 +29,7 @@
#include <vector>
#include <Wt/WDate.h>
#include "utils/EnumSet.hpp"
#include "utils/UUID.hpp"
namespace MetaData
@@ -51,10 +52,37 @@ namespace MetaData
struct Release
{
// see https://musicbrainz.org/doc/Release_Group/Type
enum class PrimaryType
{
Album,
Single,
EP,
Broadcast,
Other
};
enum class SecondaryType
{
Compilation,
Soundtrack,
Spokenword,
Interview,
Audiobook,
AudioDrama,
Live,
Remix,
DJMix,
Mixtape_Street,
Demo,
};
std::optional<UUID> mbid;
std::string name;
std::vector<Artist> artists;
std::optional<std::size_t> mediumCount;
std::optional<PrimaryType> primaryType;
EnumSet<SecondaryType> secondaryTypes;
};
struct Medium
+57
View File
@@ -115,3 +115,60 @@ TEST(MetaData, extractPerformerAndRole)
EXPECT_EQ(performer.role, testCase.expectedRole) << " str was '" << testCase.str << "'";
}
}
TEST(MetaData, primaryReleaseTypes)
{
using namespace MetaData;
struct TestCase
{
std::string str;
std::optional<Release::PrimaryType> result;
} testCases []
{
{ "", std::nullopt },
{ "album", Release::PrimaryType::Album },
{ "Album", Release::PrimaryType::Album },
{ " Album", Release::PrimaryType::Album },
{ "Album ", Release::PrimaryType::Album },
{ "ep", Release::PrimaryType::EP },
{ " ep ", Release::PrimaryType::EP },
{ "broadcast", Release::PrimaryType::Broadcast },
{ "single", Release::PrimaryType::Single },
{ "other", Release::PrimaryType::Other },
};
for (const TestCase& testCase : testCases)
{
std::optional<Release::PrimaryType> parsed {StringUtils::readAs<Release::PrimaryType>(testCase.str)};
EXPECT_EQ(parsed, testCase.result) << " str was '" << testCase.str << "'";
}
}
TEST(MetaData, secondaryReleaseTypes)
{
using namespace MetaData;
struct TestCase
{
std::string str;
std::optional<Release::SecondaryType> result;
} testCases []
{
{ "", std::nullopt },
{ "compilation", Release::SecondaryType::Compilation },
{ " compilation ", Release::SecondaryType::Compilation },
{ "soundtrack", Release::SecondaryType::Soundtrack },
{ "live", Release::SecondaryType::Live },
{ "demo", Release::SecondaryType::Demo },
};
for (const TestCase& testCase : testCases)
{
std::optional<Release::SecondaryType> parsed {StringUtils::readAs<Release::SecondaryType>(testCase.str)};
EXPECT_EQ(parsed, testCase.result) << " str was '" << testCase.str << "'";
}
}