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,6 +139,7 @@ SOURCES += common/view.cpp \
common/lc_context.cpp \ common/lc_context.cpp \
common/lc_file.cpp \ common/lc_file.cpp \
common/lc_glextensions.cpp \ common/lc_glextensions.cpp \
common/lc_http.cpp \
common/lc_library.cpp \ common/lc_library.cpp \
common/lc_lxf.cpp \ common/lc_lxf.cpp \
common/lc_mainwindow.cpp \ common/lc_mainwindow.cpp \
@ -200,6 +201,7 @@ HEADERS += \
common/lc_glextensions.h \ common/lc_glextensions.h \
common/lc_global.h \ common/lc_global.h \
common/lc_glwidget.h \ common/lc_glwidget.h \
common/lc_http.h \
common/lc_library.h \ common/lc_library.h \
common/lc_lxf.h \ common/lc_lxf.h \
common/lc_mainwindow.h \ common/lc_mainwindow.h \

View file

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

View file

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

View file

@ -1,63 +1,7 @@
#include "lc_global.h" #include "lc_global.h"
#include "lc_setsdatabasedialog.h" #include "lc_setsdatabasedialog.h"
#include "ui_lc_setsdatabasedialog.h" #include "ui_lc_setsdatabasedialog.h"
#include <QNetworkRequest> #include "lc_http.h"
#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
lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent) lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent)
: QDialog(Parent), : QDialog(Parent),
@ -66,13 +10,13 @@ lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent)
ui->setupUi(this); ui->setupUi(this);
ui->SearchEdit->installEventFilter(this); ui->SearchEdit->installEventFilter(this);
mHttpManager = new lcHttpManager(this);
connect(ui->SetsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept())); connect(ui->SetsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept()));
connect(this, SIGNAL(finished(int)), this, SLOT(Finished(int))); connect(this, SIGNAL(finished(int)), this, SLOT(Finished(int)));
#ifndef Q_OS_WIN connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*)));
connect(&mNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(DownloadFinished(QNetworkReply*)));
#endif
mKeyListReply = RequestURL("https://www.leocad.org/rebrickable.json"); mKeyListReply = mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/rebrickable.json"));
} }
lcSetsDatabaseDialog::~lcSetsDatabaseDialog() lcSetsDatabaseDialog::~lcSetsDatabaseDialog()
@ -80,18 +24,6 @@ lcSetsDatabaseDialog::~lcSetsDatabaseDialog()
delete ui; 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 QString lcSetsDatabaseDialog::GetSetName() const
{ {
QTreeWidgetItem* Current = ui->SetsTree->currentItem(); QTreeWidgetItem* Current = ui->SetsTree->currentItem();
@ -144,7 +76,7 @@ void lcSetsDatabaseDialog::accept()
int KeyIndex = QTime::currentTime().msec() % mKeys.size(); 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]); 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) while (mInventoryReply)
{ {
@ -205,7 +137,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked()
int KeyIndex = QTime::currentTime().msec() % mKeys.size(); 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]); 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) while (mSearchReply)
{ {
@ -221,14 +153,7 @@ void lcSetsDatabaseDialog::on_SearchButton_clicked()
} }
} }
#ifndef Q_OS_WIN void lcSetsDatabaseDialog::DownloadFinished(lcHttpReply* Reply)
void lcSetsDatabaseDialog::DownloadFinished(QNetworkReply* Reply)
{
ProcessReply(Reply);
}
#endif
void lcSetsDatabaseDialog::ProcessReply(lcHttpReply* Reply)
{ {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
if (Reply == mKeyListReply) if (Reply == mKeyListReply)

View file

@ -1,54 +1,14 @@
#pragma once #pragma once
#include <QDialog> #include <QDialog>
#include <QNetworkAccessManager>
class lcHttpReply;
class lcHttpManager;
namespace Ui { namespace Ui {
class lcSetsDatabaseDialog; 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 class lcSetsDatabaseDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
@ -68,20 +28,13 @@ public:
virtual bool eventFilter(QObject* Object, QEvent* Event) override; virtual bool eventFilter(QObject* Object, QEvent* Event) override;
public slots: public slots:
#ifndef Q_OS_WIN void DownloadFinished(lcHttpReply* Reply);
void DownloadFinished(QNetworkReply* Reply);
#endif
void on_SearchButton_clicked(); void on_SearchButton_clicked();
void accept() override; void accept() override;
void Finished(int Result); void Finished(int Result);
protected: protected:
lcHttpReply* RequestURL(const QString& URL); lcHttpManager* mHttpManager;
void ProcessReply(lcHttpReply* Reply);
#ifndef Q_OS_WIN
QNetworkAccessManager mNetworkManager;
#endif
lcHttpReply* mKeyListReply; lcHttpReply* mKeyListReply;
lcHttpReply* mSearchReply; lcHttpReply* mSearchReply;