Auto reformatted the base, ref #470

This commit is contained in:
emeric
2024-05-24 23:31:52 +02:00
parent 83b868673c
commit 39941d90a3
460 changed files with 8583 additions and 8514 deletions
+12 -14
View File
@@ -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);
});
}
+2 -2
View File
@@ -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
+55 -63
View File
@@ -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;
+1 -1
View File
@@ -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
+37 -36
View File
@@ -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
+17 -15
View File
@@ -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
+12 -11
View File
@@ -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