Various minor cleanup
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
#include "database/Types.hpp"
|
||||
#include "image/IEncodedImage.hpp"
|
||||
#include "services/artwork/IArtworkService.hpp"
|
||||
|
||||
@@ -43,12 +42,12 @@ namespace lms::cover
|
||||
class ArtworkService : public IArtworkService
|
||||
{
|
||||
public:
|
||||
ArtworkService(db::Db& db, const std::filesystem::path& defaultSvgCoverPath, const std::filesystem::path& defaultArtistImageSvgPath);
|
||||
|
||||
private:
|
||||
ArtworkService(db::Db& db, const std::filesystem::path& defaultReleaseCoverSvgPath, const std::filesystem::path& defaultArtistImageSvgPath);
|
||||
~ArtworkService() override = default;
|
||||
ArtworkService(const ArtworkService&) = delete;
|
||||
ArtworkService& operator=(const ArtworkService&) = delete;
|
||||
|
||||
private:
|
||||
std::shared_ptr<image::IEncodedImage> getTrackImage(db::TrackId trackId, image::ImageSize width) override;
|
||||
std::shared_ptr<image::IEncodedImage> getReleaseCover(db::ReleaseId releaseId, image::ImageSize width) override;
|
||||
std::shared_ptr<image::IEncodedImage> getArtistImage(db::ArtistId artistId, image::ImageSize width) override;
|
||||
|
||||
@@ -56,6 +56,6 @@ namespace lms::cover
|
||||
virtual void setJpegQuality(unsigned quality) = 0; // from 1 to 100
|
||||
};
|
||||
|
||||
std::unique_ptr<IArtworkService> createArtworkService(db::Db& db, const std::filesystem::path& defaultSvgCoverPath, const std::filesystem::path& defaultArtistImageSvgPath);
|
||||
std::unique_ptr<IArtworkService> createArtworkService(db::Db& db, const std::filesystem::path& defaultReleaseCoverSvgPath, const std::filesystem::path& defaultArtistImageSvgPath);
|
||||
|
||||
} // namespace lms::cover
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace lms::auth
|
||||
{
|
||||
protected:
|
||||
AuthServiceBase(db::Db& db);
|
||||
~AuthServiceBase() = default;
|
||||
AuthServiceBase(const AuthServiceBase&) = delete;
|
||||
AuthServiceBase& operator=(const AuthServiceBase&) = delete;
|
||||
|
||||
db::UserId getOrCreateUser(std::string_view loginName);
|
||||
void onUserAuthenticated(db::UserId userId);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <Wt/Auth/HashFunction.h>
|
||||
#include <Wt/WRandom.h>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/AuthToken.hpp"
|
||||
#include "database/Session.hpp"
|
||||
@@ -126,7 +125,7 @@ namespace lms::auth
|
||||
std::shared_lock lock{ _mutex };
|
||||
|
||||
if (_loginThrottler.isClientThrottled(clientAddress))
|
||||
return AuthTokenProcessResult{ AuthTokenProcessResult::State::Throttled };
|
||||
return AuthTokenProcessResult{ .state = AuthTokenProcessResult::State::Throttled, .authTokenInfo = std::nullopt };
|
||||
}
|
||||
|
||||
auto res{ processAuthToken(domain, tokenValue) };
|
||||
@@ -134,17 +133,17 @@ namespace lms::auth
|
||||
std::unique_lock lock{ _mutex };
|
||||
|
||||
if (_loginThrottler.isClientThrottled(clientAddress))
|
||||
return AuthTokenProcessResult{ AuthTokenProcessResult::State::Throttled };
|
||||
return AuthTokenProcessResult{ .state = AuthTokenProcessResult::State::Throttled, .authTokenInfo = std::nullopt };
|
||||
|
||||
if (!res)
|
||||
{
|
||||
_loginThrottler.onBadClientAttempt(clientAddress);
|
||||
return AuthTokenProcessResult{ AuthTokenProcessResult::State::Denied };
|
||||
return AuthTokenProcessResult{ .state = AuthTokenProcessResult::State::Denied, .authTokenInfo = std::nullopt };
|
||||
}
|
||||
|
||||
_loginThrottler.onGoodClientAttempt(clientAddress);
|
||||
onUserAuthenticated(res->userId);
|
||||
return AuthTokenProcessResult{ AuthTokenProcessResult::State::Granted, res };
|
||||
return AuthTokenProcessResult{ .state = AuthTokenProcessResult::State::Granted, .authTokenInfo = res };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace lms::auth
|
||||
public:
|
||||
AuthTokenService(db::Db& db, std::size_t maxThrottlerEntryCount);
|
||||
|
||||
~AuthTokenService() override = default;
|
||||
AuthTokenService(const AuthTokenService&) = delete;
|
||||
AuthTokenService& operator=(const AuthTokenService&) = delete;
|
||||
AuthTokenService(AuthTokenService&&) = delete;
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
|
||||
namespace lms::auth
|
||||
{
|
||||
std::unique_ptr<IEnvService>
|
||||
createEnvService(std::string_view backendName, db::Db& db)
|
||||
std::unique_ptr<IEnvService> createEnvService(std::string_view backendName, db::Db& db)
|
||||
{
|
||||
if (backendName == "http-headers")
|
||||
return std::make_unique<HttpHeadersEnvService>(db);
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <Wt/WDateTime.h>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/NetAddress.hpp"
|
||||
|
||||
namespace lms::auth
|
||||
@@ -35,6 +34,10 @@ namespace lms::auth
|
||||
LoginThrottler(std::size_t maxEntries)
|
||||
: _maxEntries{ maxEntries } {}
|
||||
|
||||
~LoginThrottler() = default;
|
||||
LoginThrottler(const LoginThrottler&) = delete;
|
||||
LoginThrottler& operator=(const LoginThrottler&) = delete;
|
||||
|
||||
// user must lock these calls to avoid races
|
||||
bool isClientThrottled(const boost::asio::ip::address& address) const;
|
||||
void onBadClientAttempt(const boost::asio::ip::address& address);
|
||||
|
||||
@@ -27,10 +27,8 @@
|
||||
#include "pam/PAMPasswordService.hpp"
|
||||
#endif // LMS_SUPPORT_PAM
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/User.hpp"
|
||||
#include "services/auth/Types.hpp"
|
||||
|
||||
namespace lms::auth
|
||||
@@ -63,7 +61,7 @@ namespace lms::auth
|
||||
std::shared_lock lock{ _mutex };
|
||||
|
||||
if (_loginThrottler.isClientThrottled(clientAddress))
|
||||
return { CheckResult::State::Throttled };
|
||||
return CheckResult{ .state = CheckResult::State::Throttled, .userId = {} };
|
||||
}
|
||||
|
||||
const bool match{ checkUserPassword(loginName, password) };
|
||||
@@ -71,7 +69,7 @@ namespace lms::auth
|
||||
std::unique_lock lock{ _mutex };
|
||||
|
||||
if (_loginThrottler.isClientThrottled(clientAddress))
|
||||
return { CheckResult::State::Throttled };
|
||||
return CheckResult{ .state = CheckResult::State::Throttled, .userId = {} };
|
||||
|
||||
if (match)
|
||||
{
|
||||
@@ -79,13 +77,11 @@ namespace lms::auth
|
||||
|
||||
const db::UserId userId{ getOrCreateUser(loginName) };
|
||||
onUserAuthenticated(userId);
|
||||
return { CheckResult::State::Granted, userId };
|
||||
}
|
||||
else
|
||||
{
|
||||
_loginThrottler.onBadClientAttempt(clientAddress);
|
||||
return { CheckResult::State::Denied };
|
||||
return CheckResult{ .state = CheckResult::State::Granted, .userId = userId };
|
||||
}
|
||||
|
||||
_loginThrottler.onBadClientAttempt(clientAddress);
|
||||
return CheckResult{ .state = CheckResult::State::Denied, .userId = {} };
|
||||
}
|
||||
}
|
||||
} // namespace lms::auth
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace lms::auth
|
||||
public:
|
||||
PasswordServiceBase(db::Db& db, std::size_t maxThrottlerEntries);
|
||||
|
||||
~PasswordServiceBase() override = default;
|
||||
PasswordServiceBase(const PasswordServiceBase&) = delete;
|
||||
PasswordServiceBase& operator=(const PasswordServiceBase&) = delete;
|
||||
PasswordServiceBase(PasswordServiceBase&&) = delete;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace lms::auth
|
||||
bool checkUserPassword(std::string_view loginName, std::string_view password) override;
|
||||
|
||||
bool canSetPasswords() const override;
|
||||
PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view loginName, const PasswordValidationContext& context) const override;
|
||||
PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view password, const PasswordValidationContext& context) const override;
|
||||
void setPassword(db::UserId userId, std::string_view newPassword) override;
|
||||
|
||||
db::User::PasswordHash hashPassword(std::string_view password) const;
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "services/auth/Types.hpp"
|
||||
|
||||
namespace lms::auth
|
||||
@@ -192,7 +191,7 @@ namespace lms::auth
|
||||
throw NotImplementedException{};
|
||||
}
|
||||
|
||||
void PAMPasswordService::setPassword(db::UserId, std::string_view)
|
||||
void PAMPasswordService::setPassword(db::UserId /*userId*/, std::string_view /*newPassword*/)
|
||||
{
|
||||
throw NotImplementedException{};
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "PasswordServiceBase.hpp"
|
||||
|
||||
namespace lms::auth
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <Wt/WDateTime.h>
|
||||
@@ -62,7 +61,7 @@ namespace lms::auth
|
||||
};
|
||||
|
||||
State state{ State::Denied };
|
||||
std::optional<AuthTokenInfo> authTokenInfo{};
|
||||
std::optional<AuthTokenInfo> authTokenInfo;
|
||||
};
|
||||
|
||||
struct DomainParameters
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "database/UserId.hpp"
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
#include <Wt/Dbo/ptr.h>
|
||||
@@ -52,7 +51,6 @@ namespace lms::auth
|
||||
};
|
||||
State state{ State::Denied };
|
||||
db::UserId userId{};
|
||||
std::optional<Wt::WDateTime> expiry{};
|
||||
};
|
||||
virtual CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
||||
std::string_view loginName,
|
||||
|
||||
@@ -37,12 +37,11 @@ namespace lms::feedback
|
||||
{
|
||||
public:
|
||||
FeedbackService(boost::asio::io_context& ioContext, db::Db& db);
|
||||
~FeedbackService();
|
||||
|
||||
private:
|
||||
~FeedbackService() override;
|
||||
FeedbackService(const FeedbackService&) = delete;
|
||||
FeedbackService& operator=(const FeedbackService&) = delete;
|
||||
|
||||
private:
|
||||
void star(db::UserId userId, db::ArtistId artistId) override;
|
||||
void unstar(db::UserId userId, db::ArtistId artistId) override;
|
||||
bool isStarred(db::UserId userId, db::ArtistId artistId) override;
|
||||
@@ -54,8 +53,8 @@ namespace lms::feedback
|
||||
|
||||
void star(db::UserId userId, db::ReleaseId releaseId) override;
|
||||
void unstar(db::UserId userId, db::ReleaseId releaseId) override;
|
||||
bool isStarred(db::UserId userId, db::ReleaseId releasedId) override;
|
||||
Wt::WDateTime getStarredDateTime(db::UserId userId, db::ReleaseId releasedId) override;
|
||||
bool isStarred(db::UserId userId, db::ReleaseId releaseId) override;
|
||||
Wt::WDateTime getStarredDateTime(db::UserId userId, db::ReleaseId releaseId) override;
|
||||
ReleaseContainer findStarredReleases(const FindParameters& params) override;
|
||||
|
||||
void setRating(db::UserId userId, db::ReleaseId releaseId, std::optional<db::Rating> rating) override;
|
||||
@@ -70,7 +69,6 @@ namespace lms::feedback
|
||||
void setRating(db::UserId userId, db::TrackId trackId, std::optional<db::Rating> rating) override;
|
||||
std::optional<db::Rating> getRating(db::UserId userId, db::TrackId trackId) override;
|
||||
|
||||
private:
|
||||
std::optional<db::FeedbackBackend> getUserFeedbackBackend(db::UserId userId);
|
||||
|
||||
template<typename ObjType, typename ObjIdType, typename StarredObjType>
|
||||
|
||||
@@ -30,12 +30,12 @@ namespace lms::feedback
|
||||
public:
|
||||
virtual ~IFeedbackBackend() = default;
|
||||
|
||||
virtual void onStarred(db::StarredArtistId) = 0;
|
||||
virtual void onUnstarred(db::StarredArtistId) = 0;
|
||||
virtual void onStarred(db::StarredReleaseId) = 0;
|
||||
virtual void onUnstarred(db::StarredReleaseId) = 0;
|
||||
virtual void onStarred(db::StarredTrackId) = 0;
|
||||
virtual void onUnstarred(db::StarredTrackId) = 0;
|
||||
virtual void onStarred(db::StarredArtistId artistId) = 0;
|
||||
virtual void onUnstarred(db::StarredArtistId artistId) = 0;
|
||||
virtual void onStarred(db::StarredReleaseId releaseId) = 0;
|
||||
virtual void onUnstarred(db::StarredReleaseId releaseId) = 0;
|
||||
virtual void onStarred(db::StarredTrackId trackId) = 0;
|
||||
virtual void onUnstarred(db::StarredTrackId trackId) = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<IFeedbackBackend> createFeedbackBackend(std::string_view backendName);
|
||||
|
||||
@@ -53,33 +53,33 @@ namespace lms::feedback
|
||||
{
|
||||
}
|
||||
|
||||
void InternalBackend::onStarred(db::StarredArtistId starredArtistId)
|
||||
void InternalBackend::onStarred(db::StarredArtistId artistId)
|
||||
{
|
||||
details::onStarred<db::StarredArtist>(_db.getTLSSession(), starredArtistId);
|
||||
details::onStarred<db::StarredArtist>(_db.getTLSSession(), artistId);
|
||||
}
|
||||
|
||||
void InternalBackend::onUnstarred(db::StarredArtistId starredArtistId)
|
||||
void InternalBackend::onUnstarred(db::StarredArtistId artistId)
|
||||
{
|
||||
details::onUnstarred<db::StarredArtist>(_db.getTLSSession(), starredArtistId);
|
||||
details::onUnstarred<db::StarredArtist>(_db.getTLSSession(), artistId);
|
||||
}
|
||||
|
||||
void InternalBackend::onStarred(db::StarredReleaseId starredReleaseId)
|
||||
void InternalBackend::onStarred(db::StarredReleaseId releaseId)
|
||||
{
|
||||
details::onStarred<db::StarredRelease>(_db.getTLSSession(), starredReleaseId);
|
||||
details::onStarred<db::StarredRelease>(_db.getTLSSession(), releaseId);
|
||||
}
|
||||
|
||||
void InternalBackend::onUnstarred(db::StarredReleaseId starredReleaseId)
|
||||
void InternalBackend::onUnstarred(db::StarredReleaseId releaseId)
|
||||
{
|
||||
details::onUnstarred<db::StarredRelease>(_db.getTLSSession(), starredReleaseId);
|
||||
details::onUnstarred<db::StarredRelease>(_db.getTLSSession(), releaseId);
|
||||
}
|
||||
|
||||
void InternalBackend::onStarred(db::StarredTrackId starredTrackId)
|
||||
void InternalBackend::onStarred(db::StarredTrackId trackId)
|
||||
{
|
||||
details::onStarred<db::StarredTrack>(_db.getTLSSession(), starredTrackId);
|
||||
details::onStarred<db::StarredTrack>(_db.getTLSSession(), trackId);
|
||||
}
|
||||
|
||||
void InternalBackend::onUnstarred(db::StarredTrackId starredTrackId)
|
||||
void InternalBackend::onUnstarred(db::StarredTrackId trackId)
|
||||
{
|
||||
details::onUnstarred<db::StarredTrack>(_db.getTLSSession(), starredTrackId);
|
||||
details::onUnstarred<db::StarredTrack>(_db.getTLSSession(), trackId);
|
||||
}
|
||||
} // namespace lms::feedback
|
||||
|
||||
@@ -32,14 +32,17 @@ namespace lms::feedback
|
||||
{
|
||||
public:
|
||||
InternalBackend(db::Db& db);
|
||||
~InternalBackend() override = default;
|
||||
InternalBackend(const InternalBackend&) = delete;
|
||||
InternalBackend& operator=(const InternalBackend&) = delete;
|
||||
|
||||
private:
|
||||
void onStarred(db::StarredArtistId) override;
|
||||
void onUnstarred(db::StarredArtistId) override;
|
||||
void onStarred(db::StarredReleaseId) override;
|
||||
void onUnstarred(db::StarredReleaseId) override;
|
||||
void onStarred(db::StarredTrackId) override;
|
||||
void onUnstarred(db::StarredTrackId) override;
|
||||
void onStarred(db::StarredArtistId artistId) override;
|
||||
void onUnstarred(db::StarredArtistId artistId) override;
|
||||
void onStarred(db::StarredReleaseId releaseId) override;
|
||||
void onUnstarred(db::StarredReleaseId releaseId) override;
|
||||
void onStarred(db::StarredTrackId trackId) override;
|
||||
void onUnstarred(db::StarredTrackId trackId) override;
|
||||
|
||||
db::Db& _db;
|
||||
};
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "FeedbackTypes.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace lms::feedback::listenBrainz
|
||||
{
|
||||
std::ostream& operator<<(std::ostream& os, const Feedback& feedback)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
#include <iosfwd>
|
||||
|
||||
#include <Wt/WDateTime.h>
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace lms::feedback::listenBrainz
|
||||
throw Exception{ "MBID not found!" };
|
||||
|
||||
return Feedback{
|
||||
Wt::WDateTime::fromTime_t(static_cast<int>(feedbackObj.get("created"))),
|
||||
*recordingMBID,
|
||||
static_cast<FeedbackType>(static_cast<int>(feedbackObj.get("score")))
|
||||
.created = Wt::WDateTime::fromTime_t(static_cast<int>(feedbackObj.get("created"))),
|
||||
.recordingMBID = *recordingMBID,
|
||||
.score = static_cast<FeedbackType>(static_cast<int>(feedbackObj.get("score")))
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -251,10 +251,9 @@ namespace lms::feedback::listenBrainz
|
||||
LOG(DEBUG, "getFeedbacks aborted");
|
||||
return;
|
||||
}
|
||||
else if (ec)
|
||||
{
|
||||
|
||||
if (ec)
|
||||
throw Exception{ "GetFeedbacks timer failure: " + std::string{ ec.message() } };
|
||||
}
|
||||
|
||||
startSync();
|
||||
}));
|
||||
@@ -430,7 +429,8 @@ namespace lms::feedback::listenBrainz
|
||||
LOG(DEBUG, "Too many matches for feedback '" << feedback << "': duplicate recording MBIDs found");
|
||||
return;
|
||||
}
|
||||
else if (tracks.empty())
|
||||
|
||||
if (tracks.empty())
|
||||
{
|
||||
LOG(DEBUG, "Cannot match feedback '" << feedback << "': no track found for this recording MBID");
|
||||
return;
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
|
||||
#include "database/StarredTrackId.hpp"
|
||||
#include "database/Types.hpp"
|
||||
#include "database/UserId.hpp"
|
||||
|
||||
#include "FeedbackTypes.hpp"
|
||||
@@ -50,12 +49,14 @@ namespace lms::feedback::listenBrainz
|
||||
{
|
||||
public:
|
||||
FeedbacksSynchronizer(boost::asio::io_context& ioContext, db::Db& db, core::http::IClient& client);
|
||||
~FeedbacksSynchronizer() = default;
|
||||
FeedbacksSynchronizer(const FeedbacksSynchronizer&) = delete;
|
||||
FeedbacksSynchronizer& operator=(const FeedbacksSynchronizer&) = delete;
|
||||
|
||||
void enqueFeedback(FeedbackType type, db::StarredTrackId starredTrackId);
|
||||
|
||||
private:
|
||||
void onFeedbackSent(FeedbackType type, db::StarredTrackId starredTrackId);
|
||||
|
||||
void enquePendingFeedbacks();
|
||||
|
||||
struct UserContext
|
||||
@@ -63,12 +64,13 @@ namespace lms::feedback::listenBrainz
|
||||
UserContext(db::UserId id)
|
||||
: userId{ id } {}
|
||||
|
||||
~UserContext() = default;
|
||||
UserContext(const UserContext&) = delete;
|
||||
UserContext& operator=(const UserContext&) = delete;
|
||||
|
||||
const db::UserId userId;
|
||||
bool syncing{};
|
||||
std::optional<std::size_t> feedbackCount{};
|
||||
std::optional<std::size_t> feedbackCount;
|
||||
|
||||
// resetted at each sync
|
||||
std::string listenBrainzUserName; // need to be resolved first
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "ListenBrainzBackend.hpp"
|
||||
|
||||
#include "core/IConfig.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/Service.hpp"
|
||||
#include "core/http/IClient.hpp"
|
||||
#include "database/Db.hpp"
|
||||
|
||||
@@ -133,6 +133,6 @@ namespace lms::feedback
|
||||
virtual std::optional<db::Rating> getRating(db::UserId userId, db::TrackId trackId) = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<IFeedbackService> createFeedbackService(boost::asio::io_service& ioService, db::Db& db);
|
||||
std::unique_ptr<IFeedbackService> createFeedbackService(boost::asio::io_service& ioContext, db::Db& db);
|
||||
|
||||
} // namespace lms::feedback
|
||||
|
||||
@@ -19,11 +19,8 @@
|
||||
|
||||
#include "RecommendationService.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/ScanSettings.hpp"
|
||||
#include "database/Session.hpp"
|
||||
|
||||
@@ -42,8 +42,7 @@ namespace lms::recommendation
|
||||
{
|
||||
public:
|
||||
RecommendationService(db::Db& db);
|
||||
~RecommendationService() = default;
|
||||
|
||||
~RecommendationService() override= default;
|
||||
RecommendationService(const RecommendationService&) = delete;
|
||||
RecommendationService& operator=(const RecommendationService&) = delete;
|
||||
|
||||
@@ -51,7 +50,7 @@ namespace lms::recommendation
|
||||
void load() override;
|
||||
|
||||
TrackContainer findSimilarTracks(db::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||
TrackContainer findSimilarTracks(const std::vector<db::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||
TrackContainer findSimilarTracks(const std::vector<db::TrackId>& trackIds, std::size_t maxCount) const override;
|
||||
ReleaseContainer getSimilarReleases(db::ReleaseId releaseId, std::size_t maxCount) const override;
|
||||
ArtistContainer getSimilarArtists(db::ArtistId artistId, core::EnumSet<db::TrackArtistLinkType> linkTypes, std::size_t maxCount) const override;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace lms::recommendation
|
||||
Session& dbSession{ _db.getTLSSession() };
|
||||
auto transaction{ dbSession.createReadTransaction() };
|
||||
|
||||
const auto similarTrackIds{ Track::findSimilarTrackIds(dbSession, trackIds, Range{ 0, maxCount }) };
|
||||
auto similarTrackIds{ Track::findSimilarTrackIds(dbSession, trackIds, Range{ 0, maxCount }) };
|
||||
return std::move(similarTrackIds.results);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace lms::recommendation
|
||||
if (!artist)
|
||||
return {};
|
||||
|
||||
const auto similarArtistIds{ artist->findSimilarArtistIds(artistLinkTypes, Range{ 0, maxCount }) };
|
||||
auto similarArtistIds{ artist->findSimilarArtistIds(artistLinkTypes, Range{ 0, maxCount }) };
|
||||
return std::move(similarArtistIds.results);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,17 +30,18 @@ namespace lms::recommendation
|
||||
ClusterEngine(db::Db& db)
|
||||
: _db{ db } {}
|
||||
|
||||
~ClusterEngine() override = default;
|
||||
ClusterEngine(const ClusterEngine&) = delete;
|
||||
ClusterEngine(ClusterEngine&&) = delete;
|
||||
ClusterEngine& operator=(const ClusterEngine&) = delete;
|
||||
ClusterEngine& operator=(ClusterEngine&&) = delete;
|
||||
|
||||
private:
|
||||
void load(bool, const ProgressCallback&) override {}
|
||||
void load(bool /*forceReload*/, const ProgressCallback& /*progressCallback*/) override {}
|
||||
void requestCancelLoad() override {}
|
||||
|
||||
TrackContainer findSimilarTracksFromTrackList(db::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||
TrackContainer findSimilarTracks(const std::vector<db::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||
TrackContainer findSimilarTracks(const std::vector<db::TrackId>& trackIds, std::size_t maxCount) const override;
|
||||
ReleaseContainer getSimilarReleases(db::ReleaseId releaseId, std::size_t maxCount) const override;
|
||||
ArtistContainer getSimilarArtists(db::ArtistId artistId, core::EnumSet<db::TrackArtistLinkType> linkTypes, std::size_t maxCount) const override;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Session.hpp"
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "IConstraint.hpp"
|
||||
|
||||
#include "database/ReleaseId.hpp"
|
||||
|
||||
namespace lms::db
|
||||
{
|
||||
class Db;
|
||||
@@ -34,6 +32,9 @@ namespace lms::recommendation::PlaylistGeneratorConstraint
|
||||
{
|
||||
public:
|
||||
ConsecutiveArtists(db::Db& db);
|
||||
~ConsecutiveArtists() override = default;
|
||||
ConsecutiveArtists(const ConsecutiveArtists&) = delete;
|
||||
ConsecutiveArtists& operator=(const ConsecutiveArtists&) = delete;
|
||||
|
||||
private:
|
||||
float computeScore(const TrackContainer& trackIds, std::size_t trackIndex) override;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "ConsecutiveReleases.hpp"
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Session.hpp"
|
||||
@@ -46,10 +45,10 @@ namespace lms::recommendation::PlaylistGeneratorConstraint
|
||||
for (std::size_t i{ 1 }; i < rangeSize; ++i)
|
||||
{
|
||||
if ((trackIndex >= i) && getReleaseId(trackIds[trackIndex - i]) == releaseId)
|
||||
score += (1.f / static_cast<float>(i));
|
||||
score += (1.F / static_cast<float>(i));
|
||||
|
||||
if ((trackIndex + i < trackIds.size()) && getReleaseId(trackIds[trackIndex + i]) == releaseId)
|
||||
score += (1.f / static_cast<float>(i));
|
||||
score += (1.F / static_cast<float>(i));
|
||||
}
|
||||
|
||||
return score;
|
||||
|
||||
@@ -34,6 +34,9 @@ namespace lms::recommendation::PlaylistGeneratorConstraint
|
||||
{
|
||||
public:
|
||||
ConsecutiveReleases(db::Db& db);
|
||||
~ConsecutiveReleases() override = default;
|
||||
ConsecutiveReleases(const ConsecutiveReleases&) = delete;
|
||||
ConsecutiveReleases& operator=(const ConsecutiveReleases&) = delete;
|
||||
|
||||
private:
|
||||
float computeScore(const std::vector<db::TrackId>& trackIds, std::size_t trackIndex) override;
|
||||
|
||||
@@ -26,6 +26,6 @@ namespace lms::recommendation::PlaylistGeneratorConstraint
|
||||
float DuplicateTracks::computeScore(const std::vector<db::TrackId>& trackIds, std::size_t trackIndex)
|
||||
{
|
||||
const auto count{ std::count(std::cbegin(trackIds), std::cend(trackIds), trackIds[trackIndex]) };
|
||||
return count == 1 ? 0 : 1000;
|
||||
return count == 1 ? 0 : 1'000;
|
||||
}
|
||||
} // namespace lms::recommendation::PlaylistGeneratorConstraint
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "services/recommendation/Types.hpp"
|
||||
|
||||
namespace lms::recommendation::PlaylistGeneratorConstraint
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "database/TrackListId.hpp"
|
||||
#include "database/Types.hpp"
|
||||
#include "services/recommendation/Types.hpp"
|
||||
|
||||
namespace lms::db
|
||||
@@ -42,5 +41,5 @@ namespace lms::recommendation
|
||||
virtual TrackContainer extendPlaylist(db::TrackListId tracklistId, std::size_t maxCount) const = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<IPlaylistGeneratorService> createPlaylistGeneratorService(db::Db& db, IRecommendationService& recommandationService);
|
||||
std::unique_ptr<IPlaylistGeneratorService> createPlaylistGeneratorService(db::Db& db, IRecommendationService& recommendationService);
|
||||
} // namespace lms::recommendation
|
||||
|
||||
@@ -21,11 +21,8 @@
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/IConfig.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/ITraceLogger.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "image/Exception.hpp"
|
||||
#include "image/Image.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <deque>
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
#include <span>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <span>
|
||||
|
||||
#include "core/IConfig.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
@@ -33,8 +34,6 @@
|
||||
#include "database/Image.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "image/Exception.hpp"
|
||||
#include "image/Image.hpp"
|
||||
|
||||
namespace lms::scanner
|
||||
{
|
||||
@@ -55,7 +54,7 @@ namespace lms::scanner
|
||||
db::Session& session;
|
||||
db::ArtistId lastRetrievedArtistId;
|
||||
std::size_t processedArtistCount{};
|
||||
const std::vector<std::string>& artistFileNames;
|
||||
std::span<const std::string> artistFileNames;
|
||||
};
|
||||
|
||||
db::Image::pointer findImageInDirectory(SearchImageContext& searchContext, const std::filesystem::path& directoryPath)
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace lms::scanner
|
||||
{
|
||||
public:
|
||||
ScanStepAssociateArtistImages(InitParams& initParams);
|
||||
~ScanStepAssociateArtistImages() override = default;
|
||||
ScanStepAssociateArtistImages(const ScanStepAssociateArtistImages&) = delete;
|
||||
ScanStepAssociateArtistImages& operator=(const ScanStepAssociateArtistImages&) = delete;
|
||||
|
||||
private:
|
||||
ScanStep getStep() const override { return ScanStep::AssociateArtistImages; }
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "image/Exception.hpp"
|
||||
#include "image/Image.hpp"
|
||||
|
||||
namespace lms::scanner
|
||||
{
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace lms::scanner
|
||||
{
|
||||
public:
|
||||
ScanStepAssociateReleaseImages(InitParams& initParams);
|
||||
~ScanStepAssociateReleaseImages() override = default;
|
||||
ScanStepAssociateReleaseImages(const ScanStepAssociateReleaseImages&) = delete;
|
||||
ScanStepAssociateReleaseImages& operator=(const ScanStepAssociateReleaseImages&) = delete;
|
||||
|
||||
private:
|
||||
ScanStep getStep() const override { return ScanStep::AssociateReleaseImages; }
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace lms::scanner
|
||||
}
|
||||
|
||||
protected:
|
||||
~ScanStepBase() override = default;
|
||||
|
||||
const ScannerSettings& _settings;
|
||||
ProgressCallback _progressCallback;
|
||||
bool& _abortScan;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "ScanStepComputeClusterStats.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Session.hpp"
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "ScanStepRemoveOrphanedDbEntries.hpp"
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Db.hpp"
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "ScanStepBase.hpp"
|
||||
|
||||
namespace lms::scanner
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "database/TrackArtistLink.hpp"
|
||||
#include "database/TrackFeatures.hpp"
|
||||
#include "database/TrackLyrics.hpp"
|
||||
#include "metadata/Exception.hpp"
|
||||
#include "metadata/IParser.hpp"
|
||||
|
||||
namespace lms::scanner
|
||||
@@ -391,9 +390,9 @@ namespace lms::scanner
|
||||
|
||||
if (readStyle == "fast")
|
||||
return metadata::ParserReadStyle::Fast;
|
||||
else if (readStyle == "average")
|
||||
if (readStyle == "average")
|
||||
return metadata::ParserReadStyle::Average;
|
||||
else if (readStyle == "accurate")
|
||||
if (readStyle == "accurate")
|
||||
return metadata::ParserReadStyle::Accurate;
|
||||
|
||||
throw core::LmsException{ "Invalid value for 'scanner-parser-read-style'" };
|
||||
@@ -888,16 +887,9 @@ namespace lms::scanner
|
||||
return;
|
||||
}
|
||||
|
||||
bool added;
|
||||
const bool added{ !image };
|
||||
if (!image)
|
||||
{
|
||||
image = dbSession.create<db::Image>(file);
|
||||
added = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
added = false;
|
||||
}
|
||||
|
||||
image.modify()->setLastWriteTime(fileInfo->lastWriteTime);
|
||||
image.modify()->setFileSize(fileInfo->fileSize);
|
||||
@@ -945,16 +937,11 @@ namespace lms::scanner
|
||||
return;
|
||||
}
|
||||
|
||||
bool added;
|
||||
const bool added{ !trackLyrics };
|
||||
if (!trackLyrics)
|
||||
{
|
||||
trackLyrics = dbSession.create<db::TrackLyrics>();
|
||||
trackLyrics.modify()->setAbsoluteFilePath(file);
|
||||
added = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
added = false;
|
||||
}
|
||||
|
||||
trackLyrics.modify()->setLastWriteTime(fileInfo->lastWriteTime);
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace lms::scanner
|
||||
bool checkLyricsFileNeedScan(ScanContext& context, const std::filesystem::path& file);
|
||||
|
||||
void processFileScanResults(ScanContext& context, std::span<const FileScanResult> scanResults, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
void processAudioFileScanData(ScanContext& context, const std::filesystem::path& path, const metadata::Track* trackMetadata, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
void processImageFileScanData(ScanContext& context, const std::filesystem::path& path, const ImageInfo* imageInfo, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
void processLyricsFileScanData(ScanContext& context, const std::filesystem::path& path, const metadata::Lyrics* lyrics, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
void processAudioFileScanData(ScanContext& context, const std::filesystem::path& file, const metadata::Track* trackMetadata, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
void processImageFileScanData(ScanContext& context, const std::filesystem::path& file, const ImageInfo* imageInfo, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
void processLyricsFileScanData(ScanContext& context, const std::filesystem::path& file, const metadata::Lyrics* lyrics, const ScannerSettings::MediaLibraryInfo& libraryInfo);
|
||||
|
||||
std::unique_ptr<metadata::IParser> _metadataParser;
|
||||
const std::vector<std::string> _extraTagsToParse;
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include "ScanStepUpdateLibraryFields.hpp"
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Directory.hpp"
|
||||
#include "database/MediaLibrary.hpp"
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "database/DirectoryId.hpp"
|
||||
|
||||
#include "ScanStepBase.hpp"
|
||||
|
||||
namespace lms::scanner
|
||||
|
||||
@@ -21,11 +21,9 @@
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "core/Exception.hpp"
|
||||
#include "core/IConfig.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/ITraceLogger.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "database/MediaLibrary.hpp"
|
||||
#include "database/ScanSettings.hpp"
|
||||
#include "database/TrackFeatures.hpp"
|
||||
|
||||
@@ -31,10 +31,8 @@
|
||||
|
||||
#include "IScanStep.hpp"
|
||||
#include "ScannerSettings.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Types.hpp"
|
||||
#include "services/scanner/IScannerService.hpp"
|
||||
|
||||
namespace lms::scanner
|
||||
@@ -44,11 +42,10 @@ namespace lms::scanner
|
||||
public:
|
||||
ScannerService(db::Db& db);
|
||||
~ScannerService() override;
|
||||
|
||||
private:
|
||||
ScannerService(const ScannerService&) = delete;
|
||||
ScannerService& operator=(const ScannerService&) = delete;
|
||||
|
||||
private:
|
||||
void requestReload() override;
|
||||
void requestImmediateScan(const ScanOptions& scanOptions) override;
|
||||
|
||||
@@ -83,7 +80,7 @@ namespace lms::scanner
|
||||
Wt::WIOService _ioService;
|
||||
boost::asio::system_timer _scheduleTimer{ _ioService };
|
||||
Events _events;
|
||||
std::chrono::system_clock::time_point _lastScanInProgressEmit{};
|
||||
std::chrono::system_clock::time_point _lastScanInProgressEmit;
|
||||
db::Db& _db;
|
||||
|
||||
mutable std::shared_mutex _statusMutex;
|
||||
|
||||
@@ -58,9 +58,9 @@ namespace lms
|
||||
res += track->getName();
|
||||
if (track->getRelease())
|
||||
res += " [" + std::string{ track->getRelease()->getName() } + "]";
|
||||
for (auto artist : track->getArtists({ TrackArtistLinkType::Artist }))
|
||||
for (const auto& artist : track->getArtists({ TrackArtistLinkType::Artist }))
|
||||
res += " - " + artist->getName();
|
||||
for (auto cluster : track->getClusters())
|
||||
for (const auto& cluster : track->getClusters())
|
||||
res += " {" + std::string{ cluster->getType()->getName() } + "-" + std::string{ cluster->getName() } + "}";
|
||||
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user