diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..7eef4529 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.10) + +project(lms) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +find_package(PkgConfig) +pkg_check_modules(IMAGEMAGICKXX REQUIRED ImageMagick++) + + +SUBDIRS(src) + +install(DIRECTORY approot DESTINATION share/lms) +install(DIRECTORY docroot DESTINATION share/lms) +install(FILES systemd/default.service DESTINATION share/lms) +install(FILES conf/lms.conf DESTINATION share/lms) + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..8853a8c7 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,4 @@ +add_compile_options(-Wall -Wextra -pedantic -Werror) + +SUBDIRS(liblms lms) + diff --git a/src/Makefile.am b/src/Makefile.am index 4fd65f58..b5644219 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,171 +1,6 @@ bin_PROGRAMS = lms lms_SOURCES = \ - $(srcdir)/api/subsonic/SubsonicId.cpp \ - $(srcdir)/api/subsonic/SubsonicId.hpp \ - $(srcdir)/api/subsonic/SubsonicResource.cpp \ - $(srcdir)/api/subsonic/SubsonicResource.hpp \ - $(srcdir)/api/subsonic/SubsonicResponse.cpp \ - $(srcdir)/api/subsonic/SubsonicResponse.hpp \ - $(srcdir)/auth/AuthTokenService.cpp \ - $(srcdir)/auth/AuthTokenService.hpp \ - $(srcdir)/auth/PasswordService.cpp \ - $(srcdir)/auth/PasswordService.hpp \ - $(srcdir)/auth/LoginThrottler.cpp \ - $(srcdir)/auth/LoginThrottler.hpp \ - $(srcdir)/av/AvInfo.cpp \ - $(srcdir)/av/AvInfo.hpp \ - $(srcdir)/av/AvTranscoder.cpp \ - $(srcdir)/av/AvTranscoder.hpp \ - $(srcdir)/av/AvTypes.cpp \ - $(srcdir)/av/AvTypes.hpp \ - $(srcdir)/cover/CoverArtGrabber.cpp \ - $(srcdir)/cover/CoverArtGrabber.hpp \ - $(srcdir)/database/Artist.cpp \ - $(srcdir)/database/Artist.hpp \ - $(srcdir)/database/Cluster.cpp \ - $(srcdir)/database/Cluster.hpp \ - $(srcdir)/database/Db.cpp \ - $(srcdir)/database/Db.hpp \ - $(srcdir)/database/TrackArtistLink.cpp \ - $(srcdir)/database/TrackArtistLink.hpp \ - $(srcdir)/database/TrackFeatures.cpp \ - $(srcdir)/database/TrackFeatures.hpp \ - $(srcdir)/database/TrackList.cpp \ - $(srcdir)/database/TrackList.hpp \ - $(srcdir)/database/Types.hpp \ - $(srcdir)/database/Release.cpp \ - $(srcdir)/database/Release.hpp \ - $(srcdir)/database/ScanSettings.cpp \ - $(srcdir)/database/ScanSettings.hpp \ - $(srcdir)/database/Session.cpp \ - $(srcdir)/database/Session.hpp \ - $(srcdir)/database/SessionPool.cpp \ - $(srcdir)/database/SessionPool.hpp \ - $(srcdir)/database/SqlQuery.cpp \ - $(srcdir)/database/SqlQuery.hpp \ - $(srcdir)/database/Track.cpp \ - $(srcdir)/database/Track.hpp \ - $(srcdir)/database/TrackBookmark.cpp \ - $(srcdir)/database/TrackBookmark.hpp \ - $(srcdir)/database/User.cpp \ - $(srcdir)/database/User.hpp \ - $(srcdir)/image/Image.cpp \ - $(srcdir)/image/Image.hpp \ - $(srcdir)/main/main.cpp \ - $(srcdir)/metadata/AvFormat.cpp \ - $(srcdir)/metadata/AvFormat.hpp \ - $(srcdir)/metadata/MetaData.hpp \ - $(srcdir)/metadata/TagLibParser.cpp \ - $(srcdir)/metadata/TagLibParser.hpp \ - $(srcdir)/scanner/MediaScanner.cpp \ - $(srcdir)/scanner/MediaScanner.hpp \ - $(srcdir)/scanner/MediaScannerStats.cpp \ - $(srcdir)/scanner/MediaScannerStats.hpp \ - $(srcdir)/scanner/MediaScannerAddon.hpp \ - $(srcdir)/similarity/SimilaritySearcher.cpp \ - $(srcdir)/similarity/SimilaritySearcher.hpp \ - $(srcdir)/similarity/cluster/SimilarityClusterSearcher.cpp \ - $(srcdir)/similarity/cluster/SimilarityClusterSearcher.hpp \ - $(srcdir)/similarity/features/AcousticBrainzUtils.cpp \ - $(srcdir)/similarity/features/AcousticBrainzUtils.hpp \ - $(srcdir)/similarity/features/SimilarityFeaturesCache.cpp \ - $(srcdir)/similarity/features/SimilarityFeaturesCache.hpp \ - $(srcdir)/similarity/features/SimilarityFeaturesDefs.cpp \ - $(srcdir)/similarity/features/SimilarityFeaturesDefs.hpp \ - $(srcdir)/similarity/features/SimilarityFeaturesScannerAddon.cpp \ - $(srcdir)/similarity/features/SimilarityFeaturesScannerAddon.hpp \ - $(srcdir)/similarity/features/SimilarityFeaturesSearcher.cpp \ - $(srcdir)/similarity/features/SimilarityFeaturesSearcher.hpp \ - $(srcdir)/similarity/features/som/DataNormalizer.cpp \ - $(srcdir)/similarity/features/som/DataNormalizer.hpp \ - $(srcdir)/similarity/features/som/InputVector.hpp \ - $(srcdir)/similarity/features/som/Matrix.hpp \ - $(srcdir)/similarity/features/som/Network.cpp \ - $(srcdir)/similarity/features/som/Network.hpp \ - $(srcdir)/ui/Auth.cpp \ - $(srcdir)/ui/Auth.hpp \ - $(srcdir)/ui/LmsApplication.cpp \ - $(srcdir)/ui/LmsApplication.hpp \ - $(srcdir)/ui/LmsApplicationException.hpp \ - $(srcdir)/ui/LmsApplicationGroup.cpp \ - $(srcdir)/ui/LmsApplicationGroup.hpp \ - $(srcdir)/ui/MediaPlayer.cpp \ - $(srcdir)/ui/MediaPlayer.hpp \ - $(srcdir)/ui/PlayQueueView.cpp \ - $(srcdir)/ui/PlayQueueView.hpp \ - $(srcdir)/ui/PlayHistoryView.cpp \ - $(srcdir)/ui/PlayHistoryView.hpp \ - $(srcdir)/ui/SettingsView.cpp \ - $(srcdir)/ui/SettingsView.hpp \ - $(srcdir)/ui/TrackStringUtils.cpp \ - $(srcdir)/ui/TrackStringUtils.hpp \ - $(srcdir)/ui/admin/DatabaseSettingsView.cpp \ - $(srcdir)/ui/admin/DatabaseSettingsView.hpp \ - $(srcdir)/ui/admin/DatabaseStatus.cpp \ - $(srcdir)/ui/admin/DatabaseStatus.hpp \ - $(srcdir)/ui/admin/InitWizardView.cpp \ - $(srcdir)/ui/admin/InitWizardView.hpp \ - $(srcdir)/ui/admin/UserView.cpp \ - $(srcdir)/ui/admin/UserView.hpp \ - $(srcdir)/ui/admin/UsersView.cpp \ - $(srcdir)/ui/admin/UsersView.hpp \ - $(srcdir)/ui/common/Validators.cpp \ - $(srcdir)/ui/common/Validators.hpp \ - $(srcdir)/ui/common/ValueStringModel.hpp \ - $(srcdir)/ui/explore/ArtistInfoView.cpp \ - $(srcdir)/ui/explore/ArtistInfoView.hpp \ - $(srcdir)/ui/explore/ArtistLink.cpp \ - $(srcdir)/ui/explore/ArtistLink.hpp \ - $(srcdir)/ui/explore/ArtistsInfoView.cpp \ - $(srcdir)/ui/explore/ArtistsInfoView.hpp \ - $(srcdir)/ui/explore/ArtistView.cpp \ - $(srcdir)/ui/explore/ArtistView.hpp \ - $(srcdir)/ui/explore/ArtistsView.cpp \ - $(srcdir)/ui/explore/ArtistsView.hpp \ - $(srcdir)/ui/explore/Explore.cpp \ - $(srcdir)/ui/explore/Explore.hpp \ - $(srcdir)/ui/explore/Filters.cpp \ - $(srcdir)/ui/explore/Filters.hpp \ - $(srcdir)/ui/explore/ReleaseInfoView.cpp \ - $(srcdir)/ui/explore/ReleaseInfoView.hpp \ - $(srcdir)/ui/explore/ReleaseLink.cpp \ - $(srcdir)/ui/explore/ReleaseLink.hpp \ - $(srcdir)/ui/explore/ReleasesInfoView.cpp \ - $(srcdir)/ui/explore/ReleasesInfoView.hpp \ - $(srcdir)/ui/explore/ReleasesView.cpp \ - $(srcdir)/ui/explore/ReleasesView.hpp \ - $(srcdir)/ui/explore/ReleaseView.cpp \ - $(srcdir)/ui/explore/ReleaseView.hpp \ - $(srcdir)/ui/explore/TracksInfoView.cpp \ - $(srcdir)/ui/explore/TracksInfoView.hpp \ - $(srcdir)/ui/explore/TracksView.cpp \ - $(srcdir)/ui/explore/TracksView.hpp \ - $(srcdir)/ui/resource/ImageResource.cpp \ - $(srcdir)/ui/resource/ImageResource.hpp \ - $(srcdir)/ui/resource/AudioResource.cpp \ - $(srcdir)/ui/resource/AudioResource.hpp \ - $(srcdir)/utils/Config.cpp \ - $(srcdir)/utils/Config.hpp \ - $(srcdir)/utils/Exception.hpp \ - $(srcdir)/utils/Logger.cpp \ - $(srcdir)/utils/Logger.hpp \ - $(srcdir)/utils/NetAddress.cpp \ - $(srcdir)/utils/NetAddress.hpp \ - $(srcdir)/utils/Path.cpp \ - $(srcdir)/utils/Path.hpp \ - $(srcdir)/utils/Random.cpp \ - $(srcdir)/utils/Random.hpp \ - $(srcdir)/utils/Service.hpp \ - $(srcdir)/utils/StreamLogger.cpp \ - $(srcdir)/utils/StreamLogger.hpp \ - $(srcdir)/utils/String.cpp \ - $(srcdir)/utils/String.hpp \ - $(srcdir)/utils/Utils.hpp \ - $(srcdir)/utils/UUID.cpp \ - $(srcdir)/utils/UUID.hpp \ - $(srcdir)/utils/WtLogger.cpp \ - $(srcdir)/utils/WtLogger.hpp lms_CXXFLAGS=-std=c++17 -I$(srcdir)/ui $(MAGICKXX_CFLAGS) -D_REENTRANT lms_LDADD=$(MAGICKXX_LIBS) diff --git a/src/config/.empty b/src/config/.empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cover/CoverArtGrabber.hpp b/src/cover/CoverArtGrabber.hpp deleted file mode 100644 index 07b4cc32..00000000 --- a/src/cover/CoverArtGrabber.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2015 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 . - */ - -#pragma once - -#include -#include -#include -#include -#include - -#include "database/Types.hpp" - -#include "image/Image.hpp" - -namespace Database { - class Session; -} - -namespace CoverArt { - -class Grabber -{ - public: - Grabber(); - Grabber(const Grabber&) = delete; - Grabber& operator=(const Grabber&) = delete; - Grabber(Grabber&&) = delete; - Grabber& operator=(Grabber&&) = delete; - - void setDefaultCover(const std::filesystem::path& defaultCoverPath); - - std::vector getFromTrack(Database::Session& dbSession, Database::IdType trackId, Image::Format format, std::size_t size); - std::vector getFromRelease(Database::Session& dbSession, Database::IdType releaseId, Image::Format format, std::size_t size); - - private: - - Image::Image getFromTrack(Database::Session& dbSession, Database::IdType trackId, std::size_t size); - Image::Image getFromRelease(Database::Session& dbSession, Database::IdType releaseId, std::size_t size); - - std::optional getFromTrack(const std::filesystem::path& path) const; - std::vector getCoverPaths(const std::filesystem::path& directoryPath) const; - std::optional getFromDirectory(const std::filesystem::path& path) const; - - Image::Image getDefaultCover(std::size_t size); - - Image::Image _defaultCover; - - std::mutex _mutex; - std::map _defaultCovers; - - static inline const std::vector _fileExtensions {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize - - static inline const std::size_t _maxFileSize {10000000}; - - static inline const std::vector _preferredFileNames {"cover", "front"}; // TODO parametrize -}; - -} // namespace CoverArt - diff --git a/src/liblms/CMakeLists.txt b/src/liblms/CMakeLists.txt new file mode 100644 index 00000000..37ba7cfd --- /dev/null +++ b/src/liblms/CMakeLists.txt @@ -0,0 +1,73 @@ + +add_library(liblms SHARED + impl/api/subsonic/SubsonicId.cpp + impl/api/subsonic/SubsonicResource.cpp + impl/api/subsonic/SubsonicResponse.cpp + impl/auth/AuthTokenService.cpp + impl/auth/PasswordService.cpp + impl/auth/LoginThrottler.cpp + impl/av/AvInfo.cpp + impl/av/AvTranscoder.cpp + impl/av/AvTypes.cpp + impl/cover/CoverArtGrabber.cpp + impl/database/Artist.cpp + impl/database/Cluster.cpp + impl/database/Db.cpp + impl/database/TrackArtistLink.cpp + impl/database/TrackFeatures.cpp + impl/database/TrackList.cpp + impl/database/Release.cpp + impl/database/ScanSettings.cpp + impl/database/Session.cpp + impl/database/SessionPool.cpp + impl/database/SqlQuery.cpp + impl/database/Track.cpp + impl/database/TrackBookmark.cpp + impl/database/User.cpp + impl/metadata/AvFormat.cpp + impl/metadata/TagLibParser.cpp + impl/scanner/MediaScanner.cpp + impl/scanner/MediaScannerStats.cpp + impl/recommendation/Engine.cpp + impl/recommendation/ProviderCreator.cpp + impl/recommendation/features/som/DataNormalizer.cpp + impl/recommendation/features/som/Network.cpp + impl/utils/Config.cpp + impl/utils/Logger.cpp + impl/utils/NetAddress.cpp + impl/utils/Path.cpp + impl/utils/Random.cpp + impl/utils/StreamLogger.cpp + impl/utils/String.cpp + impl/utils/UUID.cpp + impl/utils/WtLogger.cpp + ) + +include_directories(liblms include/) + +target_include_directories(liblms INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# TODO make this private +target_include_directories(liblms PUBLIC ${IMAGEMAGICKXX_INCLUDE_DIRS}) +target_link_libraries(liblms PUBLIC ${IMAGEMAGICKXX_LIBRARIES}) +target_compile_options(liblms PUBLIC ${IMAGEMAGICKXX_CFLAGS_OTHER}) + +target_link_libraries(liblms PRIVATE + avformat + avutil + config++ + tag + stdc++fs + wtdbosqlite3 + ) + +target_link_libraries(liblms PUBLIC + pthread + boost_system + wtdbo + ) + +install(TARGETS liblms DESTINATION lib) + diff --git a/src/api/subsonic/SubsonicId.cpp b/src/liblms/impl/api/subsonic/SubsonicId.cpp similarity index 100% rename from src/api/subsonic/SubsonicId.cpp rename to src/liblms/impl/api/subsonic/SubsonicId.cpp diff --git a/src/api/subsonic/SubsonicId.hpp b/src/liblms/impl/api/subsonic/SubsonicId.hpp similarity index 100% rename from src/api/subsonic/SubsonicId.hpp rename to src/liblms/impl/api/subsonic/SubsonicId.hpp diff --git a/src/api/subsonic/SubsonicResource.cpp b/src/liblms/impl/api/subsonic/SubsonicResource.cpp similarity index 97% rename from src/api/subsonic/SubsonicResource.cpp rename to src/liblms/impl/api/subsonic/SubsonicResource.cpp index a52f5d22..c2e72223 100644 --- a/src/api/subsonic/SubsonicResource.cpp +++ b/src/liblms/impl/api/subsonic/SubsonicResource.cpp @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with LMS. If not, see . */ -#include "SubsonicResource.hpp" +#include "api/subsonic/SubsonicResource.hpp" #include #include @@ -26,9 +26,9 @@ #include -#include "auth/PasswordService.hpp" +#include "auth/IPasswordService.hpp" #include "av/AvTranscoder.hpp" -#include "cover/CoverArtGrabber.hpp" +#include "cover/ICoverArtGrabber.hpp" #include "database/Artist.hpp" #include "database/Cluster.hpp" #include "database/Db.hpp" @@ -38,7 +38,7 @@ #include "database/TrackBookmark.hpp" #include "database/TrackList.hpp" #include "database/User.hpp" -#include "similarity/SimilaritySearcher.hpp" +#include "recommendation/IEngine.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" #include "utils/String.hpp" @@ -578,10 +578,10 @@ handleChangePassword(RequestContext& context) std::string username {getMandatoryParameterAs(context.parameters, "username")}; std::string password {decodePasswordIfNeeded(getMandatoryParameterAs(context.parameters, "password"))}; - if (!ServiceProvider::get()->evaluatePasswordStrength(username, password)) + if (!ServiceProvider::get()->evaluatePasswordStrength(username, password)) throw PasswordTooWeakGenericError {}; - const User::PasswordHash hash {ServiceProvider::get()->hashPassword(password)}; + const User::PasswordHash hash {ServiceProvider::get()->hashPassword(password)}; auto transaction {context.dbSession.createUniqueTransaction()}; @@ -660,10 +660,10 @@ handleCreateUserRequest(RequestContext& context) std::string password {decodePasswordIfNeeded(getMandatoryParameterAs(context.parameters, "password"))}; // Just ignore all the other fields as we don't handle them - if (!ServiceProvider::get()->evaluatePasswordStrength(username, password)) + if (!ServiceProvider::get()->evaluatePasswordStrength(username, password)) throw PasswordTooWeakGenericError {}; - const User::PasswordHash hash {ServiceProvider::get()->hashPassword(password)}; + const User::PasswordHash hash {ServiceProvider::get()->hashPassword(password)}; auto transaction {context.dbSession.createUniqueTransaction()}; @@ -944,7 +944,7 @@ handleGetArtistInfoRequestCommon(RequestContext& context, bool id3) artistInfoNode.createChild("musicBrainzId").setValue(artistMBID->getAsString()); } - auto similarArtistsId {ServiceProvider::get()->getSimilarArtists(context.dbSession, id.value, count)}; + auto similarArtistsId {ServiceProvider::get()->getSimilarArtists(context.dbSession, id.value, count)}; { auto transaction {context.dbSession.createSharedTransaction()}; @@ -1140,7 +1140,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3) // Optional params std::size_t count {getParameterAs(context.parameters, "count").value_or(50)}; - auto similarArtistsId {ServiceProvider::get()->getSimilarArtists(context.dbSession, id.value, 5)}; + auto similarArtistsId {ServiceProvider::get()->getSimilarArtists(context.dbSession, id.value, 5)}; auto transaction {context.dbSession.createSharedTransaction()}; @@ -1588,10 +1588,10 @@ handleUpdateUserRequest(RequestContext& context) if (password) { *password = decodePasswordIfNeeded(*password); - if (!ServiceProvider::get()->evaluatePasswordStrength(username, *password)) + if (!ServiceProvider::get()->evaluatePasswordStrength(username, *password)) throw PasswordTooWeakGenericError {}; - hash = ServiceProvider::get()->hashPassword(*password); + hash = ServiceProvider::get()->hashPassword(*password); } auto transaction {context.dbSession.createUniqueTransaction()}; @@ -1895,16 +1895,16 @@ handleGetCoverArt(RequestContext& context, Wt::Http::ResponseContinuation*) switch (id.type) { case Id::Type::Track: - res.data = ServiceProvider::get()->getFromTrack(context.dbSession, id.value, Image::Format::JPEG, size); + res.data = ServiceProvider::get()->getFromTrack(context.dbSession, id.value, CoverArt::Format::JPEG, {size, size}); break; case Id::Type::Release: - res.data = ServiceProvider::get()->getFromRelease(context.dbSession, id.value, Image::Format::JPEG, size); + res.data = ServiceProvider::get()->getFromRelease(context.dbSession, id.value, CoverArt::Format::JPEG, {size, size}); break; default: throw BadParameterGenericError {"id"}; } - res.mimeType = Image::format_to_mimeType(Image::Format::JPEG); + res.mimeType = CoverArt::formatToMimeType(CoverArt::Format::JPEG); return res; } @@ -2056,19 +2056,19 @@ SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Resp SessionPool::ScopedSession dbSession {_sessionPool}; - switch (ServiceProvider::get()->checkUserPassword(dbSession.get(), + switch (ServiceProvider::get()->checkUserPassword(dbSession.get(), boost::asio::ip::address::from_string(request.clientAddress()), clientInfo.user, clientInfo.password)) { - case Auth::PasswordService::PasswordCheckResult::Match: + case Auth::IPasswordService::PasswordCheckResult::Match: break; - case Auth::PasswordService::PasswordCheckResult::Mismatch: + case Auth::IPasswordService::PasswordCheckResult::Mismatch: throw WrongUsernameOrPasswordError {}; - case Auth::PasswordService::PasswordCheckResult::Throttled: + case Auth::IPasswordService::PasswordCheckResult::Throttled: throw LoginThrottledGenericError {}; } - RequestContext requestContext {.parameters = parameters, .dbSession = dbSession.get(), .userName = clientInfo.user}; + RequestContext requestContext {parameters, dbSession.get(), clientInfo.user}; auto itEntryPoint {requestEntryPoints.find(requestPath)}; if (itEntryPoint != requestEntryPoints.end()) diff --git a/src/api/subsonic/SubsonicResponse.cpp b/src/liblms/impl/api/subsonic/SubsonicResponse.cpp similarity index 100% rename from src/api/subsonic/SubsonicResponse.cpp rename to src/liblms/impl/api/subsonic/SubsonicResponse.cpp diff --git a/src/api/subsonic/SubsonicResponse.hpp b/src/liblms/impl/api/subsonic/SubsonicResponse.hpp similarity index 100% rename from src/api/subsonic/SubsonicResponse.hpp rename to src/liblms/impl/api/subsonic/SubsonicResponse.hpp diff --git a/src/auth/AuthTokenService.cpp b/src/liblms/impl/auth/AuthTokenService.cpp similarity index 95% rename from src/auth/AuthTokenService.cpp rename to src/liblms/impl/auth/AuthTokenService.cpp index 14cb933c..ba37b35c 100644 --- a/src/auth/AuthTokenService.cpp +++ b/src/liblms/impl/auth/AuthTokenService.cpp @@ -26,11 +26,17 @@ #include #include "database/Session.hpp" +#include "database/User.hpp" #include "utils/Exception.hpp" #include "utils/Logger.hpp" namespace Auth { +std::unique_ptr createAuthTokenService(std::size_t maxThrottlerEntries) +{ + return std::make_unique(maxThrottlerEntries); +} + static const Wt::Auth::SHA1HashFunction sha1Function; AuthTokenService::AuthTokenService(std::size_t maxThrottlerEntries) diff --git a/src/auth/AuthTokenService.hpp b/src/liblms/impl/auth/AuthTokenService.hpp similarity index 72% rename from src/auth/AuthTokenService.hpp rename to src/liblms/impl/auth/AuthTokenService.hpp index b44ae3e7..36a9721a 100644 --- a/src/auth/AuthTokenService.hpp +++ b/src/liblms/impl/auth/AuthTokenService.hpp @@ -21,14 +21,9 @@ #pragma once -#include -#include - -#include +#include "auth/IAuthTokenService.hpp" #include "LoginThrottler.hpp" -#include "database/User.hpp" -#include "database/Types.hpp" namespace Database { @@ -38,7 +33,7 @@ namespace Database namespace Auth { - class AuthTokenService + class AuthTokenService : public IAuthTokenService { public: @@ -52,30 +47,8 @@ namespace Auth { AuthTokenService(AuthTokenService&&) = delete; AuthTokenService& operator=(AuthTokenService&&) = delete; - - // Auth Token services - struct AuthTokenProcessResult - { - enum class State - { - Found, - Throttled, - NotFound, - }; - - struct AuthTokenInfo - { - Database::IdType userId; - Wt::WDateTime expiry; - }; - - State state {State::NotFound}; - std::optional authTokenInfo {}; - }; - - // Removed if found - AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& tokenValue); - std::string createAuthToken(Database::Session& session, Database::IdType userid, const Wt::WDateTime& expiry); + AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& tokenValue) override; + std::string createAuthToken(Database::Session& session, Database::IdType userid, const Wt::WDateTime& expiry) override; private: diff --git a/src/auth/LoginThrottler.cpp b/src/liblms/impl/auth/LoginThrottler.cpp similarity index 100% rename from src/auth/LoginThrottler.cpp rename to src/liblms/impl/auth/LoginThrottler.cpp diff --git a/src/auth/LoginThrottler.hpp b/src/liblms/impl/auth/LoginThrottler.hpp similarity index 100% rename from src/auth/LoginThrottler.hpp rename to src/liblms/impl/auth/LoginThrottler.hpp diff --git a/src/auth/PasswordService.cpp b/src/liblms/impl/auth/PasswordService.cpp similarity index 95% rename from src/auth/PasswordService.cpp rename to src/liblms/impl/auth/PasswordService.cpp index 1c592f45..9c17de2b 100644 --- a/src/auth/PasswordService.cpp +++ b/src/liblms/impl/auth/PasswordService.cpp @@ -31,6 +31,11 @@ namespace Auth { +std::unique_ptr createPasswordService(std::size_t maxThrottlerEntries) +{ + return std::make_unique(maxThrottlerEntries); +} + PasswordService::PasswordService(std::size_t maxThrottlerEntries) : _loginThrottler{maxThrottlerEntries} { diff --git a/src/auth/PasswordService.hpp b/src/liblms/impl/auth/PasswordService.hpp similarity index 60% rename from src/auth/PasswordService.hpp rename to src/liblms/impl/auth/PasswordService.hpp index 303615be..99377e8b 100644 --- a/src/auth/PasswordService.hpp +++ b/src/liblms/impl/auth/PasswordService.hpp @@ -17,17 +17,12 @@ * along with LMS. If not, see . */ -/* This file contains some classes in order to get info from file using the libavconv */ - #pragma once -#include - -#include +#include +#include "auth/IPasswordService.hpp" #include "LoginThrottler.hpp" -#include "database/User.hpp" -#include "database/Types.hpp" namespace Database { @@ -37,7 +32,7 @@ namespace Database namespace Auth { - class PasswordService + class PasswordService : public IPasswordService { public: @@ -53,39 +48,9 @@ namespace Auth { // Password services - enum class PasswordCheckResult - { - Match, - Mismatch, - Throttled, - }; - PasswordCheckResult checkUserPassword(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& loginName, const std::string& password); - Database::User::PasswordHash hashPassword(const std::string& password) const; - bool evaluatePasswordStrength(const std::string& loginName, const std::string& password) const; - - // Auth Token services - struct AuthTokenProcessResult - { - enum class State - { - Found, - Throttled, - NotFound, - }; - - struct AuthTokenInfo - { - Database::IdType userId; - Wt::WDateTime expiry; - }; - - State state; - std::optional authTokenInfo; - }; - - // Removed if found - AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& tokenValue); - std::string createAuthToken(Database::Session& session, Database::IdType userid, const Wt::WDateTime& expiry); + PasswordCheckResult checkUserPassword(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& loginName, const std::string& password) override; + Database::User::PasswordHash hashPassword(const std::string& password) const override; + bool evaluatePasswordStrength(const std::string& loginName, const std::string& password) const override; private: diff --git a/src/av/AvInfo.cpp b/src/liblms/impl/av/AvInfo.cpp similarity index 96% rename from src/av/AvInfo.cpp rename to src/liblms/impl/av/AvInfo.cpp index 2f7d9ee8..e9b1bd8c 100644 --- a/src/av/AvInfo.cpp +++ b/src/liblms/impl/av/AvInfo.cpp @@ -17,9 +17,7 @@ * along with LMS. If not, see . */ -#include "AvInfo.hpp" - -#include +#include "av/AvInfo.hpp" #include @@ -92,7 +90,7 @@ getMetaDataFromDictionnary(AVDictionary* dictionnary, std::map(tag->key)] = tag->value; + res[StringUtils::stringToUpper(tag->key)] = tag->value; } } @@ -141,7 +139,7 @@ MediaFile::getStreamInfo() const if (avstream->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) continue; - res.push_back( {.id = i, .bitrate = static_cast(avstream->codecpar->bit_rate)} ); + res.push_back( {i, static_cast(avstream->codecpar->bit_rate)} ); } return res; diff --git a/src/av/AvTranscoder.cpp b/src/liblms/impl/av/AvTranscoder.cpp similarity index 97% rename from src/av/AvTranscoder.cpp rename to src/liblms/impl/av/AvTranscoder.cpp index 1dac0797..f98b3771 100644 --- a/src/av/AvTranscoder.cpp +++ b/src/liblms/impl/av/AvTranscoder.cpp @@ -17,13 +17,13 @@ * along with LMS. If not, see . */ -#include "AvTranscoder.hpp" +#include "av/AvTranscoder.hpp" #include #include -#include "AvInfo.hpp" -#include "utils/Config.hpp" +#include "av/AvInfo.hpp" +#include "utils/IConfig.hpp" #include "utils/Path.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -38,7 +38,7 @@ static std::filesystem::path ffmpegPath; void Transcoder::init() { - ffmpegPath = ServiceProvider::get()->getPath("ffmpeg-file", "/usr/bin/ffmpeg"); + ffmpegPath = ServiceProvider::get()->getPath("ffmpeg-file", "/usr/bin/ffmpeg"); if (!std::filesystem::exists(ffmpegPath)) throw LmsException {"File '" + ffmpegPath.string() + "' does not exist!"}; } diff --git a/src/av/AvTypes.cpp b/src/liblms/impl/av/AvTypes.cpp similarity index 93% rename from src/av/AvTypes.cpp rename to src/liblms/impl/av/AvTypes.cpp index 9ad5bd5d..7e556294 100644 --- a/src/av/AvTypes.cpp +++ b/src/liblms/impl/av/AvTypes.cpp @@ -17,9 +17,7 @@ * along with LMS. If not, see . */ -#include "AvTypes.hpp" - -#include +#include "av/AvTypes.hpp" namespace Av { @@ -34,7 +32,7 @@ const char* encodingToMimetype(Encoding encoding) case Encoding::WEBM_VORBIS: return "audio/webm"; } - throw AvException("Invalid encoding"); + throw AvException {"Invalid encoding"}; } } diff --git a/src/cover/CoverArtGrabber.cpp b/src/liblms/impl/cover/CoverArtGrabber.cpp similarity index 98% rename from src/cover/CoverArtGrabber.cpp rename to src/liblms/impl/cover/CoverArtGrabber.cpp index 8809a6c1..110e9ddd 100644 --- a/src/cover/CoverArtGrabber.cpp +++ b/src/liblms/impl/cover/CoverArtGrabber.cpp @@ -236,7 +236,7 @@ Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId, } std::vector -Grabber::getFromTrack(Database::Session& session, Database::IdType trackId, Image::Format format, std::size_t size) +Grabber::getFromTrack(Database::Session& session, Database::IdType trackId, Format format, std::size_t size) { const Image::Image cover {getFromTrack(session, trackId, size)}; @@ -245,7 +245,7 @@ Grabber::getFromTrack(Database::Session& session, Database::IdType trackId, Imag } std::vector -Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId, Image::Format format, std::size_t size) +Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId, Format format, std::size_t size) { const Image::Image cover {getFromRelease(session, releaseId, size)}; diff --git a/src/liblms/impl/cover/CoverArtGrabber.hpp b/src/liblms/impl/cover/CoverArtGrabber.hpp new file mode 100644 index 00000000..3911ad43 --- /dev/null +++ b/src/liblms/impl/cover/CoverArtGrabber.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 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 . + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include "cover/ICoverArtGrabber.hpp" +#include "database/Types.hpp" +#include "Image.hpp" + +namespace Database +{ + class Session; +} + +namespace CoverArt +{ + + class Grabber : public IGrabber + { + public: + Grabber(); + Grabber(const Grabber&) = delete; + Grabber& operator=(const Grabber&) = delete; + Grabber(Grabber&&) = delete; + Grabber& operator=(Grabber&&) = delete; + + void setDefaultCover(const std::filesystem::path& defaultCoverPath) override; + + std::vector getFromTrack(Database::Session& dbSession, Database::IdType trackId, Format format, std::size_t width) override; + std::vector getFromRelease(Database::Session& dbSession, Database::IdType releaseId, Format format, std::size_t width) override; + + private: + + Image::Image getFromTrack(Database::Session& dbSession, Database::IdType trackId, std::size_t size); + Image::Image getFromRelease(Database::Session& dbSession, Database::IdType releaseId, std::size_t size); + + std::optional getFromTrack(const std::filesystem::path& path) const; + std::vector getCoverPaths(const std::filesystem::path& directoryPath) const; + std::optional getFromDirectory(const std::filesystem::path& path) const; + + Image::Image getDefaultCover(std::size_t size); + + Image::Image _defaultCover; + + std::mutex _mutex; + std::map _defaultCovers; + + static inline const std::vector _fileExtensions {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize + + static inline const std::size_t _maxFileSize {10000000}; + + static inline const std::vector _preferredFileNames {"cover", "front"}; // TODO parametrize + }; + +} // namespace CoverArt + diff --git a/src/image/Image.cpp b/src/liblms/impl/cover/Image.cpp similarity index 99% rename from src/image/Image.cpp rename to src/liblms/impl/cover/Image.cpp index 2d50bebb..06532eca 100644 --- a/src/image/Image.cpp +++ b/src/liblms/impl/cover/Image.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "Image.hpp" +#include "image/Image.hpp" #include "utils/Logger.hpp" diff --git a/src/image/Image.hpp b/src/liblms/impl/cover/Image.hpp similarity index 100% rename from src/image/Image.hpp rename to src/liblms/impl/cover/Image.hpp diff --git a/src/database/Artist.cpp b/src/liblms/impl/database/Artist.cpp similarity index 98% rename from src/database/Artist.cpp rename to src/liblms/impl/database/Artist.cpp index 88ee6cb1..5d17df1a 100644 --- a/src/database/Artist.cpp +++ b/src/liblms/impl/database/Artist.cpp @@ -16,18 +16,18 @@ * You should have received a copy of the GNU General Public License * along with LMS. If not, see . */ -#include "Artist.hpp" +#include "database/Artist.hpp" #include +#include "database/Cluster.hpp" +#include "database/Release.hpp" +#include "database/Session.hpp" +#include "database/Track.hpp" +#include "database/User.hpp" #include "utils/Logger.hpp" - -#include "Cluster.hpp" -#include "Release.hpp" #include "SqlQuery.hpp" -#include "Session.hpp" -#include "Track.hpp" -#include "User.hpp" + namespace Database { diff --git a/src/database/Cluster.cpp b/src/liblms/impl/database/Cluster.cpp similarity index 96% rename from src/database/Cluster.cpp rename to src/liblms/impl/database/Cluster.cpp index ddfafb43..66e95c12 100644 --- a/src/database/Cluster.cpp +++ b/src/liblms/impl/database/Cluster.cpp @@ -17,14 +17,14 @@ * along with LMS. If not, see . */ -#include "Cluster.hpp" +#include "database/Cluster.hpp" -#include "Artist.hpp" -#include "Release.hpp" -#include "ScanSettings.hpp" -#include "Session.hpp" +#include "database/Artist.hpp" +#include "database/Release.hpp" +#include "database/ScanSettings.hpp" +#include "database/Session.hpp" +#include "database/Track.hpp" #include "SqlQuery.hpp" -#include "Track.hpp" namespace Database { diff --git a/src/database/Db.cpp b/src/liblms/impl/database/Db.cpp similarity index 96% rename from src/database/Db.cpp rename to src/liblms/impl/database/Db.cpp index 23edca35..87bdf5d7 100644 --- a/src/database/Db.cpp +++ b/src/liblms/impl/database/Db.cpp @@ -17,13 +17,13 @@ * along with LMS. If not, see . */ -#include "Db.hpp" +#include "database/Db.hpp" #include #include +#include "database/User.hpp" #include "utils/Logger.hpp" -#include "User.hpp" namespace Database { diff --git a/src/database/Release.cpp b/src/liblms/impl/database/Release.cpp similarity index 98% rename from src/database/Release.cpp rename to src/liblms/impl/database/Release.cpp index a4857f15..343a7ce1 100644 --- a/src/database/Release.cpp +++ b/src/liblms/impl/database/Release.cpp @@ -17,16 +17,16 @@ * along with LMS. If not, see . */ -#include "Release.hpp" +#include "database/Release.hpp" #include "utils/Logger.hpp" -#include "Artist.hpp" -#include "Cluster.hpp" -#include "Session.hpp" +#include "database/Artist.hpp" +#include "database/Cluster.hpp" +#include "database/Session.hpp" +#include "database/Track.hpp" +#include "database/User.hpp" #include "SqlQuery.hpp" -#include "Track.hpp" -#include "User.hpp" namespace Database { diff --git a/src/database/ScanSettings.cpp b/src/liblms/impl/database/ScanSettings.cpp similarity index 97% rename from src/database/ScanSettings.cpp rename to src/liblms/impl/database/ScanSettings.cpp index 1c024353..673e2a24 100644 --- a/src/database/ScanSettings.cpp +++ b/src/liblms/impl/database/ScanSettings.cpp @@ -17,15 +17,15 @@ * along with LMS. If not, see . */ -#include "ScanSettings.hpp" +#include "database/ScanSettings.hpp" #include #include "utils/Logger.hpp" #include "utils/String.hpp" -#include "Cluster.hpp" -#include "Session.hpp" +#include "database/Cluster.hpp" +#include "database/Session.hpp" namespace { diff --git a/src/database/Session.cpp b/src/liblms/impl/database/Session.cpp similarity index 96% rename from src/database/Session.cpp rename to src/liblms/impl/database/Session.cpp index 0c3aab24..36750ec7 100644 --- a/src/database/Session.cpp +++ b/src/liblms/impl/database/Session.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "Session.hpp" +#include "database/Session.hpp" #include #include @@ -26,17 +26,17 @@ #include "utils/Exception.hpp" #include "utils/Logger.hpp" -#include "Artist.hpp" -#include "Cluster.hpp" -#include "Db.hpp" -#include "Release.hpp" -#include "ScanSettings.hpp" -#include "Track.hpp" -#include "TrackBookmark.hpp" -#include "TrackArtistLink.hpp" -#include "TrackList.hpp" -#include "TrackFeatures.hpp" -#include "User.hpp" +#include "database/Artist.hpp" +#include "database/Cluster.hpp" +#include "database/Db.hpp" +#include "database/Release.hpp" +#include "database/ScanSettings.hpp" +#include "database/Track.hpp" +#include "database/TrackBookmark.hpp" +#include "database/TrackArtistLink.hpp" +#include "database/TrackList.hpp" +#include "database/TrackFeatures.hpp" +#include "database/User.hpp" namespace Database { diff --git a/src/database/SessionPool.cpp b/src/liblms/impl/database/SessionPool.cpp similarity index 96% rename from src/database/SessionPool.cpp rename to src/liblms/impl/database/SessionPool.cpp index f6526aca..ff6b1111 100644 --- a/src/database/SessionPool.cpp +++ b/src/liblms/impl/database/SessionPool.cpp @@ -17,13 +17,13 @@ * along with LMS. If not, see . */ -#include "SessionPool.hpp" +#include "database/SessionPool.hpp" + +#include "database/Session.hpp" #include "utils/Exception.hpp" #include "utils/Logger.hpp" -#include "Session.hpp" - namespace Database { SessionPool::SessionPool(Db& database, std::size_t maxSessionCount) diff --git a/src/database/SqlQuery.cpp b/src/liblms/impl/database/SqlQuery.cpp similarity index 100% rename from src/database/SqlQuery.cpp rename to src/liblms/impl/database/SqlQuery.cpp diff --git a/src/database/SqlQuery.hpp b/src/liblms/impl/database/SqlQuery.hpp similarity index 100% rename from src/database/SqlQuery.hpp rename to src/liblms/impl/database/SqlQuery.hpp diff --git a/src/database/Track.cpp b/src/liblms/impl/database/Track.cpp similarity index 98% rename from src/database/Track.cpp rename to src/liblms/impl/database/Track.cpp index 65503bbf..a84af8e1 100644 --- a/src/database/Track.cpp +++ b/src/liblms/impl/database/Track.cpp @@ -17,17 +17,17 @@ * along with LMS. If not, see . */ -#include "Track.hpp" +#include "database/Track.hpp" #include +#include "database/Artist.hpp" +#include "database/Cluster.hpp" +#include "database/Release.hpp" +#include "database/TrackFeatures.hpp" +#include "database/Session.hpp" #include "utils/Logger.hpp" -#include "Artist.hpp" -#include "Cluster.hpp" -#include "Release.hpp" -#include "TrackFeatures.hpp" -#include "Session.hpp" #include "SqlQuery.hpp" namespace Database { diff --git a/src/database/TrackArtistLink.cpp b/src/liblms/impl/database/TrackArtistLink.cpp similarity index 90% rename from src/database/TrackArtistLink.cpp rename to src/liblms/impl/database/TrackArtistLink.cpp index 64ce9281..57526eab 100644 --- a/src/database/TrackArtistLink.cpp +++ b/src/liblms/impl/database/TrackArtistLink.cpp @@ -17,11 +17,11 @@ * along with LMS. If not, see . */ -#include "TrackArtistLink.hpp" +#include "database/TrackArtistLink.hpp" -#include "Artist.hpp" -#include "Session.hpp" -#include "Track.hpp" +#include "database/Artist.hpp" +#include "database/Session.hpp" +#include "database/Track.hpp" namespace Database { diff --git a/src/database/TrackBookmark.cpp b/src/liblms/impl/database/TrackBookmark.cpp similarity index 94% rename from src/database/TrackBookmark.cpp rename to src/liblms/impl/database/TrackBookmark.cpp index 1307f0a7..2a0c4bef 100644 --- a/src/database/TrackBookmark.cpp +++ b/src/liblms/impl/database/TrackBookmark.cpp @@ -17,11 +17,11 @@ * along with LMS. If not, see . */ -#include "TrackBookmark.hpp" +#include "database/TrackBookmark.hpp" -#include "Session.hpp" -#include "Track.hpp" -#include "User.hpp" +#include "database/Session.hpp" +#include "database/Track.hpp" +#include "database/User.hpp" namespace Database { diff --git a/src/database/TrackFeatures.cpp b/src/liblms/impl/database/TrackFeatures.cpp similarity index 95% rename from src/database/TrackFeatures.cpp rename to src/liblms/impl/database/TrackFeatures.cpp index 6a812bc9..6fb3c963 100644 --- a/src/database/TrackFeatures.cpp +++ b/src/liblms/impl/database/TrackFeatures.cpp @@ -17,14 +17,14 @@ * along with LMS. If not, see . */ -#include "TrackFeatures.hpp" +#include "database/TrackFeatures.hpp" #include #include +#include "database/Session.hpp" +#include "database/Track.hpp" #include "utils/Logger.hpp" -#include "Session.hpp" -#include "Track.hpp" namespace Database { diff --git a/src/database/TrackList.cpp b/src/liblms/impl/database/TrackList.cpp similarity index 97% rename from src/database/TrackList.cpp rename to src/liblms/impl/database/TrackList.cpp index d63312ca..a7fc145c 100644 --- a/src/database/TrackList.cpp +++ b/src/liblms/impl/database/TrackList.cpp @@ -16,19 +16,18 @@ * You should have received a copy of the GNU General Public License * along with LMS. If not, see . */ -#include "TrackList.hpp" +#include "database/TrackList.hpp" #include -#include #include "utils/Logger.hpp" -#include "Artist.hpp" -#include "Cluster.hpp" -#include "Release.hpp" -#include "Session.hpp" -#include "User.hpp" -#include "Track.hpp" +#include "database/Artist.hpp" +#include "database/Cluster.hpp" +#include "database/Release.hpp" +#include "database/Session.hpp" +#include "database/User.hpp" +#include "database/Track.hpp" namespace Database { diff --git a/src/database/User.cpp b/src/liblms/impl/database/User.cpp similarity index 97% rename from src/database/User.cpp rename to src/liblms/impl/database/User.cpp index 2f0e52ef..6b980130 100644 --- a/src/database/User.cpp +++ b/src/liblms/impl/database/User.cpp @@ -17,14 +17,14 @@ * along with LMS. If not, see . */ -#include "User.hpp" +#include "database/User.hpp" +#include "database/Artist.hpp" +#include "database/Release.hpp" +#include "database/Session.hpp" +#include "database/Track.hpp" +#include "database/TrackList.hpp" #include "utils/Logger.hpp" -#include "Artist.hpp" -#include "Release.hpp" -#include "Session.hpp" -#include "Track.hpp" -#include "TrackList.hpp" namespace Database { diff --git a/src/metadata/AvFormat.cpp b/src/liblms/impl/metadata/AvFormat.cpp similarity index 98% rename from src/metadata/AvFormat.cpp rename to src/liblms/impl/metadata/AvFormat.cpp index 38790589..85311c7a 100644 --- a/src/metadata/AvFormat.cpp +++ b/src/liblms/impl/metadata/AvFormat.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "AvFormat.hpp" +#include "metadata/AvFormat.hpp" #include #include @@ -142,7 +142,7 @@ AvFormat::parse(const std::filesystem::path& p, bool debug) for (auto stream : mediaFile.getStreamInfo()) { - MetaData::AudioStream audioStream {.bitRate = static_cast(stream.bitrate)}; + MetaData::AudioStream audioStream {static_cast(stream.bitrate)}; track.audioStreams.emplace_back(audioStream); } } diff --git a/src/metadata/TagLibParser.cpp b/src/liblms/impl/metadata/TagLibParser.cpp similarity index 98% rename from src/metadata/TagLibParser.cpp rename to src/liblms/impl/metadata/TagLibParser.cpp index 5f430e14..78949ce8 100644 --- a/src/metadata/TagLibParser.cpp +++ b/src/liblms/impl/metadata/TagLibParser.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "TagLibParser.hpp" +#include "metadata/TagLibParser.hpp" #include #include @@ -180,7 +180,7 @@ TagLibParser::parse(const std::filesystem::path& p, bool debug) track.duration = std::chrono::milliseconds {properties->length() * 1000}; - MetaData::AudioStream audioStream {.bitRate = static_cast(properties->bitrate() * 1000)}; + MetaData::AudioStream audioStream {static_cast(properties->bitrate() * 1000)}; track.audioStreams = {std::move(audioStream)}; } diff --git a/src/similarity/SimilaritySearcher.cpp b/src/liblms/impl/recommendation/Engine.cpp similarity index 67% rename from src/similarity/SimilaritySearcher.cpp rename to src/liblms/impl/recommendation/Engine.cpp index cf2513d0..a2c61a61 100644 --- a/src/similarity/SimilaritySearcher.cpp +++ b/src/liblms/impl/recommendation/Engine.cpp @@ -17,31 +17,38 @@ * along with LMS. If not, see . */ -#include "SimilaritySearcher.hpp" +#include "Engine.hpp" -#include "features/SimilarityFeaturesScannerAddon.hpp" -#include "cluster/SimilarityClusterSearcher.hpp" +//#include "features/SimilarityFeaturesScannerAddon.hpp" +//#include "cluster/SimilarityClusterSearcher.hpp" #include "database/ScanSettings.hpp" #include "database/TrackList.hpp" -namespace Similarity { +namespace Recommendation { -Searcher::Searcher(FeaturesScannerAddon& somAddon) -: _somAddon(somAddon) -{} - -static -Database::ScanSettings::SimilarityEngineType -getEngineType(Database::Session& dbSession) +std::unique_ptr +createEngine() { - auto transaction {dbSession.createSharedTransaction()}; - return Database::ScanSettings::get(dbSession)->getSimilarityEngineType(); + return std::make_unique(); +} + +void +Engine::clearProviders() +{ + _providers.clear(); +} + +void +Engine::addProvider(std::unique_ptr provider, unsigned priority) +{ + _providers.emplace(priority, std::move(provider)); } std::vector -Searcher::getSimilarTracksFromTrackList(Database::Session& session, Database::IdType trackListId, std::size_t maxCount) +Engine::getSimilarTracksFromTrackList(Database::Session& /*session*/, Database::IdType /*trackListId*/, std::size_t /*maxCount*/) { +#if 0 auto engineType {getEngineType(session)}; auto somSearcher {_somAddon.getSearcher()}; @@ -66,12 +73,15 @@ Searcher::getSimilarTracksFromTrackList(Database::Session& session, Database::Id return somSearcher->getSimilarTracks(trackIds, maxCount); } else - return ClusterSearcher::getSimilarTracksFromTrackList(session, trackListId, maxCount); + return ClusterEngine::getSimilarTracksFromTrackList(session, trackListId, maxCount); +#endif + return {}; } std::vector -Searcher::getSimilarTracks(Database::Session& dbSession, const std::set& trackIds, std::size_t maxCount) +Engine::getSimilarTracks(Database::Session& /*dbSession*/, const std::unordered_set& /*trackIds*/, std::size_t /*maxCount*/) { +#if 0 auto engineType {getEngineType(dbSession)}; auto somSearcher {_somAddon.getSearcher()}; @@ -82,12 +92,15 @@ Searcher::getSimilarTracks(Database::Session& dbSession, const std::setgetSimilarTracks(trackIds, maxCount); } else - return ClusterSearcher::getSimilarTracks(dbSession, trackIds, maxCount); + return ClusterEngine::getSimilarTracks(dbSession, trackIds, maxCount); +#endif + return {}; } std::vector -Searcher::getSimilarReleases(Database::Session& dbSession, Database::IdType releaseId, std::size_t maxCount) +Engine::getSimilarReleases(Database::Session& /*dbSession*/, Database::IdType /*releaseId*/, std::size_t /*maxCount*/) { +#if 0 auto engineType {getEngineType(dbSession)}; auto somSearcher {_somAddon.getSearcher()}; @@ -98,12 +111,15 @@ Searcher::getSimilarReleases(Database::Session& dbSession, Database::IdType rele return somSearcher->getSimilarReleases(releaseId, maxCount); } else - return ClusterSearcher::getSimilarReleases(dbSession, releaseId, maxCount); + return ClusterEngine::getSimilarReleases(dbSession, releaseId, maxCount); +#endif + return {}; } std::vector -Searcher::getSimilarArtists(Database::Session& dbSession, Database::IdType artistId, std::size_t maxCount) +Engine::getSimilarArtists(Database::Session& /*dbSession*/, Database::IdType /*artistId*/, std::size_t /*maxCount*/) { +#if 0 auto engineType {getEngineType(dbSession)}; auto somSearcher {_somAddon.getSearcher()}; @@ -114,7 +130,9 @@ Searcher::getSimilarArtists(Database::Session& dbSession, Database::IdType artis return somSearcher->getSimilarArtists(artistId, maxCount); } else - return ClusterSearcher::getSimilarArtists(dbSession, artistId, maxCount); + return ClusterEngine::getSimilarArtists(dbSession, artistId, maxCount); +#endif + return {}; } } // ns Similarity diff --git a/src/liblms/impl/recommendation/Engine.hpp b/src/liblms/impl/recommendation/Engine.hpp new file mode 100644 index 00000000..92dacc08 --- /dev/null +++ b/src/liblms/impl/recommendation/Engine.hpp @@ -0,0 +1,52 @@ +/* + * 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 . + */ + +#pragma once + +#include + +#include "recommendation/IEngine.hpp" +#include "recommendation/Provider.hpp" + +namespace Database +{ + class Session; +} + +namespace Recommendation +{ + class Engine : public IEngine + { + public: + void clearProviders() override; + void addProvider(std::unique_ptr provider, unsigned priority) override; + + // Closest results first + std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount) override; + std::vector getSimilarTracks(Database::Session& session, const std::unordered_set& tracksId, std::size_t maxCount) override; + std::vector getSimilarReleases(Database::Session& session, Database::IdType releaseId, std::size_t maxCount) override; + std::vector getSimilarArtists(Database::Session& session, Database::IdType artistId, std::size_t maxCount) override; + + private: + + std::map> _providers; + }; + +} // ns Recommendation + diff --git a/src/liblms/impl/recommendation/ProviderCreator.cpp b/src/liblms/impl/recommendation/ProviderCreator.cpp new file mode 100644 index 00000000..b451e480 --- /dev/null +++ b/src/liblms/impl/recommendation/ProviderCreator.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 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 . + */ + +#include "recommendation/ClustersRecommendationProviderCreator.hpp" +#include "recommendation/FeaturesRecommendationProviderCreator.hpp" +#include "recommendation/Provider.hpp" + +namespace Recommendation +{ + + std::unique_ptr createClustersRecommendationProvider() + { + return {}; + } + + std::unique_ptr createFeaturesRecommendationProvider(Scanner::MediaScanner&) + { + return {}; + } + +} + diff --git a/src/similarity/cluster/SimilarityClusterSearcher.cpp b/src/liblms/impl/recommendation/cluster/SimilarityClusterSearcher.cpp similarity index 98% rename from src/similarity/cluster/SimilarityClusterSearcher.cpp rename to src/liblms/impl/recommendation/cluster/SimilarityClusterSearcher.cpp index 037dd3c4..7b24b5e4 100644 --- a/src/similarity/cluster/SimilarityClusterSearcher.cpp +++ b/src/liblms/impl/recommendation/cluster/SimilarityClusterSearcher.cpp @@ -19,9 +19,6 @@ #include "SimilarityClusterSearcher.hpp" -#include -#include - #include "database/Artist.hpp" #include "database/Cluster.hpp" #include "database/Release.hpp" diff --git a/src/similarity/cluster/SimilarityClusterSearcher.hpp b/src/liblms/impl/recommendation/cluster/SimilarityClusterSearcher.hpp similarity index 100% rename from src/similarity/cluster/SimilarityClusterSearcher.hpp rename to src/liblms/impl/recommendation/cluster/SimilarityClusterSearcher.hpp diff --git a/src/similarity/features/AcousticBrainzUtils.cpp b/src/liblms/impl/recommendation/features/AcousticBrainzUtils.cpp similarity index 91% rename from src/similarity/features/AcousticBrainzUtils.cpp rename to src/liblms/impl/recommendation/features/AcousticBrainzUtils.cpp index 7e460782..b33f5c4f 100644 --- a/src/similarity/features/AcousticBrainzUtils.cpp +++ b/src/liblms/impl/recommendation/features/AcousticBrainzUtils.cpp @@ -25,7 +25,7 @@ #include #include -#include "utils/Config.hpp" +#include "utils/IConfig.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -39,7 +39,7 @@ getJsonData(const UUID& mbid) { static const std::string defaultAPIURL = "https://acousticbrainz.org/api/v1/"; - const std::string url {ServiceProvider::get()->getString("acousticbrainz-api-url", defaultAPIURL) + std::string {mbid.getAsString()} + "/low-level"}; + const std::string url {ServiceProvider::get()->getString("acousticbrainz-api-url", defaultAPIURL) + std::string {mbid.getAsString()} + "/low-level"}; boost::asio::io_service ioService; diff --git a/src/similarity/features/AcousticBrainzUtils.hpp b/src/liblms/impl/recommendation/features/AcousticBrainzUtils.hpp similarity index 100% rename from src/similarity/features/AcousticBrainzUtils.hpp rename to src/liblms/impl/recommendation/features/AcousticBrainzUtils.hpp diff --git a/src/similarity/features/SimilarityFeaturesCache.cpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesCache.cpp similarity index 96% rename from src/similarity/features/SimilarityFeaturesCache.cpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesCache.cpp index 1f81c010..235ed331 100644 --- a/src/similarity/features/SimilarityFeaturesCache.cpp +++ b/src/liblms/impl/recommendation/features/SimilarityFeaturesCache.cpp @@ -22,7 +22,7 @@ #include #include -#include "utils/Config.hpp" +#include "utils/IConfig.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -32,7 +32,7 @@ namespace Similarity { static std::filesystem::path getCacheDirectory() { - return ServiceProvider::get()->getPath("working-dir") / "cache" / "features"; + return ServiceProvider::get()->getPath("working-dir") / "cache" / "features"; } static std::filesystem::path getCacheNetworkFilePath() @@ -242,7 +242,7 @@ FeaturesCache::read() void FeaturesCache::write() { - std::filesystem::create_directories(ServiceProvider::get()->getPath("working-dir") / "cache" / "features"); + std::filesystem::create_directories(ServiceProvider::get()->getPath("working-dir") / "cache" / "features"); if (!networkToCacheFile(_network, getCacheNetworkFilePath()) || !objectPositionToCacheFile(_trackPositions, getCacheTrackPositionsFilePath())) diff --git a/src/similarity/features/SimilarityFeaturesCache.hpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesCache.hpp similarity index 100% rename from src/similarity/features/SimilarityFeaturesCache.hpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesCache.hpp diff --git a/src/similarity/features/SimilarityFeaturesDefs.cpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesDefs.cpp similarity index 100% rename from src/similarity/features/SimilarityFeaturesDefs.cpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesDefs.cpp diff --git a/src/similarity/features/SimilarityFeaturesDefs.hpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesDefs.hpp similarity index 100% rename from src/similarity/features/SimilarityFeaturesDefs.hpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesDefs.hpp diff --git a/src/similarity/features/SimilarityFeaturesScannerAddon.cpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesScannerAddon.cpp similarity index 97% rename from src/similarity/features/SimilarityFeaturesScannerAddon.cpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesScannerAddon.cpp index 20ecf2d3..620cedc8 100644 --- a/src/similarity/features/SimilarityFeaturesScannerAddon.cpp +++ b/src/liblms/impl/recommendation/features/SimilarityFeaturesScannerAddon.cpp @@ -17,16 +17,16 @@ * along with LMS. If not, see . */ -#include "SimilarityFeaturesScannerAddon.hpp" +#include "similarity/features/SimilarityFeaturesScannerAddon.hpp" #include "AcousticBrainzUtils.hpp" #include "database/ScanSettings.hpp" #include "database/Track.hpp" #include "database/TrackFeatures.hpp" -#include "similarity/features/SimilarityFeaturesCache.hpp" -#include "utils/Config.hpp" #include "utils/Logger.hpp" +#include "SimilarityFeaturesCache.hpp" + namespace Similarity { static diff --git a/src/similarity/features/SimilarityFeaturesSearcher.cpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesSearcher.cpp similarity index 100% rename from src/similarity/features/SimilarityFeaturesSearcher.cpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesSearcher.cpp diff --git a/src/similarity/features/SimilarityFeaturesSearcher.hpp b/src/liblms/impl/recommendation/features/SimilarityFeaturesSearcher.hpp similarity index 100% rename from src/similarity/features/SimilarityFeaturesSearcher.hpp rename to src/liblms/impl/recommendation/features/SimilarityFeaturesSearcher.hpp diff --git a/src/similarity/features/som/DataNormalizer.cpp b/src/liblms/impl/recommendation/features/som/DataNormalizer.cpp similarity index 100% rename from src/similarity/features/som/DataNormalizer.cpp rename to src/liblms/impl/recommendation/features/som/DataNormalizer.cpp diff --git a/src/similarity/features/som/DataNormalizer.hpp b/src/liblms/impl/recommendation/features/som/DataNormalizer.hpp similarity index 100% rename from src/similarity/features/som/DataNormalizer.hpp rename to src/liblms/impl/recommendation/features/som/DataNormalizer.hpp diff --git a/src/similarity/features/som/InputVector.hpp b/src/liblms/impl/recommendation/features/som/InputVector.hpp similarity index 100% rename from src/similarity/features/som/InputVector.hpp rename to src/liblms/impl/recommendation/features/som/InputVector.hpp diff --git a/src/similarity/features/som/Matrix.hpp b/src/liblms/impl/recommendation/features/som/Matrix.hpp similarity index 100% rename from src/similarity/features/som/Matrix.hpp rename to src/liblms/impl/recommendation/features/som/Matrix.hpp diff --git a/src/similarity/features/som/Network.cpp b/src/liblms/impl/recommendation/features/som/Network.cpp similarity index 100% rename from src/similarity/features/som/Network.cpp rename to src/liblms/impl/recommendation/features/som/Network.cpp diff --git a/src/similarity/features/som/Network.hpp b/src/liblms/impl/recommendation/features/som/Network.hpp similarity index 100% rename from src/similarity/features/som/Network.hpp rename to src/liblms/impl/recommendation/features/som/Network.hpp diff --git a/src/scanner/MediaScanner.cpp b/src/liblms/impl/scanner/MediaScanner.cpp similarity index 99% rename from src/scanner/MediaScanner.cpp rename to src/liblms/impl/scanner/MediaScanner.cpp index fb835855..a88893e3 100644 --- a/src/scanner/MediaScanner.cpp +++ b/src/liblms/impl/scanner/MediaScanner.cpp @@ -17,13 +17,12 @@ * along with LMS. If not, see . */ -#include "MediaScanner.hpp" +#include "scanner/MediaScanner.hpp" #include #include -#include "cover/CoverArtGrabber.hpp" #include "database/Artist.hpp" #include "database/Cluster.hpp" #include "database/Release.hpp" diff --git a/src/scanner/MediaScannerStats.cpp b/src/liblms/impl/scanner/MediaScannerStats.cpp similarity index 97% rename from src/scanner/MediaScannerStats.cpp rename to src/liblms/impl/scanner/MediaScannerStats.cpp index f2f991f5..a2a984da 100644 --- a/src/scanner/MediaScannerStats.cpp +++ b/src/liblms/impl/scanner/MediaScannerStats.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "MediaScannerStats.hpp" +#include "scanner/MediaScannerStats.hpp" namespace Scanner { diff --git a/src/utils/Config.cpp b/src/liblms/impl/utils/Config.cpp similarity index 73% rename from src/utils/Config.cpp rename to src/liblms/impl/utils/Config.cpp index 40855b64..ff8c4846 100644 --- a/src/utils/Config.cpp +++ b/src/liblms/impl/utils/Config.cpp @@ -19,16 +19,36 @@ #include "Config.hpp" +#include "utils/Exception.hpp" #include "utils/Logger.hpp" +std::unique_ptr createConfig(const std::filesystem::path& p) +{ + return std::make_unique(p); +} Config::Config(const std::filesystem::path& p) { - _config.readFile(p.string().c_str()); + try + { + _config.readFile(p.string().c_str()); + } + catch( libconfig::FileIOException& e) + { + throw LmsException {"Cannot open config file '" + p.string() + "'"}; + } + catch( libconfig::ParseException& e) + { + throw LmsException {"Cannot parse config file '" + p.string() + "', line = " + std::to_string(e.getLine()) + ", error = '" + e.getError() + "'"}; + } + catch (libconfig::ConfigException& e) + { + throw LmsException {"Cannot open config file '" + p.string() + "': " + e.what()}; + } } std::string -Config::getString(const std::string& setting, const std::string& def, const std::set& allowedValues) +Config::getString(const std::string& setting, const std::string& def, const std::unordered_set& allowedValues) { try { std::string res {(const char*)_config.lookup(setting)}; diff --git a/src/utils/Config.hpp b/src/liblms/impl/utils/Config.hpp similarity index 77% rename from src/utils/Config.hpp rename to src/liblms/impl/utils/Config.hpp index 0b248e20..e1e9600e 100644 --- a/src/utils/Config.hpp +++ b/src/liblms/impl/utils/Config.hpp @@ -18,13 +18,12 @@ */ #pragma once -#include -#include +#include "utils/IConfig.hpp" #include // Used to get config values from configuration files -class Config final +class Config final : public IConfig { public: Config(const std::filesystem::path& p); @@ -36,11 +35,11 @@ class Config final Config& operator=(Config&&) = delete; // Default values are returned in case of setting not found - std::string getString(const std::string& setting, const std::string& def = "", const std::set& allowedValues = {}); - std::filesystem::path getPath(const std::string& setting, const std::filesystem::path& def = std::filesystem::path()); - unsigned long getULong(const std::string& setting, unsigned long def = 0); - long getLong(const std::string& setting, long def = 0); - bool getBool(const std::string& setting, bool def = false); + std::string getString(const std::string& setting, const std::string& def = "", const std::unordered_set& allowedValues = {}) override; + std::filesystem::path getPath(const std::string& setting, const std::filesystem::path& def = std::filesystem::path()) override; + unsigned long getULong(const std::string& setting, unsigned long def = 0) override; + long getLong(const std::string& setting, long def = 0) override; + bool getBool(const std::string& setting, bool def = false) override; private: diff --git a/src/utils/Logger.cpp b/src/liblms/impl/utils/Logger.cpp similarity index 98% rename from src/utils/Logger.cpp rename to src/liblms/impl/utils/Logger.cpp index 79bfafe9..b0d99437 100644 --- a/src/utils/Logger.cpp +++ b/src/liblms/impl/utils/Logger.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "Logger.hpp" +#include "utils/Logger.hpp" const char* getModuleName(Module mod) { diff --git a/src/utils/NetAddress.cpp b/src/liblms/impl/utils/NetAddress.cpp similarity index 97% rename from src/utils/NetAddress.cpp rename to src/liblms/impl/utils/NetAddress.cpp index 723de502..cede3029 100644 --- a/src/utils/NetAddress.cpp +++ b/src/liblms/impl/utils/NetAddress.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "NetAddress.hpp" +#include "utils/NetAddress.hpp" namespace std { diff --git a/src/utils/Path.cpp b/src/liblms/impl/utils/Path.cpp similarity index 98% rename from src/utils/Path.cpp rename to src/liblms/impl/utils/Path.cpp index dd2c4b21..a5c0d882 100644 --- a/src/utils/Path.cpp +++ b/src/liblms/impl/utils/Path.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "Path.hpp" +#include "utils/Path.hpp" #include #include diff --git a/src/utils/Random.cpp b/src/liblms/impl/utils/Random.cpp similarity index 96% rename from src/utils/Random.cpp rename to src/liblms/impl/utils/Random.cpp index c7114ddf..eb081ae0 100644 --- a/src/utils/Random.cpp +++ b/src/liblms/impl/utils/Random.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "Random.hpp" +#include "utils/Random.hpp" namespace Random { diff --git a/src/utils/StreamLogger.cpp b/src/liblms/impl/utils/StreamLogger.cpp similarity index 96% rename from src/utils/StreamLogger.cpp rename to src/liblms/impl/utils/StreamLogger.cpp index f4fc9cf5..94434332 100644 --- a/src/utils/StreamLogger.cpp +++ b/src/liblms/impl/utils/StreamLogger.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "StreamLogger.hpp" +#include "utils/StreamLogger.hpp" StreamLogger::StreamLogger(std::ostream& os) : _os {os} diff --git a/src/utils/String.cpp b/src/liblms/impl/utils/String.cpp similarity index 97% rename from src/utils/String.cpp rename to src/liblms/impl/utils/String.cpp index 299c177e..be6a79a1 100644 --- a/src/utils/String.cpp +++ b/src/liblms/impl/utils/String.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "String.hpp" +#include "utils/String.hpp" #include @@ -103,6 +103,12 @@ stringToLower(const std::string& str) return boost::algorithm::to_lower_copy(str); } +std::string +stringToUpper(const std::string& str) +{ + return boost::to_upper_copy(str); +} + std::string bufferToString(const std::vector& data) { diff --git a/src/utils/UUID.cpp b/src/liblms/impl/utils/UUID.cpp similarity index 97% rename from src/utils/UUID.cpp rename to src/liblms/impl/utils/UUID.cpp index 9edbdad4..f95209e2 100644 --- a/src/utils/UUID.cpp +++ b/src/liblms/impl/utils/UUID.cpp @@ -17,7 +17,7 @@ * along with LMS. If not, see . */ -#include "UUID.hpp" +#include "utils/UUID.hpp" #include diff --git a/src/utils/WtLogger.cpp b/src/liblms/impl/utils/WtLogger.cpp similarity index 94% rename from src/utils/WtLogger.cpp rename to src/liblms/impl/utils/WtLogger.cpp index bb1359b0..126af923 100644 --- a/src/utils/WtLogger.cpp +++ b/src/liblms/impl/utils/WtLogger.cpp @@ -17,12 +17,12 @@ * along with LMS. If not, see . */ -#include "WtLogger.hpp" +#include "utils/WtLogger.hpp" #include #include -#include "Logger.hpp" +#include "utils/Logger.hpp" void WtLogger::processLog(const Log& log) diff --git a/src/api/subsonic/SubsonicResource.hpp b/src/liblms/include/api/subsonic/SubsonicResource.hpp similarity index 100% rename from src/api/subsonic/SubsonicResource.hpp rename to src/liblms/include/api/subsonic/SubsonicResource.hpp diff --git a/src/liblms/include/auth/IAuthTokenService.hpp b/src/liblms/include/auth/IAuthTokenService.hpp new file mode 100644 index 00000000..f85148dd --- /dev/null +++ b/src/liblms/include/auth/IAuthTokenService.hpp @@ -0,0 +1,71 @@ +/* + * 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 . + */ + +/* This file contains some classes in order to get info from file using the libavconv */ + +#pragma once + +#include +#include +#include +#include + +#include "database/Types.hpp" + +namespace Database +{ + class Session; +} + + +namespace Auth { + + class IAuthTokenService + { + public: + + // Auth Token services + struct AuthTokenProcessResult + { + enum class State + { + Found, + Throttled, + NotFound, + }; + + struct AuthTokenInfo + { + Database::IdType userId; + Wt::WDateTime expiry; + }; + + State state {State::NotFound}; + std::optional authTokenInfo {}; + }; + + // Removed if found + virtual AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& tokenValue) = 0; + virtual std::string createAuthToken(Database::Session& session, Database::IdType userid, const Wt::WDateTime& expiry) = 0; + }; + + std::unique_ptr createAuthTokenService(std::size_t maxThrottlerEntryCount); + +} + diff --git a/src/liblms/include/auth/IPasswordService.hpp b/src/liblms/include/auth/IPasswordService.hpp new file mode 100644 index 00000000..fb5f9551 --- /dev/null +++ b/src/liblms/include/auth/IPasswordService.hpp @@ -0,0 +1,59 @@ +/* + * 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 . + */ + +#pragma once + +#include +#include + +#include + +#include "database/User.hpp" +#include "database/Types.hpp" + +namespace Database +{ + class Session; +} + + +namespace Auth { + + class IPasswordService + { + public: + + virtual ~IPasswordService() = default; + + // Password services + enum class PasswordCheckResult + { + Match, + Mismatch, + Throttled, + }; + virtual PasswordCheckResult checkUserPassword(Database::Session& session, const boost::asio::ip::address& clientAddress, const std::string& loginName, const std::string& password) = 0; + virtual Database::User::PasswordHash hashPassword(const std::string& password) const = 0; + virtual bool evaluatePasswordStrength(const std::string& loginName, const std::string& password) const = 0; + }; + + std::unique_ptr createPasswordService(std::size_t maxThrottlerEntryCount); + +} + diff --git a/src/av/AvInfo.hpp b/src/liblms/include/av/AvInfo.hpp similarity index 100% rename from src/av/AvInfo.hpp rename to src/liblms/include/av/AvInfo.hpp diff --git a/src/av/AvTranscoder.hpp b/src/liblms/include/av/AvTranscoder.hpp similarity index 100% rename from src/av/AvTranscoder.hpp rename to src/liblms/include/av/AvTranscoder.hpp diff --git a/src/av/AvTypes.hpp b/src/liblms/include/av/AvTypes.hpp similarity index 100% rename from src/av/AvTypes.hpp rename to src/liblms/include/av/AvTypes.hpp diff --git a/src/liblms/include/cover/CoverArt.hpp b/src/liblms/include/cover/CoverArt.hpp new file mode 100644 index 00000000..db392e6f --- /dev/null +++ b/src/liblms/include/cover/CoverArt.hpp @@ -0,0 +1,40 @@ + +/* + * Copyright (C) 2015 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 . + */ + +#pragma once + +#include + +namespace CoverArt +{ + + enum class Format + { + JPEG, + }; + std::string formatToMimeType(Format format); + + struct Geometry + { + std::size_t width; + std::size_t height; + }; + +} diff --git a/src/liblms/include/cover/ICoverArtGrabber.hpp b/src/liblms/include/cover/ICoverArtGrabber.hpp new file mode 100644 index 00000000..e018521a --- /dev/null +++ b/src/liblms/include/cover/ICoverArtGrabber.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 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 . + */ + +#pragma once + +#include +#include + +#include "database/Types.hpp" +#include "cover/CoverArt.hpp" + +namespace Database { + class Session; +} + +namespace CoverArt { + +class IGrabber +{ + public: + virtual ~IGrabber() = default; + + virtual void setDefaultCover(const std::filesystem::path& defaultCoverPath) = 0; + + virtual std::vector getFromTrack(Database::Session& dbSession, Database::IdType trackId, Format format, std::size_t width) = 0; + virtual std::vector getFromRelease(Database::Session& dbSession, Database::IdType releaseId, Format format, std::size_t width) = 0; + +}; + +} // namespace CoverArt + diff --git a/src/database/Artist.hpp b/src/liblms/include/database/Artist.hpp similarity index 100% rename from src/database/Artist.hpp rename to src/liblms/include/database/Artist.hpp diff --git a/src/database/Cluster.hpp b/src/liblms/include/database/Cluster.hpp similarity index 100% rename from src/database/Cluster.hpp rename to src/liblms/include/database/Cluster.hpp diff --git a/src/database/Db.hpp b/src/liblms/include/database/Db.hpp similarity index 100% rename from src/database/Db.hpp rename to src/liblms/include/database/Db.hpp diff --git a/src/database/Release.hpp b/src/liblms/include/database/Release.hpp similarity index 100% rename from src/database/Release.hpp rename to src/liblms/include/database/Release.hpp diff --git a/src/database/ScanSettings.hpp b/src/liblms/include/database/ScanSettings.hpp similarity index 100% rename from src/database/ScanSettings.hpp rename to src/liblms/include/database/ScanSettings.hpp diff --git a/src/database/Session.hpp b/src/liblms/include/database/Session.hpp similarity index 94% rename from src/database/Session.hpp rename to src/liblms/include/database/Session.hpp index 427fc6fd..303501bd 100644 --- a/src/database/Session.hpp +++ b/src/liblms/include/database/Session.hpp @@ -67,8 +67,8 @@ class Session Session& operator=(const Session&) = delete; Session& operator=(Session&&) = delete; - UniqueTransaction createUniqueTransaction(); - SharedTransaction createSharedTransaction(); + [[nodiscard]] UniqueTransaction createUniqueTransaction(); + [[nodiscard]] SharedTransaction createSharedTransaction(); void checkUniqueLocked(); void checkSharedLocked(); diff --git a/src/database/SessionPool.hpp b/src/liblms/include/database/SessionPool.hpp similarity index 100% rename from src/database/SessionPool.hpp rename to src/liblms/include/database/SessionPool.hpp diff --git a/src/database/Track.hpp b/src/liblms/include/database/Track.hpp similarity index 100% rename from src/database/Track.hpp rename to src/liblms/include/database/Track.hpp diff --git a/src/database/TrackArtistLink.hpp b/src/liblms/include/database/TrackArtistLink.hpp similarity index 100% rename from src/database/TrackArtistLink.hpp rename to src/liblms/include/database/TrackArtistLink.hpp diff --git a/src/database/TrackBookmark.hpp b/src/liblms/include/database/TrackBookmark.hpp similarity index 100% rename from src/database/TrackBookmark.hpp rename to src/liblms/include/database/TrackBookmark.hpp diff --git a/src/database/TrackFeatures.hpp b/src/liblms/include/database/TrackFeatures.hpp similarity index 100% rename from src/database/TrackFeatures.hpp rename to src/liblms/include/database/TrackFeatures.hpp diff --git a/src/database/TrackList.hpp b/src/liblms/include/database/TrackList.hpp similarity index 100% rename from src/database/TrackList.hpp rename to src/liblms/include/database/TrackList.hpp diff --git a/src/database/Types.hpp b/src/liblms/include/database/Types.hpp similarity index 100% rename from src/database/Types.hpp rename to src/liblms/include/database/Types.hpp diff --git a/src/database/User.hpp b/src/liblms/include/database/User.hpp similarity index 100% rename from src/database/User.hpp rename to src/liblms/include/database/User.hpp diff --git a/src/metadata/AvFormat.hpp b/src/liblms/include/metadata/AvFormat.hpp similarity index 100% rename from src/metadata/AvFormat.hpp rename to src/liblms/include/metadata/AvFormat.hpp diff --git a/src/metadata/MetaData.hpp b/src/liblms/include/metadata/MetaData.hpp similarity index 100% rename from src/metadata/MetaData.hpp rename to src/liblms/include/metadata/MetaData.hpp diff --git a/src/metadata/TagLibParser.hpp b/src/liblms/include/metadata/TagLibParser.hpp similarity index 100% rename from src/metadata/TagLibParser.hpp rename to src/liblms/include/metadata/TagLibParser.hpp diff --git a/src/liblms/include/recommendation/ClustersRecommendationProviderCreator.hpp b/src/liblms/include/recommendation/ClustersRecommendationProviderCreator.hpp new file mode 100644 index 00000000..99b11666 --- /dev/null +++ b/src/liblms/include/recommendation/ClustersRecommendationProviderCreator.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 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 . + */ + +#pragma once + +#include + +namespace Database +{ + class Session; +} + +namespace Recommendation +{ + class Provider; + + std::unique_ptr createClustersRecommendationProvider(); +} + diff --git a/src/liblms/include/recommendation/FeaturesRecommendationProviderCreator.hpp b/src/liblms/include/recommendation/FeaturesRecommendationProviderCreator.hpp new file mode 100644 index 00000000..01c07787 --- /dev/null +++ b/src/liblms/include/recommendation/FeaturesRecommendationProviderCreator.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 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 . + */ + +#pragma once + +#include + +namespace Database +{ + class Session; +} + +namespace Scanner +{ + class MediaScanner; +} + +namespace Recommendation +{ + class Provider; + + std::unique_ptr createFeaturesRecommendationProvider(Scanner::MediaScanner& scanner); +} + diff --git a/src/liblms/include/recommendation/IEngine.hpp b/src/liblms/include/recommendation/IEngine.hpp new file mode 100644 index 00000000..bc420aff --- /dev/null +++ b/src/liblms/include/recommendation/IEngine.hpp @@ -0,0 +1,54 @@ +/* + * 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 . + */ + +#pragma once + +#include +#include + +#include "database/Types.hpp" +#include "Provider.hpp" + +namespace Database +{ + class Session; +} + +namespace Recommendation +{ + class Provider; + class IEngine + { + public: + virtual ~IEngine() = default; + + virtual void clearProviders() = 0; + virtual void addProvider(std::unique_ptr provider, unsigned priority) = 0; + + // Closest results first + virtual std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount) = 0; + virtual std::vector getSimilarTracks(Database::Session& session, const std::unordered_set& tracksId, std::size_t maxCount) = 0; + virtual std::vector getSimilarReleases(Database::Session& session, Database::IdType releaseId, std::size_t maxCount) = 0; + virtual std::vector getSimilarArtists(Database::Session& session, Database::IdType artistId, std::size_t maxCount) = 0; + }; + + std::unique_ptr createEngine(); + +} // ns Recommendation + diff --git a/src/liblms/include/recommendation/Provider.hpp b/src/liblms/include/recommendation/Provider.hpp new file mode 100644 index 00000000..d40f686e --- /dev/null +++ b/src/liblms/include/recommendation/Provider.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 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 . + */ + +#pragma once + +#include +#include + +#include "database/Types.hpp" + +namespace Database +{ + class Session; +} + +namespace Recommendation +{ + + class Provider + { + public: + virtual ~Provider() = default; + + virtual bool isTrackClassified(Database::IdType trackId) const = 0; + virtual bool isReleaseClassified(Database::IdType releaseId) const = 0; + virtual bool isArtistClassified(Database::IdType artistId) const = 0; + + virtual std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount) = 0; + virtual std::vector getSimilarTracks(Database::Session& session, const std::unordered_set& tracksId, std::size_t maxCount) const = 0; + virtual std::vector getSimilarReleases(Database::IdType releaseId, std::size_t maxCount) const = 0; + virtual std::vector getSimilarArtists(Database::IdType artistId, std::size_t maxCount) const = 0; + }; + +} // ns Recommendation diff --git a/src/scanner/MediaScanner.hpp b/src/liblms/include/scanner/MediaScanner.hpp similarity index 100% rename from src/scanner/MediaScanner.hpp rename to src/liblms/include/scanner/MediaScanner.hpp diff --git a/src/scanner/MediaScannerAddon.hpp b/src/liblms/include/scanner/MediaScannerAddon.hpp similarity index 100% rename from src/scanner/MediaScannerAddon.hpp rename to src/liblms/include/scanner/MediaScannerAddon.hpp diff --git a/src/scanner/MediaScannerStats.hpp b/src/liblms/include/scanner/MediaScannerStats.hpp similarity index 100% rename from src/scanner/MediaScannerStats.hpp rename to src/liblms/include/scanner/MediaScannerStats.hpp diff --git a/src/utils/Exception.hpp b/src/liblms/include/utils/Exception.hpp similarity index 100% rename from src/utils/Exception.hpp rename to src/liblms/include/utils/Exception.hpp diff --git a/src/liblms/include/utils/IConfig.hpp b/src/liblms/include/utils/IConfig.hpp new file mode 100644 index 00000000..6b62169b --- /dev/null +++ b/src/liblms/include/utils/IConfig.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 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 . + */ +#pragma once + +#include +#include +#include + +// Used to get config values from configuration files +class IConfig +{ + public: + + // Default values are returned in case of setting not found + virtual std::string getString(const std::string& setting, const std::string& def = "", const std::unordered_set& allowedValues = {}) = 0; + virtual std::filesystem::path getPath(const std::string& setting, const std::filesystem::path& def = std::filesystem::path()) = 0; + virtual unsigned long getULong(const std::string& setting, unsigned long def = 0) = 0; + virtual long getLong(const std::string& setting, long def = 0) = 0; + virtual bool getBool(const std::string& setting, bool def = false) = 0; +}; + + +std::unique_ptr createConfig(const std::filesystem::path& p); + diff --git a/src/utils/Logger.hpp b/src/liblms/include/utils/Logger.hpp similarity index 100% rename from src/utils/Logger.hpp rename to src/liblms/include/utils/Logger.hpp diff --git a/src/utils/NetAddress.hpp b/src/liblms/include/utils/NetAddress.hpp similarity index 100% rename from src/utils/NetAddress.hpp rename to src/liblms/include/utils/NetAddress.hpp diff --git a/src/utils/Path.hpp b/src/liblms/include/utils/Path.hpp similarity index 100% rename from src/utils/Path.hpp rename to src/liblms/include/utils/Path.hpp diff --git a/src/utils/Random.hpp b/src/liblms/include/utils/Random.hpp similarity index 100% rename from src/utils/Random.hpp rename to src/liblms/include/utils/Random.hpp diff --git a/src/utils/Service.hpp b/src/liblms/include/utils/Service.hpp similarity index 92% rename from src/utils/Service.hpp rename to src/liblms/include/utils/Service.hpp index a18363ce..c53a8c81 100644 --- a/src/utils/Service.hpp +++ b/src/liblms/include/utils/Service.hpp @@ -46,7 +46,14 @@ class ServiceProvider return *get(); } - static void assign(std::unique_ptr service) { _service = std::move(service); } + static + Class& + assign(std::unique_ptr service) + { + _service = std::move(service); + return *get(); + } + static void clear() { _service.reset(); } static Class* get() { return _service.get(); } diff --git a/src/utils/StreamLogger.hpp b/src/liblms/include/utils/StreamLogger.hpp similarity index 100% rename from src/utils/StreamLogger.hpp rename to src/liblms/include/utils/StreamLogger.hpp diff --git a/src/utils/String.hpp b/src/liblms/include/utils/String.hpp similarity index 97% rename from src/utils/String.hpp rename to src/liblms/include/utils/String.hpp index 44f67faa..1ee1a964 100644 --- a/src/utils/String.hpp +++ b/src/liblms/include/utils/String.hpp @@ -26,6 +26,7 @@ namespace StringUtils { + std::vector splitString(const std::string& string, const std::string& separators); @@ -41,6 +42,9 @@ stringTrimEnd(const std::string& str, const std::string& whitespaces = " \t"); std::string stringToLower(const std::string& str); +std::string +stringToUpper(const std::string& str); + std::string bufferToString(const std::vector& data); diff --git a/src/utils/UUID.hpp b/src/liblms/include/utils/UUID.hpp similarity index 100% rename from src/utils/UUID.hpp rename to src/liblms/include/utils/UUID.hpp diff --git a/src/utils/Utils.hpp b/src/liblms/include/utils/Utils.hpp similarity index 100% rename from src/utils/Utils.hpp rename to src/liblms/include/utils/Utils.hpp diff --git a/src/utils/WtLogger.hpp b/src/liblms/include/utils/WtLogger.hpp similarity index 100% rename from src/utils/WtLogger.hpp rename to src/liblms/include/utils/WtLogger.hpp diff --git a/src/lms/CMakeLists.txt b/src/lms/CMakeLists.txt new file mode 100644 index 00000000..94526da9 --- /dev/null +++ b/src/lms/CMakeLists.txt @@ -0,0 +1,47 @@ + +add_executable(lms + main.cpp + ui/Auth.cpp + ui/LmsApplication.cpp + ui/LmsApplicationGroup.cpp + ui/MediaPlayer.cpp + ui/PlayQueueView.cpp + ui/PlayHistoryView.cpp + ui/SettingsView.cpp + ui/TrackStringUtils.cpp + ui/admin/DatabaseSettingsView.cpp + ui/admin/DatabaseStatus.cpp + ui/admin/InitWizardView.cpp + ui/admin/UserView.cpp + ui/admin/UsersView.cpp + ui/common/Validators.cpp + ui/explore/ArtistInfoView.cpp + ui/explore/ArtistLink.cpp + ui/explore/ArtistsInfoView.cpp + ui/explore/ArtistView.cpp + ui/explore/ArtistsView.cpp + ui/explore/Explore.cpp + ui/explore/Filters.cpp + ui/explore/ReleaseInfoView.cpp + ui/explore/ReleaseLink.cpp + ui/explore/ReleasesInfoView.cpp + ui/explore/ReleasesView.cpp + ui/explore/ReleaseView.cpp + ui/explore/TracksInfoView.cpp + ui/explore/TracksView.cpp + ui/resource/ImageResource.cpp + ui/resource/AudioResource.cpp + ) + +target_include_directories(lms PRIVATE + ui/ + ) + +target_link_libraries(lms PRIVATE + liblms + wt + wthttp + ) + +install(TARGETS lms DESTINATION bin) + diff --git a/src/main/main.cpp b/src/lms/main.cpp similarity index 63% rename from src/main/main.cpp rename to src/lms/main.cpp index 805de6c0..b51512d0 100644 --- a/src/main/main.cpp +++ b/src/lms/main.cpp @@ -25,16 +25,17 @@ #include "api/subsonic/SubsonicResource.hpp" #include "av/AvInfo.hpp" #include "av/AvTranscoder.hpp" -#include "auth/AuthTokenService.hpp" -#include "auth/PasswordService.hpp" +#include "auth/IAuthTokenService.hpp" +#include "auth/IPasswordService.hpp" #include "cover/CoverArtGrabber.hpp" #include "database/Db.hpp" #include "image/Image.hpp" #include "scanner/MediaScanner.hpp" -#include "similarity/features/SimilarityFeaturesScannerAddon.hpp" -#include "similarity/SimilaritySearcher.hpp" +#include "recommendation/FeaturesRecommendationProviderCreator.hpp" +#include "recommendation/IEngine.hpp" +#include "recommendation/ClustersRecommendationProviderCreator.hpp" #include "ui/LmsApplication.hpp" -#include "utils/Config.hpp" +#include "utils/IConfig.hpp" #include "utils/Service.hpp" #include "utils/WtLogger.hpp" @@ -42,28 +43,28 @@ std::vector generateWtConfig(std::string execPath) { std::vector args; - const std::filesystem::path wtConfigPath {ServiceProvider::get()->getPath("working-dir") / "wt_config.xml"}; - const std::filesystem::path wtLogFilePath {ServiceProvider::get()->getPath("log-file", "/var/log/lms.log")}; - const std::filesystem::path wtAccessLogFilePath {ServiceProvider::get()->getPath("access-log-file", "/var/log/lms.access.log")}; + const std::filesystem::path wtConfigPath {ServiceProvider::get()->getPath("working-dir") / "wt_config.xml"}; + const std::filesystem::path wtLogFilePath {ServiceProvider::get()->getPath("log-file", "/var/log/lms.log")}; + const std::filesystem::path wtAccessLogFilePath {ServiceProvider::get()->getPath("access-log-file", "/var/log/lms.access.log")}; args.push_back(execPath); args.push_back("--config=" + wtConfigPath.string()); - args.push_back("--docroot=" + ServiceProvider::get()->getString("docroot")); - args.push_back("--approot=" + ServiceProvider::get()->getString("approot")); - args.push_back("--resources-dir=" + ServiceProvider::get()->getString("wt-resources")); + args.push_back("--docroot=" + ServiceProvider::get()->getString("docroot")); + args.push_back("--approot=" + ServiceProvider::get()->getString("approot")); + args.push_back("--resources-dir=" + ServiceProvider::get()->getString("wt-resources")); - if (ServiceProvider::get()->getBool("tls-enable", false)) + if (ServiceProvider::get()->getBool("tls-enable", false)) { - args.push_back("--https-port=" + std::to_string( ServiceProvider::get()->getULong("listen-port", 5082))); - args.push_back("--https-address=" + ServiceProvider::get()->getString("listen-addr", "0.0.0.0")); - args.push_back("--ssl-certificate=" + ServiceProvider::get()->getString("tls-cert")); - args.push_back("--ssl-private-key=" + ServiceProvider::get()->getString("tls-key")); - args.push_back("--ssl-tmp-dh=" + ServiceProvider::get()->getString("tls-dh")); + args.push_back("--https-port=" + std::to_string( ServiceProvider::get()->getULong("listen-port", 5082))); + args.push_back("--https-address=" + ServiceProvider::get()->getString("listen-addr", "0.0.0.0")); + args.push_back("--ssl-certificate=" + ServiceProvider::get()->getString("tls-cert")); + args.push_back("--ssl-private-key=" + ServiceProvider::get()->getString("tls-key")); + args.push_back("--ssl-tmp-dh=" + ServiceProvider::get()->getString("tls-dh")); } else { - args.push_back("--http-port=" + std::to_string( ServiceProvider::get()->getULong("listen-port", 5082))); - args.push_back("--http-address=" + ServiceProvider::get()->getString("listen-addr", "0.0.0.0")); + args.push_back("--http-port=" + std::to_string( ServiceProvider::get()->getULong("listen-port", 5082))); + args.push_back("--http-address=" + ServiceProvider::get()->getString("listen-addr", "0.0.0.0")); } if (!wtAccessLogFilePath.empty()) @@ -74,8 +75,8 @@ std::vector generateWtConfig(std::string execPath) pt.put("server.application-settings..location", "*"); pt.put("server.application-settings.log-file", wtLogFilePath.string()); - pt.put("server.application-settings.log-config", ServiceProvider::get()->getString("log-config", "* -debug -info:WebRequest")); - pt.put("server.application-settings.behind-reverse-proxy", ServiceProvider::get()->getBool("behind-reverse-proxy", false)); + pt.put("server.application-settings.log-config", ServiceProvider::get()->getString("log-config", "* -debug -info:WebRequest")); + pt.put("server.application-settings.behind-reverse-proxy", ServiceProvider::get()->getBool("behind-reverse-proxy", false)); pt.put("server.application-settings.progressive-bootstrap", true); std::ofstream oss(wtConfigPath.string().c_str(), std::ios::out); @@ -108,17 +109,17 @@ int main(int argc, char* argv[]) // Make pstream work with ffmpeg close(STDIN_FILENO); - ServiceProvider::create(configFilePath); + ServiceProvider::assign(createConfig(configFilePath)); ServiceProvider::create(); // Make sure the working directory exists - std::filesystem::create_directories(ServiceProvider::get()->getPath("working-dir")); - std::filesystem::create_directories(ServiceProvider::get()->getPath("working-dir") / "cache"); + std::filesystem::create_directories(ServiceProvider::get()->getPath("working-dir")); + std::filesystem::create_directories(ServiceProvider::get()->getPath("working-dir") / "cache"); // Construct WT configuration and get the argc/argv back std::vector wtServerArgs = generateWtConfig(argv[0]); - const char* wtArgv[wtServerArgs.size()]; + std::vector wtArgv(wtServerArgs.size()); for (std::size_t i = 0; i < wtServerArgs.size(); ++i) { std::cout << "ARG = " << wtServerArgs[i] << std::endl; @@ -126,14 +127,14 @@ int main(int argc, char* argv[]) } Wt::WServer server(argv[0]); - server.setServerConfiguration (wtServerArgs.size(), const_cast(wtArgv)); + server.setServerConfiguration (wtServerArgs.size(), const_cast(&wtArgv[0])); // lib init Image::init(argv[0]); Av::Transcoder::init(); // Initializing a connection pool to the database that will be shared along services - Database::Db database {ServiceProvider::get()->getPath("working-dir") / "lms.db"}; + Database::Db database {ServiceProvider::get()->getPath("working-dir") / "lms.db"}; { Database::Session session {database}; session.prepareTables(); @@ -142,23 +143,21 @@ int main(int argc, char* argv[]) UserInterface::LmsApplicationGroupContainer appGroups; // Service initialization order is important - ServiceProvider::create(ServiceProvider::get()->getULong("login-throttler-max-entriees", 10000)); - ServiceProvider::create(ServiceProvider::get()->getULong("login-throttler-max-entriees", 10000)); + ServiceProvider::assign(Auth::createAuthTokenService(ServiceProvider::get()->getULong("login-throttler-max-entriees", 10000))); + ServiceProvider::assign(Auth::createPasswordService(ServiceProvider::get()->getULong("login-throttler-max-entriees", 10000))); Scanner::MediaScanner& mediaScanner {ServiceProvider::create(database)}; - Similarity::FeaturesScannerAddon similarityFeaturesScannerAddon {database}; - - mediaScanner.setAddon(similarityFeaturesScannerAddon); + Recommendation::IEngine& recommendationEngine {ServiceProvider::assign(Recommendation::createEngine())}; + recommendationEngine.addProvider(Recommendation::createFeaturesRecommendationProvider(mediaScanner), 0); + recommendationEngine.addProvider(Recommendation::createClustersRecommendationProvider(), 1); CoverArt::Grabber& coverArtGrabber {ServiceProvider::create()}; coverArtGrabber.setDefaultCover(server.appRoot() + "/images/unknown-cover.jpg"); - ServiceProvider::create(similarityFeaturesScannerAddon); - API::Subsonic::SubsonicResource subsonicResource {database}; // bind API resources - if (ServiceProvider::get()->getBool("api-subsonic", true)) + if (ServiceProvider::get()->getBool("api-subsonic", true)) server.addResource(&subsonicResource, subsonicResource.getPath()); // bind UI entry point @@ -187,14 +186,6 @@ int main(int argc, char* argv[]) LMS_LOG(MAIN, INFO) << "Clean stop!"; res = EXIT_SUCCESS; } - catch( libconfig::FileIOException& e) - { - std::cerr << "Cannot open config file '" << configFilePath << "'" << std::endl; - } - catch( libconfig::ParseException& e) - { - std::cerr << "Caught libconfig::ParseException! error='" << e.getError() << "', file = '" << e.getFile() << "', line = " << e.getLine() << std::endl; - } catch(Wt::WServer::Exception& e) { std::cerr << "Caught a WServer::Exception: " << e.what() << std::endl; diff --git a/src/ui/Auth.cpp b/src/lms/ui/Auth.cpp similarity index 85% rename from src/ui/Auth.cpp rename to src/lms/ui/Auth.cpp index f1f37124..d450b0c7 100644 --- a/src/ui/Auth.cpp +++ b/src/lms/ui/Auth.cpp @@ -27,8 +27,8 @@ #include #include -#include "auth/AuthTokenService.hpp" -#include "auth/PasswordService.hpp" +#include "auth/IAuthTokenService.hpp" +#include "auth/IPasswordService.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -43,7 +43,7 @@ static void createAuthToken(Database::IdType userId, const Wt::WDateTime& expiry) { - const std::string secret {ServiceProvider<::Auth::AuthTokenService>::get()->createAuthToken(LmsApp->getDbSession(), userId, expiry)}; + const std::string secret {ServiceProvider<::Auth::IAuthTokenService>::get()->createAuthToken(LmsApp->getDbSession(), userId, expiry)}; LmsApp->setCookie(authCookieName, secret, @@ -61,15 +61,15 @@ processAuthToken(const Wt::WEnvironment& env) if (!authCookie) return std::nullopt; - const auto res {ServiceProvider<::Auth::AuthTokenService>::get()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)}; + const auto res {ServiceProvider<::Auth::IAuthTokenService>::get()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)}; switch (res.state) { - case ::Auth::AuthTokenService::AuthTokenProcessResult::State::NotFound: - case ::Auth::AuthTokenService::AuthTokenProcessResult::State::Throttled: + case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::NotFound: + case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::Throttled: LmsApp->setCookie(authCookieName, std::string {}, 0, "", "", env.urlScheme() == "https"); return std::nullopt; - case ::Auth::AuthTokenService::AuthTokenProcessResult::State::Found: + case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::Found: createAuthToken(res.authTokenInfo->userId, res.authTokenInfo->expiry); break; } @@ -124,18 +124,18 @@ class AuthModel : public Wt::WFormModel if (field == PasswordField) { - switch (ServiceProvider<::Auth::PasswordService>::get()->checkUserPassword( + switch (ServiceProvider<::Auth::IPasswordService>::get()->checkUserPassword( LmsApp->getDbSession(), boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()), valueText(LoginNameField).toUTF8(), valueText(PasswordField).toUTF8())) { - case ::Auth::PasswordService::PasswordCheckResult::Match: + case ::Auth::IPasswordService::PasswordCheckResult::Match: break; - case ::Auth::PasswordService::PasswordCheckResult::Mismatch: + case ::Auth::IPasswordService::PasswordCheckResult::Mismatch: error = Wt::WString::tr("Lms.password-bad-login-combination"); break; - case ::Auth::PasswordService::PasswordCheckResult::Throttled: + case ::Auth::IPasswordService::PasswordCheckResult::Throttled: error = Wt::WString::tr("Lms.password-client-throttled"); break; } diff --git a/src/ui/Auth.hpp b/src/lms/ui/Auth.hpp similarity index 100% rename from src/ui/Auth.hpp rename to src/lms/ui/Auth.hpp diff --git a/src/ui/LmsApplication.cpp b/src/lms/ui/LmsApplication.cpp similarity index 99% rename from src/ui/LmsApplication.cpp rename to src/lms/ui/LmsApplication.cpp index ebc16ae0..669417e2 100644 --- a/src/ui/LmsApplication.cpp +++ b/src/lms/ui/LmsApplication.cpp @@ -29,7 +29,6 @@ #include #include -#include "config/config.h" #include "cover/CoverArtGrabber.hpp" #include "database/Artist.hpp" #include "database/Cluster.hpp" diff --git a/src/ui/LmsApplication.hpp b/src/lms/ui/LmsApplication.hpp similarity index 100% rename from src/ui/LmsApplication.hpp rename to src/lms/ui/LmsApplication.hpp diff --git a/src/ui/LmsApplicationException.hpp b/src/lms/ui/LmsApplicationException.hpp similarity index 100% rename from src/ui/LmsApplicationException.hpp rename to src/lms/ui/LmsApplicationException.hpp diff --git a/src/ui/LmsApplicationGroup.cpp b/src/lms/ui/LmsApplicationGroup.cpp similarity index 97% rename from src/ui/LmsApplicationGroup.cpp rename to src/lms/ui/LmsApplicationGroup.cpp index 70fcbe64..d9c41199 100644 --- a/src/ui/LmsApplicationGroup.cpp +++ b/src/lms/ui/LmsApplicationGroup.cpp @@ -30,7 +30,7 @@ namespace UserInterface { LmsApplicationInfo LmsApplicationInfo::fromEnvironment(const Wt::WEnvironment& env) { - LmsApplicationInfo info = {.userAgent = env.agent()}; + LmsApplicationInfo info = {env.agent()}; return info; } diff --git a/src/ui/LmsApplicationGroup.hpp b/src/lms/ui/LmsApplicationGroup.hpp similarity index 100% rename from src/ui/LmsApplicationGroup.hpp rename to src/lms/ui/LmsApplicationGroup.hpp diff --git a/src/ui/MediaPlayer.cpp b/src/lms/ui/MediaPlayer.cpp similarity index 100% rename from src/ui/MediaPlayer.cpp rename to src/lms/ui/MediaPlayer.cpp diff --git a/src/ui/MediaPlayer.hpp b/src/lms/ui/MediaPlayer.hpp similarity index 100% rename from src/ui/MediaPlayer.hpp rename to src/lms/ui/MediaPlayer.hpp diff --git a/src/ui/PlayHistoryView.cpp b/src/lms/ui/PlayHistoryView.cpp similarity index 100% rename from src/ui/PlayHistoryView.cpp rename to src/lms/ui/PlayHistoryView.cpp diff --git a/src/ui/PlayHistoryView.hpp b/src/lms/ui/PlayHistoryView.hpp similarity index 100% rename from src/ui/PlayHistoryView.hpp rename to src/lms/ui/PlayHistoryView.hpp diff --git a/src/ui/PlayQueueView.cpp b/src/lms/ui/PlayQueueView.cpp similarity index 98% rename from src/ui/PlayQueueView.cpp rename to src/lms/ui/PlayQueueView.cpp index 91dc4c1b..e55476b6 100644 --- a/src/ui/PlayQueueView.cpp +++ b/src/lms/ui/PlayQueueView.cpp @@ -26,7 +26,7 @@ #include "database/Track.hpp" #include "database/TrackList.hpp" #include "database/User.hpp" -#include "similarity/SimilaritySearcher.hpp" +#include "recommendation/IEngine.hpp" #include "utils/Logger.hpp" #include "utils/Random.hpp" #include "utils/Service.hpp" @@ -417,7 +417,7 @@ PlayQueue::addSome() void PlayQueue::enqueueRadioTrack() { - const std::vector trackToAddIds {ServiceProvider::get()->getSimilarTracksFromTrackList(LmsApp->getDbSession(), _tracklistId, 1)}; + const std::vector trackToAddIds {ServiceProvider::get()->getSimilarTracksFromTrackList(LmsApp->getDbSession(), _tracklistId, 1)}; enqueueTracks(trackToAddIds); } diff --git a/src/ui/PlayQueueView.hpp b/src/lms/ui/PlayQueueView.hpp similarity index 100% rename from src/ui/PlayQueueView.hpp rename to src/lms/ui/PlayQueueView.hpp diff --git a/src/ui/SettingsView.cpp b/src/lms/ui/SettingsView.cpp similarity index 94% rename from src/ui/SettingsView.cpp rename to src/lms/ui/SettingsView.cpp index c1b430b6..d5aa9233 100644 --- a/src/ui/SettingsView.cpp +++ b/src/lms/ui/SettingsView.cpp @@ -30,7 +30,7 @@ #include "common/Validators.hpp" #include "common/ValueStringModel.hpp" -#include "auth/PasswordService.hpp" +#include "auth/IPasswordService.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -80,7 +80,7 @@ class SettingsModel : public Wt::WFormModel Database::User::PasswordHash passwordHash; if (!valueText(PasswordField).empty()) - passwordHash = ServiceProvider<::Auth::PasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8()); + passwordHash = ServiceProvider<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8()); auto transaction {LmsApp->getDbSession().createUniqueTransaction()}; @@ -133,18 +133,18 @@ class SettingsModel : public Wt::WFormModel { if (!valueText(PasswordOldField).empty()) { - switch (ServiceProvider<::Auth::PasswordService>::get()->checkUserPassword( + switch (ServiceProvider<::Auth::IPasswordService>::get()->checkUserPassword( LmsApp->getDbSession(), boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()), LmsApp->getUserLoginName(), valueText(PasswordOldField).toUTF8())) { - case ::Auth::PasswordService::PasswordCheckResult::Match: + case ::Auth::IPasswordService::PasswordCheckResult::Match: break; - case ::Auth::PasswordService::PasswordCheckResult::Mismatch: + case ::Auth::IPasswordService::PasswordCheckResult::Mismatch: error = Wt::WString::tr("Lms.Settings.password-bad"); break; - case ::Auth::PasswordService::PasswordCheckResult::Throttled: + case ::Auth::IPasswordService::PasswordCheckResult::Throttled: error = Wt::WString::tr("Lms.password-client-throttled"); break; } @@ -161,7 +161,7 @@ class SettingsModel : public Wt::WFormModel { if (!valueText(PasswordField).empty()) { - if (!ServiceProvider<::Auth::PasswordService>::get()->evaluatePasswordStrength(LmsApp->getUserLoginName(), valueText(PasswordField).toUTF8())) + if (!ServiceProvider<::Auth::IPasswordService>::get()->evaluatePasswordStrength(LmsApp->getUserLoginName(), valueText(PasswordField).toUTF8())) error = Wt::WString::tr("Lms.password-too-weak"); } else diff --git a/src/ui/SettingsView.hpp b/src/lms/ui/SettingsView.hpp similarity index 100% rename from src/ui/SettingsView.hpp rename to src/lms/ui/SettingsView.hpp diff --git a/src/ui/TrackStringUtils.cpp b/src/lms/ui/TrackStringUtils.cpp similarity index 100% rename from src/ui/TrackStringUtils.cpp rename to src/lms/ui/TrackStringUtils.cpp diff --git a/src/ui/TrackStringUtils.hpp b/src/lms/ui/TrackStringUtils.hpp similarity index 100% rename from src/ui/TrackStringUtils.hpp rename to src/lms/ui/TrackStringUtils.hpp diff --git a/src/ui/admin/DatabaseSettingsView.cpp b/src/lms/ui/admin/DatabaseSettingsView.cpp similarity index 100% rename from src/ui/admin/DatabaseSettingsView.cpp rename to src/lms/ui/admin/DatabaseSettingsView.cpp diff --git a/src/ui/admin/DatabaseSettingsView.hpp b/src/lms/ui/admin/DatabaseSettingsView.hpp similarity index 100% rename from src/ui/admin/DatabaseSettingsView.hpp rename to src/lms/ui/admin/DatabaseSettingsView.hpp diff --git a/src/ui/admin/DatabaseStatus.cpp b/src/lms/ui/admin/DatabaseStatus.cpp similarity index 100% rename from src/ui/admin/DatabaseStatus.cpp rename to src/lms/ui/admin/DatabaseStatus.cpp diff --git a/src/ui/admin/DatabaseStatus.hpp b/src/lms/ui/admin/DatabaseStatus.hpp similarity index 100% rename from src/ui/admin/DatabaseStatus.hpp rename to src/lms/ui/admin/DatabaseStatus.hpp diff --git a/src/ui/admin/InitWizardView.cpp b/src/lms/ui/admin/InitWizardView.cpp similarity index 93% rename from src/ui/admin/InitWizardView.cpp rename to src/lms/ui/admin/InitWizardView.cpp index 2eeba3e5..34d7c5fb 100644 --- a/src/ui/admin/InitWizardView.cpp +++ b/src/lms/ui/admin/InitWizardView.cpp @@ -23,7 +23,7 @@ #include #include -#include "auth/PasswordService.hpp" +#include "auth/IPasswordService.hpp" #include "utils/Exception.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -55,7 +55,7 @@ class InitWizardModel : public Wt::WFormModel void saveData() { - const Database::User::PasswordHash passwordHash {ServiceProvider<::Auth::PasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8())}; + const Database::User::PasswordHash passwordHash {ServiceProvider<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8())}; auto transaction(LmsApp->getDbSession().createUniqueTransaction()); @@ -77,7 +77,7 @@ class InitWizardModel : public Wt::WFormModel if (!valueText(PasswordField).empty()) { // Evaluate the strength of the password - if (!ServiceProvider<::Auth::PasswordService>::get()->evaluatePasswordStrength(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8())) + if (!ServiceProvider<::Auth::IPasswordService>::get()->evaluatePasswordStrength(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8())) error = Wt::WString::tr("Lms.password-too-weak"); } else diff --git a/src/ui/admin/InitWizardView.hpp b/src/lms/ui/admin/InitWizardView.hpp similarity index 100% rename from src/ui/admin/InitWizardView.hpp rename to src/lms/ui/admin/InitWizardView.hpp diff --git a/src/ui/admin/UserView.cpp b/src/lms/ui/admin/UserView.cpp similarity index 95% rename from src/ui/admin/UserView.cpp rename to src/lms/ui/admin/UserView.cpp index dc1dd83c..0b4d7556 100644 --- a/src/ui/admin/UserView.cpp +++ b/src/lms/ui/admin/UserView.cpp @@ -28,9 +28,9 @@ #include -#include "auth/PasswordService.hpp" +#include "auth/IPasswordService.hpp" #include "database/User.hpp" -#include "utils/Config.hpp" +#include "utils/IConfig.hpp" #include "utils/Exception.hpp" #include "utils/Logger.hpp" #include "utils/Service.hpp" @@ -82,7 +82,7 @@ class UserModel : public Wt::WFormModel { std::optional passwordHash; if (!valueText(PasswordField).empty()) - passwordHash = ServiceProvider<::Auth::PasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8()); + passwordHash = ServiceProvider<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8()); auto transaction {LmsApp->getDbSession().createUniqueTransaction()}; @@ -174,7 +174,7 @@ class UserModel : public Wt::WFormModel else { // Evaluate the strength of the password for non demo accounts - if (!ServiceProvider<::Auth::PasswordService>::get()->evaluatePasswordStrength(getLoginName(), valueText(PasswordField).toUTF8())) + if (!ServiceProvider<::Auth::IPasswordService>::get()->evaluatePasswordStrength(getLoginName(), valueText(PasswordField).toUTF8())) error = Wt::WString::tr("Lms.password-too-weak"); } } @@ -270,7 +270,7 @@ UserView::refreshView() // Demo account t->setFormWidget(UserModel::DemoField, std::make_unique()); - if (!userId && ServiceProvider::get()->getBool("demo", false)) + if (!userId && ServiceProvider::get()->getBool("demo", false)) t->setCondition("if-demo", true); Wt::WPushButton* saveBtn = t->bindNew("save-btn", Wt::WString::tr(userId ? "Lms.save" : "Lms.create")); diff --git a/src/ui/admin/UserView.hpp b/src/lms/ui/admin/UserView.hpp similarity index 100% rename from src/ui/admin/UserView.hpp rename to src/lms/ui/admin/UserView.hpp diff --git a/src/ui/admin/UsersView.cpp b/src/lms/ui/admin/UsersView.cpp similarity index 100% rename from src/ui/admin/UsersView.cpp rename to src/lms/ui/admin/UsersView.cpp diff --git a/src/ui/admin/UsersView.hpp b/src/lms/ui/admin/UsersView.hpp similarity index 100% rename from src/ui/admin/UsersView.hpp rename to src/lms/ui/admin/UsersView.hpp diff --git a/src/ui/common/Validators.cpp b/src/lms/ui/common/Validators.cpp similarity index 100% rename from src/ui/common/Validators.cpp rename to src/lms/ui/common/Validators.cpp diff --git a/src/ui/common/Validators.hpp b/src/lms/ui/common/Validators.hpp similarity index 100% rename from src/ui/common/Validators.hpp rename to src/lms/ui/common/Validators.hpp diff --git a/src/ui/common/ValueStringModel.hpp b/src/lms/ui/common/ValueStringModel.hpp similarity index 100% rename from src/ui/common/ValueStringModel.hpp rename to src/lms/ui/common/ValueStringModel.hpp diff --git a/src/ui/explore/ArtistInfoView.cpp b/src/lms/ui/explore/ArtistInfoView.cpp similarity index 93% rename from src/ui/explore/ArtistInfoView.cpp rename to src/lms/ui/explore/ArtistInfoView.cpp index 8f806eba..e9d3a3d9 100644 --- a/src/ui/explore/ArtistInfoView.cpp +++ b/src/lms/ui/explore/ArtistInfoView.cpp @@ -20,7 +20,7 @@ #include "ArtistInfoView.hpp" #include "database/Artist.hpp" -#include "similarity/SimilaritySearcher.hpp" +#include "recommendation/IEngine.hpp" #include "utils/Service.hpp" #include "utils/String.hpp" @@ -63,7 +63,7 @@ ArtistInfo::refresh() if (!artistId) return; - const std::vector artistsIds {ServiceProvider::get()->getSimilarArtists(LmsApp->getDbSession(), *artistId, 5)}; + const std::vector artistsIds {ServiceProvider::get()->getSimilarArtists(LmsApp->getDbSession(), *artistId, 5)}; auto transaction {LmsApp->getDbSession().createSharedTransaction()}; diff --git a/src/ui/explore/ArtistInfoView.hpp b/src/lms/ui/explore/ArtistInfoView.hpp similarity index 100% rename from src/ui/explore/ArtistInfoView.hpp rename to src/lms/ui/explore/ArtistInfoView.hpp diff --git a/src/ui/explore/ArtistLink.cpp b/src/lms/ui/explore/ArtistLink.cpp similarity index 100% rename from src/ui/explore/ArtistLink.cpp rename to src/lms/ui/explore/ArtistLink.cpp diff --git a/src/ui/explore/ArtistLink.hpp b/src/lms/ui/explore/ArtistLink.hpp similarity index 100% rename from src/ui/explore/ArtistLink.hpp rename to src/lms/ui/explore/ArtistLink.hpp diff --git a/src/ui/explore/ArtistView.cpp b/src/lms/ui/explore/ArtistView.cpp similarity index 100% rename from src/ui/explore/ArtistView.cpp rename to src/lms/ui/explore/ArtistView.cpp diff --git a/src/ui/explore/ArtistView.hpp b/src/lms/ui/explore/ArtistView.hpp similarity index 100% rename from src/ui/explore/ArtistView.hpp rename to src/lms/ui/explore/ArtistView.hpp diff --git a/src/ui/explore/ArtistsInfoView.cpp b/src/lms/ui/explore/ArtistsInfoView.cpp similarity index 100% rename from src/ui/explore/ArtistsInfoView.cpp rename to src/lms/ui/explore/ArtistsInfoView.cpp diff --git a/src/ui/explore/ArtistsInfoView.hpp b/src/lms/ui/explore/ArtistsInfoView.hpp similarity index 100% rename from src/ui/explore/ArtistsInfoView.hpp rename to src/lms/ui/explore/ArtistsInfoView.hpp diff --git a/src/ui/explore/ArtistsView.cpp b/src/lms/ui/explore/ArtistsView.cpp similarity index 100% rename from src/ui/explore/ArtistsView.cpp rename to src/lms/ui/explore/ArtistsView.cpp diff --git a/src/ui/explore/ArtistsView.hpp b/src/lms/ui/explore/ArtistsView.hpp similarity index 100% rename from src/ui/explore/ArtistsView.hpp rename to src/lms/ui/explore/ArtistsView.hpp diff --git a/src/ui/explore/Explore.cpp b/src/lms/ui/explore/Explore.cpp similarity index 100% rename from src/ui/explore/Explore.cpp rename to src/lms/ui/explore/Explore.cpp diff --git a/src/ui/explore/Explore.hpp b/src/lms/ui/explore/Explore.hpp similarity index 100% rename from src/ui/explore/Explore.hpp rename to src/lms/ui/explore/Explore.hpp diff --git a/src/ui/explore/Filters.cpp b/src/lms/ui/explore/Filters.cpp similarity index 100% rename from src/ui/explore/Filters.cpp rename to src/lms/ui/explore/Filters.cpp diff --git a/src/ui/explore/Filters.hpp b/src/lms/ui/explore/Filters.hpp similarity index 100% rename from src/ui/explore/Filters.hpp rename to src/lms/ui/explore/Filters.hpp diff --git a/src/ui/explore/ReleaseInfoView.cpp b/src/lms/ui/explore/ReleaseInfoView.cpp similarity index 95% rename from src/ui/explore/ReleaseInfoView.cpp rename to src/lms/ui/explore/ReleaseInfoView.cpp index 7293a678..759b20de 100644 --- a/src/ui/explore/ReleaseInfoView.cpp +++ b/src/lms/ui/explore/ReleaseInfoView.cpp @@ -22,7 +22,7 @@ #include #include "database/Release.hpp" -#include "similarity/SimilaritySearcher.hpp" +#include "recommendation/IEngine.hpp" #include "utils/Service.hpp" #include "utils/String.hpp" @@ -68,7 +68,7 @@ ReleaseInfo::refresh() if (!releaseId) return; - const std::vector releasesIds {ServiceProvider::get()->getSimilarReleases(LmsApp->getDbSession(), *releaseId, 5)}; + const std::vector releasesIds {ServiceProvider::get()->getSimilarReleases(LmsApp->getDbSession(), *releaseId, 5)}; auto transaction {LmsApp->getDbSession().createSharedTransaction()}; diff --git a/src/ui/explore/ReleaseInfoView.hpp b/src/lms/ui/explore/ReleaseInfoView.hpp similarity index 100% rename from src/ui/explore/ReleaseInfoView.hpp rename to src/lms/ui/explore/ReleaseInfoView.hpp diff --git a/src/ui/explore/ReleaseLink.cpp b/src/lms/ui/explore/ReleaseLink.cpp similarity index 100% rename from src/ui/explore/ReleaseLink.cpp rename to src/lms/ui/explore/ReleaseLink.cpp diff --git a/src/ui/explore/ReleaseLink.hpp b/src/lms/ui/explore/ReleaseLink.hpp similarity index 100% rename from src/ui/explore/ReleaseLink.hpp rename to src/lms/ui/explore/ReleaseLink.hpp diff --git a/src/ui/explore/ReleaseView.cpp b/src/lms/ui/explore/ReleaseView.cpp similarity index 100% rename from src/ui/explore/ReleaseView.cpp rename to src/lms/ui/explore/ReleaseView.cpp diff --git a/src/ui/explore/ReleaseView.hpp b/src/lms/ui/explore/ReleaseView.hpp similarity index 100% rename from src/ui/explore/ReleaseView.hpp rename to src/lms/ui/explore/ReleaseView.hpp diff --git a/src/ui/explore/ReleasesInfoView.cpp b/src/lms/ui/explore/ReleasesInfoView.cpp similarity index 100% rename from src/ui/explore/ReleasesInfoView.cpp rename to src/lms/ui/explore/ReleasesInfoView.cpp diff --git a/src/ui/explore/ReleasesInfoView.hpp b/src/lms/ui/explore/ReleasesInfoView.hpp similarity index 100% rename from src/ui/explore/ReleasesInfoView.hpp rename to src/lms/ui/explore/ReleasesInfoView.hpp diff --git a/src/ui/explore/ReleasesView.cpp b/src/lms/ui/explore/ReleasesView.cpp similarity index 100% rename from src/ui/explore/ReleasesView.cpp rename to src/lms/ui/explore/ReleasesView.cpp diff --git a/src/ui/explore/ReleasesView.hpp b/src/lms/ui/explore/ReleasesView.hpp similarity index 100% rename from src/ui/explore/ReleasesView.hpp rename to src/lms/ui/explore/ReleasesView.hpp diff --git a/src/ui/explore/TracksInfoView.cpp b/src/lms/ui/explore/TracksInfoView.cpp similarity index 100% rename from src/ui/explore/TracksInfoView.cpp rename to src/lms/ui/explore/TracksInfoView.cpp diff --git a/src/ui/explore/TracksInfoView.hpp b/src/lms/ui/explore/TracksInfoView.hpp similarity index 100% rename from src/ui/explore/TracksInfoView.hpp rename to src/lms/ui/explore/TracksInfoView.hpp diff --git a/src/ui/explore/TracksView.cpp b/src/lms/ui/explore/TracksView.cpp similarity index 100% rename from src/ui/explore/TracksView.cpp rename to src/lms/ui/explore/TracksView.cpp diff --git a/src/ui/explore/TracksView.hpp b/src/lms/ui/explore/TracksView.hpp similarity index 100% rename from src/ui/explore/TracksView.hpp rename to src/lms/ui/explore/TracksView.hpp diff --git a/src/ui/resource/AudioResource.cpp b/src/lms/ui/resource/AudioResource.cpp similarity index 100% rename from src/ui/resource/AudioResource.cpp rename to src/lms/ui/resource/AudioResource.cpp diff --git a/src/ui/resource/AudioResource.hpp b/src/lms/ui/resource/AudioResource.hpp similarity index 100% rename from src/ui/resource/AudioResource.hpp rename to src/lms/ui/resource/AudioResource.hpp diff --git a/src/ui/resource/ImageResource.cpp b/src/lms/ui/resource/ImageResource.cpp similarity index 100% rename from src/ui/resource/ImageResource.cpp rename to src/lms/ui/resource/ImageResource.cpp diff --git a/src/ui/resource/ImageResource.hpp b/src/lms/ui/resource/ImageResource.hpp similarity index 100% rename from src/ui/resource/ImageResource.hpp rename to src/lms/ui/resource/ImageResource.hpp diff --git a/src/similarity/SimilaritySearcher.hpp b/src/similarity/SimilaritySearcher.hpp deleted file mode 100644 index 3a53cb9b..00000000 --- a/src/similarity/SimilaritySearcher.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 . - */ - -#pragma once - -#include -#include - -#include "database/Types.hpp" - -namespace Database -{ - class Session; -} - -namespace Similarity { - -class FeaturesScannerAddon; - -class Searcher -{ - public: - Searcher(FeaturesScannerAddon& somAddon); - - // Closest results first - std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount); - std::vector getSimilarTracks(Database::Session& session, const std::set& tracksId, std::size_t maxCount); - std::vector getSimilarReleases(Database::Session& session, Database::IdType releaseId, std::size_t maxCount); - std::vector getSimilarArtists(Database::Session& session, Database::IdType artistId, std::size_t maxCount); - - private: - - FeaturesScannerAddon& _somAddon; -}; - -} // ns Similarity diff --git a/src/similarity/features/SimilarityFeaturesScannerAddon.hpp b/src/similarity/features/SimilarityFeaturesScannerAddon.hpp deleted file mode 100644 index 38651e37..00000000 --- a/src/similarity/features/SimilarityFeaturesScannerAddon.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2018 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 . - */ - -#pragma once - -#include "database/Session.hpp" -#include "scanner/MediaScannerAddon.hpp" - -#include "utils/UUID.hpp" - -#include "SimilarityFeaturesSearcher.hpp" - - -namespace Database { - class Db; -} - -namespace Similarity { - -class FeaturesScannerAddon final : public Scanner::MediaScannerAddon -{ - public: - - FeaturesScannerAddon(Database::Db& db); - - std::shared_ptr getSearcher(); - - private: - - void refreshSettings() override {} - void requestStop() override; - void preScanComplete() override; - - void trackAdded(Database::IdType) override {} - void trackToRemove(Database::IdType) override {} - void trackUpdated(Database::IdType trackId) override; - - bool fetchFeatures(Database::IdType trackId, const UUID& MBID); - - void updateSearcher(); - - Database::Session _dbSession; - std::shared_ptr _searcher; - bool _stopRequested {}; -}; - -FeaturesScannerAddon* setFeaturesScannerAddon(FeaturesScannerAddon addon); -FeaturesScannerAddon* getFeaturesScannerAddon(); - -} // namespace Similarity - diff --git a/tools/Makefile.am b/src/tools/Makefile.am similarity index 100% rename from tools/Makefile.am rename to src/tools/Makefile.am diff --git a/tools/metadata/LmsMetadata.cpp b/src/tools/metadata/LmsMetadata.cpp similarity index 100% rename from tools/metadata/LmsMetadata.cpp rename to src/tools/metadata/LmsMetadata.cpp diff --git a/tools/metadata/Makefile.am b/src/tools/metadata/Makefile.am similarity index 100% rename from tools/metadata/Makefile.am rename to src/tools/metadata/Makefile.am diff --git a/tools/similarity-parameters/GeneticAlgorithm.hpp b/src/tools/similarity-parameters/GeneticAlgorithm.hpp similarity index 100% rename from tools/similarity-parameters/GeneticAlgorithm.hpp rename to src/tools/similarity-parameters/GeneticAlgorithm.hpp diff --git a/tools/similarity-parameters/LmsSimilarityParameters.cpp b/src/tools/similarity-parameters/LmsSimilarityParameters.cpp similarity index 100% rename from tools/similarity-parameters/LmsSimilarityParameters.cpp rename to src/tools/similarity-parameters/LmsSimilarityParameters.cpp diff --git a/tools/similarity-parameters/Makefile.am b/src/tools/similarity-parameters/Makefile.am similarity index 100% rename from tools/similarity-parameters/Makefile.am rename to src/tools/similarity-parameters/Makefile.am diff --git a/tools/similarity-parameters/ParallelFor.hpp b/src/tools/similarity-parameters/ParallelFor.hpp similarity index 100% rename from tools/similarity-parameters/ParallelFor.hpp rename to src/tools/similarity-parameters/ParallelFor.hpp diff --git a/tools/similarity/LmsSimilarity.cpp b/src/tools/similarity/LmsSimilarity.cpp similarity index 100% rename from tools/similarity/LmsSimilarity.cpp rename to src/tools/similarity/LmsSimilarity.cpp diff --git a/tools/similarity/Makefile.am b/src/tools/similarity/Makefile.am similarity index 100% rename from tools/similarity/Makefile.am rename to src/tools/similarity/Makefile.am