summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.cpp262
-rw-r--r--installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.h19
-rw-r--r--installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader_p.h3
3 files changed, 254 insertions, 30 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.cpp b/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.cpp
index 59fd625e5..b6b316ca8 100644
--- a/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.cpp
+++ b/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.cpp
@@ -39,6 +39,9 @@
#include <QThreadPool>
#include <QDebug>
+#include <QBasicTimer>
+#include <QTimerEvent>
+
using namespace KDUpdater;
static double calcProgress(qint32 done, qint32 total)
@@ -46,6 +49,20 @@ static double calcProgress(qint32 done, qint32 total)
return total ? (double(done) / double(total)) : 0 ;
}
+static QString format(double data)
+{
+ if (data < 1024.0)
+ return KDUpdater::FileDownloader::tr("%L1 B").arg(data);
+ data /= 1024.0;
+ if (data < 1024.0)
+ return KDUpdater::FileDownloader::tr("%L1 KB").arg(data, 0, 'f', 2);
+ data /= 1024.0;
+ if (data < 1024.0)
+ return KDUpdater::FileDownloader::tr("%L1 MB").arg(data, 0, 'f', 2);
+ data /= 1024.0;
+ return KDUpdater::FileDownloader::tr("%L1 GB").arg(data, 0, 'f', 2);
+}
+
QByteArray KDUpdater::calculateHash( QIODevice* device, QCryptographicHash::Algorithm algo ) {
Q_ASSERT( device );
QCryptographicHash hash( algo );
@@ -180,7 +197,13 @@ QString downloadedFile = downloader->downloadedFileName();
struct KDUpdater::FileDownloader::FileDownloaderData
{
- FileDownloaderData() : autoRemove( true ) {
+ FileDownloaderData()
+ : autoRemove( true )
+ , m_bytesReceived(0)
+ , m_bytesToReceive(0)
+ , m_downloadSpeed(0)
+ {
+ memset(m_samples, 0, sizeof(m_samples));
}
QUrl url;
@@ -189,6 +212,15 @@ struct KDUpdater::FileDownloader::FileDownloaderData
QString errorString;
bool autoRemove;
bool followRedirect;
+
+ QTime m_time;
+ QBasicTimer m_timer;
+
+ qint64 m_bytesReceived;
+ qint64 m_bytesToReceive;
+
+ mutable qint64 m_samples[10];
+ mutable qint64 m_downloadSpeed;
};
KDUpdater::FileDownloader::FileDownloader(const QString& scheme, QObject* parent)
@@ -297,6 +329,113 @@ void KDUpdater::FileDownloader::cancelDownload()
// Do nothing
}
+void KDUpdater::FileDownloader::runDownloadSpeedTimer()
+{
+ if (!d->m_timer.isActive()) {
+ d->m_time.start();
+ d->m_timer.start(500, this);
+ }
+}
+
+void KDUpdater::FileDownloader::stopDownloadSpeedTimer()
+{
+ d->m_timer.stop();
+}
+
+void KDUpdater::FileDownloader::addSample(qint64 sample)
+{
+ d->m_samples[0] += sample;
+}
+
+int KDUpdater::FileDownloader::downloadSpeedTimerId() const
+{
+ return d->m_timer.timerId();
+}
+
+void KDUpdater::FileDownloader::setProgress(qint64 bytesReceived, qint64 bytesToReceive)
+{
+ d->m_bytesReceived = bytesReceived;
+ d->m_bytesToReceive = bytesToReceive;
+}
+
+void KDUpdater::FileDownloader::emitDownloadSpeed()
+{
+ for (int i = 8; i >= 0; --i)
+ d->m_samples[i + 1] = d->m_samples[i];
+ d->m_samples[0] = 0;
+
+ d->m_downloadSpeed = 0;
+ for (unsigned int i = 0; i < sizeof(d->m_samples) / sizeof(qint64); ++i)
+ d->m_downloadSpeed += d->m_samples[i];
+ d->m_downloadSpeed /= (sizeof(d->m_samples) / sizeof(qint64) - 1) * 0.5;
+
+ emit downloadSpeed(d->m_downloadSpeed);
+}
+
+void KDUpdater::FileDownloader::emitDownloadStatus()
+{
+ QString status;
+ if (d->m_bytesToReceive > 0) {
+ QString bytesReceived = format(d->m_bytesReceived);
+ const QString bytesToReceive = format(d->m_bytesToReceive);
+
+ const QString tmp = bytesToReceive.mid(bytesToReceive.indexOf(QLatin1Char(' ')));
+ if (bytesReceived.endsWith(tmp))
+ bytesReceived.chop(tmp.length());
+
+ status = bytesReceived + tr(" of ") + bytesToReceive;
+ } else {
+ if (d->m_bytesReceived > 0)
+ status = format(d->m_bytesReceived) + tr(" downloaded.");
+ }
+
+ status += QLatin1String(" (") + format(d->m_downloadSpeed) + tr("/sec") + QLatin1Char(')');
+ if (d->m_bytesToReceive > 0 && d->m_downloadSpeed > 0) {
+ const qint64 time = (d->m_bytesToReceive - d->m_bytesReceived) / d->m_downloadSpeed;
+
+ int s = time % 60;
+ const int d = time / 86400;
+ const int h = (time / 3600) - (d * 24);
+ const int m = (time / 60) - (d * 1440) - (h * 60);
+
+ QString days;
+ if (d > 0)
+ days = QString::number(d) + (d < 2 ? tr(" day") : tr(" days")) + QLatin1String(", ");
+
+ QString hours;
+ if (h > 0)
+ hours = QString::number(h) + (h < 2 ? tr(" hour") : tr(" hours")) + QLatin1String(", ");
+
+ QString minutes;
+ if (m > 0)
+ minutes = QString::number(m) + (m < 2 ? tr(" minute") : tr(" minutes"));
+
+ QString seconds;
+ if (s >= 0 && minutes.isEmpty()) {
+ s = (s <= 0 ? 1 : s);
+ seconds = QString::number(s) + (s < 2 ? tr(" second") : tr(" seconds"));
+ }
+ status += tr(" - ") + days + hours + minutes + seconds + tr(" remaining.");
+ } else {
+ status += tr(" - unknown time remaining.");
+ }
+
+ emit downloadStatus(status);
+}
+
+void KDUpdater::FileDownloader::emitDownloadProgress()
+{
+ emit downloadProgress(d->m_bytesReceived, d->m_bytesToReceive);
+}
+
+void KDUpdater::FileDownloader::emitEstimatedDownloadTime()
+{
+ if (d->m_bytesToReceive <= 0 || d->m_downloadSpeed <= 0) {
+ emit estimatedDownloadTime(-1);
+ return;
+ }
+ emit estimatedDownloadTime((d->m_bytesToReceive - d->m_bytesReceived) / d->m_downloadSpeed);
+}
////////////////////////////////////////////////////////////////////////////
@@ -392,8 +531,10 @@ void KDUpdater::LocalFileDownloader::doDownload()
return;
}
+ runDownloadSpeedTimer();
// Start a timer and kickoff the copy process
d->timerId = startTimer(0); // as fast as possible
+
emit downloadStarted();
emit downloadProgress(0);
}
@@ -425,39 +566,48 @@ void KDUpdater::LocalFileDownloader::cancelDownload()
emit downloadCanceled();
}
-void KDUpdater::LocalFileDownloader::timerEvent(QTimerEvent*)
+void KDUpdater::LocalFileDownloader::timerEvent(QTimerEvent *event)
{
- if( !d->source || !d->destination )
- return;
+ if (event->timerId() == d->timerId) {
+ if( !d->source || !d->destination )
+ return;
- const qint64 blockSize = 32768;
- QByteArray buffer;
- buffer.resize( blockSize );
- const qint64 numRead = d->source->read( buffer.data(), buffer.size() );
- qint64 toWrite = numRead;
- while ( toWrite > 0 ) {
- const qint64 numWritten = d->destination->write( buffer.constData() + numRead - toWrite, toWrite );
- if ( numWritten < 0 ) {
- killTimer( d->timerId );
- d->timerId = -1;
- onError();
- setDownloadAborted( tr("Writing to %1 failed: %2").arg( d->destination->fileName(), d->destination->errorString() ) );
+ const qint64 blockSize = 32768;
+ QByteArray buffer;
+ buffer.resize( blockSize );
+ const qint64 numRead = d->source->read( buffer.data(), buffer.size() );
+ qint64 toWrite = numRead;
+ while ( toWrite > 0 ) {
+ const qint64 numWritten = d->destination->write( buffer.constData() + numRead - toWrite, toWrite );
+ if ( numWritten < 0 ) {
+ killTimer( d->timerId );
+ d->timerId = -1;
+ onError();
+ setDownloadAborted( tr("Writing to %1 failed: %2").arg( d->destination->fileName(), d->destination->errorString() ) );
+ return;
+ }
+ toWrite -= numWritten;
+ }
+ addSample(numRead);
+
+ if( numRead > 0 ) {
+ setProgress(d->source->pos(), d->source->size());
+ emit downloadProgress( calcProgress(d->source->pos(), d->source->size()) );
return;
}
- toWrite -= numWritten;
- }
- if( numRead > 0 ) {
- emit downloadProgress( calcProgress(d->source->pos(), d->source->size()) );
- return;
- }
-
- d->destination->flush();
+ d->destination->flush();
- killTimer( d->timerId );
- d->timerId = -1;
+ killTimer( d->timerId );
+ d->timerId = -1;
- setDownloadCompleted( d->destination->fileName() );
+ setDownloadCompleted( d->destination->fileName() );
+ } else if (event->timerId() == downloadSpeedTimerId()) {
+ emitDownloadSpeed();
+ emitDownloadStatus();
+ emitDownloadProgress();
+ emitEstimatedDownloadTime();
+ }
}
void LocalFileDownloader::onSuccess()
@@ -471,6 +621,7 @@ void LocalFileDownloader::onSuccess()
d->destination = 0;
delete d->source;
d->source = 0;
+ stopDownloadSpeedTimer();
}
void LocalFileDownloader::onError()
@@ -481,6 +632,7 @@ void LocalFileDownloader::onError()
d->destination = 0;
delete d->source;
d->source = 0;
+ stopDownloadSpeedTimer();
}
struct KDUpdater::ResourceFileDownloader::ResourceFileDownloaderData
@@ -641,6 +793,7 @@ void KDUpdater::FtpDownloader::doDownload()
connect(d->ftp, SIGNAL(commandFinished(int,bool)), this, SLOT(ftpCmdFinished(int,bool)));
connect(d->ftp, SIGNAL(stateChanged(int)), this, SLOT(ftpStateChanged(int)));
connect(d->ftp, SIGNAL(dataTransferProgress(qint64,qint64)), this, SLOT(ftpDataTransferProgress(qint64,qint64)));
+ connect(d->ftp, SIGNAL(readyRead()), this, SLOT(ftpReadyRead()));
d->ftp->connectToHost( url().host(), url().port(21) );
d->ftp->login();
@@ -723,6 +876,7 @@ void FtpDownloader::onSuccess()
file->setAutoRemove( false );
delete d->destination;
d->destination = 0;
+ stopDownloadSpeedTimer();
}
@@ -732,7 +886,7 @@ void FtpDownloader::onError()
d->destFileName.clear();
delete d->destination;
d->destination = 0;
-
+ stopDownloadSpeedTimer();
}
void KDUpdater::FtpDownloader::ftpStateChanged(int state)
@@ -749,8 +903,10 @@ void KDUpdater::FtpDownloader::ftpStateChanged(int state)
d->destination = new QFile(d->destFileName, this);
d->destination->open(QIODevice::ReadWrite | QIODevice::Truncate);
}
- d->ftpCmdId = d->ftp->get( url().path(), d->destination );
+ runDownloadSpeedTimer();
+ d->ftpCmdId = d->ftp->get(url().path());
break;
+
case QFtp::Unconnected:
// download was unconditionally aborted
disconnect(d->ftp, 0, this, 0);
@@ -765,9 +921,40 @@ void KDUpdater::FtpDownloader::ftpStateChanged(int state)
void KDUpdater::FtpDownloader::ftpDataTransferProgress(qint64 done, qint64 total)
{
+ setProgress(done, total);
emit downloadProgress( calcProgress(done, total) );
}
+void KDUpdater::FtpDownloader::ftpReadyRead()
+{
+ static QByteArray buffer(16384, '\0');
+ while (d->ftp->bytesAvailable()) {
+ const qint64 read = d->ftp->read(buffer.data(), buffer.size());
+ qint64 written = 0;
+ while (written < read) {
+ const qint64 numWritten = d->destination->write(buffer.data() + written, read - written);
+ if (numWritten < 0) {
+ onError();
+ setDownloadAborted(tr("Cannot download %1: Writing to temporary file failed: %2")
+ .arg(url().toString(), d->destination->errorString()));
+ return;
+ }
+ written += numWritten;
+ }
+ addSample(written);
+ }
+}
+
+void KDUpdater::FtpDownloader::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == downloadSpeedTimerId()) {
+ emitDownloadSpeed();
+ emitDownloadStatus();
+ emitDownloadProgress();
+ emitEstimatedDownloadTime();
+ }
+}
+
////////////////////////////////////////////////////////////////////////////
// KDUpdater::FileDownloader
////////////////////////////////////////////////////////////////////////////
@@ -829,6 +1016,8 @@ void KDUpdater::HttpDownloader::doDownload()
if( d->http )
return;
+ runDownloadSpeedTimer();
+
d->http = d->manager.get( QNetworkRequest( url() ) );
connect( d->http, SIGNAL( readyRead() ), this, SLOT( httpReadyRead() ) );
@@ -894,6 +1083,7 @@ void KDUpdater::HttpDownloader::httpReadyRead()
}
written += numWritten;
}
+ addSample(written);
}
}
@@ -955,6 +1145,7 @@ void KDUpdater::HttpDownloader::onError()
d->destFileName.clear();
delete d->destination;
d->destination = 0;
+ stopDownloadSpeedTimer();
}
void KDUpdater::HttpDownloader::onSuccess()
@@ -965,6 +1156,7 @@ void KDUpdater::HttpDownloader::onSuccess()
file->setAutoRemove( false );
delete d->destination;
d->destination = 0;
+ stopDownloadSpeedTimer();
}
void KDUpdater::HttpDownloader::httpReqFinished()
@@ -1013,9 +1205,21 @@ void KDUpdater::HttpDownloader::httpReqFinished()
void KDUpdater::HttpDownloader::httpReadProgress( qint64 done, qint64 total)
{
+ setProgress(done, total);
emit downloadProgress( calcProgress( done, total ) );
}
+void KDUpdater::HttpDownloader::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == downloadSpeedTimerId()) {
+ emitDownloadSpeed();
+ emitDownloadStatus();
+ emitDownloadProgress();
+ emitEstimatedDownloadTime();
+ }
+}
+
+
class SignatureVerificationDownloader::Private
{
SignatureVerificationDownloader* const q;
diff --git a/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.h b/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.h
index 00ca58c1a..c66470588 100644
--- a/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.h
+++ b/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader.h
@@ -80,10 +80,15 @@ namespace KDUpdater
virtual void onSuccess() = 0;
Q_SIGNALS:
- void downloadProgress(double);
void downloadStarted();
void downloadCanceled();
+ void downloadProgress(double progress);
+ void estimatedDownloadTime(int seconds);
+ void downloadSpeed(qint64 bytesPerSecond);
+ void downloadStatus(const QString &status);
+ void downloadProgress(qint64 bytesReceived, qint64 bytesToReceive);
+
#ifndef Q_MOC_RUN
private:
#endif
@@ -94,6 +99,18 @@ namespace KDUpdater
void setDownloadCompleted( const QString& filepath );
void setDownloadAborted( const QString& error );
+ void runDownloadSpeedTimer();
+ void stopDownloadSpeedTimer();
+
+ void addSample(qint64 sample);
+ int downloadSpeedTimerId() const;
+ void setProgress(qint64 bytesReceived, qint64 bytesToReceive);
+
+ void emitDownloadSpeed();
+ void emitDownloadStatus();
+ void emitDownloadProgress();
+ void emitEstimatedDownloadTime();
+
private Q_SLOTS:
virtual void doDownload() = 0;
diff --git a/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader_p.h b/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader_p.h
index 06d3b9734..a0cc75597 100644
--- a/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader_p.h
+++ b/installerbuilder/libinstaller/3rdparty/kdtools/KDUpdater/kdupdaterfiledownloader_p.h
@@ -152,6 +152,7 @@ namespace KDUpdater
protected:
/* reimp */ void onError();
/* reimp */ void onSuccess();
+ void timerEvent(QTimerEvent *event);
private Q_SLOTS:
/* reimp */ void doDownload();
@@ -160,6 +161,7 @@ namespace KDUpdater
void ftpCmdFinished(int id, bool error);
void ftpStateChanged(int state);
void ftpDataTransferProgress(qint64 done, qint64 total);
+ void ftpReadyRead();
private:
struct FtpDownloaderData;
@@ -186,6 +188,7 @@ namespace KDUpdater
protected:
/* reimp */ void onError();
/* reimp */ void onSuccess();
+ void timerEvent(QTimerEvent *event);
private Q_SLOTS:
/* reimp */ void doDownload();