Refactored http download code.

This commit is contained in:
Leonardo Zide 2018-04-14 11:44:39 -07:00
parent 7f6a7d82ae
commit 900456ca31
7 changed files with 193 additions and 166 deletions

92
common/lc_http.cpp Normal file
View file

@ -0,0 +1,92 @@
#include "lc_global.h"
#include "lc_http.h"
#ifdef Q_OS_WIN
#include <wininet.h>
lcHttpReply::lcHttpReply(QObject* Parent, const QString& URL)
: QThread(Parent)
{
mError = true;
mAbort = false;
mURL = URL;
}
void lcHttpReply::run()
{
HINTERNET Session = nullptr;
HINTERNET Request = nullptr;
if (sizeof(wchar_t) != sizeof(QChar))
return;
Session = InternetOpen(L"LeoCAD", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!Session)
return;
Request = InternetOpenUrl(Session, (WCHAR*)mURL.data(), NULL, 0, 0, 0);
if (!Request)
{
InternetCloseHandle(Session);
return;
}
for (;;)
{
char Buffer[1024];
DWORD BytesRead;
if (mAbort)
break;
if (!InternetReadFile(Request, Buffer, sizeof(Buffer), &BytesRead))
break;
if (BytesRead)
mBuffer.append(Buffer, BytesRead);
else
{
mError = false;
break;
}
Sleep(0);
}
InternetCloseHandle(Request);
InternetCloseHandle(Session);
}
lcHttpManager::lcHttpManager(QObject* Owner)
: QObject(Owner)
{
}
lcHttpReply* lcHttpManager::DownloadFile(const QString& Url)
{
lcHttpReply* Reply = new lcHttpReply(this, Url);
connect(Reply, &QThread::finished, [this, Reply] { emit DownloadFinished(Reply); });
Reply->start();
return Reply;
}
#else
lcHttpManager::lcHttpManager(QObject* Owner)
: QNetworkAccessManager(Owner)
{
connect(this, SIGNAL(finished(QNetworkReply*)), this, SLOT(Finished(QNetworkReply*)));
}
lcHttpReply* lcHttpManager::lcHttpManager::DownloadFile(const QString& Url)
{
return mNetworkManager.get(QNetworkRequest(QUrl(Url)));
}
void lcHttpManager::Finished(QNetworkReply* Reply)
{
emit DownloadFinished(Reply);
}
#endif

72
common/lc_http.h Normal file
View file

@ -0,0 +1,72 @@
#pragma once
#include <QNetworkRequest>
#include <QNetworkReply>
#ifdef Q_OS_WIN
class lcHttpReply : public QThread
{
Q_OBJECT
public:
lcHttpReply(QObject* Parent, const QString& URL);
void run();
bool error() const
{
return mError;
}
void abort()
{
mAbort = true;
}
QByteArray readAll() const
{
return mBuffer;
}
protected:
bool mError;
bool mAbort;
QByteArray mBuffer;
QString mURL;
};
class lcHttpManager : public QObject
{
Q_OBJECT
public:
lcHttpManager(QObject* Owner = nullptr);
lcHttpReply* DownloadFile(const QString& Url);
signals:
void DownloadFinished(lcHttpReply* Reply);
};
#else
typedef QNetworkReply lcHttpReply;
class lcHttpManager : public QNetworkAccessManager
{
Q_OBJECT
public:
lcHttpManager(QObject* Owner = nullptr);
lcHttpReply* DownloadFile(const QString& Url);
signals:
void DownloadFinished(lcHttpReply* Reply);
protected slots:
void Finished(QNetworkReply* Reply);
};
#endif

View file

@ -139,8 +139,9 @@ SOURCES += common/view.cpp \
common/lc_context.cpp \
common/lc_file.cpp \
common/lc_glextensions.cpp \
common/lc_http.cpp \
common/lc_library.cpp \
common/lc_lxf.cpp \
common/lc_lxf.cpp \
common/lc_mainwindow.cpp \
common/lc_mesh.cpp \
common/lc_model.cpp \
@ -175,7 +176,7 @@ SOURCES += common/view.cpp \
qt/lc_qcolorlist.cpp \
qt/lc_qfinddialog.cpp \
qt/lc_qmodellistdialog.cpp \
common/lc_partselectionwidget.cpp \
common/lc_partselectionwidget.cpp \
common/lc_timelinewidget.cpp \
qt/lc_renderdialog.cpp \
qt/lc_setsdatabasedialog.cpp
@ -200,8 +201,9 @@ HEADERS += \
common/lc_glextensions.h \
common/lc_global.h \
common/lc_glwidget.h \
common/lc_http.h \
common/lc_library.h \
common/lc_lxf.h \
common/lc_lxf.h \
common/lc_mainwindow.h \
common/lc_math.h \
common/lc_mesh.h \
@ -235,7 +237,7 @@ HEADERS += \
qt/lc_qcolorlist.h \
qt/lc_qfinddialog.h \
qt/lc_qmodellistdialog.h \
common/lc_partselectionwidget.h \
common/lc_partselectionwidget.h \
common/lc_timelinewidget.h \
qt/lc_renderdialog.h \
qt/lc_setsdatabasedialog.h

View file

@ -4,6 +4,7 @@
#include "lc_application.h"
#include "lc_library.h"
#include "lc_profile.h"
#include "lc_http.h"
void lcDoInitialUpdateCheck()
{
@ -39,23 +40,14 @@ lcQUpdateDialog::lcQUpdateDialog(QWidget* Parent, bool InitialUpdate)
ui->status->setText(tr("Connecting to update server..."));
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
mHttpManager = new lcHttpManager(this);
connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*)));
updateReply = manager->get(QNetworkRequest(QUrl("https://www.leocad.org/updates.txt")));
mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/updates.txt"));
}
lcQUpdateDialog::~lcQUpdateDialog()
{
if (updateReply)
{
updateReply->abort();
updateReply->deleteLater();
}
if (manager)
manager->deleteLater();
delete ui;
}
@ -69,13 +61,6 @@ void lcQUpdateDialog::accept()
void lcQUpdateDialog::reject()
{
if (updateReply)
{
updateReply->abort();
updateReply->deleteLater();
updateReply = nullptr;
}
QDialog::reject();
}
@ -87,7 +72,7 @@ void lcQUpdateDialog::finished(int result)
deleteLater();
}
void lcQUpdateDialog::replyFinished(QNetworkReply *reply)
void lcQUpdateDialog::DownloadFinished(lcHttpReply *reply)
{
bool updateAvailable = false;
@ -156,9 +141,6 @@ void lcQUpdateDialog::replyFinished(QNetworkReply *reply)
#else
settings.setValue("Updates/LastCheck", QDateTime::currentDateTime());
#endif
updateReply = nullptr;
reply->deleteLater();
}
else
ui->status->setText(tr("Error connecting to the update server."));

View file

@ -1,7 +1,9 @@
#pragma once
#include <QDialog>
#include <QNetworkReply>
class lcHttpReply;
class lcHttpManager;
namespace Ui {
class lcQUpdateDialog;
@ -20,7 +22,7 @@ public:
void parseUpdate(const char *update);
public slots:
void replyFinished(QNetworkReply *reply);
void DownloadFinished(lcHttpReply* Reply);
void accept();
void reject();
void finished(int result);
@ -28,8 +30,7 @@ public slots:
private:
Ui::lcQUpdateDialog *ui;
QNetworkReply *updateReply;
QNetworkAccessManager *manager;
lcHttpManager* mHttpManager;
QByteArray versionData;
bool mInitialUpdate;
};

View file

@ -1,63 +1,7 @@
#include "lc_global.h"
#include "lc_setsdatabasedialog.h"
#include "ui_lc_setsdatabasedialog.h"
#include <QNetworkRequest>
#include <QNetworkReply>
#ifdef Q_OS_WIN
lcHttpReply::lcHttpReply(QObject* Parent, const QString& URL)
: QThread(Parent)
{
mError = true;
mAbort = false;
mURL = URL;
}
void lcHttpReply::run()
{
HINTERNET Session = nullptr;
HINTERNET Request = nullptr;
if (sizeof(wchar_t) != sizeof(QChar))
return;
Session = InternetOpen(L"LeoCAD", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!Session)
return;
Request = InternetOpenUrl(Session, (WCHAR*)mURL.data(), NULL, 0, 0, 0);
if (!Request)
{
InternetCloseHandle(Session);
return;
}
for (;;)
{
char Buffer[1024];
DWORD BytesRead;
if (mAbort)
break;
if (!InternetReadFile(Request, Buffer, sizeof(Buffer), &BytesRead))
break;
if (BytesRead)
mBuffer.append(Buffer, BytesRead);
else
{
mError = false;
break;
}
}
InternetCloseHandle(Request);
InternetCloseHandle(Session);
}
#endif
#include "lc_http.h"
lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent)
: QDialog(Parent),
@ -66,13 +10,13 @@ lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent)
ui->setupUi(this);
ui->SearchEdit->installEventFilter(this);
mHttpManager = new lcHttpManager(this);
connect(ui->SetsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept()));
connect(this, SIGNAL(finished(int)), this, SLOT(Finished(int)));
#ifndef Q_OS_WIN
connect(&mNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(DownloadFinished(QNetworkReply*)));
#endif
connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*)));
mKeyListReply = RequestURL("https://www.leocad.org/rebrickable.json");
mKeyListReply = mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/rebrickable.json"));
}
lcSetsDatabaseDialog::~lcSetsDatabaseDialog()
@ -80,18 +24,6 @@ lcSetsDatabaseDialog::~lcSetsDatabaseDialog()
delete ui;
}
lcHttpReply* lcSetsDatabaseDialog::RequestURL(const QString& URL)
{
#ifdef Q_OS_WIN
lcHttpReply* Reply = new lcHttpReply(this, URL);
connect(Reply, &QThread::finished, [this, Reply] { ProcessReply(Reply); });
Reply->start();
return Reply;
#else
return mNetworkManager.get(QNetworkRequest(QUrl(URL)));
#endif
}
QString lcSetsDatabaseDialog::GetSetName() const
{
QTreeWidgetItem* Current = ui->SetsTree->currentItem();
@ -144,7 +76,7 @@ void lcSetsDatabaseDialog::accept()
int KeyIndex = QTime::currentTime().msec() % mKeys.size();
QString DownloadUrl = QString("https://rebrickable.com/api/v3/lego/sets/%1/parts/?key=%2").arg(SetNum, mKeys[KeyIndex]);
mInventoryReply = RequestURL(DownloadUrl);
mInventoryReply = mHttpManager->DownloadFile(DownloadUrl);
while (mInventoryReply)
{
@ -205,7 +137,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked()
int KeyIndex = QTime::currentTime().msec() % mKeys.size();
QString SearchUrl = QString("https://rebrickable.com/api/v3/lego/sets/?search=%1&key=%2").arg(Keyword, mKeys[KeyIndex]);
mSearchReply = RequestURL(SearchUrl);
mSearchReply = mHttpManager->DownloadFile(SearchUrl);
while (mSearchReply)
{
@ -221,14 +153,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked()
}
}
#ifndef Q_OS_WIN
void lcSetsDatabaseDialog::DownloadFinished(QNetworkReply* Reply)
{
ProcessReply(Reply);
}
#endif
void lcSetsDatabaseDialog::ProcessReply(lcHttpReply* Reply)
void lcSetsDatabaseDialog::DownloadFinished(lcHttpReply* Reply)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
if (Reply == mKeyListReply)

View file

@ -1,54 +1,14 @@
#pragma once
#include <QDialog>
#include <QNetworkAccessManager>
class lcHttpReply;
class lcHttpManager;
namespace Ui {
class lcSetsDatabaseDialog;
}
#ifdef Q_OS_WIN
#include <wininet.h>
class lcHttpReply : public QThread
{
Q_OBJECT
public:
lcHttpReply(QObject* Parent, const QString& URL);
void run();
bool error() const
{
return mError;
}
void abort()
{
mAbort = true;
}
QByteArray readAll() const
{
return mBuffer;
}
protected:
bool mError;
bool mAbort;
QByteArray mBuffer;
QString mURL;
};
#else
typedef QNetworkReply lcHttpReply;
#endif
class lcSetsDatabaseDialog : public QDialog
{
Q_OBJECT
@ -68,20 +28,13 @@ public:
virtual bool eventFilter(QObject* Object, QEvent* Event) override;
public slots:
#ifndef Q_OS_WIN
void DownloadFinished(QNetworkReply* Reply);
#endif
void DownloadFinished(lcHttpReply* Reply);
void on_SearchButton_clicked();
void accept() override;
void Finished(int Result);
protected:
lcHttpReply* RequestURL(const QString& URL);
void ProcessReply(lcHttpReply* Reply);
#ifndef Q_OS_WIN
QNetworkAccessManager mNetworkManager;
#endif
lcHttpManager* mHttpManager;
lcHttpReply* mKeyListReply;
lcHttpReply* mSearchReply;