Use one instance of NetworkAccessManager

This commit is contained in:
Jonas Kvinge
2023-04-21 20:20:53 +02:00
parent bee6b7f946
commit 7fc5aef553
53 changed files with 270 additions and 311 deletions

View File

@@ -19,6 +19,8 @@
#include "config.h"
#include <QMutex>
#include <QList>
#include <QString>
#include <QSettings>
@@ -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<ScrobblerService*> AudioScrobbler::GetAll() {
QList<ScrobblerService*> 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<ScrobblerService*> 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<ScrobblerService*> 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<ScrobblerService*> 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<ScrobblerService*> 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<ScrobblerService*> 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<ScrobblerService*> 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<ScrobblerService*> services = GetAll();
for (ScrobblerService *service : services) {
if (!service->IsEnabled()) continue;
service->WriteCache();
}

View File

@@ -22,22 +22,39 @@
#include "config.h"
#include <QtGlobal>
#include <QObject>
#include <QMutex>
#include <QList>
#include <QMap>
#include <QString>
#include <QAtomicInt>
#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<ScrobblerService*> List() const { return services_.values(); }
bool HasAnyServices() const { return !services_.isEmpty(); }
int NextId();
QList<ScrobblerService*> GetAll();
ScrobblerService *ServiceByName(const QString &name);
template<typename T>
T *Service() {
return qobject_cast<T*>(ServiceByName(T::kName));
}
void ReloadSettings();
@@ -50,25 +67,19 @@ class AudioScrobbler : public QObject {
bool ShowErrorDialog() const { return show_error_dialog_; }
QList<Song::Source> 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<typename T>
T *Service() {
return qobject_cast<T*>(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<QString, ScrobblerService*> services_;
QMutex mutex_;
QAtomicInt next_id_;
bool enabled_;
bool offline_;
@@ -90,6 +104,7 @@ class AudioScrobbler : public QObject {
bool show_error_dialog_;
QList<Song::Source> sources_;
Q_DISABLE_COPY(AudioScrobbler)
};
#endif // AUDIOSCROBBLER_H

View File

@@ -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),

View File

@@ -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();

View File

@@ -21,8 +21,9 @@
#include <QObject>
#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) {}

View File

@@ -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;

View File

@@ -21,8 +21,9 @@
#include <QObject>
#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) {}

View File

@@ -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;

View File

@@ -40,7 +40,6 @@
#include <QJsonArray>
#include <QJsonValue>
#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<int>(std::max(app_->scrobbler()->SubmitDelay(), submit_error_ ? 30 : 5) * kMsecPerSec);
int submit_delay = static_cast<int>(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));
}

View File

@@ -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_;

View File

@@ -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) {

View File

@@ -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_; }

View File

@@ -1,73 +0,0 @@
/*
* Strawberry Music Player
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <QObject>
#include <QMutexLocker>
#include <QString>
#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;
}

View File

@@ -1,64 +0,0 @@
/*
* Strawberry Music Player
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef SCROBBLERSERVICES_H
#define SCROBBLERSERVICES_H
#include "config.h"
#include <QtGlobal>
#include <QObject>
#include <QMutex>
#include <QList>
#include <QMap>
#include <QString>
#include <QAtomicInt>
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<ScrobblerService*> List() const { return scrobbler_services_.values(); }
bool HasAnyServices() const { return !scrobbler_services_.isEmpty(); }
int NextId();
ScrobblerService *ServiceByName(const QString &name);
template<typename T>
T *Service() {
return qobject_cast<T*>(ServiceByName(T::kName));
}
private:
Q_DISABLE_COPY(ScrobblerServices)
QMap<QString, ScrobblerService *> scrobbler_services_;
QMutex mutex_;
QAtomicInt next_id_;
};
#endif // SCROBBLERSERVICES_H

View File

@@ -44,7 +44,6 @@
#include <QJsonValue>
#include <QFlags>
#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<int>(std::max(app_->scrobbler()->SubmitDelay(), submit_error_ ? 30 : 5) * kMsecPerSec);
int submit_delay = static_cast<int>(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));
}
}

View File

@@ -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_;

View File

@@ -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<SubsonicService>()),
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<int>(app_->scrobbler()->SubmitDelay() * kMsecPerSec));
timer_submit_.setInterval(static_cast<int>(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_);

View File

@@ -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_;