From c2e67e4b90a4454835cb553d25667a4462146c5c Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Mon, 26 Jun 2017 15:53:43 +0200 Subject: [PATCH] attempt to implement urlFetch with a timeout --- .gitmodules | 3 ++ chatterino.pro | 8 ++- dependencies/settings.pri | 3 -- dependencies/signals.pri | 2 + lib/signals | 1 + src/messagefactory.cpp | 6 +++ src/messagefactory.hpp | 11 ++++ src/util/urlfetch.hpp | 107 +++++++++++++++++++++++++++++++++---- src/widgets/basewidget.hpp | 4 ++ 9 files changed, 130 insertions(+), 15 deletions(-) create mode 100644 dependencies/signals.pri create mode 160000 lib/signals create mode 100644 src/messagefactory.cpp create mode 100644 src/messagefactory.hpp create mode 100644 src/widgets/basewidget.hpp diff --git a/.gitmodules b/.gitmodules index 3dbc5cdc3..eb068fef0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/humanize"] path = lib/humanize url = https://github.com/pajlada/humanize.git +[submodule "lib/signals"] + path = lib/signals + url = https://github.com/pajlada/signals.git diff --git a/chatterino.pro b/chatterino.pro index 4716dce9b..36e3ff1e8 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -92,7 +92,8 @@ SOURCES += \ src/accountmanager.cpp \ src/twitch/twitchuser.cpp \ src/ircaccount.cpp \ - src/widgets/accountpopup.cpp + src/widgets/accountpopup.cpp \ + src/messagefactory.cpp HEADERS += \ src/asyncexec.hpp \ @@ -150,7 +151,9 @@ HEADERS += \ src/twitch/twitchuser.hpp \ src/ircaccount.hpp \ src/widgets/accountpopup.hpp \ - src/util/distancebetweenpoints.hpp + src/util/distancebetweenpoints.hpp \ + src/messagefactory.hpp \ + src/widgets/basewidget.hpp PRECOMPILED_HEADER = @@ -197,4 +200,5 @@ werr { # External dependencies include(dependencies/rapidjson.pri) include(dependencies/settings.pri) +include(dependencies/signals.pri) include(dependencies/humanize.pri) diff --git a/dependencies/settings.pri b/dependencies/settings.pri index 6c1790358..7c6b080af 100644 --- a/dependencies/settings.pri +++ b/dependencies/settings.pri @@ -4,6 +4,3 @@ SOURCES += \ $$PWD/../lib/settings/src/settings/settingmanager.cpp INCLUDEPATH += $$PWD/../lib/settings/include/ - -# signals -INCLUDEPATH += $$PWD/../lib/settings/external/signals/include diff --git a/dependencies/signals.pri b/dependencies/signals.pri new file mode 100644 index 000000000..25e11f9df --- /dev/null +++ b/dependencies/signals.pri @@ -0,0 +1,2 @@ +# signals +INCLUDEPATH += $$PWD/../lib/signals/include/ diff --git a/lib/signals b/lib/signals new file mode 160000 index 000000000..2c9c92b97 --- /dev/null +++ b/lib/signals @@ -0,0 +1 @@ +Subproject commit 2c9c92b971f4a1313eeb4d9daf8ea59565d3c691 diff --git a/src/messagefactory.cpp b/src/messagefactory.cpp new file mode 100644 index 000000000..0d1dc8fc4 --- /dev/null +++ b/src/messagefactory.cpp @@ -0,0 +1,6 @@ +#include "messagefactory.hpp" + +MessageFactory::MessageFactory() +{ + +} diff --git a/src/messagefactory.hpp b/src/messagefactory.hpp new file mode 100644 index 000000000..b27195d75 --- /dev/null +++ b/src/messagefactory.hpp @@ -0,0 +1,11 @@ +#ifndef MESSAGEFACTORY_HPP +#define MESSAGEFACTORY_HPP + + +class MessageFactory +{ +public: + MessageFactory(); +}; + +#endif // MESSAGEFACTORY_HPP \ No newline at end of file diff --git a/src/util/urlfetch.hpp b/src/util/urlfetch.hpp index fb89f90ab..d68e5e1c9 100644 --- a/src/util/urlfetch.hpp +++ b/src/util/urlfetch.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -8,15 +9,22 @@ #include #include #include +#include #include namespace chatterino { namespace util { -static void urlFetch(const QString &url, std::function successCallback) +static void urlFetch(const QString &url, std::function successCallback, + QNetworkAccessManager *manager = nullptr) { - QNetworkAccessManager *manager = new QNetworkAccessManager(); + bool customManager = true; + + if (manager == nullptr) { + manager = new QNetworkAccessManager(); + customManager = false; + } QUrl requestUrl(url); QNetworkRequest request(requestUrl); @@ -39,24 +47,103 @@ static void urlFetch(const QString &url, std::function su } reply->deleteLater(); - manager->deleteLater(); + if (!customManager) { + manager->deleteLater(); + } }); } -static void urlJsonFetch(const QString &url, std::function successCallback) +static void urlFetchJSON(const QString &url, std::function successCallback, + QNetworkAccessManager *manager = nullptr) { - urlFetch(url, [=](QNetworkReply &reply) { - QByteArray data = reply.readAll(); - QJsonDocument jsonDoc(QJsonDocument::fromJson(data)); + urlFetch(url, + [=](QNetworkReply &reply) { + QByteArray data = reply.readAll(); + QJsonDocument jsonDoc(QJsonDocument::fromJson(data)); - if (jsonDoc.isNull()) { + if (jsonDoc.isNull()) { + return; + } + + QJsonObject rootNode = jsonDoc.object(); + + successCallback(rootNode); + }, + manager); +} + +static void urlFetchTimeout(const QString &url, + std::function successCallback, int timeoutMs, + QNetworkAccessManager *manager = nullptr) +{ + bool customManager = true; + + if (manager == nullptr) { + manager = new QNetworkAccessManager(); + customManager = false; + } + + QUrl requestUrl(url); + QNetworkRequest request(requestUrl); + + QNetworkReply *reply = manager->get(request); + + QTimer timer; + timer.setSingleShot(true); + + QEventLoop loop; + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + QObject::connect(reply, &QNetworkReply::finished, [=] { + /* uncomment to follow redirects + QVariant replyStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); + if (replyStatus >= 300 && replyStatus <= 304) { + QString newUrl = + reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString(); + urlFetch(newUrl, successCallback); return; } + */ - QJsonObject rootNode = jsonDoc.object(); + if (reply->error() == QNetworkReply::NetworkError::NoError) { + successCallback(*reply); + } - successCallback(rootNode); + reply->deleteLater(); + if (!customManager) { + manager->deleteLater(); + } }); + timer.start(timeoutMs); + loop.exec(); + + if (!timer.isActive()) { + qDebug() << "TIMED OUT"; + QObject::disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + reply->abort(); + } else { + // qDebug() << "XDDD HEHEHE"; + } +} + +static void urlFetchJSONTimeout(const QString &url, + std::function successCallback, int timeoutMs, + QNetworkAccessManager *manager = nullptr) +{ + urlFetchTimeout(url, + [=](QNetworkReply &reply) { + QByteArray data = reply.readAll(); + QJsonDocument jsonDoc(QJsonDocument::fromJson(data)); + + if (jsonDoc.isNull()) { + return; + } + + QJsonObject rootNode = jsonDoc.object(); + + successCallback(rootNode); + }, + timeoutMs, manager); } } // namespace util diff --git a/src/widgets/basewidget.hpp b/src/widgets/basewidget.hpp new file mode 100644 index 000000000..6dafaca83 --- /dev/null +++ b/src/widgets/basewidget.hpp @@ -0,0 +1,4 @@ +#ifndef BASEWIDGET_HPP +#define BASEWIDGET_HPP + +#endif // BASEWIDGET_HPP