From 7fc5aef553b24f7b8b8cf2502e991cecd7b4af66 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Fri, 21 Apr 2023 20:20:53 +0200 Subject: [PATCH] Use one instance of NetworkAccessManager --- src/CMakeLists.txt | 2 - src/core/application.cpp | 52 +++++++---- src/core/application.h | 2 + src/core/mainwindow.cpp | 4 +- src/core/songloader.cpp | 6 +- src/core/songloader.h | 4 +- .../albumcoverchoicecontroller.cpp | 4 +- src/covermanager/albumcoverfetcher.cpp | 4 +- src/covermanager/albumcoverfetcher.h | 2 +- src/covermanager/albumcoverloader.cpp | 4 +- src/covermanager/albumcoverloader.h | 6 +- src/covermanager/albumcovermanager.cpp | 2 +- src/covermanager/coverfromurldialog.cpp | 5 +- src/covermanager/coverfromurldialog.h | 5 +- src/covermanager/coverproviders.cpp | 3 +- src/covermanager/coverproviders.h | 5 - src/device/cddadevice.cpp | 4 +- src/device/cddasongloader.cpp | 6 +- src/device/cddasongloader.h | 7 +- src/dialogs/edittagdialog.cpp | 2 +- src/lyrics/lyricsproviders.cpp | 3 +- src/lyrics/lyricsproviders.h | 5 - src/musicbrainz/acoustidclient.cpp | 4 +- src/musicbrainz/acoustidclient.h | 2 +- src/musicbrainz/musicbrainzclient.cpp | 4 +- src/musicbrainz/musicbrainzclient.h | 2 +- src/musicbrainz/tagfetcher.cpp | 7 +- src/musicbrainz/tagfetcher.h | 3 +- src/playlist/playlist.cpp | 4 +- src/playlist/songloaderinserter.cpp | 10 +- src/playlist/songloaderinserter.h | 4 +- src/qobuz/qobuzservice.cpp | 2 +- src/radios/radioservices.cpp | 2 +- src/scrobbler/audioscrobbler.cpp | 91 +++++++++++++++---- src/scrobbler/audioscrobbler.h | 39 +++++--- src/scrobbler/lastfmimport.cpp | 4 +- src/scrobbler/lastfmimport.h | 2 +- src/scrobbler/lastfmscrobbler.cpp | 7 +- src/scrobbler/lastfmscrobbler.h | 5 +- src/scrobbler/librefmscrobbler.cpp | 7 +- src/scrobbler/librefmscrobbler.h | 5 +- src/scrobbler/listenbrainzscrobbler.cpp | 25 +++-- src/scrobbler/listenbrainzscrobbler.h | 6 +- src/scrobbler/scrobblerservice.cpp | 6 +- src/scrobbler/scrobblerservice.h | 4 +- src/scrobbler/scrobblerservices.cpp | 73 --------------- src/scrobbler/scrobblerservices.h | 64 ------------- src/scrobbler/scrobblingapi20.cpp | 25 +++-- src/scrobbler/scrobblingapi20.h | 6 +- src/scrobbler/subsonicscrobbler.cpp | 20 ++-- src/scrobbler/subsonicscrobbler.h | 5 +- src/subsonic/subsonicservice.cpp | 4 + src/tidal/tidalservice.cpp | 2 +- 53 files changed, 270 insertions(+), 311 deletions(-) delete mode 100644 src/scrobbler/scrobblerservices.cpp delete mode 100644 src/scrobbler/scrobblerservices.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1e5650d..abba8320 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -268,7 +268,6 @@ set(SOURCES radios/radioparadiseservice.cpp scrobbler/audioscrobbler.cpp - scrobbler/scrobblerservices.cpp scrobbler/scrobblerservice.cpp scrobbler/scrobblercache.cpp scrobbler/scrobblercacheitem.cpp @@ -503,7 +502,6 @@ set(HEADERS radios/radioparadiseservice.h scrobbler/audioscrobbler.h - scrobbler/scrobblerservices.h scrobbler/scrobblerservice.h scrobbler/scrobblercache.h scrobbler/scrobblingapi20.h diff --git a/src/core/application.cpp b/src/core/application.cpp index 50c88ff9..06a8c17e 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -38,6 +38,7 @@ #include "database.h" #include "taskmanager.h" #include "player.h" +#include "networkaccessmanager.h" #include "engine/devicefinders.h" #ifndef Q_OS_WIN @@ -66,7 +67,13 @@ #include "lyrics/lyricscomlyricsprovider.h" #include "scrobbler/audioscrobbler.h" +#include "scrobbler/lastfmscrobbler.h" +#include "scrobbler/librefmscrobbler.h" +#include "scrobbler/listenbrainzscrobbler.h" #include "scrobbler/lastfmimport.h" +#ifdef HAVE_SUBSONIC +# include "scrobbler/subsonicscrobbler.h" +#endif #include "internet/internetservices.h" @@ -111,6 +118,7 @@ class ApplicationImpl { }), task_manager_([app]() { return new TaskManager(app); }), player_([app]() { return new Player(app, app); }), + network_([app]() { return new NetworkAccessManager(app); }), device_finders_([app]() { return new DeviceFinders(app); }), #ifndef Q_OS_WIN device_manager_([app]() { return new DeviceManager(app, app); }), @@ -125,23 +133,23 @@ class ApplicationImpl { cover_providers_([app]() { CoverProviders *cover_providers = new CoverProviders(app); // Initialize the repository of cover providers. - cover_providers->AddProvider(new LastFmCoverProvider(app, cover_providers->network(), app)); - cover_providers->AddProvider(new MusicbrainzCoverProvider(app, cover_providers->network(), app)); - cover_providers->AddProvider(new DiscogsCoverProvider(app, cover_providers->network(), app)); - cover_providers->AddProvider(new DeezerCoverProvider(app, cover_providers->network(), app)); - cover_providers->AddProvider(new MusixmatchCoverProvider(app, cover_providers->network(), app)); - cover_providers->AddProvider(new SpotifyCoverProvider(app, cover_providers->network(), app)); + cover_providers->AddProvider(new LastFmCoverProvider(app, app->network(), app)); + cover_providers->AddProvider(new MusicbrainzCoverProvider(app, app->network(), app)); + cover_providers->AddProvider(new DiscogsCoverProvider(app, app->network(), app)); + cover_providers->AddProvider(new DeezerCoverProvider(app, app->network(), app)); + cover_providers->AddProvider(new MusixmatchCoverProvider(app, app->network(), app)); + cover_providers->AddProvider(new SpotifyCoverProvider(app, app->network(), app)); #ifdef HAVE_TIDAL - cover_providers->AddProvider(new TidalCoverProvider(app, cover_providers->network(), app)); + cover_providers->AddProvider(new TidalCoverProvider(app, app->network(), app)); #endif #ifdef HAVE_QOBUZ - cover_providers->AddProvider(new QobuzCoverProvider(app, cover_providers->network(), app)); + cover_providers->AddProvider(new QobuzCoverProvider(app, app->network(), app)); #endif cover_providers->ReloadSettings(); return cover_providers; }), album_cover_loader_([app]() { - AlbumCoverLoader *loader = new AlbumCoverLoader(app); + AlbumCoverLoader *loader = new AlbumCoverLoader(app->network(), app); app->MoveToNewThread(loader); return loader; }), @@ -149,13 +157,13 @@ class ApplicationImpl { lyrics_providers_([app]() { LyricsProviders *lyrics_providers = new LyricsProviders(app); // Initialize the repository of lyrics providers. - lyrics_providers->AddProvider(new AuddLyricsProvider(lyrics_providers->network(), app)); - lyrics_providers->AddProvider(new GeniusLyricsProvider(lyrics_providers->network(), app)); - lyrics_providers->AddProvider(new OVHLyricsProvider(lyrics_providers->network(), app)); - lyrics_providers->AddProvider(new LoloLyricsProvider(lyrics_providers->network(), app)); - lyrics_providers->AddProvider(new MusixmatchLyricsProvider(lyrics_providers->network(), app)); - lyrics_providers->AddProvider(new ChartLyricsProvider(lyrics_providers->network(), app)); - lyrics_providers->AddProvider(new LyricsComLyricsProvider(lyrics_providers->network(), app)); + lyrics_providers->AddProvider(new AuddLyricsProvider(app->network(), app)); + lyrics_providers->AddProvider(new GeniusLyricsProvider(app->network(), app)); + lyrics_providers->AddProvider(new OVHLyricsProvider(app->network(), app)); + lyrics_providers->AddProvider(new LoloLyricsProvider(app->network(), app)); + lyrics_providers->AddProvider(new MusixmatchLyricsProvider(app->network(), app)); + lyrics_providers->AddProvider(new ChartLyricsProvider(app->network(), app)); + lyrics_providers->AddProvider(new LyricsComLyricsProvider(app->network(), app)); lyrics_providers->ReloadSettings(); return lyrics_providers; }), @@ -173,18 +181,25 @@ class ApplicationImpl { return internet_services; }), radio_services_([app]() { return new RadioServices(app, app); }), - scrobbler_([app]() { return new AudioScrobbler(app, app); }), + scrobbler_([app]() { + AudioScrobbler *scrobbler = new AudioScrobbler(app); + scrobbler->AddService(new LastFMScrobbler(scrobbler, app->network(), app)); + scrobbler->AddService(new LibreFMScrobbler(scrobbler, app->network(), app)); + scrobbler->AddService(new ListenBrainzScrobbler(scrobbler, app->network(), app)); + return scrobbler; + }), #ifdef HAVE_MOODBAR moodbar_loader_([app]() { return new MoodbarLoader(app, app); }), moodbar_controller_([app]() { return new MoodbarController(app, app); }), #endif - lastfm_import_([app]() { return new LastFMImport(app); }) + lastfm_import_([app]() { return new LastFMImport(app->network(), app); }) {} Lazy tag_reader_client_; Lazy database_; Lazy task_manager_; Lazy player_; + Lazy network_; Lazy device_finders_; #ifndef Q_OS_WIN Lazy device_manager_; @@ -317,6 +332,7 @@ TagReaderClient *Application::tag_reader_client() const { return p_->tag_reader_ Database *Application::database() const { return p_->database_.get(); } TaskManager *Application::task_manager() const { return p_->task_manager_.get(); } Player *Application::player() const { return p_->player_.get(); } +NetworkAccessManager *Application::network() const { return p_->network_.get(); } DeviceFinders *Application::device_finders() const { return p_->device_finders_.get(); } #ifndef Q_OS_WIN DeviceManager *Application::device_manager() const { return p_->device_manager_.get(); } diff --git a/src/core/application.h b/src/core/application.h index b793f209..7f9c9c8e 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -41,6 +41,7 @@ class TagReaderClient; class Database; class DeviceFinders; class Player; +class NetworkAccessManager; class SCollection; class CollectionBackend; class CollectionModel; @@ -74,6 +75,7 @@ class Application : public QObject { Database *database() const; TaskManager *task_manager() const; Player *player() const; + NetworkAccessManager *network() const; DeviceFinders *device_finders() const; #ifndef Q_OS_WIN DeviceManager *device_manager() const; diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 19e309b8..56ff8dd8 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -1024,7 +1024,7 @@ MainWindow::MainWindow(Application *app, std::shared_ptr tray_ic if (!sparkle_url.isEmpty()) { qLog(Debug) << "Creating Qt Sparkle updater"; qtsparkle::Updater *updater = new qtsparkle::Updater(sparkle_url, this); - updater->SetNetworkAccessManager(new NetworkAccessManager(this)); + updater->SetNetworkAccessManager(app->network()); updater->SetVersion(STRAWBERRY_VERSION_PACKAGE); QObject::connect(check_updates, &QAction::triggered, updater, &qtsparkle::Updater::CheckNow); } @@ -2933,7 +2933,7 @@ void MainWindow::AutoCompleteTags() { // Create the tag fetching stuff if it hasn't been already if (!tag_fetcher_) { - tag_fetcher_ = std::make_unique(); + tag_fetcher_ = std::make_unique(app_->network()); track_selection_dialog_ = std::make_unique(); track_selection_dialog_->set_save_on_close(true); diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index c4ec0862..2ecf20f0 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -46,6 +46,7 @@ #include "signalchecker.h" #include "player.h" +#include "networkaccessmanager.h" #include "song.h" #include "songloader.h" #include "tagreaderclient.h" @@ -66,9 +67,10 @@ QSet SongLoader::sRawUriSchemes; const int SongLoader::kDefaultTimeout = 5000; -SongLoader::SongLoader(CollectionBackendInterface *collection, const Player *player, QObject *parent) +SongLoader::SongLoader(CollectionBackendInterface *collection, const Player *player, NetworkAccessManager *network, QObject *parent) : QObject(parent), player_(player), + network_(network), collection_(collection), timeout_timer_(new QTimer(this)), playlist_parser_(new PlaylistParser(collection, this)), @@ -191,7 +193,7 @@ SongLoader::Result SongLoader::LoadAudioCD() { #if defined(HAVE_AUDIOCD) && defined(HAVE_GSTREAMER) if (player_->engine()->type() == Engine::EngineType::GStreamer) { - CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this); + CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), network_, this); QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot); QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded); cdda_song_loader->LoadSongs(); diff --git a/src/core/songloader.h b/src/core/songloader.h index 1bfddab8..5c851482 100644 --- a/src/core/songloader.h +++ b/src/core/songloader.h @@ -45,6 +45,7 @@ class QTimer; class Player; +class NetworkAccessManager; class CollectionBackendInterface; class PlaylistParser; class ParserBase; @@ -58,7 +59,7 @@ class SongLoader : public QObject { Q_OBJECT public: - explicit SongLoader(CollectionBackendInterface *collection, const Player *player, QObject *parent = nullptr); + explicit SongLoader(CollectionBackendInterface *collection, const Player *player, NetworkAccessManager *network, QObject *parent = nullptr); ~SongLoader() override; enum class Result { @@ -144,6 +145,7 @@ class SongLoader : public QObject { SongList songs_; const Player *player_; + NetworkAccessManager *network_; CollectionBackendInterface *collection_; QTimer *timeout_timer_; PlaylistParser *playlist_parser_; diff --git a/src/covermanager/albumcoverchoicecontroller.cpp b/src/covermanager/albumcoverchoicecontroller.cpp index eb21d5d0..c8d7abba 100644 --- a/src/covermanager/albumcoverchoicecontroller.cpp +++ b/src/covermanager/albumcoverchoicecontroller.cpp @@ -132,7 +132,7 @@ void AlbumCoverChoiceController::Init(Application *app) { app_ = app; - cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), this); + cover_fetcher_ = new AlbumCoverFetcher(app_->cover_providers(), app->network(), this); cover_searcher_ = new AlbumCoverSearcher(QIcon(":/pictures/cdcase.png"), app, this); cover_searcher_->Init(cover_fetcher_); @@ -322,7 +322,7 @@ QUrl AlbumCoverChoiceController::LoadCoverFromURL(Song *song) { AlbumCoverImageResultPtr AlbumCoverChoiceController::LoadImageFromURL() { - if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(this); } + if (!cover_from_url_dialog_) { cover_from_url_dialog_ = new CoverFromURLDialog(app_->network(), this); } return cover_from_url_dialog_->Exec(); diff --git a/src/covermanager/albumcoverfetcher.cpp b/src/covermanager/albumcoverfetcher.cpp index fe2bff92..bde617d1 100644 --- a/src/covermanager/albumcoverfetcher.cpp +++ b/src/covermanager/albumcoverfetcher.cpp @@ -37,10 +37,10 @@ using namespace std::chrono_literals; const int AlbumCoverFetcher::kMaxConcurrentRequests = 5; -AlbumCoverFetcher::AlbumCoverFetcher(CoverProviders *cover_providers, QObject *parent, NetworkAccessManager *network) +AlbumCoverFetcher::AlbumCoverFetcher(CoverProviders *cover_providers, NetworkAccessManager *network, QObject *parent) : QObject(parent), cover_providers_(cover_providers), - network_(network ? network : new NetworkAccessManager(this)), + network_(network), next_id_(0), request_starter_(new QTimer(this)) { diff --git a/src/covermanager/albumcoverfetcher.h b/src/covermanager/albumcoverfetcher.h index 40297e1b..54344fc8 100644 --- a/src/covermanager/albumcoverfetcher.h +++ b/src/covermanager/albumcoverfetcher.h @@ -107,7 +107,7 @@ class AlbumCoverFetcher : public QObject { Q_OBJECT public: - explicit AlbumCoverFetcher(CoverProviders *cover_providers, QObject *parent = nullptr, NetworkAccessManager *network = nullptr); + explicit AlbumCoverFetcher(CoverProviders *cover_providers, NetworkAccessManager *network, QObject *parent = nullptr); ~AlbumCoverFetcher() override; static const int kMaxConcurrentRequests; diff --git a/src/covermanager/albumcoverloader.cpp b/src/covermanager/albumcoverloader.cpp index 2bf53771..5abaadf4 100644 --- a/src/covermanager/albumcoverloader.cpp +++ b/src/covermanager/albumcoverloader.cpp @@ -53,12 +53,12 @@ #include "albumcoverloaderresult.h" #include "albumcoverimageresult.h" -AlbumCoverLoader::AlbumCoverLoader(QObject *parent) +AlbumCoverLoader::AlbumCoverLoader(NetworkAccessManager *network, QObject *parent) : QObject(parent), + network_(network), stop_requested_(false), load_image_async_id_(1), save_image_async_id_(1), - network_(new NetworkAccessManager(this)), original_thread_(nullptr) { original_thread_ = thread(); diff --git a/src/covermanager/albumcoverloader.h b/src/covermanager/albumcoverloader.h index b5ad1e41..7bb57811 100644 --- a/src/covermanager/albumcoverloader.h +++ b/src/covermanager/albumcoverloader.h @@ -51,7 +51,7 @@ class AlbumCoverLoader : public QObject { Q_OBJECT public: - explicit AlbumCoverLoader(QObject *parent = nullptr); + explicit AlbumCoverLoader(NetworkAccessManager *network, QObject *parent = nullptr); enum class State { None, @@ -135,6 +135,8 @@ class AlbumCoverLoader : public QObject { void NextState(TaskPtr task); TryLoadResult TryLoadImage(TaskPtr task); + NetworkAccessManager *network_; + bool stop_requested_; QMutex mutex_load_image_async_; @@ -144,8 +146,6 @@ class AlbumCoverLoader : public QObject { quint64 load_image_async_id_; quint64 save_image_async_id_; - NetworkAccessManager *network_; - static const int kMaxRedirects = 3; QThread *original_thread_; diff --git a/src/covermanager/albumcovermanager.cpp b/src/covermanager/albumcovermanager.cpp index cafe75d4..7a30ef09 100644 --- a/src/covermanager/albumcovermanager.cpp +++ b/src/covermanager/albumcovermanager.cpp @@ -106,7 +106,7 @@ AlbumCoverManager::AlbumCoverManager(Application *app, CollectionBackend *collec filter_all_(nullptr), filter_with_covers_(nullptr), filter_without_covers_(nullptr), - cover_fetcher_(new AlbumCoverFetcher(app_->cover_providers(), this)), + cover_fetcher_(new AlbumCoverFetcher(app_->cover_providers(), app_->network(), this)), cover_searcher_(nullptr), cover_export_(nullptr), cover_exporter_(new AlbumCoverExporter(this)), diff --git a/src/covermanager/coverfromurldialog.cpp b/src/covermanager/coverfromurldialog.cpp index 5c6693b0..b4fc6a7b 100644 --- a/src/covermanager/coverfromurldialog.cpp +++ b/src/covermanager/coverfromurldialog.cpp @@ -40,7 +40,10 @@ #include "coverfromurldialog.h" #include "ui_coverfromurldialog.h" -CoverFromURLDialog::CoverFromURLDialog(QWidget *parent) : QDialog(parent), ui_(new Ui_CoverFromURLDialog), network_(new NetworkAccessManager(this)) { +CoverFromURLDialog::CoverFromURLDialog(NetworkAccessManager *network, QWidget *parent) + : QDialog(parent), + network_(network), + ui_(new Ui_CoverFromURLDialog) { ui_->setupUi(this); ui_->busy->hide(); diff --git a/src/covermanager/coverfromurldialog.h b/src/covermanager/coverfromurldialog.h index 0386ba3e..3f1724a7 100644 --- a/src/covermanager/coverfromurldialog.h +++ b/src/covermanager/coverfromurldialog.h @@ -40,7 +40,7 @@ class CoverFromURLDialog : public QDialog { Q_OBJECT public: - explicit CoverFromURLDialog(QWidget *parent = nullptr); + explicit CoverFromURLDialog(NetworkAccessManager *network, QWidget *parent = nullptr); ~CoverFromURLDialog() override; // Opens the dialog. This returns an image found at the URL chosen by user or null image if the dialog got rejected. @@ -51,9 +51,8 @@ class CoverFromURLDialog : public QDialog { void LoadCoverFromURLFinished(); private: - Ui_CoverFromURLDialog *ui_; - NetworkAccessManager *network_; + Ui_CoverFromURLDialog *ui_; AlbumCoverImageResultPtr last_album_cover_; }; diff --git a/src/covermanager/coverproviders.cpp b/src/covermanager/coverproviders.cpp index 651718c2..b958cff6 100644 --- a/src/covermanager/coverproviders.cpp +++ b/src/covermanager/coverproviders.cpp @@ -30,7 +30,6 @@ #include #include "core/logging.h" -#include "core/networkaccessmanager.h" #include "coverprovider.h" #include "coverproviders.h" @@ -38,7 +37,7 @@ int CoverProviders::NextOrderId = 0; -CoverProviders::CoverProviders(QObject *parent) : QObject(parent), network_(new NetworkAccessManager(this)) {} +CoverProviders::CoverProviders(QObject *parent) : QObject(parent) {} CoverProviders::~CoverProviders() { diff --git a/src/covermanager/coverproviders.h b/src/covermanager/coverproviders.h index 294cbc28..56b10691 100644 --- a/src/covermanager/coverproviders.h +++ b/src/covermanager/coverproviders.h @@ -32,7 +32,6 @@ #include #include -class NetworkAccessManager; class CoverProvider; // This is a repository for cover providers. @@ -60,8 +59,6 @@ class CoverProviders : public QObject { int NextId(); - NetworkAccessManager *network() const { return network_; } - private slots: void ProviderDestroyed(); @@ -70,8 +67,6 @@ class CoverProviders : public QObject { static int NextOrderId; - NetworkAccessManager *network_; - QMap cover_providers_; QMutex mutex_; diff --git a/src/device/cddadevice.cpp b/src/device/cddadevice.cpp index b259953c..ddd499ba 100644 --- a/src/device/cddadevice.cpp +++ b/src/device/cddadevice.cpp @@ -24,6 +24,8 @@ #include #include +#include "core/application.h" +#include "core/networkaccessmanager.h" #include "collection/collectionmodel.h" #include "cddasongloader.h" #include "connecteddevice.h" @@ -35,7 +37,7 @@ class DeviceManager; CddaDevice::CddaDevice(const QUrl &url, DeviceLister *lister, const QString &unique_id, DeviceManager *manager, Application *app, int database_id, bool first_time, QObject *parent) : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time, parent), - cdda_song_loader_(url) { + cdda_song_loader_(url, app->network()) { QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsLoaded, this, &CddaDevice::SongsLoaded); QObject::connect(&cdda_song_loader_, &CddaSongLoader::SongsDurationLoaded, this, &CddaDevice::SongsLoaded); diff --git a/src/device/cddasongloader.cpp b/src/device/cddasongloader.cpp index 7a5c3baf..6d5a214e 100644 --- a/src/device/cddasongloader.cpp +++ b/src/device/cddasongloader.cpp @@ -39,11 +39,13 @@ #include "cddasongloader.h" #include "core/logging.h" +#include "core/networkaccessmanager.h" #include "utilities/timeconstants.h" -CddaSongLoader::CddaSongLoader(const QUrl &url, QObject *parent) +CddaSongLoader::CddaSongLoader(const QUrl &url, NetworkAccessManager *network, QObject *parent) : QObject(parent), url_(url), + network_(network), cdda_(nullptr), cdio_(nullptr) {} @@ -195,7 +197,7 @@ void CddaSongLoader::LoadSongs() { QString musicbrainz_discid(string_mb); qLog(Info) << "MusicBrainz discid: " << musicbrainz_discid; - MusicBrainzClient *musicbrainz_client = new MusicBrainzClient; + MusicBrainzClient *musicbrainz_client = new MusicBrainzClient(network_); QObject::connect(musicbrainz_client, &MusicBrainzClient::DiscIdFinished, this, &CddaSongLoader::AudioCDTagsLoaded); musicbrainz_client->StartDiscIdRequest(musicbrainz_discid); g_free(string_mb); diff --git a/src/device/cddasongloader.h b/src/device/cddasongloader.h index 0bac971c..2450851d 100644 --- a/src/device/cddasongloader.h +++ b/src/device/cddasongloader.h @@ -40,12 +40,14 @@ # include "musicbrainz/musicbrainzclient.h" #endif +class NetworkAccessManager; + // This class provides a (hopefully) nice, high level interface to get CD information and load tracks class CddaSongLoader : public QObject { Q_OBJECT public: - explicit CddaSongLoader(const QUrl &url = QUrl(), QObject *parent = nullptr); + explicit CddaSongLoader(const QUrl &url, NetworkAccessManager *network, QObject *parent = nullptr); ~CddaSongLoader() override; // Load songs. Signals declared below will be emitted anytime new information will be available. @@ -68,7 +70,8 @@ class CddaSongLoader : public QObject { #endif private: - QUrl url_; + const QUrl url_; + NetworkAccessManager *network_; GstElement *cdda_; CdIo_t *cdio_; QMutex mutex_load_; diff --git a/src/dialogs/edittagdialog.cpp b/src/dialogs/edittagdialog.cpp index 755af5e8..06ea1e43 100644 --- a/src/dialogs/edittagdialog.cpp +++ b/src/dialogs/edittagdialog.cpp @@ -109,7 +109,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent) app_(app), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), #ifdef HAVE_MUSICBRAINZ - tag_fetcher_(new TagFetcher(this)), + tag_fetcher_(new TagFetcher(app->network(), this)), results_dialog_(new TrackSelectionDialog(this)), #endif image_no_cover_thumbnail_(ImageUtils::GenerateNoCoverImage(QSize(128, 128))), diff --git a/src/lyrics/lyricsproviders.cpp b/src/lyrics/lyricsproviders.cpp index e572a45b..d5ebc113 100644 --- a/src/lyrics/lyricsproviders.cpp +++ b/src/lyrics/lyricsproviders.cpp @@ -28,7 +28,6 @@ #include #include "core/logging.h" -#include "core/networkaccessmanager.h" #include "lyricsprovider.h" #include "lyricsproviders.h" @@ -37,7 +36,7 @@ int LyricsProviders::NextOrderId = 0; -LyricsProviders::LyricsProviders(QObject *parent) : QObject(parent), network_(new NetworkAccessManager(this)) {} +LyricsProviders::LyricsProviders(QObject *parent) : QObject(parent) {} LyricsProviders::~LyricsProviders() { diff --git a/src/lyrics/lyricsproviders.h b/src/lyrics/lyricsproviders.h index 789f4965..6ab2adb5 100644 --- a/src/lyrics/lyricsproviders.h +++ b/src/lyrics/lyricsproviders.h @@ -30,7 +30,6 @@ #include #include -class NetworkAccessManager; class LyricsProvider; class LyricsProviders : public QObject { @@ -49,8 +48,6 @@ class LyricsProviders : public QObject { bool HasAnyProviders() const { return !lyrics_providers_.isEmpty(); } int NextId(); - NetworkAccessManager *network() const { return network_; } - private slots: void ProviderDestroyed(); @@ -59,8 +56,6 @@ class LyricsProviders : public QObject { static int NextOrderId; - NetworkAccessManager *network_; - QMap lyrics_providers_; QList ordered_providers_; QMutex mutex_; diff --git a/src/musicbrainz/acoustidclient.cpp b/src/musicbrainz/acoustidclient.cpp index a8e649c4..4b6d2709 100644 --- a/src/musicbrainz/acoustidclient.cpp +++ b/src/musicbrainz/acoustidclient.cpp @@ -50,9 +50,9 @@ const char *AcoustidClient::kClientId = "0qjUoxbowg"; const char *AcoustidClient::kUrl = "https://api.acoustid.org/v2/lookup"; const int AcoustidClient::kDefaultTimeout = 5000; // msec -AcoustidClient::AcoustidClient(QObject *parent) +AcoustidClient::AcoustidClient(NetworkAccessManager *network, QObject *parent) : QObject(parent), - network_(new NetworkAccessManager(this)), + network_(network), timeouts_(new NetworkTimeouts(kDefaultTimeout, this)) {} AcoustidClient::~AcoustidClient() { diff --git a/src/musicbrainz/acoustidclient.h b/src/musicbrainz/acoustidclient.h index 8c20656c..86a345d4 100644 --- a/src/musicbrainz/acoustidclient.h +++ b/src/musicbrainz/acoustidclient.h @@ -43,7 +43,7 @@ class AcoustidClient : public QObject { // IDs are provided by the caller when a request is started and included in the Finished signal - they have no meaning to AcoustidClient. public: - explicit AcoustidClient(QObject *parent = nullptr); + explicit AcoustidClient(NetworkAccessManager *network, QObject *parent = nullptr); ~AcoustidClient() override; // Network requests will be aborted after this interval. diff --git a/src/musicbrainz/musicbrainzclient.cpp b/src/musicbrainz/musicbrainzclient.cpp index aa77a0bd..b04893f5 100644 --- a/src/musicbrainz/musicbrainzclient.cpp +++ b/src/musicbrainz/musicbrainzclient.cpp @@ -55,9 +55,9 @@ const int MusicBrainzClient::kRequestsDelay = 1200; const int MusicBrainzClient::kDefaultTimeout = 8000; const int MusicBrainzClient::kMaxRequestPerTrack = 3; -MusicBrainzClient::MusicBrainzClient(QObject *parent, QNetworkAccessManager *network) +MusicBrainzClient::MusicBrainzClient(QNetworkAccessManager *network, QObject *parent) : QObject(parent), - network_(network ? network : new NetworkAccessManager(this)), + network_(network), timeouts_(new NetworkTimeouts(kDefaultTimeout, this)), timer_flush_requests_(new QTimer(this)) { diff --git a/src/musicbrainz/musicbrainzclient.h b/src/musicbrainz/musicbrainzclient.h index b3deceba..5c96121d 100644 --- a/src/musicbrainz/musicbrainzclient.h +++ b/src/musicbrainz/musicbrainzclient.h @@ -50,7 +50,7 @@ class MusicBrainzClient : public QObject { public: // The second argument allows for specifying a custom network access manager. // It is used in tests. The ownership of network is not transferred. - explicit MusicBrainzClient(QObject *parent = nullptr, QNetworkAccessManager *network = nullptr); + explicit MusicBrainzClient(QNetworkAccessManager *network, QObject *parent = nullptr); ~MusicBrainzClient() override; struct Result { diff --git a/src/musicbrainz/tagfetcher.cpp b/src/musicbrainz/tagfetcher.cpp index d230866b..5d023bf5 100644 --- a/src/musicbrainz/tagfetcher.cpp +++ b/src/musicbrainz/tagfetcher.cpp @@ -29,17 +29,18 @@ #include #include +#include "core/networkaccessmanager.h" #include "utilities/timeconstants.h" #include "engine/chromaprinter.h" #include "acoustidclient.h" #include "musicbrainzclient.h" #include "tagfetcher.h" -TagFetcher::TagFetcher(QObject *parent) +TagFetcher::TagFetcher(NetworkAccessManager *network, QObject *parent) : QObject(parent), fingerprint_watcher_(nullptr), - acoustid_client_(new AcoustidClient(this)), - musicbrainz_client_(new MusicBrainzClient(this)) { + acoustid_client_(new AcoustidClient(network, this)), + musicbrainz_client_(new MusicBrainzClient(network, this)) { QObject::connect(acoustid_client_, &AcoustidClient::Finished, this, &TagFetcher::PuidsFound); QObject::connect(musicbrainz_client_, &MusicBrainzClient::Finished, this, &TagFetcher::TagsFetched); diff --git a/src/musicbrainz/tagfetcher.h b/src/musicbrainz/tagfetcher.h index b4c15179..b0a1cd7d 100644 --- a/src/musicbrainz/tagfetcher.h +++ b/src/musicbrainz/tagfetcher.h @@ -32,6 +32,7 @@ #include "core/song.h" #include "musicbrainzclient.h" +class NetworkAccessManager; class AcoustidClient; class TagFetcher : public QObject { @@ -40,7 +41,7 @@ class TagFetcher : public QObject { // High level interface to Fingerprinter, AcoustidClient and MusicBrainzClient. public: - explicit TagFetcher(QObject *parent = nullptr); + explicit TagFetcher(NetworkAccessManager *network, QObject *parent = nullptr); void StartFetch(const SongList &songs); diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp index 3967545a..1445cd83 100644 --- a/src/playlist/playlist.cpp +++ b/src/playlist/playlist.cpp @@ -845,7 +845,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, int ro } } else if (data->hasFormat(kCddaMimeType)) { - SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player()); + SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player(), backend_->app()->network()); QObject::connect(inserter, &SongLoaderInserter::Error, this, &Playlist::Error); inserter->LoadAudioCD(this, row, play_now, enqueue_now, enqueue_next_now); } @@ -860,7 +860,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, int ro void Playlist::InsertUrls(const QList &urls, const int pos, const bool play_now, const bool enqueue, const bool enqueue_next) { - SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player()); + SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player(), backend_->app()->network()); QObject::connect(inserter, &SongLoaderInserter::Error, this, &Playlist::Error); inserter->Load(this, pos, play_now, enqueue, enqueue_next, urls); diff --git a/src/playlist/songloaderinserter.cpp b/src/playlist/songloaderinserter.cpp index 4bec6d15..4ddcaf94 100644 --- a/src/playlist/songloaderinserter.cpp +++ b/src/playlist/songloaderinserter.cpp @@ -29,10 +29,11 @@ #include "core/logging.h" #include "core/songloader.h" #include "core/taskmanager.h" +#include "core/networkaccessmanager.h" #include "playlist.h" #include "songloaderinserter.h" -SongLoaderInserter::SongLoaderInserter(TaskManager *task_manager, CollectionBackendInterface *collection, const Player *player, QObject *parent) +SongLoaderInserter::SongLoaderInserter(TaskManager *task_manager, CollectionBackendInterface *collection, const Player *player, NetworkAccessManager *network, QObject *parent) : QObject(parent), task_manager_(task_manager), destination_(nullptr), @@ -41,7 +42,8 @@ SongLoaderInserter::SongLoaderInserter(TaskManager *task_manager, CollectionBack enqueue_(false), enqueue_next_(false), collection_(collection), - player_(player) {} + player_(player), + network_(network) {} SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); } @@ -58,7 +60,7 @@ void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now, boo QObject::connect(this, &SongLoaderInserter::EffectiveLoadFinished, destination, &Playlist::UpdateItems); for (const QUrl &url : urls) { - SongLoader *loader = new SongLoader(collection_, player_, this); + SongLoader *loader = new SongLoader(collection_, player_, network_, this); SongLoader::Result ret = loader->Load(url); @@ -103,7 +105,7 @@ void SongLoaderInserter::LoadAudioCD(Playlist *destination, int row, bool play_n enqueue_ = enqueue; enqueue_next_ = enqueue_next; - SongLoader *loader = new SongLoader(collection_, player_, this); + SongLoader *loader = new SongLoader(collection_, player_, network_, this); QObject::connect(loader, &SongLoader::AudioCDTracksLoadFinished, this, [this, loader]() { AudioCDTracksLoadFinished(loader); }); QObject::connect(loader, &SongLoader::LoadAudioCDFinished, this, &SongLoaderInserter::AudioCDTagsLoaded); qLog(Info) << "Loading audio CD..."; diff --git a/src/playlist/songloaderinserter.h b/src/playlist/songloaderinserter.h index 80c44f90..2f240144 100644 --- a/src/playlist/songloaderinserter.h +++ b/src/playlist/songloaderinserter.h @@ -32,6 +32,7 @@ #include "core/song.h" class Player; +class NetworkAccessManager; class SongLoader; class TaskManager; class CollectionBackendInterface; @@ -41,7 +42,7 @@ class SongLoaderInserter : public QObject { Q_OBJECT public: - explicit SongLoaderInserter(TaskManager *task_manager, CollectionBackendInterface *collection, const Player *player, QObject *parent = nullptr); + explicit SongLoaderInserter(TaskManager *task_manager, CollectionBackendInterface *collection, const Player *player, NetworkAccessManager *network, QObject *parent = nullptr); ~SongLoaderInserter() override; void Load(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next, const QList &urls); @@ -75,6 +76,7 @@ class SongLoaderInserter : public QObject { QList pending_; CollectionBackendInterface *collection_; const Player *player_; + NetworkAccessManager *network_; }; diff --git a/src/qobuz/qobuzservice.cpp b/src/qobuz/qobuzservice.cpp index 6a456bbc..0962613d 100644 --- a/src/qobuz/qobuzservice.cpp +++ b/src/qobuz/qobuzservice.cpp @@ -76,7 +76,7 @@ constexpr char QobuzService::kSongsFtsTable[] = "qobuz_songs_fts"; QobuzService::QobuzService(Application *app, QObject *parent) : InternetService(Song::Source::Qobuz, "Qobuz", "qobuz", QobuzSettingsPage::kSettingsGroup, SettingsDialog::Page::Qobuz, app, parent), app_(app), - network_(new NetworkAccessManager(this)), + network_(app->network()), url_handler_(new QobuzUrlHandler(app, this)), artists_collection_backend_(nullptr), albums_collection_backend_(nullptr), diff --git a/src/radios/radioservices.cpp b/src/radios/radioservices.cpp index 5fd22db7..b19d1736 100644 --- a/src/radios/radioservices.cpp +++ b/src/radios/radioservices.cpp @@ -34,7 +34,7 @@ RadioServices::RadioServices(Application *app, QObject *parent) : QObject(parent), - network_(new NetworkAccessManager(this)), + network_(app->network()), backend_(nullptr), model_(new RadioModel(app, this)), sort_model_(new QSortFilterProxyModel(this)), diff --git a/src/scrobbler/audioscrobbler.cpp b/src/scrobbler/audioscrobbler.cpp index 8eea753c..6e4ec0ba 100644 --- a/src/scrobbler/audioscrobbler.cpp +++ b/src/scrobbler/audioscrobbler.cpp @@ -19,6 +19,8 @@ #include "config.h" +#include +#include #include #include @@ -29,7 +31,6 @@ #include "settings/scrobblersettingspage.h" #include "audioscrobbler.h" -#include "scrobblerservices.h" #include "scrobblerservice.h" #include "lastfmscrobbler.h" #include "librefmscrobbler.h" @@ -41,7 +42,6 @@ AudioScrobbler::AudioScrobbler(Application *app, QObject *parent) : QObject(parent), app_(app), - scrobbler_services_(new ScrobblerServices(this)), enabled_(false), offline_(false), scrobble_button_(false), @@ -50,21 +50,69 @@ AudioScrobbler::AudioScrobbler(Application *app, QObject *parent) prefer_albumartist_(false), show_error_dialog_(false) { - scrobbler_services_->AddService(new LastFMScrobbler(app_, scrobbler_services_)); - scrobbler_services_->AddService(new LibreFMScrobbler(app_, scrobbler_services_)); - scrobbler_services_->AddService(new ListenBrainzScrobbler(app_, scrobbler_services_)); -#ifdef HAVE_SUBSONIC - scrobbler_services_->AddService(new SubsonicScrobbler(app_, scrobbler_services_)); -#endif - ReloadSettings(); - for (ScrobblerService *service : scrobbler_services_->List()) { - QObject::connect(service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived); +} + +AudioScrobbler::~AudioScrobbler() { + + while (!services_.isEmpty()) { + delete services_.take(services_.firstKey()); } } +void AudioScrobbler::AddService(ScrobblerService *service) { + + { + QMutexLocker locker(&mutex_); + services_.insert(service->name(), service); + } + + QObject::connect(service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived); + + qLog(Debug) << "Registered scrobbler service" << service->name(); + +} + +void AudioScrobbler::RemoveService(ScrobblerService *service) { + + if (!service || !services_.contains(service->name())) return; + + { + QMutexLocker locker(&mutex_); + services_.remove(service->name()); + QObject::disconnect(service, nullptr, this, nullptr); + } + + QObject::disconnect(service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived); + + qLog(Debug) << "Unregistered scrobbler service" << service->name(); + +} + +int AudioScrobbler::NextId() { return next_id_.fetchAndAddRelaxed(1); } + +QList AudioScrobbler::GetAll() { + + QList services; + + { + QMutexLocker locker(&mutex_); + services = services_.values(); + } + + return services; + +} + +ScrobblerService *AudioScrobbler::ServiceByName(const QString &name) { + + if (services_.contains(name)) return services_.value(name); + return nullptr; + +} + void AudioScrobbler::ReloadSettings() { QSettings s; @@ -104,7 +152,8 @@ void AudioScrobbler::ReloadSettings() { emit ScrobbleButtonVisibilityChanged(scrobble_button_); emit LoveButtonVisibilityChanged(love_button_); - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = services_.values(); + for (ScrobblerService *service : services) { service->ReloadSettings(); } @@ -150,7 +199,8 @@ void AudioScrobbler::UpdateNowPlaying(const Song &song) { qLog(Debug) << "Sending now playing for song" << song.artist() << song.album() << song.title(); - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = GetAll(); + for (ScrobblerService *service : services) { if (!service->IsEnabled()) continue; service->UpdateNowPlaying(song); } @@ -159,7 +209,8 @@ void AudioScrobbler::UpdateNowPlaying(const Song &song) { void AudioScrobbler::ClearPlaying() { - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = GetAll(); + for (ScrobblerService *service : services) { if (!service->IsEnabled()) continue; service->ClearPlaying(); } @@ -172,7 +223,8 @@ void AudioScrobbler::Scrobble(const Song &song, const qint64 scrobble_point) { qLog(Debug) << "Scrobbling song" << song.artist() << song.album() << song.title() << "at" << scrobble_point; - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = GetAll(); + for (ScrobblerService *service : services) { if (!service->IsEnabled()) continue; service->Scrobble(song); } @@ -181,7 +233,8 @@ void AudioScrobbler::Scrobble(const Song &song, const qint64 scrobble_point) { void AudioScrobbler::Love() { - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = GetAll(); + for (ScrobblerService *service : services) { if (!service->IsEnabled() || !service->IsAuthenticated()) continue; service->Love(); } @@ -190,7 +243,8 @@ void AudioScrobbler::Love() { void AudioScrobbler::Submit() { - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = GetAll(); + for (ScrobblerService *service : services) { if (!service->IsEnabled() || !service->IsAuthenticated() || service->IsSubmitted()) continue; service->StartSubmit(); } @@ -199,7 +253,8 @@ void AudioScrobbler::Submit() { void AudioScrobbler::WriteCache() { - for (ScrobblerService *service : scrobbler_services_->List()) { + QList services = GetAll(); + for (ScrobblerService *service : services) { if (!service->IsEnabled()) continue; service->WriteCache(); } diff --git a/src/scrobbler/audioscrobbler.h b/src/scrobbler/audioscrobbler.h index 30e80063..d83fe3c0 100644 --- a/src/scrobbler/audioscrobbler.h +++ b/src/scrobbler/audioscrobbler.h @@ -22,22 +22,39 @@ #include "config.h" +#include #include +#include #include +#include #include +#include #include "core/song.h" -#include "scrobblerservices.h" class Application; -class Song; class ScrobblerService; +class Song; class AudioScrobbler : public QObject { Q_OBJECT public: explicit AudioScrobbler(Application *app, QObject *parent = nullptr); + ~AudioScrobbler(); + + void AddService(ScrobblerService *service); + void RemoveService(ScrobblerService *service); + QList List() const { return services_.values(); } + bool HasAnyServices() const { return !services_.isEmpty(); } + int NextId(); + + QList GetAll(); + ScrobblerService *ServiceByName(const QString &name); + template + T *Service() { + return qobject_cast(ServiceByName(T::kName)); + } void ReloadSettings(); @@ -50,25 +67,19 @@ class AudioScrobbler : public QObject { bool ShowErrorDialog() const { return show_error_dialog_; } QList sources() const { return sources_; } + void ShowConfig(); + void UpdateNowPlaying(const Song &song); void ClearPlaying(); void Scrobble(const Song &song, const qint64 scrobble_point); - void ShowConfig(); - - ScrobblerService *ServiceByName(const QString &name) const { return scrobbler_services_->ServiceByName(name); } - - template - T *Service() { - return qobject_cast(ServiceByName(T::kName)); - } public slots: void ToggleScrobbling(); void ToggleOffline(); + void ErrorReceived(const QString &error); void Submit(); void Love(); void WriteCache(); - void ErrorReceived(const QString &error); signals: void ErrorMessage(const QString &error); @@ -79,7 +90,10 @@ class AudioScrobbler : public QObject { private: Application *app_; - ScrobblerServices *scrobbler_services_; + + QMap services_; + QMutex mutex_; + QAtomicInt next_id_; bool enabled_; bool offline_; @@ -90,6 +104,7 @@ class AudioScrobbler : public QObject { bool show_error_dialog_; QList sources_; + Q_DISABLE_COPY(AudioScrobbler) }; #endif // AUDIOSCROBBLER_H diff --git a/src/scrobbler/lastfmimport.cpp b/src/scrobbler/lastfmimport.cpp index 441bca54..7cd68439 100644 --- a/src/scrobbler/lastfmimport.cpp +++ b/src/scrobbler/lastfmimport.cpp @@ -48,9 +48,9 @@ const int LastFMImport::kRequestsDelay = 2000; -LastFMImport::LastFMImport(QObject *parent) +LastFMImport::LastFMImport(NetworkAccessManager *network, QObject *parent) : QObject(parent), - network_(new NetworkAccessManager(this)), + network_(network), timer_flush_requests_(new QTimer(this)), lastplayed_(false), playcount_(false), diff --git a/src/scrobbler/lastfmimport.h b/src/scrobbler/lastfmimport.h index ef636aad..a1012003 100644 --- a/src/scrobbler/lastfmimport.h +++ b/src/scrobbler/lastfmimport.h @@ -40,7 +40,7 @@ class LastFMImport : public QObject { Q_OBJECT public: - explicit LastFMImport(QObject *parent = nullptr); + explicit LastFMImport(NetworkAccessManager *network, QObject *parent = nullptr); ~LastFMImport() override; void ReloadSettings(); diff --git a/src/scrobbler/lastfmscrobbler.cpp b/src/scrobbler/lastfmscrobbler.cpp index 1807203e..89119397 100644 --- a/src/scrobbler/lastfmscrobbler.cpp +++ b/src/scrobbler/lastfmscrobbler.cpp @@ -21,8 +21,9 @@ #include -#include "core/application.h" +#include "core/networkaccessmanager.h" +#include "audioscrobbler.h" #include "lastfmscrobbler.h" const char *LastFMScrobbler::kName = "Last.fm"; @@ -31,5 +32,5 @@ const char *LastFMScrobbler::kAuthUrl = "https://www.last.fm/api/auth/"; const char *LastFMScrobbler::kApiUrl = "https://ws.audioscrobbler.com/2.0/"; const char *LastFMScrobbler::kCacheFile = "lastfmscrobbler.cache"; -LastFMScrobbler::LastFMScrobbler(Application *app, QObject *parent) - : ScrobblingAPI20(kName, kSettingsGroup, kAuthUrl, kApiUrl, true, kCacheFile, app, parent) {} +LastFMScrobbler::LastFMScrobbler(AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent) + : ScrobblingAPI20(kName, kSettingsGroup, kAuthUrl, kApiUrl, true, kCacheFile, scrobbler, network, parent) {} diff --git a/src/scrobbler/lastfmscrobbler.h b/src/scrobbler/lastfmscrobbler.h index efb90f4d..6031cd1f 100644 --- a/src/scrobbler/lastfmscrobbler.h +++ b/src/scrobbler/lastfmscrobbler.h @@ -27,13 +27,14 @@ #include "scrobblingapi20.h" -class Application; +class AudioScrobbler; +class NetworkAccessManager; class LastFMScrobbler : public ScrobblingAPI20 { Q_OBJECT public: - explicit LastFMScrobbler(Application *app, QObject *parent = nullptr); + explicit LastFMScrobbler(AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent = nullptr); static const char *kName; static const char *kSettingsGroup; diff --git a/src/scrobbler/librefmscrobbler.cpp b/src/scrobbler/librefmscrobbler.cpp index e78d6ba1..8b363300 100644 --- a/src/scrobbler/librefmscrobbler.cpp +++ b/src/scrobbler/librefmscrobbler.cpp @@ -21,8 +21,9 @@ #include -#include "core/application.h" +#include "core/networkaccessmanager.h" +#include "audioscrobbler.h" #include "scrobblingapi20.h" #include "librefmscrobbler.h" @@ -32,5 +33,5 @@ const char *LibreFMScrobbler::kAuthUrl = "https://www.libre.fm/api/auth/"; const char *LibreFMScrobbler::kApiUrl = "https://libre.fm/2.0/"; const char *LibreFMScrobbler::kCacheFile = "librefmscrobbler.cache"; -LibreFMScrobbler::LibreFMScrobbler(Application *app, QObject *parent) - : ScrobblingAPI20(kName, kSettingsGroup, kAuthUrl, kApiUrl, false, kCacheFile, app, parent) {} +LibreFMScrobbler::LibreFMScrobbler(AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent) + : ScrobblingAPI20(kName, kSettingsGroup, kAuthUrl, kApiUrl, false, kCacheFile, scrobbler, network, parent) {} diff --git a/src/scrobbler/librefmscrobbler.h b/src/scrobbler/librefmscrobbler.h index df9f3810..e41e7f7d 100644 --- a/src/scrobbler/librefmscrobbler.h +++ b/src/scrobbler/librefmscrobbler.h @@ -27,13 +27,14 @@ #include "scrobblingapi20.h" -class Application; +class AudioScrobbler; +class NetworkAccessManager; class LibreFMScrobbler : public ScrobblingAPI20 { Q_OBJECT public: - explicit LibreFMScrobbler(Application *app, QObject *parent = nullptr); + explicit LibreFMScrobbler(AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent = nullptr); static const char *kName; static const char *kSettingsGroup; diff --git a/src/scrobbler/listenbrainzscrobbler.cpp b/src/scrobbler/listenbrainzscrobbler.cpp index eb8a7cbe..25995a6b 100644 --- a/src/scrobbler/listenbrainzscrobbler.cpp +++ b/src/scrobbler/listenbrainzscrobbler.cpp @@ -40,7 +40,6 @@ #include #include -#include "core/application.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "core/logging.h" @@ -66,10 +65,10 @@ const char *ListenBrainzScrobbler::kClientSecretB64 = "Uk9GZ2hrZVEzRjNvUHlFaHFpe const char *ListenBrainzScrobbler::kCacheFile = "listenbrainzscrobbler.cache"; const int ListenBrainzScrobbler::kScrobblesPerRequest = 10; -ListenBrainzScrobbler::ListenBrainzScrobbler(Application *app, QObject *parent) - : ScrobblerService(kName, app, parent), - app_(app), - network_(new NetworkAccessManager(this)), +ListenBrainzScrobbler::ListenBrainzScrobbler(AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent) + : ScrobblerService(kName, parent), + scrobbler_(scrobbler), + network_(network), cache_(new ScrobblerCache(kCacheFile, this)), server_(nullptr), enabled_(false), @@ -87,7 +86,7 @@ ListenBrainzScrobbler::ListenBrainzScrobbler(Application *app, QObject *parent) timer_submit_.setSingleShot(true); QObject::connect(&timer_submit_, &QTimer::timeout, this, &ListenBrainzScrobbler::Submit); - ListenBrainzScrobbler::ReloadSettings(); + ReloadSettings(); LoadSession(); } @@ -449,7 +448,7 @@ void ListenBrainzScrobbler::UpdateNowPlaying(const Song &song) { scrobbled_ = false; timestamp_ = QDateTime::currentDateTime().toSecsSinceEpoch(); - if (!song.is_metadata_good() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return; + if (!song.is_metadata_good() || !IsAuthenticated() || scrobbler_->IsOffline()) return; QJsonObject object_listen; object_listen.insert("track_metadata", JsonTrackMetadata(ScrobbleMetadata(song))); @@ -509,7 +508,7 @@ void ListenBrainzScrobbler::Scrobble(const Song &song) { cache_->Add(song, timestamp_); - if (app_->scrobbler()->IsOffline() || !IsAuthenticated()) return; + if (scrobbler_->IsOffline() || !IsAuthenticated()) return; StartSubmit(); @@ -518,14 +517,14 @@ void ListenBrainzScrobbler::Scrobble(const Song &song) { void ListenBrainzScrobbler::StartSubmit(const bool initial) { if (!submitted_ && cache_->Count() > 0) { - if (initial && app_->scrobbler()->SubmitDelay() <= 0 && !submit_error_) { + if (initial && scrobbler_->SubmitDelay() <= 0 && !submit_error_) { if (timer_submit_.isActive()) { timer_submit_.stop(); } Submit(); } else if (!timer_submit_.isActive()) { - int submit_delay = static_cast(std::max(app_->scrobbler()->SubmitDelay(), submit_error_ ? 30 : 5) * kMsecPerSec); + int submit_delay = static_cast(std::max(scrobbler_->SubmitDelay(), submit_error_ ? 30 : 5) * kMsecPerSec); timer_submit_.setInterval(submit_delay); timer_submit_.start(); } @@ -537,7 +536,7 @@ void ListenBrainzScrobbler::Submit() { qLog(Debug) << "ListenBrainz: Submitting scrobbles."; - if (!IsEnabled() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return; + if (!IsEnabled() || !IsAuthenticated() || scrobbler_->IsOffline()) return; QJsonArray array; ScrobblerCacheItemPtrList cache_items_sent; @@ -620,7 +619,7 @@ void ListenBrainzScrobbler::Love() { if (!song_playing_.is_valid() || !song_playing_.is_metadata_good()) return; - if (!IsAuthenticated()) app_->scrobbler()->ShowConfig(); + if (!IsAuthenticated()) scrobbler_->ShowConfig(); if (song_playing_.musicbrainz_recording_id().isEmpty()) { Error(tr("Missing MusicBrainz recording ID for %1 %2 %3").arg(song_playing_.artist()).arg(song_playing_.album()).arg(song_playing_.title())); @@ -671,7 +670,7 @@ void ListenBrainzScrobbler::Error(const QString &error, const QVariant &debug) { qLog(Error) << "ListenBrainz:" << error; if (debug.isValid()) qLog(Debug) << debug; - if (app_->scrobbler()->ShowErrorDialog()) { + if (scrobbler_->ShowErrorDialog()) { emit ErrorMessage(tr("ListenBrainz error: %1").arg(error)); } diff --git a/src/scrobbler/listenbrainzscrobbler.h b/src/scrobbler/listenbrainzscrobbler.h index 83b4f6c6..44500ab5 100644 --- a/src/scrobbler/listenbrainzscrobbler.h +++ b/src/scrobbler/listenbrainzscrobbler.h @@ -39,7 +39,7 @@ class QNetworkReply; -class Application; +class AudioScrobbler; class NetworkAccessManager; class LocalRedirectServer; @@ -47,7 +47,7 @@ class ListenBrainzScrobbler : public ScrobblerService { Q_OBJECT public: - explicit ListenBrainzScrobbler(Application *app, QObject *parent = nullptr); + explicit ListenBrainzScrobbler(AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent = nullptr); ~ListenBrainzScrobbler() override; static const char *kName; @@ -110,7 +110,7 @@ class ListenBrainzScrobbler : public ScrobblerService { static const char *kCacheFile; static const int kScrobblesPerRequest; - Application *app_; + AudioScrobbler *scrobbler_; NetworkAccessManager *network_; ScrobblerCache *cache_; LocalRedirectServer *server_; diff --git a/src/scrobbler/scrobblerservice.cpp b/src/scrobbler/scrobblerservice.cpp index 87e36fce..20512e63 100644 --- a/src/scrobbler/scrobblerservice.cpp +++ b/src/scrobbler/scrobblerservice.cpp @@ -30,11 +30,7 @@ #include "core/song.h" -ScrobblerService::ScrobblerService(const QString &name, Application *app, QObject *parent) : QObject(parent), name_(name) { - - Q_UNUSED(app); - -} +ScrobblerService::ScrobblerService(const QString &name, QObject *parent) : QObject(parent), name_(name) {} bool ScrobblerService::ExtractJsonObj(const QByteArray &data, QJsonObject &json_obj, QString &error_description) { diff --git a/src/scrobbler/scrobblerservice.h b/src/scrobbler/scrobblerservice.h index dc24a41b..8292734b 100644 --- a/src/scrobbler/scrobblerservice.h +++ b/src/scrobbler/scrobblerservice.h @@ -32,13 +32,11 @@ #include "core/song.h" -class Application; - class ScrobblerService : public QObject { Q_OBJECT public: - explicit ScrobblerService(const QString &name, Application *app, QObject *parent); + explicit ScrobblerService(const QString &name, QObject *parent); QString name() const { return name_; } diff --git a/src/scrobbler/scrobblerservices.cpp b/src/scrobbler/scrobblerservices.cpp deleted file mode 100644 index 0939f191..00000000 --- a/src/scrobbler/scrobblerservices.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Strawberry Music Player - * Copyright 2018-2021, Jonas Kvinge - * - * Strawberry 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. - * - * Strawberry 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 Strawberry. If not, see . - * - */ - -#include "config.h" - -#include -#include -#include - -#include "core/logging.h" - -#include "scrobblerservices.h" -#include "scrobblerservice.h" - -ScrobblerServices::ScrobblerServices(QObject *parent) : QObject(parent) {} - -ScrobblerServices::~ScrobblerServices() { - - while (!scrobbler_services_.isEmpty()) { - delete scrobbler_services_.take(scrobbler_services_.firstKey()); - } - -} - -void ScrobblerServices::AddService(ScrobblerService *service) { - - { - QMutexLocker locker(&mutex_); - scrobbler_services_.insert(service->name(), service); - } - - qLog(Debug) << "Registered scrobbler service" << service->name(); - -} - -void ScrobblerServices::RemoveService(ScrobblerService *service) { - - if (!service || !scrobbler_services_.contains(service->name())) return; - - { - QMutexLocker locker(&mutex_); - scrobbler_services_.remove(service->name()); - QObject::disconnect(service, nullptr, this, nullptr); - } - - qLog(Debug) << "Unregistered scrobbler service" << service->name(); - -} - -int ScrobblerServices::NextId() { return next_id_.fetchAndAddRelaxed(1); } - -ScrobblerService *ScrobblerServices::ServiceByName(const QString &name) { - - if (scrobbler_services_.contains(name)) return scrobbler_services_.value(name); - return nullptr; - -} diff --git a/src/scrobbler/scrobblerservices.h b/src/scrobbler/scrobblerservices.h deleted file mode 100644 index cb5d927d..00000000 --- a/src/scrobbler/scrobblerservices.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Strawberry Music Player - * Copyright 2018-2021, Jonas Kvinge - * - * Strawberry 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. - * - * Strawberry 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 Strawberry. If not, see . - * - */ - -#ifndef SCROBBLERSERVICES_H -#define SCROBBLERSERVICES_H - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -class ScrobblerService; - -class ScrobblerServices : public QObject { - Q_OBJECT - - public: - explicit ScrobblerServices(QObject *parent = nullptr); - ~ScrobblerServices() override; - - void AddService(ScrobblerService *service); - void RemoveService(ScrobblerService *service); - QList List() const { return scrobbler_services_.values(); } - bool HasAnyServices() const { return !scrobbler_services_.isEmpty(); } - int NextId(); - - ScrobblerService *ServiceByName(const QString &name); - template - T *Service() { - return qobject_cast(ServiceByName(T::kName)); - } - - private: - Q_DISABLE_COPY(ScrobblerServices) - - QMap scrobbler_services_; - QMutex mutex_; - - QAtomicInt next_id_; - -}; - -#endif // SCROBBLERSERVICES_H diff --git a/src/scrobbler/scrobblingapi20.cpp b/src/scrobbler/scrobblingapi20.cpp index 76faeb64..e24af197 100644 --- a/src/scrobbler/scrobblingapi20.cpp +++ b/src/scrobbler/scrobblingapi20.cpp @@ -44,7 +44,6 @@ #include #include -#include "core/application.h" #include "core/networkaccessmanager.h" #include "core/song.h" #include "core/logging.h" @@ -63,15 +62,15 @@ const char *ScrobblingAPI20::kApiKey = "211990b4c96782c05d1536e7219eb56e"; const char *ScrobblingAPI20::kSecret = "80fd738f49596e9709b1bf9319c444a8"; const int ScrobblingAPI20::kScrobblesPerRequest = 50; -ScrobblingAPI20::ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, Application *app, QObject *parent) - : ScrobblerService(name, app, parent), +ScrobblingAPI20::ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent) + : ScrobblerService(name, parent), name_(name), settings_group_(settings_group), auth_url_(auth_url), api_url_(api_url), batch_(batch), - app_(app), - network_(new NetworkAccessManager(this)), + scrobbler_(scrobbler), + network_(network), cache_(new ScrobblerCache(cache_file, this)), server_(nullptr), enabled_(false), @@ -398,7 +397,7 @@ void ScrobblingAPI20::UpdateNowPlaying(const Song &song) { timestamp_ = QDateTime::currentDateTime().toSecsSinceEpoch(); scrobbled_ = false; - if (!IsAuthenticated() || !song.is_metadata_good() || app_->scrobbler()->IsOffline()) return; + if (!IsAuthenticated() || !song.is_metadata_good() || scrobbler_->IsOffline()) return; ParamList params = ParamList() << Param("method", "track.updateNowPlaying") @@ -457,10 +456,10 @@ void ScrobblingAPI20::Scrobble(const Song &song) { cache_->Add(song, timestamp_); - if (app_->scrobbler()->IsOffline()) return; + if (scrobbler_->IsOffline()) return; if (!IsAuthenticated()) { - if (app_->scrobbler()->ShowErrorDialog()) { + if (scrobbler_->ShowErrorDialog()) { emit ErrorMessage(tr("Scrobbler %1 is not authenticated!").arg(name_)); } return; @@ -472,14 +471,14 @@ void ScrobblingAPI20::Scrobble(const Song &song) { void ScrobblingAPI20::StartSubmit(const bool initial) { if (!submitted_ && cache_->Count() > 0) { - if (initial && (!batch_ || app_->scrobbler()->SubmitDelay() <= 0) && !submit_error_) { + if (initial && (!batch_ || scrobbler_->SubmitDelay() <= 0) && !submit_error_) { if (timer_submit_.isActive()) { timer_submit_.stop(); } Submit(); } else if (!timer_submit_.isActive()) { - int submit_delay = static_cast(std::max(app_->scrobbler()->SubmitDelay(), submit_error_ ? 30 : 5) * kMsecPerSec); + int submit_delay = static_cast(std::max(scrobbler_->SubmitDelay(), submit_error_ ? 30 : 5) * kMsecPerSec); timer_submit_.setInterval(submit_delay); timer_submit_.start(); } @@ -489,7 +488,7 @@ void ScrobblingAPI20::StartSubmit(const bool initial) { void ScrobblingAPI20::Submit() { - if (!IsEnabled() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return; + if (!IsEnabled() || !IsAuthenticated() || scrobbler_->IsOffline()) return; qLog(Debug) << name_ << "Submitting scrobbles."; @@ -827,7 +826,7 @@ void ScrobblingAPI20::Love() { if (!song_playing_.is_valid() || !song_playing_.is_metadata_good()) return; - if (!IsAuthenticated()) app_->scrobbler()->ShowConfig(); + if (!IsAuthenticated()) scrobbler_->ShowConfig(); qLog(Debug) << name_ << "Sending love for song" << song_playing_.artist() << song_playing_.album() << song_playing_.title(); @@ -909,7 +908,7 @@ void ScrobblingAPI20::Error(const QString &error, const QVariant &debug) { qLog(Error) << name_ << error; if (debug.isValid()) qLog(Debug) << debug; - if (app_->scrobbler()->ShowErrorDialog()) { + if (scrobbler_->ShowErrorDialog()) { emit ErrorMessage(tr("Scrobbler %1 error: %2").arg(name_, error)); } } diff --git a/src/scrobbler/scrobblingapi20.h b/src/scrobbler/scrobblingapi20.h index 01513833..a6327171 100644 --- a/src/scrobbler/scrobblingapi20.h +++ b/src/scrobbler/scrobblingapi20.h @@ -37,7 +37,7 @@ class QNetworkReply; -class Application; +class AudioScrobbler; class NetworkAccessManager; class LocalRedirectServer; @@ -45,7 +45,7 @@ class ScrobblingAPI20 : public ScrobblerService { Q_OBJECT public: - explicit ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, Application *app, QObject *parent = nullptr); + explicit ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, AudioScrobbler *scrobbler, NetworkAccessManager *network, QObject *parent = nullptr); ~ScrobblingAPI20() override; static const char *kApiKey; @@ -142,7 +142,7 @@ class ScrobblingAPI20 : public ScrobblerService { QString api_url_; bool batch_; - Application *app_; + AudioScrobbler *scrobbler_; NetworkAccessManager *network_; ScrobblerCache *cache_; LocalRedirectServer *server_; diff --git a/src/scrobbler/subsonicscrobbler.cpp b/src/scrobbler/subsonicscrobbler.cpp index 4c51ddf7..fda56d37 100644 --- a/src/scrobbler/subsonicscrobbler.cpp +++ b/src/scrobbler/subsonicscrobbler.cpp @@ -39,13 +39,15 @@ const char *SubsonicScrobbler::kName = "Subsonic"; -SubsonicScrobbler::SubsonicScrobbler(Application *app, QObject *parent) - : ScrobblerService(kName, app, parent), - app_(app), - service_(app->internet_services()->Service()), +SubsonicScrobbler::SubsonicScrobbler(AudioScrobbler *scrobbler, SubsonicService *service, QObject *parent) + : ScrobblerService(kName, parent), + scrobbler_(scrobbler), + service_(service), enabled_(false), submitted_(false) { + ReloadSettings(); + timer_submit_.setSingleShot(true); QObject::connect(&timer_submit_, &QTimer::timeout, this, &SubsonicScrobbler::Submit); @@ -67,7 +69,7 @@ void SubsonicScrobbler::UpdateNowPlaying(const Song &song) { song_playing_ = song; time_ = QDateTime::currentDateTime(); - if (!song.is_metadata_good() || app_->scrobbler()->IsOffline()) return; + if (!song.is_metadata_good() || scrobbler_->IsOffline()) return; service_->Scrobble(song.song_id(), false, time_); @@ -84,15 +86,15 @@ void SubsonicScrobbler::Scrobble(const Song &song) { if (song.source() != Song::Source::Subsonic || song.id() != song_playing_.id() || song.url() != song_playing_.url() || !song.is_metadata_good()) return; - if (app_->scrobbler()->IsOffline()) return; + if (scrobbler_->IsOffline()) return; if (!submitted_) { submitted_ = true; - if (app_->scrobbler()->SubmitDelay() <= 0) { + if (scrobbler_->SubmitDelay() <= 0) { Submit(); } else if (!timer_submit_.isActive()) { - timer_submit_.setInterval(static_cast(app_->scrobbler()->SubmitDelay() * kMsecPerSec)); + timer_submit_.setInterval(static_cast(scrobbler_->SubmitDelay() * kMsecPerSec)); timer_submit_.start(); } } @@ -104,7 +106,7 @@ void SubsonicScrobbler::Submit() { qLog(Debug) << "SubsonicScrobbler: Submitting scrobble for" << song_playing_.artist() << song_playing_.title(); submitted_ = false; - if (app_->scrobbler()->IsOffline()) return; + if (scrobbler_->IsOffline()) return; service_->Scrobble(song_playing_.song_id(), true, time_); diff --git a/src/scrobbler/subsonicscrobbler.h b/src/scrobbler/subsonicscrobbler.h index d732f83e..377ef7f5 100644 --- a/src/scrobbler/subsonicscrobbler.h +++ b/src/scrobbler/subsonicscrobbler.h @@ -34,13 +34,14 @@ #include "scrobblerservice.h" class Application; +class AudioScrobbler; class SubsonicService; class SubsonicScrobbler : public ScrobblerService { Q_OBJECT public: - explicit SubsonicScrobbler(Application *app, QObject *parent = nullptr); + explicit SubsonicScrobbler(AudioScrobbler *scrobbler, SubsonicService *service, QObject *parent = nullptr); static const char *kName; @@ -62,7 +63,7 @@ class SubsonicScrobbler : public ScrobblerService { void Submit() override; private: - Application *app_; + AudioScrobbler *scrobbler_; SubsonicService *service_; bool enabled_; bool submitted_; diff --git a/src/subsonic/subsonicservice.cpp b/src/subsonic/subsonicservice.cpp index dbeb955b..b0a01ca6 100644 --- a/src/subsonic/subsonicservice.cpp +++ b/src/subsonic/subsonicservice.cpp @@ -57,6 +57,8 @@ #include "subsonicscrobblerequest.h" #include "settings/settingsdialog.h" #include "settings/subsonicsettingspage.h" +#include "scrobbler/audioscrobbler.h" +#include "scrobbler/subsonicscrobbler.h" const Song::Source SubsonicService::kSource = Song::Source::Subsonic; const char *SubsonicService::kClientName = "Strawberry"; @@ -97,6 +99,8 @@ SubsonicService::SubsonicService(Application *app, QObject *parent) SubsonicService::ReloadSettings(); + app->scrobbler()->AddService(new SubsonicScrobbler(app->scrobbler(), this, this)); + } SubsonicService::~SubsonicService() { diff --git a/src/tidal/tidalservice.cpp b/src/tidal/tidalservice.cpp index 060760b8..2bcc5b41 100644 --- a/src/tidal/tidalservice.cpp +++ b/src/tidal/tidalservice.cpp @@ -87,7 +87,7 @@ using namespace std::chrono_literals; TidalService::TidalService(Application *app, QObject *parent) : InternetService(Song::Source::Tidal, "Tidal", "tidal", TidalSettingsPage::kSettingsGroup, SettingsDialog::Page::Tidal, app, parent), app_(app), - network_(new NetworkAccessManager(this)), + network_(app->network()), url_handler_(new TidalUrlHandler(app, this)), artists_collection_backend_(nullptr), albums_collection_backend_(nullptr),