From a40c05ec6bf9db4d0917f19b5cca0f98310e7a52 Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 23 Mar 2020 18:06:39 +0100 Subject: [PATCH 01/12] Always storing MBID in lowercase to avoid silly duplicates --- src/libs/utils/impl/String.cpp | 16 +++++++++++++--- src/libs/utils/impl/UUID.cpp | 6 ++++++ src/libs/utils/include/utils/String.hpp | 3 ++- src/libs/utils/include/utils/UUID.hpp | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/libs/utils/impl/String.cpp b/src/libs/utils/impl/String.cpp index be6a79a1..1b181325 100644 --- a/src/libs/utils/impl/String.cpp +++ b/src/libs/utils/impl/String.cpp @@ -98,15 +98,25 @@ stringTrimEnd(const std::string& str, const std::string& whitespace) } std::string -stringToLower(const std::string& str) +stringToLower(std::string_view str) { - return boost::algorithm::to_lower_copy(str); + std::string res; + res.reserve(str.size()); + + std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](char c) { return std::tolower(c);}); + + return res; } std::string stringToUpper(const std::string& str) { - return boost::to_upper_copy(str); + std::string res; + res.reserve(str.size()); + + std::transform(std::cbegin(str), std::cend(str), std::back_inserter(res), [](char c) { return std::toupper(c);}); + + return res; } std::string diff --git a/src/libs/utils/impl/UUID.cpp b/src/libs/utils/impl/UUID.cpp index f95209e2..6b9b402a 100644 --- a/src/libs/utils/impl/UUID.cpp +++ b/src/libs/utils/impl/UUID.cpp @@ -21,6 +21,8 @@ #include +#include "utils/String.hpp" + namespace StringUtils { template <> @@ -40,6 +42,10 @@ stringIsUUID(std::string_view str) return std::regex_match(std::cbegin(str), std::cend(str), re); } +UUID::UUID(std::string_view str) + : _value {StringUtils::stringToLower(str)} +{ +} std::optional UUID::fromString(std::string_view str) diff --git a/src/libs/utils/include/utils/String.hpp b/src/libs/utils/include/utils/String.hpp index e62edb91..62d6fba4 100644 --- a/src/libs/utils/include/utils/String.hpp +++ b/src/libs/utils/include/utils/String.hpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -40,7 +41,7 @@ std::string stringTrimEnd(const std::string& str, const std::string& whitespaces = " \t"); std::string -stringToLower(const std::string& str); +stringToLower(std::string_view str); std::string stringToUpper(const std::string& str); diff --git a/src/libs/utils/include/utils/UUID.hpp b/src/libs/utils/include/utils/UUID.hpp index daf561d0..38814d1f 100644 --- a/src/libs/utils/include/utils/UUID.hpp +++ b/src/libs/utils/include/utils/UUID.hpp @@ -34,7 +34,7 @@ class UUID std::string_view getAsString() const { return _value; } private: - UUID(std::string_view value) : _value {value} {} + UUID(std::string_view value); std::string _value; }; From bd6a08facbc0498b82aa007fe75bdb0c00400018 Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 23 Mar 2020 20:16:12 +0100 Subject: [PATCH 02/12] WMA: better metadata parsing. fixes #40 --- src/libs/database/impl/Session.cpp | 10 +- src/libs/metadata/impl/TagLibParser.cpp | 262 ++++++++++-------- .../include/metadata/TagLibParser.hpp | 9 +- 3 files changed, 160 insertions(+), 121 deletions(-) diff --git a/src/libs/database/impl/Session.cpp b/src/libs/database/impl/Session.cpp index 35eeb7df..63586f17 100644 --- a/src/libs/database/impl/Session.cpp +++ b/src/libs/database/impl/Session.cpp @@ -40,7 +40,7 @@ namespace Database { -#define LMS_DATABASE_VERSION 13 +#define LMS_DATABASE_VERSION 14 using Version = std::size_t; @@ -153,7 +153,13 @@ CREATE TABLE IF NOT EXISTS "track_bookmark" ( } else if (version == 12) { - // Artist and release that have a baddly parsed name but a MBID had no chance to updat the name + // Artist and release that have a badly parsed name but a MBID had no chance to updat the name + // Just increment the scan version of the settings to make the next scheduled scan rescan everything + ScanSettings::get(*this).modify()->incScanVersion(); + } + else if (version == 13) + { + // Always store UUID in lower case + better WMA parsing // Just increment the scan version of the settings to make the next scheduled scan rescan everything ScanSettings::get(*this).modify()->incScanVersion(); } diff --git a/src/libs/metadata/impl/TagLibParser.cpp b/src/libs/metadata/impl/TagLibParser.cpp index 78949ce8..fee48f25 100644 --- a/src/libs/metadata/impl/TagLibParser.cpp +++ b/src/libs/metadata/impl/TagLibParser.cpp @@ -154,12 +154,118 @@ getAlbum(const TagLib::PropertyMap& properties) return Album {std::move(albumName.front()), albumMBID.front()}; } +void +TagLibParser::processTag(Track& track, const std::string& tag, const TagLib::StringList& values, bool debug) +{ + + // TODO validate MBID format + if (debug) + { + std::vector strs; + std::transform(values.begin(), values.end(), std::back_inserter(strs), [](const auto& value) { return value.to8Bit(true); }); + + std::cout << "[" << tag << "] = " << StringUtils::joinStrings(strs, "*SEP*") << std::endl; + } + + if (tag.empty() || values.isEmpty() || values.front().isEmpty()) + return; + + std::string value {StringUtils::stringTrim(values.front().to8Bit(true))}; + + if (tag == "TITLE") + track.title = value; + else if (tag == "MUSICBRAINZ_RELEASETRACKID" + || tag == "MUSICBRAINZ RELEASE TRACK ID") + { + track.musicBrainzTrackID = UUID::fromString(value); + } + else if (tag == "MUSICBRAINZ_TRACKID" + || tag == "MUSICBRAINZ TRACK ID") + track.musicBrainzRecordID = UUID::fromString(value); + else if (tag == "ACOUSTID_ID") + track.acoustID = UUID::fromString(value); + else if (tag == "TRACKTOTAL") + { + auto totalTrack = StringUtils::readAs(value); + if (totalTrack) + track.totalTrack = totalTrack; + } + else if (tag == "TRACKNUMBER") + { + // Expecting 'Number/Total' + std::vector strings {splitAndTrimString(value, "/")}; + + if (!strings.empty()) + { + track.trackNumber = StringUtils::readAs(strings[0]); + + // Lower priority than TRACKTOTAL + if (strings.size() > 1 && !track.totalTrack) + track.totalTrack = StringUtils::readAs(strings[1]); + } + } + else if (tag == "DISCTOTAL") + { + auto totalDisc = StringUtils::readAs(value); + if (totalDisc) + track.totalDisc = totalDisc; + } + else if (tag == "DISCNUMBER") + { + // Expecting 'Number/Total' + std::vector strings {StringUtils::splitString(value, "/")}; + + if (!strings.empty()) + { + track.discNumber = StringUtils::readAs(strings[0]); + + // Lower priority than DISCTOTAL + if (strings.size() > 1 && !track.totalDisc) + track.totalDisc = StringUtils::readAs(strings[1]); + } + } + else if (tag == "DATE") + track.year = StringUtils::readAs(value); + else if (tag == "ORIGINALDATE" && !track.originalYear) + { + // Lower priority than ORIGINALYEAR + track.originalYear = StringUtils::readAs(value); + } + else if (tag == "ORIGINALYEAR") + { + // Higher priority than ORIGINALDATE + auto originalYear = StringUtils::readAs(value); + if (originalYear) + track.originalYear = originalYear; + } + else if (tag == "METADATA_BLOCK_PICTURE") + track.hasCover = true; + else if (tag == "COPYRIGHT") + track.copyright = value; + else if (tag == "COPYRIGHTURL") + track.copyrightURL = value; + else if (_clusterTypeNames.find(tag) != _clusterTypeNames.end()) + { + std::set clusterNames; + for (const auto& valueList : values) + { + auto values = splitAndTrimString(valueList.to8Bit(true), "/,;"); + + for (const auto& value : values) + clusterNames.insert(value); + } + + if (!clusterNames.empty()) + track.clusters[tag] = clusterNames; + } +} + std::optional TagLibParser::parse(const std::filesystem::path& p, bool debug) { TagLib::FileRef f {p.string().c_str(), - true, // read audio properties - TagLib::AudioProperties::Fast}; + true, // read audio properties + TagLib::AudioProperties::Fast}; if (f.isNull()) { @@ -184,14 +290,40 @@ TagLibParser::parse(const std::filesystem::path& p, bool debug) track.audioStreams = {std::move(audioStream)}; } + TagLib::PropertyMap properties {f.file()->properties()}; + // Not that good embedded pictures handling // WMA if (TagLib::ASF::File* asfFile {dynamic_cast(f.file())}) { const TagLib::ASF::Tag* tag {asfFile->tag()}; - if (tag && tag->attributeListMap().contains("WM/Picture")) - track.hasCover = true; + if (tag) + { + if (tag->attributeListMap().contains("WM/Picture")) + track.hasCover = true; + + for (const auto& [name, attributeList] : tag->attributeListMap()) + { + if (name.to8Bit().find("WM/") == 0 || properties.contains(name)) + continue; + + TagLib::StringList stringAttributeList; + for (const auto& attribute : attributeList) + { + if (attribute.type() == TagLib::ASF::Attribute::AttributeTypes::UnicodeType) + stringAttributeList.append(attribute.toString()); + } + + if (!stringAttributeList.isEmpty()) + { + if (debug) + std::cout << "Property: '" << name << "'" << std::endl; + + properties.insert(name, stringAttributeList); + } + } + } } // MP3 else if (TagLib::MPEG::File* mp3File {dynamic_cast(f.file())}) @@ -209,124 +341,18 @@ TagLibParser::parse(const std::filesystem::path& p, bool debug) track.hasCover = true; } - if (f.tag()) + for(const auto& property : properties) { - MetaData::Clusters clusters; - const TagLib::PropertyMap& properties {f.file()->properties()}; - - for(const auto& property : properties) - { - const std::string tag {property.first.upper().to8Bit(true)}; - const TagLib::StringList& values {property.second}; - - // TODO validate MBID format - if (debug) - { - std::vector strs; - std::transform(values.begin(), values.end(), std::back_inserter(strs), [](const auto& value) { return value.to8Bit(true); }); - - std::cout << "[" << tag << "] = " << StringUtils::joinStrings(strs, "*SEP*") << std::endl; - } - - if (tag.empty() || values.isEmpty() || values.front().isEmpty()) - continue; - - std::string value {StringUtils::stringTrim(values.front().to8Bit(true))}; - - if (tag == "TITLE") - track.title = value; - else if (tag == "MUSICBRAINZ_RELEASETRACKID" - || tag == "MUSICBRAINZ RELEASE TRACK ID") - { - track.musicBrainzTrackID = UUID::fromString(value); - } - else if (tag == "MUSICBRAINZ_TRACKID" - || tag == "MUSICBRAINZ TRACK ID") - track.musicBrainzRecordID = UUID::fromString(value); - else if (tag == "ACOUSTID_ID") - track.acoustID = UUID::fromString(value); - else if (tag == "TRACKTOTAL") - { - auto totalTrack = StringUtils::readAs(value); - if (totalTrack) - track.totalTrack = totalTrack; - } - else if (tag == "TRACKNUMBER") - { - // Expecting 'Number/Total' - std::vector strings {splitAndTrimString(value, "/")}; - - if (!strings.empty()) - { - track.trackNumber = StringUtils::readAs(strings[0]); - - // Lower priority than TRACKTOTAL - if (strings.size() > 1 && !track.totalTrack) - track.totalTrack = StringUtils::readAs(strings[1]); - } - } - else if (tag == "DISCTOTAL") - { - auto totalDisc = StringUtils::readAs(value); - if (totalDisc) - track.totalDisc = totalDisc; - } - else if (tag == "DISCNUMBER") - { - // Expecting 'Number/Total' - std::vector strings {StringUtils::splitString(value, "/")}; - - if (!strings.empty()) - { - track.discNumber = StringUtils::readAs(strings[0]); - - // Lower priority than DISCTOTAL - if (strings.size() > 1 && !track.totalDisc) - track.totalDisc = StringUtils::readAs(strings[1]); - } - } - else if (tag == "DATE") - track.year = StringUtils::readAs(value); - else if (tag == "ORIGINALDATE" && !track.originalYear) - { - // Lower priority than ORIGINALYEAR - track.originalYear = StringUtils::readAs(value); - } - else if (tag == "ORIGINALYEAR") - { - // Higher priority than ORIGINALDATE - auto originalYear = StringUtils::readAs(value); - if (originalYear) - track.originalYear = originalYear; - } - else if (tag == "METADATA_BLOCK_PICTURE") - track.hasCover = true; - else if (tag == "COPYRIGHT") - track.copyright = value; - else if (tag == "COPYRIGHTURL") - track.copyrightURL = value; - else if (_clusterTypeNames.find(tag) != _clusterTypeNames.end()) - { - std::set clusterNames; - for (const auto& valueList : values) - { - auto values = splitAndTrimString(valueList.to8Bit(true), "/,;"); - - for (const auto& value : values) - clusterNames.insert(value); - } - - if (!clusterNames.empty()) - track.clusters[tag] = clusterNames; - } - } - - track.artists = getArtists(properties); - track.albumArtists = getAlbumArtists(properties); - track.album = getAlbum(properties); + const std::string tag {property.first.upper().to8Bit(true)}; + const TagLib::StringList& values {property.second}; + processTag(track, tag, values, debug); } + track.artists = getArtists(properties); + track.albumArtists = getAlbumArtists(properties); + track.album = getAlbum(properties); + return track; } diff --git a/src/libs/metadata/include/metadata/TagLibParser.hpp b/src/libs/metadata/include/metadata/TagLibParser.hpp index 1c055b76..ee298f8d 100644 --- a/src/libs/metadata/include/metadata/TagLibParser.hpp +++ b/src/libs/metadata/include/metadata/TagLibParser.hpp @@ -21,14 +21,21 @@ #include "metadata/IParser.hpp" +namespace TagLib +{ + class StringList; +} + namespace MetaData { // Parse that makes use of AvFormat class TagLibParser : public IParser { - public: + private: std::optional parse(const std::filesystem::path& p, bool debug = false) override; + + void processTag(Track& track, const std::string& tag, const TagLib::StringList& values, bool debug); }; } // namespace MetaData From 2c9952b8b71ea020d2c785030957a9164231e290 Mon Sep 17 00:00:00 2001 From: emeric Date: Sat, 28 Mar 2020 20:09:57 +0100 Subject: [PATCH 03/12] Switching from ImageMagick++ to GraphicsMagick++ to ease compatibility with wt4. ref #42 --- CMakeLists.txt | 2 +- src/libs/cover/CMakeLists.txt | 6 +++--- src/libs/cover/impl/CoverArtGrabber.cpp | 14 ++++++-------- src/libs/cover/impl/CoverArtGrabber.hpp | 4 +--- src/libs/cover/impl/Image.cpp | 6 ------ src/libs/cover/impl/Image.hpp | 1 - 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 516595ee..804bf495 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) include(CTest) find_package(PkgConfig) -pkg_check_modules(IMAGEMAGICKXX REQUIRED ImageMagick++) +pkg_check_modules(GRAPHICSMAGICKXX REQUIRED GraphicsMagick++) add_subdirectory(src) diff --git a/src/libs/cover/CMakeLists.txt b/src/libs/cover/CMakeLists.txt index 62eb5d43..cffb40b5 100644 --- a/src/libs/cover/CMakeLists.txt +++ b/src/libs/cover/CMakeLists.txt @@ -10,17 +10,17 @@ target_include_directories(lmscover INTERFACE target_include_directories(lmscover PRIVATE include - ${IMAGEMAGICKXX_INCLUDE_DIRS} + ${GRAPHICSMAGICKXX_INCLUDE_DIRS} ) target_compile_options(lmscover PRIVATE - ${IMAGEMAGICKXX_CFLAGS_OTHER} + ${GRAPHICSMAGICKXX_CFLAGS_OTHER} ) target_link_libraries(lmscover PRIVATE lmsav lmsdatabase - ${IMAGEMAGICKXX_LIBRARIES} + ${GRAPHICSMAGICKXX_LIBRARIES} ) install(TARGETS lmscover DESTINATION lib) diff --git a/src/libs/cover/impl/CoverArtGrabber.cpp b/src/libs/cover/impl/CoverArtGrabber.cpp index 110b80d1..38781cbc 100644 --- a/src/libs/cover/impl/CoverArtGrabber.cpp +++ b/src/libs/cover/impl/CoverArtGrabber.cpp @@ -49,15 +49,13 @@ Grabber::Grabber(const std::filesystem::path& execPath) init(execPath); } -Grabber::~Grabber() -{ - deinit(); -} - void Grabber::setDefaultCover(const std::filesystem::path& p) { - if (!_defaultCover.load(p)) + std::unique_lock lock {_mutex}; + + _defaultCover = std::make_unique(); + if (!_defaultCover->load(p)) throw LmsException("Cannot read default cover file '" + p.string() + "'"); } @@ -65,12 +63,12 @@ Image Grabber::getDefaultCover(std::size_t size) { LMS_LOG(COVER, DEBUG) << "Getting a default cover using size = " << size; - std::unique_lock lock(_mutex); + std::unique_lock lock {_mutex}; auto it = _defaultCovers.find(size); if (it == _defaultCovers.end()) { - Image cover = _defaultCover; + Image cover = *_defaultCover; LMS_LOG(COVER, DEBUG) << "default cover size = " << cover.getSize().width << " x " << cover.getSize().height; diff --git a/src/libs/cover/impl/CoverArtGrabber.hpp b/src/libs/cover/impl/CoverArtGrabber.hpp index bc921355..df932315 100644 --- a/src/libs/cover/impl/CoverArtGrabber.hpp +++ b/src/libs/cover/impl/CoverArtGrabber.hpp @@ -41,7 +41,6 @@ namespace CoverArt { public: Grabber(const std::filesystem::path& execPath); - ~Grabber(); Grabber(const Grabber&) = delete; Grabber& operator=(const Grabber&) = delete; @@ -63,9 +62,8 @@ namespace CoverArt std::optional getFromDirectory(const std::filesystem::path& path) const; Image getDefaultCover(std::size_t size); - Image _defaultCover; - std::mutex _mutex; + std::unique_ptr _defaultCover; std::map _defaultCovers; static inline const std::vector _fileExtensions {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize diff --git a/src/libs/cover/impl/Image.cpp b/src/libs/cover/impl/Image.cpp index a39c0061..f05fcc73 100644 --- a/src/libs/cover/impl/Image.cpp +++ b/src/libs/cover/impl/Image.cpp @@ -29,12 +29,6 @@ init(const std::filesystem::path& path) Magick::InitializeMagick(path.string().c_str()); } -void -deinit() -{ - MagickCore::MagickCoreTerminus(); -} - static std::string formatToMagick(Format format) diff --git a/src/libs/cover/impl/Image.hpp b/src/libs/cover/impl/Image.hpp index 6932825f..7abcb37c 100644 --- a/src/libs/cover/impl/Image.hpp +++ b/src/libs/cover/impl/Image.hpp @@ -30,7 +30,6 @@ namespace CoverArt { void init(const std::filesystem::path& path); - void deinit(); class Image { From e5e23009cbc3cd16dbcacecbc5ddda9bbd709ef6 Mon Sep 17 00:00:00 2001 From: emeric Date: Sat, 28 Mar 2020 20:15:26 +0100 Subject: [PATCH 04/12] Updated readme and travis scripts. ref #42 --- .travis.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f2f798b8..be9b1c71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ matrix: - gcc before_install: - eval "${MATRIX_EVAL}" -- sudo apt-get install build-essential cmake libboost-all-dev libconfig++-dev libavcodec-dev libavutil-dev libavformat-dev ffmpeg libmagick++-dev libpstreams-dev libconfig++-dev libpstreams-dev libtag1-dev +- sudo apt-get install build-essential cmake libboost-all-dev libconfig++-dev libavcodec-dev libavutil-dev libavformat-dev ffmpeg libgraphicsmagick++1-dev libpstreams-dev libconfig++-dev libpstreams-dev libtag1-dev - git clone https://github.com/emweb/wt.git wt - pushd wt; - git checkout 4.1.0 diff --git a/README.md b/README.md index 25b903a4..0a800149 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ __Notes__: * a C++17 compiler is needed * ffmpeg version 4 minimum is required ```sh -apt-get install g++ cmake libboost-system-dev libavutil-dev libavformat-dev libmagick++-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev +apt-get install g++ cmake libboost-system-dev libavutil-dev libavformat-dev libgraphicsmagick++1-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev ``` You also need _Wt4_, which is not packaged yet on _Debian_. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html).
@@ -208,6 +208,6 @@ To connect to _LMS_, just open your favorite browser and go to http://localhost: * Wt (http://www.webtoolkit.eu/) * bootstrap3 (http://getbootstrap.com/) * ffmpeg project (https://ffmpeg.org/) -* Magick++ (http://www.imagemagick.org/Magick++/) +* GraphicsMagick++ (http://www.graphicsmagick.org/) * MetaBrainz (https://metabrainz.org/) * Bootstrap Notify: https://github.com/mouse0270/bootstrap-notify From 7bad8ff98ba0802c12195c132d24e1156865179d Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 29 Mar 2020 14:06:35 +0200 Subject: [PATCH 05/12] Updated Dockerfile. ref #42 --- docker/Dockerfile | 75 ++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 4ac83cd4..6e404a0e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -5,7 +5,7 @@ WORKDIR /tmp/workdir ARG MAKEFLAGS="-j2" ARG FFMPEG_VERSION=4.1.4 ARG WT_VERSION=4.2.0 -ARG IMAGEMAGICK6_VERSION=6.9.10-71 +ARG GRAPHICSMAGICK_VERSION=1.3.35 ARG PSTREAMS_VERSION=1.0.1 ARG LMS_VERSION=v3.6.3 @@ -24,6 +24,7 @@ ARG BUILD_PACKAGES=" \ make \ libjpeg-turbo-dev \ openjpeg-dev \ + jasper-dev \ libpng-dev \ tiff-dev \ nasm \ @@ -95,50 +96,42 @@ RUN \ make && \ make install -# ImageMagick +# GraphicsMagick++ RUN \ - DIR=/tmp/imagemagick && mkdir -p ${DIR} && cd ${DIR} && \ - curl -sLO https://github.com/ImageMagick/ImageMagick6/archive/${IMAGEMAGICK6_VERSION}.tar.gz && \ - tar -x --strip-components=1 -f ${IMAGEMAGICK6_VERSION}.tar.gz + DIR=/tmp/graphicsmagick && mkdir -p ${DIR} && cd ${DIR} && \ + curl -sL ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/1.3/GraphicsMagick-${GRAPHICSMAGICK_VERSION}.tar.gz -o ${GRAPHICSMAGICK_VERSION}.tar.gz && \ + tar -x --strip-components=1 -f ${GRAPHICSMAGICK_VERSION}.tar.gz RUN \ - DIR=/tmp/imagemagick && mkdir -p ${DIR} && cd ${DIR} && \ + DIR=/tmp/graphicsmagick && mkdir -p ${DIR} && cd ${DIR} && \ ./configure \ --prefix=${PREFIX} \ --enable-shared=yes \ - --disable-static \ - --disable-docs \ - --with-magick-plus-plus \ - --without-zstd \ - --without-dps \ - --without-autotrace \ - --without-dps \ - --without-fftw \ - --without-flif \ - --without-fpx \ - --without-djvu \ - --without-fontconfig \ - --without-freetype \ - --without-raqm \ - --without-gslib \ - --without-gvc \ - --without-heic \ - --without-jbig \ - --with-jpeg \ - --without-jxl \ - --without-lcms \ - --with-openjp2 \ - --without-lqr \ - --with-lzma \ - --without-openexr \ - --without-pango \ - --with-png \ - --without-raw \ - --without-rsvg \ - --with-tiff \ - --without-webp \ - --without-wmf \ - --without-xml && \ + --enable-static=no \ + --with-quantum-depth=8 \ + --with-modules=no \ + --with-frozenpaths=no \ + --with-magick-plus-plus=yes \ + --with-perl=no \ + --with-bzlib=no \ + --with-dps=no \ + --with-fpx=no \ + --with-jbig=no \ + --with-webp=no \ + --with-jp2=yes \ + --with-jpeg=yes \ + --with-lcms2=no \ + --with-lzma=no \ + --with-png=yes \ + --with-tiff=yes \ + --with-trio=no \ + --with-ttf=no \ + --with-tcmalloc=no \ + --with-wmf=no \ + --with-xml=no \ + --with-zlib=yes \ + --with-zstd=no \ + --with-x=no && \ make && \ make install && \ make distclean @@ -178,7 +171,8 @@ RUN \ done && \ cp -r ${PREFIX}/lib /tmp/fakeroot/lib && \ cp -r ${PREFIX}/share /tmp/fakeroot/share && \ - LD_LIBRARY_PATH=/tmp/fakeroot/lib /tmp/fakeroot/bin/ffmpeg -buildconf + rm -rf /tmp/fakeroot/share/doc && \ + rm -rf /tmp/fakeroot/share/man ## Release Stage FROM alpine:3.10 AS release @@ -188,6 +182,7 @@ ARG RUNTIME_PACKAGES=" \ openssl \ libjpeg-turbo \ openjpeg \ + jasper-libs \ libpng \ tiff \ libogg \ From f5034e1e7b433fd470ea5535283ff7eb933ab3e7 Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 29 Mar 2020 14:16:58 +0200 Subject: [PATCH 06/12] Fix some compilation warnings --- .../recommendation/impl/clusters/ClustersClassifier.hpp | 2 +- .../recommendation/impl/features/FeaturesClassifier.hpp | 6 +++--- src/libs/subsonic/impl/ParameterParsing.cpp | 4 ++-- src/libs/subsonic/impl/ParameterParsing.hpp | 4 ++-- src/libs/subsonic/impl/SubsonicResource.cpp | 2 +- src/tools/recommendation/LmsRecommendation.cpp | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libs/recommendation/impl/clusters/ClustersClassifier.hpp b/src/libs/recommendation/impl/clusters/ClustersClassifier.hpp index 4619d5dc..53a7bd5f 100644 --- a/src/libs/recommendation/impl/clusters/ClustersClassifier.hpp +++ b/src/libs/recommendation/impl/clusters/ClustersClassifier.hpp @@ -36,7 +36,7 @@ namespace Recommendation private: - std::string_view getName() const { return "Clusters"; } + std::string_view getName() const override { return "Clusters"; } bool init(Database::Session&, bool) override {return true;} void requestCancelInit() override {} diff --git a/src/libs/recommendation/impl/features/FeaturesClassifier.hpp b/src/libs/recommendation/impl/features/FeaturesClassifier.hpp index ecf3b947..f20beec7 100644 --- a/src/libs/recommendation/impl/features/FeaturesClassifier.hpp +++ b/src/libs/recommendation/impl/features/FeaturesClassifier.hpp @@ -55,15 +55,15 @@ class FeaturesClassifier : public IClassifier static const FeatureSettingsMap& getDefaultTrainFeatureSettings(); private: - std::string_view getName() const { return "Features"; } + std::string_view getName() const override { return "Features"; } bool init(Database::Session& session, bool databaseChanged) override; void requestCancelInit() override; std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount) const override; std::vector getSimilarTracks(Database::Session& session, const std::unordered_set& tracksId, std::size_t maxCount) const override; - std::vector getSimilarReleases(Database::Session& session, Database::IdType releaseId, std::size_t maxCount) const; - std::vector getSimilarArtists(Database::Session& session, Database::IdType artistId, std::size_t maxCount) const; + std::vector getSimilarReleases(Database::Session& session, Database::IdType releaseId, std::size_t maxCount) const override; + std::vector getSimilarArtists(Database::Session& session, Database::IdType artistId, std::size_t maxCount) const override; bool initFromCache(Database::Session& session, const FeaturesClassifierCache& cache); diff --git a/src/libs/subsonic/impl/ParameterParsing.cpp b/src/libs/subsonic/impl/ParameterParsing.cpp index dbfd0656..48dc09e4 100644 --- a/src/libs/subsonic/impl/ParameterParsing.cpp +++ b/src/libs/subsonic/impl/ParameterParsing.cpp @@ -23,14 +23,14 @@ namespace StringUtils { template<> std::optional - StringUtils::readAs(const std::string& str) + readAs(const std::string& str) { return API::Subsonic::IdFromString(str); } template<> std::optional - StringUtils::readAs(const std::string& str) + readAs(const std::string& str) { if (str == "true") return true; diff --git a/src/libs/subsonic/impl/ParameterParsing.hpp b/src/libs/subsonic/impl/ParameterParsing.hpp index 4b503238..c5cb15f3 100644 --- a/src/libs/subsonic/impl/ParameterParsing.hpp +++ b/src/libs/subsonic/impl/ParameterParsing.hpp @@ -90,10 +90,10 @@ namespace StringUtils { template<> std::optional - StringUtils::readAs(const std::string& str); + readAs(const std::string& str); template<> std::optional - StringUtils::readAs(const std::string& str); + readAs(const std::string& str); } diff --git a/src/libs/subsonic/impl/SubsonicResource.cpp b/src/libs/subsonic/impl/SubsonicResource.cpp index c09a4c98..ed7c87ce 100644 --- a/src/libs/subsonic/impl/SubsonicResource.cpp +++ b/src/libs/subsonic/impl/SubsonicResource.cpp @@ -65,7 +65,7 @@ namespace StringUtils { template<> std::optional - StringUtils::readAs(const std::string& str) + readAs(const std::string& str) { // Expects "X.Y.Z" const auto numbers {StringUtils::splitString(str, ".")}; diff --git a/src/tools/recommendation/LmsRecommendation.cpp b/src/tools/recommendation/LmsRecommendation.cpp index 954af8c0..31af307d 100644 --- a/src/tools/recommendation/LmsRecommendation.cpp +++ b/src/tools/recommendation/LmsRecommendation.cpp @@ -88,7 +88,7 @@ dumpRecommendation(Database::Session session, Recommendation::IEngine& engine) }; std::cout << "Processing release '" << releaseToString(releaseId) << "'" << std::endl; - for (Database::IdType similarReleaseId : engine.getSimilarReleases(session, {releaseId}, 3)) + for (Database::IdType similarReleaseId : engine.getSimilarReleases(session, releaseId, 3)) std::cout << "\t- Similar release '" << releaseToString(similarReleaseId) << "'" << std::endl; } @@ -110,7 +110,7 @@ dumpRecommendation(Database::Session session, Recommendation::IEngine& engine) }; std::cout << "Processing artist '" << artistToString(artistId) << "'" << std::endl; - for (Database::IdType similarArtistId : engine.getSimilarArtists(session, {artistId}, 3)) + for (Database::IdType similarArtistId : engine.getSimilarArtists(session, artistId, 3)) std::cout << "\t- Similar artist '" << artistToString(similarArtistId) << "'" << std::endl; } From d8fa47c949939688646122a6b999149aadaf5556 Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 29 Mar 2020 14:20:29 +0200 Subject: [PATCH 07/12] Added missing includes. ref #42 --- src/libs/subsonic/impl/SubsonicResource.cpp | 1 + src/libs/utils/impl/String.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libs/subsonic/impl/SubsonicResource.cpp b/src/libs/subsonic/impl/SubsonicResource.cpp index ed7c87ce..11391e36 100644 --- a/src/libs/subsonic/impl/SubsonicResource.cpp +++ b/src/libs/subsonic/impl/SubsonicResource.cpp @@ -19,6 +19,7 @@ #include "subsonic/SubsonicResource.hpp" #include +#include #include diff --git a/src/libs/utils/impl/String.cpp b/src/libs/utils/impl/String.cpp index 1b181325..dbcb82d2 100644 --- a/src/libs/utils/impl/String.cpp +++ b/src/libs/utils/impl/String.cpp @@ -20,6 +20,7 @@ #include "utils/String.hpp" #include +#include #include #include From 8a09aa4e019196c6ea0c2610cda6b7c56bd6f996 Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 29 Mar 2020 18:41:26 +0200 Subject: [PATCH 08/12] Trying to find std::filesystem using cmake --- CMakeLists.txt | 6 +- cmake/modules/FindFilesystem.cmake | 233 +++++++++++++++++++++++++ src/libs/av/CMakeLists.txt | 1 + src/libs/cover/CMakeLists.txt | 6 +- src/libs/database/CMakeLists.txt | 1 + src/libs/metadata/CMakeLists.txt | 1 + src/libs/recommendation/CMakeLists.txt | 1 + src/libs/scanner/CMakeLists.txt | 1 + src/libs/subsonic/CMakeLists.txt | 1 + src/libs/utils/CMakeLists.txt | 2 +- 10 files changed, 250 insertions(+), 3 deletions(-) create mode 100755 cmake/modules/FindFilesystem.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 804bf495..69b4c9b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,15 @@ cmake_minimum_required(VERSION 3.10) 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) include(CTest) -find_package(PkgConfig) +find_package(PkgConfig REQUIRED) +find_package(Filesystem REQUIRED) pkg_check_modules(GRAPHICSMAGICKXX REQUIRED GraphicsMagick++) add_subdirectory(src) diff --git a/cmake/modules/FindFilesystem.cmake b/cmake/modules/FindFilesystem.cmake new file mode 100755 index 00000000..221130f8 --- /dev/null +++ b/cmake/modules/FindFilesystem.cmake @@ -0,0 +1,233 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: + +FindFilesystem +############## + +This module supports the C++17 standard library's filesystem utilities. Use the +:imp-target:`std::filesystem` imported target to + +Options +******* + +The ``COMPONENTS`` argument to this module supports the following values: + +.. find-component:: Experimental + :name: fs.Experimental + + Allows the module to find the "experimental" Filesystem TS version of the + Filesystem library. This is the library that should be used with the + ``std::experimental::filesystem`` namespace. + +.. find-component:: Final + :name: fs.Final + + Finds the final C++17 standard version of the filesystem library. + +If no components are provided, behaves as if the +:find-component:`fs.Final` component was specified. + +If both :find-component:`fs.Experimental` and :find-component:`fs.Final` are +provided, first looks for ``Final``, and falls back to ``Experimental`` in case +of failure. If ``Final`` is found, :imp-target:`std::filesystem` and all +:ref:`variables ` will refer to the ``Final`` version. + + +Imported Targets +**************** + +.. imp-target:: std::filesystem + + The ``std::filesystem`` imported target is defined when any requested + version of the C++ filesystem library has been found, whether it is + *Experimental* or *Final*. + + If no version of the filesystem library is available, this target will not + be defined. + + .. note:: + This target has ``cxx_std_17`` as an ``INTERFACE`` + :ref:`compile language standard feature `. Linking + to this target will automatically enable C++17 if no later standard + version is already required on the linking target. + + +.. _fs.variables: + +Variables +********* + +.. variable:: CXX_FILESYSTEM_IS_EXPERIMENTAL + + Set to ``TRUE`` when the :find-component:`fs.Experimental` version of C++ + filesystem library was found, otherwise ``FALSE``. + +.. variable:: CXX_FILESYSTEM_HAVE_FS + + Set to ``TRUE`` when a filesystem header was found. + +.. variable:: CXX_FILESYSTEM_HEADER + + Set to either ``filesystem`` or ``experimental/filesystem`` depending on + whether :find-component:`fs.Final` or :find-component:`fs.Experimental` was + found. + +.. variable:: CXX_FILESYSTEM_NAMESPACE + + Set to either ``std::filesystem`` or ``std::experimental::filesystem`` + depending on whether :find-component:`fs.Final` or + :find-component:`fs.Experimental` was found. + + +Examples +******** + +Using `find_package(Filesystem)` with no component arguments: + +.. code-block:: cmake + + find_package(Filesystem REQUIRED) + + add_executable(my-program main.cpp) + target_link_libraries(my-program PRIVATE std::filesystem) + + +#]=======================================================================] + + +if(TARGET std::filesystem) + # This module has already been processed. Don't do it again. + return() +endif() + +include(CMakePushCheckState) +include(CheckIncludeFileCXX) +include(CheckCXXSourceCompiles) + +cmake_push_check_state() + +set(CMAKE_REQUIRED_QUIET ${Filesystem_FIND_QUIETLY}) + +# All of our tests required C++17 or later +set(CMAKE_CXX_STANDARD 17) + +# Normalize and check the component list we were given +set(want_components ${Filesystem_FIND_COMPONENTS}) +if(Filesystem_FIND_COMPONENTS STREQUAL "") + set(want_components Final) +endif() + +# Warn on any unrecognized components +set(extra_components ${want_components}) +list(REMOVE_ITEM extra_components Final Experimental) +foreach(component IN LISTS extra_components) + message(WARNING "Extraneous find_package component for Filesystem: ${component}") +endforeach() + +# Detect which of Experimental and Final we should look for +set(find_experimental TRUE) +set(find_final TRUE) +if(NOT "Final" IN_LIST want_components) + set(find_final FALSE) +endif() +if(NOT "Experimental" IN_LIST want_components) + set(find_experimental FALSE) +endif() + +if(find_final) + check_include_file_cxx("filesystem" _CXX_FILESYSTEM_HAVE_HEADER) + mark_as_advanced(_CXX_FILESYSTEM_HAVE_HEADER) + if(_CXX_FILESYSTEM_HAVE_HEADER) + # We found the non-experimental header. Don't bother looking for the + # experimental one. + set(find_experimental FALSE) + endif() +else() + set(_CXX_FILESYSTEM_HAVE_HEADER FALSE) +endif() + +if(find_experimental) + check_include_file_cxx("experimental/filesystem" _CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) + mark_as_advanced(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) +else() + set(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER FALSE) +endif() + +if(_CXX_FILESYSTEM_HAVE_HEADER) + set(_have_fs TRUE) + set(_fs_header filesystem) + set(_fs_namespace std::filesystem) +elseif(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) + set(_have_fs TRUE) + set(_fs_header experimental/filesystem) + set(_fs_namespace std::experimental::filesystem) +else() + set(_have_fs FALSE) +endif() + +set(CXX_FILESYSTEM_HAVE_FS ${_have_fs} CACHE BOOL "TRUE if we have the C++ filesystem headers") +set(CXX_FILESYSTEM_HEADER ${_fs_header} CACHE STRING "The header that should be included to obtain the filesystem APIs") +set(CXX_FILESYSTEM_NAMESPACE ${_fs_namespace} CACHE STRING "The C++ namespace that contains the filesystem APIs") + +set(_found FALSE) + +if(CXX_FILESYSTEM_HAVE_FS) + # We have some filesystem library available. Do link checks + string(CONFIGURE [[ + #include <@CXX_FILESYSTEM_HEADER@> + + int main() { + auto cwd = @CXX_FILESYSTEM_NAMESPACE@::current_path(); + return static_cast(cwd.string().size()); + } + ]] code @ONLY) + + # Try to compile a simple filesystem program without any linker flags + check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED) + + set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED}) + + if(NOT CXX_FILESYSTEM_NO_LINK_NEEDED) + set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES}) + # Try to compile a simple filesystem program with the libstdc++ flag + set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lstdc++fs) + check_cxx_source_compiles("${code}" CXX_FILESYSTEM_STDCPPFS_NEEDED) + set(can_link ${CXX_FILESYSTEM_STDCPPFS_NEEDED}) + if(NOT CXX_FILESYSTEM_STDCPPFS_NEEDED) + # Try to compile a simple filesystem program with the libc++ flag + set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lc++fs) + check_cxx_source_compiles("${code}" CXX_FILESYSTEM_CPPFS_NEEDED) + set(can_link ${CXX_FILESYSTEM_CPPFS_NEEDED}) + if(NOT CXX_FILESYSTEM_CPPFS_NEEDED) + # Try to compile a simple filesystem program without any linker flags + check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED) + set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED}) + endif() + endif() + + endif() + + if(can_link) + add_library(std::filesystem INTERFACE IMPORTED) + target_compile_features(std::filesystem INTERFACE cxx_std_17) + set(_found TRUE) + + if(CXX_FILESYSTEM_NO_LINK_NEEDED) + # Nothing to add... + elseif(CXX_FILESYSTEM_STDCPPFS_NEEDED) + target_link_libraries(std::filesystem INTERFACE -lstdc++fs) + elseif(CXX_FILESYSTEM_CPPFS_NEEDED) + target_link_libraries(std::filesystem INTERFACE -lc++fs) + endif() + endif() +endif() + +cmake_pop_check_state() + +set(Filesystem_FOUND ${_found} CACHE BOOL "TRUE if we can compile and link a program using std::filesystem" FORCE) + +if(Filesystem_FIND_REQUIRED AND NOT Filesystem_FOUND) + message(FATAL_ERROR "Cannot Compile simple program using std::filesystem") +endif() diff --git a/src/libs/av/CMakeLists.txt b/src/libs/av/CMakeLists.txt index adb37766..d79974ac 100644 --- a/src/libs/av/CMakeLists.txt +++ b/src/libs/av/CMakeLists.txt @@ -19,6 +19,7 @@ target_link_libraries(lmsav PUBLIC lmsutils avformat avutil + std::filesystem wt ) diff --git a/src/libs/cover/CMakeLists.txt b/src/libs/cover/CMakeLists.txt index cffb40b5..2e540725 100644 --- a/src/libs/cover/CMakeLists.txt +++ b/src/libs/cover/CMakeLists.txt @@ -19,9 +19,13 @@ target_compile_options(lmscover PRIVATE target_link_libraries(lmscover PRIVATE lmsav - lmsdatabase ${GRAPHICSMAGICKXX_LIBRARIES} ) +target_link_libraries(lmscover PUBLIC + lmsdatabase + std::filesystem + ) + install(TARGETS lmscover DESTINATION lib) diff --git a/src/libs/database/CMakeLists.txt b/src/libs/database/CMakeLists.txt index 638fb2e2..a7eba7e2 100644 --- a/src/libs/database/CMakeLists.txt +++ b/src/libs/database/CMakeLists.txt @@ -30,6 +30,7 @@ target_link_libraries(lmsdatabase PRIVATE target_link_libraries(lmsdatabase PUBLIC lmsutils + std::filesystem wtdbo ) diff --git a/src/libs/metadata/CMakeLists.txt b/src/libs/metadata/CMakeLists.txt index cc6a1dbb..0fc6da2d 100644 --- a/src/libs/metadata/CMakeLists.txt +++ b/src/libs/metadata/CMakeLists.txt @@ -19,6 +19,7 @@ target_link_libraries(lmsmetadata PRIVATE target_link_libraries(lmsmetadata PUBLIC lmsutils + std::filesystem ) install(TARGETS lmsmetadata DESTINATION lib) diff --git a/src/libs/recommendation/CMakeLists.txt b/src/libs/recommendation/CMakeLists.txt index b7a52f12..35243f50 100644 --- a/src/libs/recommendation/CMakeLists.txt +++ b/src/libs/recommendation/CMakeLists.txt @@ -18,6 +18,7 @@ target_include_directories(lmsrecommendation PRIVATE target_link_libraries(lmsrecommendation PRIVATE lmsdatabase lmssom + std::filesystem wt ) diff --git a/src/libs/scanner/CMakeLists.txt b/src/libs/scanner/CMakeLists.txt index 57fae63a..2ec7539e 100644 --- a/src/libs/scanner/CMakeLists.txt +++ b/src/libs/scanner/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(lmsscanner PRIVATE ) target_link_libraries(lmsscanner PUBLIC + std::filesystem wt ) diff --git a/src/libs/subsonic/CMakeLists.txt b/src/libs/subsonic/CMakeLists.txt index e5743a37..34d3d68d 100644 --- a/src/libs/subsonic/CMakeLists.txt +++ b/src/libs/subsonic/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(lmssubsonic PRIVATE lmscover lmsrecommendation lmsutils + std::filesystem ) target_link_libraries(lmssubsonic PUBLIC diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index e3cd2e9e..2dbf4d2c 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -26,7 +26,7 @@ target_link_libraries(lmsutils PRIVATE target_link_libraries(lmsutils PUBLIC boost_system - stdc++fs + std::filesystem wt ) From 3727c64a13af2c54f112a37512b8a59788f21967 Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 29 Mar 2020 19:37:48 +0200 Subject: [PATCH 09/12] Fixed exit (make freebsd 12.1 happy when exiting. ref #42 --- src/lms/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lms/main.cpp b/src/lms/main.cpp index 54fe076c..16c333d1 100644 --- a/src/lms/main.cpp +++ b/src/lms/main.cpp @@ -197,6 +197,8 @@ int main(int argc, char* argv[]) LMS_LOG(MAIN, INFO) << "Stopping recommendation engine..."; recommendationEngine.stop(); + ServiceProvider::clear(); + LMS_LOG(MAIN, INFO) << "Clean stop!"; res = EXIT_SUCCESS; } From eb20ade14d69667acc3e6b1cdf14ba1e2f3f1183 Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 29 Mar 2020 20:07:52 +0200 Subject: [PATCH 10/12] Added an option to set the deployment path. Fixes #41 --- README.md | 2 +- conf/lms.conf | 3 +++ src/libs/subsonic/include/subsonic/SubsonicResource.hpp | 2 +- src/lms/main.cpp | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a800149..2738d002 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ systemctl restart lms __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, ...). +_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, ...). diff --git a/conf/lms.conf b/conf/lms.conf index 2c186cb3..04d48d54 100644 --- a/conf/lms.conf +++ b/conf/lms.conf @@ -18,6 +18,9 @@ listen-port = 5082; listen-addr = "0.0.0.0"; behind-reverse-proxy = false; +# Location for deployment +deploy-path = "/"; + # If enabled, these files have to exist and have correct permissions tls-enable = false; tls-cert = "/var/lms/cert.pem"; diff --git a/src/libs/subsonic/include/subsonic/SubsonicResource.hpp b/src/libs/subsonic/include/subsonic/SubsonicResource.hpp index af9bc53c..1d8746e7 100644 --- a/src/libs/subsonic/include/subsonic/SubsonicResource.hpp +++ b/src/libs/subsonic/include/subsonic/SubsonicResource.hpp @@ -36,7 +36,7 @@ class SubsonicResource final : public Wt::WResource public: SubsonicResource(Database::Db& db); - static std::string getPath() { return "/rest/"; } + static std::string getPath() { return "rest/"; } private: void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) override; diff --git a/src/lms/main.cpp b/src/lms/main.cpp index 16c333d1..18dcd7f2 100644 --- a/src/lms/main.cpp +++ b/src/lms/main.cpp @@ -48,6 +48,7 @@ std::vector generateWtConfig(std::string execPath) args.push_back("--config=" + wtConfigPath.string()); args.push_back("--docroot=" + ServiceProvider::get()->getString("docroot")); args.push_back("--approot=" + ServiceProvider::get()->getString("approot")); + args.push_back("--deploy-path=" + ServiceProvider::get()->getString("deploy-path", "/")); args.push_back("--resources-dir=" + ServiceProvider::get()->getString("wt-resources")); if (ServiceProvider::get()->getBool("tls-enable", false)) From 4105b3ea8251b966934fd0d2537939d65587655b Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 30 Mar 2020 15:26:37 +0200 Subject: [PATCH 11/12] Upgrade requirements to build on ubuntu --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index be9b1c71..19156a46 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,9 @@ matrix: sources: - ubuntu-toolchain-r-test packages: - - g++-8 + - g++-9 env: - - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" + - MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" compiler: - gcc before_install: @@ -19,7 +19,7 @@ before_install: - sudo apt-get install build-essential cmake libboost-all-dev libconfig++-dev libavcodec-dev libavutil-dev libavformat-dev ffmpeg libgraphicsmagick++1-dev libpstreams-dev libconfig++-dev libpstreams-dev libtag1-dev - git clone https://github.com/emweb/wt.git wt - pushd wt; -- git checkout 4.1.0 +- git checkout 4.2.1 - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr && sudo make install - popd script: cmake -DCMAKE_BUILD_TYPE=Release . && make && make test From fb7484f9e0ab2fb7c36b448665dcedfa2f980708 Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 30 Mar 2020 21:05:36 +0200 Subject: [PATCH 12/12] Now running tests during docker image generation --- docker/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 6e404a0e..e3ed986c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -151,8 +151,9 @@ RUN \ RUN \ DIR=/tmp/lms && mkdir -p ${DIR} && cd ${DIR} && \ - PKG_CONFIG_PATH=/tmp/install/lib/pkgconfig CXXFLAGS="-I${PREFIX}/include -L${PREFIX}/lib -Wl,--rpath-link=${PREFIX}/lib" cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} && \ + PKG_CONFIG_PATH=/tmp/install/lib/pkgconfig CXXFLAGS="-I${PREFIX}/include" LDFLAGS="-L${PREFIX}/lib -Wl,--rpath-link=${PREFIX}/lib" cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} && \ make && \ + LD_LIBRARY_PATH=${PREFIX}/lib make test && \ make install && \ mkdir -p ${PREFIX}/etc/ && \ cp conf/lms.conf ${PREFIX}/etc