Adding support for partial dates (only year or month), fixes #477
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <span>
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/PartialDateTime.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
|
||||
@@ -360,44 +361,27 @@ namespace lms::metadata
|
||||
track.recordingMBID = getTagValueAs<core::UUID>(tagReader, TagType::MusicBrainzRecordingID);
|
||||
track.acoustID = getTagValueAs<core::UUID>(tagReader, TagType::AcoustID);
|
||||
track.position = getTagValueAs<std::size_t>(tagReader, TagType::TrackNumber); // May parse 'Number/Total', that's fine
|
||||
if (auto dateStr = getTagValueAs<std::string>(tagReader, TagType::Date))
|
||||
if (const auto dateStr{ getTagValueAs<std::string>(tagReader, TagType::Date) })
|
||||
{
|
||||
if (const Wt::WDate date{ utils::parseDate(*dateStr) }; date.isValid())
|
||||
{
|
||||
if (const core::PartialDateTime date{ core::PartialDateTime::fromString(*dateStr) }; date.isValid())
|
||||
track.date = date;
|
||||
track.year = date.year();
|
||||
}
|
||||
else
|
||||
{
|
||||
track.year = utils::parseYear(*dateStr);
|
||||
}
|
||||
}
|
||||
if (auto dateStr = getTagValueAs<std::string>(tagReader, TagType::OriginalReleaseDate))
|
||||
if (const auto dateStr = getTagValueAs<std::string>(tagReader, TagType::OriginalReleaseDate))
|
||||
{
|
||||
if (const Wt::WDate date{ utils::parseDate(*dateStr) }; date.isValid())
|
||||
{
|
||||
if (const core::PartialDateTime date{ core::PartialDateTime::fromString(*dateStr) }; date.isValid())
|
||||
track.originalDate = date;
|
||||
track.originalYear = date.year();
|
||||
}
|
||||
else
|
||||
{
|
||||
track.originalYear = utils::parseYear(*dateStr);
|
||||
}
|
||||
}
|
||||
if (auto dateStr = getTagValueAs<std::string>(tagReader, TagType::OriginalReleaseYear))
|
||||
{
|
||||
if (const auto dateStr{ getTagValueAs<std::string>(tagReader, TagType::OriginalReleaseYear) })
|
||||
track.originalYear = utils::parseYear(*dateStr);
|
||||
|
||||
if (const auto encodingTimeStr{ getTagValueAs<std::string>(tagReader, TagType::EncodingTime) })
|
||||
{
|
||||
if (const core::PartialDateTime date{ core::PartialDateTime::fromString(*encodingTimeStr) }; date.isValid())
|
||||
track.encodingTime = date;
|
||||
}
|
||||
|
||||
track.advisory = getAdvisory(tagReader);
|
||||
|
||||
if (const auto encodingTime{ getTagValueAs<std::string>(tagReader, TagType::EncodingTime) })
|
||||
{
|
||||
if (auto dateTime{ core::stringUtils::fromISO8601String(*encodingTime) }; dateTime.isValid())
|
||||
track.encodingTime = dateTime;
|
||||
else if (const Wt::WDate date{ utils::parseDate(*encodingTime) }; date.isValid())
|
||||
track.encodingTime = Wt::WDateTime{ date };
|
||||
}
|
||||
track.lyrics = getLyrics(tagReader); // no custom delimiter on lyrics
|
||||
track.comments = getTagValuesAs<std::string>(tagReader, TagType::Comment, {} /* no custom delimiter on comments */);
|
||||
track.copyright = getTagValueAs<std::string>(tagReader, TagType::Copyright).value_or("");
|
||||
@@ -432,13 +416,9 @@ namespace lms::metadata
|
||||
track.remixerArtists = getArtists(tagReader, { TagType::Remixers, TagType::Remixer }, { TagType::RemixersSortOrder, TagType::RemixerSortOrder }, {}, _artistTagDelimiters, _defaultTagDelimiters);
|
||||
track.performerArtists = getPerformerArtists(tagReader); // artistDelimiters not supported
|
||||
|
||||
// If a file has date but no year, set it
|
||||
if (!track.year && track.date.isValid())
|
||||
track.year = track.date.year();
|
||||
|
||||
// If a file has originalDate but no originalYear, set it
|
||||
if (!track.originalYear && track.originalDate.isValid())
|
||||
track.originalYear = track.originalDate.year();
|
||||
if (!track.originalYear)
|
||||
track.originalYear = track.originalDate.getYear();
|
||||
}
|
||||
|
||||
std::optional<Medium> Parser::getMedium(const ITagReader& tagReader)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
@@ -26,9 +26,7 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <Wt/WDate.h>
|
||||
#include <Wt/WDateTime.h>
|
||||
|
||||
#include "core/PartialDateTime.hpp"
|
||||
#include "core/UUID.hpp"
|
||||
|
||||
#include "Lyrics.hpp"
|
||||
@@ -120,12 +118,11 @@ namespace lms::metadata
|
||||
std::vector<std::string> moods;
|
||||
std::vector<std::string> languages;
|
||||
Tags userExtraTags;
|
||||
std::optional<int> year{};
|
||||
Wt::WDate date;
|
||||
std::optional<int> originalYear{};
|
||||
Wt::WDate originalDate;
|
||||
core::PartialDateTime date;
|
||||
std::optional<int> originalYear;
|
||||
core::PartialDateTime originalDate;
|
||||
std::optional<Advisory> advisory;
|
||||
Wt::WDateTime encodingTime;
|
||||
core::PartialDateTime encodingTime;
|
||||
bool hasCover{};
|
||||
std::optional<core::UUID> acoustID;
|
||||
std::string copyright;
|
||||
|
||||
@@ -125,9 +125,9 @@ namespace lms::metadata
|
||||
EXPECT_EQ(track->copyright, "MyCopyright");
|
||||
EXPECT_EQ(track->copyrightURL, "MyCopyrightURL");
|
||||
ASSERT_TRUE(track->date.isValid());
|
||||
EXPECT_EQ(track->date.year(), 2020);
|
||||
EXPECT_EQ(track->date.month(), 3);
|
||||
EXPECT_EQ(track->date.day(), 4);
|
||||
EXPECT_EQ(track->date.getYear(), 2020);
|
||||
EXPECT_EQ(track->date.getMonth(), 3);
|
||||
EXPECT_EQ(track->date.getDay(), 4);
|
||||
EXPECT_FALSE(track->hasCover);
|
||||
ASSERT_EQ(track->genres.size(), 2);
|
||||
EXPECT_EQ(track->genres[0], "Genre1");
|
||||
@@ -157,9 +157,9 @@ namespace lms::metadata
|
||||
EXPECT_EQ(track->moods[0], "Mood1");
|
||||
EXPECT_EQ(track->moods[1], "Mood2");
|
||||
ASSERT_TRUE(track->originalDate.isValid());
|
||||
EXPECT_EQ(track->originalDate.year(), 2019);
|
||||
EXPECT_EQ(track->originalDate.month(), 2);
|
||||
EXPECT_EQ(track->originalDate.day(), 3);
|
||||
EXPECT_EQ(track->originalDate.getYear(), 2019);
|
||||
EXPECT_EQ(track->originalDate.getMonth(), 2);
|
||||
EXPECT_EQ(track->originalDate.getDay(), 3);
|
||||
ASSERT_TRUE(track->originalYear.has_value());
|
||||
EXPECT_EQ(track->originalYear.value(), 2019);
|
||||
ASSERT_TRUE(track->performerArtists.contains("Rolea"));
|
||||
@@ -188,8 +188,6 @@ namespace lms::metadata
|
||||
ASSERT_EQ(track->userExtraTags["MY_AWESOME_TAG_B"].size(), 2);
|
||||
EXPECT_EQ(track->userExtraTags["MY_AWESOME_TAG_B"][0], "MyTagValue1ForTagB");
|
||||
EXPECT_EQ(track->userExtraTags["MY_AWESOME_TAG_B"][1], "MyTagValue2ForTagB");
|
||||
ASSERT_TRUE(track->year.has_value());
|
||||
EXPECT_EQ(track->year.value(), 2020);
|
||||
|
||||
// Medium
|
||||
ASSERT_TRUE(track->medium.has_value());
|
||||
@@ -615,7 +613,7 @@ namespace lms::metadata
|
||||
|
||||
TEST(Parser, encodingTime)
|
||||
{
|
||||
auto doTest = [](std::string_view value, Wt::WDateTime expectedValue) {
|
||||
auto doTest = [](std::string_view value, core::PartialDateTime expectedValue) {
|
||||
const TestTagReader testTags{
|
||||
{
|
||||
{ TagType::EncodingTime, { value } },
|
||||
@@ -628,10 +626,36 @@ namespace lms::metadata
|
||||
ASSERT_EQ(track->encodingTime, expectedValue) << "Value = '" << value << "'";
|
||||
};
|
||||
|
||||
doTest("", Wt::WDateTime{});
|
||||
doTest("foo", Wt::WDateTime{});
|
||||
doTest("2020-01-03T09:08:11.075", Wt::WDateTime{ Wt::WDate{ 2020, 01, 03 }, Wt::WTime{ 9, 8, 11, 75 } });
|
||||
doTest("2020-01-03", Wt::WDateTime{ Wt::WDate{ 2020, 01, 03 } });
|
||||
doTest("2020/01/03", Wt::WDateTime{ Wt::WDate{ 2020, 01, 03 } });
|
||||
doTest("", core::PartialDateTime{});
|
||||
doTest("foo", core::PartialDateTime{});
|
||||
doTest("2020-01-03T09:08:11.075", core::PartialDateTime{ 2020, 01, 03, 9, 8, 11 });
|
||||
doTest("2020-01-03", core::PartialDateTime{ 2020, 01, 03 });
|
||||
doTest("2020/01/03", core::PartialDateTime{ 2020, 01, 03 });
|
||||
}
|
||||
|
||||
TEST(Parser, date)
|
||||
{
|
||||
auto doTest = [](std::string_view value, core::PartialDateTime expectedValue) {
|
||||
const TestTagReader testTags{
|
||||
{
|
||||
{ TagType::Date, { value } },
|
||||
}
|
||||
};
|
||||
|
||||
Parser parser;
|
||||
std::unique_ptr<Track> track{ Parser{}.parse(testTags) };
|
||||
|
||||
ASSERT_EQ(track->date, expectedValue) << "Value = '" << value << "'";
|
||||
};
|
||||
|
||||
doTest("", core::PartialDateTime{});
|
||||
doTest("foo", core::PartialDateTime{});
|
||||
doTest("2020-01-03", core::PartialDateTime{ 2020, 01, 03 });
|
||||
doTest("2020-01", core::PartialDateTime{ 2020, 1 });
|
||||
doTest("2020", core::PartialDateTime{ 2020 });
|
||||
doTest("2020/01/03", core::PartialDateTime{ 2020, 01, 03 });
|
||||
doTest("2020/01", core::PartialDateTime{ 2020, 1 });
|
||||
doTest("2020", core::PartialDateTime{ 2020 });
|
||||
}
|
||||
|
||||
} // namespace lms::metadata
|
||||
|
||||
Reference in New Issue
Block a user