diff --git a/.lgtm.yml b/.lgtm.yml index 295120c5..11ce21a0 100644 --- a/.lgtm.yml +++ b/.lgtm.yml @@ -17,7 +17,7 @@ extraction: - libtag1-dev - libpam0g-dev after_prepare: - - export WT_VERSION=4.5.0 + - export WT_VERSION=4.7.2 - export WT_INSTALL_PREFIX=${LGTM_WORKSPACE}/wt-${WT_VERSION} - pushd ${LGTM_WORKSPACE} - git clone https://github.com/emweb/wt.git ${LGTM_WORKSPACE}/wt @@ -28,7 +28,7 @@ extraction: - popd configure: command: - - export WT_VERSION=4.5.0 + - export WT_VERSION=4.7.2 - export WT_INSTALL_PREFIX=${LGTM_WORKSPACE}/wt-${WT_VERSION} - cmake -DCMAKE_PREFIX_PATH=${WT_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=Release diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index db3f1713..00000000 --- a/.travis.yml +++ /dev/null @@ -1,55 +0,0 @@ -arch: -- amd64 -- arm64 -language: cpp -os: linux -dist: focal -addons: - apt: - packages: - - build-essential - - cmake - - libboost-all-dev - - libconfig++-dev - - libavcodec-dev - - libavutil-dev - - libavformat-dev - - ffmpeg - - libstb-dev - - libtag1-dev - - libpam0g-dev - - libgraphicsmagick++1-dev - - libgtest-dev -compiler: -- clang -- gcc -before_install: -- | - if [ ! -d ${HOME}/wt-${WT_VERSION}/include ]; then - git clone https://github.com/emweb/wt.git wt - cd wt - git checkout ${WT_VERSION} - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${WT_INSTALL_PREFIX} -DBUILD_EXAMPLES=OFF -DENABLE_LIBWTTEST=OFF -DCONNECTOR_FCGI=OFF - make install - cd .. - fi -script: mkdir build && cd build && cmake -DCMAKE_PREFIX_PATH=${WT_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DUSE_PAM=${USE_PAM} -DIMAGE_LIBRARY=${IMAGE_LIBRARY} .. && make && make test -cache: - directories: - - ${HOME}/wt-${WT_VERSION} -env: - global: - - MAKEFLAGS="-j 2" - - WT_VERSION=4.5.0 - - WT_INSTALL_PREFIX=${HOME}/wt-${WT_VERSION} - jobs: - - BUILD_TYPE=Release USE_PAM=ON IMAGE_LIBRARY=STB - - BUILD_TYPE=Release USE_PAM=OFF IMAGE_LIBRARY=STB - - BUILD_TYPE=Release USE_PAM=OFF IMAGE_LIBRARY=GraphicsMagick++ - - BUILD_TYPE=Debug USE_PAM=ON IMAGE_LIBRARY=STB - -# clang7 is not enough for full c++17 support -jobs: - exclude: - - compiler: clang - arch: amd64 diff --git a/CMakeLists.txt b/CMakeLists.txt index b14fb02e..d56176ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(lms) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules/) set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) if (UNIX) set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") endif () diff --git a/Dockerfile-build b/Dockerfile-build index 0f5fbeba..4be54d95 100644 --- a/Dockerfile-build +++ b/Dockerfile-build @@ -1,5 +1,5 @@ FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx -FROM --platform=$BUILDPLATFORM alpine:3.14 +FROM --platform=$BUILDPLATFORM alpine:3.16 ARG BUILD_PACKAGES="\ clang \ @@ -30,7 +30,7 @@ RUN xx-apk add --no-scripts --no-cache ${LMS_BUILD_PACKAGES} ARG PREFIX="/tmp/install" # STB -ARG STB_VERSION=b42009b3b9d4ca35bc703f5310eedc74f584be58 +ARG STB_VERSION=af1a5bc352164740c1cc1354942b1c6b72eacb8a RUN \ DIR=/tmp/stb && mkdir -p ${DIR} && cd ${DIR} && \ curl -sLO https://github.com/nothings/stb/archive/${STB_VERSION}.tar.gz && \ @@ -47,4 +47,4 @@ RUN \ PKG_CONFIG_PATH=/$(xx-info)/usr/lib/pkgconfig cmake /tmp/lms/ -DCMAKE_INCLUDE_PATH=${PREFIX}/include -DCMAKE_BUILD_TYPE=${LMS_BUILD_TYPE} $(xx-clang --print-cmake-defines) -DCMAKE_PREFIX_PATH=/$(xx-info)/usr/lib/cmake -DBUILD_TESTING=${BUILD_TESTS} && \ VERBOSE=1 make -j$(nproc) && \ xx-verify src/lms/lms && \ - xx-info is-cross || make test + (xx-info is-cross || make test) diff --git a/Dockerfile-release b/Dockerfile-release index a30db9f2..6bb7d3bc 100644 --- a/Dockerfile-release +++ b/Dockerfile-release @@ -1,4 +1,4 @@ -FROM alpine:3.14 AS build +FROM alpine:3.16 AS build WORKDIR /tmp/workdir @@ -77,7 +77,7 @@ RUN \ make distclean # WT -ARG WT_VERSION=4.5.0 +ARG WT_VERSION=4.7.2 RUN \ DIR=/tmp/wt && mkdir -p ${DIR} && cd ${DIR} && \ curl -sLO https://github.com/emweb/wt/archive/${WT_VERSION}.tar.gz && \ @@ -126,8 +126,13 @@ RUN \ rm -rf /tmp/fakeroot/share/doc && \ rm -rf /tmp/fakeroot/share/man +# Remove useless stuff +RUN \ + rm -rf /tmp/fakeroot/share/Wt/resources/jPlayer \ + rm -rf /tmp/fakeroot/share/Wt/resources/themes + ## Release Stage -FROM alpine:3.14 AS release +FROM alpine:3.16 AS release LABEL maintainer="Emeric Poupon " ARG RUNTIME_PACKAGES=" \ diff --git a/INSTALL.md b/INSTALL.md index 19bbd849..c8f44f61 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,6 @@ - [Installation](#installation) * [Docker](#docker) - * [Debian Buster packages](#debian-buster-packages) + * [Debian Bullseye packages](#debian-bullseye-packages) * [From source](#from-source) + [Build dependencies](#build-dependencies) + [Build](#build) @@ -12,33 +12,25 @@ * [Deploy on non root path](#deploy-on-non-root-path) * [Reverse proxy settings](#reverse-proxy-settings) - [Run](#run) - # Installation - ## Docker _Docker_ images are available, please see detailed instructions on https://hub.docker.com/r/epoupon/lms. - -## Debian Buster packages -_Buster_ packages are provided for _amd64_ and _armhf_ architectures. - +## Debian Bullseye packages +_Bullseye_ packages are provided for _amd64_ and _armhf_ architectures. As root, trust the following debian package provider and add it in your list of repositories: ```sh wget -O - https://debian.poupon.dev/apt/debian/epoupon.gpg.key | apt-key add - -echo "deb https://debian.poupon.dev/apt/debian buster main" > /etc/apt/sources.list.d/epoupon.list +echo "deb https://debian.poupon.dev/apt/debian bullseye main" > /etc/apt/sources.list.d/epoupon.list ``` - To install or upgrade _LMS_: ```sh apt update apt install lms ``` - The _lms_ service is started just after the package installation, run by a dedicated _lms_ system user.
Please refer to [Deployment](#deployment) for further configuration options. - ## From source -__Note__: this installation process and the default values of the configuration files have been written for _Debian Buster_. Therefore, you may have to adapt commands and/or paths in order to fit to your distribution. - +__Note__: this installation process and the default values of the configuration files have been written for _Debian Bullseye_. Therefore, you may have to adapt commands and/or paths in order to fit to your distribution. ### Build dependencies __Notes__: * a C++17 compiler is needed @@ -49,12 +41,9 @@ apt-get install g++ cmake libboost-program-options-dev libboost-system-dev libav __Notes__: * libpam0g-dev is optional (only for using PAM authentication) * libstb-dev can be replaced by libgraphicsmagick++1-dev (the latter will likely use more RAM) - You also need _Wt4_, which is not packaged yet on _Debian_. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html).
No optional requirement is needed, except openSSL if you plan not to deploy behind a reverse proxy (which is not recommended). - ### Build - Get the latest stable release and build it: ```sh git clone https://github.com/epoupon/lms.git lms @@ -66,80 +55,69 @@ cmake .. -DCMAKE_BUILD_TYPE=Release __Notes__: * you can customize the installation directory using `-DCMAKE_INSTALL_PREFIX=path` (defaults to `/usr/local`). * you can customize the image library using `-DIMAGE_LIBRARY=` - ```sh make ``` __Note__: you can use `make -jN` to speed up compilation time (N is the number of compilation workers to spawn). - ### Installation - __Note__: the commands of this section require root privileges. - ```sh make install ``` - Create a dedicated system user: ```sh useradd --system --group lms ``` - Copy the configuration files: ```sh cp /usr/share/lms/lms.conf /etc/lms.conf cp /usr/share/lms/lms.service /lib/systemd/system/lms.service ``` - Create the working directory and give it access to the _lms_ user: ```sh mkdir /var/lms chown lms:lms /var/lms ``` - To make _LMS_ run automatically during startup: ```sh systemctl enable lms ``` - ### Upgrade - To upgrade _LMS_ from sources, you need to update the master branch and rebuild/install it: ```sh cd build git pull make ``` - Then using root privileges: ```sh make install systemctl restart lms ``` - # Deployment - __Note__: don't forget to give the _lms_ user read access to the music directory you want to scan. - ## Configuration _LMS_ uses a configuration file, installed by default in `/etc/lms.conf`. It is recommended to edit this file and change relevant settings (listen address, listen port, working directory, Subsonic API activation, deployment path, ...). - All other settings are set using the web interface (user management, scan settings, transcode settings, ...). - If a setting is not present in the configuration file, a hardcoded default value is used (the same as in the [default configuration file](conf/lms.conf)) - ## Authentication backend - You can define which authentication backend to be used thanks to the `authentication-backend` option: * `internal` (default): _LMS_ uses an internal database to store users and their associated passwords (salted and hashed using [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt)). Only the admin user can create, edit or remove other users. * `PAM`: the user/password authentication request is forwarded to PAM (see the default [PAM configuration file](conf/pam/lms) provided). * `http-headers`: _LMS_ uses a configurable HTTP header field, typically set by a reverse proxy to handle [SSO](https://en.wikipedia.org/wiki/Single_sign-on), to extract the login name. You can customize the field to be used using the `http-headers-login-field` option. - __Note__: the first created user is the admin user - +### `internal` backend: reset admin password +Open the the database file located in `/var/lms/lms.db` using `sqlite3`: +```sh +sqlite3 /var/lms/lms.db +``` +Now force reset the password of the admin user to `adminadmin`: +```sqlite3 +UPDATE user SET password_salt="sliIgHUpEoAlBMquivH4VzKXbSzexlvS", password_hash="$2y$07$a0vnQUbGTV/DZyDqOizvbOdCaytNjDhkOPcGoBZup4V0MRKDzOpEG" WHERE id=1; +.quit +``` ## Deploy on non root path If you want to deploy on non root path (e.g. https://mydomain.com/newroot/), you have to set the `deploy-path` option accordingly in `lms.conf`. - As static resources are __not__ related to the `deploy-path` option, you have to perform the following steps if you want them to be on a non root path too: * Create a new intermediary `newroot` directory in `/usr/share/lms/docroot` and move everything in it. * Symlink `/usr/share/lms/docroot/newroot/resources` to `/usr/share/Wt/resources`. @@ -149,12 +127,9 @@ wt-resources = "" # do not comment the whole line docroot = "/usr/share/lms/docroot/;/newroot/resources,/newroot/css,/newroot/images,/newroot/js,/newroot/favicon.ico";` deploy-path = "/newroot/"; # ending slash is important ``` - If you use nginx as a reverse proxy, you can simply replace `location /` with `location /newroot/` to achieve the same result. - ## Reverse proxy settings _LMS_ is shipped with an embedded web server, but it is recommended to deploy behind a reverse proxy. You have to set the _behind-reverse-proxy_ option to _true_ in the `lms.conf` configuration file. - Here is an example to make _LMS_ properly work on _myserver.org_ using _nginx_: ``` server { @@ -183,16 +158,12 @@ server { } } ``` - # Run ```sh systemctl start lms ``` - Log traces can be accessed using journactl: ```sh journalctl -u lms.service ``` - -To connect to _LMS_, just open your favorite browser and go to http://localhost:5082 - +To connect to _LMS_, just open your favorite browser and go to `http://localhost:5082` diff --git a/approot/admin-database.xml b/approot/admin-database.xml index d455b4fc..a81dc5ab 100644 --- a/approot/admin-database.xml +++ b/approot/admin-database.xml @@ -4,77 +4,60 @@ -
-
-
- ${tr:Lms.Admin.Database.database} -
-
- -
- ${media-directory} - ${media-directory-info class="help-block"} - ${tr:Lms.Admin.Database.path-help} -
-
-
- -
- ${update-period} - ${update-period-info class="help-block"} -
-
-
- -
- ${update-start-time} - ${update-start-time-info class="help-block"} -
-
-
- ${tr:Lms.Admin.Database.scan-options} -
-
- -
- ${recommendation-engine-type} - ${recommendation-engine-type-info class="help-block"} -
-
-
- -
- ${tags} - ${tags-info class="help-block"} -
-
-
-
-
-
- ${apply-btn class="btn-primary"} ${discard-btn} -
-
-
-
+
+ ${tr:Lms.Admin.Database.database} +
+ + ${media-directory class="form-control"} +
+ ${media-directory-info} +
-
+
+ + ${update-period class="form-control"} +
+ ${update-period-info"} +
+
+
+ + ${update-start-time class="form-control"} +
+ ${update-start-time-info} +
+
+ ${tr:Lms.Admin.Database.scan-options} +
+ + ${recommendation-engine-type class="form-control"} +
+ ${recommendation-engine-type-info} +
+
+
+ + ${tags class="form-control"} +
+ ${tags-info} +
+
+
+ ${apply-btn class="btn btn-primary me-1"}${discard-btn class="btn btn-secondary"} +
+
-
-
- ${scanner-controller} -
-
+ ${scanner-controller} diff --git a/approot/admin-initwizard.xml b/approot/admin-initwizard.xml index e86ba76d..8ec6620b 100644 --- a/approot/admin-initwizard.xml +++ b/approot/admin-initwizard.xml @@ -4,49 +4,44 @@
-
-
- diff --git a/approot/admin-scannercontroller.xml b/approot/admin-scannercontroller.xml index 484fc64a..d5e17584 100644 --- a/approot/admin-scannercontroller.xml +++ b/approot/admin-scannercontroller.xml @@ -2,42 +2,44 @@ -
-
${tr:Lms.Admin.ScannerController.scanner}
-
-
-
- -
-
- ${status} -
${step-status}
+
+
${tr:Lms.Admin.ScannerController.scanner}
+
+
+
+
+ + ${status class="form-control"} +
+
+ + ${step-status class="form-control"} +
+
+ +
+ ${last-scan class="form-control"} + ${report-btn class="btn btn-outline-info"} +
+
+
+
+ ${scan-btn class="btn btn-primary"} + +
-
- -
-
- ${last-scan} -
-
-
-
-
- ${btn-report class="btn btn-xs"} -
-
-
-
- ${btn-action} -
-
-
+
diff --git a/approot/admin-user.xml b/approot/admin-user.xml index 458653f8..26f0c989 100644 --- a/approot/admin-user.xml +++ b/approot/admin-user.xml @@ -2,64 +2,55 @@ -
-
- ${title} -
-
- ${} -
- -
-
- ${last-login} -
-
-
- ${
} - ${} -
- -
- ${login} - ${login-info class="help-block"} -
-
- ${
} - ${} -
- -
- ${password} - ${password-info class="help-block"} -
-
- ${
} - ${} -
-
-
- - ${demo-info class="help-block"} -
-
-
- ${
} -
-
- ${save-btn class="btn-primary"} -
+ + ${title} + ${} +
+ + +
+ ${
} + ${} +
+ + ${login class="form-control"} +
+ ${login-info} +
+
+ ${
} + ${} +
+ + ${password class="form-control"} +
+ ${password-info} +
+
+ ${
} + ${} +
+
+ ${demo class="form-check-input"} + +
+ ${demo-info}
- +
+ ${
} +
+ ${save-btn class="btn btn-primary"}
-
+ diff --git a/approot/admin-users.xml b/approot/admin-users.xml index 0e8da5ce..ac326d97 100644 --- a/approot/admin-users.xml +++ b/approot/admin-users.xml @@ -2,22 +2,39 @@ -
-

${tr:Lms.Admin.Users.users}

-
- ${users} +

${tr:Lms.Admin.Users.users}

+ ${users class="d-grid gap-1 mb-3"} ${} - ${add-btn class="btn-primary Lms-admin-users-add-btn"} + ${add-btn class="btn btn-primary"} ${}
-
-
- ${name}${}${tag}${} +
+
+ ${name}${}${tag}${}
-
- ${}${edit-btn class="btn-warning btn-sm Lms-admin-users-entry-btn"}${del-btn class="btn-danger btn-sm Lms-admin-users-entry-btn"}${} +
+ ${}${edit-btn class="btn btn-sm btn-secondary me-1"}${del-btn class="btn btn-sm btn-danger"}${} +
+
+ + + + diff --git a/approot/artist.xml b/approot/artist.xml index 79f7c3c9..2b3f5730 100644 --- a/approot/artist.xml +++ b/approot/artist.xml @@ -3,56 +3,35 @@ -
-

${name}

- ${clusters} - ${play-btn class="Lms-explore-btn Lms-btn"}${more-btn class="Lms-explore-btn Lms-btn"} +
+

${name}

+ ${clusters class="mb-2"} +
+ ${play-btn class="btn btn-primary"} +
${} -
- ${releases class="Lms-explore-artist-entries-container"} -
+ ${releases class="mb-3"} ${
} ${} -
- ${tracks} -
+ ${tracks class="mb-3"} ${
} -
- ${} -
-
-

${tr:Lms.Explore.Artist.similar-artists}

- ${similar-artists} -
-
- ${
} - ${} -
-
-

${tr:Lms.Explore.links}

- ${mbid-link class="Lms-btn text-muted"} -
-
- ${
} -
- - - -
-
-
-
- ${cover} -
-
-
-
${name class="Lms-releasename text-primary"}
- ${}
${artist class="Lms-btn Lms-artistname text-muted"}
${
} -
${}${year}${}${} (${orig-year})${}
-
-
+ ${} +
+

${tr:Lms.Explore.Artist.similar-artists}

+ ${similar-artists class="d-grid gap-3"}
+ ${
} diff --git a/approot/artists.xml b/approot/artists.xml index cf00bdf7..a0fd6409 100644 --- a/approot/artists.xml +++ b/approot/artists.xml @@ -3,11 +3,30 @@ -
- ${mode class="nav nav-pills Lms-explore-mode-container"} +
+
-
- ${link-type} +
+ ${link-type class="form-select"}
@@ -15,15 +34,12 @@ -
-

${name class="Lms-btn Lms-artistname text-primary"}

-
+ ${name class="text-decoration-none link-secondary"}
- -
- ${name class="Lms-btn Lms-artistname text-primary"} -
+ + ${elements class="d-grid gap-3"} + ${loading-indicator} diff --git a/approot/explore.xml b/approot/explore.xml index ae88ff4b..60628d1e 100644 --- a/approot/explore.xml +++ b/approot/explore.xml @@ -2,37 +2,43 @@ - ${contents class="Lms-explore-contents"} + ${contents} - - + + - ${add-filter class="btn-sm btn-info"} ${clusters class="Lms-explore-clusters"} + ${add-filter class="btn btn-sm btn-outline-primary me-2"}${clusters class="d-inline-block align-items-center"} -
-
- -
- ${type} -
-
-
- -
- ${value} -
-
-
-
- ${add-btn class="btn-primary"} ${cancel-btn} + diff --git a/approot/login.xml b/approot/login.xml index 7dab178c..c349088a 100644 --- a/approot/login.xml +++ b/approot/login.xml @@ -4,46 +4,38 @@
- -
-
-
- -
- ${login-name} + +
+
+

${tr:Lms.Auth.welcome}

+
+ + ${login-name class="form-control"} +
+ ${login-name-info} +
-
- ${login-name-info} +
+ + ${password class="form-control"} +
+ ${password-info} +
-
- -
- -
- ${password} +
+
+ ${remember-me class="form-check-input"} + +
-
- ${password-info} -
-
- -
- -
-
-
-
-
-
- ${login-btn class="btn-primary"} +
+ ${login-btn class="btn btn-primary"}
diff --git a/approot/main.xml b/approot/main.xml new file mode 100644 index 00000000..ffd58fbb --- /dev/null +++ b/approot/main.xml @@ -0,0 +1,70 @@ + + + + + ${navbar} +
+ ${contents} + ${notifications class="toast-container Lms-notification-container p-3"} + ${modal} +
+ ${player class="fixed-bottom bg-dark Lms-player"} +
+ + + + + +
diff --git a/approot/mediaplayer.xml b/approot/mediaplayer.xml index 46f1078f..3abe70eb 100644 --- a/approot/mediaplayer.xml +++ b/approot/mediaplayer.xml @@ -6,36 +6,35 @@
-
+
-
-
-
+
+
-
-
- +
+
+ + +
-