diff --git a/README.md b/README.md
index dd3cf954..d60a242d 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,8 @@ $ apt-get install g++ autoconf automake libboost-dev libboost-locale-dev libboos
## Build
```sh
+$ git clone https://github.com/epoupon/lms.git lms
+$ cd lms
$ autoreconf -vfi
$ mkdir build
$ cd build
@@ -52,51 +54,25 @@ $ make install
This command requires root privileges
## Configuration
-LMS uses a config file for low level settings:
-- database file path, default is /var/lms/lms.db
-- TLS settings, default is none
-- listen address/port, default is 0.0.0.0 port 5081
+LMS uses a configuration file, installed in '/etc/lms.conf'
+It is recommended to edit this file and change the relevant settings (working directory, listen port, etc.)
Other settings are set using the web interface.
-By default, LMS will read its configuration in the file '/etc/lms.conf'
+
+It is highly recommended to run LMS as a non root user. Therefore make sure the user has write permissions on the working directory.
## Running
```sh
-$ /usr/bin/lms [config_file]
+$ lms [config_file]
```
-LMS needs write access to the directory used for the database.
-It is highly recommended to run LMS as a non root user.
+Logs are output in the working directory, in the file 'lms.log'
To connect to LMS, just open your favorite browser and go to http://localhost:5081
-## Mobile
-
-Add the following code in your /etc/wt/wt_config.xml file:
-```
-
- true
-
-```
-
-## Setting up SSL materials (optional)
-Here is just a self signed certificate example, you could do use a CA if you want.
-
-Generate a dh file:
-```sh
-$ openssl dhparam -out dh2048.pem 2048
-```
-Generate a self signed certificate:
-```sh
-$ openssl req -x509 -out cert.pem -keyout privkey.pem -newkey rsa:4096
-```
-Depending on your SSL parameters, you may be asked for the PEM passphrase to unlock the private key.
-
-To connect to LMS, just open your favorite browser and go to https://localhost:5081
-
## Credits
- Wt (http://www.webtoolkit.eu/)
- bootstrap3 (http://getbootstrap.com/)
-- libav project (https://www.libav.org/)
+- ffmpeg project (https://ffmpeg.org/)
- Magick++ (http://www.imagemagick.org/Magick++/)
- MetaBrainz (https://metabrainz.org/)
diff --git a/conf/lms.conf b/conf/lms.conf
index b482a6f1..e457c84a 100644
--- a/conf/lms.conf
+++ b/conf/lms.conf
@@ -1,15 +1,13 @@
# LMS Sample configuration file
-# Path to the DB file.
-# Must have write privileges in order to create and modify the file
-db-path = "/storage/emeric/lms/lms.dev.db";
-
-# Cache directory for downloaded contents
-cache-dir-path = "/var/lms/cache";
+# Path to the working directory
+# Must have write privileges in order to create and modify this directory
+working-dir = "/var/lms/";
# Listen port/addr of the web server
listen-port = 5082;
listen-addr = "0.0.0.0";
+behind-reverse-proxy = false;
# If enabled, these files have to exist and have correct permissions
tls-enable = false;
@@ -21,6 +19,4 @@ tls-dh = "/var/lms/dh2048.pem";
docroot = "/usr/share/lms/docroot/;/resources,/css,/images,/favicon.ico";
approot = "/usr/share/lms/approot";
-# Path to the wt_config.xml file
-wt-config = "/etc/wt/wt_config.xml";
diff --git a/src/feature/FeatureStore.cpp b/src/feature/FeatureStore.cpp
index 3856bcf8..4322ac7e 100644
--- a/src/feature/FeatureStore.cpp
+++ b/src/feature/FeatureStore.cpp
@@ -38,37 +38,15 @@ Store::instance(void)
return instance;
}
-void
-Store::reload(void)
+static boost::filesystem::path
+getPath(std::string mbid, std::string type)
{
- boost::filesystem::path cacheDir = _storePath = Config::instance().getString("cache-dir-path", "");
-
- if (!ensureDirectory(cacheDir))
- {
- LMS_LOG(DBUPDATER, ERROR) << "Cache directory '" << cacheDir << "' not valid";
- throw std::runtime_error("Cache directory '" + cacheDir.string() + "' not valid!");
- }
-
- _storePath = cacheDir / "features";
-
- if (!ensureDirectory(_storePath))
- {
- LMS_LOG(DBUPDATER, ERROR) << "Features directory '" << _storePath << "' not valid";
- throw std::runtime_error("Features directory '" + _storePath.string() + "' not valid");
- }
-}
-
-boost::filesystem::path getPath(boost::filesystem::path root, std::string mbid, std::string type)
-{
- return root / (mbid + "_" + type);
+ return Config::instance().getPath("working-dir") / "features" / (mbid + "_" + type);
}
bool
Store::exists(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type)
{
- if (_storePath.empty())
- reload();
-
Wt::Dbo::Transaction transaction(session);
auto track = Database::Track::getById(session, trackId);
@@ -79,16 +57,13 @@ Store::exists(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::
if (mbid.empty())
return false;
- boost::filesystem::path path = getPath(_storePath, mbid, type);
+ boost::filesystem::path path = getPath(mbid, type);
return boost::filesystem::exists(path);
}
bool
Store::get(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, Type& feature)
{
- if (_storePath.empty())
- reload();
-
Wt::Dbo::Transaction transaction(session);
auto track = Database::Track::getById(session, trackId);
@@ -99,7 +74,7 @@ Store::get(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::str
if (mbid.empty())
return false;
- boost::filesystem::path path = getPath(_storePath, mbid, type);
+ boost::filesystem::path path = getPath(mbid, type);
if (!boost::filesystem::exists(path))
return false;
@@ -121,9 +96,6 @@ Store::get(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::str
bool
Store::set(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, const Type& feature)
{
- if (_storePath.empty())
- reload();
-
Wt::Dbo::Transaction transaction(session);
auto track = Database::Track::getById(session, trackId);
@@ -134,7 +106,7 @@ Store::set(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::str
if (mbid.empty())
return false;
- boost::filesystem::path path = getPath(_storePath, mbid, type);
+ boost::filesystem::path path = getPath(mbid, type);
try
{
diff --git a/src/feature/FeatureStore.hpp b/src/feature/FeatureStore.hpp
index 7716d9d7..e1f70bea 100644
--- a/src/feature/FeatureStore.hpp
+++ b/src/feature/FeatureStore.hpp
@@ -39,11 +39,8 @@ class Store
bool set(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, const Type& feature);
- void reload();
private:
Store();
-
- boost::filesystem::path _storePath;
};
} // namespace CoverArt
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 0282a8e1..7cfafa8a 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -18,6 +18,7 @@
*/
#include
+#include
#include
@@ -34,13 +35,15 @@
#include "ui/LmsApplication.hpp"
-
-static std::vector getWtArgs(std::string path)
+std::vector generateWtConfig(std::string execPath)
{
std::vector args;
- args.push_back(path);
- args.push_back("-c" + Config::instance().getString("wt-config"));
+ boost::filesystem::path wtConfigPath = Config::instance().getPath("working-dir") / "wt_config.xml";
+ boost::filesystem::path wtLogFilePath = Config::instance().getPath("working-dir") / "lms.log";
+
+ args.push_back(execPath);
+ args.push_back("--config=" + wtConfigPath.string());
args.push_back("--docroot=" + Config::instance().getString("docroot"));
args.push_back("--approot=" + Config::instance().getString("approot"));
@@ -58,9 +61,21 @@ static std::vector getWtArgs(std::string path)
args.push_back("--http-address=" + Config::instance().getString("listen-addr", "0.0.0.0"));
}
+ // Generate the wt_config.xml file
+ boost::property_tree::ptree pt;
+
+ pt.put("server.application-settings..location", "*");
+ pt.put("server.application-settings.log-file", wtLogFilePath.string());
+ pt.put("server.application-settings.behind-reverse-proxy", Config::instance().getBool("behind-reverse-proxy", false));
+ pt.put("server.application-settings.progressive-bootstrap", true);
+
+ std::ofstream oss(wtConfigPath.string().c_str(), std::ios::out);
+ boost::property_tree::xml_parser::write_xml(oss, pt);
+
return args;
}
+
int main(int argc, char* argv[])
{
boost::filesystem::path configFilePath = "/etc/lms.conf";
@@ -77,18 +92,25 @@ int main(int argc, char* argv[])
// Make pstream work with ffmpeg
close(STDIN_FILENO);
-
Config::instance().setFile(configFilePath);
- std::vector wtArgs = getWtArgs(argv[0]);
+ // Make sure the working directory exists
+ // TODO check with boost::system::error_code ec;
+ boost::filesystem::create_directories(Config::instance().getPath("working-dir"));
+ boost::filesystem::create_directories(Config::instance().getPath("working-dir") / "features");
- // Construct argc/argv for Wt
- const char* wtArgv[wtArgs.size()];
- for (std::size_t i = 0; i < wtArgs.size(); ++i)
- wtArgv[i] = wtArgs[i].c_str();
+ // Construct WT configuration and get the argc/argv back
+ std::vector wtServerArgs = generateWtConfig(argv[0]);
+
+ const char* wtArgv[wtServerArgs.size()];
+ for (std::size_t i = 0; i < wtServerArgs.size(); ++i)
+ {
+ std::cout << "ARG = " << wtServerArgs[i] << std::endl;
+ wtArgv[i] = wtServerArgs[i].c_str();
+ }
Wt::WServer server(argv[0]);
- server.setServerConfiguration (wtArgs.size(), const_cast(wtArgv));
+ server.setServerConfiguration (wtServerArgs.size(), const_cast(wtArgv));
Wt::WServer::instance()->logger().configure("*"); // log everything, TODO configure this
diff --git a/src/utils/Config.cpp b/src/utils/Config.cpp
index 9ff3a95e..abc20d89 100644
--- a/src/utils/Config.cpp
+++ b/src/utils/Config.cpp
@@ -66,6 +66,19 @@ Config::getString(std::string setting, std::string def)
}
}
+boost::filesystem::path
+Config::getPath(std::string setting, boost::filesystem::path path)
+{
+ try {
+ const char* res = _config->lookup(setting);
+ return boost::filesystem::path(std::string(res));
+ }
+ catch (std::exception &e)
+ {
+ return path;
+ }
+}
+
unsigned long
Config::getULong(std::string setting, unsigned long def)
{
diff --git a/src/utils/Config.hpp b/src/utils/Config.hpp
index bd52e732..799e772a 100644
--- a/src/utils/Config.hpp
+++ b/src/utils/Config.hpp
@@ -36,6 +36,7 @@ class Config
// Default values are returned in case of setting not found
std::string getString(std::string setting, std::string def = "");
+ boost::filesystem::path getPath(std::string setting, boost::filesystem::path def = boost::filesystem::path());
unsigned long getULong(std::string setting, unsigned long def = 0);
long getLong(std::string setting, long def = 0);
bool getBool(std::string setting, bool def = false);