Changed the way services are handled
This commit is contained in:
@@ -38,7 +38,7 @@ static std::filesystem::path ffmpegPath;
|
|||||||
void
|
void
|
||||||
Transcoder::init()
|
Transcoder::init()
|
||||||
{
|
{
|
||||||
ffmpegPath = ServiceProvider<IConfig>::get()->getPath("ffmpeg-file", "/usr/bin/ffmpeg");
|
ffmpegPath = Service<IConfig>::get()->getPath("ffmpeg-file", "/usr/bin/ffmpeg");
|
||||||
if (!std::filesystem::exists(ffmpegPath))
|
if (!std::filesystem::exists(ffmpegPath))
|
||||||
throw LmsException {"File '" + ffmpegPath.string() + "' does not exist!"};
|
throw LmsException {"File '" + ffmpegPath.string() + "' does not exist!"};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace Recommendation {
|
|||||||
static
|
static
|
||||||
std::filesystem::path getCacheDirectory()
|
std::filesystem::path getCacheDirectory()
|
||||||
{
|
{
|
||||||
return ServiceProvider<IConfig>::get()->getPath("working-dir") / "cache" / "features";
|
return Service<IConfig>::get()->getPath("working-dir") / "cache" / "features";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::filesystem::path getCacheNetworkFilePath()
|
static std::filesystem::path getCacheNetworkFilePath()
|
||||||
@@ -237,7 +237,7 @@ FeaturesClassifierCache::read()
|
|||||||
void
|
void
|
||||||
FeaturesClassifierCache::write() const
|
FeaturesClassifierCache::write() const
|
||||||
{
|
{
|
||||||
std::filesystem::create_directories(ServiceProvider<IConfig>::get()->getPath("working-dir") / "cache" / "features");
|
std::filesystem::create_directories(Service<IConfig>::get()->getPath("working-dir") / "cache" / "features");
|
||||||
|
|
||||||
if (!networkToCacheFile(_network, getCacheNetworkFilePath())
|
if (!networkToCacheFile(_network, getCacheNetworkFilePath())
|
||||||
|| !objectPositionToCacheFile(_trackPositions, getCacheTrackPositionsFilePath()))
|
|| !objectPositionToCacheFile(_trackPositions, getCacheTrackPositionsFilePath()))
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ getJsonData(const UUID& mbid)
|
|||||||
{
|
{
|
||||||
static const std::string defaultAPIURL = "https://acousticbrainz.org/api/v1/";
|
static const std::string defaultAPIURL = "https://acousticbrainz.org/api/v1/";
|
||||||
|
|
||||||
const std::string url {ServiceProvider<IConfig>::get()->getString("acousticbrainz-api-url", defaultAPIURL) + std::string {mbid.getAsString()} + "/low-level"};
|
const std::string url {Service<IConfig>::get()->getString("acousticbrainz-api-url", defaultAPIURL) + std::string {mbid.getAsString()} + "/low-level"};
|
||||||
|
|
||||||
boost::asio::io_service ioService;
|
boost::asio::io_service ioService;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace API::Subsonic::Scan
|
|||||||
{
|
{
|
||||||
Response::Node statusResponse;
|
Response::Node statusResponse;
|
||||||
|
|
||||||
const IMediaScanner::Status scanStatus {ServiceProvider<IMediaScanner>::get()->getStatus()};
|
const IMediaScanner::Status scanStatus {Service<IMediaScanner>::get()->getStatus()};
|
||||||
|
|
||||||
statusResponse.setAttribute("scanning", scanStatus.currentState == IMediaScanner::State::InProgress);
|
statusResponse.setAttribute("scanning", scanStatus.currentState == IMediaScanner::State::InProgress);
|
||||||
if (scanStatus.currentState == IMediaScanner::State::InProgress)
|
if (scanStatus.currentState == IMediaScanner::State::InProgress)
|
||||||
@@ -61,7 +61,7 @@ namespace API::Subsonic::Scan
|
|||||||
Response
|
Response
|
||||||
handleStartScan(RequestContext& context)
|
handleStartScan(RequestContext& context)
|
||||||
{
|
{
|
||||||
ServiceProvider<IMediaScanner>::get()->requestImmediateScan(false);
|
Service<IMediaScanner>::get()->requestImmediateScan(false);
|
||||||
|
|
||||||
Response response {Response::createOkResponse(context)};
|
Response response {Response::createOkResponse(context)};
|
||||||
response.addNode("scanStatus", createStatusResponseNode());
|
response.addNode("scanStatus", createStatusResponseNode());
|
||||||
|
|||||||
@@ -511,10 +511,10 @@ handleChangePassword(RequestContext& context)
|
|||||||
std::string username {getMandatoryParameterAs<std::string>(context.parameters, "username")};
|
std::string username {getMandatoryParameterAs<std::string>(context.parameters, "username")};
|
||||||
std::string password {decodePasswordIfNeeded(getMandatoryParameterAs<std::string>(context.parameters, "password"))};
|
std::string password {decodePasswordIfNeeded(getMandatoryParameterAs<std::string>(context.parameters, "password"))};
|
||||||
|
|
||||||
if (!ServiceProvider<Auth::IPasswordService>::get()->evaluatePasswordStrength(username, password))
|
if (!Service<Auth::IPasswordService>::get()->evaluatePasswordStrength(username, password))
|
||||||
throw PasswordTooWeakGenericError {};
|
throw PasswordTooWeakGenericError {};
|
||||||
|
|
||||||
const User::PasswordHash hash {ServiceProvider<Auth::IPasswordService>::get()->hashPassword(password)};
|
const User::PasswordHash hash {Service<Auth::IPasswordService>::get()->hashPassword(password)};
|
||||||
|
|
||||||
auto transaction {context.dbSession.createUniqueTransaction()};
|
auto transaction {context.dbSession.createUniqueTransaction()};
|
||||||
|
|
||||||
@@ -593,10 +593,10 @@ handleCreateUserRequest(RequestContext& context)
|
|||||||
std::string password {decodePasswordIfNeeded(getMandatoryParameterAs<std::string>(context.parameters, "password"))};
|
std::string password {decodePasswordIfNeeded(getMandatoryParameterAs<std::string>(context.parameters, "password"))};
|
||||||
// Just ignore all the other fields as we don't handle them
|
// Just ignore all the other fields as we don't handle them
|
||||||
|
|
||||||
if (!ServiceProvider<Auth::IPasswordService>::get()->evaluatePasswordStrength(username, password))
|
if (!Service<Auth::IPasswordService>::get()->evaluatePasswordStrength(username, password))
|
||||||
throw PasswordTooWeakGenericError {};
|
throw PasswordTooWeakGenericError {};
|
||||||
|
|
||||||
const User::PasswordHash hash {ServiceProvider<Auth::IPasswordService>::get()->hashPassword(password)};
|
const User::PasswordHash hash {Service<Auth::IPasswordService>::get()->hashPassword(password)};
|
||||||
|
|
||||||
auto transaction {context.dbSession.createUniqueTransaction()};
|
auto transaction {context.dbSession.createUniqueTransaction()};
|
||||||
|
|
||||||
@@ -878,7 +878,7 @@ handleGetArtistInfoRequestCommon(RequestContext& context, bool id3)
|
|||||||
artistInfoNode.createChild("musicBrainzId").setValue(artistMBID->getAsString());
|
artistInfoNode.createChild("musicBrainzId").setValue(artistMBID->getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto similarArtistsId {ServiceProvider<Recommendation::IEngine>::get()->getSimilarArtists(context.dbSession, id.value, count)};
|
auto similarArtistsId {Service<Recommendation::IEngine>::get()->getSimilarArtists(context.dbSession, id.value, count)};
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction {context.dbSession.createSharedTransaction()};
|
auto transaction {context.dbSession.createSharedTransaction()};
|
||||||
@@ -1107,7 +1107,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3)
|
|||||||
// Optional params
|
// Optional params
|
||||||
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(50)};
|
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(50)};
|
||||||
|
|
||||||
auto similarArtistsId {ServiceProvider<Recommendation::IEngine>::get()->getSimilarArtists(context.dbSession, id.value, 5)};
|
auto similarArtistsId {Service<Recommendation::IEngine>::get()->getSimilarArtists(context.dbSession, id.value, 5)};
|
||||||
|
|
||||||
auto transaction {context.dbSession.createSharedTransaction()};
|
auto transaction {context.dbSession.createSharedTransaction()};
|
||||||
|
|
||||||
@@ -1552,10 +1552,10 @@ handleUpdateUserRequest(RequestContext& context)
|
|||||||
if (password)
|
if (password)
|
||||||
{
|
{
|
||||||
*password = decodePasswordIfNeeded(*password);
|
*password = decodePasswordIfNeeded(*password);
|
||||||
if (!ServiceProvider<Auth::IPasswordService>::get()->evaluatePasswordStrength(username, *password))
|
if (!Service<Auth::IPasswordService>::get()->evaluatePasswordStrength(username, *password))
|
||||||
throw PasswordTooWeakGenericError {};
|
throw PasswordTooWeakGenericError {};
|
||||||
|
|
||||||
hash = ServiceProvider<Auth::IPasswordService>::get()->hashPassword(*password);
|
hash = Service<Auth::IPasswordService>::get()->hashPassword(*password);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto transaction {context.dbSession.createUniqueTransaction()};
|
auto transaction {context.dbSession.createUniqueTransaction()};
|
||||||
@@ -1746,10 +1746,10 @@ handleGetCoverArt(RequestContext& context, const Wt::Http::Request& /*request*/,
|
|||||||
switch (id.type)
|
switch (id.type)
|
||||||
{
|
{
|
||||||
case Id::Type::Track:
|
case Id::Type::Track:
|
||||||
data = ServiceProvider<CoverArt::IGrabber>::get()->getFromTrack(context.dbSession, id.value, CoverArt::Format::JPEG, size);
|
data = Service<CoverArt::IGrabber>::get()->getFromTrack(context.dbSession, id.value, CoverArt::Format::JPEG, size);
|
||||||
break;
|
break;
|
||||||
case Id::Type::Release:
|
case Id::Type::Release:
|
||||||
data = ServiceProvider<CoverArt::IGrabber>::get()->getFromRelease(context.dbSession, id.value, CoverArt::Format::JPEG, size);
|
data = Service<CoverArt::IGrabber>::get()->getFromRelease(context.dbSession, id.value, CoverArt::Format::JPEG, size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw BadParameterGenericError {"id"};
|
throw BadParameterGenericError {"id"};
|
||||||
@@ -1909,7 +1909,7 @@ SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Resp
|
|||||||
|
|
||||||
SessionPool::ScopedSession dbSession {_sessionPool};
|
SessionPool::ScopedSession dbSession {_sessionPool};
|
||||||
|
|
||||||
switch (ServiceProvider<Auth::IPasswordService>::get()->checkUserPassword(dbSession.get(),
|
switch (Service<Auth::IPasswordService>::get()->checkUserPassword(dbSession.get(),
|
||||||
boost::asio::ip::address::from_string(request.clientAddress()),
|
boost::asio::ip::address::from_string(request.clientAddress()),
|
||||||
clientInfo.user, clientInfo.password))
|
clientInfo.user, clientInfo.password))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,5 +82,5 @@ class Logger
|
|||||||
virtual void processLog(const Log& log) = 0;
|
virtual void processLog(const Log& log) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LMS_LOG(module, severity) Log(ServiceProvider<Logger>::get(), Module::module, Severity::severity).getOstream()
|
#define LMS_LOG(module, severity) Log(Service<Logger>::get(), Module::module, Severity::severity).getOstream()
|
||||||
|
|
||||||
|
|||||||
@@ -19,46 +19,44 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
template <typename Class>
|
template <typename Class>
|
||||||
class ServiceProvider
|
class Service
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <class DerivedClass, class ...Args>
|
Service(std::unique_ptr<Class> service)
|
||||||
static
|
|
||||||
Class&
|
|
||||||
create(Args&&... args)
|
|
||||||
{
|
{
|
||||||
static_assert(std::is_base_of<Class, DerivedClass>::value);
|
assign(std::move(service));
|
||||||
|
|
||||||
assign(std::make_unique<DerivedClass>(std::forward<Args>(args)...));
|
|
||||||
return *get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ...Args>
|
~Service()
|
||||||
static
|
|
||||||
Class&
|
|
||||||
create(Args&&... args)
|
|
||||||
{
|
{
|
||||||
assign(std::make_unique<Class>(std::forward<Args>(args)...));
|
clear();
|
||||||
return *get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
Service(const Service&) = delete;
|
||||||
Class&
|
Service(Service&&) = delete;
|
||||||
assign(std::unique_ptr<Class> service)
|
Service& operator=(const Service&) = delete;
|
||||||
{
|
Service& operator=(Service&&) = delete;
|
||||||
_service = std::move(service);
|
|
||||||
return *get();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear() { _service.reset(); }
|
Class* operator->() const
|
||||||
|
{
|
||||||
|
return Service<Class>::get();
|
||||||
|
}
|
||||||
|
|
||||||
static Class* get() { return _service.get(); }
|
static Class* get() { return _service.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static Class& assign(std::unique_ptr<Class> service)
|
||||||
|
{
|
||||||
|
assert(!_service);
|
||||||
|
_service = std::move(service);
|
||||||
|
return *get();
|
||||||
|
}
|
||||||
|
static void clear() { _service.reset(); }
|
||||||
|
|
||||||
static inline std::unique_ptr<Class> _service;
|
static inline std::unique_ptr<Class> _service;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+33
-51
@@ -42,31 +42,31 @@ generateWtConfig(std::string execPath)
|
|||||||
{
|
{
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
|
|
||||||
const std::filesystem::path wtConfigPath {ServiceProvider<IConfig>::get()->getPath("working-dir") / "wt_config.xml"};
|
const std::filesystem::path wtConfigPath {Service<IConfig>::get()->getPath("working-dir") / "wt_config.xml"};
|
||||||
const std::filesystem::path wtLogFilePath {ServiceProvider<IConfig>::get()->getPath("log-file", "/var/log/lms.log")};
|
const std::filesystem::path wtLogFilePath {Service<IConfig>::get()->getPath("log-file", "/var/log/lms.log")};
|
||||||
const std::filesystem::path wtAccessLogFilePath {ServiceProvider<IConfig>::get()->getPath("access-log-file", "/var/log/lms.access.log")};
|
const std::filesystem::path wtAccessLogFilePath {Service<IConfig>::get()->getPath("access-log-file", "/var/log/lms.access.log")};
|
||||||
const std::filesystem::path wtResourcesPath {ServiceProvider<IConfig>::get()->getPath("wt-resources", "/usr/share/Wt/resources")};
|
const std::filesystem::path wtResourcesPath {Service<IConfig>::get()->getPath("wt-resources", "/usr/share/Wt/resources")};
|
||||||
|
|
||||||
args.push_back(execPath);
|
args.push_back(execPath);
|
||||||
args.push_back("--config=" + wtConfigPath.string());
|
args.push_back("--config=" + wtConfigPath.string());
|
||||||
args.push_back("--docroot=" + ServiceProvider<IConfig>::get()->getString("docroot"));
|
args.push_back("--docroot=" + Service<IConfig>::get()->getString("docroot"));
|
||||||
args.push_back("--approot=" + ServiceProvider<IConfig>::get()->getString("approot"));
|
args.push_back("--approot=" + Service<IConfig>::get()->getString("approot"));
|
||||||
args.push_back("--deploy-path=" + ServiceProvider<IConfig>::get()->getString("deploy-path", "/"));
|
args.push_back("--deploy-path=" + Service<IConfig>::get()->getString("deploy-path", "/"));
|
||||||
if (!wtResourcesPath.empty())
|
if (!wtResourcesPath.empty())
|
||||||
args.push_back("--resources-dir=" + wtResourcesPath.string());
|
args.push_back("--resources-dir=" + wtResourcesPath.string());
|
||||||
|
|
||||||
if (ServiceProvider<IConfig>::get()->getBool("tls-enable", false))
|
if (Service<IConfig>::get()->getBool("tls-enable", false))
|
||||||
{
|
{
|
||||||
args.push_back("--https-port=" + std::to_string( ServiceProvider<IConfig>::get()->getULong("listen-port", 5082)));
|
args.push_back("--https-port=" + std::to_string( Service<IConfig>::get()->getULong("listen-port", 5082)));
|
||||||
args.push_back("--https-address=" + ServiceProvider<IConfig>::get()->getString("listen-addr", "0.0.0.0"));
|
args.push_back("--https-address=" + Service<IConfig>::get()->getString("listen-addr", "0.0.0.0"));
|
||||||
args.push_back("--ssl-certificate=" + ServiceProvider<IConfig>::get()->getString("tls-cert"));
|
args.push_back("--ssl-certificate=" + Service<IConfig>::get()->getString("tls-cert"));
|
||||||
args.push_back("--ssl-private-key=" + ServiceProvider<IConfig>::get()->getString("tls-key"));
|
args.push_back("--ssl-private-key=" + Service<IConfig>::get()->getString("tls-key"));
|
||||||
args.push_back("--ssl-tmp-dh=" + ServiceProvider<IConfig>::get()->getString("tls-dh"));
|
args.push_back("--ssl-tmp-dh=" + Service<IConfig>::get()->getString("tls-dh"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args.push_back("--http-port=" + std::to_string( ServiceProvider<IConfig>::get()->getULong("listen-port", 5082)));
|
args.push_back("--http-port=" + std::to_string( Service<IConfig>::get()->getULong("listen-port", 5082)));
|
||||||
args.push_back("--http-address=" + ServiceProvider<IConfig>::get()->getString("listen-addr", "0.0.0.0"));
|
args.push_back("--http-address=" + Service<IConfig>::get()->getString("listen-addr", "0.0.0.0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wtAccessLogFilePath.empty())
|
if (!wtAccessLogFilePath.empty())
|
||||||
@@ -77,8 +77,8 @@ generateWtConfig(std::string execPath)
|
|||||||
|
|
||||||
pt.put("server.application-settings.<xmlattr>.location", "*");
|
pt.put("server.application-settings.<xmlattr>.location", "*");
|
||||||
pt.put("server.application-settings.log-file", wtLogFilePath.string());
|
pt.put("server.application-settings.log-file", wtLogFilePath.string());
|
||||||
pt.put("server.application-settings.log-config", ServiceProvider<IConfig>::get()->getString("log-config", "* -debug -info:WebRequest"));
|
pt.put("server.application-settings.log-config", Service<IConfig>::get()->getString("log-config", "* -debug -info:WebRequest"));
|
||||||
pt.put("server.application-settings.behind-reverse-proxy", ServiceProvider<IConfig>::get()->getBool("behind-reverse-proxy", false));
|
pt.put("server.application-settings.behind-reverse-proxy", Service<IConfig>::get()->getBool("behind-reverse-proxy", false));
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::property_tree::ptree viewport;
|
boost::property_tree::ptree viewport;
|
||||||
@@ -132,12 +132,12 @@ int main(int argc, char* argv[])
|
|||||||
// Make pstream work with ffmpeg
|
// Make pstream work with ffmpeg
|
||||||
close(STDIN_FILENO);
|
close(STDIN_FILENO);
|
||||||
|
|
||||||
ServiceProvider<IConfig>::assign(createConfig(configFilePath));
|
Service<IConfig> config {createConfig(configFilePath)};
|
||||||
ServiceProvider<Logger>::create<WtLogger>();
|
Service<Logger> logger {std::make_unique<WtLogger>()};
|
||||||
|
|
||||||
// Make sure the working directory exists
|
// Make sure the working directory exists
|
||||||
std::filesystem::create_directories(ServiceProvider<IConfig>::get()->getPath("working-dir"));
|
std::filesystem::create_directories(config->getPath("working-dir"));
|
||||||
std::filesystem::create_directories(ServiceProvider<IConfig>::get()->getPath("working-dir") / "cache");
|
std::filesystem::create_directories(config->getPath("working-dir") / "cache");
|
||||||
|
|
||||||
// Construct WT configuration and get the argc/argv back
|
// Construct WT configuration and get the argc/argv back
|
||||||
std::vector<std::string> wtServerArgs = generateWtConfig(argv[0]);
|
std::vector<std::string> wtServerArgs = generateWtConfig(argv[0]);
|
||||||
@@ -156,7 +156,7 @@ int main(int argc, char* argv[])
|
|||||||
Av::Transcoder::init();
|
Av::Transcoder::init();
|
||||||
|
|
||||||
// Initializing a connection pool to the database that will be shared along services
|
// Initializing a connection pool to the database that will be shared along services
|
||||||
Database::Db database {ServiceProvider<IConfig>::get()->getPath("working-dir") / "lms.db"};
|
Database::Db database {config->getPath("working-dir") / "lms.db"};
|
||||||
{
|
{
|
||||||
Database::Session session {database};
|
Database::Session session {database};
|
||||||
session.prepareTables();
|
session.prepareTables();
|
||||||
@@ -166,22 +166,21 @@ int main(int argc, char* argv[])
|
|||||||
UserInterface::LmsApplicationGroupContainer appGroups;
|
UserInterface::LmsApplicationGroupContainer appGroups;
|
||||||
|
|
||||||
// Service initialization order is important
|
// Service initialization order is important
|
||||||
ServiceProvider<Auth::IAuthTokenService>::assign(Auth::createAuthTokenService(ServiceProvider<IConfig>::get()->getULong("login-throttler-max-entriees", 10000)));
|
Service<Auth::IAuthTokenService> authTokenService {Auth::createAuthTokenService(config->getULong("login-throttler-max-entriees", 10000))};
|
||||||
ServiceProvider<Auth::IPasswordService>::assign(Auth::createPasswordService(ServiceProvider<IConfig>::get()->getULong("login-throttler-max-entriees", 10000)));
|
Service<Auth::IPasswordService> passwordService {Auth::createPasswordService(config->getULong("login-throttler-max-entriees", 10000))};
|
||||||
Scanner::IMediaScanner& mediaScanner {ServiceProvider<Scanner::IMediaScanner>::assign(Scanner::createMediaScanner(database))};
|
Service<CoverArt::IGrabber> coverArtService {CoverArt::createGrabber(argv[0])};
|
||||||
|
coverArtService->setDefaultCover(server.appRoot() + "/images/unknown-cover.jpg");
|
||||||
|
Service<Recommendation::IEngine> recommendationEngineService {Recommendation::createEngine(database)};
|
||||||
|
Service<Scanner::IMediaScanner> mediaScannerService {Scanner::createMediaScanner(database)};
|
||||||
|
|
||||||
Recommendation::IEngine& recommendationEngine {ServiceProvider<Recommendation::IEngine>::assign(Recommendation::createEngine(database))};
|
mediaScannerService->scanComplete().connect([&]()
|
||||||
CoverArt::IGrabber& coverArtGrabber {ServiceProvider<CoverArt::IGrabber>::assign(CoverArt::createGrabber(argv[0]))};
|
|
||||||
coverArtGrabber.setDefaultCover(server.appRoot() + "/images/unknown-cover.jpg");
|
|
||||||
|
|
||||||
mediaScanner.scanComplete().connect([&]()
|
|
||||||
{
|
{
|
||||||
auto status = mediaScanner.getStatus();
|
auto status = mediaScannerService->getStatus();
|
||||||
|
|
||||||
if (status.lastCompleteScanStats->nbChanges() > 0 || status.lastCompleteScanStats->featuresFetched > 0)
|
if (status.lastCompleteScanStats->nbChanges() > 0 || status.lastCompleteScanStats->featuresFetched > 0)
|
||||||
{
|
{
|
||||||
LMS_LOG(MAIN, INFO) << "Scanner changed some files, reloading the recommendation engine...";
|
LMS_LOG(MAIN, INFO) << "Scanner changed some files, reloading the recommendation engine...";
|
||||||
recommendationEngine.requestReload();
|
recommendationEngineService->requestReload();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -189,13 +188,13 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
// Flush cover cache even if no changes:
|
// Flush cover cache even if no changes:
|
||||||
// covers may be external files that changed and we don't keep track of them
|
// covers may be external files that changed and we don't keep track of them
|
||||||
coverArtGrabber.flushCache();
|
coverArtService->flushCache();
|
||||||
});
|
});
|
||||||
|
|
||||||
API::Subsonic::SubsonicResource subsonicResource {database};
|
API::Subsonic::SubsonicResource subsonicResource {database};
|
||||||
|
|
||||||
// bind API resources
|
// bind API resources
|
||||||
if (ServiceProvider<IConfig>::get()->getBool("api-subsonic", true))
|
if (config->getBool("api-subsonic", true))
|
||||||
server.addResource(&subsonicResource, subsonicResource.getPath());
|
server.addResource(&subsonicResource, subsonicResource.getPath());
|
||||||
|
|
||||||
// bind UI entry point
|
// bind UI entry point
|
||||||
@@ -203,32 +202,15 @@ int main(int argc, char* argv[])
|
|||||||
std::bind(UserInterface::LmsApplication::create,
|
std::bind(UserInterface::LmsApplication::create,
|
||||||
std::placeholders::_1, std::ref(database), std::ref(appGroups)));
|
std::placeholders::_1, std::ref(database), std::ref(appGroups)));
|
||||||
|
|
||||||
// Start
|
|
||||||
LMS_LOG(MAIN, INFO) << "Starting recommendation engine";
|
|
||||||
recommendationEngine.start();
|
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Starting media scanner...";
|
|
||||||
mediaScanner.start();
|
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Starting server...";
|
LMS_LOG(MAIN, INFO) << "Starting server...";
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
// Wait
|
|
||||||
LMS_LOG(MAIN, INFO) << "Now running...";
|
LMS_LOG(MAIN, INFO) << "Now running...";
|
||||||
Wt::WServer::waitForShutdown();
|
Wt::WServer::waitForShutdown();
|
||||||
|
|
||||||
// Stop
|
|
||||||
LMS_LOG(MAIN, INFO) << "Stopping server...";
|
LMS_LOG(MAIN, INFO) << "Stopping server...";
|
||||||
server.stop();
|
server.stop();
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Stopping media scanner...";
|
|
||||||
mediaScanner.stop();
|
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Stopping recommendation engine...";
|
|
||||||
recommendationEngine.stop();
|
|
||||||
|
|
||||||
ServiceProvider<CoverArt::IGrabber>::clear();
|
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Clean stop!";
|
LMS_LOG(MAIN, INFO) << "Clean stop!";
|
||||||
res = EXIT_SUCCESS;
|
res = EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -43,7 +43,7 @@ static
|
|||||||
void
|
void
|
||||||
createAuthToken(Database::IdType userId, const Wt::WDateTime& expiry)
|
createAuthToken(Database::IdType userId, const Wt::WDateTime& expiry)
|
||||||
{
|
{
|
||||||
const std::string secret {ServiceProvider<::Auth::IAuthTokenService>::get()->createAuthToken(LmsApp->getDbSession(), userId, expiry)};
|
const std::string secret {Service<::Auth::IAuthTokenService>::get()->createAuthToken(LmsApp->getDbSession(), userId, expiry)};
|
||||||
|
|
||||||
LmsApp->setCookie(authCookieName,
|
LmsApp->setCookie(authCookieName,
|
||||||
secret,
|
secret,
|
||||||
@@ -61,7 +61,7 @@ processAuthToken(const Wt::WEnvironment& env)
|
|||||||
if (!authCookie)
|
if (!authCookie)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
const auto res {ServiceProvider<::Auth::IAuthTokenService>::get()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)};
|
const auto res {Service<::Auth::IAuthTokenService>::get()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)};
|
||||||
switch (res.state)
|
switch (res.state)
|
||||||
{
|
{
|
||||||
case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::NotFound:
|
case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::NotFound:
|
||||||
@@ -124,7 +124,7 @@ class AuthModel : public Wt::WFormModel
|
|||||||
|
|
||||||
if (field == PasswordField)
|
if (field == PasswordField)
|
||||||
{
|
{
|
||||||
switch (ServiceProvider<::Auth::IPasswordService>::get()->checkUserPassword(
|
switch (Service<::Auth::IPasswordService>::get()->checkUserPassword(
|
||||||
LmsApp->getDbSession(),
|
LmsApp->getDbSession(),
|
||||||
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
||||||
valueText(LoginNameField).toUTF8(),
|
valueText(LoginNameField).toUTF8(),
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ LmsApplication::createHome()
|
|||||||
{
|
{
|
||||||
const std::string sessionId {LmsApp->sessionId()};
|
const std::string sessionId {LmsApp->sessionId()};
|
||||||
|
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->scanStarted().connect(this, [=] ()
|
Service<Scanner::IMediaScanner>::get()->scanStarted().connect(this, [=] ()
|
||||||
{
|
{
|
||||||
Wt::WServer::instance()->post(sessionId, [=]
|
Wt::WServer::instance()->post(sessionId, [=]
|
||||||
{
|
{
|
||||||
@@ -539,7 +539,7 @@ LmsApplication::createHome()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->scanComplete().connect(this, [=] ()
|
Service<Scanner::IMediaScanner>::get()->scanComplete().connect(this, [=] ()
|
||||||
{
|
{
|
||||||
Wt::WServer::instance()->post(sessionId, [=]
|
Wt::WServer::instance()->post(sessionId, [=]
|
||||||
{
|
{
|
||||||
@@ -548,7 +548,7 @@ LmsApplication::createHome()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->scanInProgress().connect(this, [=] (Scanner::ScanStepStats stepStats)
|
Service<Scanner::IMediaScanner>::get()->scanInProgress().connect(this, [=] (Scanner::ScanStepStats stepStats)
|
||||||
{
|
{
|
||||||
Wt::WServer::instance()->post(sessionId, [=]
|
Wt::WServer::instance()->post(sessionId, [=]
|
||||||
{
|
{
|
||||||
@@ -557,7 +557,7 @@ LmsApplication::createHome()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->scheduled().connect(this, [=] (Wt::WDateTime dateTime)
|
Service<Scanner::IMediaScanner>::get()->scheduled().connect(this, [=] (Wt::WDateTime dateTime)
|
||||||
{
|
{
|
||||||
Wt::WServer::instance()->post(sessionId, [=]
|
Wt::WServer::instance()->post(sessionId, [=]
|
||||||
{
|
{
|
||||||
@@ -572,7 +572,7 @@ LmsApplication::createHome()
|
|||||||
{
|
{
|
||||||
if (isUserAdmin())
|
if (isUserAdmin())
|
||||||
{
|
{
|
||||||
const auto& stats {*ServiceProvider<Scanner::IMediaScanner>::get()->getStatus().lastCompleteScanStats};
|
const auto& stats {*Service<Scanner::IMediaScanner>::get()->getStatus().lastCompleteScanStats};
|
||||||
|
|
||||||
notifyMsg(MsgType::Info, Wt::WString::tr("Lms.Admin.Database.scan-complete")
|
notifyMsg(MsgType::Info, Wt::WString::tr("Lms.Admin.Database.scan-complete")
|
||||||
.arg(static_cast<unsigned>(stats.nbFiles()))
|
.arg(static_cast<unsigned>(stats.nbFiles()))
|
||||||
|
|||||||
@@ -500,7 +500,7 @@ PlayQueue::addSome()
|
|||||||
void
|
void
|
||||||
PlayQueue::enqueueRadioTrack()
|
PlayQueue::enqueueRadioTrack()
|
||||||
{
|
{
|
||||||
const std::vector<Database::IdType> trackToAddIds {ServiceProvider<Recommendation::IEngine>::get()->getSimilarTracksFromTrackList(LmsApp->getDbSession(), _tracklistId, 1)};
|
const std::vector<Database::IdType> trackToAddIds {Service<Recommendation::IEngine>::get()->getSimilarTracksFromTrackList(LmsApp->getDbSession(), _tracklistId, 1)};
|
||||||
enqueueTracks(trackToAddIds);
|
enqueueTracks(trackToAddIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class SettingsModel : public Wt::WFormModel
|
|||||||
User::PasswordHash passwordHash;
|
User::PasswordHash passwordHash;
|
||||||
|
|
||||||
if (!valueText(PasswordField).empty())
|
if (!valueText(PasswordField).empty())
|
||||||
passwordHash = ServiceProvider<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8());
|
passwordHash = Service<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8());
|
||||||
|
|
||||||
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
|
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ class SettingsModel : public Wt::WFormModel
|
|||||||
{
|
{
|
||||||
if (!valueText(PasswordOldField).empty())
|
if (!valueText(PasswordOldField).empty())
|
||||||
{
|
{
|
||||||
switch (ServiceProvider<::Auth::IPasswordService>::get()->checkUserPassword(
|
switch (Service<::Auth::IPasswordService>::get()->checkUserPassword(
|
||||||
LmsApp->getDbSession(),
|
LmsApp->getDbSession(),
|
||||||
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
||||||
LmsApp->getUserLoginName(),
|
LmsApp->getUserLoginName(),
|
||||||
@@ -271,7 +271,7 @@ class SettingsModel : public Wt::WFormModel
|
|||||||
{
|
{
|
||||||
if (!valueText(PasswordField).empty())
|
if (!valueText(PasswordField).empty())
|
||||||
{
|
{
|
||||||
if (!ServiceProvider<::Auth::IPasswordService>::get()->evaluatePasswordStrength(LmsApp->getUserLoginName(), valueText(PasswordField).toUTF8()))
|
if (!Service<::Auth::IPasswordService>::get()->evaluatePasswordStrength(LmsApp->getUserLoginName(), valueText(PasswordField).toUTF8()))
|
||||||
error = Wt::WString::tr("Lms.password-too-weak");
|
error = Wt::WString::tr("Lms.password-too-weak");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -468,7 +468,7 @@ SettingsView::refreshView()
|
|||||||
|
|
||||||
// Subsonic
|
// Subsonic
|
||||||
{
|
{
|
||||||
t->setCondition("if-has-subsonic-api", ServiceProvider<IConfig>::get()->getBool("api-subsonic", true));
|
t->setCondition("if-has-subsonic-api", Service<IConfig>::get()->getBool("api-subsonic", true));
|
||||||
|
|
||||||
// Transcode
|
// Transcode
|
||||||
auto transcode {std::make_unique<Wt::WCheckBox>()};
|
auto transcode {std::make_unique<Wt::WCheckBox>()};
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ DatabaseSettingsView::refreshView()
|
|||||||
{
|
{
|
||||||
model->saveData();
|
model->saveData();
|
||||||
|
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->requestReload();
|
Service<Scanner::IMediaScanner>::get()->requestReload();
|
||||||
LmsApp->notifyMsg(MsgType::Success, Wt::WString::tr("Lms.Admin.Database.settings-saved"));
|
LmsApp->notifyMsg(MsgType::Success, Wt::WString::tr("Lms.Admin.Database.settings-saved"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ DatabaseSettingsView::refreshView()
|
|||||||
|
|
||||||
immScanBtn->clicked().connect([=] ()
|
immScanBtn->clicked().connect([=] ()
|
||||||
{
|
{
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->requestImmediateScan(false);
|
Service<Scanner::IMediaScanner>::get()->requestImmediateScan(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
t->updateView(model.get());
|
t->updateView(model.get());
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class InitWizardModel : public Wt::WFormModel
|
|||||||
|
|
||||||
void saveData()
|
void saveData()
|
||||||
{
|
{
|
||||||
const Database::User::PasswordHash passwordHash {ServiceProvider<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8())};
|
const Database::User::PasswordHash passwordHash {Service<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8())};
|
||||||
|
|
||||||
auto transaction(LmsApp->getDbSession().createUniqueTransaction());
|
auto transaction(LmsApp->getDbSession().createUniqueTransaction());
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ class InitWizardModel : public Wt::WFormModel
|
|||||||
if (!valueText(PasswordField).empty())
|
if (!valueText(PasswordField).empty())
|
||||||
{
|
{
|
||||||
// Evaluate the strength of the password
|
// Evaluate the strength of the password
|
||||||
if (!ServiceProvider<::Auth::IPasswordService>::get()->evaluatePasswordStrength(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8()))
|
if (!Service<::Auth::IPasswordService>::get()->evaluatePasswordStrength(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8()))
|
||||||
error = Wt::WString::tr("Lms.password-too-weak");
|
error = Wt::WString::tr("Lms.password-too-weak");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -146,20 +146,20 @@ ScannerController::refreshContents()
|
|||||||
actionBtn->actionButton()->setText(Wt::WString::tr("Lms.Admin.ScannerController.scan-now"));
|
actionBtn->actionButton()->setText(Wt::WString::tr("Lms.Admin.ScannerController.scan-now"));
|
||||||
actionBtn->actionButton()->clicked().connect([]
|
actionBtn->actionButton()->clicked().connect([]
|
||||||
{
|
{
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->requestImmediateScan(false);
|
Service<Scanner::IMediaScanner>::get()->requestImmediateScan(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto popup = std::make_unique<Wt::WPopupMenu>();
|
auto popup = std::make_unique<Wt::WPopupMenu>();
|
||||||
popup->addItem(Wt::WString::tr("Lms.Admin.ScannerController.force-scan-now"));
|
popup->addItem(Wt::WString::tr("Lms.Admin.ScannerController.force-scan-now"));
|
||||||
popup->itemSelected().connect([]
|
popup->itemSelected().connect([]
|
||||||
{
|
{
|
||||||
ServiceProvider<Scanner::IMediaScanner>::get()->requestImmediateScan(true);
|
Service<Scanner::IMediaScanner>::get()->requestImmediateScan(true);
|
||||||
});
|
});
|
||||||
actionBtn->dropDownButton()->setMenu(std::move(popup));
|
actionBtn->dropDownButton()->setMenu(std::move(popup));
|
||||||
actionBtn->dropDownButton()->addStyleClass("btn-primary");
|
actionBtn->dropDownButton()->addStyleClass("btn-primary");
|
||||||
|
|
||||||
|
|
||||||
const IMediaScanner::Status status {ServiceProvider<IMediaScanner>::get()->getStatus()};
|
const IMediaScanner::Status status {Service<IMediaScanner>::get()->getStatus()};
|
||||||
if (status.lastCompleteScanStats)
|
if (status.lastCompleteScanStats)
|
||||||
{
|
{
|
||||||
bindString("last-scan", Wt::WString::tr("Lms.Admin.ScannerController.last-scan-status")
|
bindString("last-scan", Wt::WString::tr("Lms.Admin.ScannerController.last-scan-status")
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class UserModel : public Wt::WFormModel
|
|||||||
{
|
{
|
||||||
std::optional<Database::User::PasswordHash> passwordHash;
|
std::optional<Database::User::PasswordHash> passwordHash;
|
||||||
if (!valueText(PasswordField).empty())
|
if (!valueText(PasswordField).empty())
|
||||||
passwordHash = ServiceProvider<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8());
|
passwordHash = Service<::Auth::IPasswordService>::get()->hashPassword(valueText(PasswordField).toUTF8());
|
||||||
|
|
||||||
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
|
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ class UserModel : public Wt::WFormModel
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Evaluate the strength of the password for non demo accounts
|
// Evaluate the strength of the password for non demo accounts
|
||||||
if (!ServiceProvider<::Auth::IPasswordService>::get()->evaluatePasswordStrength(getLoginName(), valueText(PasswordField).toUTF8()))
|
if (!Service<::Auth::IPasswordService>::get()->evaluatePasswordStrength(getLoginName(), valueText(PasswordField).toUTF8()))
|
||||||
error = Wt::WString::tr("Lms.password-too-weak");
|
error = Wt::WString::tr("Lms.password-too-weak");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ UserView::refreshView()
|
|||||||
|
|
||||||
// Demo account
|
// Demo account
|
||||||
t->setFormWidget(UserModel::DemoField, std::make_unique<Wt::WCheckBox>());
|
t->setFormWidget(UserModel::DemoField, std::make_unique<Wt::WCheckBox>());
|
||||||
if (!userId && ServiceProvider<IConfig>::get()->getBool("demo", false))
|
if (!userId && Service<IConfig>::get()->getBool("demo", false))
|
||||||
t->setCondition("if-demo", true);
|
t->setCondition("if-demo", true);
|
||||||
|
|
||||||
Wt::WPushButton* saveBtn = t->bindNew<Wt::WPushButton>("save-btn", Wt::WString::tr(userId ? "Lms.save" : "Lms.create"));
|
Wt::WPushButton* saveBtn = t->bindNew<Wt::WPushButton>("save-btn", Wt::WString::tr(userId ? "Lms.save" : "Lms.create"));
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ createAuthModeModel()
|
|||||||
{
|
{
|
||||||
auto model {std::make_unique<AuthModeModel>()};
|
auto model {std::make_unique<AuthModeModel>()};
|
||||||
|
|
||||||
if (ServiceProvider<::Auth::IPasswordService>::get()->isAuthModeSupported(Database::User::AuthMode::Internal))
|
if (Service<::Auth::IPasswordService>::get()->isAuthModeSupported(Database::User::AuthMode::Internal))
|
||||||
model->add(Wt::WString::tr("Lms.Admin.User.auth-mode.internal"), Database::User::AuthMode::Internal);
|
model->add(Wt::WString::tr("Lms.Admin.User.auth-mode.internal"), Database::User::AuthMode::Internal);
|
||||||
if (ServiceProvider<::Auth::IPasswordService>::get()->isAuthModeSupported(Database::User::AuthMode::PAM))
|
if (Service<::Auth::IPasswordService>::get()->isAuthModeSupported(Database::User::AuthMode::PAM))
|
||||||
model->add(Wt::WString::tr("Lms.Admin.User.auth-mode.pam"), Database::User::AuthMode::PAM);
|
model->add(Wt::WString::tr("Lms.Admin.User.auth-mode.pam"), Database::User::AuthMode::PAM);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ Artist::refreshView()
|
|||||||
if (!artistId)
|
if (!artistId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::vector<Database::IdType> similarArtistIds {ServiceProvider<Recommendation::IEngine>::get()->getSimilarArtists(LmsApp->getDbSession(), *artistId, 5)};
|
const std::vector<Database::IdType> similarArtistIds {Service<Recommendation::IEngine>::get()->getSimilarArtists(LmsApp->getDbSession(), *artistId, 5)};
|
||||||
|
|
||||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ Release::refreshView()
|
|||||||
if (!releaseId)
|
if (!releaseId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::vector<Database::IdType> similarReleasesIds {ServiceProvider<Recommendation::IEngine>::get()->getSimilarReleases(LmsApp->getDbSession(), *releaseId, 6)};
|
const std::vector<Database::IdType> similarReleasesIds {Service<Recommendation::IEngine>::get()->getSimilarReleases(LmsApp->getDbSession(), *releaseId, 6)};
|
||||||
|
|
||||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
// DbSession are not thread safe
|
// DbSession are not thread safe
|
||||||
{
|
{
|
||||||
Wt::WApplication::UpdateLock lock {LmsApp};
|
Wt::WApplication::UpdateLock lock {LmsApp};
|
||||||
cover = ServiceProvider<CoverArt::IGrabber>::get()->getFromTrack(LmsApp->getDbSession(), *trackId, CoverArt::Format::JPEG, *size);
|
cover = Service<CoverArt::IGrabber>::get()->getFromTrack(LmsApp->getDbSession(), *trackId, CoverArt::Format::JPEG, *size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (releaseIdStr)
|
else if (releaseIdStr)
|
||||||
@@ -104,7 +104,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
// DbSession are not thread safe
|
// DbSession are not thread safe
|
||||||
{
|
{
|
||||||
Wt::WApplication::UpdateLock lock {LmsApp};
|
Wt::WApplication::UpdateLock lock {LmsApp};
|
||||||
cover = ServiceProvider<CoverArt::IGrabber>::get()->getFromRelease(LmsApp->getDbSession(), *releaseId, CoverArt::Format::JPEG, *size);
|
cover = Service<CoverArt::IGrabber>::get()->getFromRelease(LmsApp->getDbSession(), *releaseId, CoverArt::Format::JPEG, *size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1882,7 +1882,7 @@ int main()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// log to stdout
|
// log to stdout
|
||||||
ServiceProvider<Logger>::create<StreamLogger>(std::cout);
|
Service<Logger> logger {std::make_unique<StreamLogger>(std::cout)};
|
||||||
|
|
||||||
const std::filesystem::path tmpFile {std::tmpnam(nullptr)};
|
const std::filesystem::path tmpFile {std::tmpnam(nullptr)};
|
||||||
ScopedFileDeleter tmpFileDeleter {tmpFile};
|
ScopedFileDeleter tmpFileDeleter {tmpFile};
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// log to stdout
|
// log to stdout
|
||||||
ServiceProvider<Logger>::create<StreamLogger>(std::cout);
|
Service<Logger> logger {std::make_unique<StreamLogger>(std::cout)};
|
||||||
|
|
||||||
for (std::size_t i {}; i < static_cast<std::size_t>(argc - 1); ++i)
|
for (std::size_t i {}; i < static_cast<std::size_t>(argc - 1); ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,15 +131,15 @@ int main(int argc, char *argv[])
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// log to stdout
|
// log to stdout
|
||||||
ServiceProvider<Logger>::create<StreamLogger>(std::cout);
|
Service<Logger> logger {std::make_unique<StreamLogger>(std::cout)};
|
||||||
|
|
||||||
std::filesystem::path configFilePath {"/etc/lms.conf"};
|
std::filesystem::path configFilePath {"/etc/lms.conf"};
|
||||||
if (argc >= 2)
|
if (argc >= 2)
|
||||||
configFilePath = std::string(argv[1], 0, 256);
|
configFilePath = std::string(argv[1], 0, 256);
|
||||||
|
|
||||||
ServiceProvider<IConfig>::assign(createConfig(configFilePath));
|
Service<IConfig> config {createConfig(configFilePath)};
|
||||||
|
|
||||||
Database::Db db {ServiceProvider<IConfig>::get()->getPath("working-dir") / "lms.db"};
|
Database::Db db {config->getPath("working-dir") / "lms.db"};
|
||||||
Database::Session session {db};
|
Database::Session session {db};
|
||||||
|
|
||||||
std::cout << "Creating recommendation engine..." << std::endl;
|
std::cout << "Creating recommendation engine..." << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user