diff --git a/README.md b/README.md index 5f6ed2bb..637db883 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ The Subsonic API is enabled by default. ## Installation Here are the required packages to build LMS on Debian Stretch: ```sh -apt-get install g++ autoconf automake libboost-filesystem-dev libboost-system-dev libavcodec-dev libavutil-dev libavformat-dev libav-tools libmagick++-dev libpstreams-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev libcurl4-openssl-dev +apt-get install g++ autoconf automake libboost-filesystem-dev libboost-system-dev libavcodec-dev libavutil-dev libavformat-dev libav-tools libmagick++-dev libpstreams-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev ``` You also need wt4, that is not packaged yet on Debian. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html). You may need to build Wt4 in "Release" mode if you want to compile it natively on a Raspberry Pi3B+. diff --git a/configure.ac b/configure.ac index 8c64b518..1a6908d7 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ fi AC_SUBST(MAGICKXX_CFLAGS) AC_SUBST(MAGICKXX_LIBS) -AC_CHECK_HEADERS([Wt/WApplication.h pstreams/pstream.h curl/curl.h], +AC_CHECK_HEADERS([Wt/WApplication.h pstreams/pstream.h], [], [AC_MSG_ERROR([Header not found or unusable !])]) @@ -81,11 +81,6 @@ AC_CHECK_LIB( [config++], , [AC_MSG_ERROR([libconfig++ not found!])]) -AC_CHECK_LIB( [curl], - [curl_easy_init], - , - [AC_MSG_ERROR([libcurl not found!])]) - AC_CONFIG_FILES([Makefile src/Makefile test/Makefile diff --git a/src/similarity/features/AcousticBrainzUtils.cpp b/src/similarity/features/AcousticBrainzUtils.cpp index 9a302da7..d550e06e 100644 --- a/src/similarity/features/AcousticBrainzUtils.cpp +++ b/src/similarity/features/AcousticBrainzUtils.cpp @@ -21,7 +21,9 @@ #include #include -#include + +#include +#include #include "main/Service.hpp" #include "utils/Config.hpp" @@ -31,63 +33,52 @@ namespace AcousticBrainz { - -static size_t writeToOStringStream(void *buffer, size_t size, size_t nmemb, void* ctx) -{ - std::ostringstream& oss = *reinterpret_cast(ctx); - - oss.write(reinterpret_cast(buffer), size * nmemb); - - return size * nmemb; -} - static std::string getJsonData(const std::string& mbid) { static const std::string defaultAPIURL = "https://acousticbrainz.org/api/v1/"; - std::string data; - std::string url = getService()->getString("acousticbrainz-api-url", defaultAPIURL) + mbid + "/low-level"; + const std::string url {getService()->getString("acousticbrainz-api-url", defaultAPIURL) + mbid + "/low-level"}; - CURL *curl; - CURLcode res; + boost::asio::io_service ioService; - curl = curl_easy_init(); - if (!curl) + Wt::Http::Client client {ioService}; + client.setFollowRedirect(true); + client.setSslCertificateVerificationEnabled(true); + client.setMaximumResponseSize(256*1024); + + if (!client.get(url)) { - LMS_LOG(SIMILARITY, ERROR) << "CURL init failed"; - return data; + LMS_LOG(SIMILARITY, ERROR) << "Cannot perform a GET request to url '" << url << "'"; + return {}; } - std::ostringstream oss; - - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeToOStringStream); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss); - - res = curl_easy_perform(curl); - if (res != CURLE_OK) + std::string response; + client.done().connect([&](Wt::AsioWrapper::error_code ec, const Wt::Http::Message &msg) { - LMS_LOG(SIMILARITY, ERROR) << "CURL perform failed: " << curl_easy_strerror(res); - return data; - } + if (ec) + { + LMS_LOG(SIMILARITY, ERROR) << "GET request to url '" << url << "' failed: " << ec.message(); + return; + } - curl_easy_cleanup(curl); + if (msg.status() != 200) + { + LMS_LOG(SIMILARITY, ERROR) << "GET request to url '" << url << "' failed: status = " << msg.status() << ", body = " << msg.body(); + return; + } - data = std::move(oss.str()); + response = msg.body(); + }); - return data; + ioService.run(); + + return response; } std::string extractLowLevelFeatures(const std::string& mbid) { - if (boost::filesystem::exists("/storage/emeric/lms-dev/features/" + mbid)) - { - std::ifstream ifs{std::string{"/storage/emeric/lms-dev/features/" + mbid}.c_str()}; - return std::string {std::istreambuf_iterator{ifs}, std::istreambuf_iterator{}}; - } - return getJsonData(mbid); } diff --git a/src/similarity/features/SimilarityFeaturesScannerAddon.cpp b/src/similarity/features/SimilarityFeaturesScannerAddon.cpp index 713906c0..3a044c71 100644 --- a/src/similarity/features/SimilarityFeaturesScannerAddon.cpp +++ b/src/similarity/features/SimilarityFeaturesScannerAddon.cpp @@ -160,22 +160,22 @@ FeaturesScannerAddon::fetchFeatures(Database::IdType trackId, const std::string& std::map features; LMS_LOG(DBUPDATER, DEBUG) << "Fetching low level features for track '" << MBID << "'"; - std::string data {AcousticBrainz::extractLowLevelFeatures(MBID)}; + const std::string data {AcousticBrainz::extractLowLevelFeatures(MBID)}; if (data.empty()) { LMS_LOG(DBUPDATER, ERROR) << "Track " << trackId << ", MBID = '" << MBID << "': cannot extract features using AcousticBrainz"; return false; } - auto uniqueTransaction {_dbSession->createUniqueTransaction()}; + { + auto uniqueTransaction {_dbSession->createUniqueTransaction()}; - Wt::Dbo::ptr track {Database::Track::getById(*_dbSession, trackId)}; - if (!track) - return false; + Wt::Dbo::ptr track {Database::Track::getById(*_dbSession, trackId)}; + if (!track) + return false; - LMS_LOG(DBUPDATER, DEBUG) << "Successfully extracted AcousticBrainz lowlevel features for track '" << track->getPath().string() << "'"; - - Database::TrackFeatures::create(*_dbSession, track, data); + Database::TrackFeatures::create(*_dbSession, track, data); + } return true; }