2010-03-24 00:11:46 +01:00
|
|
|
/* This file is part of Clementine.
|
|
|
|
|
|
|
|
Clementine 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.
|
|
|
|
|
|
|
|
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2010-02-23 20:26:21 +01:00
|
|
|
#include "albumcoverfetcher.h"
|
2010-05-10 15:15:52 +02:00
|
|
|
#include "networkaccessmanager.h"
|
2010-02-23 20:26:21 +01:00
|
|
|
|
|
|
|
#include <QNetworkReply>
|
2010-02-28 20:25:52 +01:00
|
|
|
#include <QTimer>
|
2010-02-23 20:26:21 +01:00
|
|
|
|
|
|
|
#include <lastfm/Artist>
|
|
|
|
#include <lastfm/XmlQuery>
|
|
|
|
#include <lastfm/ws.h>
|
|
|
|
|
2010-02-28 20:25:52 +01:00
|
|
|
const int AlbumCoverFetcher::kMaxConcurrentRequests = 5;
|
|
|
|
|
2010-05-10 15:15:52 +02:00
|
|
|
AlbumCoverFetcher::AlbumCoverFetcher(NetworkAccessManager* network, QObject* parent)
|
2010-02-28 20:25:52 +01:00
|
|
|
: QObject(parent),
|
2010-05-10 15:15:52 +02:00
|
|
|
network_(network->network()),
|
2010-02-28 20:25:52 +01:00
|
|
|
next_id_(0),
|
|
|
|
request_starter_(new QTimer(this))
|
|
|
|
{
|
|
|
|
request_starter_->setInterval(1000);
|
|
|
|
connect(request_starter_, SIGNAL(timeout()), SLOT(StartRequests()));
|
2010-02-23 20:26:21 +01:00
|
|
|
}
|
|
|
|
|
2010-02-28 20:25:52 +01:00
|
|
|
quint64 AlbumCoverFetcher::FetchAlbumCover(
|
2010-02-23 20:26:21 +01:00
|
|
|
const QString& artist_name, const QString& album_name) {
|
2010-02-28 20:25:52 +01:00
|
|
|
QueuedRequest request;
|
|
|
|
request.album = album_name;
|
|
|
|
request.artist = artist_name;
|
|
|
|
request.id = next_id_ ++;
|
|
|
|
|
2010-06-12 19:13:01 +02:00
|
|
|
AddRequest(request);
|
|
|
|
return request.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
quint64 AlbumCoverFetcher::SearchForCovers(const QString &query) {
|
|
|
|
QueuedRequest request;
|
|
|
|
request.query = query;
|
|
|
|
request.id = next_id_ ++;
|
|
|
|
|
|
|
|
AddRequest(request);
|
|
|
|
return request.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumCoverFetcher::AddRequest(QueuedRequest req) {
|
|
|
|
queued_requests_.enqueue(req);
|
2010-02-28 20:25:52 +01:00
|
|
|
|
|
|
|
if (!request_starter_->isActive())
|
|
|
|
request_starter_->start();
|
|
|
|
|
|
|
|
if (active_requests_.count() < kMaxConcurrentRequests)
|
|
|
|
StartRequests();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumCoverFetcher::Clear() {
|
|
|
|
queued_requests_.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumCoverFetcher::StartRequests() {
|
|
|
|
if (queued_requests_.isEmpty()) {
|
|
|
|
request_starter_->stop();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!queued_requests_.isEmpty() &&
|
|
|
|
active_requests_.count() < kMaxConcurrentRequests) {
|
|
|
|
QueuedRequest request = queued_requests_.dequeue();
|
|
|
|
|
2010-06-12 19:13:01 +02:00
|
|
|
if (request.query.isEmpty()) {
|
|
|
|
lastfm::Artist artist(request.artist);
|
|
|
|
lastfm::Album album(artist, request.album);
|
|
|
|
|
|
|
|
QNetworkReply* reply = album.getInfo();
|
|
|
|
connect(reply, SIGNAL(finished()), SLOT(AlbumGetInfoFinished()));
|
|
|
|
active_requests_.insert(reply, request.id);
|
|
|
|
} else {
|
|
|
|
QMap<QString, QString> params;
|
|
|
|
params["method"] = "album.search";
|
|
|
|
params["album"] = request.query;
|
|
|
|
|
|
|
|
QNetworkReply* reply = lastfm::ws::post(params);
|
|
|
|
connect(reply, SIGNAL(finished()), SLOT(AlbumSearchFinished()));
|
|
|
|
active_requests_.insert(reply, request.id);
|
|
|
|
}
|
2010-02-28 20:25:52 +01:00
|
|
|
}
|
2010-02-23 20:26:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumCoverFetcher::AlbumGetInfoFinished() {
|
|
|
|
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
|
|
|
reply->deleteLater();
|
2010-02-28 20:25:52 +01:00
|
|
|
quint64 id = active_requests_.take(reply);
|
2010-02-23 20:26:21 +01:00
|
|
|
|
2010-03-22 22:36:02 +01:00
|
|
|
if (reply->error() != QNetworkReply::NoError) {
|
|
|
|
// TODO: retry request.
|
|
|
|
emit AlbumCoverFetched(id, QImage());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-02-28 20:25:52 +01:00
|
|
|
try {
|
|
|
|
lastfm::XmlQuery query(lastfm::ws::parse(reply));
|
2010-02-23 20:26:21 +01:00
|
|
|
|
2010-02-28 20:25:52 +01:00
|
|
|
QUrl image_url(query["album"]["image size=large"].text());
|
2010-03-03 20:14:14 +01:00
|
|
|
QNetworkReply* image_reply = network_->get(QNetworkRequest(image_url));
|
2010-02-28 20:25:52 +01:00
|
|
|
connect(image_reply, SIGNAL(finished()), SLOT(AlbumCoverFetchFinished()));
|
2010-02-23 20:26:21 +01:00
|
|
|
|
2010-02-28 20:25:52 +01:00
|
|
|
active_requests_[image_reply] = id;
|
|
|
|
} catch (std::runtime_error&) {
|
|
|
|
emit AlbumCoverFetched(id, QImage());
|
|
|
|
}
|
2010-02-23 20:26:21 +01:00
|
|
|
}
|
|
|
|
|
2010-06-12 19:13:01 +02:00
|
|
|
void AlbumCoverFetcher::AlbumSearchFinished() {
|
|
|
|
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
|
|
|
reply->deleteLater();
|
|
|
|
quint64 id = active_requests_.take(reply);
|
|
|
|
|
|
|
|
if (reply->error() != QNetworkReply::NoError) {
|
|
|
|
qDebug() << "Error" << reply->error();
|
|
|
|
// TODO: retry request.
|
|
|
|
emit SearchFinished(id, SearchResults());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
lastfm::XmlQuery query(lastfm::ws::parse(reply));
|
|
|
|
|
|
|
|
QList<lastfm::XmlQuery> elements = query["results"]["albummatches"].children("album");
|
|
|
|
SearchResults results;
|
|
|
|
foreach (const lastfm::XmlQuery& element, elements) {
|
|
|
|
SearchResult result;
|
|
|
|
result.album = element["name"].text();
|
|
|
|
result.artist = element["artist"].text();
|
|
|
|
result.image_url = element["image size=large"].text();
|
|
|
|
results << result;
|
|
|
|
}
|
|
|
|
|
|
|
|
emit SearchFinished(id, results);
|
|
|
|
} catch (std::runtime_error&) {
|
|
|
|
qDebug() << "Parse error";
|
|
|
|
emit SearchFinished(id, SearchResults());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-23 20:26:21 +01:00
|
|
|
void AlbumCoverFetcher::AlbumCoverFetchFinished() {
|
|
|
|
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
|
|
|
reply->deleteLater();
|
2010-03-22 22:36:02 +01:00
|
|
|
quint64 id = active_requests_.take(reply);
|
|
|
|
|
|
|
|
if (reply->error() != QNetworkReply::NoError) {
|
|
|
|
// TODO: retry request.
|
|
|
|
emit AlbumCoverFetched(id, QImage());
|
|
|
|
return;
|
|
|
|
}
|
2010-02-23 20:26:21 +01:00
|
|
|
|
|
|
|
QImage image;
|
|
|
|
image.loadFromData(reply->readAll());
|
|
|
|
|
2010-02-28 20:25:52 +01:00
|
|
|
emit AlbumCoverFetched(id, image);
|
2010-02-23 20:26:21 +01:00
|
|
|
}
|