Commit e1447c10 authored by Ming Rui Zhang's avatar Ming Rui Zhang Committed by Andreas Traczyk

networkmanager: remove singleton, add read online file functionality

- add unique_ptr in LRCInstance
- provide the option to read online file in a QString
  instead of saving to a file

Change-Id: Ie1935738f73648d25577faf9421f6f948af2e4f0
parent 46f4294a
......@@ -18,7 +18,7 @@
#include "connectivitymonitor.h"
#include "lrcinstance.h"
#include <QDebug>
#include <atlbase.h>
#include <netlistmgr.h>
......
......@@ -33,6 +33,7 @@
#include "settingskey.h"
#include "accountlistmodel.h"
#include "utils.h"
#include "networkmanager.h"
#include "api/lrc.h"
#include "api/account.h"
......@@ -257,17 +258,23 @@ public:
instance().lrc_->subscribeToDebugReceived();
}
static NetWorkManager* getNetworkManager() {
return instance().netWorkManager_.get();
}
signals:
void accountListChanged();
private:
std::unique_ptr<Lrc> lrc_;
std::unique_ptr<NetWorkManager> netWorkManager_;
AccountListModel accountListModel_;
LRCInstance(migrateCallback willMigrateCb = {},
migrateCallback didMigrateCb = {}) {
lrc_ = std::make_unique<Lrc>(willMigrateCb, didMigrateCb);
renderer_ = std::make_unique<RenderDistributer>();
netWorkManager_ = std::make_unique<NetWorkManager>();
};
std::string selectedAccountId_;
......
......@@ -21,7 +21,7 @@
#include "accountmigrationdialog.h"
#include "globalinstances.h"
#include "downloadmanager.h"
#include "networkmanager.h"
#include "lrcinstance.h"
#include "pixbufmanipulator.h"
#include "runguard.h"
......
......@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#include "downloadmanager.h"
#include "networkmanager.h"
#include "updatedownloaddialog.h"
#include "utils.h"
......@@ -26,21 +26,26 @@
#include <windows.h>
#endif // !Q_OS_WIN
DownloadManager::DownloadManager()
NetWorkManager::NetWorkManager(QObject* parent) :
QObject(parent)
{}
NetWorkManager::~NetWorkManager()
{}
void DownloadManager::downloadFile(const QUrl& fileUrl,
const QString& path,
bool withUI,
std::function<void(int)> doneCb)
void
NetWorkManager::getRequestFile(const QUrl& fileUrl,
const QString& path,
bool withUI,
std::function<void(int)> doneCbRequestInFile)
{
if (currentDownload_ && currentDownload_->isRunning()) {
qWarning() << "DownloadManager::downloadFile - currently downloading";
if (reply_ && reply_->isRunning()) {
qWarning() << "NetworkManager::getRequestFile - currently downloading";
return;
} else if (fileUrl.isEmpty() || path.isEmpty()) {
qWarning() << "NetworkManager::getRequestFile - lack of infomation";
return;
}
doneCb_ = doneCb;
withUI_ = withUI;
QFileInfo fileInfo(fileUrl.path());
QString fileName = fileInfo.fileName();
......@@ -54,56 +59,49 @@ void DownloadManager::downloadFile(const QUrl& fileUrl,
}
QNetworkRequest request(fileUrl);
currentDownload_ = manager_.get(request);
reply_ = manager_.get(request);
currentDownload_->disconnect();
connect(reply_, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
[this, withUI, doneCbRequestInFile] (QNetworkReply::NetworkError code) {
getRequestFileResetStatus(code, withUI, doneCbRequestInFile);
});
connect(currentDownload_, SIGNAL(finished()), this, SLOT(slotDownloadFinished()));
connect(currentDownload_, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(slotDownloadProgress(qint64, qint64)));
connect(currentDownload_, SIGNAL(readyRead()), this, SLOT(slotHttpReadyRead()));
connect(reply_, &QNetworkReply::finished,
[this, withUI, doneCbRequestInFile] {
int statusCode = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
getRequestFileResetStatus(statusCode, withUI, doneCbRequestInFile);
});
connect(reply_, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(slotDownloadProgress(qint64, qint64)));
connect(reply_, SIGNAL(readyRead()), this, SLOT(slotHttpReadyRead()));
#if QT_CONFIG(ssl)
connect(currentDownload_, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(slotSslErrors(QList<QSslError>)));
connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(slotSslErrors(QList<QSslError>)));
#endif
connect(&progressBar_, &UpdateDownloadDialog::isCanceled,
[this] {
cancelDownload();
});
if (withUI_) {
if (withUI) {
connect(&progressBar_, &UpdateDownloadDialog::isCanceled,
[this] {
cancelRequest();
});
progressBar_.exec();
}
}
void DownloadManager::slotDownloadFinished()
void
NetWorkManager::refresh(bool requestInFile)
{
statusCode_ = currentDownload_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpRequestAborted_) {
// request aborted
statusCode_ = 0;
}
currentDownload_->deleteLater();
currentDownload_ = nullptr;
file_->flush();
file_->close();
file_.reset(nullptr);
reply_->deleteLater();
reply_ = nullptr;
if (withUI_) {
progressBar_.setMaximum(0);
progressBar_.setValue(0);
progressBar_.update("0");
progressBar_.done(0);
if (requestInFile) {
file_->flush();
file_->close();
file_.reset(nullptr);
}
if (doneCb_)
doneCb_(statusCode_);
}
void DownloadManager::slotDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
void
NetWorkManager::slotDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
// If the number of bytes to be downloaded is not known, bytesTotal will be -1.
if (bytesTotal < 0) {
......@@ -119,17 +117,19 @@ void DownloadManager::slotDownloadProgress(qint64 bytesReceived, qint64 bytesTot
progressBar_.update(Utils::humanFileSize(bytesReceived) + " / " + Utils::humanFileSize(bytesTotal));
}
void DownloadManager::slotHttpReadyRead()
void
NetWorkManager::slotHttpReadyRead()
{
// this slot gets called every time the QNetworkReply has new data.
// We read all of its new data and write it into the file.
// That way we use less RAM than when reading it at the finished()
// signal of the QNetworkReply
if (file_)
file_->write(currentDownload_->readAll());
file_->write(reply_->readAll());
}
void DownloadManager::slotSslErrors(const QList<QSslError>& sslErrors)
void
NetWorkManager::slotSslErrors(const QList<QSslError>& sslErrors)
{
#if QT_CONFIG(ssl)
for (const QSslError& error : sslErrors)
......@@ -140,14 +140,70 @@ void DownloadManager::slotSslErrors(const QList<QSslError>& sslErrors)
#endif
}
int DownloadManager::getDownloadStatus()
void
NetWorkManager::cancelRequest()
{
return statusCode_;
if(reply_)
reply_->abort();
}
void
NetWorkManager::getRequestReply(const QUrl & fileUrl,
std::function<void(int, QString)> doneCbRequest)
{
if (reply_ && reply_->isRunning()) {
qWarning() << "NetworkManager::getRequestReply - currently downloading";
return;
} else if (fileUrl.isEmpty()) {
qWarning() << "NetworkManager::getRequestReply - lack of infomation";
return;
}
QNetworkRequest request(fileUrl);
reply_ = manager_.get(request);
connect(reply_, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
[this, doneCbRequest] (QNetworkReply::NetworkError code) {
getRequestReplyResetStatus("", code, doneCbRequest);
});
connect(reply_, &QNetworkReply::finished,
[this, doneCbRequest] {
int statusCode = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString response = QString(reply_->readAll());
getRequestReplyResetStatus(response, statusCode, doneCbRequest);
});
#if QT_CONFIG(ssl)
connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(slotSslErrors(QList<QSslError>)));
#endif
}
void
NetWorkManager::resetProgressBar()
{
progressBar_.setMaximum(0);
progressBar_.setValue(0);
progressBar_.update("0");
progressBar_.done(0);
}
void
NetWorkManager::getRequestFileResetStatus(int code, bool withUI, std::function<void(int)> doneCbRequestInFile)
{
reply_->disconnect();
refresh(true);
if (withUI) {
resetProgressBar();
}
if (doneCbRequestInFile)
doneCbRequestInFile(code);
}
void DownloadManager::cancelDownload()
void
NetWorkManager::getRequestReplyResetStatus(const QString& response, int code, std::function<void(int, QString)> doneCbRequest)
{
httpRequestAborted_ = true;
if(currentDownload_)
currentDownload_->abort();
reply_->disconnect();
refresh(false);
if (doneCbRequest)
doneCbRequest(code, response);
}
......@@ -18,47 +18,62 @@
#pragma once
#include <memory>
#include "updatedownloaddialog.h"
#include <QtCore>
#include <QtNetwork>
#include "updatedownloaddialog.h"
#include <memory>
class QSslError;
class DownloadManager : public QObject {
class NetWorkManager : public QObject {
Q_OBJECT
public:
static DownloadManager& instance() {
static DownloadManager* instance_ = new DownloadManager();
return *instance_;
}
explicit NetWorkManager(QObject* parent = nullptr);
~NetWorkManager();
void downloadFile(const QUrl& fileUrl,
const QString& path,
bool withUI,
std::function<void(int)> doneCb = {});
int getDownloadStatus();
void cancelDownload();
/**
* using qt get request to store the reply in file
* @param fileUrl - network address
* @param path - file saving path
* @param withUI - with download progress bar
* @param doneCbRequestInFile - done callback
*/
void getRequestFile(const QUrl& fileUrl,
const QString& path,
bool withUI,
std::function<void(int)> doneCbRequestInFile = {});
public slots:
/**
* using qt get request to return the reply (QString format) in callback
* @param fileUrl - network address
* @param path - file saving path
* @param withUI - with download progress bar
* @param doneCbRequest - done callback
*/
void getRequestReply(const QUrl& fileUrl,
std::function<void(int,QString)> doneCbRequest = {});
/*
* manually abort the current request
*/
void cancelRequest();
private slots:
void slotSslErrors(const QList<QSslError>& sslErrors);
void slotDownloadFinished();
void slotDownloadProgress(qint64 bytesRead, qint64 totalBytes);
void slotHttpReadyRead();
private:
DownloadManager();
void refresh(bool requestInFile);
void resetProgressBar();
void getRequestFileResetStatus(int code, bool withUI, std::function<void(int)> doneCbRequestInFile);
void getRequestReplyResetStatus(const QString& response, int code, std::function<void(int, QString)> doneCbRequest);
QNetworkAccessManager manager_;
QNetworkReply* currentDownload_;
QNetworkReply* reply_;
UpdateDownloadDialog progressBar_;
std::unique_ptr<QFile> file_;
int statusCode_;
bool withUI_;
bool httpRequestAborted_ { false };
std::function<void(int)> doneCb_;
};
......@@ -250,7 +250,7 @@ del /s /q $(OutDir)\Jami.exp</Command>
<ClCompile Include="sipinputpanel.cpp" />
<ClCompile Include="splashscreen.cpp" />
<ClCompile Include="updatedownloaddialog.cpp" />
<ClCompile Include="downloadmanager.cpp" />
<ClCompile Include="networkmanager.cpp" />
<ClCompile Include="accountitemdelegate.cpp" />
<ClCompile Include="accountlistmodel.cpp" />
<ClCompile Include="callwidget.cpp">
......@@ -417,8 +417,8 @@ del /s /q $(OutDir)\Jami.exp</Command>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
<QtMoc Include="downloadmanager.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<QtMoc Include="networkmanager.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
<QtMoc Include="passworddialog.h">
......
......@@ -204,9 +204,6 @@
<ClCompile Include="updatedownloaddialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="downloadmanager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="contactpicker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
......@@ -240,6 +237,9 @@
<ClCompile Include="lrcinstance.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="networkmanager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="aboutdialog.h">
......@@ -383,9 +383,6 @@
<QtMoc Include="updatedownloaddialog.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="downloadmanager.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="runguard.h">
<Filter>Header Files</Filter>
</QtMoc>
......@@ -410,8 +407,15 @@
<QtMoc Include="overlaybutton.h">
<Filter>Header Files</Filter>
</QtMoc>
==== BASE ====
==== BASE ====
<QtMoc Include="accountmigrationdialog.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="connectivitymonitor.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="networkmanager.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
......
......@@ -46,7 +46,7 @@
#include "pixbufmanipulator.h"
#include "globalsystemtray.h"
#include "lrcinstance.h"
#include "downloadmanager.h"
#include "networkmanager.h"
#include "updateconfirmdialog.h"
#include "version.h"
......@@ -366,32 +366,17 @@ void
Utils::checkForUpdates(bool withUI, QWidget* parent)
{
Utils::cleanUpdateFiles();
QString downloadpath = WinGetEnv("TEMP");
DownloadManager::instance().downloadFile(
LRCInstance::instance().getNetworkManager()->getRequestReply(
QUrl::fromEncoded("https://dl.jami.net/windows/version"),
downloadpath,
withUI,
[parent, withUI, downloadpath](int status) {
[parent, withUI] (int status, const QString& onlineVersion) {
if (status != 200) {
if (withUI)
if (withUI) {
QMessageBox::critical(0,
QObject::tr("Update"),
QObject::tr("Version cannot be verified"));
}
return;
}
QFile file(downloadpath + "/" + "version");
if (!file.open(QIODevice::ReadOnly)) {
if (withUI)
QMessageBox::critical(0,
QObject::tr("Update"),
QObject::tr("File cannnot be opened"));
return;
}
QTextStream in(&file);
QString onlineVersion = in.readLine();
file.close();
auto currentVersion = QString(VERSION_STRING).toULongLong();
if (onlineVersion.isEmpty()) {
qWarning() << "No version file found";
......@@ -420,7 +405,7 @@ Utils::applyUpdates(QWidget* parent)
} else
return;
DownloadManager::instance().downloadFile(
LRCInstance::instance().getNetworkManager()->getRequestFile(
QUrl::fromEncoded("https://dl.jami.net/windows/jami.release.x64.msi"),
WinGetEnv("TEMP"),
true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment