Migrated recommendation stuff
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
#include <Wt/Auth/PasswordStrengthValidator.h>
|
#include <Wt/Auth/PasswordStrengthValidator.h>
|
||||||
#include <Wt/WRandom.h>
|
#include <Wt/WRandom.h>
|
||||||
|
|
||||||
#include "auth/Types.hpp"
|
#include "services/auth/Types.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "utils/Exception.hpp"
|
#include "utils/Exception.hpp"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
#include "auth/IAuthTokenService.hpp"
|
#include "services/auth/IAuthTokenService.hpp"
|
||||||
#include "AuthServiceBase.hpp"
|
#include "AuthServiceBase.hpp"
|
||||||
#include "LoginThrottler.hpp"
|
#include "LoginThrottler.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "auth/IEnvService.hpp"
|
#include "services/auth/IEnvService.hpp"
|
||||||
|
|
||||||
#include "auth/Types.hpp"
|
#include "services/auth/Types.hpp"
|
||||||
#include "http-headers/HttpHeadersEnvService.hpp"
|
#include "http-headers/HttpHeadersEnvService.hpp"
|
||||||
|
|
||||||
namespace Auth
|
namespace Auth
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "pam/PAMPasswordService.hpp"
|
#include "pam/PAMPasswordService.hpp"
|
||||||
#endif // LMS_SUPPORT_PAM
|
#endif // LMS_SUPPORT_PAM
|
||||||
|
|
||||||
#include "auth/Types.hpp"
|
#include "services/auth/Types.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "utils/Exception.hpp"
|
#include "utils/Exception.hpp"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "AuthServiceBase.hpp"
|
#include "AuthServiceBase.hpp"
|
||||||
#include "LoginThrottler.hpp"
|
#include "LoginThrottler.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "auth/IEnvService.hpp"
|
#include "services/auth/IEnvService.hpp"
|
||||||
#include "AuthServiceBase.hpp"
|
#include "AuthServiceBase.hpp"
|
||||||
|
|
||||||
namespace Auth
|
namespace Auth
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
#include "InternalPasswordService.hpp"
|
#include "InternalPasswordService.hpp"
|
||||||
#include <Wt/WRandom.h>
|
#include <Wt/WRandom.h>
|
||||||
|
|
||||||
#include "auth/IAuthTokenService.hpp"
|
#include "services/auth/IAuthTokenService.hpp"
|
||||||
#include "auth/Types.hpp"
|
#include "services/auth/Types.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "utils/Exception.hpp"
|
#include "utils/Exception.hpp"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
|
|
||||||
#include "auth/Types.hpp"
|
#include "services/auth/Types.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
#include <boost/asio/ip/address.hpp>
|
||||||
#include <Wt/WDateTime.h>
|
#include <Wt/WDateTime.h>
|
||||||
#include <Wt/Dbo/ptr.h>
|
#include <Wt/Dbo/ptr.h>
|
||||||
|
|
||||||
#include <boost/asio/ip/address.hpp>
|
#include "services/auth/Types.hpp"
|
||||||
#include "auth/Types.hpp"
|
|
||||||
#include "database/Types.hpp"
|
#include "database/Types.hpp"
|
||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
@@ -4,7 +4,7 @@ add_library(lmsrecommendation SHARED
|
|||||||
impl/features/FeaturesEngineCache.cpp
|
impl/features/FeaturesEngineCache.cpp
|
||||||
impl/features/FeaturesEngine.cpp
|
impl/features/FeaturesEngine.cpp
|
||||||
impl/features/FeaturesDefs.cpp
|
impl/features/FeaturesDefs.cpp
|
||||||
impl/Engine.cpp
|
impl/RecommendationService.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(lmsrecommendation INTERFACE
|
target_include_directories(lmsrecommendation INTERFACE
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "IEngine.hpp"
|
||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-14
@@ -24,6 +24,7 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include "database/Types.hpp"
|
#include "database/Types.hpp"
|
||||||
#include "utils/EnumSet.hpp"
|
#include "utils/EnumSet.hpp"
|
||||||
|
#include "services/recommendation/Types.hpp"
|
||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
@@ -37,23 +38,9 @@ namespace Recommendation
|
|||||||
public:
|
public:
|
||||||
virtual ~IEngine() = default;
|
virtual ~IEngine() = default;
|
||||||
|
|
||||||
struct Progress
|
|
||||||
{
|
|
||||||
std::size_t totalElems {};
|
|
||||||
std::size_t processedElems {};
|
|
||||||
};
|
|
||||||
using ProgressCallback = std::function<void(const Progress&)>;
|
|
||||||
virtual void load(bool forceReload, const ProgressCallback& progressCallback = {}) = 0;
|
virtual void load(bool forceReload, const ProgressCallback& progressCallback = {}) = 0;
|
||||||
virtual void cancelLoad() = 0; // wait for cancel done
|
|
||||||
virtual void requestCancelLoad() = 0;
|
virtual void requestCancelLoad() = 0;
|
||||||
|
|
||||||
template <typename IdType>
|
|
||||||
using ResultContainer = std::vector<IdType>;
|
|
||||||
|
|
||||||
using ArtistContainer = ResultContainer<Database::ArtistId>;
|
|
||||||
using ReleaseContainer = ResultContainer<Database::ReleaseId>;
|
|
||||||
using TrackContainer = ResultContainer<Database::TrackId>;
|
|
||||||
|
|
||||||
virtual TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const = 0;
|
virtual TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const = 0;
|
||||||
virtual TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const = 0;
|
virtual TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const = 0;
|
||||||
virtual ReleaseContainer getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const = 0;
|
virtual ReleaseContainer getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const = 0;
|
||||||
+18
-18
@@ -17,7 +17,7 @@
|
|||||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Engine.hpp"
|
#include "RecommendationService.hpp"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -47,19 +47,19 @@ namespace Recommendation
|
|||||||
throw LmsException {"Internal error"};
|
throw LmsException {"Internal error"};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IEngine>
|
std::unique_ptr<IRecommendationService>
|
||||||
createEngine(Database::Db& db)
|
createRecommendationService(Database::Db& db)
|
||||||
{
|
{
|
||||||
return std::make_unique<Engine>(db);
|
return std::make_unique<RecommendationService>(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::Engine(Database::Db& db)
|
RecommendationService::RecommendationService(Database::Db& db)
|
||||||
: _db {db}
|
: _db {db}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::TrackContainer
|
TrackContainer
|
||||||
Engine::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
RecommendationService::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
TrackContainer res;
|
TrackContainer res;
|
||||||
|
|
||||||
@@ -78,8 +78,8 @@ namespace Recommendation
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::TrackContainer
|
TrackContainer
|
||||||
Engine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
RecommendationService::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
TrackContainer res;
|
TrackContainer res;
|
||||||
|
|
||||||
@@ -102,8 +102,8 @@ namespace Recommendation
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::ReleaseContainer
|
ReleaseContainer
|
||||||
Engine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
RecommendationService::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
ReleaseContainer res;
|
ReleaseContainer res;
|
||||||
|
|
||||||
@@ -128,8 +128,8 @@ namespace Recommendation
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::ArtistContainer
|
ArtistContainer
|
||||||
Engine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
RecommendationService::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
ArtistContainer res;
|
ArtistContainer res;
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ namespace Recommendation
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Engine::load(bool forceReload, const ProgressCallback& progressCallback)
|
RecommendationService::load(bool forceReload, const ProgressCallback& progressCallback)
|
||||||
{
|
{
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
@@ -208,18 +208,18 @@ namespace Recommendation
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Engine::loadPendingEngine(EngineType engineType, std::unique_ptr<IEngine> engine, bool forceReload, const ProgressCallback& progressCallback)
|
RecommendationService::loadPendingEngine(EngineType engineType, std::unique_ptr<IEngine> engine, bool forceReload, const ProgressCallback& progressCallback)
|
||||||
{
|
{
|
||||||
if (!_loadCancelled)
|
if (!_loadCancelled)
|
||||||
{
|
{
|
||||||
LMS_LOG(RECOMMENDATION, INFO) << "Initializing engine '" << engineTypeToString(engineType) << "'...";
|
LMS_LOG(RECOMMENDATION, INFO) << "Initializing engine '" << engineTypeToString(engineType) << "'...";
|
||||||
|
|
||||||
auto progress {[&](const IEngine::Progress& progress)
|
auto progress {[&](const Progress& progress)
|
||||||
{
|
{
|
||||||
progressCallback(progress);
|
progressCallback(progress);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
engine->load(forceReload, progressCallback ? progress : IEngine::ProgressCallback {});
|
engine->load(forceReload, progressCallback ? progress : ProgressCallback {});
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock {_controlMutex};
|
std::scoped_lock lock {_controlMutex};
|
||||||
@@ -236,7 +236,7 @@ namespace Recommendation
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Engine::cancelLoad()
|
RecommendationService::cancelLoad()
|
||||||
{
|
{
|
||||||
LMS_LOG(RECOMMENDATION, DEBUG) << "Cancelling loading...";
|
LMS_LOG(RECOMMENDATION, DEBUG) << "Cancelling loading...";
|
||||||
|
|
||||||
+9
-9
@@ -25,7 +25,8 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
|
#include "IEngine.hpp"
|
||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
@@ -40,21 +41,20 @@ namespace Recommendation
|
|||||||
Features,
|
Features,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Engine : public IEngine
|
class RecommendationService : public IRecommendationService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Engine(Database::Db& db);
|
RecommendationService(Database::Db& db);
|
||||||
~Engine() = default;
|
~RecommendationService() = default;
|
||||||
|
|
||||||
Engine(const Engine&) = delete;
|
RecommendationService(const RecommendationService&) = delete;
|
||||||
Engine(Engine&&) = delete;
|
RecommendationService(RecommendationService&&) = delete;
|
||||||
Engine& operator=(const Engine&) = delete;
|
RecommendationService& operator=(const RecommendationService&) = delete;
|
||||||
Engine& operator=(Engine&&) = delete;
|
RecommendationService& operator=(RecommendationService&&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load(bool forceReload, const ProgressCallback& progressCallback) override;
|
void load(bool forceReload, const ProgressCallback& progressCallback) override;
|
||||||
void cancelLoad() override;
|
void cancelLoad() override;
|
||||||
void requestCancelLoad() override {};
|
|
||||||
|
|
||||||
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||||
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||||
@@ -34,7 +34,7 @@ std::unique_ptr<IEngine> createClustersEngine(Database::Db& db)
|
|||||||
return std::make_unique<ClusterEngine>(db);
|
return std::make_unique<ClusterEngine>(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::TrackContainer
|
TrackContainer
|
||||||
ClusterEngine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
ClusterEngine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
Database::Session& dbSession {_db.getTLSSession()};
|
Database::Session& dbSession {_db.getTLSSession()};
|
||||||
@@ -52,7 +52,7 @@ ClusterEngine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::ResultContainer<Database::TrackId>
|
TrackContainer
|
||||||
ClusterEngine::getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const
|
ClusterEngine::getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
Database::Session& dbSession {_db.getTLSSession()};
|
Database::Session& dbSession {_db.getTLSSession()};
|
||||||
@@ -74,7 +74,7 @@ ClusterEngine::getSimilarTracksFromTrackList(Database::TrackListId tracklistId,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::ResultContainer<Database::ReleaseId>
|
ReleaseContainer
|
||||||
ClusterEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
ClusterEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
Database::Session& dbSession {_db.getTLSSession()};
|
Database::Session& dbSession {_db.getTLSSession()};
|
||||||
@@ -95,7 +95,7 @@ ClusterEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t max
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::ResultContainer<Database::ArtistId>
|
ArtistContainer
|
||||||
ClusterEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> artistLinkTypes, std::size_t maxCount) const
|
ClusterEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> artistLinkTypes, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
Database::Session& dbSession {_db.getTLSSession()};
|
Database::Session& dbSession {_db.getTLSSession()};
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "IEngine.hpp"
|
||||||
|
|
||||||
namespace Recommendation
|
namespace Recommendation
|
||||||
{
|
{
|
||||||
@@ -37,7 +37,6 @@ namespace Recommendation
|
|||||||
private:
|
private:
|
||||||
void load(bool, const ProgressCallback&) override {}
|
void load(bool, const ProgressCallback&) override {}
|
||||||
void requestCancelLoad() override {}
|
void requestCancelLoad() override {}
|
||||||
void cancelLoad() {}
|
|
||||||
|
|
||||||
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||||
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ FeaturesEngine::loadFromCache(FeaturesEngineCache cache)
|
|||||||
load(std::move(cache._network), cache._trackPositions);
|
load(std::move(cache._network), cache._trackPositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::TrackContainer
|
TrackContainer
|
||||||
FeaturesEngine::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
FeaturesEngine::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
const TrackContainer trackIds {[&]
|
const TrackContainer trackIds {[&]
|
||||||
@@ -269,7 +269,7 @@ FeaturesEngine::getSimilarTracksFromTrackList(Database::TrackListId trackListId,
|
|||||||
return getSimilarTracks(trackIds, maxCount);
|
return getSimilarTracks(trackIds, maxCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::TrackContainer
|
TrackContainer
|
||||||
FeaturesEngine::getSimilarTracks(const std::vector<Database::TrackId>& tracksIds, std::size_t maxCount) const
|
FeaturesEngine::getSimilarTracks(const std::vector<Database::TrackId>& tracksIds, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
auto similarTrackIds {getSimilarObjects(tracksIds, _trackMatrix, _trackPositions, maxCount)};
|
auto similarTrackIds {getSimilarObjects(tracksIds, _trackMatrix, _trackPositions, maxCount)};
|
||||||
@@ -290,7 +290,7 @@ FeaturesEngine::getSimilarTracks(const std::vector<Database::TrackId>& tracksIds
|
|||||||
return similarTrackIds;
|
return similarTrackIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEngine::ReleaseContainer
|
ReleaseContainer
|
||||||
FeaturesEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
FeaturesEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
auto similarReleaseIds {getSimilarObjects({releaseId}, _releaseMatrix, _releasePositions, maxCount)};
|
auto similarReleaseIds {getSimilarObjects({releaseId}, _releaseMatrix, _releasePositions, maxCount)};
|
||||||
@@ -312,12 +312,12 @@ FeaturesEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t ma
|
|||||||
return similarReleaseIds;
|
return similarReleaseIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Database::ArtistId>
|
ArtistContainer
|
||||||
FeaturesEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
FeaturesEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
||||||
{
|
{
|
||||||
auto getSimilarArtistIdsForLinkType {[&] (Database::TrackArtistLinkType linkType)
|
auto getSimilarArtistIdsForLinkType {[&] (Database::TrackArtistLinkType linkType)
|
||||||
{
|
{
|
||||||
std::vector<Database::ArtistId> similarArtistIds;
|
ArtistContainer similarArtistIds;
|
||||||
|
|
||||||
const auto itArtists {_artistMatrix.find(linkType)};
|
const auto itArtists {_artistMatrix.find(linkType)};
|
||||||
if (itArtists == std::cend(_artistMatrix))
|
if (itArtists == std::cend(_artistMatrix))
|
||||||
@@ -336,7 +336,7 @@ FeaturesEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database:
|
|||||||
similarArtistIds.insert(std::begin(similarArtistIdsForLinkType), std::end(similarArtistIdsForLinkType));
|
similarArtistIds.insert(std::begin(similarArtistIdsForLinkType), std::end(similarArtistIdsForLinkType));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Database::ArtistId> res(std::cbegin(similarArtistIds), std::cend(similarArtistIds));
|
ArtistContainer res(std::cbegin(similarArtistIds), std::cend(similarArtistIds));
|
||||||
|
|
||||||
Database::Session& session {_db.getTLSSession()};
|
Database::Session& session {_db.getTLSSession()};
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,10 +26,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "recommendation/IEngine.hpp"
|
|
||||||
#include "som/DataNormalizer.hpp"
|
#include "som/DataNormalizer.hpp"
|
||||||
#include "som/Network.hpp"
|
#include "som/Network.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
|
#include "IEngine.hpp"
|
||||||
#include "FeaturesEngineCache.hpp"
|
#include "FeaturesEngineCache.hpp"
|
||||||
#include "FeaturesDefs.hpp"
|
#include "FeaturesDefs.hpp"
|
||||||
|
|
||||||
@@ -62,7 +62,6 @@ class FeaturesEngine : public IEngine
|
|||||||
private:
|
private:
|
||||||
void load(bool forceReload, const ProgressCallback& progressCallback) override;
|
void load(bool forceReload, const ProgressCallback& progressCallback) override;
|
||||||
void requestCancelLoad() override;
|
void requestCancelLoad() override;
|
||||||
void cancelLoad() override {}
|
|
||||||
|
|
||||||
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||||
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||||
|
|||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Emeric Poupon
|
||||||
|
*
|
||||||
|
* This file is part of LMS.
|
||||||
|
*
|
||||||
|
* LMS is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LMS is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
#include "utils/EnumSet.hpp"
|
||||||
|
#include "services/recommendation/Types.hpp"
|
||||||
|
|
||||||
|
namespace Database
|
||||||
|
{
|
||||||
|
class Db;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Recommendation
|
||||||
|
{
|
||||||
|
class IRecommendationService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IRecommendationService() = default;
|
||||||
|
|
||||||
|
virtual void load(bool forceReload, const ProgressCallback& progressCallback = {}) = 0;
|
||||||
|
virtual void cancelLoad() = 0; // wait for cancel done
|
||||||
|
|
||||||
|
virtual TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const = 0;
|
||||||
|
virtual TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const = 0;
|
||||||
|
virtual ReleaseContainer getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const = 0;
|
||||||
|
virtual ArtistContainer getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<IRecommendationService> createRecommendationService(Database::Db& db);
|
||||||
|
|
||||||
|
} // ns Recommendation
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include "database/Types.hpp"
|
||||||
|
|
||||||
|
namespace Recommendation
|
||||||
|
{
|
||||||
|
struct Progress
|
||||||
|
{
|
||||||
|
std::size_t totalElems {};
|
||||||
|
std::size_t processedElems {};
|
||||||
|
};
|
||||||
|
using ProgressCallback = std::function<void(const Progress&)>;
|
||||||
|
|
||||||
|
template <typename IdType>
|
||||||
|
using ResultContainer = std::vector<IdType>;
|
||||||
|
|
||||||
|
using ArtistContainer = ResultContainer<Database::ArtistId>;
|
||||||
|
using ReleaseContainer = ResultContainer<Database::ReleaseId>;
|
||||||
|
using TrackContainer = ResultContainer<Database::TrackId>;
|
||||||
|
|
||||||
|
} // namespace Recommendation
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
#include "database/TrackArtistLink.hpp"
|
#include "database/TrackArtistLink.hpp"
|
||||||
#include "database/TrackFeatures.hpp"
|
#include "database/TrackFeatures.hpp"
|
||||||
#include "metadata/TagLibParser.hpp"
|
#include "metadata/TagLibParser.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "utils/Exception.hpp"
|
#include "utils/Exception.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Path.hpp"
|
#include "utils/Path.hpp"
|
||||||
@@ -249,13 +249,13 @@ getOrCreateClusters(Session& session, const MetaData::Clusters& clustersNames)
|
|||||||
namespace Scanner {
|
namespace Scanner {
|
||||||
|
|
||||||
std::unique_ptr<IScanner>
|
std::unique_ptr<IScanner>
|
||||||
createScanner(Database::Db& db, Recommendation::IEngine& recommendationEngine)
|
createScanner(Database::Db& db, Recommendation::IRecommendationService& recommendationService)
|
||||||
{
|
{
|
||||||
return std::make_unique<Scanner>(db, recommendationEngine);
|
return std::make_unique<Scanner>(db, recommendationService);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scanner::Scanner(Database::Db& db, Recommendation::IEngine& recommendationEngine)
|
Scanner::Scanner(Database::Db& db, Recommendation::IRecommendationService& recommendationService)
|
||||||
: _recommendationEngine {recommendationEngine}
|
: _recommendationService {recommendationService}
|
||||||
, _dbSession {db}
|
, _dbSession {db}
|
||||||
{
|
{
|
||||||
// For now, always use TagLib
|
// For now, always use TagLib
|
||||||
@@ -284,8 +284,8 @@ Scanner::start()
|
|||||||
if (_abortScan)
|
if (_abortScan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_recommendationEngine.load(false,
|
_recommendationService.load(false,
|
||||||
[](const Recommendation::IEngine::Progress& progress)
|
[](const Recommendation::Progress& progress)
|
||||||
{
|
{
|
||||||
LMS_LOG(DBUPDATER, DEBUG) << "Reloading recommendation : " << progress.processedElems << "/" << progress.totalElems;
|
LMS_LOG(DBUPDATER, DEBUG) << "Reloading recommendation : " << progress.processedElems << "/" << progress.totalElems;
|
||||||
});
|
});
|
||||||
@@ -302,7 +302,7 @@ Scanner::stop()
|
|||||||
|
|
||||||
_abortScan = true;
|
_abortScan = true;
|
||||||
_scheduleTimer.cancel();
|
_scheduleTimer.cancel();
|
||||||
_recommendationEngine.cancelLoad();
|
_recommendationService.cancelLoad();
|
||||||
_ioService.stop();
|
_ioService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +316,7 @@ Scanner::abortScan()
|
|||||||
|
|
||||||
_abortScan = true;
|
_abortScan = true;
|
||||||
_scheduleTimer.cancel();
|
_scheduleTimer.cancel();
|
||||||
_recommendationEngine.cancelLoad();
|
_recommendationService.cancelLoad();
|
||||||
_ioService.stop();
|
_ioService.stop();
|
||||||
LMS_LOG(DBUPDATER, DEBUG) << "Scan abort done!";
|
LMS_LOG(DBUPDATER, DEBUG) << "Scan abort done!";
|
||||||
|
|
||||||
@@ -571,7 +571,7 @@ Scanner::fetchTrackFeatures(Database::TrackId trackId, const UUID& recordingMBID
|
|||||||
void
|
void
|
||||||
Scanner::fetchTrackFeatures(ScanStats& stats)
|
Scanner::fetchTrackFeatures(ScanStats& stats)
|
||||||
{
|
{
|
||||||
if (_recommendationEngineType != ScanSettings::RecommendationEngineType::Features)
|
if (_recommendationServiceType != ScanSettings::RecommendationEngineType::Features)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ScanStepStats stepStats{stats.startTime, ScanProgressStep::FetchingTrackFeatures};
|
ScanStepStats stepStats{stats.startTime, ScanProgressStep::FetchingTrackFeatures};
|
||||||
@@ -638,7 +638,7 @@ Scanner::refreshScanSettings()
|
|||||||
[](const std::filesystem::path& extension) { return std::filesystem::path{ StringUtils::stringToLower(extension.string()) }; });
|
[](const std::filesystem::path& extension) { return std::filesystem::path{ StringUtils::stringToLower(extension.string()) }; });
|
||||||
}
|
}
|
||||||
_mediaDirectory = scanSettings->getMediaDirectory();
|
_mediaDirectory = scanSettings->getMediaDirectory();
|
||||||
_recommendationEngineType = scanSettings->getRecommendationEngineType();
|
_recommendationServiceType = scanSettings->getRecommendationEngineType();
|
||||||
|
|
||||||
const auto clusterTypes = scanSettings->getClusterTypes();
|
const auto clusterTypes = scanSettings->getClusterTypes();
|
||||||
std::set<std::string> clusterTypeNames;
|
std::set<std::string> clusterTypeNames;
|
||||||
@@ -1037,7 +1037,7 @@ Scanner::reloadSimilarityEngine(ScanStats& stats)
|
|||||||
{
|
{
|
||||||
ScanStepStats stepStats {stats.startTime, ScanProgressStep::ReloadingSimilarityEngine};
|
ScanStepStats stepStats {stats.startTime, ScanProgressStep::ReloadingSimilarityEngine};
|
||||||
|
|
||||||
auto progressCallback {[&](const Recommendation::IEngine::Progress& progress)
|
auto progressCallback {[&](const Recommendation::Progress& progress)
|
||||||
{
|
{
|
||||||
stepStats.totalElems = progress.totalElems;
|
stepStats.totalElems = progress.totalElems;
|
||||||
stepStats.processedElems = progress.processedElems;
|
stepStats.processedElems = progress.processedElems;
|
||||||
@@ -1045,7 +1045,7 @@ Scanner::reloadSimilarityEngine(ScanStats& stats)
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
notifyInProgress(stepStats);
|
notifyInProgress(stepStats);
|
||||||
_recommendationEngine.load(stats.nbChanges() > 0, progressCallback);
|
_recommendationService.load(stats.nbChanges() > 0, progressCallback);
|
||||||
notifyInProgress(stepStats);
|
notifyInProgress(stepStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class UUID;
|
|||||||
|
|
||||||
namespace Recommendation
|
namespace Recommendation
|
||||||
{
|
{
|
||||||
class IEngine;
|
class IRecommendationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Scanner {
|
namespace Scanner {
|
||||||
@@ -49,7 +49,7 @@ namespace Scanner {
|
|||||||
class Scanner : public IScanner
|
class Scanner : public IScanner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scanner(Database::Db& db, Recommendation::IEngine& recommendationEngine);
|
Scanner(Database::Db& db, Recommendation::IRecommendationService& recommendationService);
|
||||||
~Scanner();
|
~Scanner();
|
||||||
|
|
||||||
Scanner(const Scanner&) = delete;
|
Scanner(const Scanner&) = delete;
|
||||||
@@ -92,7 +92,7 @@ class Scanner : public IScanner
|
|||||||
void notifyInProgress(const ScanStepStats& stats);
|
void notifyInProgress(const ScanStepStats& stats);
|
||||||
void reloadSimilarityEngine(ScanStats& stats);
|
void reloadSimilarityEngine(ScanStats& stats);
|
||||||
|
|
||||||
Recommendation::IEngine& _recommendationEngine;
|
Recommendation::IRecommendationService& _recommendationService;
|
||||||
|
|
||||||
std::mutex _controlMutex;
|
std::mutex _controlMutex;
|
||||||
std::atomic<bool> _abortScan {};
|
std::atomic<bool> _abortScan {};
|
||||||
@@ -115,7 +115,7 @@ class Scanner : public IScanner
|
|||||||
Database::ScanSettings::UpdatePeriod _updatePeriod {Database::ScanSettings::UpdatePeriod::Never};
|
Database::ScanSettings::UpdatePeriod _updatePeriod {Database::ScanSettings::UpdatePeriod::Never};
|
||||||
std::unordered_set<std::filesystem::path> _fileExtensions;
|
std::unordered_set<std::filesystem::path> _fileExtensions;
|
||||||
std::filesystem::path _mediaDirectory;
|
std::filesystem::path _mediaDirectory;
|
||||||
Database::ScanSettings::RecommendationEngineType _recommendationEngineType;
|
Database::ScanSettings::RecommendationEngineType _recommendationServiceType;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Scanner
|
} // Scanner
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace Database
|
|||||||
|
|
||||||
namespace Recommendation
|
namespace Recommendation
|
||||||
{
|
{
|
||||||
class IEngine;
|
class IRecommendationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Scanner
|
namespace Scanner
|
||||||
@@ -66,7 +66,7 @@ namespace Scanner
|
|||||||
virtual Events& getEvents() = 0;
|
virtual Events& getEvents() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IScanner> createScanner(Database::Db& db, Recommendation::IEngine& recommendationEngine);
|
std::unique_ptr<IScanner> createScanner(Database::Db& db, Recommendation::IRecommendationService& recommendationEngine);
|
||||||
|
|
||||||
} // Scanner
|
} // Scanner
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
#include <Wt/WLocalDateTime.h>
|
#include <Wt/WLocalDateTime.h>
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "auth/IEnvService.hpp"
|
#include "services/auth/IEnvService.hpp"
|
||||||
#include "database/Artist.hpp"
|
#include "database/Artist.hpp"
|
||||||
#include "database/Cluster.hpp"
|
#include "database/Cluster.hpp"
|
||||||
#include "database/Db.hpp"
|
#include "database/Db.hpp"
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "database/TrackBookmark.hpp"
|
#include "database/TrackBookmark.hpp"
|
||||||
#include "database/TrackList.hpp"
|
#include "database/TrackList.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "services/scrobbling/IScrobblingService.hpp"
|
#include "services/scrobbling/IScrobblingService.hpp"
|
||||||
#include "services/cover/ICoverService.hpp"
|
#include "services/cover/ICoverService.hpp"
|
||||||
#include "utils/IConfig.hpp"
|
#include "utils/IConfig.hpp"
|
||||||
@@ -905,7 +905,7 @@ handleGetArtistInfoRequestCommon(RequestContext& context, bool id3)
|
|||||||
artistInfoNode.createChild("musicBrainzId").setValue(artistMBID->getAsString());
|
artistInfoNode.createChild("musicBrainzId").setValue(artistMBID->getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto similarArtistsId {Service<Recommendation::IEngine>::get()->getSimilarArtists(id, {TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist}, count)};
|
auto similarArtistsId {Service<Recommendation::IRecommendationService>::get()->getSimilarArtists(id, {TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist}, count)};
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction {context.dbSession.createSharedTransaction()};
|
auto transaction {context.dbSession.createSharedTransaction()};
|
||||||
@@ -1141,7 +1141,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3)
|
|||||||
// Optional params
|
// Optional params
|
||||||
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(50)};
|
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(50)};
|
||||||
|
|
||||||
const auto similarArtistIds {Service<Recommendation::IEngine>::get()->getSimilarArtists(artistId, {TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist}, 5)};
|
const auto similarArtistIds {Service<Recommendation::IRecommendationService>::get()->getSimilarArtists(artistId, {TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist}, 5)};
|
||||||
|
|
||||||
auto transaction {context.dbSession.createSharedTransaction()};
|
auto transaction {context.dbSession.createSharedTransaction()};
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -25,15 +25,15 @@
|
|||||||
#include <Wt/WServer.h>
|
#include <Wt/WServer.h>
|
||||||
#include <Wt/WApplication.h>
|
#include <Wt/WApplication.h>
|
||||||
|
|
||||||
#include "auth/IAuthTokenService.hpp"
|
#include "services/auth/IAuthTokenService.hpp"
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "auth/IEnvService.hpp"
|
#include "services/auth/IEnvService.hpp"
|
||||||
#include "services/cover/ICoverService.hpp"
|
#include "services/cover/ICoverService.hpp"
|
||||||
#include "database/Db.hpp"
|
#include "database/Db.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "scanner/IScanner.hpp"
|
#include "scanner/IScanner.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
|
||||||
#include "subsonic/SubsonicResource.hpp"
|
#include "subsonic/SubsonicResource.hpp"
|
||||||
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "services/scrobbling/IScrobblingService.hpp"
|
#include "services/scrobbling/IScrobblingService.hpp"
|
||||||
#include "ui/LmsApplication.hpp"
|
#include "ui/LmsApplication.hpp"
|
||||||
#include "ui/LmsApplicationManager.hpp"
|
#include "ui/LmsApplicationManager.hpp"
|
||||||
@@ -258,8 +258,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
Service<Http::IClient> httpClient {Http::createClient(ioContext)};
|
Service<Http::IClient> httpClient {Http::createClient(ioContext)};
|
||||||
Service<Cover::ICoverService> coverService {Cover::createCoverService(database, argv[0], server.appRoot() + "/images/unknown-cover.jpg")};
|
Service<Cover::ICoverService> coverService {Cover::createCoverService(database, argv[0], server.appRoot() + "/images/unknown-cover.jpg")};
|
||||||
Service<Recommendation::IEngine> recommendationEngineService {Recommendation::createEngine(database)};
|
Service<Recommendation::IRecommendationService> recommendationService {Recommendation::createRecommendationService(database)};
|
||||||
Service<Scanner::IScanner> scannerService {Scanner::createScanner(database, *recommendationEngineService)};
|
Service<Scanner::IScanner> scannerService {Scanner::createScanner(database, *recommendationService)};
|
||||||
|
|
||||||
scannerService->getEvents().scanComplete.connect([&]
|
scannerService->getEvents().scanComplete.connect([&]
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-2
@@ -28,8 +28,8 @@
|
|||||||
#include <Wt/WPushButton.h>
|
#include <Wt/WPushButton.h>
|
||||||
#include <Wt/WRandom.h>
|
#include <Wt/WRandom.h>
|
||||||
|
|
||||||
#include "auth/IAuthTokenService.hpp"
|
#include "services/auth/IAuthTokenService.hpp"
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
#include <Wt/WStackedWidget.h>
|
#include <Wt/WStackedWidget.h>
|
||||||
#include <Wt/WText.h>
|
#include <Wt/WText.h>
|
||||||
|
|
||||||
#include "auth/IEnvService.hpp"
|
#include "services/auth/IEnvService.hpp"
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "services/cover/ICoverService.hpp"
|
#include "services/cover/ICoverService.hpp"
|
||||||
#include "database/Artist.hpp"
|
#include "database/Artist.hpp"
|
||||||
#include "database/Cluster.hpp"
|
#include "database/Cluster.hpp"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
#include "database/TrackList.hpp"
|
#include "database/TrackList.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Random.hpp"
|
#include "utils/Random.hpp"
|
||||||
#include "utils/Service.hpp"
|
#include "utils/Service.hpp"
|
||||||
@@ -520,7 +520,7 @@ PlayQueue::addEntry(const Database::TrackListEntry::pointer& tracklistEntry)
|
|||||||
void
|
void
|
||||||
PlayQueue::enqueueRadioTracks()
|
PlayQueue::enqueueRadioTracks()
|
||||||
{
|
{
|
||||||
const auto similarTrackIds {Service<Recommendation::IEngine>::get()->getSimilarTracksFromTrackList(_tracklistId, 3)};
|
const auto similarTrackIds {Service<Recommendation::IRecommendationService>::get()->getSimilarTracksFromTrackList(_tracklistId, 3)};
|
||||||
|
|
||||||
std::vector<Database::TrackId> trackToAddIds(std::cbegin(similarTrackIds), std::cend(similarTrackIds));
|
std::vector<Database::TrackId> trackToAddIds(std::cbegin(similarTrackIds), std::cend(similarTrackIds));
|
||||||
Random::shuffleContainer(trackToAddIds);
|
Random::shuffleContainer(trackToAddIds);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#include "common/UUIDValidator.hpp"
|
#include "common/UUIDValidator.hpp"
|
||||||
#include "common/ValueStringModel.hpp"
|
#include "common/ValueStringModel.hpp"
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "utils/IConfig.hpp"
|
#include "utils/IConfig.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <Wt/WLineEdit.h>
|
#include <Wt/WLineEdit.h>
|
||||||
#include <Wt/WPushButton.h>
|
#include <Wt/WPushButton.h>
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "utils/Exception.hpp"
|
#include "utils/Exception.hpp"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include <Wt/WFormModel.h>
|
#include <Wt/WFormModel.h>
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "utils/IConfig.hpp"
|
#include "utils/IConfig.hpp"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <Wt/WMessageBox.h>
|
#include <Wt/WMessageBox.h>
|
||||||
#include <Wt/WTemplate.h>
|
#include <Wt/WTemplate.h>
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <Wt/WEnvironment.h>
|
#include <Wt/WEnvironment.h>
|
||||||
|
|
||||||
#include "auth/IPasswordService.hpp"
|
#include "services/auth/IPasswordService.hpp"
|
||||||
#include "utils/Service.hpp"
|
#include "utils/Service.hpp"
|
||||||
#include "LmsApplication.hpp"
|
#include "LmsApplication.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <Wt/WValidator.h>
|
#include <Wt/WValidator.h>
|
||||||
|
|
||||||
#include "database/Types.hpp"
|
#include "database/Types.hpp"
|
||||||
#include "auth/Types.hpp"
|
#include "services/auth/Types.hpp"
|
||||||
|
|
||||||
namespace UserInterface
|
namespace UserInterface
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/String.hpp"
|
#include "utils/String.hpp"
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ Artist::refreshView()
|
|||||||
if (!artistId)
|
if (!artistId)
|
||||||
throw ArtistNotFoundException {};
|
throw ArtistNotFoundException {};
|
||||||
|
|
||||||
const auto similarArtistIds {Service<Recommendation::IEngine>::get()->getSimilarArtists(*artistId, {TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist}, 5)};
|
const auto similarArtistIds {Service<Recommendation::IRecommendationService>::get()->getSimilarArtists(*artistId, {TrackArtistLinkType::Artist, TrackArtistLinkType::ReleaseArtist}, 5)};
|
||||||
|
|
||||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#include "database/ScanSettings.hpp"
|
#include "database/ScanSettings.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/String.hpp"
|
#include "utils/String.hpp"
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ Release::refreshView()
|
|||||||
if (!releaseId)
|
if (!releaseId)
|
||||||
throw ReleaseNotFoundException {};
|
throw ReleaseNotFoundException {};
|
||||||
|
|
||||||
auto similarReleasesIds {Service<Recommendation::IEngine>::get()->getSimilarReleases(*releaseId, 6)};
|
auto similarReleasesIds {Service<Recommendation::IRecommendationService>::get()->getSimilarReleases(*releaseId, 6)};
|
||||||
|
|
||||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||||
|
|
||||||
|
|||||||
@@ -30,14 +30,14 @@
|
|||||||
#include "database/Release.hpp"
|
#include "database/Release.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
|
#include "services/recommendation/IRecommendationService.hpp"
|
||||||
#include "utils/IConfig.hpp"
|
#include "utils/IConfig.hpp"
|
||||||
#include "utils/Service.hpp"
|
#include "utils/Service.hpp"
|
||||||
#include "utils/StreamLogger.hpp"
|
#include "utils/StreamLogger.hpp"
|
||||||
#include "recommendation/IEngine.hpp"
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
dumpTracksRecommendation(Database::Session session, Recommendation::IEngine& engine, unsigned maxSimilarityCount)
|
dumpTracksRecommendation(Database::Session session, Recommendation::IRecommendationService& recommendationService, unsigned maxSimilarityCount)
|
||||||
{
|
{
|
||||||
const std::vector<Database::TrackId> trackIds {[&]()
|
const std::vector<Database::TrackId> trackIds {[&]()
|
||||||
{
|
{
|
||||||
@@ -66,14 +66,14 @@ dumpTracksRecommendation(Database::Session session, Recommendation::IEngine& eng
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::cout << "Processing track '" << trackToString(trackId) << std::endl;
|
std::cout << "Processing track '" << trackToString(trackId) << std::endl;
|
||||||
for (Database::TrackId similarTrackId : engine.getSimilarTracks({trackId}, maxSimilarityCount))
|
for (Database::TrackId similarTrackId : recommendationService.getSimilarTracks({trackId}, maxSimilarityCount))
|
||||||
std::cout << "\t- Similar track '" << trackToString(similarTrackId) << std::endl;
|
std::cout << "\t- Similar track '" << trackToString(similarTrackId) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
dumpReleasesRecommendation(Database::Session session, Recommendation::IEngine& engine, unsigned maxSimilarityCount)
|
dumpReleasesRecommendation(Database::Session session, Recommendation::IRecommendationService& recommendationService, unsigned maxSimilarityCount)
|
||||||
{
|
{
|
||||||
const std::vector<Database::ReleaseId> releaseIds = std::invoke([&]()
|
const std::vector<Database::ReleaseId> releaseIds = std::invoke([&]()
|
||||||
{
|
{
|
||||||
@@ -93,14 +93,14 @@ dumpReleasesRecommendation(Database::Session session, Recommendation::IEngine& e
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::cout << "Processing release '" << releaseToString(releaseId) << "'" << std::endl;
|
std::cout << "Processing release '" << releaseToString(releaseId) << "'" << std::endl;
|
||||||
for (Database::ReleaseId similarReleaseId : engine.getSimilarReleases(releaseId, maxSimilarityCount))
|
for (Database::ReleaseId similarReleaseId : recommendationService.getSimilarReleases(releaseId, maxSimilarityCount))
|
||||||
std::cout << "\t- Similar release '" << releaseToString(similarReleaseId) << "'" << std::endl;
|
std::cout << "\t- Similar release '" << releaseToString(similarReleaseId) << "'" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
dumpArtistsRecommendation(Database::Session session, Recommendation::IEngine& engine, unsigned maxSimilarityCount)
|
dumpArtistsRecommendation(Database::Session session, Recommendation::IRecommendationService& recommendationService, unsigned maxSimilarityCount)
|
||||||
{
|
{
|
||||||
const std::vector<Database::ArtistId> artistIds = std::invoke([&]()
|
const std::vector<Database::ArtistId> artistIds = std::invoke([&]()
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ dumpArtistsRecommendation(Database::Session session, Recommendation::IEngine& en
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::cout << "Processing artist '" << artistToString(artistId) << "'" << std::endl;
|
std::cout << "Processing artist '" << artistToString(artistId) << "'" << std::endl;
|
||||||
for (Database::ArtistId similarArtistId : engine.getSimilarArtists(artistId, {Database::TrackArtistLinkType::Artist, Database::TrackArtistLinkType::ReleaseArtist}, maxSimilarityCount))
|
for (Database::ArtistId similarArtistId : recommendationService.getSimilarArtists(artistId, {Database::TrackArtistLinkType::Artist, Database::TrackArtistLinkType::ReleaseArtist}, maxSimilarityCount))
|
||||||
{
|
{
|
||||||
std::cout << "\t- Similar artist '" << artistToString(similarArtistId) << "'" << std::endl;
|
std::cout << "\t- Similar artist '" << artistToString(similarArtistId) << "'" << std::endl;
|
||||||
}
|
}
|
||||||
@@ -161,25 +161,25 @@ int main(int argc, char *argv[])
|
|||||||
Database::Db db {config->getPath("working-dir") / "lms.db"};
|
Database::Db db {config->getPath("working-dir") / "lms.db"};
|
||||||
Database::Session session {db};
|
Database::Session session {db};
|
||||||
|
|
||||||
std::cout << "Creating recommendation engine..." << std::endl;
|
std::cout << "Creating recommendation recommendationService..." << std::endl;
|
||||||
const auto engine {Recommendation::createEngine(db)};
|
const auto recommendationService {Recommendation::createRecommendationService(db)};
|
||||||
std::cout << "Recommendation engine created!" << std::endl;
|
std::cout << "Recommendation recommendationService created!" << std::endl;
|
||||||
|
|
||||||
std::cout << "Loading recommendation engine..." << std::endl;
|
std::cout << "Loading recommendation recommendationService..." << std::endl;
|
||||||
engine->load(false);
|
recommendationService->load(false);
|
||||||
|
|
||||||
unsigned maxSimilarityCount {vm["max"].as<unsigned>()};
|
unsigned maxSimilarityCount {vm["max"].as<unsigned>()};
|
||||||
|
|
||||||
std::cout << "Recommendation engine loaded!" << std::endl;
|
std::cout << "Recommendation recommendationService loaded!" << std::endl;
|
||||||
|
|
||||||
if (vm.count("tracks"))
|
if (vm.count("tracks"))
|
||||||
dumpTracksRecommendation(db, *engine, maxSimilarityCount);
|
dumpTracksRecommendation(db, *recommendationService, maxSimilarityCount);
|
||||||
|
|
||||||
if (vm.count("releases"))
|
if (vm.count("releases"))
|
||||||
dumpReleasesRecommendation(db, *engine, maxSimilarityCount);
|
dumpReleasesRecommendation(db, *recommendationService, maxSimilarityCount);
|
||||||
|
|
||||||
if (vm.count("artists"))
|
if (vm.count("artists"))
|
||||||
dumpArtistsRecommendation(db, *engine, maxSimilarityCount);
|
dumpArtistsRecommendation(db, *recommendationService, maxSimilarityCount);
|
||||||
}
|
}
|
||||||
catch( std::exception& e)
|
catch( std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user