/* * Strawberry Music Player * Copyright 2018-2021, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Strawberry is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Strawberry. If not, see . * */ #ifndef TIDALREQUEST_H #define TIDALREQUEST_H #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core/shared_ptr.h" #include "core/song.h" #include "tidalbaserequest.h" class QNetworkReply; class QTimer; class Application; class NetworkAccessManager; class TidalService; class TidalUrlHandler; class TidalRequest : public TidalBaseRequest { Q_OBJECT public: explicit TidalRequest(TidalService *service, TidalUrlHandler *url_handler, Application *app, SharedPtr network, Type query_type, QObject *parent); ~TidalRequest() override; void ReloadSettings(); void Process(); void set_need_login() override { need_login_ = true; } void Search(const int query_id, const QString &search_text); private: struct Artist { QString artist_id; QString artist; }; struct Album { Album() : album_explicit(false) {} QString album_id; QString album; QUrl cover_url; bool album_explicit; }; struct Request { Request() : offset(0), limit(0) {} int offset; int limit; }; struct ArtistAlbumsRequest { ArtistAlbumsRequest() : offset(0), limit(0) {} Artist artist; int offset; int limit; }; struct AlbumSongsRequest { AlbumSongsRequest() : offset(0), limit(0) {} Artist artist; Album album; int offset; int limit; }; struct AlbumCoverRequest { QString artist_id; QString album_id; QUrl url; QString filename; }; signals: void LoginSuccess(); void LoginFailure(const QString &failure_reason); void Results(const int id, const SongMap &songs = SongMap(), const QString &error = QString()); void UpdateStatus(const int id, const QString &text); void UpdateProgress(const int id, const int max); void StreamURLFinished(const QUrl &media_url, const QUrl &url, const Song::FileType filetype, const QString &error = QString()); private slots: 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 Artist &artist_requested, const int limit_requested, const int offset_requested, const bool auto_login); void SongsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested); void SongsReceived(QNetworkReply *reply, const Artist &artist, const Album &album, const int limit_requested, const int offset_requested, const bool auto_login = false); void ArtistAlbumsReplyReceived(QNetworkReply *reply, const Artist &artist, const int offset_requested); void AlbumSongsReplyReceived(QNetworkReply *reply, const Artist &artist, const Album &album, const int offset_requested); void AlbumCoverReceived(QNetworkReply *reply, const QString &album_id, const QUrl &url, const QString &filename); public slots: void LoginComplete(const bool success, const QString &error = QString()); private: bool IsQuery() const { return (query_type_ == Type::Artists || query_type_ == Type::Albums || query_type_ == Type::Songs); } bool IsSearch() const { return (query_type_ == Type::SearchArtists || query_type_ == Type::SearchAlbums || query_type_ == Type::SearchSongs); } void StartRequests(); void FlushRequests(); void GetArtists(); void GetAlbums(); void GetSongs(); void ArtistsSearch(); void AlbumsSearch(); void SongsSearch(); void AddArtistsRequest(const int offset = 0, const int limit = 0); void AddArtistsSearchRequest(const int offset = 0); void FlushArtistsRequests(); void AddAlbumsRequest(const int offset = 0, const int limit = 0); void AddAlbumsSearchRequest(const int offset = 0); void FlushAlbumsRequests(); void AddSongsRequest(const int offset = 0, const int limit = 0); void AddSongsSearchRequest(const int offset = 0); void FlushSongsRequests(); void ArtistsFinishCheck(const int limit = 0, const int offset = 0, const int artists_received = 0); void AlbumsFinishCheck(const Artist &artist, const int limit = 0, const int offset = 0, const int albums_total = 0, const int albums_received = 0); void SongsFinishCheck(const Artist &artist, const Album &album, const int limit = 0, const int offset = 0, const int songs_total = 0, const int songs_received = 0); void AddArtistAlbumsRequest(const Artist &artist, const int offset = 0); void FlushArtistAlbumsRequests(); void AddAlbumSongsRequest(const Artist &artist, const Album &album, const int offset = 0); void FlushAlbumSongsRequests(); void ParseSong(Song &song, const QJsonObject &json_obj, const Artist &album_artist, const Album &album); void GetAlbumCoversCheck(); void GetAlbumCovers(); void AddAlbumCoverRequest(const Song &song); void FlushAlbumCoverRequests(); void AlbumCoverFinishCheck(); int GetProgress(const int count, const int total); void FinishCheck(); static void Warn(const QString &error, const QVariant &debug = QVariant()); void Error(const QString &error, const QVariant &debug = QVariant()) override; TidalService *service_; TidalUrlHandler *url_handler_; Application *app_; SharedPtr network_; QTimer *timer_flush_requests_; const Type query_type_; const bool fetchalbums_; const QString coversize_; int query_id_; QString search_text_; bool finished_; QQueue artists_requests_queue_; QQueue albums_requests_queue_; QQueue songs_requests_queue_; QQueue artist_albums_requests_queue_; QQueue album_songs_requests_queue_; QQueue album_cover_requests_queue_; QHash artist_albums_requests_pending_; QHash album_songs_requests_pending_; QMultiMap album_covers_requests_sent_; int artists_requests_total_; int artists_requests_active_; int artists_requests_received_; int artists_total_; int artists_received_; int albums_requests_total_; int albums_requests_active_; int albums_requests_received_; int albums_total_; int albums_received_; int songs_requests_total_; int songs_requests_active_; int songs_requests_received_; int songs_total_; int songs_received_; int artist_albums_requests_total_; int artist_albums_requests_active_; int artist_albums_requests_received_; int artist_albums_total_; int artist_albums_received_; int album_songs_requests_active_; int album_songs_requests_received_; int album_songs_requests_total_; int album_songs_total_; int album_songs_received_; int album_covers_requests_total_; int album_covers_requests_active_; int album_covers_requests_received_; SongMap songs_; QStringList errors_; bool need_login_; QList replies_; QList album_cover_replies_; }; #endif // TIDALREQUEST_H