/* This file is part of Clementine. Copyright 2011, Paweł Bara Copyright 2011-2012, David Sansome Copyright 2014, Krzysztof Sobiecki Copyright 2014, John Maguire 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 . */ #include "albumcoverfetcher.h" #include #include "albumcoverfetchersearch.h" #include "core/network.h" const int AlbumCoverFetcher::kMaxConcurrentRequests = 5; AlbumCoverFetcher::AlbumCoverFetcher(CoverProviders* cover_providers, QObject* parent, QNetworkAccessManager* network) : QObject(parent), cover_providers_(cover_providers), network_(network ? network : new NetworkAccessManager(this)), next_id_(0), request_starter_(new QTimer(this)) { request_starter_->setInterval(1000); connect(request_starter_, SIGNAL(timeout()), SLOT(StartRequests())); } quint64 AlbumCoverFetcher::FetchAlbumCover(const QString& artist, const QString& album, bool fetchall) { CoverSearchRequest request; request.artist = artist; request.album = album; request.search = false; request.id = next_id_++; request.fetchall = fetchall; AddRequest(request); return request.id; } quint64 AlbumCoverFetcher::SearchForCovers(const QString& artist, const QString& album) { CoverSearchRequest request; request.artist = artist; request.album = album; request.search = true; request.id = next_id_++; request.fetchall = false; AddRequest(request); return request.id; } void AlbumCoverFetcher::AddRequest(const CoverSearchRequest& req) { queued_requests_.enqueue(req); if (!request_starter_->isActive()) request_starter_->start(); if (active_requests_.size() < kMaxConcurrentRequests) StartRequests(); } void AlbumCoverFetcher::Clear() { queued_requests_.clear(); for (AlbumCoverFetcherSearch* search : active_requests_.values()) { search->Cancel(); search->deleteLater(); } active_requests_.clear(); } void AlbumCoverFetcher::StartRequests() { if (queued_requests_.isEmpty()) { request_starter_->stop(); return; } while (!queued_requests_.isEmpty() && active_requests_.size() < kMaxConcurrentRequests) { CoverSearchRequest request = queued_requests_.dequeue(); // search objects are this fetcher's children so worst case scenario - they // get // deleted with it AlbumCoverFetcherSearch* search = new AlbumCoverFetcherSearch(request, network_, this); active_requests_.insert(request.id, search); connect(search, SIGNAL(SearchFinished(quint64, CoverSearchResults)), SLOT(SingleSearchFinished(quint64, CoverSearchResults))); connect(search, SIGNAL(AlbumCoverFetched(quint64, const QImage&)), SLOT(SingleCoverFetched(quint64, const QImage&))); search->Start(cover_providers_); } } void AlbumCoverFetcher::SingleSearchFinished(quint64 request_id, CoverSearchResults results) { AlbumCoverFetcherSearch* search = active_requests_.take(request_id); if (!search) return; search->deleteLater(); emit SearchFinished(request_id, results, search->statistics()); } void AlbumCoverFetcher::SingleCoverFetched(quint64 request_id, const QImage& image) { AlbumCoverFetcherSearch* search = active_requests_.take(request_id); if (!search) return; search->deleteLater(); emit AlbumCoverFetched(request_id, image, search->statistics()); }