Add a thread safe network disk cache, and remove the need to pass a NetworkAccessManager around everywhere. Fixes issue #852

This commit is contained in:
David Sansome 2010-10-16 17:20:54 +00:00
parent c35ba55e75
commit b5f366c40a
39 changed files with 240 additions and 249 deletions

View File

@ -47,7 +47,7 @@ set(SOURCES
core/gnomeglobalshortcutbackend.cpp
core/mergedproxymodel.cpp
core/musicstorage.cpp
core/networkaccessmanager.cpp
core/network.cpp
core/organise.cpp
core/organiseformat.cpp
core/player.cpp
@ -211,7 +211,7 @@ set(HEADERS
core/globalshortcuts.h
core/gnomeglobalshortcutbackend.h
core/mergedproxymodel.h
core/networkaccessmanager.h
core/network.h
core/organise.h
core/player.h
core/songloader.h

View File

@ -15,7 +15,7 @@
*/
#include "albumcoverfetcher.h"
#include "networkaccessmanager.h"
#include "network.h"
#include <QNetworkReply>
#include <QTimer>
@ -26,9 +26,9 @@
const int AlbumCoverFetcher::kMaxConcurrentRequests = 5;
AlbumCoverFetcher::AlbumCoverFetcher(NetworkAccessManager* network, QObject* parent)
AlbumCoverFetcher::AlbumCoverFetcher(QObject* parent)
: QObject(parent),
network_(network->network()),
network_(new NetworkAccessManager(this)),
next_id_(0),
request_starter_(new QTimer(this))
{

View File

@ -30,13 +30,11 @@
class QNetworkReply;
class QString;
class NetworkAccessManager;
class AlbumCoverFetcher : public QObject {
Q_OBJECT
public:
AlbumCoverFetcher(NetworkAccessManager* network, QObject* parent = 0);
AlbumCoverFetcher(QObject* parent = 0);
virtual ~AlbumCoverFetcher() {}
struct SearchResult {

View File

@ -15,7 +15,7 @@
*/
#include "albumcoverloader.h"
#include "networkaccessmanager.h"
#include "network.h"
#include <QPainter>
#include <QDir>
@ -37,7 +37,7 @@ AlbumCoverLoader::AlbumCoverLoader(QObject* parent)
height_(120),
padding_(true),
next_id_(0),
network_(NULL)
network_(new NetworkAccessManager(this))
{
}
@ -137,9 +137,10 @@ AlbumCoverLoader::TryLoadResult AlbumCoverLoader::TryLoadImage(
}
if (filename.toLower().startsWith("http://")) {
network_->Get(QUrl(filename), this, "RemoteFetchFinished", task.id, true);
QNetworkReply* reply = network_->get(QNetworkRequest(filename));
connect(reply, SIGNAL(finished()), SLOT(RemoteFetchFinished()));
remote_tasks_.insert(task.id, task);
remote_tasks_.insert(reply, task);
return TryLoadResult(true, false, QImage());
}
@ -171,8 +172,12 @@ QImage AlbumCoverLoader::LoadFromTaglib(const QString& filename) const {
return ret;
}
void AlbumCoverLoader::RemoteFetchFinished(quint64 id, QNetworkReply* reply) {
Task task = remote_tasks_.take(id);
void AlbumCoverLoader::RemoteFetchFinished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if (!reply)
return;
Task task = remote_tasks_.take(reply);
if (reply->error() == QNetworkReply::NoError) {
// Try to load the image

View File

@ -34,7 +34,6 @@ class AlbumCoverLoader : public QObject {
public:
AlbumCoverLoader(QObject* parent = 0);
void SetNetwork(NetworkAccessManager* network) { network_ = network; }
void Stop() { stop_requested_ = true; }
@ -63,7 +62,7 @@ class AlbumCoverLoader : public QObject {
private slots:
void ProcessTasks();
void RemoteFetchFinished(quint64 id, QNetworkReply* reply);
void RemoteFetchFinished();
private:
enum State {
@ -103,7 +102,7 @@ class AlbumCoverLoader : public QObject {
QMutex mutex_;
QQueue<Task> tasks_;
QMap<quint64, Task> remote_tasks_;
QMap<QNetworkReply*, Task> remote_tasks_;
quint64 next_id_;
NetworkAccessManager* network_;

94
src/core/network.cpp Normal file
View File

@ -0,0 +1,94 @@
/* 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/>.
*/
#include "network.h"
#include <QCoreApplication>
#include <QDir>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
QMutex ThreadSafeNetworkDiskCache::sMutex;
QNetworkDiskCache* ThreadSafeNetworkDiskCache::sCache = NULL;
ThreadSafeNetworkDiskCache::ThreadSafeNetworkDiskCache(QObject* parent) {
QMutexLocker l(&sMutex);
if (!sCache) {
sCache = new QNetworkDiskCache;
sCache->setCacheDirectory(QString("%1/.config/%2/networkcache/")
.arg(QDir::homePath(), QCoreApplication::organizationName()));
}
}
qint64 ThreadSafeNetworkDiskCache::cacheSize() const {
QMutexLocker l(&sMutex);
return sCache->cacheSize();
}
QIODevice* ThreadSafeNetworkDiskCache::data(const QUrl& url) {
QMutexLocker l(&sMutex);
return sCache->data(url);
}
void ThreadSafeNetworkDiskCache::insert(QIODevice* device) {
QMutexLocker l(&sMutex);
sCache->insert(device);
}
QNetworkCacheMetaData ThreadSafeNetworkDiskCache::metaData(const QUrl& url) {
QMutexLocker l(&sMutex);
return sCache->metaData(url);
}
QIODevice* ThreadSafeNetworkDiskCache::prepare(const QNetworkCacheMetaData& metaData) {
QMutexLocker l(&sMutex);
return sCache->prepare(metaData);
}
bool ThreadSafeNetworkDiskCache::remove(const QUrl& url) {
QMutexLocker l(&sMutex);
return sCache->remove(url);
}
void ThreadSafeNetworkDiskCache::updateMetaData(const QNetworkCacheMetaData& metaData) {
QMutexLocker l(&sMutex);
sCache->updateMetaData(metaData);
}
void ThreadSafeNetworkDiskCache::clear() {
QMutexLocker l(&sMutex);
sCache->clear();
}
NetworkAccessManager::NetworkAccessManager(QObject* parent)
: QNetworkAccessManager(parent)
{
setCache(new ThreadSafeNetworkDiskCache(this));
}
QNetworkReply* NetworkAccessManager::createRequest(
Operation op, const QNetworkRequest& request, QIODevice* outgoingData) {
QNetworkRequest new_request(request);
new_request.setRawHeader("User-Agent", QString("%1 %2").arg(
QCoreApplication::applicationName(),
QCoreApplication::applicationVersion()).toUtf8());
new_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
QNetworkRequest::PreferCache);
return QNetworkAccessManager::createRequest(op, new_request, outgoingData);
}

56
src/core/network.h Normal file
View File

@ -0,0 +1,56 @@
/* 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/>.
*/
#ifndef NETWORK_H
#define NETWORK_H
#include <QAbstractNetworkCache>
#include <QMutex>
#include <QNetworkAccessManager>
class QNetworkDiskCache;
class ThreadSafeNetworkDiskCache : public QAbstractNetworkCache {
public:
ThreadSafeNetworkDiskCache(QObject* parent);
qint64 cacheSize() const;
QIODevice* data(const QUrl& url);
void insert(QIODevice* device);
QNetworkCacheMetaData metaData(const QUrl& url);
QIODevice* prepare(const QNetworkCacheMetaData& metaData);
bool remove(const QUrl& url);
void updateMetaData(const QNetworkCacheMetaData& metaData);
void clear();
private:
static QMutex sMutex;
static QNetworkDiskCache* sCache;
};
class NetworkAccessManager : public QNetworkAccessManager {
Q_OBJECT
public:
NetworkAccessManager(QObject* parent = 0);
protected:
QNetworkReply* createRequest(Operation op, const QNetworkRequest& request,
QIODevice* outgoingData);
};
#endif // NETWORK_H

View File

@ -1,77 +0,0 @@
#include "networkaccessmanager.h"
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkDiskCache>
#include <QCoreApplication>
#include <QDir>
#include <QtDebug>
NetworkAccessManager::NetworkAccessManager(QObject* parent,
QNetworkAccessManager* injected)
: QObject(parent),
network_(injected ? injected : new QNetworkAccessManager(this)),
cache_(new QNetworkDiskCache(this))
{
cache_->setCacheDirectory(QString("%1/.config/%2/networkcache/")
.arg(QDir::homePath(), QCoreApplication::organizationName()));
network_->setCache(cache_);
}
void NetworkAccessManager::Get(const QUrl &url, QObject *receiver,
const char *slot, quint64 id, bool force_cache) {
connect(receiver, SIGNAL(destroyed(QObject*)), SLOT(ReceiverDestroyed(QObject*)));
QMetaObject::invokeMethod(
this, "RunGet", Qt::QueuedConnection,
Q_ARG(QUrl, url), Q_ARG(QObject*, receiver),
Q_ARG(const char*, slot),
Q_ARG(quint64, id), Q_ARG(bool, force_cache));
}
void NetworkAccessManager::RunGet(const QUrl &url, QObject *receiver,
const char *slot, quint64 id, bool force_cache) {
QNetworkRequest req = CreateRequest(url, force_cache);
QNetworkReply* reply = network_->get(req);
connect(reply, SIGNAL(finished()), SLOT(RequestFinished()));
Receiver r;
r.receiver = receiver;
r.slot = slot;
r.id = id;
pending_replies_.insert(reply, r);
}
void NetworkAccessManager::ReceiverDestroyed(QObject* receiver) {
foreach (QNetworkReply* key, pending_replies_.keys()) {
if (pending_replies_[key].receiver == receiver)
pending_replies_[key].receiver = NULL;
}
}
QNetworkRequest NetworkAccessManager::CreateRequest(const QUrl& url, bool force_cache) {
QNetworkRequest req(url);
req.setRawHeader("User-Agent", QString("%1 %2").arg(
QCoreApplication::applicationName(),
QCoreApplication::applicationVersion()).toUtf8());
if (force_cache) {
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
QNetworkRequest::PreferCache);
}
return req;
}
void NetworkAccessManager::RequestFinished() {
QNetworkReply* reply = static_cast<QNetworkReply*>(sender());
Receiver r = pending_replies_.take(reply);
if (!r.receiver)
return;
QMetaObject::invokeMethod(r.receiver, r.slot,
Q_ARG(quint64, r.id),
Q_ARG(QNetworkReply*, reply));
}

View File

@ -1,49 +0,0 @@
#ifndef NETWORKACCESSMANAGER_H
#define NETWORKACCESSMANAGER_H
#include <QObject>
#include <QMap>
class QNetworkAccessManager;
class QNetworkDiskCache;
class QNetworkReply;
class QNetworkRequest;
class QUrl;
// It's like QNetworkAccessManager, but threadsafe, and sets our User-Agent
// on all requests
class NetworkAccessManager : public QObject {
Q_OBJECT
public:
NetworkAccessManager(QObject* parent = 0, QNetworkAccessManager* injected = 0);
// Only use this from the main thread
QNetworkAccessManager* network() const { return network_; }
// Thread-safe. slot should take (quint64, QNetworkReply*)
void Get(const QUrl& url, QObject* receiver, const char* slot,
quint64 id, bool force_cache = false);
private slots:
void RunGet(const QUrl& url, QObject* receiver, const char* slot,
quint64 id, bool force_cache);
void RequestFinished();
void ReceiverDestroyed(QObject* receiver);
private:
QNetworkRequest CreateRequest(const QUrl& url, bool force_cache);
QNetworkAccessManager* network_;
QNetworkDiskCache* cache_;
struct Receiver {
QObject* receiver;
const char* slot;
quint64 id;
};
QMap<QNetworkReply*, Receiver> pending_replies_;
};
#endif // NETWORKACCESSMANAGER_H

View File

@ -24,7 +24,7 @@
#include "core/commandlineoptions.h"
#include "core/encoding.h"
#include "core/mac_startup.h"
#include "core/networkaccessmanager.h"
#include "core/network.h"
#include "core/player.h"
#include "core/potranslator.h"
#include "core/song.h"
@ -198,10 +198,8 @@ int main(int argc, char *argv[]) {
// Icons
IconLoader::Init();
NetworkAccessManager network;
Echonest::Config::instance()->setAPIKey("DFLFLJBUF4EGTXHIG");
Echonest::Config::instance()->setNetworkAccessManager(network.network());
Echonest::Config::instance()->setNetworkAccessManager(new NetworkAccessManager);
// MPRIS DBus interface.
#ifdef Q_WS_X11
@ -216,7 +214,7 @@ int main(int argc, char *argv[]) {
srand(time(NULL));
// Window
MainWindow w(&network, options.engine());
MainWindow w(options.engine());
QObject::connect(&a, SIGNAL(messageReceived(QByteArray)), &w, SLOT(CommandlineOptionsReceived(QByteArray)));
w.CommandlineOptionsReceived(options);

View File

@ -19,7 +19,6 @@
#include "lastfmstationdialog.h"
#include "radiomodel.h"
#include "radioplaylistitem.h"
#include "core/networkaccessmanager.h"
#include "core/song.h"
#include "core/taskmanager.h"
#include "ui/iconloader.h"
@ -63,8 +62,7 @@ LastFMService::LastFMService(RadioModel* parent)
tag_list_(NULL),
custom_list_(NULL),
friends_list_(NULL),
neighbours_list_(NULL),
network_(parent->network()->network())
neighbours_list_(NULL)
{
ReloadSettings();

View File

@ -185,7 +185,6 @@ class LastFMService : public RadioService {
RadioItem* friends_list_;
RadioItem* neighbours_list_;
QNetworkAccessManager* network_;
QHash<lastfm::Track, QString> art_urls_;
};

View File

@ -18,7 +18,7 @@
#include "magnatuneservice.h"
#include "radiomodel.h"
#include "ui_magnatunedownloaddialog.h"
#include "core/networkaccessmanager.h"
#include "core/network.h"
#include "widgets/progressitemdelegate.h"
#include <QCloseEvent>
@ -37,7 +37,7 @@ MagnatuneDownloadDialog::MagnatuneDownloadDialog(MagnatuneService* service,
: QDialog(parent),
ui_(new Ui_MagnatuneDownloadDialog),
service_(service),
network_(service_->model()->network()->network()),
network_(new NetworkAccessManager(this)),
current_reply_(NULL),
next_row_(0)
{
@ -122,8 +122,7 @@ void MagnatuneDownloadDialog::DownloadNext() {
url.addQueryItem("id", MagnatuneService::kPartnerId);
url.addQueryItem("sku", sku);
QNetworkRequest req(url);
current_reply_ = network_->get(req);
current_reply_ = network_->get(QNetworkRequest(url));
connect(current_reply_, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(Error(QNetworkReply::NetworkError)));
connect(current_reply_, SIGNAL(finished()), SLOT(MetadataFinished()));
@ -183,8 +182,7 @@ void MagnatuneDownloadDialog::MetadataFinished() {
url.setPassword(service_->password());
// Start the actual download
QNetworkRequest req(url);
current_reply_ = network_->get(req);
current_reply_ = network_->get(QNetworkRequest(url));
connect(current_reply_, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(Error(QNetworkReply::NetworkError)));
connect(current_reply_, SIGNAL(finished()), SLOT(DownloadFinished()));
@ -212,8 +210,7 @@ void MagnatuneDownloadDialog::DownloadFinished() {
redirect.setUserName(service_->username());
redirect.setPassword(service_->password());
QNetworkRequest req(redirect);
current_reply_ = network_->get(req);
current_reply_ = network_->get(QNetworkRequest(redirect));
connect(current_reply_, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(Error(QNetworkReply::NetworkError)));
connect(current_reply_, SIGNAL(finished()), SLOT(DownloadFinished()));

View File

@ -19,7 +19,7 @@
#include "magnatuneservice.h"
#include "radiomodel.h"
#include "core/mergedproxymodel.h"
#include "core/networkaccessmanager.h"
#include "core/network.h"
#include "core/song.h"
#include "core/taskmanager.h"
#include "library/librarymodel.h"
@ -69,7 +69,7 @@ MagnatuneService::MagnatuneService(RadioModel* parent)
membership_(Membership_None),
format_(Format_Ogg),
total_song_count_(0),
network_(parent->network()->network())
network_(new NetworkAccessManager(this))
{
ReloadSettings();

View File

@ -29,12 +29,10 @@
QMap<QString, RadioService*> RadioModel::sServices;
RadioModel::RadioModel(BackgroundThread<Database>* db_thread,
NetworkAccessManager* network, TaskManager* task_manager,
QObject* parent)
TaskManager* task_manager, QObject* parent)
: SimpleTreeModel<RadioItem>(new RadioItem(this), parent),
db_thread_(db_thread),
merged_model_(new MergedProxyModel(this)),
network_(network),
task_manager_(task_manager)
{
Q_ASSERT(sServices.isEmpty());

View File

@ -28,7 +28,6 @@
class Database;
class LastFMService;
class MergedProxyModel;
class NetworkAccessManager;
class RadioService;
class SettingsDialog;
class TaskManager;
@ -37,8 +36,7 @@ class RadioModel : public SimpleTreeModel<RadioItem> {
Q_OBJECT
public:
RadioModel(BackgroundThread<Database>* db_thread,
NetworkAccessManager* network, TaskManager* task_manager,
RadioModel(BackgroundThread<Database>* db_thread, TaskManager* task_manager,
QObject* parent = 0);
enum {
@ -73,7 +71,6 @@ class RadioModel : public SimpleTreeModel<RadioItem> {
BackgroundThread<Database>* db_thread() const { return db_thread_; }
MergedProxyModel* merged_model() const { return merged_model_; }
NetworkAccessManager* network() const { return network_; }
TaskManager* task_manager() const { return task_manager_; }
signals:
@ -96,7 +93,6 @@ class RadioModel : public SimpleTreeModel<RadioItem> {
static QMap<QString, RadioService*> sServices;
BackgroundThread<Database>* db_thread_;
MergedProxyModel* merged_model_;
NetworkAccessManager* network_;
TaskManager* task_manager_;
};

View File

@ -16,11 +16,10 @@
#include "somafmservice.h"
#include "radiomodel.h"
#include "core/networkaccessmanager.h"
#include "core/network.h"
#include "core/taskmanager.h"
#include "ui/iconloader.h"
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QXmlStreamReader>
@ -41,7 +40,7 @@ SomaFMService::SomaFMService(RadioModel* parent)
context_menu_(NULL),
get_channels_task_id_(0),
get_stream_task_id_(0),
network_(parent->network()->network())
network_(new NetworkAccessManager(this))
{
}

View File

@ -22,8 +22,8 @@
#include "songinfofetcher.h"
#include "widgets/prettyimageview.h"
ArtistInfoView::ArtistInfoView(NetworkAccessManager* network, QWidget *parent)
: SongInfoBase(network, parent)
ArtistInfoView::ArtistInfoView(QWidget *parent)
: SongInfoBase(parent)
{
fetcher_->AddProvider(new EchoNestBiographies);
fetcher_->AddProvider(new EchoNestImages);
@ -48,7 +48,7 @@ void ArtistInfoView::ResultReady(int id, const SongInfoFetcher::Result& result)
Clear();
// Image view goes at the top
PrettyImageView* image_view = new PrettyImageView(network_);
PrettyImageView* image_view = new PrettyImageView(this);
AddWidget(image_view);
foreach (const QUrl& url, result.images_) {

View File

@ -32,7 +32,7 @@ class ArtistInfoView : public SongInfoBase {
Q_OBJECT
public:
ArtistInfoView(NetworkAccessManager* network, QWidget* parent = 0);
ArtistInfoView(QWidget* parent = 0);
~ArtistInfoView();
protected:

View File

@ -25,9 +25,8 @@
const char* SongInfoBase::kSettingsGroup = "SongInfo";
SongInfoBase::SongInfoBase(NetworkAccessManager* network, QWidget* parent)
SongInfoBase::SongInfoBase(QWidget* parent)
: QWidget(parent),
network_(network),
fetcher_(new SongInfoFetcher(this)),
current_request_id_(-1),
scroll_area_(new QScrollArea),

View File

@ -26,7 +26,6 @@
#include "widgets/widgetfadehelper.h"
class CollapsibleInfoPane;
class NetworkAccessManager;
class WidgetFadeHelper;
class QScrollArea;
@ -36,7 +35,7 @@ class SongInfoBase : public QWidget {
Q_OBJECT
public:
SongInfoBase(NetworkAccessManager* network, QWidget* parent = 0);
SongInfoBase(QWidget* parent = 0);
static const char* kSettingsGroup;
@ -64,7 +63,6 @@ protected slots:
virtual void ResultReady(int id, const SongInfoFetcher::Result& result);
protected:
NetworkAccessManager* network_;
SongInfoFetcher* fetcher_;
int current_request_id_;

View File

@ -29,9 +29,9 @@ const char* SongInfoView::kSettingsGroup = "SongInfo";
typedef QList<SongInfoProvider*> ProviderList;
SongInfoView::SongInfoView(NetworkAccessManager* network, QWidget* parent)
: SongInfoBase(network, parent),
ultimate_reader_(new UltimateLyricsReader(network))
SongInfoView::SongInfoView(QWidget* parent)
: SongInfoBase(parent),
ultimate_reader_(new UltimateLyricsReader(this))
{
// Parse the ultimate lyrics xml file in the background
QFuture<ProviderList> future = QtConcurrent::run(

View File

@ -28,7 +28,7 @@ class SongInfoView : public SongInfoBase {
Q_OBJECT
public:
SongInfoView(NetworkAccessManager* network, QWidget* parent = 0);
SongInfoView(QWidget* parent = 0);
~SongInfoView();
static const char* kSettingsGroup;

View File

@ -16,7 +16,7 @@
#include "songinfotextview.h"
#include "ultimatelyricsprovider.h"
#include "core/networkaccessmanager.h"
#include "core/network.h"
#include <QNetworkReply>
#include <QTextCodec>
@ -26,8 +26,8 @@
const int UltimateLyricsProvider::kRedirectLimit = 5;
UltimateLyricsProvider::UltimateLyricsProvider(NetworkAccessManager* network)
: network_(network),
UltimateLyricsProvider::UltimateLyricsProvider()
: network_(new NetworkAccessManager(this)),
relevance_(0),
redirect_count_(0)
{
@ -57,10 +57,17 @@ void UltimateLyricsProvider::FetchInfo(int id, const Song& metadata) {
// Fetch the URL, follow redirects
redirect_count_ = 0;
network_->Get(url, this, "LyricsFetched", id);
QNetworkReply* reply = network_->get(QNetworkRequest(url));
requests_[reply] = id;
connect(reply, SIGNAL(finished()), SLOT(LyricsFetched()));
}
void UltimateLyricsProvider::LyricsFetched(quint64 id, QNetworkReply* reply) {
void UltimateLyricsProvider::LyricsFetched() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if (!reply)
return;
int id = requests_.take(reply);
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
@ -84,7 +91,9 @@ void UltimateLyricsProvider::LyricsFetched(quint64 id, QNetworkReply* reply) {
}
redirect_count_ ++;
network_->Get(target, this, "LyricsFetched", id);
QNetworkReply* reply = network_->get(QNetworkRequest(target));
requests_[reply] = id;
connect(reply, SIGNAL(finished()), SLOT(LyricsFetched()));
return;
}

View File

@ -31,7 +31,7 @@ class UltimateLyricsProvider : public SongInfoProvider {
Q_OBJECT
public:
UltimateLyricsProvider(NetworkAccessManager* network);
UltimateLyricsProvider();
static const int kRedirectLimit;
@ -58,7 +58,7 @@ public:
void FetchInfo(int id, const Song& metadata);
private slots:
void LyricsFetched(quint64 id, QNetworkReply* reply);
void LyricsFetched();
private:
void ApplyExtractRule(const Rule& rule, QString* content) const;
@ -74,6 +74,7 @@ private:
private:
NetworkAccessManager* network_;
QMap<QNetworkReply*, int> requests_;
QString name_;
QString title_;

View File

@ -21,9 +21,8 @@
#include <QFile>
#include <QXmlStreamReader>
UltimateLyricsReader::UltimateLyricsReader(NetworkAccessManager* network, QObject* parent)
: QObject(parent),
network_(network)
UltimateLyricsReader::UltimateLyricsReader(QObject* parent)
: QObject(parent)
{
}
@ -59,7 +58,7 @@ QList<SongInfoProvider*> UltimateLyricsReader::ParseDevice(QIODevice* device) co
SongInfoProvider* UltimateLyricsReader::ParseProvider(QXmlStreamReader* reader) const {
QXmlStreamAttributes attributes = reader->attributes();
UltimateLyricsProvider* scraper = new UltimateLyricsProvider(network_);
UltimateLyricsProvider* scraper = new UltimateLyricsProvider;
scraper->set_name(attributes.value("name").toString());
scraper->set_title(attributes.value("title").toString());
scraper->set_charset(attributes.value("charset").toString());

View File

@ -28,7 +28,7 @@ class UltimateLyricsReader : public QObject {
Q_OBJECT
public:
UltimateLyricsReader(NetworkAccessManager* network, QObject* parent = 0);
UltimateLyricsReader(QObject* parent = 0);
QList<SongInfoProvider*> Parse(const QString& filename) const;
QList<SongInfoProvider*> ParseDevice(QIODevice* device) const;
@ -37,9 +37,6 @@ private:
SongInfoProvider* ParseProvider(QXmlStreamReader* reader) const;
UltimateLyricsProvider::Rule ParseRule(QXmlStreamReader* reader) const;
QString ParseInvalidIndicator(QXmlStreamReader* reader) const;
private:
NetworkAccessManager* network_;
};
#endif // ULTIMATELYRICSREADER_H

View File

@ -41,15 +41,13 @@
const char* AlbumCoverManager::kSettingsGroup = "CoverManager";
AlbumCoverManager::AlbumCoverManager(NetworkAccessManager* network,
LibraryBackend* backend, QWidget *parent)
AlbumCoverManager::AlbumCoverManager(LibraryBackend* backend, QWidget *parent)
: QMainWindow(parent),
constructed_(false),
ui_(new Ui_CoverManager),
backend_(backend),
network_(network),
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this)),
cover_fetcher_(new AlbumCoverFetcher(network, this)),
cover_fetcher_(new AlbumCoverFetcher(this)),
cover_searcher_(new AlbumCoverSearcher(this)),
artist_icon_(IconLoader::Load("x-clementine-artist")),
all_artists_icon_(IconLoader::Load("x-clementine-album")),
@ -158,7 +156,6 @@ void AlbumCoverManager::Init() {
}
void AlbumCoverManager::CoverLoaderInitialised() {
cover_loader_->Worker()->SetNetwork(network_);
cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
SLOT(CoverImageLoaded(quint64,QImage)));

View File

@ -30,7 +30,6 @@
class LibraryBackend;
class AlbumCoverFetcher;
class AlbumCoverSearcher;
class NetworkAccessManager;
class Ui_CoverManager;
class QListWidgetItem;
@ -40,8 +39,7 @@ class QProgressBar;
class AlbumCoverManager : public QMainWindow {
Q_OBJECT
public:
AlbumCoverManager(NetworkAccessManager* network, LibraryBackend* backend,
QWidget *parent = 0);
AlbumCoverManager(LibraryBackend* backend, QWidget *parent = 0);
~AlbumCoverManager();
static const char* kSettingsGroup;
@ -125,7 +123,6 @@ class AlbumCoverManager : public QMainWindow {
QAction* filter_with_covers_;
QAction* filter_without_covers_;
NetworkAccessManager* network_;
BackgroundThread<AlbumCoverLoader>* cover_loader_;
QMap<quint64, QListWidgetItem*> cover_loading_tasks_;

View File

@ -121,12 +121,11 @@ const char* MainWindow::kMusicFilterSpec =
const char* MainWindow::kAllFilesFilterSpec =
QT_TR_NOOP("All Files (*)");
MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidget *parent)
MainWindow::MainWindow(Engine::Type engine, QWidget *parent)
: QMainWindow(parent),
ui_(new Ui_MainWindow),
network_(network),
tray_icon_(SystemTrayIcon::CreateSystemTrayIcon(this)),
osd_(new OSD(tray_icon_, network, this)),
osd_(new OSD(tray_icon_, this)),
task_manager_(new TaskManager(this)),
database_(new BackgroundThreadImplementation<Database, Database>(this)),
radio_model_(NULL),
@ -141,8 +140,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
file_view_(new FileView(this)),
radio_view_(new RadioViewContainer(this)),
device_view_(new DeviceView(this)),
song_info_view_(new SongInfoView(network, this)),
artist_info_view_(new ArtistInfoView(network, this)),
song_info_view_(new SongInfoView(this)),
artist_info_view_(new ArtistInfoView(this)),
settings_dialog_(NULL),
cover_manager_(NULL),
equalizer_(new Equalizer),
@ -169,7 +168,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
playlist_backend_->SetDatabase(database_->Worker());
// Create stuff that needs the database
radio_model_ = new RadioModel(database_, network, task_manager_, this);
radio_model_ = new RadioModel(database_, task_manager_, this);
player_ = new Player(playlists_, radio_model_->GetLastFMService(), engine, this);
library_ = new Library(database_, task_manager_, this);
devices_ = new DeviceManager(database_, task_manager_, this);
@ -519,7 +518,6 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(ui_->multi_loading_indicator, SIGNAL(TaskCountChange(int)), SLOT(TaskCountChanged(int)));
// Now playing widget
ui_->now_playing->set_network(network);
ui_->now_playing->set_ideal_height(ui_->status_bar->sizeHint().height() +
ui_->player_controls->sizeHint().height() +
1); // Don't question the 1
@ -1477,7 +1475,7 @@ void MainWindow::PlaylistCopyToDevice() {
void MainWindow::ShowCoverManager() {
if (!cover_manager_) {
cover_manager_.reset(new AlbumCoverManager(network_, library_->backend()));
cover_manager_.reset(new AlbumCoverManager(library_->backend()));
cover_manager_->Init();
// Cover manager connections

View File

@ -47,7 +47,6 @@ class GroupByDialog;
class Library;
class LibraryViewContainer;
class MultiLoadingIndicator;
class NetworkAccessManager;
class OrganiseDialog;
class OSD;
class Player;
@ -74,7 +73,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
Q_OBJECT
public:
MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidget *parent = 0);
MainWindow(Engine::Type engine, QWidget *parent = 0);
~MainWindow();
static const char* kSettingsGroup;
@ -203,7 +202,6 @@ class MainWindow : public QMainWindow, public PlatformInterface {
private:
Ui_MainWindow* ui_;
NetworkAccessManager* network_;
SystemTrayIcon* tray_icon_;
OSD* osd_;

View File

@ -16,7 +16,6 @@
#include "nowplayingwidget.h"
#include "core/albumcoverloader.h"
#include "core/networkaccessmanager.h"
#include <QMenu>
#include <QMovie>
@ -52,7 +51,6 @@ const int NowPlayingWidget::kTopBorder = 4;
NowPlayingWidget::NowPlayingWidget(QWidget *parent)
: QWidget(parent),
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this)),
network_(NULL),
mode_(SmallSongDetails),
menu_(new QMenu(this)),
above_statusbar_action_(NULL),
@ -118,7 +116,6 @@ QSize NowPlayingWidget::sizeHint() const {
void NowPlayingWidget::CoverLoaderInitialised() {
UpdateHeight();
cover_loader_->Worker()->SetNetwork(network_);
cover_loader_->Worker()->SetPadOutputImage(true);
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),
SLOT(AlbumArtLoaded(quint64,QImage)));

View File

@ -23,7 +23,6 @@
#include <QWidget>
class AlbumCoverLoader;
class NetworkAccessManager;
class QActionGroup;
class QMenu;
@ -52,7 +51,6 @@ public:
LargeSongDetails = 1,
};
void set_network(NetworkAccessManager* network) { network_ = network; }
void set_ideal_height(int height);
bool show_above_status_bar() const;
@ -93,7 +91,6 @@ private:
private:
BackgroundThread<AlbumCoverLoader>* cover_loader_;
NetworkAccessManager* network_;
Mode mode_;

View File

@ -28,7 +28,7 @@
const char* OSD::kSettingsGroup = "OSD";
OSD::OSD(SystemTrayIcon* tray_icon, NetworkAccessManager* network, QObject* parent)
OSD::OSD(SystemTrayIcon* tray_icon, QObject* parent)
: QObject(parent),
tray_icon_(tray_icon),
timeout_msec_(5000),
@ -38,7 +38,6 @@ OSD::OSD(SystemTrayIcon* tray_icon, NetworkAccessManager* network, QObject* pare
force_show_next_(false),
ignore_next_stopped_(false),
pretty_popup_(new OSDPretty(OSDPretty::Mode_Popup)),
network_(network),
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this))
{
cover_loader_->Start();
@ -54,7 +53,6 @@ OSD::~OSD() {
}
void OSD::CoverLoaderInitialised() {
cover_loader_->Worker()->SetNetwork(network_);
cover_loader_->Worker()->SetPadOutputImage(false);
cover_loader_->Worker()->SetDefaultOutputImage(QImage(":nocover.png"));
connect(cover_loader_->Worker().get(), SIGNAL(ImageLoaded(quint64,QImage)),

View File

@ -26,7 +26,6 @@
#include "core/backgroundthread.h"
#include "core/song.h"
class NetworkAccessManager;
class OrgFreedesktopNotificationsInterface;
class OSDPretty;
class SystemTrayIcon;
@ -45,7 +44,7 @@ class OSD : public QObject {
Q_OBJECT
public:
OSD(SystemTrayIcon* tray_icon, NetworkAccessManager* network, QObject* parent = 0);
OSD(SystemTrayIcon* tray_icon, QObject* parent = 0);
~OSD();
static const char* kSettingsGroup;
@ -118,7 +117,6 @@ class OSD : public QObject {
OSDPretty* pretty_popup_;
NetworkAccessManager* network_;
BackgroundThread<AlbumCoverLoader>* cover_loader_;
QMap<quint64, WaitingForAlbumArt> waiting_for_album_art_;

View File

@ -15,7 +15,7 @@
*/
#include "prettyimage.h"
#include "core/networkaccessmanager.h"
#include "core/network.h"
#include "ui/iconloader.h"
#include <QApplication>
@ -39,9 +39,9 @@ const int PrettyImage::kMaxImageWidth = 400;
const char* PrettyImage::kSettingsGroup = "PrettyImageView";
PrettyImage::PrettyImage(const QUrl& url, NetworkAccessManager* network, QWidget* parent)
PrettyImage::PrettyImage(const QUrl& url, QWidget* parent)
: QWidget(parent),
network_(network),
network_(new NetworkAccessManager(this)),
state_(State_WaitingForLazyLoad),
url_(url),
menu_(NULL)
@ -56,7 +56,8 @@ void PrettyImage::LazyLoad() {
return;
// Start fetching the image
network_->Get(url_, this, "ImageFetched", 0);
QNetworkReply* reply = network_->get(QNetworkRequest(url_));
connect(reply, SIGNAL(finished()), SLOT(ImageFetched()));
state_ = State_Loading;
}
@ -73,7 +74,8 @@ QSize PrettyImage::sizeHint() const {
return QSize(image_size().width(), kTotalHeight);
}
void PrettyImage::ImageFetched(quint64 id, QNetworkReply* reply) {
void PrettyImage::ImageFetched() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
reply->deleteLater();
QImage image = QImage::fromData(reply->readAll());

View File

@ -29,7 +29,7 @@ class PrettyImage : public QWidget {
Q_OBJECT
public:
PrettyImage(const QUrl& url, NetworkAccessManager* network, QWidget* parent = 0);
PrettyImage(const QUrl& url, QWidget* parent = 0);
static const int kTotalHeight;
static const int kReflectionHeight;
@ -55,7 +55,7 @@ protected:
void paintEvent(QPaintEvent*);
private slots:
void ImageFetched(quint64 id, QNetworkReply* reply);
void ImageFetched();
private:
enum State {

View File

@ -24,9 +24,8 @@
#include <QTimer>
#include <QtDebug>
PrettyImageView::PrettyImageView(NetworkAccessManager* network, QWidget* parent)
PrettyImageView::PrettyImageView(QWidget* parent)
: QScrollArea(parent),
network_(network),
container_(new QWidget(this)),
layout_(new QHBoxLayout(container_)),
current_index_(-1),
@ -54,7 +53,7 @@ PrettyImageView::PrettyImageView(NetworkAccessManager* network, QWidget* parent)
}
void PrettyImageView::AddImage(const QUrl& url) {
PrettyImage* image = new PrettyImage(url, network_, container_);
PrettyImage* image = new PrettyImage(url, container_);
connect(image, SIGNAL(destroyed()), SLOT(ScrollToCurrent()));
connect(image, SIGNAL(Loaded()), SLOT(ScrollToCurrent()));

View File

@ -21,8 +21,6 @@
#include <QScrollArea>
#include <QUrl>
class NetworkAccessManager;
class QHBoxLayout;
class QMenu;
class QNetworkReply;
@ -33,7 +31,7 @@ class PrettyImageView : public QScrollArea {
Q_OBJECT
public:
PrettyImageView(NetworkAccessManager* network, QWidget* parent = 0);
PrettyImageView(QWidget* parent = 0);
static const char* kSettingsGroup;
@ -51,8 +49,6 @@ private slots:
void ScrollToCurrent();
private:
NetworkAccessManager* network_;
QWidget* container_;
QHBoxLayout* layout_;