diff --git a/src/ui/approot/templates.xml b/approot/templates.xml similarity index 100% rename from src/ui/approot/templates.xml rename to approot/templates.xml diff --git a/conf/lms.conf.sample b/conf/lms.conf.sample index 01ffec79..d2e3378b 100644 --- a/conf/lms.conf.sample +++ b/conf/lms.conf.sample @@ -26,38 +26,3 @@ main = { } } - -ui = { - resources = { - docroot = "/var/lms/docroot" - approot = "/var/lms/approot" - } - - listen-endpoint = { - port = 5081; - addr = "0.0.0.0"; - } - - ssl-crypto = { - cert = "/var/lms/certs/certUI.pem"; - key = "/var/lms/private/privkeyUI.pem"; - dh = "/var/lms/dh/dh2048.pem"; - } - -} - -remote = { - nb-threads = 1; - - listen-endpoint = { - port = 5080; - addr = "0.0.0.0"; - } - - ssl-crypto = { - cert = "/var/lms/certs/certRemote.pem"; - key = "/var/lms/private/privkeyRemote.pem"; - dh = "/var/lms/dh/dh2048.pem"; - } -} - diff --git a/src/ui/docroot/css/lms.css b/docroot/css/lms.css similarity index 100% rename from src/ui/docroot/css/lms.css rename to docroot/css/lms.css diff --git a/src/ui/docroot/images/unknown-cover.jpg b/docroot/images/unknown-cover.jpg similarity index 100% rename from src/ui/docroot/images/unknown-cover.jpg rename to docroot/images/unknown-cover.jpg diff --git a/src/Makefile.am b/src/Makefile.am index e60d4e1c..c8d3d1d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,6 @@ lms_SOURCES = \ $(srcdir)/metadata/Utils.cpp \ $(srcdir)/service/ServiceManager.cpp \ $(srcdir)/service/DatabaseUpdateService.cpp \ - $(srcdir)/service/UserInterfaceService.cpp \ $(srcdir)/transcode/AvConvTranscoder.cpp \ $(srcdir)/transcode/Format.cpp \ $(srcdir)/transcode/Parameters.cpp \ diff --git a/src/database/DatabaseHandler.cpp b/src/database/DatabaseHandler.cpp index ba5b4883..e21bcf0f 100644 --- a/src/database/DatabaseHandler.cpp +++ b/src/database/DatabaseHandler.cpp @@ -79,6 +79,7 @@ Handler::Handler(Wt::Dbo::SqlConnectionPool& connectionPool) { _session.setConnectionPool(connectionPool); + _session.mapClass("artist"); _session.mapClass("genre"); _session.mapClass("track"); @@ -95,6 +96,8 @@ Handler::Handler(Wt::Dbo::SqlConnectionPool& connectionPool) _session.mapClass("auth_token"); try { + Wt::Dbo::Transaction transaction(_session); + _session.createTables(); _session.execute("CREATE INDEX artist_name_idx ON artist(name)"); _session.execute("CREATE INDEX genre_name_idx ON genre(name)"); diff --git a/src/logger/Logger.cpp b/src/logger/Logger.cpp index 39adccce..fa9a71ad 100644 --- a/src/logger/Logger.cpp +++ b/src/logger/Logger.cpp @@ -81,6 +81,19 @@ Logger::init() boost::log::register_simple_formatter_factory< Severity, char >("Severity"); + if (ConfigReader::instance().getBool("main.logger.console.enable", false)) + { + boost::log::add_console_log(std::cout, + boost::log::keywords::format = ( + boost::log::expressions::stream + << boost::log::expressions::format_date_time< boost::posix_time::ptime >("TimeStamp", "[%Y-%m-%d %H:%M:%S]") + << " [" << boost::log::expressions::attr< Module >("Module") << "]" + << " [" << boost::log::expressions::attr< Severity >("Severity") << "]" + << " " << boost::log::expressions::smessage + ) + ); + } + if (ConfigReader::instance().getBool("main.logger.file.enable", false)) { boost::log::add_file_log @@ -99,19 +112,6 @@ Logger::init() ); } - if (ConfigReader::instance().getBool("main.logger.console.enable", false)) - { - boost::log::add_console_log(std::cout, - boost::log::keywords::format = ( - boost::log::expressions::stream - << boost::log::expressions::format_date_time< boost::posix_time::ptime >("TimeStamp", "[%Y-%m-%d %H:%M:%S]") - << " [" << boost::log::expressions::attr< Module >("Module") << "]" - << " [" << boost::log::expressions::attr< Severity >("Severity") << "]" - << " " << boost::log::expressions::smessage - ) - ); - } - boost::log::core::get()->set_filter ( boost::log::expressions::attr("Severity") <= ConfigReader::instance().getULong("main.logger.level", SEV_DEBUG) diff --git a/src/main/main.cpp b/src/main/main.cpp index 697c727d..8e41efd1 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -26,16 +26,18 @@ #include "logger/Logger.hpp" #include "cover/CoverArtGrabber.hpp" +#include "ui/LmsApplication.hpp" + #include "service/ServiceManager.hpp" #include "service/DatabaseUpdateService.hpp" -#include "service/UserInterfaceService.hpp" #if defined HAVE_LMSAPI #include "service/LmsAPIServerService.hpp" #endif +#include + int main(int argc, char* argv[]) { - int res = EXIT_FAILURE; assert(argc > 0); @@ -43,25 +45,10 @@ int main(int argc, char* argv[]) try { - // TODO generate a nice command line help with args - // Open configuration file - boost::filesystem::path configFile("/etc/lms.conf"); // TODO - if (argc > 1) - configFile = boost::filesystem::path(argv[1]); + boost::filesystem::path configFilePath("/etc/lms.conf"); // TODO use $confdir from autotools - if ( !boost::filesystem::exists(configFile)) - { - std::cerr << "Config file '" << configFile << "' does not exist!" << std::endl; - return EXIT_FAILURE; - } - else if (!boost::filesystem::is_regular(configFile)) - { - std::cerr << "Config file '" << configFile << "' is not regular!" << std::endl; - return EXIT_FAILURE; - } - - ConfigReader::instance().setFile(configFile); + ConfigReader::instance().setFile(configFilePath); Logger::instance().init(); CoverArt::Grabber::instance().init(); @@ -76,17 +63,36 @@ int main(int argc, char* argv[]) // Initializing a connection pool to the database that will be shared along services std::unique_ptr connectionPool( Database::Handler::createConnectionPool( ConfigReader::instance().getString("main.database.path") )); - LMS_LOG(MOD_MAIN, SEV_INFO) << "Starting services..."; - serviceManager.startService( std::make_shared(*connectionPool)); - serviceManager.startService( std::make_shared(boost::filesystem::path(argv[0]), *connectionPool)); + serviceManager.add( std::make_shared(*connectionPool)); + #if defined HAVE_LMSAPI - serviceManager.startService( std::make_shared(*connectionPool)); + serviceManager.add( std::make_shared(*connectionPool)); #endif + Wt::WServer server(argv[0]); + server.setServerConfiguration (argc, argv); + // bind entry point + server.addEntryPoint(Wt::Application, boost::bind(UserInterface::LmsApplication::create, _1, boost::ref(*connectionPool))); + LMS_LOG(MOD_MAIN, SEV_NOTICE) << "Now running..."; - serviceManager.run(); + // Start underlying services + LMS_LOG(MOD_MAIN, SEV_INFO) << "Starting services..."; + serviceManager.start(); + + // Starting the main server + LMS_LOG(MOD_MAIN, SEV_INFO) << "Starting server..."; + server.start(); + + // Waiting for shutdown command + Wt::WServer::waitForShutdown(argv[0]); + + LMS_LOG(MOD_MAIN, SEV_INFO) << "Stopping server..."; + server.stop(); + + LMS_LOG(MOD_MAIN, SEV_INFO) << "Stopping services..."; + serviceManager.stop(); res = EXIT_SUCCESS; } diff --git a/src/service/ServiceManager.cpp b/src/service/ServiceManager.cpp index 83ffbd2b..59469857 100644 --- a/src/service/ServiceManager.cpp +++ b/src/service/ServiceManager.cpp @@ -19,9 +19,6 @@ #include "logger/Logger.hpp" -#include -#include - #include "ServiceManager.hpp" namespace Service { @@ -34,112 +31,51 @@ ServiceManager::instance() } ServiceManager::ServiceManager() -: _signalSet(_ioService) { - _signalSet.add(SIGINT); - _signalSet.add(SIGTERM); -#if defined(SIGQUIT) - _signalSet.add(SIGQUIT); -#endif // defined(SIGQUIT) - - _signalSet.add(SIGHUP); - - // Excplicitely ignore SIGCHLD to avoid zombies - // when avconv child processes are being killed - if (::signal(SIGCHLD, SIG_IGN) == SIG_ERR) - throw std::runtime_error("ServiceManager::ServiceManager, signal failed!"); } ServiceManager::~ServiceManager() { LMS_LOG(MOD_SERVICE, SEV_NOTICE) << "Stopping services..."; - stopServices(); + stop(); } void -ServiceManager::run() -{ - - asyncWaitSignals(); - - LMS_LOG(MOD_SERVICE, SEV_DEBUG) << "ServiceManager: waiting for events..."; - try { - // Wait for events - _ioService.run(); - } - catch( std::exception& e ) - { - LMS_LOG(MOD_SERVICE, SEV_ERROR) << "ServiceManager: exception in ioService::run: " << e.what(); - } - - // Stopping services - stopServices(); - - LMS_LOG(MOD_SERVICE, SEV_DEBUG) << "ServiceManager: run complete !"; -} - -void -ServiceManager::asyncWaitSignals(void) -{ - _signalSet.async_wait(boost::bind(&ServiceManager::handleSignal, - this, - boost::asio::placeholders::error, - boost::asio::placeholders::signal_number)); -} - -void -ServiceManager::startService(Service::pointer service) +ServiceManager::add(Service::pointer service) { _services.insert(service); service->start(); } void -ServiceManager::stopService(Service::pointer service) +ServiceManager::del(Service::pointer service) { - _services.erase(service); service->stop(); + _services.erase(service); } void -ServiceManager::stopServices(void) +ServiceManager::start(void) { - BOOST_FOREACH(Service::pointer service, _services) + for (Service::pointer service : _services) + service->start(); +} + +void +ServiceManager::stop(void) +{ + for (Service::pointer service : _services) service->stop(); } void -ServiceManager::restartServices(void) +ServiceManager::restart(void) { LMS_LOG(MOD_SERVICE, SEV_NOTICE) << "Restarting services..."; - BOOST_FOREACH(Service::pointer service, _services) + for (Service::pointer service : _services) service->restart(); } -void -ServiceManager::handleSignal(boost::system::error_code /*ec*/, int signo) -{ - LMS_LOG(MOD_SERVICE, SEV_INFO) << "Received signal " << signo; - - switch (signo) - { - case SIGINT: - case SIGTERM: - case SIGQUIT: - stopServices(); - - // Do not listen for signals, this will make the ioservice.run return - break; - case SIGHUP: - restartServices(); - - asyncWaitSignals(); - break; - default: - LMS_LOG(MOD_SERVICE, SEV_NOTICE) << "Unhandled signal " << signo; - } -} - } // namespace Service diff --git a/src/service/ServiceManager.hpp b/src/service/ServiceManager.hpp index 8f8704ac..266c850b 100644 --- a/src/service/ServiceManager.hpp +++ b/src/service/ServiceManager.hpp @@ -20,7 +20,6 @@ #ifndef SERVICE_CONTROLER_HPP #define SERVICE_CONTROLER_HPP -#include #include #include "Service.hpp" @@ -35,15 +34,14 @@ class ServiceManager static ServiceManager& instance(); ~ServiceManager(); - void stopService(Service::pointer service); - void startService(Service::pointer service); + void add(Service::pointer service); + void del(Service::pointer service); - void stopAllServices(); + void start(); + void stop(); + void restart(); - // Return in case of failure/stop by user - void run(); - - template typename T::pointer getService(); + template typename T::pointer get(); boost::mutex& mutex() { return _mutex;} @@ -53,32 +51,20 @@ class ServiceManager ServiceManager(ServiceManager const&); // Don't Implement void operator=(ServiceManager const&); // Don't implement - void restartServices(void); - void stopServices(void); - - void asyncWaitSignals(void); - - void handleSignal(boost::system::error_code error, int signo); - boost::mutex _mutex; - boost::asio::io_service _ioService; - - // Listen for interesting signals - boost::asio::signal_set _signalSet; - std::set _services; }; template typename T::pointer -ServiceManager::getService() +ServiceManager::get() { std::set::iterator it; - for (std::set::iterator it = _services.begin(); it != _services.end(); ++it) + for (Service::pointer service : _services) { - if (typeid(*(*it)) == typeid(T)) { - return std::dynamic_pointer_cast(*it); + if (typeid(*(service)) == typeid(T)) { + return std::dynamic_pointer_cast(service); } } return std::shared_ptr(); diff --git a/src/service/UserInterfaceService.cpp b/src/service/UserInterfaceService.cpp deleted file mode 100644 index 2fec2fe1..00000000 --- a/src/service/UserInterfaceService.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2013 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 - -#include "logger/Logger.hpp" - -#include "UserInterfaceService.hpp" -#include "ui/LmsApplication.hpp" - -#include "config/ConfigReader.hpp" - -namespace Service { - -UserInterfaceService::UserInterfaceService( boost::filesystem::path runAppPath, Wt::Dbo::SqlConnectionPool& connectionPool) -: _server(runAppPath.string()) -{ - std::vector args; - - args.push_back(runAppPath.string()); - args.push_back("--docroot=" + ConfigReader::instance().getString("ui.resources.docroot")); - args.push_back("--approot=" + ConfigReader::instance().getString("ui.resources.approot")); - args.push_back("--https-port=" + std::to_string( ConfigReader::instance().getULong("ui.listen-endpoint.port"))); - args.push_back("--https-address=" + ConfigReader::instance().getString("ui.listen-endpoint.addr")); - args.push_back("--ssl-certificate=" + ConfigReader::instance().getString("ui.ssl-crypto.cert")); - args.push_back("--ssl-private-key=" + ConfigReader::instance().getString("ui.ssl-crypto.key")); - args.push_back("--ssl-tmp-dh=" + ConfigReader::instance().getString("ui.ssl-crypto.dh")); - - // Construct argc/argv - int argc = args.size(); - const char* argv[args.size()]; - for (int i = 0; i < argc; ++i) - argv[i] = args[i].c_str(); - - for(int i = 0; i < argc; ++i) - { - LMS_LOG(MOD_SERVICE, SEV_DEBUG) << "i = " << i << ", arg = '" << argv[i] << "'"; - } - - _server.setServerConfiguration (argc, const_cast(argv)); - - // bind entry point - _server.addEntryPoint(Wt::Application, boost::bind(UserInterface::LmsApplication::create, _1, boost::ref(connectionPool))); - -} - -void -UserInterfaceService::start(void) -{ - _server.start(); - LMS_LOG(MOD_SERVICE, SEV_DEBUG) << "UserInterfaceService::start -> Service started..."; -} - -void -UserInterfaceService::stop(void) -{ - LMS_LOG(MOD_SERVICE, SEV_DEBUG) << "UserInterfaceService::stop -> stopping..."; - _server.stop(); - LMS_LOG(MOD_SERVICE, SEV_DEBUG) << "UserInterfaceService::stop -> stopped!"; -} - -void -UserInterfaceService::restart(void) -{ - -} - -} // namespace Service - diff --git a/src/service/UserInterfaceService.hpp b/src/service/UserInterfaceService.hpp deleted file mode 100644 index e9396471..00000000 --- a/src/service/UserInterfaceService.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2013 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 . - */ - -#ifndef WEB_SERVER_SERVICE_HPP -#define WEB_SERVER_SERVICE_HPP - -#include - -#include - -#include "Service.hpp" - -namespace Service { - -class UserInterfaceService : public Service -{ - public: - - UserInterfaceService(boost::filesystem::path runAppPath, Wt::Dbo::SqlConnectionPool& connectionPool); - - void start(void); - void stop(void); - void restart(void); - - private: - - Wt::WServer _server; - -}; - -} //namespace Service - -#endif - diff --git a/src/ui/settings/Settings.cpp b/src/ui/settings/Settings.cpp index 3e6a462e..d884f377 100644 --- a/src/ui/settings/Settings.cpp +++ b/src/ui/settings/Settings.cpp @@ -107,7 +107,7 @@ Settings::restartDatabaseUpdateService() // Restarting the update service boost::lock_guard serviceLock (Service::ServiceManager::instance().mutex()); - Service::DatabaseUpdateService::pointer service = Service::ServiceManager::instance().getService(); + Service::DatabaseUpdateService::pointer service = Service::ServiceManager::instance().get(); if (service) service->restart(); }