[CONF] Made a single configuration file
This commit is contained in:
@@ -33,6 +33,8 @@ $ apt-get install g++ autoconf automake libboost-dev libboost-locale-dev libboos
|
|||||||
## Build
|
## Build
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
$ git clone https://github.com/epoupon/lms.git lms
|
||||||
|
$ cd lms
|
||||||
$ autoreconf -vfi
|
$ autoreconf -vfi
|
||||||
$ mkdir build
|
$ mkdir build
|
||||||
$ cd build
|
$ cd build
|
||||||
@@ -52,51 +54,25 @@ $ make install
|
|||||||
This command requires root privileges
|
This command requires root privileges
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
LMS uses a config file for low level settings:
|
LMS uses a configuration file, installed in '/etc/lms.conf'
|
||||||
- database file path, default is /var/lms/lms.db
|
It is recommended to edit this file and change the relevant settings (working directory, listen port, etc.)
|
||||||
- TLS settings, default is none
|
|
||||||
- listen address/port, default is 0.0.0.0 port 5081
|
|
||||||
|
|
||||||
Other settings are set using the web interface.
|
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
|
## Running
|
||||||
```sh
|
```sh
|
||||||
$ /usr/bin/lms [config_file]
|
$ lms [config_file]
|
||||||
```
|
```
|
||||||
LMS needs write access to the directory used for the database.
|
Logs are output in the working directory, in the file 'lms.log'
|
||||||
It is highly recommended to run LMS as a non root user.
|
|
||||||
|
|
||||||
To connect to LMS, just open your favorite browser and go to http://localhost:5081
|
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:
|
|
||||||
```
|
|
||||||
<application-settings location="/usr/bin/lms">
|
|
||||||
<progressive-bootstrap>true</progressive-bootstrap>
|
|
||||||
</application-settings>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 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
|
## Credits
|
||||||
|
|
||||||
- Wt (http://www.webtoolkit.eu/)
|
- Wt (http://www.webtoolkit.eu/)
|
||||||
- bootstrap3 (http://getbootstrap.com/)
|
- bootstrap3 (http://getbootstrap.com/)
|
||||||
- libav project (https://www.libav.org/)
|
- ffmpeg project (https://ffmpeg.org/)
|
||||||
- Magick++ (http://www.imagemagick.org/Magick++/)
|
- Magick++ (http://www.imagemagick.org/Magick++/)
|
||||||
- MetaBrainz (https://metabrainz.org/)
|
- MetaBrainz (https://metabrainz.org/)
|
||||||
|
|||||||
+4
-8
@@ -1,15 +1,13 @@
|
|||||||
# LMS Sample configuration file
|
# LMS Sample configuration file
|
||||||
|
|
||||||
# Path to the DB file.
|
# Path to the working directory
|
||||||
# Must have write privileges in order to create and modify the file
|
# Must have write privileges in order to create and modify this directory
|
||||||
db-path = "/storage/emeric/lms/lms.dev.db";
|
working-dir = "/var/lms/";
|
||||||
|
|
||||||
# Cache directory for downloaded contents
|
|
||||||
cache-dir-path = "/var/lms/cache";
|
|
||||||
|
|
||||||
# Listen port/addr of the web server
|
# Listen port/addr of the web server
|
||||||
listen-port = 5082;
|
listen-port = 5082;
|
||||||
listen-addr = "0.0.0.0";
|
listen-addr = "0.0.0.0";
|
||||||
|
behind-reverse-proxy = false;
|
||||||
|
|
||||||
# If enabled, these files have to exist and have correct permissions
|
# If enabled, these files have to exist and have correct permissions
|
||||||
tls-enable = false;
|
tls-enable = false;
|
||||||
@@ -21,6 +19,4 @@ tls-dh = "/var/lms/dh2048.pem";
|
|||||||
docroot = "/usr/share/lms/docroot/;/resources,/css,/images,/favicon.ico";
|
docroot = "/usr/share/lms/docroot/;/resources,/css,/images,/favicon.ico";
|
||||||
approot = "/usr/share/lms/approot";
|
approot = "/usr/share/lms/approot";
|
||||||
|
|
||||||
# Path to the wt_config.xml file
|
|
||||||
wt-config = "/etc/wt/wt_config.xml";
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,37 +38,15 @@ Store::instance(void)
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static boost::filesystem::path
|
||||||
Store::reload(void)
|
getPath(std::string mbid, std::string type)
|
||||||
{
|
{
|
||||||
boost::filesystem::path cacheDir = _storePath = Config::instance().getString("cache-dir-path", "");
|
return Config::instance().getPath("working-dir") / "features" / (mbid + "_" + type);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Store::exists(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type)
|
Store::exists(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type)
|
||||||
{
|
{
|
||||||
if (_storePath.empty())
|
|
||||||
reload();
|
|
||||||
|
|
||||||
Wt::Dbo::Transaction transaction(session);
|
Wt::Dbo::Transaction transaction(session);
|
||||||
|
|
||||||
auto track = Database::Track::getById(session, trackId);
|
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())
|
if (mbid.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boost::filesystem::path path = getPath(_storePath, mbid, type);
|
boost::filesystem::path path = getPath(mbid, type);
|
||||||
return boost::filesystem::exists(path);
|
return boost::filesystem::exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Store::get(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, Type& feature)
|
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);
|
Wt::Dbo::Transaction transaction(session);
|
||||||
|
|
||||||
auto track = Database::Track::getById(session, trackId);
|
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())
|
if (mbid.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boost::filesystem::path path = getPath(_storePath, mbid, type);
|
boost::filesystem::path path = getPath(mbid, type);
|
||||||
if (!boost::filesystem::exists(path))
|
if (!boost::filesystem::exists(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -121,9 +96,6 @@ Store::get(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::str
|
|||||||
bool
|
bool
|
||||||
Store::set(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, const Type& feature)
|
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);
|
Wt::Dbo::Transaction transaction(session);
|
||||||
|
|
||||||
auto track = Database::Track::getById(session, trackId);
|
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())
|
if (mbid.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boost::filesystem::path path = getPath(_storePath, mbid, type);
|
boost::filesystem::path path = getPath(mbid, type);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,11 +39,8 @@ class Store
|
|||||||
|
|
||||||
bool set(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, const Type& feature);
|
bool set(Wt::Dbo::Session& session, Database::Track::id_type trackId, std::string type, const Type& feature);
|
||||||
|
|
||||||
void reload();
|
|
||||||
private:
|
private:
|
||||||
Store();
|
Store();
|
||||||
|
|
||||||
boost::filesystem::path _storePath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CoverArt
|
} // namespace CoverArt
|
||||||
|
|||||||
+33
-11
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/property_tree/xml_parser.hpp>
|
||||||
|
|
||||||
#include <Wt/WServer>
|
#include <Wt/WServer>
|
||||||
|
|
||||||
@@ -34,13 +35,15 @@
|
|||||||
|
|
||||||
#include "ui/LmsApplication.hpp"
|
#include "ui/LmsApplication.hpp"
|
||||||
|
|
||||||
|
std::vector<std::string> generateWtConfig(std::string execPath)
|
||||||
static std::vector<std::string> getWtArgs(std::string path)
|
|
||||||
{
|
{
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
|
|
||||||
args.push_back(path);
|
boost::filesystem::path wtConfigPath = Config::instance().getPath("working-dir") / "wt_config.xml";
|
||||||
args.push_back("-c" + Config::instance().getString("wt-config"));
|
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("--docroot=" + Config::instance().getString("docroot"));
|
||||||
args.push_back("--approot=" + Config::instance().getString("approot"));
|
args.push_back("--approot=" + Config::instance().getString("approot"));
|
||||||
|
|
||||||
@@ -58,9 +61,21 @@ static std::vector<std::string> getWtArgs(std::string path)
|
|||||||
args.push_back("--http-address=" + Config::instance().getString("listen-addr", "0.0.0.0"));
|
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.<xmlattr>.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;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
boost::filesystem::path configFilePath = "/etc/lms.conf";
|
boost::filesystem::path configFilePath = "/etc/lms.conf";
|
||||||
@@ -77,18 +92,25 @@ int main(int argc, char* argv[])
|
|||||||
// Make pstream work with ffmpeg
|
// Make pstream work with ffmpeg
|
||||||
close(STDIN_FILENO);
|
close(STDIN_FILENO);
|
||||||
|
|
||||||
|
|
||||||
Config::instance().setFile(configFilePath);
|
Config::instance().setFile(configFilePath);
|
||||||
|
|
||||||
std::vector<std::string> 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
|
// Construct WT configuration and get the argc/argv back
|
||||||
const char* wtArgv[wtArgs.size()];
|
std::vector<std::string> wtServerArgs = generateWtConfig(argv[0]);
|
||||||
for (std::size_t i = 0; i < wtArgs.size(); ++i)
|
|
||||||
wtArgv[i] = wtArgs[i].c_str();
|
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]);
|
Wt::WServer server(argv[0]);
|
||||||
server.setServerConfiguration (wtArgs.size(), const_cast<char**>(wtArgv));
|
server.setServerConfiguration (wtServerArgs.size(), const_cast<char**>(wtArgv));
|
||||||
|
|
||||||
Wt::WServer::instance()->logger().configure("*"); // log everything, TODO configure this
|
Wt::WServer::instance()->logger().configure("*"); // log everything, TODO configure this
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
unsigned long
|
||||||
Config::getULong(std::string setting, unsigned long def)
|
Config::getULong(std::string setting, unsigned long def)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class Config
|
|||||||
|
|
||||||
// Default values are returned in case of setting not found
|
// Default values are returned in case of setting not found
|
||||||
std::string getString(std::string setting, std::string def = "");
|
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);
|
unsigned long getULong(std::string setting, unsigned long def = 0);
|
||||||
long getLong(std::string setting, long def = 0);
|
long getLong(std::string setting, long def = 0);
|
||||||
bool getBool(std::string setting, bool def = false);
|
bool getBool(std::string setting, bool def = false);
|
||||||
|
|||||||
Reference in New Issue
Block a user