diff --git a/src/internet/lastfm/lastfmservice.cpp b/src/internet/lastfm/lastfmservice.cpp index d8445fa60..a3981d1f4 100644 --- a/src/internet/lastfm/lastfmservice.cpp +++ b/src/internet/lastfm/lastfmservice.cpp @@ -74,6 +74,7 @@ const char* LastFMService::kSettingsGroup = "Last.fm"; const char* LastFMService::kAudioscrobblerClientId = "tng"; const char* LastFMService::kApiKey = "75d20fb472be99275392aefa2760ea09"; const char* LastFMService::kSecret = "d3072b60ae626be12be69448f5c46e70"; +const char* LastFMService::kAuthLoginUrl = "http://www.last.fm/api/auth/?api_key=%1&token=%2"; LastFMService::LastFMService(Application* app, QObject* parent) : Scrobbler(parent), @@ -82,6 +83,8 @@ LastFMService::LastFMService(Application* app, QObject* parent) scrobbling_enabled_(false), connection_problems_(false), app_(app) { + lastfm::ws::setScheme(lastfm::ws::Https); + ReloadSettings(); // we emit the signal the first time to be sure the buttons are in the right @@ -127,13 +130,32 @@ bool LastFMService::IsSubscriber() const { return settings.value("Subscriber", false).toBool(); } -void LastFMService::Authenticate(const QString& username, - const QString& password) { +void LastFMService::GetToken() { QMap params; - params["method"] = "auth.getMobileSession"; - params["username"] = username; - params["authToken"] = - lastfm::md5((username + lastfm::md5(password.toUtf8())).toUtf8()); + params["method"] = "auth.getToken"; + QNetworkReply* reply = lastfm::ws::post(params); + NewClosure(reply, SIGNAL(finished()), this, + SLOT(GetTokenReplyFinished(QNetworkReply*)), reply); +} + +void LastFMService::GetTokenReplyFinished(QNetworkReply* reply) { + reply->deleteLater(); + + // Parse the reply + lastfm::XmlQuery lfm(lastfm::compat::EmptyXmlQuery()); + if (lastfm::compat::ParseQuery(reply->readAll(), &lfm)) { + QString token = lfm["token"].text(); + + emit TokenReceived(true, token); + } else { + emit TokenReceived(false, lfm["error"].text().trimmed()); + } +} + +void LastFMService::Authenticate(const QString& token) { + QMap params; + params["method"] = "auth.getSession"; + params["token"] = token; QNetworkReply* reply = lastfm::ws::post(params); NewClosure(reply, SIGNAL(finished()), this, @@ -141,17 +163,6 @@ void LastFMService::Authenticate(const QString& username, // If we need more detailed error reporting, handle error(NetworkError) signal } -void LastFMService::SignOut() { - lastfm::ws::Username.clear(); - lastfm::ws::SessionKey.clear(); - - QSettings settings; - settings.beginGroup(kSettingsGroup); - - settings.setValue("Username", QString()); - settings.setValue("Session", QString()); -} - void LastFMService::AuthenticateReplyFinished(QNetworkReply* reply) { reply->deleteLater(); @@ -181,6 +192,17 @@ void LastFMService::AuthenticateReplyFinished(QNetworkReply* reply) { emit AuthenticationComplete(true, QString()); } +void LastFMService::SignOut() { + lastfm::ws::Username.clear(); + lastfm::ws::SessionKey.clear(); + + QSettings settings; + settings.beginGroup(kSettingsGroup); + + settings.setValue("Username", QString()); + settings.setValue("Session", QString()); +} + void LastFMService::UpdateSubscriberStatus() { QMap params; params["method"] = "user.getInfo"; diff --git a/src/internet/lastfm/lastfmservice.h b/src/internet/lastfm/lastfmservice.h index 3f8af4627..d777be976 100644 --- a/src/internet/lastfm/lastfmservice.h +++ b/src/internet/lastfm/lastfmservice.h @@ -54,6 +54,7 @@ class LastFMService : public Scrobbler { static const char* kAudioscrobblerClientId; static const char* kApiKey; static const char* kSecret; + static const char* kAuthLoginUrl; void ReloadSettings(); @@ -68,7 +69,8 @@ class LastFMService : public Scrobbler { bool PreferAlbumArtist() const { return prefer_albumartist_; } bool HasConnectionProblems() const { return connection_problems_; } - void Authenticate(const QString& username, const QString& password); + void GetToken(); + void Authenticate(const QString& token); void SignOut(); void UpdateSubscriberStatus(); @@ -81,6 +83,7 @@ class LastFMService : public Scrobbler { void ToggleScrobbling(); signals: + void TokenReceived(bool success, const QString& token); void AuthenticationComplete(bool success, const QString& error_message); void ScrobblingEnabledChanged(bool value); void ButtonVisibilityChanged(bool value); @@ -94,6 +97,7 @@ class LastFMService : public Scrobbler { void SavedItemsChanged(); private slots: + void GetTokenReplyFinished(QNetworkReply* reply); void AuthenticateReplyFinished(QNetworkReply* reply); void UpdateSubscriberStatusFinished(QNetworkReply* reply); diff --git a/src/internet/lastfm/lastfmsettingspage.cpp b/src/internet/lastfm/lastfmsettingspage.cpp index 016a78a91..7e79bad2b 100644 --- a/src/internet/lastfm/lastfmsettingspage.cpp +++ b/src/internet/lastfm/lastfmsettingspage.cpp @@ -24,6 +24,7 @@ #include +#include #include #include @@ -42,17 +43,16 @@ LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog) // Icons setWindowIcon(IconLoader::Load("lastfm", IconLoader::Provider)); + connect(service_, SIGNAL(TokenReceived(bool,QString)), + SLOT(TokenReceived(bool,QString))); connect(service_, SIGNAL(AuthenticationComplete(bool, QString)), SLOT(AuthenticationComplete(bool, QString))); connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout())); connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(Login())); connect(ui_->login, SIGNAL(clicked()), SLOT(Login())); - ui_->login_state->AddCredentialField(ui_->username); - ui_->login_state->AddCredentialField(ui_->password); - ui_->login_state->AddCredentialGroup(ui_->groupBox); + ui_->login_state->AddCredentialGroup(ui_->login_container); - ui_->username->setMinimumWidth(QFontMetrics(QFont()).width("WWWWWWWWWWWW")); resize(sizeHint()); } @@ -62,7 +62,22 @@ void LastFMSettingsPage::Login() { waiting_for_auth_ = true; ui_->login_state->SetLoggedIn(LoginStateWidget::LoginInProgress); - service_->Authenticate(ui_->username->text(), ui_->password->text()); + service_->GetToken(); +} + +void LastFMSettingsPage::TokenReceived(bool success, const QString &token) { + if (!success) { + QMessageBox::warning(this, tr("Last.fm authentication failed"), token); + return; + } + + QString url = QString(LastFMService::kAuthLoginUrl).arg(LastFMService::kApiKey, token); + QDesktopServices::openUrl(QUrl(url)); + + QMessageBox::information(this, tr("Last.fm authentication"), + tr("Click Ok once you authenticated Clementine in your last.fm account.")); + + service_->Authenticate(token); } void LastFMSettingsPage::AuthenticationComplete(bool success, @@ -72,8 +87,6 @@ void LastFMSettingsPage::AuthenticationComplete(bool success, waiting_for_auth_ = false; if (success) { - // Clear password just to be sure - ui_->password->clear(); // Save settings Save(); } else { @@ -109,8 +122,6 @@ void LastFMSettingsPage::Save() { } void LastFMSettingsPage::Logout() { - ui_->username->clear(); - ui_->password->clear(); RefreshControls(false); service_->SignOut(); diff --git a/src/internet/lastfm/lastfmsettingspage.h b/src/internet/lastfm/lastfmsettingspage.h index 24001bc44..225cb407c 100644 --- a/src/internet/lastfm/lastfmsettingspage.h +++ b/src/internet/lastfm/lastfmsettingspage.h @@ -38,6 +38,7 @@ class LastFMSettingsPage : public SettingsPage { private slots: void Login(); + void TokenReceived(bool success, const QString& token); void AuthenticationComplete(bool success, const QString& error_message); void Logout(); diff --git a/src/internet/lastfm/lastfmsettingspage.ui b/src/internet/lastfm/lastfmsettingspage.ui index cf8f865b6..dbc675411 100644 --- a/src/internet/lastfm/lastfmsettingspage.ui +++ b/src/internet/lastfm/lastfmsettingspage.ui @@ -18,26 +18,19 @@ - - - Account details - - - - QFormLayout::AllNonFixedFieldsGrow + + + + 28 - - - - Last.fm username - - - - + + 0 + + + 0 + + - - - @@ -45,19 +38,28 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - + + - Last.fm password + Clicking the Login button will open a web browser. You should return to Clementine after you have logged in. - - - - - - QLineEdit::Password + + true @@ -112,6 +114,9 @@ Qt::Vertical + + QSizePolicy::MinimumExpanding + 20 @@ -131,9 +136,6 @@ - username - password - login scrobble love_ban_ scrobble_button