diff --git a/src/covermanager/tidalcoverprovider.cpp b/src/covermanager/tidalcoverprovider.cpp index 2d4c39f96..27f55d639 100644 --- a/src/covermanager/tidalcoverprovider.cpp +++ b/src/covermanager/tidalcoverprovider.cpp @@ -99,8 +99,7 @@ bool TidalCoverProvider::StartSearch(const QString &artist, const QString &album QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (service_->oauth() && !service_->access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + service_->access_token().toUtf8()); - else if (!service_->session_id().isEmpty()) req.setRawHeader("X-Tidal-SessionId", service_->session_id().toUtf8()); + if (!service_->access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + service_->access_token().toUtf8()); QNetworkReply *reply = network_->get(req); replies_ << reply; diff --git a/src/settings/tidalsettingspage.cpp b/src/settings/tidalsettingspage.cpp index dd5981f9c..70dd24335 100644 --- a/src/settings/tidalsettingspage.cpp +++ b/src/settings/tidalsettingspage.cpp @@ -53,10 +53,8 @@ TidalSettingsPage::TidalSettingsPage(SettingsDialog *dialog, SharedPtrbutton_login, &QPushButton::clicked, this, &TidalSettingsPage::LoginClicked); QObject::connect(ui_->login_state, &LoginStateWidget::LogoutClicked, this, &TidalSettingsPage::LogoutClicked); - QObject::connect(ui_->oauth, &QCheckBox::toggled, this, &TidalSettingsPage::OAuthClicked); QObject::connect(this, &TidalSettingsPage::Authorize, &*service_, &TidalService::StartAuthorization); - QObject::connect(this, &TidalSettingsPage::Login, &*service_, &TidalService::SendLoginWithCredentials); QObject::connect(&*service_, &StreamingService::LoginFailure, this, &TidalSettingsPage::LoginFailure); QObject::connect(&*service_, &StreamingService::LoginSuccess, this, &TidalSettingsPage::LoginSuccess); @@ -88,16 +86,7 @@ void TidalSettingsPage::Load() { Settings s; s.beginGroup(kSettingsGroup); ui_->enable->setChecked(s.value(kEnabled, false).toBool()); - ui_->oauth->setChecked(s.value(kOAuth, true).toBool()); - ui_->client_id->setText(s.value(kClientId).toString()); - ui_->api_token->setText(s.value(kApiToken).toString()); - - ui_->username->setText(s.value(kUsername).toString()); - QByteArray password = s.value(kPassword).toByteArray(); - if (password.isEmpty()) ui_->password->clear(); - else ui_->password->setText(QString::fromUtf8(QByteArray::fromBase64(password))); - ComboBoxLoadFromSettings(s, ui_->quality, QLatin1String(kQuality), u"LOSSLESS"_s); ui_->searchdelay->setValue(s.value(kSearchDelay, 1500).toInt()); ui_->artistssearchlimit->setValue(s.value("kArtistsSearchLimit", 4).toInt()); @@ -108,11 +97,11 @@ void TidalSettingsPage::Load() { ComboBoxLoadFromSettings(s, ui_->coversize, QLatin1String(kCoverSize), u"640x640"_s); ui_->streamurl->setCurrentIndex(ui_->streamurl->findData(s.value(kStreamUrl, static_cast(StreamUrlMethod::StreamUrl)).toInt())); ui_->checkbox_album_explicit->setChecked(s.value(kAlbumExplicit, false).toBool()); - s.endGroup(); - OAuthClicked(ui_->oauth->isChecked()); - if (service_->authenticated()) ui_->login_state->SetLoggedIn(LoginStateWidget::State::LoggedIn); + if (service_->authenticated()) { + ui_->login_state->SetLoggedIn(LoginStateWidget::State::LoggedIn); + } Init(ui_->layout_tidalsettingspage->parentWidget()); @@ -125,13 +114,19 @@ void TidalSettingsPage::Save() { Settings s; s.beginGroup(kSettingsGroup); s.setValue(kEnabled, ui_->enable->isChecked()); - s.setValue(kOAuth, ui_->oauth->isChecked()); + if (s.contains(kOAuth)) { + s.remove(kOAuth); + } + if (s.contains(kApiToken)) { + s.remove(kApiToken); + } + if (s.contains(kUsername)) { + s.remove(kUsername); + } + if (s.contains(kPassword)) { + s.remove(kPassword); + } s.setValue(kClientId, ui_->client_id->text()); - s.setValue(kApiToken, ui_->api_token->text()); - - s.setValue(kUsername, ui_->username->text()); - s.setValue(kPassword, QString::fromUtf8(ui_->password->text().toUtf8().toBase64())); - s.setValue(kQuality, ui_->quality->currentData().toString()); s.setValue(kSearchDelay, ui_->searchdelay->value()); s.setValue(kArtistsSearchLimit, ui_->artistssearchlimit->value()); @@ -148,28 +143,11 @@ void TidalSettingsPage::Save() { void TidalSettingsPage::LoginClicked() { - if (ui_->oauth->isChecked()) { - if (ui_->client_id->text().isEmpty()) { - QMessageBox::critical(this, tr("Configuration incomplete"), tr("Missing Tidal client ID.")); - return; - } - Q_EMIT Authorize(ui_->client_id->text()); - } - else { - if (ui_->api_token->text().isEmpty()) { - QMessageBox::critical(this, tr("Configuration incomplete"), tr("Missing API token.")); - return; - } - if (ui_->username->text().isEmpty()) { - QMessageBox::critical(this, tr("Configuration incomplete"), tr("Missing username.")); - return; - } - if (ui_->password->text().isEmpty()) { - QMessageBox::critical(this, tr("Configuration incomplete"), tr("Missing password.")); - return; - } - Q_EMIT Login(ui_->api_token->text(), ui_->username->text(), ui_->password->text()); + if (ui_->client_id->text().isEmpty()) { + QMessageBox::critical(this, tr("Configuration incomplete"), tr("Missing Tidal client ID.")); + return; } + Q_EMIT Authorize(ui_->client_id->text()); ui_->button_login->setEnabled(false); } @@ -184,15 +162,6 @@ bool TidalSettingsPage::eventFilter(QObject *object, QEvent *event) { } -void TidalSettingsPage::OAuthClicked(const bool enabled) { - - ui_->client_id->setEnabled(enabled); - ui_->api_token->setEnabled(!enabled); - ui_->username->setEnabled(!enabled); - ui_->password->setEnabled(!enabled); - -} - void TidalSettingsPage::LogoutClicked() { service_->Logout(); diff --git a/src/settings/tidalsettingspage.h b/src/settings/tidalsettingspage.h index 740bf59cf..03c435e7f 100644 --- a/src/settings/tidalsettingspage.h +++ b/src/settings/tidalsettingspage.h @@ -47,10 +47,8 @@ class TidalSettingsPage : public SettingsPage { Q_SIGNALS: void Authorize(const QString &client_id); - void Login(const QString &api_token, const QString &username, const QString &password); private Q_SLOTS: - void OAuthClicked(const bool enabled); void LoginClicked(); void LogoutClicked(); void LoginSuccess(); diff --git a/src/settings/tidalsettingspage.ui b/src/settings/tidalsettingspage.ui index 2c26b6f95..39494fd56 100644 --- a/src/settings/tidalsettingspage.ui +++ b/src/settings/tidalsettingspage.ui @@ -47,13 +47,6 @@ - - - Use OAuth - - - - @@ -66,74 +59,13 @@ - + - - - - - 150 - 0 - - - - API Token - - - - - - - - 200 - 0 - - - - - - - - - - - Username - - - - - - - - - - - - - - - - - - Password - - - - - - - - - - QLineEdit::EchoMode::Password - - - @@ -308,7 +240,7 @@ - Qt::Orientation::Vertical + Qt::Vertical @@ -323,7 +255,7 @@ - Qt::Orientation::Horizontal + Qt::Horizontal @@ -366,11 +298,7 @@ enable - oauth client_id - api_token - username - password button_login quality searchdelay @@ -384,6 +312,8 @@ + + diff --git a/src/tidal/tidalbaserequest.cpp b/src/tidal/tidalbaserequest.cpp index 9750f7441..1f077ab37 100644 --- a/src/tidal/tidalbaserequest.cpp +++ b/src/tidal/tidalbaserequest.cpp @@ -62,8 +62,7 @@ QNetworkReply *TidalBaseRequest::CreateRequest(const QString &ressource_name, co QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (oauth() && !access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); - else if (!session_id().isEmpty()) req.setRawHeader("X-Tidal-SessionId", session_id().toUtf8()); + if (!access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); QNetworkReply *reply = network_->get(req); QObject::connect(reply, &QNetworkReply::sslErrors, this, &TidalBaseRequest::HandleSSLErrors); @@ -82,7 +81,7 @@ void TidalBaseRequest::HandleSSLErrors(const QList &ssl_errors) { } -QByteArray TidalBaseRequest::GetReplyData(QNetworkReply *reply, const bool send_login) { +QByteArray TidalBaseRequest::GetReplyData(QNetworkReply *reply) { QByteArray data; @@ -121,24 +120,8 @@ QByteArray TidalBaseRequest::GetReplyData(QNetworkReply *reply, const bool send_ } if (status == 401 && sub_status == 6001) { // User does not have a valid session service_->Logout(); - if (!oauth() && send_login && login_attempts() < max_login_attempts() && !api_token().isEmpty() && !username().isEmpty() && !password().isEmpty()) { - qLog(Error) << "Tidal:" << error; - set_need_login(); - if (login_sent()) { - qLog(Info) << "Tidal:" << "Waiting for login."; - } - else { - qLog(Info) << "Tidal:" << "Attempting to login."; - Q_EMIT RequestLogin(); - } - } - else { - Error(error); - } - } - else { - Error(error); } + Error(error); } return QByteArray(); } diff --git a/src/tidal/tidalbaserequest.h b/src/tidal/tidalbaserequest.h index 573073d6d..f9efc2926 100644 --- a/src/tidal/tidalbaserequest.h +++ b/src/tidal/tidalbaserequest.h @@ -64,7 +64,7 @@ class TidalBaseRequest : public QObject { using ParamList = QList; QNetworkReply *CreateRequest(const QString &ressource_name, const ParamList ¶ms_provided); - QByteArray GetReplyData(QNetworkReply *reply, const bool send_login); + QByteArray GetReplyData(QNetworkReply *reply); QJsonObject ExtractJsonObj(const QByteArray &data); QJsonValue ExtractItems(const QByteArray &data); QJsonValue ExtractItems(const QJsonObject &json_obj); @@ -72,30 +72,15 @@ class TidalBaseRequest : public QObject { virtual void Error(const QString &error, const QVariant &debug = QVariant()) = 0; static QString ErrorsToHTML(const QStringList &errors); - bool oauth() const { return service_->oauth(); } QString client_id() const { return service_->client_id(); } - QString api_token() const { return service_->api_token(); } quint64 user_id() const { return service_->user_id(); } QString country_code() const { return service_->country_code(); } - QString username() const { return service_->username(); } - QString password() const { return service_->password(); } QString quality() const { return service_->quality(); } int artistssearchlimit() const { return service_->artistssearchlimit(); } int albumssearchlimit() const { return service_->albumssearchlimit(); } int songssearchlimit() const { return service_->songssearchlimit(); } - QString access_token() const { return service_->access_token(); } - QString session_id() const { return service_->session_id(); } - bool authenticated() const { return service_->authenticated(); } - bool login_sent() const { return service_->login_sent(); } - int max_login_attempts() const { return service_->max_login_attempts(); } - int login_attempts() const { return service_->login_attempts(); } - - virtual void set_need_login() = 0; - - Q_SIGNALS: - void RequestLogin(); private Q_SLOTS: void HandleSSLErrors(const QList &ssl_errors); diff --git a/src/tidal/tidalfavoriterequest.cpp b/src/tidal/tidalfavoriterequest.cpp index f57336f14..4341586c1 100644 --- a/src/tidal/tidalfavoriterequest.cpp +++ b/src/tidal/tidalfavoriterequest.cpp @@ -44,8 +44,7 @@ using namespace Qt::Literals::StringLiterals; TidalFavoriteRequest::TidalFavoriteRequest(TidalService *service, const SharedPtr network, QObject *parent) : TidalBaseRequest(service, network, parent), service_(service), - network_(network), - need_login_(false) {} + network_(network) {} TidalFavoriteRequest::~TidalFavoriteRequest() { @@ -148,8 +147,7 @@ void TidalFavoriteRequest::AddFavoritesRequest(const FavoriteType type, const QS QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (oauth() && !access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); - else if (!session_id().isEmpty()) req.setRawHeader("X-Tidal-SessionId", session_id().toUtf8()); + if (!access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); QByteArray query = url_query.toString(QUrl::FullyEncoded).toUtf8(); QNetworkReply *reply = network_->post(req, query); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { AddFavoritesReply(reply, type, songs); }); @@ -170,7 +168,7 @@ void TidalFavoriteRequest::AddFavoritesReply(QNetworkReply *reply, const Favorit return; } - GetReplyData(reply, false); + GetReplyData(reply); if (reply->error() != QNetworkReply::NoError) { return; @@ -258,8 +256,7 @@ void TidalFavoriteRequest::RemoveFavoritesRequest(const FavoriteType type, const QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (oauth() && !access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); - else if (!session_id().isEmpty()) req.setRawHeader("X-Tidal-SessionId", session_id().toUtf8()); + if (!access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); QNetworkReply *reply = network_->deleteResource(req); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { RemoveFavoritesReply(reply, type, songs); }); replies_ << reply; @@ -279,7 +276,7 @@ void TidalFavoriteRequest::RemoveFavoritesReply(QNetworkReply *reply, const Favo return; } - GetReplyData(reply, false); + GetReplyData(reply); if (reply->error() != QNetworkReply::NoError) { return; } diff --git a/src/tidal/tidalfavoriterequest.h b/src/tidal/tidalfavoriterequest.h index 33079db9e..966529c8f 100644 --- a/src/tidal/tidalfavoriterequest.h +++ b/src/tidal/tidalfavoriterequest.h @@ -43,9 +43,6 @@ class TidalFavoriteRequest : public TidalBaseRequest { explicit TidalFavoriteRequest(TidalService *service, const SharedPtr network, QObject *parent = nullptr); ~TidalFavoriteRequest() override; - bool need_login() const { return need_login_; } - void set_need_login() override { need_login_ = true; } - private: enum class FavoriteType { Artists, @@ -89,7 +86,6 @@ class TidalFavoriteRequest : public TidalBaseRequest { TidalService *service_; const SharedPtr network_; QList replies_; - bool need_login_; }; #endif // TIDALFAVORITEREQUEST_H diff --git a/src/tidal/tidalrequest.cpp b/src/tidal/tidalrequest.cpp index 29200857a..0af609297 100644 --- a/src/tidal/tidalrequest.cpp +++ b/src/tidal/tidalrequest.cpp @@ -99,8 +99,7 @@ TidalRequest::TidalRequest(TidalService *service, TidalUrlHandler *url_handler, album_songs_received_(0), album_covers_requests_total_(0), album_covers_requests_active_(0), - album_covers_requests_received_(0), - need_login_(false) { + album_covers_requests_received_(0) { timer_flush_requests_->setInterval(kFlushRequestsDelay); timer_flush_requests_->setSingleShot(false); @@ -126,29 +125,8 @@ TidalRequest::~TidalRequest() { } -void TidalRequest::LoginComplete(const bool success, const QString &error) { - - if (!need_login_) return; - need_login_ = false; - - if (!success) { - Error(error); - return; - } - - Process(); - -} - void TidalRequest::Process() { - if (!service_->authenticated()) { - Q_EMIT UpdateStatus(query_id_, tr("Authenticating...")); - need_login_ = true; - service_->TryLogin(); - return; - } - switch (query_type_) { case Type::FavouriteArtists: GetArtists(); @@ -417,7 +395,7 @@ void TidalRequest::ArtistsReplyReceived(QNetworkReply *reply, const int limit_re QObject::disconnect(reply, nullptr, this, nullptr); reply->deleteLater(); - QByteArray data = GetReplyData(reply, (offset_requested == 0)); + QByteArray data = GetReplyData(reply); --artists_requests_active_; ++artists_requests_received_; @@ -564,7 +542,7 @@ void TidalRequest::AlbumsReplyReceived(QNetworkReply *reply, const int limit_req --albums_requests_active_; ++albums_requests_received_; - AlbumsReceived(reply, Artist(), limit_requested, offset_requested, offset_requested == 0); + AlbumsReceived(reply, Artist(), limit_requested, offset_requested); } @@ -604,18 +582,18 @@ void TidalRequest::ArtistAlbumsReplyReceived(QNetworkReply *reply, const Artist --artist_albums_requests_active_; ++artist_albums_requests_received_; Q_EMIT UpdateProgress(query_id_, GetProgress(artist_albums_requests_received_, artist_albums_requests_total_)); - AlbumsReceived(reply, artist, 0, offset_requested, false); + AlbumsReceived(reply, artist, 0, offset_requested); } -void TidalRequest::AlbumsReceived(QNetworkReply *reply, const Artist &artist_requested, const int limit_requested, const int offset_requested, const bool auto_login) { +void TidalRequest::AlbumsReceived(QNetworkReply *reply, const Artist &artist_requested, const int limit_requested, const int offset_requested) { if (!replies_.contains(reply)) return; replies_.removeAll(reply); QObject::disconnect(reply, nullptr, this, nullptr); reply->deleteLater(); - QByteArray data = GetReplyData(reply, auto_login); + QByteArray data = GetReplyData(reply); if (finished_) return; @@ -835,10 +813,10 @@ void TidalRequest::SongsReplyReceived(QNetworkReply *reply, const int limit_requ --songs_requests_active_; ++songs_requests_received_; if (query_type_ == Type::SearchSongs && fetchalbums_) { - AlbumsReceived(reply, Artist(), limit_requested, offset_requested, offset_requested == 0); + AlbumsReceived(reply, Artist(), limit_requested, offset_requested); } else { - SongsReceived(reply, Artist(), Album(), limit_requested, offset_requested, offset_requested == 0); + SongsReceived(reply, Artist(), Album(), limit_requested, offset_requested); } } @@ -881,18 +859,18 @@ void TidalRequest::AlbumSongsReplyReceived(QNetworkReply *reply, const Artist &a if (offset_requested == 0) { Q_EMIT UpdateProgress(query_id_, GetProgress(album_songs_requests_received_, album_songs_requests_total_)); } - SongsReceived(reply, artist, album, 0, offset_requested, false); + SongsReceived(reply, artist, album, 0, offset_requested); } -void TidalRequest::SongsReceived(QNetworkReply *reply, const Artist &artist, const Album &album, const int limit_requested, const int offset_requested, const bool auto_login) { +void TidalRequest::SongsReceived(QNetworkReply *reply, const Artist &artist, const Album &album, const int limit_requested, const int offset_requested) { if (!replies_.contains(reply)) return; replies_.removeAll(reply); QObject::disconnect(reply, nullptr, this, nullptr); reply->deleteLater(); - QByteArray data = GetReplyData(reply, auto_login); + QByteArray data = GetReplyData(reply); if (finished_) return; @@ -1339,7 +1317,6 @@ void TidalRequest::FinishCheck() { if ( !finished_ && - !need_login_ && artists_requests_queue_.isEmpty() && albums_requests_queue_.isEmpty() && songs_requests_queue_.isEmpty() && diff --git a/src/tidal/tidalrequest.h b/src/tidal/tidalrequest.h index 181c38223..549b81741 100644 --- a/src/tidal/tidalrequest.h +++ b/src/tidal/tidalrequest.h @@ -58,7 +58,6 @@ class TidalRequest : public TidalBaseRequest { void ReloadSettings(); void Process(); - void set_need_login() override { need_login_ = true; } void Search(const int query_id, const QString &search_text); private: @@ -110,18 +109,15 @@ class TidalRequest : public TidalBaseRequest { void ArtistsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested); void AlbumsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested); - void AlbumsReceived(QNetworkReply *reply, const TidalRequest::Artist &artist_requested, const int limit_requested, const int offset_requested, const bool auto_login); + void AlbumsReceived(QNetworkReply *reply, const TidalRequest::Artist &artist_requested, const int limit_requested, const int offset_requested); void SongsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested); - void SongsReceived(QNetworkReply *reply, const TidalRequest::Artist &artist, const TidalRequest::Album &album, const int limit_requested, const int offset_requested, const bool auto_login = false); + void SongsReceived(QNetworkReply *reply, const TidalRequest::Artist &artist, const TidalRequest::Album &album, const int limit_requested, const int offset_requested); void ArtistAlbumsReplyReceived(QNetworkReply *reply, const TidalRequest::Artist &artist, const int offset_requested); void AlbumSongsReplyReceived(QNetworkReply *reply, const TidalRequest::Artist &artist, const TidalRequest::Album &album, const int offset_requested); void AlbumCoverReceived(QNetworkReply *reply, const QString &album_id, const QUrl &url, const QString &filename); - public Q_SLOTS: - void LoginComplete(const bool success, const QString &error = QString()); - private: bool IsQuery() const { return (query_type_ == Type::FavouriteArtists || query_type_ == Type::FavouriteAlbums || query_type_ == Type::FavouriteSongs); } bool IsSearch() const { return (query_type_ == Type::SearchArtists || query_type_ == Type::SearchAlbums || query_type_ == Type::SearchSongs); } @@ -233,7 +229,6 @@ class TidalRequest : public TidalBaseRequest { SongMap songs_; QStringList errors_; - bool need_login_; QList replies_; QList album_cover_replies_; }; diff --git a/src/tidal/tidalservice.cpp b/src/tidal/tidalservice.cpp index 5fff67caa..6b46b3c75 100644 --- a/src/tidal/tidalservice.cpp +++ b/src/tidal/tidalservice.cpp @@ -75,16 +75,12 @@ const Song::Source TidalService::kSource = Song::Source::Tidal; const char TidalService::kApiUrl[] = "https://api.tidalhifi.com/v1"; const char TidalService::kResourcesUrl[] = "https://resources.tidal.com"; -const int TidalService::kLoginAttempts = 2; namespace { constexpr char kOAuthUrl[] = "https://login.tidal.com/authorize"; constexpr char kOAuthAccessTokenUrl[] = "https://login.tidal.com/oauth2/token"; constexpr char kOAuthRedirectUrl[] = "tidal://login/auth"; -constexpr char kAuthUrl[] = "https://api.tidalhifi.com/v1/login/username"; - -constexpr int kTimeResetLoginAttempts = 60000; constexpr char kArtistsSongsTable[] = "tidal_artists_songs"; constexpr char kAlbumsSongsTable[] = "tidal_albums_songs"; @@ -116,11 +112,9 @@ TidalService::TidalService(const SharedPtr task_manager, albums_collection_model_(nullptr), songs_collection_model_(nullptr), timer_search_delay_(new QTimer(this)), - timer_login_attempt_(new QTimer(this)), timer_refresh_login_(new QTimer(this)), favorite_request_(new TidalFavoriteRequest(this, network_, this)), enabled_(false), - oauth_(false), user_id_(0), artistssearchlimit_(1), albumssearchlimit_(1), @@ -135,8 +129,6 @@ TidalService::TidalService(const SharedPtr task_manager, next_pending_search_id_(1), pending_search_type_(StreamingSearchView::SearchType::Artists), search_id_(0), - login_sent_(false), - login_attempts_(0), next_stream_url_request_id_(0) { url_handlers->Register(url_handler_); @@ -165,16 +157,9 @@ TidalService::TidalService(const SharedPtr task_manager, timer_search_delay_->setSingleShot(true); QObject::connect(timer_search_delay_, &QTimer::timeout, this, &TidalService::StartSearch); - timer_login_attempt_->setSingleShot(true); - timer_login_attempt_->setInterval(kTimeResetLoginAttempts); - QObject::connect(timer_login_attempt_, &QTimer::timeout, this, &TidalService::ResetLoginAttempts); - timer_refresh_login_->setSingleShot(true); QObject::connect(timer_refresh_login_, &QTimer::timeout, this, &TidalService::RequestNewAccessToken); - QObject::connect(this, &TidalService::RequestLogin, this, &TidalService::SendLogin); - QObject::connect(this, &TidalService::LoginWithCredentials, this, &TidalService::SendLoginWithCredentials); - QObject::connect(this, &TidalService::AddArtists, favorite_request_, &TidalFavoriteRequest::AddArtists); QObject::connect(this, &TidalService::AddAlbums, favorite_request_, &TidalFavoriteRequest::AddAlbums); QObject::connect(this, &TidalService::AddSongs, favorite_request_, QOverload::of(&TidalFavoriteRequest::AddSongs)); @@ -184,8 +169,6 @@ TidalService::TidalService(const SharedPtr task_manager, QObject::connect(this, &TidalService::RemoveSongsByList, favorite_request_, QOverload::of(&TidalFavoriteRequest::RemoveSongs)); QObject::connect(this, &TidalService::RemoveSongsByMap, favorite_request_, QOverload::of(&TidalFavoriteRequest::RemoveSongs)); - QObject::connect(favorite_request_, &TidalFavoriteRequest::RequestLogin, this, &TidalService::SendLogin); - QObject::connect(favorite_request_, &TidalFavoriteRequest::ArtistsAdded, &*artists_collection_backend_, &CollectionBackend::AddOrUpdateSongs); QObject::connect(favorite_request_, &TidalFavoriteRequest::AlbumsAdded, &*albums_collection_backend_, &CollectionBackend::AddOrUpdateSongs); QObject::connect(favorite_request_, &TidalFavoriteRequest::SongsAdded, &*songs_collection_backend_, &CollectionBackend::AddOrUpdateSongs); @@ -247,7 +230,6 @@ void TidalService::LoadSession() { country_code_ = s.value(kCountryCode, u"US"_s).toString(); access_token_ = s.value(kAccessToken).toString(); refresh_token_ = s.value(kRefreshToken).toString(); - session_id_ = s.value(kSessionId).toString(); expires_in_ = s.value(kExpiresIn).toLongLong(); login_time_ = s.value(kLoginTime).toLongLong(); s.endGroup(); @@ -271,15 +253,7 @@ void TidalService::ReloadSettings() { s.beginGroup(TidalSettings::kSettingsGroup); enabled_ = s.value(TidalSettings::kEnabled, false).toBool(); - oauth_ = s.value(TidalSettings::kOAuth, true).toBool(); client_id_ = s.value(TidalSettings::kClientId).toString(); - api_token_ = s.value(TidalSettings::kApiToken).toString(); - - username_ = s.value(TidalSettings::kUsername).toString(); - QByteArray password = s.value(TidalSettings::kPassword).toByteArray(); - if (password.isEmpty()) password_.clear(); - else password_ = QString::fromUtf8(QByteArray::fromBase64(password)); - quality_ = s.value(TidalSettings::kQuality, u"LOSSLESS"_s).toString(); quint64 search_delay = s.value(TidalSettings::kSearchDelay, 1500).toInt(); artistssearchlimit_ = s.value(TidalSettings::kArtistsSearchLimit, 4).toInt(); @@ -339,7 +313,6 @@ void TidalService::AuthorizationUrlReceived(const QUrl &url) { } expires_in_ = url_query.queryItemValue(u"expires_in"_s).toInt(); login_time_ = QDateTime::currentSecsSinceEpoch(); - session_id_.clear(); Settings s; s.beginGroup(TidalSettings::kSettingsGroup); @@ -382,7 +355,7 @@ void TidalService::RequestAccessToken(const QString &code) { params << Param(u"redirect_uri"_s, QLatin1String(kOAuthRedirectUrl)); params << Param(u"scope"_s, u"r_usr w_usr"_s); } - else if (!refresh_token_.isEmpty() && enabled_ && oauth_) { + else if (!refresh_token_.isEmpty() && enabled_) { params << Param(u"grant_type"_s, u"refresh_token"_s); params << Param(u"refresh_token"_s, refresh_token_); } @@ -501,8 +474,6 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) { } } - session_id_.clear(); - Settings s; s.beginGroup(TidalSettings::kSettingsGroup); s.setValue(kAccessToken, access_token_); @@ -512,6 +483,8 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) { s.setValue(kCountryCode, country_code_); s.setValue(kUserId, user_id_); s.remove(kSessionId); + s.remove(kUserId); + s.remove(kCountryCode); s.endGroup(); if (expires_in_ > 0) { @@ -526,153 +499,12 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) { } -void TidalService::SendLogin() { - SendLoginWithCredentials(api_token_, username_, password_); -} - -void TidalService::SendLoginWithCredentials(const QString &api_token, const QString &username, const QString &password) { - - login_sent_ = true; - ++login_attempts_; - timer_login_attempt_->start(); - timer_refresh_login_->stop(); - - const ParamList params = ParamList() << Param(u"token"_s, (api_token.isEmpty() ? api_token_ : api_token)) - << Param(u"username"_s, username) - << Param(u"password"_s, password) - << Param(u"clientVersion"_s, u"2.2.1--7"_s); - - QUrlQuery url_query; - for (const Param ¶m : params) { - url_query.addQueryItem(QString::fromLatin1(QUrl::toPercentEncoding(param.first)), QString::fromLatin1(QUrl::toPercentEncoding(param.second))); - } - - QUrl url(QString::fromLatin1(kAuthUrl)); - QNetworkRequest req(url); - - req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - req.setRawHeader("X-Tidal-Token", (api_token.isEmpty() ? api_token_.toUtf8() : api_token.toUtf8())); - - QByteArray query = url_query.toString(QUrl::FullyEncoded).toUtf8(); - QNetworkReply *reply = network_->post(req, query); - QObject::connect(reply, &QNetworkReply::sslErrors, this, &TidalService::HandleLoginSSLErrors); - QObject::connect(reply, &QNetworkReply::finished, this, [this, reply]() { HandleAuthReply(reply); }); - replies_ << reply; - - //qLog(Debug) << "Tidal: Sending request" << url << query; - -} - -void TidalService::HandleAuthReply(QNetworkReply *reply) { - - if (!replies_.contains(reply)) return; - replies_.removeAll(reply); - QObject::disconnect(reply, nullptr, this, nullptr); - reply->deleteLater(); - - login_sent_ = false; - - if (reply->error() != QNetworkReply::NoError || reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) { - if (reply->error() != QNetworkReply::NoError && reply->error() < 200) { - // This is a network error, there is nothing more to do. - LoginError(QStringLiteral("%1 (%2)").arg(reply->errorString()).arg(reply->error())); - login_errors_.clear(); - return; - } - else { - // See if there is Json data containing "status" and "userMessage" - then use that instead. - QByteArray data(reply->readAll()); - QJsonParseError json_error; - QJsonDocument json_doc = QJsonDocument::fromJson(data, &json_error); - if (json_error.error == QJsonParseError::NoError && !json_doc.isEmpty() && json_doc.isObject()) { - QJsonObject json_obj = json_doc.object(); - if (!json_obj.isEmpty() && json_obj.contains("status"_L1) && json_obj.contains("userMessage"_L1)) { - int status = json_obj["status"_L1].toInt(); - int sub_status = json_obj["subStatus"_L1].toInt(); - QString user_message = json_obj["userMessage"_L1].toString(); - login_errors_ << QStringLiteral("Authentication failure: %1 (%2) (%3)").arg(user_message).arg(status).arg(sub_status); - } - } - if (login_errors_.isEmpty()) { - if (reply->error() != QNetworkReply::NoError) { - login_errors_ << QStringLiteral("%1 (%2)").arg(reply->errorString()).arg(reply->error()); - } - else { - login_errors_ << QStringLiteral("Received HTTP code %1").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); - } - } - LoginError(); - login_errors_.clear(); - return; - } - } - - login_errors_.clear(); - - const QByteArray data = reply->readAll(); - QJsonParseError json_error; - QJsonDocument json_doc = QJsonDocument::fromJson(data, &json_error); - - if (json_error.error != QJsonParseError::NoError) { - LoginError(u"Authentication reply from server missing Json data."_s); - return; - } - - if (json_doc.isEmpty()) { - LoginError(u"Authentication reply from server has empty Json document."_s); - return; - } - - if (!json_doc.isObject()) { - LoginError(u"Authentication reply from server has Json document that is not an object."_s, json_doc); - return; - } - - QJsonObject json_obj = json_doc.object(); - if (json_obj.isEmpty()) { - LoginError(u"Authentication reply from server has empty Json object."_s, json_doc); - return; - } - - if (!json_obj.contains("userId"_L1) || !json_obj.contains("sessionId"_L1) || !json_obj.contains("countryCode"_L1)) { - LoginError(u"Authentication reply from server is missing userId, sessionId or countryCode"_s, json_obj); - return; - } - - country_code_ = json_obj["countryCode"_L1].toString(); - session_id_ = json_obj["sessionId"_L1].toString(); - user_id_ = json_obj["userId"_L1].toInt(); - access_token_.clear(); - refresh_token_.clear(); - - Settings s; - s.beginGroup(TidalSettings::kSettingsGroup); - s.remove(kAccessToken); - s.remove(kRefreshToken); - s.remove(kExpiresIn); - s.remove(kLoginTime); - s.setValue(kUserId, user_id_); - s.setValue(kSessionId, session_id_); - s.setValue(kCountryCode, country_code_); - s.endGroup(); - - qLog(Debug) << "Tidal: Login successful" << "user id" << user_id_ << "session id" << session_id_ << "country code" << country_code_; - - login_attempts_ = 0; - timer_login_attempt_->stop(); - - Q_EMIT LoginComplete(true); - Q_EMIT LoginSuccess(); - -} - void TidalService::Logout() { user_id_ = 0; country_code_.clear(); access_token_.clear(); refresh_token_.clear(); - session_id_.clear(); expires_in_ = 0; login_time_ = 0; @@ -691,35 +523,6 @@ void TidalService::Logout() { } -void TidalService::ResetLoginAttempts() { - login_attempts_ = 0; -} - -void TidalService::TryLogin() { - - if (authenticated() || login_sent_) return; - - if (api_token_.isEmpty()) { - Q_EMIT LoginComplete(false, tr("Missing Tidal API token.")); - return; - } - if (username_.isEmpty()) { - Q_EMIT LoginComplete(false, tr("Missing Tidal username.")); - return; - } - if (password_.isEmpty()) { - Q_EMIT LoginComplete(false, tr("Missing Tidal password.")); - return; - } - if (login_attempts_ >= kLoginAttempts) { - Q_EMIT LoginComplete(false, tr("Not authenticated with Tidal and reached maximum number of login attempts.")); - return; - } - - Q_EMIT RequestLogin(); - -} - void TidalService::ResetArtistsRequest() { if (artists_request_) { @@ -733,25 +536,16 @@ void TidalService::ResetArtistsRequest() { void TidalService::GetArtists() { if (!authenticated()) { - if (oauth_) { - Q_EMIT ArtistsResults(SongMap(), tr("Not authenticated with Tidal.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } - else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) { - Q_EMIT ArtistsResults(SongMap(), tr("Missing Tidal API token, username or password.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } + Q_EMIT ArtistsResults(SongMap(), tr("Not authenticated with Tidal.")); + Q_EMIT OpenSettingsDialog(kSource); + return; } ResetArtistsRequest(); artists_request_.reset(new TidalRequest(this, url_handler_, network_, TidalBaseRequest::Type::FavouriteArtists, this), [](TidalRequest *request) { request->deleteLater(); }); - QObject::connect(&*artists_request_, &TidalRequest::RequestLogin, this, &TidalService::SendLogin); QObject::connect(&*artists_request_, &TidalRequest::Results, this, &TidalService::ArtistsResultsReceived); QObject::connect(&*artists_request_, &TidalRequest::UpdateStatus, this, &TidalService::ArtistsUpdateStatusReceived); QObject::connect(&*artists_request_, &TidalRequest::UpdateProgress, this, &TidalService::ArtistsUpdateProgressReceived); - QObject::connect(this, &TidalService::LoginComplete, &*artists_request_, &TidalRequest::LoginComplete); artists_request_->Process(); @@ -788,25 +582,16 @@ void TidalService::ResetAlbumsRequest() { void TidalService::GetAlbums() { if (!authenticated()) { - if (oauth_) { - Q_EMIT AlbumsResults(SongMap(), tr("Not authenticated with Tidal.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } - else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) { - Q_EMIT AlbumsResults(SongMap(), tr("Missing Tidal API token, username or password.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } + Q_EMIT AlbumsResults(SongMap(), tr("Not authenticated with Tidal.")); + Q_EMIT OpenSettingsDialog(kSource); + return; } ResetAlbumsRequest(); albums_request_.reset(new TidalRequest(this, url_handler_, network_, TidalBaseRequest::Type::FavouriteAlbums, this), [](TidalRequest *request) { request->deleteLater(); }); - QObject::connect(&*albums_request_, &TidalRequest::RequestLogin, this, &TidalService::SendLogin); QObject::connect(&*albums_request_, &TidalRequest::Results, this, &TidalService::AlbumsResultsReceived); QObject::connect(&*albums_request_, &TidalRequest::UpdateStatus, this, &TidalService::AlbumsUpdateStatusReceived); QObject::connect(&*albums_request_, &TidalRequest::UpdateProgress, this, &TidalService::AlbumsUpdateProgressReceived); - QObject::connect(this, &TidalService::LoginComplete, &*albums_request_, &TidalRequest::LoginComplete); albums_request_->Process(); @@ -843,25 +628,16 @@ void TidalService::ResetSongsRequest() { void TidalService::GetSongs() { if (!authenticated()) { - if (oauth_) { - Q_EMIT SongsResults(SongMap(), tr("Not authenticated with Tidal.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } - else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) { - Q_EMIT SongsResults(SongMap(), tr("Missing Tidal API token, username or password.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } + Q_EMIT SongsResults(SongMap(), tr("Not authenticated with Tidal.")); + Q_EMIT OpenSettingsDialog(kSource); + return; } ResetSongsRequest(); songs_request_.reset(new TidalRequest(this, url_handler_, network_, TidalBaseRequest::Type::FavouriteSongs, this), [](TidalRequest *request) { request->deleteLater(); }); - QObject::connect(&*songs_request_, &TidalRequest::RequestLogin, this, &TidalService::SendLogin); QObject::connect(&*songs_request_, &TidalRequest::Results, this, &TidalService::SongsResultsReceived); QObject::connect(&*songs_request_, &TidalRequest::UpdateStatus, this, &TidalService::SongsUpdateStatusReceived); QObject::connect(&*songs_request_, &TidalRequest::UpdateProgress, this, &TidalService::SongsUpdateProgressReceived); - QObject::connect(this, &TidalService::LoginComplete, &*songs_request_, &TidalRequest::LoginComplete); songs_request_->Process(); @@ -906,16 +682,9 @@ int TidalService::Search(const QString &text, StreamingSearchView::SearchType ty void TidalService::StartSearch() { if (!authenticated()) { - if (oauth_) { - Q_EMIT SearchResults(pending_search_id_, SongMap(), tr("Not authenticated with Tidal.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } - else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) { - Q_EMIT SearchResults(pending_search_id_, SongMap(), tr("Missing Tidal API token, username or password.")); - Q_EMIT OpenSettingsDialog(kSource); - return; - } + Q_EMIT SearchResults(pending_search_id_, SongMap(), tr("Not authenticated with Tidal.")); + Q_EMIT OpenSettingsDialog(kSource); + return; } search_id_ = pending_search_id_; @@ -925,8 +694,7 @@ void TidalService::StartSearch() { } -void TidalService::CancelSearch() { -} +void TidalService::CancelSearch() {} void TidalService::SendSearch() { @@ -949,11 +717,9 @@ void TidalService::SendSearch() { search_request_.reset(new TidalRequest(this, url_handler_, network_, query_type, this), [](TidalRequest *request) { request->deleteLater(); }); - QObject::connect(&*search_request_, &TidalRequest::RequestLogin, this, &TidalService::SendLogin); QObject::connect(&*search_request_, &TidalRequest::Results, this, &TidalService::SearchResultsReceived); QObject::connect(&*search_request_, &TidalRequest::UpdateStatus, this, &TidalService::SearchUpdateStatus); QObject::connect(&*search_request_, &TidalRequest::UpdateProgress, this, &TidalService::SearchUpdateProgress); - QObject::connect(this, &TidalService::LoginComplete, &*search_request_, &TidalRequest::LoginComplete); search_request_->Search(search_id_, search_text_); search_request_->Process(); @@ -970,26 +736,18 @@ void TidalService::SearchResultsReceived(const int id, const SongMap &songs, con uint TidalService::GetStreamURL(const QUrl &url, QString &error) { if (!authenticated()) { - if (oauth_) { - error = tr("Not authenticated with Tidal."); - return 0; - } - else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) { - error = tr("Missing Tidal API token, username or password."); - return 0; - } + error = tr("Not authenticated with Tidal."); + return 0; } uint id = 0; while (id == 0) id = ++next_stream_url_request_id_; - SharedPtr stream_url_req; + SharedPtr stream_url_req; stream_url_req.reset(new TidalStreamURLRequest(this, network_, url, id), [](TidalStreamURLRequest *request) { request->deleteLater(); }); stream_url_requests_.insert(id, stream_url_req); - QObject::connect(&*stream_url_req, &TidalStreamURLRequest::TryLogin, this, &TidalService::TryLogin); QObject::connect(&*stream_url_req, &TidalStreamURLRequest::StreamURLFailure, this, &TidalService::HandleStreamURLFailure); QObject::connect(&*stream_url_req, &TidalStreamURLRequest::StreamURLSuccess, this, &TidalService::HandleStreamURLSuccess); - QObject::connect(this, &TidalService::LoginComplete, &*stream_url_req, &TidalStreamURLRequest::LoginComplete); stream_url_req->Process(); diff --git a/src/tidal/tidalservice.h b/src/tidal/tidalservice.h index 9f6ef3beb..b0a2306bd 100644 --- a/src/tidal/tidalservice.h +++ b/src/tidal/tidalservice.h @@ -74,7 +74,6 @@ class TidalService : public StreamingService { static const Song::Source kSource; static const char kApiUrl[]; static const char kResourcesUrl[]; - static const int kLoginAttempts; void Exit() override; void ReloadSettings() override; @@ -83,15 +82,9 @@ class TidalService : public StreamingService { int Search(const QString &text, StreamingSearchView::SearchType type) override; void CancelSearch() override; - int max_login_attempts() const { return kLoginAttempts; } - - bool oauth() const override { return oauth_; } QString client_id() const { return client_id_; } - QString api_token() const { return api_token_; } quint64 user_id() const { return user_id_; } QString country_code() const { return country_code_; } - QString username() const { return username_; } - QString password() const { return password_; } QString quality() const { return quality_; } int artistssearchlimit() const { return artistssearchlimit_; } int albumssearchlimit() const { return albumssearchlimit_; } @@ -103,11 +96,8 @@ class TidalService : public StreamingService { bool album_explicit() const { return album_explicit_; } QString access_token() const { return access_token_; } - QString session_id() const { return session_id_; } - bool authenticated() const override { return (!access_token_.isEmpty() || !session_id_.isEmpty()); } - bool login_sent() const { return login_sent_; } - bool login_attempts() const { return login_attempts_; } + bool authenticated() const override { return !access_token_.isEmpty(); } uint GetStreamURL(const QUrl &url, QString &error); @@ -125,9 +115,6 @@ class TidalService : public StreamingService { public Q_SLOTS: void StartAuthorization(const QString &client_id); - void TryLogin(); - void SendLogin(); - void SendLoginWithCredentials(const QString &api_token, const QString &username, const QString &password); void GetArtists() override; void GetAlbums() override; void GetSongs() override; @@ -141,8 +128,6 @@ class TidalService : public StreamingService { void RequestNewAccessToken() { RequestAccessToken(); } void HandleLoginSSLErrors(const QList &ssl_errors); void AccessTokenRequestFinished(QNetworkReply *reply); - void HandleAuthReply(QNetworkReply *reply); - void ResetLoginAttempts(); void StartSearch(); void ArtistsResultsReceived(const int id, const SongMap &songs, const QString &error); void AlbumsResultsReceived(const int id, const SongMap &songs, const QString &error); @@ -178,7 +163,6 @@ class TidalService : public StreamingService { CollectionModel *songs_collection_model_; QTimer *timer_search_delay_; - QTimer *timer_login_attempt_; QTimer *timer_refresh_login_; SharedPtr artists_request_; @@ -188,13 +172,9 @@ class TidalService : public StreamingService { TidalFavoriteRequest *favorite_request_; bool enabled_; - bool oauth_; QString client_id_; - QString api_token_; quint64 user_id_; QString country_code_; - QString username_; - QString password_; QString quality_; int artistssearchlimit_; int albumssearchlimit_; @@ -207,7 +187,6 @@ class TidalService : public StreamingService { QString access_token_; QString refresh_token_; - QString session_id_; quint64 expires_in_; quint64 login_time_; @@ -218,8 +197,6 @@ class TidalService : public StreamingService { int search_id_; QString search_text_; - bool login_sent_; - int login_attempts_; QString code_verifier_; QString code_challenge_; diff --git a/src/tidal/tidalstreamurlrequest.cpp b/src/tidal/tidalstreamurlrequest.cpp index 340f16293..e71dae387 100644 --- a/src/tidal/tidalstreamurlrequest.cpp +++ b/src/tidal/tidalstreamurlrequest.cpp @@ -50,9 +50,7 @@ TidalStreamURLRequest::TidalStreamURLRequest(TidalService *service, const Shared reply_(nullptr), media_url_(media_url), id_(id), - song_id_(media_url.path().toInt()), - tries_(0), - need_login_(false) {} + song_id_(media_url.path().toInt()) {} TidalStreamURLRequest::~TidalStreamURLRequest() { @@ -64,33 +62,10 @@ TidalStreamURLRequest::~TidalStreamURLRequest() { } -void TidalStreamURLRequest::LoginComplete(const bool success, const QString &error) { - - if (!need_login_) return; - need_login_ = false; - - if (!success) { - Q_EMIT StreamURLFailure(id_, media_url_, error); - return; - } - - Process(); - -} - void TidalStreamURLRequest::Process() { if (!authenticated()) { - if (oauth()) { - Q_EMIT StreamURLFailure(id_, media_url_, tr("Not authenticated with Tidal.")); - return; - } - else if (api_token().isEmpty() || username().isEmpty() || password().isEmpty()) { - Q_EMIT StreamURLFailure(id_, media_url_, tr("Missing Tidal API token, username or password.")); - return; - } - need_login_ = true; - Q_EMIT TryLogin(); + Q_EMIT StreamURLFailure(id_, media_url_, tr("Not authenticated with Tidal.")); return; } @@ -111,8 +86,6 @@ void TidalStreamURLRequest::Cancel() { void TidalStreamURLRequest::GetStreamURL() { - ++tries_; - if (reply_) { QObject::disconnect(reply_, nullptr, this, nullptr); if (reply_->isRunning()) reply_->abort(); @@ -150,17 +123,13 @@ void TidalStreamURLRequest::StreamURLReceived() { if (!reply_) return; - QByteArray data = GetReplyData(reply_, true); + QByteArray data = GetReplyData(reply_); QObject::disconnect(reply_, nullptr, this, nullptr); reply_->deleteLater(); reply_ = nullptr; if (data.isEmpty()) { - if (!authenticated() && login_sent() && tries_ <= 1) { - need_login_ = true; - return; - } Q_EMIT StreamURLFailure(id_, media_url_, errors_.constFirst()); return; } diff --git a/src/tidal/tidalstreamurlrequest.h b/src/tidal/tidalstreamurlrequest.h index 5fc0fcefb..983449c0b 100644 --- a/src/tidal/tidalstreamurlrequest.h +++ b/src/tidal/tidalstreamurlrequest.h @@ -54,20 +54,13 @@ class TidalStreamURLRequest : public TidalBaseRequest { QUrl media_url() const { return media_url_; } int song_id() const { return song_id_; } - void set_need_login() override { need_login_ = true; } - bool need_login() const { return need_login_; } - Q_SIGNALS: - void TryLogin(); void StreamURLFailure(const uint id, const QUrl &media_url, const QString &error); void StreamURLSuccess(const uint id, const QUrl &media_url, const QUrl &stream_url, const Song::FileType filetype, const int samplerate = -1, const int bit_depth = -1, const qint64 duration = -1); private Q_SLOTS: void StreamURLReceived(); - public Q_SLOTS: - void LoginComplete(const bool success, const QString &error = QString()); - private: void Error(const QString &error, const QVariant &debug = QVariant()) override; @@ -76,7 +69,6 @@ class TidalStreamURLRequest : public TidalBaseRequest { QUrl media_url_; uint id_; int song_id_; - int tries_; bool need_login_; QStringList errors_; };