Updated the Service interface
This commit is contained in:
@@ -20,7 +20,6 @@ lms_SOURCES = \
|
|||||||
$(srcdir)/database/User.cpp \
|
$(srcdir)/database/User.cpp \
|
||||||
$(srcdir)/image/Image.cpp \
|
$(srcdir)/image/Image.cpp \
|
||||||
$(srcdir)/main/main.cpp \
|
$(srcdir)/main/main.cpp \
|
||||||
$(srcdir)/main/Services.cpp \
|
|
||||||
$(srcdir)/metadata/AvFormat.cpp \
|
$(srcdir)/metadata/AvFormat.cpp \
|
||||||
$(srcdir)/metadata/TagLibParser.cpp \
|
$(srcdir)/metadata/TagLibParser.cpp \
|
||||||
$(srcdir)/scanner/MediaScanner.cpp \
|
$(srcdir)/scanner/MediaScanner.cpp \
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#include "database/Release.hpp"
|
#include "database/Release.hpp"
|
||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
#include "database/TrackList.hpp"
|
#include "database/TrackList.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "similarity/SimilaritySearcher.hpp"
|
#include "similarity/SimilaritySearcher.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
@@ -880,7 +880,7 @@ Response handleGetArtistInfoRequestCommon(RequestContext& context, bool id3)
|
|||||||
if (!artist->getMBID().empty())
|
if (!artist->getMBID().empty())
|
||||||
artistInfoNode.createChild("musicBrainzId").setValue(artist->getMBID());
|
artistInfoNode.createChild("musicBrainzId").setValue(artist->getMBID());
|
||||||
|
|
||||||
auto similarArtistsId {getServices().similaritySearcher->getSimilarArtists(context.db.getSession(), artist.id(), count)};
|
auto similarArtistsId {getService<Similarity::Searcher>()->getSimilarArtists(context.db.getSession(), artist.id(), count)};
|
||||||
for ( const auto& similarArtistId : similarArtistsId )
|
for ( const auto& similarArtistId : similarArtistsId )
|
||||||
{
|
{
|
||||||
Database::Artist::pointer similarArtist {Database::Artist::getById(context.db.getSession(), similarArtistId)};
|
Database::Artist::pointer similarArtist {Database::Artist::getById(context.db.getSession(), similarArtistId)};
|
||||||
@@ -1059,7 +1059,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3)
|
|||||||
// "Returns a random collection of songs from the given artist and similar artists"
|
// "Returns a random collection of songs from the given artist and similar artists"
|
||||||
auto tracks {artist->getRandomTracks(count / 2)};
|
auto tracks {artist->getRandomTracks(count / 2)};
|
||||||
|
|
||||||
auto similarArtistsId {getServices().similaritySearcher->getSimilarArtists(context.db.getSession(), artist.id(), 5)};
|
auto similarArtistsId {getService<Similarity::Searcher>()->getSimilarArtists(context.db.getSession(), artist.id(), 5)};
|
||||||
for ( const auto& similarArtistId : similarArtistsId )
|
for ( const auto& similarArtistId : similarArtistsId )
|
||||||
{
|
{
|
||||||
Database::Artist::pointer similarArtist {Database::Artist::getById(context.db.getSession(), similarArtistId)};
|
Database::Artist::pointer similarArtist {Database::Artist::getById(context.db.getSession(), similarArtistId)};
|
||||||
@@ -1433,10 +1433,10 @@ handleGetCoverArt(RequestContext& context, Wt::Http::ResponseContinuation* conti
|
|||||||
switch (id.type)
|
switch (id.type)
|
||||||
{
|
{
|
||||||
case Id::Type::Track:
|
case Id::Type::Track:
|
||||||
cover = getServices().coverArtGrabber->getFromTrack(context.db.getSession(), id.value, Image::Format::JPEG, size);
|
cover = getService<CoverArt::Grabber>()->getFromTrack(context.db.getSession(), id.value, Image::Format::JPEG, size);
|
||||||
break;
|
break;
|
||||||
case Id::Type::Release:
|
case Id::Type::Release:
|
||||||
cover = getServices().coverArtGrabber->getFromRelease(context.db.getSession(), id.value, Image::Format::JPEG, size);
|
cover = getService<CoverArt::Grabber>()->getFromRelease(context.db.getSession(), id.value, Image::Format::JPEG, size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw Error {Error::CustomType::BadId};
|
throw Error {Error::CustomType::BadId};
|
||||||
|
|||||||
@@ -19,26 +19,36 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace CoverArt
|
template <typename T>
|
||||||
|
class ServiceProvider
|
||||||
{
|
{
|
||||||
class Grabber;
|
public:
|
||||||
}
|
|
||||||
|
|
||||||
namespace Scanner {
|
template <class ...Args>
|
||||||
class MediaScanner;
|
static
|
||||||
}
|
T&
|
||||||
|
create(Args&&... args)
|
||||||
|
{
|
||||||
|
assign(std::make_unique<T>(std::forward<Args>(args)...));
|
||||||
|
return *get();
|
||||||
|
}
|
||||||
|
static void assign(std::unique_ptr<T> service) { _service = std::move(service); }
|
||||||
|
static void clear() { _service.reset(); }
|
||||||
|
|
||||||
namespace Similarity {
|
static T* get() { return _service.get(); }
|
||||||
class Searcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private:
|
||||||
struct Services
|
static std::unique_ptr<T> _service;
|
||||||
{
|
|
||||||
std::unique_ptr<CoverArt::Grabber> coverArtGrabber;
|
|
||||||
std::unique_ptr<Scanner::MediaScanner> mediaScanner;
|
|
||||||
std::unique_ptr<Similarity::Searcher> similaritySearcher;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Services& getServices();
|
template <typename T>
|
||||||
|
std::unique_ptr<T> ServiceProvider<T>::_service = {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T*
|
||||||
|
getService()
|
||||||
|
{
|
||||||
|
return ServiceProvider<T>::get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 Emeric Poupon
|
|
||||||
*
|
|
||||||
* This file is part of LMS.
|
|
||||||
*
|
|
||||||
* LMS is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* LMS is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Services.hpp"
|
|
||||||
|
|
||||||
#include "cover/CoverArtGrabber.hpp"
|
|
||||||
#include "scanner/MediaScanner.hpp"
|
|
||||||
#include "similarity/SimilaritySearcher.hpp"
|
|
||||||
|
|
||||||
Services& getServices()
|
|
||||||
{
|
|
||||||
static Services services;
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
+9
-8
@@ -34,7 +34,7 @@
|
|||||||
#include "ui/LmsApplication.hpp"
|
#include "ui/LmsApplication.hpp"
|
||||||
#include "utils/Config.hpp"
|
#include "utils/Config.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "Services.hpp"
|
#include "Service.hpp"
|
||||||
|
|
||||||
std::vector<std::string> generateWtConfig(std::string execPath)
|
std::vector<std::string> generateWtConfig(std::string execPath)
|
||||||
{
|
{
|
||||||
@@ -127,15 +127,16 @@ int main(int argc, char* argv[])
|
|||||||
UserInterface::LmsApplicationGroupContainer appGroups;
|
UserInterface::LmsApplicationGroupContainer appGroups;
|
||||||
|
|
||||||
// Service initialization order is important
|
// Service initialization order is important
|
||||||
getServices().mediaScanner = std::make_unique<Scanner::MediaScanner>(*connectionPool);
|
Scanner::MediaScanner& mediaScanner {ServiceProvider<Scanner::MediaScanner>::create(*connectionPool)};
|
||||||
|
|
||||||
Similarity::FeaturesScannerAddon similarityFeaturesScannerAddon(*connectionPool);
|
Similarity::FeaturesScannerAddon similarityFeaturesScannerAddon(*connectionPool);
|
||||||
|
|
||||||
getServices().mediaScanner->setAddon(similarityFeaturesScannerAddon);
|
mediaScanner.setAddon(similarityFeaturesScannerAddon);
|
||||||
getServices().coverArtGrabber = std::make_unique<CoverArt::Grabber>();
|
|
||||||
getServices().coverArtGrabber->setDefaultCover(server.appRoot() + "/images/unknown-cover.jpg");
|
|
||||||
|
|
||||||
getServices().similaritySearcher = std::make_unique<Similarity::Searcher>(similarityFeaturesScannerAddon);
|
CoverArt::Grabber& coverArtGrabber {ServiceProvider<CoverArt::Grabber>::create()};
|
||||||
|
coverArtGrabber.setDefaultCover(server.appRoot() + "/images/unknown-cover.jpg");
|
||||||
|
|
||||||
|
ServiceProvider<Similarity::Searcher>::create(similarityFeaturesScannerAddon);
|
||||||
|
|
||||||
API::Subsonic::SubsonicResource subsonicResource {*connectionPool};
|
API::Subsonic::SubsonicResource subsonicResource {*connectionPool};
|
||||||
|
|
||||||
@@ -153,7 +154,7 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// Start
|
// Start
|
||||||
LMS_LOG(MAIN, INFO) << "Starting media scanner...";
|
LMS_LOG(MAIN, INFO) << "Starting media scanner...";
|
||||||
getServices().mediaScanner->start();
|
mediaScanner.start();
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Starting server...";
|
LMS_LOG(MAIN, INFO) << "Starting server...";
|
||||||
server.start();
|
server.start();
|
||||||
@@ -167,7 +168,7 @@ int main(int argc, char* argv[])
|
|||||||
server.stop();
|
server.stop();
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Stopping media scanner...";
|
LMS_LOG(MAIN, INFO) << "Stopping media scanner...";
|
||||||
getServices().mediaScanner->stop();
|
mediaScanner.stop();
|
||||||
|
|
||||||
LMS_LOG(MAIN, INFO) << "Clean stop!";
|
LMS_LOG(MAIN, INFO) << "Clean stop!";
|
||||||
res = EXIT_SUCCESS;
|
res = EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#include "database/Cluster.hpp"
|
#include "database/Cluster.hpp"
|
||||||
#include "database/Release.hpp"
|
#include "database/Release.hpp"
|
||||||
#include "explore/Explore.hpp"
|
#include "explore/Explore.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
|
|
||||||
@@ -459,7 +459,7 @@ LmsApplication::createHome()
|
|||||||
|
|
||||||
// Events from MediaScanner
|
// Events from MediaScanner
|
||||||
std::string sessionId = LmsApp->sessionId();
|
std::string sessionId = LmsApp->sessionId();
|
||||||
getServices().mediaScanner->scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
|
getService<Scanner::MediaScanner>()->scanComplete().connect([=] (Scanner::MediaScanner::Stats stats)
|
||||||
{
|
{
|
||||||
// Runs from media scanner context
|
// Runs from media scanner context
|
||||||
Wt::WServer::instance()->post(sessionId, [=]
|
Wt::WServer::instance()->post(sessionId, [=]
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include <Wt/WText.h>
|
#include <Wt/WText.h>
|
||||||
|
|
||||||
#include "database/TrackList.hpp"
|
#include "database/TrackList.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "similarity/SimilaritySearcher.hpp"
|
#include "similarity/SimilaritySearcher.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "LmsApplication.hpp"
|
#include "LmsApplication.hpp"
|
||||||
@@ -399,7 +399,7 @@ PlayQueue::addRadioTrack()
|
|||||||
if (trackIds.empty())
|
if (trackIds.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto res = getServices().similaritySearcher->getSimilarTracks(LmsApp->getDboSession(), std::set<Database::IdType>(trackIds.begin(), trackIds.end()), 1);
|
auto res = getService<Similarity::Searcher>()->getSimilarTracks(LmsApp->getDboSession(), std::set<Database::IdType>(trackIds.begin(), trackIds.end()), 1);
|
||||||
for (auto trackId : res)
|
for (auto trackId : res)
|
||||||
{
|
{
|
||||||
auto trackToAdd = Database::Track::getById(LmsApp->getDboSession(), trackId);
|
auto trackToAdd = Database::Track::getById(LmsApp->getDboSession(), trackId);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include <Wt/WTemplateFormView.h>
|
#include <Wt/WTemplateFormView.h>
|
||||||
|
|
||||||
#include "database/Cluster.hpp"
|
#include "database/Cluster.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ DatabaseSettingsView::refreshView()
|
|||||||
{
|
{
|
||||||
model->saveData();
|
model->saveData();
|
||||||
|
|
||||||
getServices().mediaScanner->reschedule();
|
getService<Scanner::MediaScanner>()->reschedule();
|
||||||
LmsApp->notifyMsg(MsgType::Success, Wt::WString::tr("Lms.Admin.Database.settings-saved"));
|
LmsApp->notifyMsg(MsgType::Success, Wt::WString::tr("Lms.Admin.Database.settings-saved"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ DatabaseSettingsView::refreshView()
|
|||||||
|
|
||||||
immScanBtn->clicked().connect([=] ()
|
immScanBtn->clicked().connect([=] ()
|
||||||
{
|
{
|
||||||
getServices().mediaScanner->scheduleImmediateScan();
|
getService<Scanner::MediaScanner>()->scheduleImmediateScan();
|
||||||
LmsApp->notifyMsg(MsgType::Info, Wt::WString::tr("Lms.Admin.Database.scan-launched"));
|
LmsApp->notifyMsg(MsgType::Info, Wt::WString::tr("Lms.Admin.Database.scan-launched"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "ArtistInfoView.hpp"
|
#include "ArtistInfoView.hpp"
|
||||||
|
|
||||||
#include "database/Artist.hpp"
|
#include "database/Artist.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "similarity/SimilaritySearcher.hpp"
|
#include "similarity/SimilaritySearcher.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ ArtistInfo::refresh()
|
|||||||
if (!artistId)
|
if (!artistId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto artistsIds = getServices().similaritySearcher->getSimilarArtists(LmsApp->getDboSession(), *artistId, 5);
|
auto artistsIds = getService<Similarity::Searcher>()->getSimilarArtists(LmsApp->getDboSession(), *artistId, 5);
|
||||||
|
|
||||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include <Wt/WAnchor.h>
|
#include <Wt/WAnchor.h>
|
||||||
|
|
||||||
#include "database/Release.hpp"
|
#include "database/Release.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "similarity/SimilaritySearcher.hpp"
|
#include "similarity/SimilaritySearcher.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ ReleaseInfo::refresh()
|
|||||||
if (!releaseId)
|
if (!releaseId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<Database::IdType> releasesIds {getServices().similaritySearcher->getSimilarReleases(LmsApp->getDboSession(), *releaseId, 5)};
|
std::vector<Database::IdType> releasesIds {getService<Similarity::Searcher>()->getSimilarReleases(LmsApp->getDboSession(), *releaseId, 5)};
|
||||||
|
|
||||||
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
|
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "cover/CoverArtGrabber.hpp"
|
#include "cover/CoverArtGrabber.hpp"
|
||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
#include "main/Services.hpp"
|
#include "main/Service.hpp"
|
||||||
#include "utils/Exception.hpp"
|
#include "utils/Exception.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
@@ -80,7 +80,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
// transactions are not thread safe
|
// transactions are not thread safe
|
||||||
{
|
{
|
||||||
Wt::WApplication::UpdateLock lock(LmsApp);
|
Wt::WApplication::UpdateLock lock(LmsApp);
|
||||||
cover = getServices().coverArtGrabber->getFromTrack(LmsApp->getDboSession(), *trackId, Image::Format::JPEG, *size);
|
cover = getService<CoverArt::Grabber>()->getFromTrack(LmsApp->getDboSession(), *trackId, Image::Format::JPEG, *size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (releaseIdStr)
|
else if (releaseIdStr)
|
||||||
@@ -92,7 +92,7 @@ ImageResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
// transactions are not thread safe
|
// transactions are not thread safe
|
||||||
{
|
{
|
||||||
Wt::WApplication::UpdateLock lock(LmsApp);
|
Wt::WApplication::UpdateLock lock(LmsApp);
|
||||||
cover = getServices().coverArtGrabber->getFromRelease(LmsApp->getDboSession(), *releaseId, Image::Format::JPEG, *size);
|
cover = getService<CoverArt::Grabber>()->getFromRelease(LmsApp->getDboSession(), *releaseId, Image::Format::JPEG, *size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user