1 /* 2 * Strawberry Music Player 3 * This file was part of Clementine. 4 * Copyright 2010, David Sansome <me@davidsansome.com> 5 * Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net> 6 * 7 * Strawberry is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Strawberry is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Strawberry. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 #ifndef ALBUMCOVERFETCHER_H 23 #define ALBUMCOVERFETCHER_H 24 25 #include "config.h" 26 27 #include <QtGlobal> 28 #include <QObject> 29 #include <QMetaType> 30 #include <QSet> 31 #include <QList> 32 #include <QHash> 33 #include <QQueue> 34 #include <QByteArray> 35 #include <QString> 36 #include <QUrl> 37 #include <QImage> 38 39 #include "coversearchstatistics.h" 40 #include "albumcoverimageresult.h" 41 42 class QTimer; 43 class NetworkAccessManager; 44 class CoverProviders; 45 class AlbumCoverFetcherSearch; 46 47 // This class represents a single search-for-cover request. It identifies and describes the request. 48 struct CoverSearchRequest { DialogResultDialogResult49 explicit CoverSearchRequest() : id(-1), search(false), batch(false) {} 50 51 // An unique (for one AlbumCoverFetcher) request identifier 52 quint64 id; 53 54 // A search query 55 QString artist; 56 QString album; 57 QString title; 58 59 // Is this only a search request or should we also fetch the first cover that's found? 60 bool search; IsSizeForcedDialogResult61 62 // Is the request part of a batch (fetching all missing covers) 63 bool batch; 64 }; RequiresCoverProcessingDialogResult65 66 // This structure represents a single result of some album's cover search request. 67 struct CoverProviderSearchResult { 68 explicit CoverProviderSearchResult() : score_provider(0.0), score_match(0.0), score_quality(0.0), number(0) {} 69 70 // Used for grouping in the user interface. 71 QString provider; 72 73 // Artist and album returned by the provider 74 QString artist; 75 QString album; 76 77 // An URL of a cover image 78 QUrl image_url; 79 80 // Image size 81 QSize image_size; 82 83 // Score for this provider 84 float score_provider; 85 86 // Score for match 87 float score_match; 88 89 // Score for image quality 90 float score_quality; 91 92 // The result number 93 int number; 94 95 // Total score for this result 96 float score() const { return score_provider + score_match + score_quality; } 97 98 }; 99 Q_DECLARE_METATYPE(CoverProviderSearchResult) 100 101 // This is a complete result of a single search request (a list of results, each describing one image, actually). 102 typedef QList<CoverProviderSearchResult> CoverProviderSearchResults; 103 Q_DECLARE_METATYPE(QList<CoverProviderSearchResult>) 104 105 // This class searches for album covers for a given query or artist/album and returns URLs. It's NOT thread-safe. 106 class AlbumCoverFetcher : public QObject { 107 Q_OBJECT 108 109 public: 110 explicit AlbumCoverFetcher(CoverProviders *cover_providers, QObject *parent = nullptr, NetworkAccessManager *network = nullptr); 111 ~AlbumCoverFetcher() override; 112 113 static const int kMaxConcurrentRequests; 114 115 quint64 SearchForCovers(const QString &artist, const QString &album, const QString &title = QString()); 116 quint64 FetchAlbumCover(const QString &artist, const QString &album, const QString &title, const bool batch); 117 118 void Clear(); 119 120 signals: 121 void AlbumCoverFetched(quint64 request_id, AlbumCoverImageResult result, CoverSearchStatistics statistics); 122 void SearchFinished(quint64 request_id, CoverProviderSearchResults results, CoverSearchStatistics statistics); 123 124 private slots: 125 void SingleSearchFinished(const quint64, const CoverProviderSearchResults &results); 126 void SingleCoverFetched(const quint64, const AlbumCoverImageResult &result); 127 void StartRequests(); 128 129 private: 130 void AddRequest(const CoverSearchRequest &req); 131 132 CoverProviders *cover_providers_; 133 NetworkAccessManager *network_; 134 quint64 next_id_; 135 136 QQueue<CoverSearchRequest> queued_requests_; 137 QHash<quint64, AlbumCoverFetcherSearch*> active_requests_; 138 139 QTimer *request_starter_; 140 141 }; 142 143 #endif // ALBUMCOVERFETCHER_H 144