Add new method for updating songs based on song ID

Show status updating database.

Fixes #750
This commit is contained in:
Jonas Kvinge
2021-09-19 15:41:36 +02:00
parent 120b18b399
commit d2d7f32c45
44 changed files with 650 additions and 194 deletions

View File

@@ -66,10 +66,26 @@ QString TidalFavoriteRequest::FavoriteText(const FavoriteType type) {
case FavoriteType_Albums:
return "albums";
case FavoriteType_Songs:
default:
return "tracks";
}
return QString();
}
QString TidalFavoriteRequest::FavoriteMethod(const FavoriteType type) {
switch (type) {
case FavoriteType_Artists:
return "artistIds";
case FavoriteType_Albums:
return "albumIds";
case FavoriteType_Songs:
return "trackIds";
}
return QString();
}
void TidalFavoriteRequest::AddArtists(const SongList &songs) {
@@ -80,27 +96,12 @@ void TidalFavoriteRequest::AddAlbums(const SongList &songs) {
AddFavorites(FavoriteType_Albums, songs);
}
void TidalFavoriteRequest::AddSongs(const SongList &songs) {
AddFavorites(FavoriteType_Songs, songs);
void TidalFavoriteRequest::AddSongs(const SongMap &songs) {
AddFavoritesRequest(FavoriteType_Songs, songs.keys(), songs.values());
}
void TidalFavoriteRequest::AddFavorites(const FavoriteType type, const SongList &songs) {
if (songs.isEmpty()) return;
QString text;
switch (type) {
case FavoriteType_Artists:
text = "artistIds";
break;
case FavoriteType_Albums:
text = "albumIds";
break;
case FavoriteType_Songs:
text = "trackIds";
break;
}
QStringList id_list;
for (const Song &song : songs) {
QString id;
@@ -118,15 +119,21 @@ void TidalFavoriteRequest::AddFavorites(const FavoriteType type, const SongList
id = song.song_id();
break;
}
if (id.isEmpty()) continue;
if (!id_list.contains(id)) {
if (!id.isEmpty() && !id_list.contains(id)) {
id_list << id;
}
}
if (id_list.isEmpty()) return;
AddFavoritesRequest(type, id_list, songs);
}
void TidalFavoriteRequest::AddFavoritesRequest(const FavoriteType type, const QStringList &id_list, const SongList &songs) {
ParamList params = ParamList() << Param("countryCode", country_code())
<< Param(text, id_list.join(','));
<< Param(FavoriteMethod(type), id_list.join(','));
QUrlQuery url_query;
for (const Param &param : params) {
@@ -197,11 +204,17 @@ void TidalFavoriteRequest::RemoveSongs(const SongList &songs) {
RemoveFavorites(FavoriteType_Songs, songs);
}
void TidalFavoriteRequest::RemoveSongs(const SongMap &songs) {
SongList songs_list = songs.values();
for (const Song &song : songs_list) {
RemoveFavoritesRequest(FavoriteType_Songs, song.song_id(), SongList() << song);
}
}
void TidalFavoriteRequest::RemoveFavorites(const FavoriteType type, const SongList &songs) {
if (songs.isEmpty()) return;
QStringList ids;
QMultiMap<QString, Song> songs_map;
for (const Song &song : songs) {
QString id;
@@ -219,18 +232,19 @@ void TidalFavoriteRequest::RemoveFavorites(const FavoriteType type, const SongLi
id = song.song_id();
break;
}
if (!ids.contains(id)) ids << id;
songs_map.insert(id, song);
if (!id.isEmpty()) {
songs_map.insert(id, song);
}
}
QStringList ids = songs_map.uniqueKeys();
for (const QString &id : ids) {
SongList songs_list = songs_map.values(id);
RemoveFavorites(type, id, songs_list);
RemoveFavoritesRequest(type, id, songs_map.values(id));
}
}
void TidalFavoriteRequest::RemoveFavorites(const FavoriteType type, const QString &id, const SongList &songs) {
void TidalFavoriteRequest::RemoveFavoritesRequest(const FavoriteType type, const QString &id, const SongList &songs) {
ParamList params = ParamList() << Param("countryCode", country_code());

View File

@@ -24,6 +24,7 @@
#include <QObject>
#include <QList>
#include <QMap>
#include <QVariant>
#include <QString>
@@ -65,18 +66,22 @@ class TidalFavoriteRequest : public TidalBaseRequest {
public slots:
void AddArtists(const SongList &songs);
void AddAlbums(const SongList &songs);
void AddSongs(const SongList &songs);
void AddSongs(const SongMap &songs);
void RemoveArtists(const SongList &songs);
void RemoveAlbums(const SongList &songs);
void RemoveSongs(const SongList &songs);
void RemoveSongs(const SongMap &songs);
private:
void Error(const QString &error, const QVariant &debug = QVariant()) override;
static QString FavoriteText(const FavoriteType type);
static QString FavoriteMethod(const FavoriteType type);
void AddFavorites(const FavoriteType type, const SongList &songs);
void AddFavoritesRequest(const FavoriteType type, const QStringList &id_list, const SongList &songs);
void RemoveFavorites(const FavoriteType type, const SongList &songs);
void RemoveFavorites(const FavoriteType type, const QString &id, const SongList &songs);
void RemoveFavoritesRequest(const FavoriteType type, const QString &id, const SongList &songs);
TidalService *service_;
NetworkAccessManager *network_;

View File

@@ -1270,15 +1270,17 @@ void TidalRequest::FinishCheck() {
finished_ = true;
if (no_results_ && songs_.isEmpty()) {
if (IsSearch())
emit Results(query_id_, SongList(), tr("No match."));
emit Results(query_id_, SongMap(), tr("No match."));
else
emit Results(query_id_, SongList(), QString());
emit Results(query_id_, SongMap(), QString());
}
else {
if (songs_.isEmpty() && errors_.isEmpty())
emit Results(query_id_, songs_.values(), tr("Unknown error"));
else
emit Results(query_id_, songs_.values(), ErrorsToHTML(errors_));
if (songs_.isEmpty() && errors_.isEmpty()) {
emit Results(query_id_, songs_, tr("Unknown error"));
}
else {
emit Results(query_id_, songs_, ErrorsToHTML(errors_));
}
}
}

View File

@@ -81,7 +81,7 @@ class TidalRequest : public TidalBaseRequest {
signals:
void LoginSuccess();
void LoginFailure(QString failure_reason);
void Results(int id, SongList songs, QString error);
void Results(int id, SongMap songs, QString error);
void UpdateStatus(int id, QString text);
void ProgressSetMaximum(int id, int max);
void UpdateProgress(int id, int max);
@@ -199,7 +199,7 @@ class TidalRequest : public TidalBaseRequest {
int album_covers_requested_;
int album_covers_received_;
QMap<QString, Song> songs_;
SongMap songs_;
QStringList errors_;
bool need_login_;
bool no_results_;

View File

@@ -28,6 +28,7 @@
#include <QByteArray>
#include <QPair>
#include <QList>
#include <QMap>
#include <QString>
#include <QChar>
#include <QUrl>
@@ -127,15 +128,15 @@ TidalService::TidalService(Application *app, QObject *parent)
artists_collection_backend_ = new CollectionBackend();
artists_collection_backend_->moveToThread(app_->database()->thread());
artists_collection_backend_->Init(app_->database(), Song::Source_Tidal, kArtistsSongsTable, kArtistsSongsFtsTable);
artists_collection_backend_->Init(app_->database(), app->task_manager(), Song::Source_Tidal, kArtistsSongsTable, kArtistsSongsFtsTable);
albums_collection_backend_ = new CollectionBackend();
albums_collection_backend_->moveToThread(app_->database()->thread());
albums_collection_backend_->Init(app_->database(), Song::Source_Tidal, kAlbumsSongsTable, kAlbumsSongsFtsTable);
albums_collection_backend_->Init(app_->database(), app->task_manager(), Song::Source_Tidal, kAlbumsSongsTable, kAlbumsSongsFtsTable);
songs_collection_backend_ = new CollectionBackend();
songs_collection_backend_->moveToThread(app_->database()->thread());
songs_collection_backend_->Init(app_->database(), Song::Source_Tidal, kSongsTable, kSongsFtsTable);
songs_collection_backend_->Init(app_->database(), app->task_manager(), Song::Source_Tidal, kSongsTable, kSongsFtsTable);
artists_collection_model_ = new CollectionModel(artists_collection_backend_, app_, this);
albums_collection_model_ = new CollectionModel(albums_collection_backend_, app_, this);
@@ -180,7 +181,8 @@ TidalService::TidalService(Application *app, QObject *parent)
QObject::connect(this, &TidalService::RemoveArtists, favorite_request_, &TidalFavoriteRequest::RemoveArtists);
QObject::connect(this, &TidalService::RemoveAlbums, favorite_request_, &TidalFavoriteRequest::RemoveAlbums);
QObject::connect(this, &TidalService::RemoveSongs, favorite_request_, &TidalFavoriteRequest::RemoveSongs);
QObject::connect(this, QOverload<SongList>::of(&TidalService::RemoveSongs), favorite_request_, QOverload<const SongList&>::of(&TidalFavoriteRequest::RemoveSongs));
QObject::connect(this, QOverload<SongMap>::of(&TidalService::RemoveSongs), favorite_request_, QOverload<const SongMap&>::of(&TidalFavoriteRequest::RemoveSongs));
QObject::connect(favorite_request_, &TidalFavoriteRequest::RequestLogin, this, &TidalService::SendLogin);
@@ -743,12 +745,12 @@ void TidalService::GetArtists() {
if (!authenticated()) {
if (oauth_) {
emit ArtistsResults(SongList(), tr("Not authenticated with Tidal."));
emit ArtistsResults(SongMap(), tr("Not authenticated with Tidal."));
ShowConfig();
return;
}
else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) {
emit ArtistsResults(SongList(), tr("Missing Tidal API token, username or password."));
emit ArtistsResults(SongMap(), tr("Missing Tidal API token, username or password."));
ShowConfig();
return;
}
@@ -769,7 +771,7 @@ void TidalService::GetArtists() {
}
void TidalService::ArtistsResultsReceived(const int id, const SongList &songs, const QString &error) {
void TidalService::ArtistsResultsReceived(const int id, const SongMap &songs, const QString &error) {
Q_UNUSED(id);
emit ArtistsResults(songs, error);
}
@@ -803,12 +805,12 @@ void TidalService::GetAlbums() {
if (!authenticated()) {
if (oauth_) {
emit AlbumsResults(SongList(), tr("Not authenticated with Tidal."));
emit AlbumsResults(SongMap(), tr("Not authenticated with Tidal."));
ShowConfig();
return;
}
else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) {
emit AlbumsResults(SongList(), tr("Missing Tidal API token, username or password."));
emit AlbumsResults(SongMap(), tr("Missing Tidal API token, username or password."));
ShowConfig();
return;
}
@@ -827,7 +829,7 @@ void TidalService::GetAlbums() {
}
void TidalService::AlbumsResultsReceived(const int id, const SongList &songs, const QString &error) {
void TidalService::AlbumsResultsReceived(const int id, const SongMap &songs, const QString &error) {
Q_UNUSED(id);
emit AlbumsResults(songs, error);
}
@@ -861,12 +863,12 @@ void TidalService::GetSongs() {
if (!authenticated()) {
if (oauth_) {
emit SongsResults(SongList(), tr("Not authenticated with Tidal."));
emit SongsResults(SongMap(), tr("Not authenticated with Tidal."));
ShowConfig();
return;
}
else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) {
emit SongsResults(SongList(), tr("Missing Tidal API token, username or password."));
emit SongsResults(SongMap(), tr("Missing Tidal API token, username or password."));
ShowConfig();
return;
}
@@ -885,7 +887,7 @@ void TidalService::GetSongs() {
}
void TidalService::SongsResultsReceived(const int id, const SongList &songs, const QString &error) {
void TidalService::SongsResultsReceived(const int id, const SongMap &songs, const QString &error) {
Q_UNUSED(id);
emit SongsResults(songs, error);
}
@@ -927,12 +929,12 @@ void TidalService::StartSearch() {
if (!authenticated()) {
if (oauth_) {
emit SearchResults(pending_search_id_, SongList(), tr("Not authenticated with Tidal."));
emit SearchResults(pending_search_id_, SongMap(), tr("Not authenticated with Tidal."));
ShowConfig();
return;
}
else if (api_token_.isEmpty() || username_.isEmpty() || password_.isEmpty()) {
emit SearchResults(pending_search_id_, SongList(), tr("Missing Tidal API token, username or password."));
emit SearchResults(pending_search_id_, SongMap(), tr("Missing Tidal API token, username or password."));
ShowConfig();
return;
}
@@ -981,7 +983,7 @@ void TidalService::SendSearch() {
}
void TidalService::SearchResultsReceived(const int id, const SongList &songs, const QString &error) {
void TidalService::SearchResultsReceived(const int id, const SongMap &songs, const QString &error) {
emit SearchResults(id, songs, error);
}

View File

@@ -138,10 +138,10 @@ class TidalService : public InternetService {
void HandleAuthReply(QNetworkReply *reply);
void ResetLoginAttempts();
void StartSearch();
void ArtistsResultsReceived(const int id, const SongList &songs, const QString &error);
void AlbumsResultsReceived(const int id, const SongList &songs, const QString &error);
void SongsResultsReceived(const int id, const SongList &songs, const QString &error);
void SearchResultsReceived(const int id, const SongList &songs, const QString &error);
void ArtistsResultsReceived(const int id, const SongMap &songs, const QString &error);
void AlbumsResultsReceived(const int id, const SongMap &songs, const QString &error);
void SongsResultsReceived(const int id, const SongMap &songs, const QString &error);
void SearchResultsReceived(const int id, const SongMap &songs, const QString &error);
void ArtistsUpdateStatusReceived(const int id, const QString &text);
void AlbumsUpdateStatusReceived(const int id, const QString &text);
void SongsUpdateStatusReceived(const int id, const QString &text);