148 lines
3.9 KiB
C++
148 lines
3.9 KiB
C++
#ifndef FILEDOWNLOADER_H
|
|
#define FILEDOWNLOADER_H
|
|
|
|
#include <QObject>
|
|
#include <QByteArray>
|
|
#include <QNetworkAccessManager>
|
|
#include <QNetworkRequest>
|
|
#include <QNetworkReply>
|
|
#include <QTemporaryFile>
|
|
#ifdef QT_WIDGET
|
|
#include <QProgressDialog>
|
|
#include <QPushButton>
|
|
#include <QCoreApplication>
|
|
#else
|
|
#include <qdeclarative.h>
|
|
#endif //QT_WIDGET
|
|
|
|
|
|
class FileDownloader :
|
|
#ifdef QT_WIDGET
|
|
public QProgressDialog
|
|
#else
|
|
public QObject
|
|
#endif //QT_WIDGET
|
|
{
|
|
Q_OBJECT
|
|
|
|
Q_PROPERTY(qint64 received READ received NOTIFY receivedChanged)
|
|
Q_PROPERTY(QString status READ getStatus NOTIFY statusChanged)
|
|
Q_PROPERTY(DownloadState state READ getState NOTIFY stateChanged )
|
|
Q_PROPERTY(QString state_string READ getStateString NOTIFY stateStringChanged )
|
|
Q_ENUMS(DownloadState)
|
|
public:
|
|
enum DownloadState {
|
|
NETWORK_ERROR,
|
|
DOWNLOADING_HASH,
|
|
DOWNLOADING_FILE,
|
|
DOWNLOADED
|
|
} ;
|
|
|
|
explicit FileDownloader(QString localPath, QString targetFile, QObject *parent = 0);
|
|
virtual ~FileDownloader();
|
|
qint64 received() const {return m_received;};
|
|
QString getStatus() {return m_status;};
|
|
DownloadState getState() {
|
|
return m_state;
|
|
};
|
|
QString getStateString() {
|
|
if(m_state == DOWNLOADING_HASH )
|
|
return "DOWNLOADING_HASH";
|
|
else if(m_state == DOWNLOADING_FILE )
|
|
return "DOWNLOADING_FILE";
|
|
else
|
|
return "DOWNLOADED";
|
|
}
|
|
|
|
signals:
|
|
void receivedChanged(int value);
|
|
void statusChanged();
|
|
void stateChanged(DownloadState state);
|
|
void stateStringChanged();
|
|
|
|
private slots:
|
|
void fileDownloaded(){
|
|
// let's check some error
|
|
if(m_downloadReply->error() != QNetworkReply::NoError) {
|
|
m_state = NETWORK_ERROR;
|
|
} else {
|
|
if(m_tmp.write(m_downloadReply->readAll()) == -1) return;
|
|
if(QFile(m_localPath).exists())
|
|
QFile::remove(m_localPath);
|
|
|
|
m_tmp.close();
|
|
computeLocalHash(m_tmp);
|
|
if(m_localHash == m_remoteHash) {
|
|
if(!m_tmp.rename(m_localPath)) return;
|
|
m_tmp.setAutoRemove(false);
|
|
m_state = DOWNLOADED;
|
|
}
|
|
else {
|
|
m_state = NETWORK_ERROR;
|
|
}
|
|
}
|
|
emit stateChanged(m_state);
|
|
};
|
|
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal){
|
|
if(m_tmp.write(m_downloadReply->readAll()) == -1) return;
|
|
if(!bytesTotal) return;
|
|
m_received = bytesReceived*100/bytesTotal;
|
|
emit receivedChanged(m_received);
|
|
};
|
|
void setDownloadUrl(QUrl url);
|
|
void computeLocalHash(QFile& file);
|
|
void requestHash(QUrl url);
|
|
void computeRemoteHash();
|
|
void handleStateChange(DownloadState state){
|
|
#ifdef QT_WIDGET
|
|
switch(state) {
|
|
case NETWORK_ERROR:
|
|
if(m_localHash == "") {
|
|
setLabelText("Network Error");
|
|
setCancelButton(new QPushButton("OK"));
|
|
show();
|
|
} else {
|
|
emit finished(0);
|
|
}
|
|
break;
|
|
case DOWNLOADED:
|
|
emit finished(0);
|
|
break;
|
|
case DOWNLOADING_HASH:
|
|
break;
|
|
case DOWNLOADING_FILE:
|
|
show();
|
|
break;
|
|
}
|
|
|
|
#else
|
|
emit stateStringChanged();
|
|
#endif //QT_WIDGET
|
|
};
|
|
#ifdef QT_WIDGET
|
|
void handleCancel(){
|
|
QCoreApplication::instance()->exit(1);
|
|
}
|
|
#endif //QT_WIDGET
|
|
|
|
|
|
private:
|
|
DownloadState m_state;
|
|
QNetworkAccessManager m_WebCtrl;
|
|
qint64 m_received;
|
|
QTemporaryFile m_tmp;
|
|
QString m_targetFile;
|
|
QString m_localPath;
|
|
QString m_localHash;
|
|
QString m_remoteHash;
|
|
bool m_OK;
|
|
QString m_status;
|
|
QNetworkReply* m_downloadReply;
|
|
QNetworkReply* m_hashReply;
|
|
};
|
|
#ifndef QT_WIDGET
|
|
QML_DECLARE_TYPEINFO(FileDownloader, QML_HAS_ATTACHED_PROPERTIES)
|
|
#endif //QT_WIDGET
|
|
|
|
#endif // FILEDOWNLOADER_H
|