parent
7c51f04140
commit
7a53ca7f8e
|
@ -195,7 +195,7 @@ void AudioScrobbler::Submit() {
|
|||
|
||||
for (ScrobblerService *service : scrobbler_services_->List()) {
|
||||
if (!service->IsEnabled() || !service->IsAuthenticated() || service->IsSubmitted()) continue;
|
||||
service->DoSubmit();
|
||||
service->StartSubmit();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QDesktopServices>
|
||||
#include <QVariant>
|
||||
|
@ -73,7 +75,8 @@ ListenBrainzScrobbler::ListenBrainzScrobbler(Application *app, QObject *parent)
|
|||
login_time_(0),
|
||||
submitted_(false),
|
||||
scrobbled_(false),
|
||||
timestamp_(0) {
|
||||
timestamp_(0),
|
||||
submit_error_(false) {
|
||||
|
||||
refresh_login_timer_.setSingleShot(true);
|
||||
QObject::connect(&refresh_login_timer_, &QTimer::timeout, this, &ListenBrainzScrobbler::RequestNewAccessToken);
|
||||
|
@ -339,7 +342,7 @@ void ListenBrainzScrobbler::AuthenticateReplyFinished(QNetworkReply *reply) {
|
|||
|
||||
qLog(Debug) << "ListenBrainz: Authentication was successful, login expires in" << expires_in_;
|
||||
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
|
||||
}
|
||||
|
||||
|
@ -509,25 +512,22 @@ void ListenBrainzScrobbler::Scrobble(const Song &song) {
|
|||
|
||||
if (app_->scrobbler()->IsOffline() || !IsAuthenticated()) return;
|
||||
|
||||
if (!submitted_) {
|
||||
submitted_ = true;
|
||||
if (app_->scrobbler()->SubmitDelay() <= 0) {
|
||||
Submit();
|
||||
}
|
||||
else if (!timer_submit_.isActive()) {
|
||||
timer_submit_.setInterval(static_cast<int>(app_->scrobbler()->SubmitDelay() * kMsecPerSec));
|
||||
timer_submit_.start();
|
||||
}
|
||||
}
|
||||
StartSubmit();
|
||||
|
||||
}
|
||||
|
||||
void ListenBrainzScrobbler::DoSubmit() {
|
||||
void ListenBrainzScrobbler::StartSubmit(const bool initial) {
|
||||
|
||||
if (!submitted_ && cache_->Count() > 0) {
|
||||
submitted_ = true;
|
||||
if (!timer_submit_.isActive()) {
|
||||
timer_submit_.setInterval(static_cast<int>(app_->scrobbler()->SubmitDelay() * kMsecPerSec));
|
||||
if (initial && app_->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);
|
||||
timer_submit_.setInterval(submit_delay);
|
||||
timer_submit_.start();
|
||||
}
|
||||
}
|
||||
|
@ -538,8 +538,6 @@ void ListenBrainzScrobbler::Submit() {
|
|||
|
||||
qLog(Debug) << "ListenBrainz: Submitting scrobbles.";
|
||||
|
||||
submitted_ = false;
|
||||
|
||||
if (!IsEnabled() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return;
|
||||
|
||||
QJsonArray array;
|
||||
|
@ -573,6 +571,8 @@ void ListenBrainzScrobbler::Submit() {
|
|||
|
||||
if (i <= 0) return;
|
||||
|
||||
submitted_ = true;
|
||||
|
||||
QJsonObject object;
|
||||
object.insert("listen_type", "import");
|
||||
object.insert("payload", array);
|
||||
|
@ -591,17 +591,21 @@ void ListenBrainzScrobbler::ScrobbleRequestFinished(QNetworkReply *reply, const
|
|||
QObject::disconnect(reply, nullptr, this, nullptr);
|
||||
reply->deleteLater();
|
||||
|
||||
submitted_ = false;
|
||||
|
||||
QByteArray data = GetReplyData(reply);
|
||||
if (data.isEmpty()) {
|
||||
cache_->ClearSent(list);
|
||||
DoSubmit();
|
||||
submit_error_ = true;
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject json_obj = ExtractJsonObj(data);
|
||||
if (json_obj.isEmpty()) {
|
||||
cache_->ClearSent(list);
|
||||
DoSubmit();
|
||||
submit_error_ = true;
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -609,7 +613,8 @@ void ListenBrainzScrobbler::ScrobbleRequestFinished(QNetworkReply *reply, const
|
|||
QString error_desc = json_obj["error_description"].toString();
|
||||
Error(error_desc);
|
||||
cache_->ClearSent(list);
|
||||
DoSubmit();
|
||||
submit_error_ = true;
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -619,7 +624,8 @@ void ListenBrainzScrobbler::ScrobbleRequestFinished(QNetworkReply *reply, const
|
|||
}
|
||||
|
||||
cache_->Flush(list);
|
||||
DoSubmit();
|
||||
submit_error_ = false;
|
||||
StartSubmit();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ class ListenBrainzScrobbler : public ScrobblerService {
|
|||
void AuthError(const QString &error);
|
||||
void Error(const QString &error, const QVariant &debug = QVariant()) override;
|
||||
void RequestAccessToken(const QUrl &redirect_url = QUrl(), const QString &code = QString());
|
||||
void DoSubmit() override;
|
||||
void StartSubmit(const bool initial = false) override;
|
||||
void CheckScrobblePrevSong();
|
||||
|
||||
static const char *kOAuthAuthorizeUrl;
|
||||
|
@ -118,6 +118,7 @@ class ListenBrainzScrobbler : public ScrobblerService {
|
|||
quint64 timestamp_;
|
||||
QTimer refresh_login_timer_;
|
||||
QTimer timer_submit_;
|
||||
bool submit_error_;
|
||||
|
||||
QList<QNetworkReply*> replies_;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class ScrobblerService : public QObject {
|
|||
virtual void Love() {}
|
||||
virtual void Error(const QString &error, const QVariant &debug = QVariant()) = 0;
|
||||
|
||||
virtual void DoSubmit() = 0;
|
||||
virtual void StartSubmit(const bool initial = false) = 0;
|
||||
virtual void Submitted() = 0;
|
||||
virtual bool IsSubmitted() const { return false; }
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ ScrobblingAPI20::ScrobblingAPI20(const QString &name, const QString &settings_gr
|
|||
subscriber_(false),
|
||||
submitted_(false),
|
||||
scrobbled_(false),
|
||||
timestamp_(0) {
|
||||
timestamp_(0),
|
||||
submit_error_(false) {
|
||||
|
||||
timer_submit_.setSingleShot(true);
|
||||
QObject::connect(&timer_submit_, &QTimer::timeout, this, &ScrobblingAPI20::Submit);
|
||||
|
@ -345,7 +346,7 @@ void ScrobblingAPI20::AuthenticateReplyFinished(QNetworkReply *reply) {
|
|||
|
||||
emit AuthenticationComplete(true);
|
||||
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
|
||||
}
|
||||
|
||||
|
@ -536,25 +537,22 @@ void ScrobblingAPI20::Scrobble(const Song &song) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!submitted_) {
|
||||
submitted_ = true;
|
||||
if (!batch_ || app_->scrobbler()->SubmitDelay() <= 0) {
|
||||
Submit();
|
||||
}
|
||||
else if (!timer_submit_.isActive()) {
|
||||
timer_submit_.setInterval(static_cast<int>(app_->scrobbler()->SubmitDelay() * kMsecPerSec));
|
||||
timer_submit_.start();
|
||||
}
|
||||
}
|
||||
StartSubmit(true);
|
||||
|
||||
}
|
||||
|
||||
void ScrobblingAPI20::DoSubmit() {
|
||||
void ScrobblingAPI20::StartSubmit(const bool initial) {
|
||||
|
||||
if (!submitted_ && cache()->Count() > 0) {
|
||||
submitted_ = true;
|
||||
if (!timer_submit_.isActive()) {
|
||||
timer_submit_.setInterval(static_cast<int>(app_->scrobbler()->SubmitDelay() * kMsecPerSec));
|
||||
if (initial && (!batch_ || app_->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);
|
||||
timer_submit_.setInterval(submit_delay);
|
||||
timer_submit_.start();
|
||||
}
|
||||
}
|
||||
|
@ -563,8 +561,6 @@ void ScrobblingAPI20::DoSubmit() {
|
|||
|
||||
void ScrobblingAPI20::Submit() {
|
||||
|
||||
submitted_ = false;
|
||||
|
||||
if (!IsEnabled() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return;
|
||||
|
||||
qLog(Debug) << name_ << "Submitting scrobbles.";
|
||||
|
@ -601,6 +597,8 @@ void ScrobblingAPI20::Submit() {
|
|||
|
||||
if (!batch_ || i <= 0) return;
|
||||
|
||||
submitted_ = true;
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, list]() { ScrobbleRequestFinished(reply, list); });
|
||||
|
||||
|
@ -613,17 +611,21 @@ void ScrobblingAPI20::ScrobbleRequestFinished(QNetworkReply *reply, const QList<
|
|||
QObject::disconnect(reply, nullptr, this, nullptr);
|
||||
reply->deleteLater();
|
||||
|
||||
submitted_ = false;
|
||||
|
||||
QByteArray data = GetReplyData(reply);
|
||||
if (data.isEmpty()) {
|
||||
cache()->ClearSent(list);
|
||||
DoSubmit();
|
||||
submit_error_ = true;
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject json_obj = ExtractJsonObj(data);
|
||||
if (json_obj.isEmpty()) {
|
||||
cache()->ClearSent(list);
|
||||
DoSubmit();
|
||||
submit_error_ = true;
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -633,52 +635,53 @@ void ScrobblingAPI20::ScrobbleRequestFinished(QNetworkReply *reply, const QList<
|
|||
QString error_reason = QString("%1 (%2)").arg(error_message).arg(error_code);
|
||||
Error(error_reason);
|
||||
cache()->ClearSent(list);
|
||||
DoSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!json_obj.contains("scrobbles")) {
|
||||
Error("Json reply from server is missing scrobbles.", json_obj);
|
||||
cache()->ClearSent(list);
|
||||
DoSubmit();
|
||||
submit_error_ = true;
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
cache()->Flush(list);
|
||||
submit_error_ = false;
|
||||
|
||||
if (!json_obj.contains("scrobbles")) {
|
||||
Error("Json reply from server is missing scrobbles.", json_obj);
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonValue value_scrobbles = json_obj["scrobbles"];
|
||||
if (!value_scrobbles.isObject()) {
|
||||
Error("Json scrobbles is not an object.", json_obj);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
json_obj = value_scrobbles.toObject();
|
||||
if (json_obj.isEmpty()) {
|
||||
Error("Json scrobbles object is empty.", value_scrobbles);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
if (!json_obj.contains("@attr") || !json_obj.contains("scrobble")) {
|
||||
Error("Json scrobbles object is missing values.", json_obj);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonValue value_attr = json_obj["@attr"];
|
||||
if (!value_attr.isObject()) {
|
||||
Error("Json scrobbles attr is not an object.", value_attr);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
QJsonObject obj_attr = value_attr.toObject();
|
||||
if (obj_attr.isEmpty()) {
|
||||
Error("Json scrobbles attr is empty.", value_attr);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
if (!obj_attr.contains("accepted") || !obj_attr.contains("ignored")) {
|
||||
Error("Json scrobbles attr is missing values.", obj_attr);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
int accepted = obj_attr["accepted"].toInt();
|
||||
|
@ -693,7 +696,7 @@ void ScrobblingAPI20::ScrobbleRequestFinished(QNetworkReply *reply, const QList<
|
|||
QJsonObject obj_scrobble = value_scrobble.toObject();
|
||||
if (obj_scrobble.isEmpty()) {
|
||||
Error("Json scrobbles scrobble object is empty.", obj_scrobble);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
array_scrobble.append(obj_scrobble);
|
||||
|
@ -702,13 +705,13 @@ void ScrobblingAPI20::ScrobbleRequestFinished(QNetworkReply *reply, const QList<
|
|||
array_scrobble = value_scrobble.toArray();
|
||||
if (array_scrobble.isEmpty()) {
|
||||
Error("Json scrobbles scrobble array is empty.", value_scrobble);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Error("Json scrobbles scrobble is not an object or array.", value_scrobble);
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -774,7 +777,7 @@ void ScrobblingAPI20::ScrobbleRequestFinished(QNetworkReply *reply, const QList<
|
|||
|
||||
}
|
||||
|
||||
DoSubmit();
|
||||
StartSubmit();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ class ScrobblingAPI20 : public ScrobblerService {
|
|||
void SendSingleScrobble(ScrobblerCacheItemPtr item);
|
||||
void Error(const QString &error, const QVariant &debug = QVariant()) override;
|
||||
static QString ErrorString(const ScrobbleErrorCode error);
|
||||
void DoSubmit() override;
|
||||
void StartSubmit(const bool initial = false) override;
|
||||
void CheckScrobblePrevSong();
|
||||
|
||||
QString name_;
|
||||
|
@ -154,6 +154,7 @@ class ScrobblingAPI20 : public ScrobblerService {
|
|||
Song song_playing_;
|
||||
bool scrobbled_;
|
||||
quint64 timestamp_;
|
||||
bool submit_error_;
|
||||
|
||||
QTimer timer_submit_;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ class SubsonicScrobbler : public ScrobblerService {
|
|||
void Scrobble(const Song &song) override;
|
||||
void Error(const QString &error, const QVariant &debug = QVariant()) override;
|
||||
|
||||
void DoSubmit() override {}
|
||||
void StartSubmit(const bool initial = false) override { Q_UNUSED(initial) }
|
||||
void Submitted() override { submitted_ = true; }
|
||||
bool IsSubmitted() const override { return submitted_; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue