Tidal: Handle login better and allow duplicate albums

This commit is contained in:
Jonas Kvinge 2019-03-23 21:14:46 +01:00
parent 86b057a301
commit f698b860f7
2 changed files with 27 additions and 30 deletions

View File

@ -207,13 +207,13 @@ void TidalService::HandleAuthReply(QNetworkReply *reply) {
if (json_error.error == QJsonParseError::NoError && !json_doc.isNull() && !json_doc.isEmpty() && json_doc.isObject()) { if (json_error.error == QJsonParseError::NoError && !json_doc.isNull() && !json_doc.isEmpty() && json_doc.isObject()) {
QJsonObject json_obj = json_doc.object(); QJsonObject json_obj = json_doc.object();
if (!json_obj.isEmpty() && json_obj.contains("userMessage")) { if (!json_obj.isEmpty() && json_obj.contains("userMessage")) {
failure_reason = QString("Authentication failure: %1").arg(json_obj["userMessage"].toString()); int status = json_obj["status"].toInt();
} int sub_status = json_obj["subStatus"].toInt();
else { QString user_message = json_obj["userMessage"].toString();
failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()); failure_reason = QString("Authentication failure: %1 (%2) (%3)").arg(user_message).arg(status).arg(sub_status);
} }
} }
else { if (failure_reason.isEmpty()) {
failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()); failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error());
} }
LoginError(failure_reason); LoginError(failure_reason);
@ -348,26 +348,26 @@ QByteArray TidalService::GetReplyData(QNetworkReply *reply, QString &error, cons
data = reply->readAll(); data = reply->readAll();
QJsonParseError parse_error; QJsonParseError parse_error;
QJsonDocument json_doc = QJsonDocument::fromJson(data, &parse_error); QJsonDocument json_doc = QJsonDocument::fromJson(data, &parse_error);
int status = 0;
int sub_status = 0;
QString failure_reason; QString failure_reason;
if (parse_error.error == QJsonParseError::NoError && !json_doc.isNull() && !json_doc.isEmpty() && json_doc.isObject()) { if (parse_error.error == QJsonParseError::NoError && !json_doc.isNull() && !json_doc.isEmpty() && json_doc.isObject()) {
QJsonObject json_obj = json_doc.object(); QJsonObject json_obj = json_doc.object();
if (!json_obj.isEmpty() && json_obj.contains("userMessage")) { if (!json_obj.isEmpty() && json_obj.contains("status") && json_obj.contains("userMessage")) {
failure_reason = json_obj["userMessage"].toString(); status = json_obj["status"].toInt();
} sub_status = json_obj["subStatus"].toInt();
else { QString user_message = json_obj["userMessage"].toString();
failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()); failure_reason = QString("%1 (%2) (%3)").arg(user_message).arg(status).arg(sub_status);
} }
} }
else { if (failure_reason.isEmpty()) {
failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()); failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error());
} }
if (reply->error() == QNetworkReply::ContentAccessDenied || reply->error() == QNetworkReply::ContentOperationNotPermittedError || reply->error() == QNetworkReply::AuthenticationRequiredError) { if (status == 401 && sub_status == 6001) { // User does not have a valid session
// Session is probably expired, attempt to login once
Logout(); Logout();
if (sendlogin && login_attempts_ < kLoginAttempts && !username_.isEmpty() && !password_.isEmpty()) { if (sendlogin && login_attempts_ < kLoginAttempts && !username_.isEmpty() && !password_.isEmpty()) {
qLog(Error) << "Tidal:" << failure_reason; qLog(Error) << "Tidal:" << failure_reason;
qLog(Error) << "Tidal:" << QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()); qLog(Info) << "Tidal:" << "Attempting to login.";
qLog(Error) << "Tidal:" << "Attempting to login.";
emit Login(); emit Login();
} }
else { else {
@ -489,7 +489,6 @@ void TidalService::ClearSearch() {
album_songs_received_ = 0; album_songs_received_ = 0;
requests_artist_albums_.clear(); requests_artist_albums_.clear();
requests_album_songs_.clear(); requests_album_songs_.clear();
requests_artist_album_.clear();
songs_.clear(); songs_.clear();
} }
@ -753,13 +752,6 @@ void TidalService::AlbumsReceived(QNetworkReply *reply, int search_id, int artis
//qLog(Debug) << "Tidal:" << artist << album << quality << copyright; //qLog(Debug) << "Tidal:" << artist << album << quality << copyright;
QPair<QString,QString> artist_album(artist.toLower(), album.toLower());
if (requests_artist_album_.contains(artist_album)) {
qLog(Debug) << "Tidal: Skipping duplicate album" << artist << album << quality << copyright;
continue;
}
requests_artist_album_.append(artist_album);
requests_album_songs_.insert(album_id, artist); requests_album_songs_.insert(album_id, artist);
album_songs_requested_++; album_songs_requested_++;
if (album_songs_requested_ >= albumssearchlimit_) break; if (album_songs_requested_ >= albumssearchlimit_) break;
@ -828,7 +820,7 @@ void TidalService::SongsReceived(QNetworkReply *reply, int search_id, int album_
QString error; QString error;
QByteArray data = GetReplyData(reply, error); QByteArray data = GetReplyData(reply, error, false);
if (data.isEmpty()) { if (data.isEmpty()) {
CheckFinish(); CheckFinish();
return; return;
@ -890,7 +882,8 @@ Song TidalService::ParseSong(const int album_id_requested, const QJsonValue &val
!json_obj.contains("title") || !json_obj.contains("title") ||
!json_obj.contains("trackNumber") || !json_obj.contains("trackNumber") ||
!json_obj.contains("url") || !json_obj.contains("url") ||
!json_obj.contains("volumeNumber") !json_obj.contains("volumeNumber") ||
!json_obj.contains("copyright")
) { ) {
qLog(Error) << "Tidal: Invalid Json reply, track is missing one or more values."; qLog(Error) << "Tidal: Invalid Json reply, track is missing one or more values.";
qLog(Debug) << json_obj; qLog(Debug) << json_obj;
@ -910,6 +903,7 @@ Song TidalService::ParseSong(const int album_id_requested, const QJsonValue &val
int disc = json_obj["volumeNumber"].toInt(); int disc = json_obj["volumeNumber"].toInt();
bool allow_streaming = json_obj["allowStreaming"].toBool(); bool allow_streaming = json_obj["allowStreaming"].toBool();
bool stream_ready = json_obj["streamReady"].toBool(); bool stream_ready = json_obj["streamReady"].toBool();
QString copyright = json_obj["copyright"].toString();
if (!json_value_artist.isObject()) { if (!json_value_artist.isObject()) {
qLog(Error) << "Tidal: Invalid Json reply, track artist is not a object."; qLog(Error) << "Tidal: Invalid Json reply, track artist is not a object.";
@ -944,15 +938,17 @@ Song TidalService::ParseSong(const int album_id_requested, const QJsonValue &val
QString album = json_album["title"].toString(); QString album = json_album["title"].toString();
QString cover = json_album["cover"].toString(); QString cover = json_album["cover"].toString();
if (!allow_streaming || !stream_ready) { if (!allow_streaming) {
qLog(Error) << "Tidal: Skipping song" << artist << album << title << "because allowStreaming is false OR streamReady is false."; qLog(Error) << "Tidal: Song" << artist << album << title << "is not allowStreaming";
return Song(); }
if (!stream_ready) {
qLog(Error) << "Tidal: Song" << artist << album << title << "is not streamReady.";
} }
//qLog(Debug) << "id" << id << "track" << track << "disc" << disc << "title" << title << "album" << album << "artist" << artist << cover << allow_streaming << url; //qLog(Debug) << "id" << id << "track" << track << "disc" << disc << "title" << title << "album" << album << "artist" << artist << cover << allow_streaming << url;
title.remove(Song::kTitleRemoveMisc); title.remove(Song::kTitleRemoveMisc);
album.remove(Song::kAlbumRemoveMisc);
Song song; Song song;
song.set_source(Song::Source_Tidal); song.set_source(Song::Source_Tidal);
@ -964,6 +960,7 @@ Song TidalService::ParseSong(const int album_id_requested, const QJsonValue &val
song.set_title(title); song.set_title(title);
song.set_track(track); song.set_track(track);
song.set_disc(disc); song.set_disc(disc);
song.set_comment(copyright);
QVariant q_duration = json_duration.toVariant(); QVariant q_duration = json_duration.toVariant();
if (q_duration.isValid()) { if (q_duration.isValid()) {

View File

@ -40,6 +40,7 @@
#include "internet/internetservice.h" #include "internet/internetservice.h"
#include "internet/internetsearch.h" #include "internet/internetsearch.h"
class Application;
class NetworkAccessManager; class NetworkAccessManager;
class TidalUrlHandler; class TidalUrlHandler;
@ -151,7 +152,6 @@ class TidalService : public InternetService {
QHash<int, QString> requests_album_songs_; QHash<int, QString> requests_album_songs_;
QHash<int, QUrl> requests_stream_url_; QHash<int, QUrl> requests_stream_url_;
QList<QUrl> queue_stream_url_; QList<QUrl> queue_stream_url_;
QList<QPair<QString, QString>> requests_artist_album_;
int artist_albums_requested_; int artist_albums_requested_;
int artist_albums_received_; int artist_albums_received_;
int album_songs_requested_; int album_songs_requested_;