Updated clang format, and restored dsd file handling that was actually broken
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ Language: Cpp
|
|||||||
BasedOnStyle: Microsoft
|
BasedOnStyle: Microsoft
|
||||||
Standard: c++20
|
Standard: c++20
|
||||||
AccessModifierOffset: -4
|
AccessModifierOffset: -4
|
||||||
AlignAfterOpenBracket: DontAlign
|
AlignAfterOpenBracket: Align
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
AlignConsecutiveDeclarations: false
|
AlignConsecutiveDeclarations: false
|
||||||
AlignOperands: AlignAfterOperator
|
AlignOperands: AlignAfterOperator
|
||||||
|
|||||||
@@ -204,11 +204,11 @@ namespace lms::av
|
|||||||
std::optional<std::size_t> AudioFile::getBestStreamIndex() const
|
std::optional<std::size_t> AudioFile::getBestStreamIndex() const
|
||||||
{
|
{
|
||||||
int res = ::av_find_best_stream(_context,
|
int res = ::av_find_best_stream(_context,
|
||||||
AVMEDIA_TYPE_AUDIO,
|
AVMEDIA_TYPE_AUDIO,
|
||||||
-1, // Auto
|
-1, // Auto
|
||||||
-1, // Auto
|
-1, // Auto
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|||||||
@@ -202,24 +202,24 @@ namespace lms::core
|
|||||||
LMS_LOG(CHILDPROCESS, DEBUG, "Async read, bufferSize = " << bufferSize);
|
LMS_LOG(CHILDPROCESS, DEBUG, "Async read, bufferSize = " << bufferSize);
|
||||||
|
|
||||||
boost::asio::async_read(_childStdout, boost::asio::buffer(data, bufferSize),
|
boost::asio::async_read(_childStdout, boost::asio::buffer(data, bufferSize),
|
||||||
[this, callback{ std::move(callback) }](const boost::system::error_code& error, std::size_t bytesTransferred) {
|
[this, callback{ std::move(callback) }](const boost::system::error_code& error, std::size_t bytesTransferred) {
|
||||||
LMS_LOG(CHILDPROCESS, DEBUG, "Async read cb - ec = '" << error.message() << "' (" << error.value() << "), bytesTransferred = " << bytesTransferred);
|
LMS_LOG(CHILDPROCESS, DEBUG, "Async read cb - ec = '" << error.message() << "' (" << error.value() << "), bytesTransferred = " << bytesTransferred);
|
||||||
|
|
||||||
ReadResult readResult{ ReadResult::Success };
|
ReadResult readResult{ ReadResult::Success };
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
if (error != boost::asio::error::eof)
|
if (error != boost::asio::error::eof)
|
||||||
{
|
{
|
||||||
// forbidden to read any captured param here as the ChildProcess instance may already have been killed
|
// forbidden to read any captured param here as the ChildProcess instance may already have been killed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
readResult = ReadResult::EndOfFile;
|
readResult = ReadResult::EndOfFile;
|
||||||
_finished = true;
|
_finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(readResult, bytesTransferred);
|
callback(readResult, bytesTransferred);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t ChildProcess::readSome(std::byte* data, std::size_t bufferSize)
|
std::size_t ChildProcess::readSome(std::byte* data, std::size_t bufferSize)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace lms::core
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
||||||
void abort() override{};
|
void abort() override {};
|
||||||
|
|
||||||
static constexpr std::size_t _chunkSize{ 262'144 };
|
static constexpr std::size_t _chunkSize{ 262'144 };
|
||||||
|
|
||||||
|
|||||||
@@ -78,9 +78,9 @@ namespace lms::core::tracing
|
|||||||
setMetadata("cpu_count", std::to_string(std::thread::hardware_concurrency()));
|
setMetadata("cpu_count", std::to_string(std::thread::hardware_concurrency()));
|
||||||
setMetadata("build_type",
|
setMetadata("build_type",
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
"debug"
|
"debug"
|
||||||
#else
|
#else
|
||||||
"release"
|
"release"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace lms::core::http
|
|||||||
std::visit([&](const auto& parameters) {
|
std::visit([&](const auto& parameters) {
|
||||||
res = &static_cast<const ClientRequestParameters&>(parameters);
|
res = &static_cast<const ClientRequestParameters&>(parameters);
|
||||||
},
|
},
|
||||||
_parameters);
|
_parameters);
|
||||||
|
|
||||||
return *res;
|
return *res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
|||||||
SELECT 1, 0, s_s.media_directory, "Main"
|
SELECT 1, 0, s_s.media_directory, "Main"
|
||||||
FROM scan_settings s_s
|
FROM scan_settings s_s
|
||||||
WHERE id = ?)",
|
WHERE id = ?)",
|
||||||
scanSettingsId);
|
scanSettingsId);
|
||||||
|
|
||||||
// Remove the outdated column in scan_settings
|
// Remove the outdated column in scan_settings
|
||||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE scan_settings DROP media_directory");
|
utils::executeCommand(*session.getDboSession(), "ALTER TABLE scan_settings DROP media_directory");
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace lms::db
|
|||||||
class SelectStatement
|
class SelectStatement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SelectStatement(){};
|
SelectStatement() {};
|
||||||
SelectStatement(const std::string& item);
|
SelectStatement(const std::string& item);
|
||||||
|
|
||||||
SelectStatement& And(const std::string& item);
|
SelectStatement& And(const std::string& item);
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ namespace lms::image::STB
|
|||||||
|
|
||||||
#if STB_IMAGE_RESIZE_VERSION == 1
|
#if STB_IMAGE_RESIZE_VERSION == 1
|
||||||
if (::stbir_resize_uint8_srgb(reinterpret_cast<const unsigned char*>(_data.get()), _width, _height, 0,
|
if (::stbir_resize_uint8_srgb(reinterpret_cast<const unsigned char*>(_data.get()), _width, _height, 0,
|
||||||
reinterpret_cast<unsigned char*>(resizedData.get()), width, height, 0,
|
reinterpret_cast<unsigned char*>(resizedData.get()), width, height, 0,
|
||||||
3, STBIR_ALPHA_CHANNEL_NONE, 0)
|
3, STBIR_ALPHA_CHANNEL_NONE, 0)
|
||||||
== 0)
|
== 0)
|
||||||
#elif STB_IMAGE_RESIZE_VERSION == 2
|
#elif STB_IMAGE_RESIZE_VERSION == 2
|
||||||
if (::stbir_resize_uint8_srgb(reinterpret_cast<const unsigned char*>(_data.get()), _width, _height, 0,
|
if (::stbir_resize_uint8_srgb(reinterpret_cast<const unsigned char*>(_data.get()), _width, _height, 0,
|
||||||
reinterpret_cast<unsigned char*>(resizedData.get()), width, height, 0,
|
reinterpret_cast<unsigned char*>(resizedData.get()), width, height, 0,
|
||||||
STBIR_RGB)
|
STBIR_RGB)
|
||||||
== 0)
|
== 0)
|
||||||
#else
|
#else
|
||||||
#error "Unhandled STB image resize version"!
|
#error "Unhandled STB image resize version"!
|
||||||
|
|||||||
@@ -75,43 +75,43 @@ namespace lms::metadata::benchmarks
|
|||||||
params.artistTagDelimiters = { "/", ";" };
|
params.artistTagDelimiters = { "/", ";" };
|
||||||
// The list itself is not important, the idea is to have some volume
|
// The list itself is not important, the idea is to have some volume
|
||||||
params.artistsToNotSplit = { "AC/DC",
|
params.artistsToNotSplit = { "AC/DC",
|
||||||
"+/-",
|
"+/-",
|
||||||
R"(A/N【eɪ-ɛn)",
|
R"(A/N【eɪ-ɛn)",
|
||||||
"Akron/Family",
|
"Akron/Family",
|
||||||
"AM/FM",
|
"AM/FM",
|
||||||
"Ashes/Dust",
|
"Ashes/Dust",
|
||||||
"B/B/S/",
|
"B/B/S/",
|
||||||
"BLCK/MRKT/RGNS",
|
"BLCK/MRKT/RGNS",
|
||||||
"Body/Gate/Head",
|
"Body/Gate/Head",
|
||||||
"Body/Head",
|
"Body/Head",
|
||||||
"Born/Dead",
|
"Born/Dead",
|
||||||
"Burger/Ink",
|
"Burger/Ink",
|
||||||
"case/lang/veirs",
|
"case/lang/veirs",
|
||||||
"Chicago / London Underground",
|
"Chicago / London Underground",
|
||||||
"Dakota/Dakota",
|
"Dakota/Dakota",
|
||||||
"Dark/Light",
|
"Dark/Light",
|
||||||
"Decades/Failures",
|
"Decades/Failures",
|
||||||
"The Denison/Kimball Trio",
|
"The Denison/Kimball Trio",
|
||||||
"D-W/L-SS",
|
"D-W/L-SS",
|
||||||
"F/i",
|
"F/i",
|
||||||
"Friend / Enemy",
|
"Friend / Enemy",
|
||||||
"GZA/Genius",
|
"GZA/Genius",
|
||||||
"I/O",
|
"I/O",
|
||||||
"I/O3",
|
"I/O3",
|
||||||
"In/Humanity",
|
"In/Humanity",
|
||||||
"Love/Lust",
|
"Love/Lust",
|
||||||
"Mirror/Dash",
|
"Mirror/Dash",
|
||||||
"Model/Actress",
|
"Model/Actress",
|
||||||
"N/N",
|
"N/N",
|
||||||
"Neither/Neither World",
|
"Neither/Neither World",
|
||||||
"P1/E",
|
"P1/E",
|
||||||
"Sick/Tired",
|
"Sick/Tired",
|
||||||
"t/e/u/",
|
"t/e/u/",
|
||||||
"tide/edit",
|
"tide/edit",
|
||||||
"V/Vm",
|
"V/Vm",
|
||||||
"White/Lichens",
|
"White/Lichens",
|
||||||
"White/Light",
|
"White/Light",
|
||||||
"Yamantaka // Sonic Titan" };
|
"Yamantaka // Sonic Titan" };
|
||||||
|
|
||||||
const TestAudioFileParser parser{ params };
|
const TestAudioFileParser parser{ params };
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
|
|||||||
@@ -196,10 +196,10 @@ namespace lms::metadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Artist> getArtists(const ITagReader& tagReader,
|
std::vector<Artist> getArtists(const ITagReader& tagReader,
|
||||||
std::initializer_list<TagType> artistTagNames,
|
std::initializer_list<TagType> artistTagNames,
|
||||||
std::initializer_list<TagType> artistSortTagNames,
|
std::initializer_list<TagType> artistSortTagNames,
|
||||||
std::initializer_list<TagType> artistMBIDTagNames,
|
std::initializer_list<TagType> artistMBIDTagNames,
|
||||||
const AudioFileParserParameters& params)
|
const AudioFileParserParameters& params)
|
||||||
{
|
{
|
||||||
std::vector<std::string> artistNames{ getTagValuesFirstMatchAs<std::string>(tagReader, artistTagNames, params.artistTagDelimiters, ¶ms.artistsToNotSplit) };
|
std::vector<std::string> artistNames{ getTagValuesFirstMatchAs<std::string>(tagReader, artistTagNames, params.artistTagDelimiters, ¶ms.artistsToNotSplit) };
|
||||||
if (artistNames.empty())
|
if (artistNames.empty())
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <taglib/taglib.h>
|
#include <taglib/taglib.h>
|
||||||
|
|
||||||
#if (TAGLIB_MAJOR_VERSION > 2)
|
#if (TAGLIB_MAJOR_VERSION >= 2)
|
||||||
#define TAGLIB_HAS_DSF 1
|
#define TAGLIB_HAS_DSF 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include <taglib/wavfile.h>
|
#include <taglib/wavfile.h>
|
||||||
#include <taglib/wavpackfile.h>
|
#include <taglib/wavpackfile.h>
|
||||||
#if TAGLIB_HAS_DSF
|
#if TAGLIB_HAS_DSF
|
||||||
|
#include <taglib/dsdifffile.h>
|
||||||
#include <taglib/dsffile.h>
|
#include <taglib/dsffile.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -452,6 +453,8 @@ namespace lms::metadata::taglib
|
|||||||
#if TAGLIB_HAS_DSF
|
#if TAGLIB_HAS_DSF
|
||||||
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();
|
_audioProperties.bitsPerSample = dsfProperties->bitsPerSample();
|
||||||
|
else if (const auto* dsfProperties{ dynamic_cast<const TagLib::DSDIFF::Properties*>(properties) })
|
||||||
|
_audioProperties.bitsPerSample = dsfProperties->bitsPerSample();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <taglib/wavfile.h>
|
#include <taglib/wavfile.h>
|
||||||
#include <taglib/wavpackfile.h>
|
#include <taglib/wavpackfile.h>
|
||||||
#if TAGLIB_HAS_DSF
|
#if TAGLIB_HAS_DSF
|
||||||
|
#include <taglib/dsdifffile.h>
|
||||||
#include <taglib/dsffile.h>
|
#include <taglib/dsffile.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -50,14 +51,13 @@ namespace lms::metadata::taglib::utils
|
|||||||
{
|
{
|
||||||
std::span<const std::filesystem::path> getSupportedExtensions()
|
std::span<const std::filesystem::path> getSupportedExtensions()
|
||||||
{
|
{
|
||||||
static const std::vector<std::filesystem::path> supportedExtensions
|
static const std::vector<std::filesystem::path> supportedExtensions{
|
||||||
{
|
|
||||||
".mp3", ".mp2", ".aac", ".ogg", ".oga", ".flac", ".spx", ".opus",
|
".mp3", ".mp2", ".aac", ".ogg", ".oga", ".flac", ".spx", ".opus",
|
||||||
".mpc", ".wv", ".ape", ".tta", ".m4a", ".m4r", ".m4b", ".m4p",
|
".mpc", ".wv", ".ape", ".tta", ".m4a", ".m4r", ".m4b", ".m4p",
|
||||||
".3g2", ".m4v", ".wma", ".asf", ".aif", ".aiff", ".afc", ".aifc",
|
".3g2", ".m4v", ".wma", ".asf", ".aif", ".aiff", ".afc", ".aifc",
|
||||||
".wav",
|
".wav",
|
||||||
#if TAGLIB_HAS_DSF
|
#if TAGLIB_HAS_DSF
|
||||||
".dsf", ".dff", ".dsdiff"
|
".dsf", ".dff", ".dsdiff"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -201,9 +201,9 @@ namespace lms::metadata::taglib::utils
|
|||||||
else if (TagLib::RIFF::WAV::File::isSupported(stream))
|
else if (TagLib::RIFF::WAV::File::isSupported(stream))
|
||||||
file = std::make_unique<TagLib::RIFF::WAV::File>(stream, readAudioProperties, audioPropertiesStyle);
|
file = std::make_unique<TagLib::RIFF::WAV::File>(stream, readAudioProperties, audioPropertiesStyle);
|
||||||
#if TAGLIB_HAS_DSF
|
#if TAGLIB_HAS_DSF
|
||||||
else if (DSF::File::isSupported(stream))
|
else if (TagLib::DSF::File::isSupported(stream))
|
||||||
file = std::make_unique<TagLib::DSF::File>(stream, readAudioProperties, audioPropertiesStyle);
|
file = std::make_unique<TagLib::DSF::File>(stream, readAudioProperties, audioPropertiesStyle);
|
||||||
else if (DSDIFF::File::isSupported(stream))
|
else if (TagLib::DSDIFF::File::isSupported(stream))
|
||||||
file = std::make_unique<TagLib::DSDIFF::File>(stream, readAudioProperties, audioPropertiesStyle);
|
file = std::make_unique<TagLib::DSDIFF::File>(stream, readAudioProperties, audioPropertiesStyle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -161,9 +161,9 @@ namespace lms::metadata::tests
|
|||||||
{ TagType::TotalDiscs, { "3" } },
|
{ TagType::TotalDiscs, { "3" } },
|
||||||
}) };
|
}) };
|
||||||
testTags->setExtraUserTags({ { "MY_AWESOME_TAG_A", { "MyTagValue1ForTagA", "MyTagValue2ForTagA" } },
|
testTags->setExtraUserTags({ { "MY_AWESOME_TAG_A", { "MyTagValue1ForTagA", "MyTagValue2ForTagA" } },
|
||||||
{ "MY_AWESOME_TAG_B", { "MyTagValue1ForTagB", "MyTagValue2ForTagB" } } });
|
{ "MY_AWESOME_TAG_B", { "MyTagValue1ForTagB", "MyTagValue2ForTagB" } } });
|
||||||
testTags->setPerformersTags({ { "RoleA", { "MyPerformer1ForRoleA", "MyPerformer2ForRoleA" } },
|
testTags->setPerformersTags({ { "RoleA", { "MyPerformer1ForRoleA", "MyPerformer2ForRoleA" } },
|
||||||
{ "RoleB", { "MyPerformer1ForRoleB", "MyPerformer2ForRoleB" } } });
|
{ "RoleB", { "MyPerformer1ForRoleB", "MyPerformer2ForRoleB" } } });
|
||||||
testTags->setLyricsTags({ { "eng", "[00:00.00]First line\n[00:01.00]Second line" } });
|
testTags->setLyricsTags({ { "eng", "[00:00.00]First line\n[00:01.00]Second line" } });
|
||||||
|
|
||||||
return testTags;
|
return testTags;
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ namespace lms::artwork
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArtworkService::ArtworkService(db::IDb& db,
|
ArtworkService::ArtworkService(db::IDb& db,
|
||||||
const std::filesystem::path& defaultReleaseCoverSvgPath,
|
const std::filesystem::path& defaultReleaseCoverSvgPath,
|
||||||
const std::filesystem::path& defaultArtistImageSvgPath)
|
const std::filesystem::path& defaultArtistImageSvgPath)
|
||||||
: _db{ db }
|
: _db{ db }
|
||||||
, _audioFileParser{ metadata::createAudioFileParser(metadata::AudioFileParserParameters{}) }
|
, _audioFileParser{ metadata::createAudioFileParser(metadata::AudioFileParserParameters{}) }
|
||||||
, _cache{ core::Service<core::IConfig>::get()->getULong("cover-max-cache-size", 30) * 1000 * 1000 }
|
, _cache{ core::Service<core::IConfig>::get()->getULong("cover-max-cache-size", 30) * 1000 * 1000 }
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ namespace lms::auth
|
|||||||
virtual bool checkUserPassword(std::string_view loginName, std::string_view password) = 0;
|
virtual bool checkUserPassword(std::string_view loginName, std::string_view password) = 0;
|
||||||
|
|
||||||
CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
||||||
std::string_view loginName,
|
std::string_view loginName,
|
||||||
std::string_view password) override;
|
std::string_view password) override;
|
||||||
|
|
||||||
std::shared_mutex _mutex;
|
std::shared_mutex _mutex;
|
||||||
LoginThrottler _loginThrottler;
|
LoginThrottler _loginThrottler;
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ namespace lms::auth
|
|||||||
db::UserId userId{};
|
db::UserId userId{};
|
||||||
};
|
};
|
||||||
virtual CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
virtual CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
||||||
std::string_view loginName,
|
std::string_view loginName,
|
||||||
std::string_view password)
|
std::string_view password)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
virtual bool canSetPasswords() const = 0;
|
virtual bool canSetPasswords() const = 0;
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ namespace lms::recommendation
|
|||||||
FeatureNames res;
|
FeatureNames res;
|
||||||
|
|
||||||
std::transform(std::cbegin(featureDefinitions), std::cend(featureDefinitions),
|
std::transform(std::cbegin(featureDefinitions), std::cend(featureDefinitions),
|
||||||
std::inserter(res, std::begin(res)), [](auto itFeature) { return itFeature.first; });
|
std::inserter(res, std::begin(res)), [](auto itFeature) { return itFeature.first; });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,10 +101,10 @@ namespace lms::recommendation
|
|||||||
|
|
||||||
std::unordered_set<FeatureName> featureNames;
|
std::unordered_set<FeatureName> featureNames;
|
||||||
std::transform(std::cbegin(trainSettings.featureSettingsMap), std::cend(trainSettings.featureSettingsMap), std::inserter(featureNames, std::begin(featureNames)),
|
std::transform(std::cbegin(trainSettings.featureSettingsMap), std::cend(trainSettings.featureSettingsMap), std::inserter(featureNames, std::begin(featureNames)),
|
||||||
[](const auto& itFeatureSetting) { return itFeatureSetting.first; });
|
[](const auto& itFeatureSetting) { return itFeatureSetting.first; });
|
||||||
|
|
||||||
const std::size_t nbDimensions{ std::accumulate(std::cbegin(featureNames), std::cend(featureNames), std::size_t{ 0 },
|
const std::size_t nbDimensions{ std::accumulate(std::cbegin(featureNames), std::cend(featureNames), std::size_t{ 0 },
|
||||||
[](std::size_t sum, const FeatureName& featureName) { return sum + getFeatureDef(featureName).nbDimensions; }) };
|
[](std::size_t sum, const FeatureName& featureName) { return sum + getFeatureDef(featureName).nbDimensions; }) };
|
||||||
|
|
||||||
LMS_LOG(RECOMMENDATION, DEBUG, "Features dimension = " << nbDimensions);
|
LMS_LOG(RECOMMENDATION, DEBUG, "Features dimension = " << nbDimensions);
|
||||||
|
|
||||||
@@ -184,8 +184,8 @@ namespace lms::recommendation
|
|||||||
|
|
||||||
LMS_LOG(RECOMMENDATION, DEBUG, "Training network...");
|
LMS_LOG(RECOMMENDATION, DEBUG, "Training network...");
|
||||||
network.train(samples, trainSettings.iterationCount,
|
network.train(samples, trainSettings.iterationCount,
|
||||||
progressCallback ? somProgressCallback : som::Network::ProgressCallback{},
|
progressCallback ? somProgressCallback : som::Network::ProgressCallback{},
|
||||||
[this] { return _loadCancelled; });
|
[this] { return _loadCancelled; });
|
||||||
LMS_LOG(RECOMMENDATION, DEBUG, "Training network DONE");
|
LMS_LOG(RECOMMENDATION, DEBUG, "Training network DONE");
|
||||||
|
|
||||||
LMS_LOG(RECOMMENDATION, DEBUG, "Classifying tracks...");
|
LMS_LOG(RECOMMENDATION, DEBUG, "Classifying tracks...");
|
||||||
@@ -242,10 +242,10 @@ namespace lms::recommendation
|
|||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
similarTrackIds.erase(std::remove_if(std::begin(similarTrackIds), std::end(similarTrackIds),
|
similarTrackIds.erase(std::remove_if(std::begin(similarTrackIds), std::end(similarTrackIds),
|
||||||
[&](TrackId trackId) {
|
[&](TrackId trackId) {
|
||||||
return !Track::exists(session, trackId);
|
return !Track::exists(session, trackId);
|
||||||
}),
|
}),
|
||||||
std::end(similarTrackIds));
|
std::end(similarTrackIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
return similarTrackIds;
|
return similarTrackIds;
|
||||||
@@ -263,10 +263,10 @@ namespace lms::recommendation
|
|||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
similarReleaseIds.erase(std::remove_if(std::begin(similarReleaseIds), std::end(similarReleaseIds),
|
similarReleaseIds.erase(std::remove_if(std::begin(similarReleaseIds), std::end(similarReleaseIds),
|
||||||
[&](ReleaseId releaseId) {
|
[&](ReleaseId releaseId) {
|
||||||
return !Release::exists(session, releaseId);
|
return !Release::exists(session, releaseId);
|
||||||
}),
|
}),
|
||||||
std::end(similarReleaseIds));
|
std::end(similarReleaseIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
return similarReleaseIds;
|
return similarReleaseIds;
|
||||||
@@ -302,10 +302,10 @@ namespace lms::recommendation
|
|||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
res.erase(std::remove_if(std::begin(res), std::end(res),
|
res.erase(std::remove_if(std::begin(res), std::end(res),
|
||||||
[&](ArtistId artistId) {
|
[&](ArtistId artistId) {
|
||||||
return !Artist::exists(session, artistId);
|
return !Artist::exists(session, artistId);
|
||||||
}),
|
}),
|
||||||
std::end(res));
|
std::end(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (res.size() > maxCount)
|
while (res.size() > maxCount)
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ namespace lms::recommendation
|
|||||||
|
|
||||||
template<typename IdType>
|
template<typename IdType>
|
||||||
std::vector<IdType> getSimilarObjects(const std::vector<IdType>& ids,
|
std::vector<IdType> getSimilarObjects(const std::vector<IdType>& ids,
|
||||||
const ObjectMatrix<IdType>& objectMatrix,
|
const ObjectMatrix<IdType>& objectMatrix,
|
||||||
const ObjectPositions<IdType>& objectPositions,
|
const ObjectPositions<IdType>& objectPositions,
|
||||||
std::size_t maxCount) const;
|
std::size_t maxCount) const;
|
||||||
|
|
||||||
db::IDb& _db;
|
db::IDb& _db;
|
||||||
bool _loadCancelled{};
|
bool _loadCancelled{};
|
||||||
@@ -157,9 +157,9 @@ namespace lms::recommendation
|
|||||||
|
|
||||||
template<typename IdType>
|
template<typename IdType>
|
||||||
std::vector<IdType> FeaturesEngine::getSimilarObjects(const std::vector<IdType>& ids,
|
std::vector<IdType> FeaturesEngine::getSimilarObjects(const std::vector<IdType>& ids,
|
||||||
const ObjectMatrix<IdType>& objectMatrix,
|
const ObjectMatrix<IdType>& objectMatrix,
|
||||||
const ObjectPositions<IdType>& objectPositions,
|
const ObjectPositions<IdType>& objectPositions,
|
||||||
std::size_t maxCount) const
|
std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
std::vector<IdType> res;
|
std::vector<IdType> res;
|
||||||
|
|
||||||
@@ -173,10 +173,10 @@ namespace lms::recommendation
|
|||||||
|
|
||||||
// Remove objects that are already in input or already reported
|
// Remove objects that are already in input or already reported
|
||||||
closestObjectIds.erase(std::remove_if(std::begin(closestObjectIds), std::end(closestObjectIds),
|
closestObjectIds.erase(std::remove_if(std::begin(closestObjectIds), std::end(closestObjectIds),
|
||||||
[&](IdType id) {
|
[&](IdType id) {
|
||||||
return std::find(std::cbegin(ids), std::cend(ids), id) != std::cend(ids);
|
return std::find(std::cbegin(ids), std::cend(ids), id) != std::cend(ids);
|
||||||
}),
|
}),
|
||||||
std::end(closestObjectIds));
|
std::end(closestObjectIds));
|
||||||
|
|
||||||
for (IdType id : closestObjectIds)
|
for (IdType id : closestObjectIds)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ namespace lms::recommendation::PlaylistGeneratorConstraint
|
|||||||
ArtistContainer intersection;
|
ArtistContainer intersection;
|
||||||
|
|
||||||
std::set_intersection(std::cbegin(artists1), std::cend(artists1),
|
std::set_intersection(std::cbegin(artists1), std::cend(artists1),
|
||||||
std::cbegin(artists2), std::cend(artists2),
|
std::cbegin(artists2), std::cend(artists2),
|
||||||
std::back_inserter(intersection));
|
std::back_inserter(intersection));
|
||||||
|
|
||||||
return intersection.size();
|
return intersection.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -591,9 +591,9 @@ namespace lms::scanner
|
|||||||
// Skip if duplicate files no longer in media root: as it will be removed later, we will end up with no file
|
// Skip if duplicate files no longer in media root: as it will be removed later, we will end up with no file
|
||||||
auto& mediaLibraries{ getScannerSettings().mediaLibraries };
|
auto& mediaLibraries{ getScannerSettings().mediaLibraries };
|
||||||
if (std::none_of(std::cbegin(mediaLibraries), std::cend(mediaLibraries),
|
if (std::none_of(std::cbegin(mediaLibraries), std::cend(mediaLibraries),
|
||||||
[&](const MediaLibraryInfo& libraryInfo) {
|
[&](const MediaLibraryInfo& libraryInfo) {
|
||||||
return core::pathUtils::isPathInRootPath(getFilePath(), libraryInfo.rootDirectory, &excludeDirFileName);
|
return core::pathUtils::isPathInRootPath(getFilePath(), libraryInfo.rootDirectory, &excludeDirFileName);
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,10 +246,10 @@ namespace lms::scanner
|
|||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
core::Service<core::IConfig>::get()->visitStrings("artist-image-file-names",
|
core::Service<core::IConfig>::get()->visitStrings("artist-image-file-names",
|
||||||
[&res](std::string_view fileName) {
|
[&res](std::string_view fileName) {
|
||||||
res.emplace_back(fileName);
|
res.emplace_back(fileName);
|
||||||
},
|
},
|
||||||
{ "artist" });
|
{ "artist" });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -259,10 +259,10 @@ namespace lms::scanner
|
|||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
core::Service<core::IConfig>::get()->visitStrings("artist-info-image-file-names",
|
core::Service<core::IConfig>::get()->visitStrings("artist-info-image-file-names",
|
||||||
[&res](std::string_view fileName) {
|
[&res](std::string_view fileName) {
|
||||||
res.emplace_back(fileName);
|
res.emplace_back(fileName);
|
||||||
},
|
},
|
||||||
{ "thumb", "folder", "fanart" });
|
{ "thumb", "folder", "fanart" });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,10 +175,10 @@ namespace lms::scanner
|
|||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
core::Service<core::IConfig>::get()->visitStrings("medium-image-file-names",
|
core::Service<core::IConfig>::get()->visitStrings("medium-image-file-names",
|
||||||
[&res](std::string_view fileName) {
|
[&res](std::string_view fileName) {
|
||||||
res.emplace_back(fileName);
|
res.emplace_back(fileName);
|
||||||
},
|
},
|
||||||
{ "discsubtitle" });
|
{ "discsubtitle" });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,10 +204,10 @@ namespace lms::scanner
|
|||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
core::Service<core::IConfig>::get()->visitStrings("cover-preferred-file-names",
|
core::Service<core::IConfig>::get()->visitStrings("cover-preferred-file-names",
|
||||||
[&res](std::string_view fileName) {
|
[&res](std::string_view fileName) {
|
||||||
res.emplace_back(fileName);
|
res.emplace_back(fileName);
|
||||||
},
|
},
|
||||||
{ "cover", "front", "folder", "default" });
|
{ "cover", "front", "folder", "default" });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ namespace lms::scanner
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (std::none_of(std::cbegin(_settings.mediaLibraries), std::cend(_settings.mediaLibraries),
|
if (std::none_of(std::cbegin(_settings.mediaLibraries), std::cend(_settings.mediaLibraries),
|
||||||
[&](const MediaLibraryInfo& libraryInfo) {
|
[&](const MediaLibraryInfo& libraryInfo) {
|
||||||
return core::pathUtils::isPathInRootPath(p, libraryInfo.rootDirectory, &excludeDirFileName);
|
return core::pathUtils::isPathInRootPath(p, libraryInfo.rootDirectory, &excludeDirFileName);
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
LMS_LOG(DBUPDATER, DEBUG, "Removing " << p << ": out of media directory");
|
LMS_LOG(DBUPDATER, DEBUG, "Removing " << p << ": out of media directory");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace lms::transcoding
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
Wt::Http::ResponseContinuation* processRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
||||||
void abort() override{};
|
void abort() override {};
|
||||||
|
|
||||||
static constexpr std::size_t _chunkSize{ 262'144 };
|
static constexpr std::size_t _chunkSize{ 262'144 };
|
||||||
std::optional<std::size_t> _estimatedContentLength;
|
std::optional<std::size_t> _estimatedContentLength;
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ namespace lms::som
|
|||||||
const T mean{ std::accumulate(vec.begin(), vec.end(), T{}) / size };
|
const T mean{ std::accumulate(vec.begin(), vec.end(), T{}) / size };
|
||||||
|
|
||||||
return std::accumulate(vec.begin(), vec.end(), T{},
|
return std::accumulate(vec.begin(), vec.end(), T{},
|
||||||
[mean, size](T accumulator, const T& val) {
|
[mean, size](T accumulator, const T& val) {
|
||||||
return accumulator + ((val - mean) * (val - mean) / (size - 1));
|
return accumulator + ((val - mean) * (val - mean) / (size - 1));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DataNormalizer::DataNormalizer(std::size_t inputDimCount)
|
DataNormalizer::DataNormalizer(std::size_t inputDimCount)
|
||||||
|
|||||||
@@ -212,9 +212,9 @@ namespace lms::som
|
|||||||
for (const Position& neighbourPosition : neighboursPosition)
|
for (const Position& neighbourPosition : neighboursPosition)
|
||||||
{
|
{
|
||||||
auto min = std::min_element(refVectorsPosition.begin(), refVectorsPosition.end(),
|
auto min = std::min_element(refVectorsPosition.begin(), refVectorsPosition.end(),
|
||||||
[this, neighbourPosition](const auto& a, const auto& b) {
|
[this, neighbourPosition](const auto& a, const auto& b) {
|
||||||
return (this->getRefVectorsDistance(a, neighbourPosition) < this->getRefVectorsDistance(b, neighbourPosition));
|
return (this->getRefVectorsDistance(a, neighbourPosition) < this->getRefVectorsDistance(b, neighbourPosition));
|
||||||
});
|
});
|
||||||
|
|
||||||
InputVector::Distance distance{ getRefVectorsDistance(neighbourPosition, *min) };
|
InputVector::Distance distance{ getRefVectorsDistance(neighbourPosition, *min) };
|
||||||
if (distance > maxDistance)
|
if (distance > maxDistance)
|
||||||
@@ -227,9 +227,9 @@ namespace lms::som
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
auto min{ std::min_element(std::cbegin(neighboursInfo), std::cend(neighboursInfo),
|
auto min{ std::min_element(std::cbegin(neighboursInfo), std::cend(neighboursInfo),
|
||||||
[&](const auto& a, const auto& b) {
|
[&](const auto& a, const auto& b) {
|
||||||
return a.distance < b.distance;
|
return a.distance < b.distance;
|
||||||
}) };
|
}) };
|
||||||
|
|
||||||
return min->position;
|
return min->position;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ namespace lms::api::subsonic
|
|||||||
std::unordered_map<std::string, ProtocolVersion> res;
|
std::unordered_map<std::string, ProtocolVersion> res;
|
||||||
|
|
||||||
core::Service<core::IConfig>::get()->visitStrings("api-subsonic-old-server-protocol-clients",
|
core::Service<core::IConfig>::get()->visitStrings("api-subsonic-old-server-protocol-clients",
|
||||||
[&](std::string_view client) {
|
[&](std::string_view client) {
|
||||||
res.emplace(std::string{ client }, ProtocolVersion{ .major = 1, .minor = 12, .patch = 0 });
|
res.emplace(std::string{ client }, ProtocolVersion{ .major = 1, .minor = 12, .patch = 0 });
|
||||||
},
|
},
|
||||||
{ "DSub" });
|
{ "DSub" });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -78,10 +78,10 @@ namespace lms::api::subsonic
|
|||||||
std::unordered_set<std::string> res;
|
std::unordered_set<std::string> res;
|
||||||
|
|
||||||
core::Service<core::IConfig>::get()->visitStrings("api-open-subsonic-disabled-clients",
|
core::Service<core::IConfig>::get()->visitStrings("api-open-subsonic-disabled-clients",
|
||||||
[&](std::string_view client) {
|
[&](std::string_view client) {
|
||||||
res.emplace(std::string{ client });
|
res.emplace(std::string{ client });
|
||||||
},
|
},
|
||||||
{ "DSub" });
|
{ "DSub" });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ namespace lms::api::subsonic
|
|||||||
[&](bool value) { os << (value ? "true" : "false"); },
|
[&](bool value) { os << (value ? "true" : "false"); },
|
||||||
[&](float value) { os << value; },
|
[&](float value) { os << value; },
|
||||||
[&](long long value) { os << value; } },
|
[&](long long value) { os << value; } },
|
||||||
value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Response::XmlSerializer::serializeEscapedString(std::ostream& os, std::string_view str)
|
void Response::XmlSerializer::serializeEscapedString(std::ostream& os, std::string_view str)
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ namespace lms::api::subsonic
|
|||||||
|
|
||||||
const auto artistTracks{ Track::findIds(context.dbSession, params) };
|
const auto artistTracks{ Track::findIds(context.dbSession, params) };
|
||||||
tracks.insert(std::end(tracks),
|
tracks.insert(std::end(tracks),
|
||||||
std::begin(artistTracks.results),
|
std::begin(artistTracks.results),
|
||||||
std::end(artistTracks.results));
|
std::end(artistTracks.results));
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracks;
|
return tracks;
|
||||||
@@ -159,8 +159,8 @@ namespace lms::api::subsonic
|
|||||||
|
|
||||||
const auto releaseTracks{ Track::findIds(context.dbSession, params) };
|
const auto releaseTracks{ Track::findIds(context.dbSession, params) };
|
||||||
tracks.insert(std::end(tracks),
|
tracks.insert(std::end(tracks),
|
||||||
std::begin(releaseTracks.results),
|
std::begin(releaseTracks.results),
|
||||||
std::end(releaseTracks.results));
|
std::end(releaseTracks.results));
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracks;
|
return tracks;
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ namespace lms::api::subsonic
|
|||||||
names.resize(artists.size());
|
names.resize(artists.size());
|
||||||
|
|
||||||
std::transform(std::cbegin(artists), std::cend(artists), std::begin(names),
|
std::transform(std::cbegin(artists), std::cend(artists), std::begin(names),
|
||||||
[](const Artist::pointer& artist) {
|
[](const Artist::pointer& artist) {
|
||||||
return artist->getName();
|
return artist->getName();
|
||||||
});
|
});
|
||||||
|
|
||||||
return core::stringUtils::joinStrings(names, ", ");
|
return core::stringUtils::joinStrings(names, ", ");
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -138,7 +138,7 @@ namespace lms
|
|||||||
config.visitStrings("trusted-proxies", [&](std::string_view trustedProxy) {
|
config.visitStrings("trusted-proxies", [&](std::string_view trustedProxy) {
|
||||||
pt.add("server.application-settings.trusted-proxy-config.trusted-proxies.proxy", std::string{ trustedProxy });
|
pt.add("server.application-settings.trusted-proxy-config.trusted-proxies.proxy", std::string{ trustedProxy });
|
||||||
},
|
},
|
||||||
{ "127.0.0.1", "::1" });
|
{ "127.0.0.1", "::1" });
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -360,9 +360,9 @@ namespace lms
|
|||||||
|
|
||||||
// As initialization can take a while (db migration, analyze, etc.), we bind a temporary init entry point to warn the user
|
// As initialization can take a while (db migration, analyze, etc.), we bind a temporary init entry point to warn the user
|
||||||
server.addEntryPoint(Wt::EntryPointType::Application,
|
server.addEntryPoint(Wt::EntryPointType::Application,
|
||||||
[&](const Wt::WEnvironment& env) {
|
[&](const Wt::WEnvironment& env) {
|
||||||
return ui::LmsInitApplication::create(env);
|
return ui::LmsInitApplication::create(env);
|
||||||
});
|
});
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO, "Starting init web server...");
|
LMS_LOG(MAIN, INFO, "Starting init web server...");
|
||||||
server.start();
|
server.start();
|
||||||
@@ -455,9 +455,9 @@ namespace lms
|
|||||||
|
|
||||||
// bind UI entry point
|
// bind UI entry point
|
||||||
server.addEntryPoint(Wt::EntryPointType::Application,
|
server.addEntryPoint(Wt::EntryPointType::Application,
|
||||||
[&database, &appManager, uiAuthenticationBackend](const Wt::WEnvironment& env) {
|
[&database, &appManager, uiAuthenticationBackend](const Wt::WEnvironment& env) {
|
||||||
return ui::LmsApplication::create(env, *database, appManager, uiAuthenticationBackend);
|
return ui::LmsApplication::create(env, *database, appManager, uiAuthenticationBackend);
|
||||||
});
|
});
|
||||||
|
|
||||||
proxyScannerEventsToApplication(*scannerService, server);
|
proxyScannerEventsToApplication(*scannerService, server);
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -54,11 +54,11 @@ namespace lms::ui
|
|||||||
core::Service<auth::IAuthTokenService>::get()->createAuthToken(authTokenDomain, userId, hashedAuthCookie);
|
core::Service<auth::IAuthTokenService>::get()->createAuthToken(authTokenDomain, userId, hashedAuthCookie);
|
||||||
|
|
||||||
LmsApp->setCookie(authCookieName,
|
LmsApp->setCookie(authCookieName,
|
||||||
authCookie,
|
authCookie,
|
||||||
expiry.toTime_t() - Wt::WDateTime::currentDateTime().toTime_t(),
|
expiry.toTime_t() - Wt::WDateTime::currentDateTime().toTime_t(),
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
LmsApp->environment().urlScheme() == "https");
|
LmsApp->environment().urlScheme() == "https");
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthModel : public Wt::WFormModel
|
class AuthModel : public Wt::WFormModel
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ namespace lms::ui
|
|||||||
|
|
||||||
declareJavaScriptFunction("onLoadCover", "function(id) { id.className += \" Lms-cover-loaded\"}");
|
declareJavaScriptFunction("onLoadCover", "function(id) { id.className += \" Lms-cover-loaded\"}");
|
||||||
declareJavaScriptFunction("updateActiveNav",
|
declareJavaScriptFunction("updateActiveNav",
|
||||||
R"(function(current) {
|
R"(function(current) {
|
||||||
const menuItems = document.querySelectorAll('.nav-item a[href]:not([href=""])');
|
const menuItems = document.querySelectorAll('.nav-item a[href]:not([href=""])');
|
||||||
for (const menuItem of menuItems) {
|
for (const menuItem of menuItems) {
|
||||||
if (menuItem.getAttribute("href") === current) {
|
if (menuItem.getAttribute("href") === current) {
|
||||||
@@ -546,13 +546,13 @@ namespace lms::ui
|
|||||||
{
|
{
|
||||||
_scannerEvents.scanComplete.connect([this](const scanner::ScanStats& stats) {
|
_scannerEvents.scanComplete.connect([this](const scanner::ScanStats& stats) {
|
||||||
notifyMsg(Notification::Type::Info,
|
notifyMsg(Notification::Type::Info,
|
||||||
Wt::WString::tr("Lms.Admin.Database.scan-complete")
|
Wt::WString::tr("Lms.Admin.Database.scan-complete")
|
||||||
.arg(static_cast<unsigned>(stats.getTotalFileCount()))
|
.arg(static_cast<unsigned>(stats.getTotalFileCount()))
|
||||||
.arg(static_cast<unsigned>(stats.additions))
|
.arg(static_cast<unsigned>(stats.additions))
|
||||||
.arg(static_cast<unsigned>(stats.updates))
|
.arg(static_cast<unsigned>(stats.updates))
|
||||||
.arg(static_cast<unsigned>(stats.deletions))
|
.arg(static_cast<unsigned>(stats.deletions))
|
||||||
.arg(static_cast<unsigned>(stats.duplicates.size()))
|
.arg(static_cast<unsigned>(stats.duplicates.size()))
|
||||||
.arg(static_cast<unsigned>(stats.errorsCount)));
|
.arg(static_cast<unsigned>(stats.errorsCount)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,15 +31,15 @@ namespace lms::ui
|
|||||||
std::string name() const override;
|
std::string name() const override;
|
||||||
std::string resourcesUrl() const override;
|
std::string resourcesUrl() const override;
|
||||||
std::vector<Wt::WLinkedCssStyleSheet> styleSheets() const override;
|
std::vector<Wt::WLinkedCssStyleSheet> styleSheets() const override;
|
||||||
void apply(Wt::WWidget*, Wt::WWidget*, int) const override{};
|
void apply(Wt::WWidget*, Wt::WWidget*, int) const override {};
|
||||||
void apply(Wt::WWidget*, Wt::DomElement&, int) const override{};
|
void apply(Wt::WWidget*, Wt::DomElement&, int) const override {};
|
||||||
std::string disabledClass() const override { return "disabled"; }
|
std::string disabledClass() const override { return "disabled"; }
|
||||||
std::string activeClass() const override { return "active"; };
|
std::string activeClass() const override { return "active"; };
|
||||||
std::string utilityCssClass(int) const override { return ""; };
|
std::string utilityCssClass(int) const override { return ""; };
|
||||||
bool canStyleAnchorAsButton() const override { return true; };
|
bool canStyleAnchorAsButton() const override { return true; };
|
||||||
void applyValidationStyle(Wt::WWidget* widget,
|
void applyValidationStyle(Wt::WWidget* widget,
|
||||||
const Wt::WValidator::Result& validation,
|
const Wt::WValidator::Result& validation,
|
||||||
Wt::WFlags<Wt::ValidationStyleFlag> flags) const override;
|
Wt::WFlags<Wt::ValidationStyleFlag> flags) const override;
|
||||||
bool canBorderBoxElement(const Wt::DomElement&) const override { return true; }
|
bool canBorderBoxElement(const Wt::DomElement&) const override { return true; }
|
||||||
};
|
};
|
||||||
} // namespace lms::ui
|
} // namespace lms::ui
|
||||||
|
|||||||
@@ -34,6 +34,6 @@ namespace lms::ui
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void handleRequest(const Wt::Http::Request& request,
|
void handleRequest(const Wt::Http::Request& request,
|
||||||
Wt::Http::Response& response) override;
|
Wt::Http::Response& response) override;
|
||||||
};
|
};
|
||||||
} // namespace lms::ui
|
} // namespace lms::ui
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ int main(int argc, char* argv[])
|
|||||||
.options(allOptions)
|
.options(allOptions)
|
||||||
.positional(positional)
|
.positional(positional)
|
||||||
.run(),
|
.run(),
|
||||||
vm);
|
vm);
|
||||||
|
|
||||||
program_options::notify(vm);
|
program_options::notify(vm);
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ GeneticAlgorithm<Individual>::simulate(const std::vector<Individual>& initialPop
|
|||||||
scoredPopulation.reserve(initialPopulation.size());
|
scoredPopulation.reserve(initialPopulation.size());
|
||||||
|
|
||||||
std::transform(std::cbegin(initialPopulation), std::cend(initialPopulation), std::back_inserter(scoredPopulation),
|
std::transform(std::cbegin(initialPopulation), std::cend(initialPopulation), std::back_inserter(scoredPopulation),
|
||||||
[](const Individual& individual) { return ScoredIndividual{ individual }; });
|
[](const Individual& individual) { return ScoredIndividual{ individual }; });
|
||||||
|
|
||||||
scoreAndSortPopulation(scoredPopulation);
|
scoreAndSortPopulation(scoredPopulation);
|
||||||
|
|
||||||
@@ -133,10 +133,10 @@ template<typename Individual>
|
|||||||
void GeneticAlgorithm<Individual>::scoreAndSortPopulation(std::vector<ScoredIndividual>& scoredPopulation)
|
void GeneticAlgorithm<Individual>::scoreAndSortPopulation(std::vector<ScoredIndividual>& scoredPopulation)
|
||||||
{
|
{
|
||||||
parallel_foreach(_params.nbWorkers, std::begin(scoredPopulation), std::end(scoredPopulation),
|
parallel_foreach(_params.nbWorkers, std::begin(scoredPopulation), std::end(scoredPopulation),
|
||||||
[&](ScoredIndividual& scoredIndividual) {
|
[&](ScoredIndividual& scoredIndividual) {
|
||||||
if (!scoredIndividual.score)
|
if (!scoredIndividual.score)
|
||||||
scoredIndividual.score = _params.scoreFunction(scoredIndividual.individual);
|
scoredIndividual.score = _params.scoreFunction(scoredIndividual.individual);
|
||||||
});
|
});
|
||||||
|
|
||||||
std::sort(std::begin(scoredPopulation), std::end(scoredPopulation), [](const ScoredIndividual& a, const ScoredIndividual& b) { return a.score > b.score; });
|
std::sort(std::begin(scoredPopulation), std::end(scoredPopulation), [](const ScoredIndividual& a, const ScoredIndividual& b) { return a.score > b.score; });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ constructFeaturesCache(db::Session& session, const FeatureSettingsMap& featureSe
|
|||||||
|
|
||||||
std::unordered_set<FeatureName> names;
|
std::unordered_set<FeatureName> names;
|
||||||
std::transform(std::cbegin(featureSettings), std::cend(featureSettings), std::inserter(names, std::begin(names)),
|
std::transform(std::cbegin(featureSettings), std::cend(featureSettings), std::inserter(names, std::begin(names)),
|
||||||
[](const auto& itFeature) { return itFeature.first; });
|
[](const auto& itFeature) { return itFeature.first; });
|
||||||
|
|
||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
@@ -254,8 +254,8 @@ computeTrackScore(db::Session& session, db::IdType track1Id, db::IdType track2Id
|
|||||||
|
|
||||||
std::vector<db::IdType> commonArtistIds;
|
std::vector<db::IdType> commonArtistIds;
|
||||||
std::set_intersection(std::cbegin(track1ArtistIds), std::cend(track1ArtistIds),
|
std::set_intersection(std::cbegin(track1ArtistIds), std::cend(track1ArtistIds),
|
||||||
std::cbegin(track2ArtistIds), std::cend(track2ArtistIds),
|
std::cbegin(track2ArtistIds), std::cend(track2ArtistIds),
|
||||||
std::back_inserter(commonArtistIds));
|
std::back_inserter(commonArtistIds));
|
||||||
|
|
||||||
score += commonArtistIds.size();
|
score += commonArtistIds.size();
|
||||||
}
|
}
|
||||||
@@ -267,8 +267,8 @@ computeTrackScore(db::Session& session, db::IdType track1Id, db::IdType track2Id
|
|||||||
|
|
||||||
std::vector<db::IdType> commonClusterIds;
|
std::vector<db::IdType> commonClusterIds;
|
||||||
std::set_intersection(std::cbegin(track1ClusterIds), std::cend(track1ClusterIds),
|
std::set_intersection(std::cbegin(track1ClusterIds), std::cend(track1ClusterIds),
|
||||||
std::cbegin(track2ClusterIds), std::cend(track2ClusterIds),
|
std::cbegin(track2ClusterIds), std::cend(track2ClusterIds),
|
||||||
std::back_inserter(commonClusterIds));
|
std::back_inserter(commonClusterIds));
|
||||||
|
|
||||||
score += commonClusterIds.size();
|
score += commonClusterIds.size();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user