@@ -19,36 +19,27 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <memory>
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/song.h"
|
||||
#include "settings/settingsdialog.h"
|
||||
#include "settings/scrobblersettingspage.h"
|
||||
|
||||
#include "audioscrobbler.h"
|
||||
#include "scrobblersettings.h"
|
||||
#include "scrobblerservice.h"
|
||||
#include "lastfmscrobbler.h"
|
||||
#include "librefmscrobbler.h"
|
||||
#include "listenbrainzscrobbler.h"
|
||||
#ifdef HAVE_SUBSONIC
|
||||
# include "subsonicscrobbler.h"
|
||||
#endif
|
||||
|
||||
using std::make_shared;
|
||||
|
||||
AudioScrobbler::AudioScrobbler(Application *app, QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
enabled_(false),
|
||||
offline_(false),
|
||||
scrobble_button_(false),
|
||||
love_button_(false),
|
||||
submit_delay_(0),
|
||||
prefer_albumartist_(false),
|
||||
show_error_dialog_(false) {
|
||||
settings_(make_shared<ScrobblerSettings>(app)) {
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
@@ -57,56 +48,46 @@ AudioScrobbler::AudioScrobbler(Application *app, QObject *parent)
|
||||
AudioScrobbler::~AudioScrobbler() {
|
||||
|
||||
while (!services_.isEmpty()) {
|
||||
delete services_.take(services_.firstKey());
|
||||
ScrobblerServicePtr service = services_.first();
|
||||
RemoveService(service);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AudioScrobbler::AddService(ScrobblerService *service) {
|
||||
void AudioScrobbler::AddService(ScrobblerServicePtr service) {
|
||||
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
services_.insert(service->name(), service);
|
||||
}
|
||||
services_.insert(service->name(), service);
|
||||
|
||||
QObject::connect(service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived);
|
||||
QObject::connect(&*service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived);
|
||||
|
||||
qLog(Debug) << "Registered scrobbler service" << service->name();
|
||||
|
||||
}
|
||||
|
||||
void AudioScrobbler::RemoveService(ScrobblerService *service) {
|
||||
void AudioScrobbler::RemoveService(ScrobblerServicePtr service) {
|
||||
|
||||
if (!service || !services_.contains(service->name())) return;
|
||||
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
services_.remove(service->name());
|
||||
QObject::disconnect(service, nullptr, this, nullptr);
|
||||
}
|
||||
services_.remove(service->name());
|
||||
QObject::disconnect(&*service, nullptr, this, nullptr);
|
||||
|
||||
QObject::disconnect(service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived);
|
||||
QObject::disconnect(&*service, &ScrobblerService::ErrorMessage, this, &AudioScrobbler::ErrorReceived);
|
||||
|
||||
qLog(Debug) << "Unregistered scrobbler service" << service->name();
|
||||
|
||||
}
|
||||
|
||||
int AudioScrobbler::NextId() { return next_id_.fetchAndAddRelaxed(1); }
|
||||
QList<ScrobblerServicePtr> AudioScrobbler::GetAll() {
|
||||
|
||||
QList<ScrobblerService*> AudioScrobbler::GetAll() {
|
||||
QList<ScrobblerServicePtr> services;
|
||||
|
||||
QList<ScrobblerService*> services;
|
||||
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
services = services_.values();
|
||||
}
|
||||
|
||||
return services;
|
||||
|
||||
}
|
||||
|
||||
ScrobblerService *AudioScrobbler::ServiceByName(const QString &name) {
|
||||
ScrobblerServicePtr AudioScrobbler::ServiceByName(const QString &name) {
|
||||
|
||||
if (services_.contains(name)) return services_.value(name);
|
||||
return nullptr;
|
||||
@@ -115,45 +96,10 @@ ScrobblerService *AudioScrobbler::ServiceByName(const QString &name) {
|
||||
|
||||
void AudioScrobbler::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
s.beginGroup(ScrobblerSettingsPage::kSettingsGroup);
|
||||
enabled_ = s.value("enabled", false).toBool();
|
||||
offline_ = s.value("offline", false).toBool();
|
||||
scrobble_button_ = s.value("scrobble_button", false).toBool();
|
||||
love_button_ = s.value("love_button", false).toBool();
|
||||
submit_delay_ = s.value("submit", 0).toInt();
|
||||
prefer_albumartist_ = s.value("albumartist", false).toBool();
|
||||
show_error_dialog_ = s.value("show_error_dialog", true).toBool();
|
||||
QStringList sources = s.value("sources").toStringList();
|
||||
s.endGroup();
|
||||
settings_->ReloadSettings();
|
||||
|
||||
sources_.clear();
|
||||
|
||||
if (sources.isEmpty()) {
|
||||
sources_ << Song::Source::Unknown
|
||||
<< Song::Source::LocalFile
|
||||
<< Song::Source::Collection
|
||||
<< Song::Source::CDDA
|
||||
<< Song::Source::Device
|
||||
<< Song::Source::Stream
|
||||
<< Song::Source::Tidal
|
||||
<< Song::Source::Subsonic
|
||||
<< Song::Source::Qobuz
|
||||
<< Song::Source::SomaFM
|
||||
<< Song::Source::RadioParadise;
|
||||
}
|
||||
else {
|
||||
for (const QString &source : sources) {
|
||||
sources_ << Song::SourceFromText(source);
|
||||
}
|
||||
}
|
||||
|
||||
emit ScrobblingEnabledChanged(enabled_);
|
||||
emit ScrobbleButtonVisibilityChanged(scrobble_button_);
|
||||
emit LoveButtonVisibilityChanged(love_button_);
|
||||
|
||||
QList<ScrobblerService*> services = services_.values();
|
||||
for (ScrobblerService *service : services) {
|
||||
QList<ScrobblerServicePtr> services = services_.values();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
service->ReloadSettings();
|
||||
}
|
||||
|
||||
@@ -161,31 +107,17 @@ void AudioScrobbler::ReloadSettings() {
|
||||
|
||||
void AudioScrobbler::ToggleScrobbling() {
|
||||
|
||||
bool enabled_old_ = enabled_;
|
||||
enabled_ = !enabled_;
|
||||
settings_->ToggleScrobbling();
|
||||
|
||||
QSettings s;
|
||||
s.beginGroup(ScrobblerSettingsPage::kSettingsGroup);
|
||||
s.setValue("enabled", enabled_);
|
||||
s.endGroup();
|
||||
|
||||
if (enabled_ != enabled_old_) emit ScrobblingEnabledChanged(enabled_);
|
||||
if (enabled_ && !offline_) { Submit(); }
|
||||
if (settings_->enabled() && !settings_->offline()) { Submit(); }
|
||||
|
||||
}
|
||||
|
||||
void AudioScrobbler::ToggleOffline() {
|
||||
|
||||
bool offline_old_ = offline_;
|
||||
offline_ = !offline_;
|
||||
settings_->ToggleOffline();
|
||||
|
||||
QSettings s;
|
||||
s.beginGroup(ScrobblerSettingsPage::kSettingsGroup);
|
||||
s.setValue("offline", offline_);
|
||||
s.endGroup();
|
||||
|
||||
if (offline_ != offline_old_) { emit ScrobblingOfflineChanged(offline_); }
|
||||
if (enabled_ && !offline_) { Submit(); }
|
||||
if (settings_->enabled() && !settings_->offline()) { Submit(); }
|
||||
|
||||
}
|
||||
|
||||
@@ -195,13 +127,13 @@ void AudioScrobbler::ShowConfig() {
|
||||
|
||||
void AudioScrobbler::UpdateNowPlaying(const Song &song) {
|
||||
|
||||
if (!sources_.contains(song.source())) return;
|
||||
if (!settings_->sources().contains(song.source())) return;
|
||||
|
||||
qLog(Debug) << "Sending now playing for song" << song.artist() << song.album() << song.title();
|
||||
|
||||
QList<ScrobblerService*> services = GetAll();
|
||||
for (ScrobblerService *service : services) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
QList<ScrobblerServicePtr> services = GetAll();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
if (!service->enabled()) continue;
|
||||
service->UpdateNowPlaying(song);
|
||||
}
|
||||
|
||||
@@ -209,9 +141,9 @@ void AudioScrobbler::UpdateNowPlaying(const Song &song) {
|
||||
|
||||
void AudioScrobbler::ClearPlaying() {
|
||||
|
||||
QList<ScrobblerService*> services = GetAll();
|
||||
for (ScrobblerService *service : services) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
QList<ScrobblerServicePtr> services = GetAll();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
if (!service->enabled()) continue;
|
||||
service->ClearPlaying();
|
||||
}
|
||||
|
||||
@@ -219,13 +151,13 @@ void AudioScrobbler::ClearPlaying() {
|
||||
|
||||
void AudioScrobbler::Scrobble(const Song &song, const qint64 scrobble_point) {
|
||||
|
||||
if (!sources_.contains(song.source())) return;
|
||||
if (!settings_->sources().contains(song.source())) return;
|
||||
|
||||
qLog(Debug) << "Scrobbling song" << song.artist() << song.album() << song.title() << "at" << scrobble_point;
|
||||
|
||||
QList<ScrobblerService*> services = GetAll();
|
||||
for (ScrobblerService *service : services) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
QList<ScrobblerServicePtr> services = GetAll();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
if (!service->enabled()) continue;
|
||||
service->Scrobble(song);
|
||||
}
|
||||
|
||||
@@ -233,9 +165,9 @@ void AudioScrobbler::Scrobble(const Song &song, const qint64 scrobble_point) {
|
||||
|
||||
void AudioScrobbler::Love() {
|
||||
|
||||
QList<ScrobblerService*> services = GetAll();
|
||||
for (ScrobblerService *service : services) {
|
||||
if (!service->IsEnabled() || !service->IsAuthenticated()) continue;
|
||||
QList<ScrobblerServicePtr> services = GetAll();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
if (!service->enabled() || !service->authenticated()) continue;
|
||||
service->Love();
|
||||
}
|
||||
|
||||
@@ -243,9 +175,9 @@ void AudioScrobbler::Love() {
|
||||
|
||||
void AudioScrobbler::Submit() {
|
||||
|
||||
QList<ScrobblerService*> services = GetAll();
|
||||
for (ScrobblerService *service : services) {
|
||||
if (!service->IsEnabled() || !service->IsAuthenticated() || service->IsSubmitted()) continue;
|
||||
QList<ScrobblerServicePtr> services = GetAll();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
if (!service->enabled() || !service->authenticated() || service->submitted()) continue;
|
||||
service->StartSubmit();
|
||||
}
|
||||
|
||||
@@ -253,9 +185,9 @@ void AudioScrobbler::Submit() {
|
||||
|
||||
void AudioScrobbler::WriteCache() {
|
||||
|
||||
QList<ScrobblerService*> services = GetAll();
|
||||
for (ScrobblerService *service : services) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
QList<ScrobblerServicePtr> services = GetAll();
|
||||
for (ScrobblerServicePtr service : services) {
|
||||
if (!service->enabled()) continue;
|
||||
service->WriteCache();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user