8#include "HttpDownloadManager.h"
10#include <QCoreApplication>
13#include <QNetworkAccessManager>
16#include "DownloadPolicy.h"
17#include "DownloadQueueSet.h"
19#include "MarbleDebug.h"
20#include "StoragePolicy.h"
25const quint32 requeueTime = 60000;
30 Private(HttpDownloadManager *parent, StoragePolicy *policy);
33 void connectDefaultQueueSets();
34 void connectQueueSet(DownloadQueueSet *);
35 bool hasDownloadPolicy(
const DownloadPolicy &policy)
const;
36 void finishJob(
const QByteArray &,
const QString &,
const QString &
id);
38 void startRetryTimer();
40 DownloadQueueSet *findQueues(
const QString &hostName,
const DownloadUsage usage);
42 HttpDownloadManager *m_downloadManager;
43 QTimer m_requeueTimer;
49 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>> m_queueSets;
50 QMap<DownloadUsage, DownloadQueueSet *> m_defaultQueueSets;
51 StoragePolicy *
const m_storagePolicy;
52 QNetworkAccessManager m_networkAccessManager;
57 : m_downloadManager(parent)
59 , m_storagePolicy(policy)
60 , m_networkAccessManager()
64 DownloadPolicy defaultBrowsePolicy;
65 defaultBrowsePolicy.setMaximumConnections(20);
67 DownloadPolicy defaultBulkDownloadPolicy;
68 defaultBulkDownloadPolicy.setMaximumConnections(2);
72HttpDownloadManager::Private::~Private()
74 QMap<DownloadUsage, DownloadQueueSet *>::iterator pos = m_defaultQueueSets.begin();
75 QMap<DownloadUsage, DownloadQueueSet *>::iterator
const end = m_defaultQueueSets.end();
76 for (; pos !=
end; ++pos)
80DownloadQueueSet *HttpDownloadManager::Private::findQueues(
const QString &hostName,
const DownloadUsage usage)
82 DownloadQueueSet *result =
nullptr;
83 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>>::iterator pos = m_queueSets.begin();
84 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>>::iterator
const end = m_queueSets.end();
85 for (; pos !=
end; ++pos) {
86 if ((*pos).first.matches(hostName, usage)) {
87 result = (*pos).second;
92 mDebug() <<
"No download policy found for" << hostName << usage <<
", using default policy.";
93 result = m_defaultQueueSets[usage];
99 : d(new Private(this, policy))
101 d->m_requeueTimer.setInterval(requeueTime);
102 connect(&d->m_requeueTimer, SIGNAL(timeout()),
this, SLOT(requeue()));
103 d->connectDefaultQueueSets();
117 d->m_acceptJobs = enable;
120 for (; pos != end; ++pos) {
121 pos->second->purgeJobs();
125void HttpDownloadManager::addDownloadPolicy(
const DownloadPolicy &policy)
127 if (d->hasDownloadPolicy(policy))
130 d->connectQueueSet(queueSet);
131 d->m_queueSets.append(QPair<DownloadPolicyKey, DownloadQueueSet *>(queueSet->downloadPolicy().key(), queueSet));
136 if (!d->m_acceptJobs) {
137 mDebug() <<
"Working offline, not adding job";
142 if (queueSet->canAcceptJob(sourceUrl, destFileName)) {
143 auto const job =
new HttpJob(sourceUrl, destFileName,
id, &d->m_networkAccessManager);
144 job->setUserAgentPluginId(QStringLiteral(
"QNamNetworkPlugin"));
145 job->setDownloadUsage(usage);
146 mDebug() <<
"adding job " << sourceUrl;
147 queueSet->addJob(job);
151void HttpDownloadManager::Private::finishJob(
const QByteArray &data,
const QString &destinationFileName,
const QString &
id)
153 mDebug() <<
"emitting downloadComplete( QByteArray, " <<
id <<
")";
154 Q_EMIT m_downloadManager->downloadComplete(data,
id);
155 if (m_storagePolicy) {
156 const bool saved = m_storagePolicy->updateFile(destinationFileName, data);
158 mDebug() <<
"emitting downloadComplete( " << destinationFileName <<
", " <<
id <<
")";
159 Q_EMIT m_downloadManager->downloadComplete(destinationFileName,
id);
161 qWarning() <<
"Could not save:" << destinationFileName;
166void HttpDownloadManager::Private::requeue()
168 m_requeueTimer.stop();
170 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>>::iterator pos = m_queueSets.
begin();
171 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>>::iterator
const end = m_queueSets.end();
172 for (; pos !=
end; ++pos) {
173 (*pos).second->retryJobs();
177void HttpDownloadManager::Private::startRetryTimer()
179 if (!m_requeueTimer.isActive())
180 m_requeueTimer.start();
183void HttpDownloadManager::Private::connectDefaultQueueSets()
185 QMap<DownloadUsage, DownloadQueueSet *>::iterator pos = m_defaultQueueSets.
begin();
186 QMap<DownloadUsage, DownloadQueueSet *>::iterator
const end = m_defaultQueueSets.end();
187 for (; pos !=
end; ++pos)
188 connectQueueSet(pos.value());
191void HttpDownloadManager::Private::connectQueueSet(DownloadQueueSet *queueSet)
193 connect(queueSet, SIGNAL(jobFinished(QByteArray, QString, QString)), m_downloadManager, SLOT(finishJob(QByteArray, QString, QString)));
194 connect(queueSet, SIGNAL(jobRetry()), m_downloadManager, SLOT(startRetryTimer()));
202bool HttpDownloadManager::Private::hasDownloadPolicy(
const DownloadPolicy &policy)
const
205 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>>::const_iterator pos = m_queueSets.constBegin();
206 QList<QPair<DownloadPolicyKey, DownloadQueueSet *>>::const_iterator
const end = m_queueSets.constEnd();
207 for (; pos !=
end; ++pos) {
208 if ((*pos).second->downloadPolicy() == policy) {
216QByteArray HttpDownloadManager::userAgent(
const QString &platform,
const QString &component)
218 QString result(QStringLiteral(
"Mozilla/5.0 (compatible; Marble/%1; %2; %3; %4; %5)"));
219 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
220 QString
const device = smallScreen ? QStringLiteral(
"MobileDevice") : QStringLiteral(
"DesktopDevice");
222 result = result.arg(
QString::fromLatin1(MARBLE_VERSION_STRING), device, platform, component, app);
223 return result.toLatin1();
226#include "moc_HttpDownloadManager.cpp"
This class manages scheduled downloads.
void jobRemoved()
Signal is emitted when a job is removed from the queue.
void setDownloadEnabled(const bool enable)
Switches loading on/off, useful for offline mode.
void jobAdded()
Signal is emitted when a new job is added to the queue.
~HttpDownloadManager() override
Destroys the http download manager.
HttpDownloadManager(StoragePolicy *policy)
Creates a new http download manager.
void addJob(const QUrl &sourceUrl, const QString &destFilename, const QString &id, const DownloadUsage usage)
Adds a new job with a sourceUrl, destination file name and given id.
void progressChanged(int active, int queued)
A job was queued, activated or removed (finished, failed)
const QList< QKeySequence > & end()
Binds a QML item to a specific geodetic location in screen coordinates.
DownloadUsage
This enum is used to describe the type of download.
@ DownloadBrowse
Browsing mode, normal operation of Marble, like a web browser.
@ DownloadBulk
Bulk download, for example "File/Download region".
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString fromLatin1(QByteArrayView str)
QString host(ComponentFormattingOptions options) const const