Add love button
This commit is contained in:
@@ -49,6 +49,7 @@ AudioScrobbler::AudioScrobbler(Application *app, QObject *parent) :
|
||||
enabled_(false),
|
||||
offline_(false),
|
||||
scrobble_button_(false),
|
||||
love_button_(false),
|
||||
submit_delay_(0)
|
||||
{
|
||||
|
||||
@@ -69,11 +70,13 @@ void AudioScrobbler::ReloadSettings() {
|
||||
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();
|
||||
s.endGroup();
|
||||
|
||||
emit ScrobblingEnabledChanged(enabled_);
|
||||
emit ScrobbleButtonVisibilityChanged(scrobble_button_);
|
||||
emit LoveButtonVisibilityChanged(love_button_);
|
||||
|
||||
for (ScrobblerService *service : scrobbler_services_->List()) {
|
||||
service->ReloadSettings();
|
||||
@@ -116,25 +119,32 @@ void AudioScrobbler::ShowConfig() {
|
||||
}
|
||||
|
||||
void AudioScrobbler::UpdateNowPlaying(const Song &song) {
|
||||
qLog(Debug) << "Sending now playing for song" << song.title();
|
||||
qLog(Debug) << "Sending now playing for song" << song.artist() << song.album() << song.title();
|
||||
for (ScrobblerService *service : scrobbler_services_->List()) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
service->UpdateNowPlaying(song);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioScrobbler::ClearPlaying() {
|
||||
for (ScrobblerService *service : scrobbler_services_->List()) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
service->ClearPlaying();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioScrobbler::Scrobble(const Song &song, const int scrobble_point) {
|
||||
qLog(Debug) << "Scrobbling song" << QString("") + song.title() + QString("") << "at" << scrobble_point;
|
||||
qLog(Debug) << "Scrobbling song" << song.artist() << song.album() << song.title() << "at" << scrobble_point;
|
||||
for (ScrobblerService *service : scrobbler_services_->List()) {
|
||||
if (!service->IsEnabled()) continue;
|
||||
service->Scrobble(song);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioScrobbler::Love(const Song &song) {
|
||||
void AudioScrobbler::Love() {
|
||||
for (ScrobblerService *service : scrobbler_services_->List()) {
|
||||
if (!service->IsEnabled() || !service->IsAuthenticated()) continue;
|
||||
service->Love(song);
|
||||
service->Love();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,11 +46,12 @@ class AudioScrobbler : public QObject {
|
||||
bool IsEnabled() const { return enabled_; }
|
||||
bool IsOffline() const { return offline_; }
|
||||
bool ScrobbleButton() const { return scrobble_button_; }
|
||||
bool LoveButton() const { return love_button_; }
|
||||
int SubmitDelay() const { return submit_delay_; }
|
||||
|
||||
void UpdateNowPlaying(const Song &song);
|
||||
void ClearPlaying();
|
||||
void Scrobble(const Song &song, const int scrobble_point);
|
||||
void Love(const Song &song);
|
||||
void ShowConfig();
|
||||
void ConnectError();
|
||||
|
||||
@@ -65,6 +66,7 @@ class AudioScrobbler : public QObject {
|
||||
void ToggleScrobbling();
|
||||
void ToggleOffline();
|
||||
void Submit();
|
||||
void Love();
|
||||
void WriteCache();
|
||||
void ErrorReceived(QString);
|
||||
|
||||
@@ -73,6 +75,7 @@ class AudioScrobbler : public QObject {
|
||||
void ScrobblingEnabledChanged(bool value);
|
||||
void ScrobblingOfflineChanged(bool value);
|
||||
void ScrobbleButtonVisibilityChanged(bool value);
|
||||
void LoveButtonVisibilityChanged(bool value);
|
||||
|
||||
private:
|
||||
|
||||
@@ -82,6 +85,7 @@ class AudioScrobbler : public QObject {
|
||||
bool enabled_;
|
||||
bool offline_;
|
||||
bool scrobble_button_;
|
||||
bool love_button_;
|
||||
int submit_delay_;
|
||||
|
||||
};
|
||||
|
||||
@@ -340,7 +340,7 @@ void ListenBrainzScrobbler::UpdateNowPlaying(const Song &song) {
|
||||
album = album.remove(Song::kAlbumRemoveMisc);
|
||||
|
||||
QJsonObject object_track_metadata;
|
||||
object_track_metadata.insert("artist_name", QJsonValue::fromVariant(song.artist()));
|
||||
object_track_metadata.insert("artist_name", QJsonValue::fromVariant(song.effective_albumartist()));
|
||||
object_track_metadata.insert("release_name", QJsonValue::fromVariant(album));
|
||||
object_track_metadata.insert("track_name", QJsonValue::fromVariant(song.title()));
|
||||
|
||||
@@ -394,6 +394,10 @@ void ListenBrainzScrobbler::UpdateNowPlayingRequestFinished(QNetworkReply *reply
|
||||
|
||||
}
|
||||
|
||||
void ListenBrainzScrobbler::ClearPlaying() {
|
||||
song_playing_ = Song();
|
||||
}
|
||||
|
||||
void ListenBrainzScrobbler::Scrobble(const Song &song) {
|
||||
|
||||
if (song.id() != song_playing_.id() || song.url() != song_playing_.url() || !song.is_metadata_good()) return;
|
||||
@@ -450,7 +454,8 @@ void ListenBrainzScrobbler::Submit() {
|
||||
QJsonObject object_listen;
|
||||
object_listen.insert("listened_at", QJsonValue::fromVariant(item->timestamp_));
|
||||
QJsonObject object_track_metadata;
|
||||
object_track_metadata.insert("artist_name", QJsonValue::fromVariant(item->artist_));
|
||||
if (item->albumartist_.isEmpty()) object_track_metadata.insert("artist_name", QJsonValue::fromVariant(item->artist_));
|
||||
else object_track_metadata.insert("artist_name", QJsonValue::fromVariant(item->albumartist_));
|
||||
object_track_metadata.insert("release_name", QJsonValue::fromVariant(item->album_));
|
||||
object_track_metadata.insert("track_name", QJsonValue::fromVariant(item->song_));
|
||||
object_listen.insert("track_metadata", object_track_metadata);
|
||||
@@ -508,8 +513,6 @@ void ListenBrainzScrobbler::ScrobbleRequestFinished(QNetworkReply *reply, QList<
|
||||
|
||||
}
|
||||
|
||||
void ListenBrainzScrobbler::Love(const Song &song) {}
|
||||
|
||||
void ListenBrainzScrobbler::AuthError(QString error) {
|
||||
emit AuthenticationComplete(false, error);
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ class ListenBrainzScrobbler : public ScrobblerService {
|
||||
void ShowConfig();
|
||||
void Submit();
|
||||
void UpdateNowPlaying(const Song &song);
|
||||
void ClearPlaying();
|
||||
void Scrobble(const Song &song);
|
||||
void Love(const Song &song);
|
||||
|
||||
signals:
|
||||
void AuthenticationComplete(bool success, QString error = QString());
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
ScrobblerService::ScrobblerService(const QString &name, Application *app, QObject *parent) : QObject(parent), name_(name) {}
|
||||
|
||||
QJsonObject ScrobblerService::ExtractJsonObj(const QByteArray &data) {
|
||||
QJsonObject ScrobblerService::ExtractJsonObj(const QByteArray &data, const bool ignore_empty) {
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument json_doc = QJsonDocument::fromJson(data, &error);
|
||||
@@ -49,7 +49,8 @@ QJsonObject ScrobblerService::ExtractJsonObj(const QByteArray &data) {
|
||||
}
|
||||
QJsonObject json_obj = json_doc.object();
|
||||
if (json_obj.isEmpty()) {
|
||||
Error("Received empty Json object.", json_doc);
|
||||
if (!ignore_empty)
|
||||
Error("Received empty Json object.", json_doc);
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,9 @@ class ScrobblerService : public QObject {
|
||||
virtual bool IsAuthenticated() const { return false; }
|
||||
|
||||
virtual void UpdateNowPlaying(const Song &song) = 0;
|
||||
virtual void ClearPlaying() = 0;
|
||||
virtual void Scrobble(const Song &song) = 0;
|
||||
virtual void Love(const Song &song) = 0;
|
||||
virtual void Love() {}
|
||||
virtual void Error(QString error, QVariant debug = QVariant()) = 0;
|
||||
|
||||
virtual void DoSubmit() = 0;
|
||||
@@ -61,7 +62,7 @@ class ScrobblerService : public QObject {
|
||||
typedef QPair<QByteArray, QByteArray> EncodedParam;
|
||||
typedef QList<Param> ParamList;
|
||||
|
||||
QJsonObject ExtractJsonObj(const QByteArray &data);
|
||||
QJsonObject ExtractJsonObj(const QByteArray &data, const bool ignore_empty = false);
|
||||
|
||||
public slots:
|
||||
virtual void Submit() = 0;
|
||||
|
||||
@@ -414,6 +414,7 @@ void ScrobblingAPI20::UpdateNowPlaying(const Song &song) {
|
||||
<< Param("artist", song.artist())
|
||||
<< Param("track", song.title())
|
||||
<< Param("album", album);
|
||||
if (!song.albumartist().isEmpty()) params << Param("albumArtist", song.albumartist());
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(UpdateNowPlayingRequestFinished(QNetworkReply*)), reply);
|
||||
@@ -449,6 +450,10 @@ void ScrobblingAPI20::UpdateNowPlayingRequestFinished(QNetworkReply *reply) {
|
||||
|
||||
}
|
||||
|
||||
void ScrobblingAPI20::ClearPlaying() {
|
||||
song_playing_ = Song();
|
||||
}
|
||||
|
||||
void ScrobblingAPI20::Scrobble(const Song &song) {
|
||||
|
||||
if (song.id() != song_playing_.id() || song.url() != song_playing_.url() || !song.is_metadata_good()) return;
|
||||
@@ -488,14 +493,13 @@ void ScrobblingAPI20::DoSubmit() {
|
||||
|
||||
void ScrobblingAPI20::Submit() {
|
||||
|
||||
qLog(Debug) << __PRETTY_FUNCTION__ << name_;
|
||||
|
||||
submitted_ = false;
|
||||
|
||||
if (!IsEnabled() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return;
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("method", "track.scrobble");
|
||||
qLog(Debug) << name_ << "Submitting scrobbles.";
|
||||
|
||||
ParamList params = ParamList() << Param("method", "track.scrobble");
|
||||
|
||||
int i(0);
|
||||
QList<quint64> list;
|
||||
@@ -820,18 +824,73 @@ void ScrobblingAPI20::SingleScrobbleRequestFinished(QNetworkReply *reply, quint6
|
||||
|
||||
}
|
||||
|
||||
void ScrobblingAPI20::Love(const Song &song) {
|
||||
void ScrobblingAPI20::Love() {
|
||||
|
||||
if (!song_playing_.is_valid() || !song_playing_.is_metadata_good()) return;
|
||||
|
||||
if (!IsAuthenticated()) app_->scrobbler()->ShowConfig();
|
||||
|
||||
qLog(Debug) << name_ << "Sending love for song" << song_playing_.artist() << song_playing_.album() << song_playing_.title();
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("method", "track.love")
|
||||
<< Param("artist", song.artist())
|
||||
<< Param("track", song.title())
|
||||
<< Param("album", song.album());
|
||||
<< Param("artist", song_playing_.artist())
|
||||
<< Param("track", song_playing_.title())
|
||||
<< Param("album", song_playing_.album());
|
||||
if (!song_playing_.albumartist().isEmpty()) params << Param("albumArtist", song_playing_.albumartist());
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(RequestFinished(QNetworkReply*)), reply);
|
||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(LoveRequestFinished(QNetworkReply*)), reply);
|
||||
|
||||
}
|
||||
|
||||
void ScrobblingAPI20::LoveRequestFinished(QNetworkReply *reply) {
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
QByteArray data = GetReplyData(reply);
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject json_obj = ExtractJsonObj(data, true);
|
||||
if (json_obj.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (json_obj.contains("error")) {
|
||||
QJsonValue json_value = json_obj["error"];
|
||||
if (!json_value.isObject()) {
|
||||
Error("Error is not on object.");
|
||||
return;
|
||||
}
|
||||
QJsonObject json_obj_error = json_value.toObject();
|
||||
if (json_obj_error.isEmpty()) {
|
||||
Error("Received empty json error object.", json_obj);
|
||||
return;
|
||||
}
|
||||
if (json_obj_error.contains("code") && json_obj_error.contains("#text")) {
|
||||
int code = json_obj_error["code"].toInt();
|
||||
QString text = json_obj_error["#text"].toString();
|
||||
QString error_reason = QString("%1 (%2)").arg(text).arg(code);
|
||||
Error(error_reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (json_obj.contains("lfm")) {
|
||||
QJsonValue json_value = json_obj["lfm"];
|
||||
if (json_value.isObject()) {
|
||||
QJsonObject json_obj_lfm = json_value.toObject();
|
||||
if (json_obj_lfm.contains("status")) {
|
||||
QString status = json_obj_lfm["status"].toString();
|
||||
qLog(Debug) << name_ << "Received love status:" << status;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qLog(Debug) << name_ << json_obj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,10 @@ class ScrobblingAPI20 : public ScrobblerService {
|
||||
void Authenticate(const bool https = false);
|
||||
void Logout();
|
||||
void UpdateNowPlaying(const Song &song);
|
||||
void ClearPlaying();
|
||||
void Scrobble(const Song &song);
|
||||
void Submit();
|
||||
void Love(const Song &song);
|
||||
void Love();
|
||||
|
||||
signals:
|
||||
void AuthenticationComplete(bool success, QString error = QString());
|
||||
@@ -85,6 +86,7 @@ class ScrobblingAPI20 : public ScrobblerService {
|
||||
void UpdateNowPlayingRequestFinished(QNetworkReply *reply);
|
||||
void ScrobbleRequestFinished(QNetworkReply *reply, QList<quint64>);
|
||||
void SingleScrobbleRequestFinished(QNetworkReply *reply, quint64 timestamp);
|
||||
void LoveRequestFinished(QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user