Auto reformatted the base, ref #470
This commit is contained in:
@@ -23,9 +23,10 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "av/IAudioFile.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace lms::metadata
|
||||
@@ -33,8 +34,7 @@ namespace lms::metadata
|
||||
namespace
|
||||
{
|
||||
// Mapping to internal avformat names and/or common alternative custom names
|
||||
static const std::unordered_map<TagType, std::vector<std::string>> tagMapping
|
||||
{
|
||||
static const std::unordered_map<TagType, std::vector<std::string>> tagMapping{
|
||||
{ TagType::AcoustID, { "ACOUSTID_ID", "ACOUSTID ID" } },
|
||||
{ TagType::Album, { "ALBUM", "TALB", "WM/ALBUMTITLE" } },
|
||||
{ TagType::AlbumArtist, { "ALBUMARTIST", "ALBUM_ARTIST" } },
|
||||
@@ -64,7 +64,7 @@ namespace lms::metadata
|
||||
{ TagType::CopyrightURL, { "COPYRIGHTURL" } },
|
||||
{ TagType::Date, { "DATE", "YEAR", "WM/YEAR" } },
|
||||
{ TagType::Director, { "DIRECTOR" } },
|
||||
{ TagType::DiscNumber, { "TPOS", "DISC", "DISK", "DISCNUMBER", "WM/PARTOFSET" } },
|
||||
{ TagType::DiscNumber, { "TPOS", "DISC", "DISK", "DISCNUMBER", "WM/PARTOFSET" } },
|
||||
{ TagType::DiscSubtitle, { "TSST", "DISCSUBTITLE", "SETSUBTITLE" } },
|
||||
{ TagType::EncodedBy, { "ENCODEDBY" } },
|
||||
{ TagType::Engineer, { "ENGINEER" } },
|
||||
@@ -129,7 +129,7 @@ namespace lms::metadata
|
||||
{ TagType::Script, { "SCRIPT", "WM/SCRIPT" } },
|
||||
{ TagType::ShowWorkAndMovement, { "SHOWWORKMOVEMENT", "SHOWMOVEMENT" } },
|
||||
{ TagType::Subtitle, { "SUBTITLE" } },
|
||||
{ TagType::TotalDiscs, { "DISCTOTAL", "TOTALDISCS"} },
|
||||
{ TagType::TotalDiscs, { "DISCTOTAL", "TOTALDISCS" } },
|
||||
{ TagType::TotalTracks, { "TRACKTOTAL", "TOTALTRACKS" } },
|
||||
{ TagType::TrackNumber, { "TRCK", "TRACK", "TRACKNUMBER", "TRKN", "WM/TRACKNUMBER" } },
|
||||
{ TagType::TrackTitle, { "TITLE" } },
|
||||
@@ -137,14 +137,14 @@ namespace lms::metadata
|
||||
{ TagType::WorkTitle, { "WORK" } },
|
||||
{ TagType::Writer, { "WRITER" } },
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
AvFormatTagReader::AvFormatTagReader(const std::filesystem::path& p, bool debug)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto audioFile{ av::parseAudioFile(p) };
|
||||
|
||||
|
||||
_audioProperties.duration = audioFile->getContainerInfo().duration;
|
||||
|
||||
const auto bestAudioStream{ audioFile->getBestStreamInfo() };
|
||||
@@ -182,11 +182,10 @@ namespace lms::metadata
|
||||
{
|
||||
bool visited{};
|
||||
|
||||
visitTagValues(tagName, [&](std::string_view value)
|
||||
{
|
||||
visited = true;
|
||||
visitor(value);
|
||||
});
|
||||
visitTagValues(tagName, [&](std::string_view value) {
|
||||
visited = true;
|
||||
visitor(value);
|
||||
});
|
||||
|
||||
if (visited)
|
||||
break;
|
||||
@@ -204,8 +203,7 @@ namespace lms::metadata
|
||||
|
||||
void AvFormatTagReader::visitPerformerTags(PerformerVisitor visitor) const
|
||||
{
|
||||
visitTagValues("PERFORMER", [&](std::string_view value)
|
||||
{
|
||||
visitTagValues("PERFORMER", [&](std::string_view value) {
|
||||
visitor("", value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,13 +23,14 @@
|
||||
|
||||
#include "av/IAudioFile.hpp"
|
||||
#include "metadata/IParser.hpp"
|
||||
|
||||
#include "ITagReader.hpp"
|
||||
|
||||
namespace lms::metadata
|
||||
{
|
||||
class AvFormatTagReader : public ITagReader
|
||||
{
|
||||
public:
|
||||
public:
|
||||
AvFormatTagReader(const std::filesystem::path& path, bool debug);
|
||||
|
||||
private:
|
||||
@@ -48,4 +49,3 @@ namespace lms::metadata
|
||||
bool _hasEmbeddedCover{};
|
||||
};
|
||||
} // namespace lms::metadata
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
#include <span>
|
||||
|
||||
#include "metadata/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
|
||||
#include "AvFormatTagReader.hpp"
|
||||
#include "TagLibTagReader.hpp"
|
||||
@@ -35,29 +35,27 @@ namespace lms::metadata
|
||||
{
|
||||
void visitTagValues(const ITagReader& tagReader, std::string_view tagType, std::span<const std::string> tagDelimiters, ITagReader::TagValueVisitor visitor)
|
||||
{
|
||||
tagReader.visitTagValues(tagType, [&](std::string_view value)
|
||||
tagReader.visitTagValues(tagType, [&](std::string_view value) {
|
||||
auto visitTagIfNonEmpty{ [&](std::string_view tag) {
|
||||
tag = core::stringUtils::stringTrim(tag);
|
||||
if (!tag.empty())
|
||||
visitor(tag);
|
||||
} };
|
||||
|
||||
for (std::string_view tagDelimiter : tagDelimiters)
|
||||
{
|
||||
auto visitTagIfNonEmpty{ [&](std::string_view tag)
|
||||
if (value.find(tagDelimiter) != std::string_view::npos)
|
||||
{
|
||||
tag = core::stringUtils::stringTrim(tag);
|
||||
if (!tag.empty())
|
||||
visitor(tag);
|
||||
} };
|
||||
for (std::string_view splitTag : core::stringUtils::splitString(value, tagDelimiter))
|
||||
visitTagIfNonEmpty(splitTag);
|
||||
|
||||
for (std::string_view tagDelimiter : tagDelimiters)
|
||||
{
|
||||
if (value.find(tagDelimiter) != std::string_view::npos)
|
||||
{
|
||||
for (std::string_view splitTag : core::stringUtils::splitString(value, tagDelimiter))
|
||||
visitTagIfNonEmpty(splitTag);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// no delimiter found, or no delimiter to be used
|
||||
visitTagIfNonEmpty(value);
|
||||
});
|
||||
// no delimiter found, or no delimiter to be used
|
||||
visitTagIfNonEmpty(value);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -67,8 +65,7 @@ namespace lms::metadata
|
||||
|
||||
for (const TagType tagType : tagTypes)
|
||||
{
|
||||
auto addTagIfNonEmpty{ [&res](std::string_view tag)
|
||||
{
|
||||
auto addTagIfNonEmpty{ [&res](std::string_view tag) {
|
||||
tag = core::stringUtils::stringTrim(tag);
|
||||
if (!tag.empty())
|
||||
{
|
||||
@@ -78,22 +75,21 @@ namespace lms::metadata
|
||||
}
|
||||
} };
|
||||
|
||||
tagReader.visitTagValues(tagType, [&](std::string_view value)
|
||||
tagReader.visitTagValues(tagType, [&](std::string_view value) {
|
||||
for (std::string_view tagDelimiter : tagDelimiters)
|
||||
{
|
||||
for (std::string_view tagDelimiter : tagDelimiters)
|
||||
if (value.find(tagDelimiter) != std::string_view::npos)
|
||||
{
|
||||
if (value.find(tagDelimiter) != std::string_view::npos)
|
||||
{
|
||||
for (std::string_view splitTag : core::stringUtils::splitString(value, tagDelimiter))
|
||||
addTagIfNonEmpty(splitTag);
|
||||
for (std::string_view splitTag : core::stringUtils::splitString(value, tagDelimiter))
|
||||
addTagIfNonEmpty(splitTag);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// no delimiter found, or no delimiter to be used
|
||||
addTagIfNonEmpty(value);
|
||||
});
|
||||
// no delimiter found, or no delimiter to be used
|
||||
addTagIfNonEmpty(value);
|
||||
});
|
||||
|
||||
if (!res.empty())
|
||||
break;
|
||||
@@ -102,7 +98,7 @@ namespace lms::metadata
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
std::optional<T> getTagValueFirstMatchAs(const ITagReader& tagReader, std::initializer_list<TagType> tagTypes)
|
||||
{
|
||||
std::optional<T> res;
|
||||
@@ -113,13 +109,13 @@ namespace lms::metadata
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
std::vector<T> getTagValuesAs(const ITagReader& tagReader, TagType tagType, std::span<const std::string> tagDelimiters)
|
||||
{
|
||||
return getTagValuesFirstMatchAs<T>(tagReader, { tagType }, tagDelimiters);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
std::optional<T> getTagValueAs(const ITagReader& tagReader, TagType tagType)
|
||||
{
|
||||
return getTagValueFirstMatchAs<T>(tagReader, { tagType });
|
||||
@@ -129,8 +125,7 @@ namespace lms::metadata
|
||||
std::initializer_list<TagType> artistTagNames,
|
||||
std::initializer_list<TagType> artistSortTagNames,
|
||||
std::initializer_list<TagType> artistMBIDTagNames,
|
||||
std::span<const std::string> artistTagDelimiters
|
||||
)
|
||||
std::span<const std::string> artistTagDelimiters)
|
||||
{
|
||||
std::vector<std::string> artistNames{ getTagValuesFirstMatchAs<std::string>(tagReader, artistTagNames, artistTagDelimiters) };
|
||||
if (artistNames.empty())
|
||||
@@ -159,29 +154,28 @@ namespace lms::metadata
|
||||
{
|
||||
PerformerContainer performers;
|
||||
|
||||
tagReader.visitPerformerTags([&](std::string_view role, std::string_view name)
|
||||
tagReader.visitPerformerTags([&](std::string_view role, std::string_view name) {
|
||||
// picard stores like this: (see https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html#performer)
|
||||
// We consider we may hit both styles for the same track
|
||||
if (role.empty())
|
||||
{
|
||||
// picard stores like this: (see https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html#performer)
|
||||
// We consider we may hit both styles for the same track
|
||||
if (role.empty())
|
||||
{
|
||||
// "PERFORMER" "artist (role)"
|
||||
utils::PerformerArtist performer{ utils::extractPerformerAndRole(name) };
|
||||
core::stringUtils::capitalize(performer.role);
|
||||
performers[performer.role].push_back(std::move(performer.artist));
|
||||
}
|
||||
else
|
||||
{
|
||||
// "PERFORMER:role", "artist" (MP3)
|
||||
std::string roleCapitalized{ core::stringUtils::stringToLower(role) };
|
||||
core::stringUtils::capitalize(roleCapitalized);
|
||||
performers[roleCapitalized].push_back(Artist{ name });
|
||||
}
|
||||
});
|
||||
// "PERFORMER" "artist (role)"
|
||||
utils::PerformerArtist performer{ utils::extractPerformerAndRole(name) };
|
||||
core::stringUtils::capitalize(performer.role);
|
||||
performers[performer.role].push_back(std::move(performer.artist));
|
||||
}
|
||||
else
|
||||
{
|
||||
// "PERFORMER:role", "artist" (MP3)
|
||||
std::string roleCapitalized{ core::stringUtils::stringToLower(role) };
|
||||
core::stringUtils::capitalize(roleCapitalized);
|
||||
performers[roleCapitalized].push_back(Artist{ name });
|
||||
}
|
||||
});
|
||||
|
||||
return performers;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<IParser> createParser(ParserBackend parserBackend, ParserReadStyle parserReadStyle)
|
||||
{
|
||||
@@ -286,12 +280,11 @@ namespace lms::metadata
|
||||
|
||||
for (const std::string& userExtraTag : _userExtraTags)
|
||||
{
|
||||
visitTagValues(tagReader, userExtraTag, _defaultTagDelimiters, [&](std::string_view value)
|
||||
{
|
||||
value = core::stringUtils::stringTrim(value);
|
||||
if (!value.empty())
|
||||
track.userExtraTags[userExtraTag].push_back(std::string{ value });
|
||||
});
|
||||
visitTagValues(tagReader, userExtraTag, _defaultTagDelimiters, [&](std::string_view value) {
|
||||
value = core::stringUtils::stringTrim(value);
|
||||
if (!value.empty())
|
||||
track.userExtraTags[userExtraTag].push_back(std::string{ value });
|
||||
});
|
||||
}
|
||||
|
||||
track.genres = getTagValuesAs<std::string>(tagReader, TagType::Genre, _defaultTagDelimiters);
|
||||
@@ -321,7 +314,6 @@ namespace lms::metadata
|
||||
track.originalYear = track.originalDate.year();
|
||||
}
|
||||
|
||||
|
||||
std::optional<Medium> Parser::getMedium(const ITagReader& tagReader)
|
||||
{
|
||||
std::optional<Medium> medium;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "metadata/IParser.hpp"
|
||||
|
||||
#include "ITagReader.hpp"
|
||||
|
||||
namespace lms::metadata
|
||||
@@ -50,4 +51,3 @@ namespace lms::metadata
|
||||
std::vector<std::string> _defaultTagDelimiters;
|
||||
};
|
||||
} // namespace lms::metadata
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
#include <taglib/apetag.h>
|
||||
#include <taglib/asffile.h>
|
||||
#if TAGLIB_MAJOR_VERSION >= 2
|
||||
#include <taglib/dsffile.h>
|
||||
#include <taglib/dsffile.h>
|
||||
#endif
|
||||
#include <taglib/id3v2tag.h>
|
||||
#include <taglib/fileref.h>
|
||||
#include <taglib/flacfile.h>
|
||||
#include <taglib/id3v2tag.h>
|
||||
#include <taglib/mp4file.h>
|
||||
#include <taglib/mpcfile.h>
|
||||
#include <taglib/mpegfile.h>
|
||||
@@ -39,20 +39,21 @@
|
||||
#include <taglib/vorbisfile.h>
|
||||
#include <taglib/wavpackfile.h>
|
||||
|
||||
#include "metadata/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/ITraceLogger.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
|
||||
namespace lms::metadata
|
||||
{
|
||||
namespace
|
||||
{
|
||||
class ParsingFailedException : public Exception {};
|
||||
class ParsingFailedException : public Exception
|
||||
{
|
||||
};
|
||||
|
||||
// Mapping to internal taglib names and/or common alternative custom names
|
||||
static const std::unordered_map<TagType, std::vector<std::string>> tagMapping
|
||||
{
|
||||
static const std::unordered_map<TagType, std::vector<std::string>> tagMapping{
|
||||
{ TagType::AcoustID, { "ACOUSTID_ID", "ACOUSTID ID" } },
|
||||
{ TagType::Album, { "ALBUM" } },
|
||||
{ TagType::AlbumArtist, { "ALBUMARTIST" } },
|
||||
@@ -147,7 +148,7 @@ namespace lms::metadata
|
||||
{ TagType::Script, { "SCRIPT" } },
|
||||
{ TagType::ShowWorkAndMovement, { "SHOWWORKMOVEMENT", "SHOWMOVEMENT" } },
|
||||
{ TagType::Subtitle, { "SUBTITLE" } },
|
||||
{ TagType::TotalDiscs, { "DISCTOTAL", "TOTALDISCS"} },
|
||||
{ TagType::TotalDiscs, { "DISCTOTAL", "TOTALDISCS" } },
|
||||
{ TagType::TotalTracks, { "TRACKTOTAL", "TOTALTRACKS" } },
|
||||
{ TagType::TrackNumber, { "TRACKNUMBER" } },
|
||||
{ TagType::TrackTitle, { "TITLE" } },
|
||||
@@ -160,9 +161,12 @@ namespace lms::metadata
|
||||
{
|
||||
switch (readStyle)
|
||||
{
|
||||
case ParserReadStyle::Fast: return TagLib::AudioProperties::ReadStyle::Fast;
|
||||
case ParserReadStyle::Average: return TagLib::AudioProperties::ReadStyle::Average;
|
||||
case ParserReadStyle::Accurate: return TagLib::AudioProperties::ReadStyle::Accurate;
|
||||
case ParserReadStyle::Fast:
|
||||
return TagLib::AudioProperties::ReadStyle::Fast;
|
||||
case ParserReadStyle::Average:
|
||||
return TagLib::AudioProperties::ReadStyle::Average;
|
||||
case ParserReadStyle::Accurate:
|
||||
return TagLib::AudioProperties::ReadStyle::Accurate;
|
||||
}
|
||||
|
||||
throw core::LmsException{ "Cannot convert read style" };
|
||||
@@ -181,11 +185,11 @@ namespace lms::metadata
|
||||
{
|
||||
LMS_SCOPED_TRACE_DETAILED("MetaData", "TagLibParseFile");
|
||||
|
||||
return TagLib::FileRef{ p.string().c_str()
|
||||
, true // read audio properties
|
||||
, readStyleToTagLibReadStyle(parserReadStyle) };
|
||||
return TagLib::FileRef{ p.string().c_str(), true // read audio properties
|
||||
,
|
||||
readStyleToTagLibReadStyle(parserReadStyle) };
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TagLibTagReader::TagLibTagReader(const std::filesystem::path& p, ParserReadStyle parserReadStyle, bool debug)
|
||||
: _file{ parseFile(p, parserReadStyle) }
|
||||
@@ -207,13 +211,12 @@ namespace lms::metadata
|
||||
_propertyMap = _file.file()->properties();
|
||||
|
||||
// Some tags may not be known by TagLib
|
||||
auto getAPETags = [&](const TagLib::APE::Tag* apeTag)
|
||||
{
|
||||
if (!apeTag)
|
||||
return;
|
||||
auto getAPETags = [&](const TagLib::APE::Tag* apeTag) {
|
||||
if (!apeTag)
|
||||
return;
|
||||
|
||||
mergeTagMaps(_propertyMap, apeTag->properties());
|
||||
};
|
||||
mergeTagMaps(_propertyMap, apeTag->properties());
|
||||
};
|
||||
|
||||
// Not that good embedded pictures handling
|
||||
// + get some extra tags that may not be known by taglib
|
||||
@@ -263,7 +266,7 @@ namespace lms::metadata
|
||||
|
||||
getAPETags(mp3File->APETag());
|
||||
}
|
||||
//MP4
|
||||
// MP4
|
||||
else if (TagLib::MP4::File * mp4File{ dynamic_cast<TagLib::MP4::File*>(_file.file()) })
|
||||
{
|
||||
TagLib::MP4::Item coverItem{ mp4File->tag()->item("covr") };
|
||||
@@ -321,18 +324,18 @@ namespace lms::metadata
|
||||
_audioProperties.duration = std::chrono::milliseconds{ properties->lengthInMilliseconds() };
|
||||
_audioProperties.sampleRate = static_cast<std::size_t>(properties->sampleRate());
|
||||
|
||||
if (const auto * apeProperties{ dynamic_cast<const TagLib::APE::Properties*>(properties) })
|
||||
if (const auto* apeProperties{ dynamic_cast<const TagLib::APE::Properties*>(properties) })
|
||||
_audioProperties.bitsPerSample = apeProperties->bitsPerSample();
|
||||
if (const auto * asfProperties{ dynamic_cast<const TagLib::ASF::Properties*>(properties) })
|
||||
if (const auto* asfProperties{ dynamic_cast<const TagLib::ASF::Properties*>(properties) })
|
||||
_audioProperties.bitsPerSample = asfProperties->bitsPerSample();
|
||||
else if (const auto * flacProperties{ dynamic_cast<const TagLib::FLAC::Properties*>(properties) })
|
||||
else if (const auto* flacProperties{ dynamic_cast<const TagLib::FLAC::Properties*>(properties) })
|
||||
_audioProperties.bitsPerSample = flacProperties->bitsPerSample();
|
||||
else if (const auto * mp4Properties{ dynamic_cast<const TagLib::MP4::Properties*>(properties) })
|
||||
else if (const auto* mp4Properties{ dynamic_cast<const TagLib::MP4::Properties*>(properties) })
|
||||
_audioProperties.bitsPerSample = mp4Properties->bitsPerSample();
|
||||
else if (const auto * wavePackProperties{ dynamic_cast<const TagLib::WavPack::Properties*>(properties) })
|
||||
else if (const auto* wavePackProperties{ dynamic_cast<const TagLib::WavPack::Properties*>(properties) })
|
||||
_audioProperties.bitsPerSample = wavePackProperties->bitsPerSample();
|
||||
#if TAGLIB_MAJOR_VERSION >= 2
|
||||
else if (const auto * dsfProperties{ dynamic_cast<const TagLib::DSF::Properties*>(properties) })
|
||||
else if (const auto* dsfProperties{ dynamic_cast<const TagLib::DSF::Properties*>(properties) })
|
||||
_audioProperties.bitsPerSample = dsfProperties->bitsPerSample();
|
||||
#endif
|
||||
}
|
||||
@@ -347,11 +350,10 @@ namespace lms::metadata
|
||||
{
|
||||
bool visited{};
|
||||
|
||||
visitTagValues(tagName, [&](std::string_view value)
|
||||
{
|
||||
visited = true;
|
||||
visitor(value);
|
||||
});
|
||||
visitTagValues(tagName, [&](std::string_view value) {
|
||||
visited = true;
|
||||
visitor(value);
|
||||
});
|
||||
|
||||
if (visited)
|
||||
break;
|
||||
@@ -372,10 +374,9 @@ namespace lms::metadata
|
||||
|
||||
void TagLibTagReader::visitPerformerTags(PerformerVisitor visitor) const
|
||||
{
|
||||
visitTagValues("PERFORMER", [&](std::string_view value)
|
||||
{
|
||||
visitor("", value);
|
||||
});
|
||||
visitTagValues("PERFORMER", [&](std::string_view value) {
|
||||
visitor("", value);
|
||||
});
|
||||
|
||||
for (const auto& [key, values] : _propertyMap)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <taglib/tpropertymap.h>
|
||||
|
||||
#include "metadata/IParser.hpp"
|
||||
|
||||
#include "ITagReader.hpp"
|
||||
|
||||
namespace lms::metadata
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
#include "Utils.hpp"
|
||||
#include <ctime>
|
||||
#include <string_view>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
|
||||
@@ -29,8 +29,7 @@ namespace lms::metadata::utils
|
||||
{
|
||||
Wt::WDate parseDate(std::string_view dateStr)
|
||||
{
|
||||
static constexpr const char* formats[]
|
||||
{
|
||||
static constexpr const char* formats[]{
|
||||
"%Y-%m-%d",
|
||||
"%Y/%m/%d",
|
||||
};
|
||||
@@ -41,7 +40,7 @@ namespace lms::metadata::utils
|
||||
tm.tm_mon = -1;
|
||||
tm.tm_mday = -1;
|
||||
|
||||
std::istringstream ss{ std::string {dateStr} }; // TODO, remove extra copy here
|
||||
std::istringstream ss{ std::string{ dateStr } }; // TODO, remove extra copy here
|
||||
ss >> std::get_time(&tm, format);
|
||||
if (ss.fail())
|
||||
continue;
|
||||
@@ -49,11 +48,10 @@ namespace lms::metadata::utils
|
||||
if (tm.tm_mday <= 0 || tm.tm_mon < 0)
|
||||
continue;
|
||||
|
||||
const Wt::WDate res
|
||||
{
|
||||
tm.tm_year + 1900, // tm.tm_year: years since 1900
|
||||
tm.tm_mon + 1, // tm.tm_mon: months since January – [00, 11]
|
||||
tm.tm_mday // tm.tm_mday: day of the month – [1, 31]
|
||||
const Wt::WDate res{
|
||||
tm.tm_year + 1900, // tm.tm_year: years since 1900
|
||||
tm.tm_mon + 1, // tm.tm_mon: months since January – [00, 11]
|
||||
tm.tm_mday // tm.tm_mday: day of the month – [1, 31]
|
||||
};
|
||||
if (!res.isValid())
|
||||
continue;
|
||||
@@ -87,7 +85,8 @@ namespace lms::metadata::utils
|
||||
int result{};
|
||||
for (std::size_t i{}; i < yearStr.size() && i < 4; ++i)
|
||||
{
|
||||
if (!std::isdigit(yearStr[i])) {
|
||||
if (!std::isdigit(yearStr[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
result = result * 10 + (yearStr[i] - '0');
|
||||
@@ -100,9 +99,12 @@ namespace lms::metadata::utils
|
||||
{
|
||||
switch (readStyle)
|
||||
{
|
||||
case ParserReadStyle::Fast: return "fast";
|
||||
case ParserReadStyle::Average: return "average";
|
||||
case ParserReadStyle::Accurate: return "accurate";
|
||||
case ParserReadStyle::Fast:
|
||||
return "fast";
|
||||
case ParserReadStyle::Average:
|
||||
return "average";
|
||||
case ParserReadStyle::Accurate:
|
||||
return "accurate";
|
||||
}
|
||||
|
||||
throw core::LmsException{ "Unknown read style" };
|
||||
@@ -150,6 +152,6 @@ namespace lms::metadata::utils
|
||||
if (!roleEnd || !roleBegin)
|
||||
artistName = core::stringUtils::stringTrim(entry);
|
||||
|
||||
return PerformerArtist{ Artist {artistName}, std::string {role} };
|
||||
return PerformerArtist{ Artist{ artistName }, std::string{ role } };
|
||||
}
|
||||
}
|
||||
} // namespace lms::metadata::utils
|
||||
@@ -22,22 +22,23 @@
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
#include <Wt/WDate.h>
|
||||
|
||||
#include "metadata/IParser.hpp"
|
||||
|
||||
namespace lms::metadata::utils
|
||||
{
|
||||
Wt::WDate parseDate(std::string_view dateStr);
|
||||
std::optional<int> parseYear(std::string_view yearStr);
|
||||
std::string_view readStyleToString(ParserReadStyle readStyle);
|
||||
Wt::WDate parseDate(std::string_view dateStr);
|
||||
std::optional<int> parseYear(std::string_view yearStr);
|
||||
std::string_view readStyleToString(ParserReadStyle readStyle);
|
||||
|
||||
struct PerformerArtist
|
||||
{
|
||||
Artist artist;
|
||||
std::string role;
|
||||
};
|
||||
struct PerformerArtist
|
||||
{
|
||||
Artist artist;
|
||||
std::string role;
|
||||
};
|
||||
|
||||
// format is "artist name (role)"
|
||||
PerformerArtist extractPerformerAndRole(std::string_view entry);
|
||||
}
|
||||
// format is "artist name (role)"
|
||||
PerformerArtist extractPerformerAndRole(std::string_view entry);
|
||||
} // namespace lms::metadata::utils
|
||||
|
||||
Reference in New Issue
Block a user