QtNetwork (examples) - update the second download manager example

It's the one that is more complex - with a text-based 'progress-bar'
and queueing (for some, probably educational, reason) of requests.

Changes:

- update the C++ syntax (mem-initializers, range for, etc.)
- new-style headers
- redirects should not result in creating an empty file.  Since we
  have no UI, and this example is already complex enough, settle
  for just reporting the redirect and removing the empty file.

Task-number: QTBUG-60628
Change-Id: I0b69cd77414ecac7c0bc6b2f8f787befc978de28
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Timur Pocheptsov 2017-09-27 15:33:25 +02:00
parent 42d7bc4c00
commit d892292409
5 changed files with 72 additions and 42 deletions

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@ -50,23 +50,21 @@
#include "downloadmanager.h"
#include <QFileInfo>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <stdio.h>
#include <QTextStream>
#include <cstdio>
using namespace std;
DownloadManager::DownloadManager(QObject *parent)
: QObject(parent), downloadedCount(0), totalCount(0)
: QObject(parent)
{
}
void DownloadManager::append(const QStringList &urlList)
void DownloadManager::append(const QStringList &urls)
{
foreach (QString url, urlList)
append(QUrl::fromEncoded(url.toLocal8Bit()));
for (const QString &urlAsString : urls)
append(QUrl::fromEncoded(urlAsString.toLocal8Bit()));
if (downloadQueue.isEmpty())
QTimer::singleShot(0, this, SIGNAL(finished()));
@ -167,9 +165,16 @@ void DownloadManager::downloadFinished()
if (currentDownload->error()) {
// download failed
fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
output.remove();
} else {
printf("Succeeded.\n");
++downloadedCount;
// let's check if it was actually a redirect
if (isHttpRedirect()) {
reportRedirect();
output.remove();
} else {
printf("Succeeded.\n");
++downloadedCount;
}
}
currentDownload->deleteLater();
@ -180,3 +185,28 @@ void DownloadManager::downloadReadyRead()
{
output.write(currentDownload->readAll());
}
bool DownloadManager::isHttpRedirect() const
{
int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
return statusCode == 301 || statusCode == 302 || statusCode == 303
|| statusCode == 305 || statusCode == 307 || statusCode == 308;
}
void DownloadManager::reportRedirect()
{
int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QUrl requestUrl = currentDownload->request().url();
QTextStream(stderr) << "Request: " << requestUrl.toDisplayString()
<< " was redirected with code: " << statusCode
<< '\n';
QVariant target = currentDownload->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (!target.isValid())
return;
QUrl redirectUrl = target.toUrl();
if (redirectUrl.isRelative())
redirectUrl = requestUrl.resolved(redirectUrl);
QTextStream(stderr) << "Redirected to: " << redirectUrl.toDisplayString()
<< '\n';
}

View File

@ -51,12 +51,8 @@
#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H
#include <QFile>
#include <QObject>
#include <QQueue>
#include <QTime>
#include <QUrl>
#include <QNetworkAccessManager>
#include <QtNetwork>
#include <QtCore>
#include "textprogressbar.h"
@ -64,11 +60,11 @@ class DownloadManager: public QObject
{
Q_OBJECT
public:
DownloadManager(QObject *parent = 0);
explicit DownloadManager(QObject *parent = nullptr);
void append(const QUrl &url);
void append(const QStringList &urlList);
QString saveFileName(const QUrl &url);
void append(const QStringList &urls);
static QString saveFileName(const QUrl &url);
signals:
void finished();
@ -80,15 +76,18 @@ private slots:
void downloadReadyRead();
private:
bool isHttpRedirect() const;
void reportRedirect();
QNetworkAccessManager manager;
QQueue<QUrl> downloadQueue;
QNetworkReply *currentDownload;
QNetworkReply *currentDownload = nullptr;
QFile output;
QTime downloadTime;
TextProgressBar progressBar;
int downloadedCount;
int totalCount;
int downloadedCount = 0;
int totalCount = 0;
};
#endif

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@ -50,11 +50,15 @@
#include <QCoreApplication>
#include <QStringList>
#include "downloadmanager.h"
#include <stdio.h>
#include <cstdio>
int main(int argc, char **argv)
{
using namespace std;
QCoreApplication app(argc, argv);
QStringList arguments = app.arguments();
arguments.takeFirst(); // remove the first argument, which is the program's name

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@ -49,22 +49,21 @@
****************************************************************************/
#include "textprogressbar.h"
#include <QByteArray>
#include <stdio.h>
TextProgressBar::TextProgressBar()
: value(0), maximum(-1), iteration(0)
{
}
#include <QByteArray>
#include <cstdio>
using namespace std;
void TextProgressBar::clear()
{
printf("\n");
fflush(stdout);
iteration = 0;
value = 0;
maximum = -1;
iteration = 0;
}
void TextProgressBar::update()

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@ -56,8 +56,6 @@
class TextProgressBar
{
public:
TextProgressBar();
void clear();
void update();
void setMessage(const QString &message);
@ -65,9 +63,9 @@ public:
private:
QString message;
qint64 value;
qint64 maximum;
int iteration;
qint64 value = 0;
qint64 maximum = -1;
int iteration = 0;
};
#endif