Networkmanager (#134)
* rename ImageLoader* to Network* * static NetworkManager * NetworkManager queue arbitrary requests * modify urlfetch to use NetworkManager * urlfetchjson in terms of NetworkManager * fetchurljson fetchurltimeout fetchurljsontimeout special fetch url functions with various connects and functions to be called * operate on fetched data in the correct thread * operate on fetched resources in correct thread * networkmanager urlfetch functions * expose urlfetch functions of networkmanager through util and util::twitch * add caller to util functions * cleanup * formatting * urlPut function for NetworkManager and util::twitch * cleanup worker (no more leak) * use urlfetch for LazyLoadedImage::loadImage * Rename NetworkManager methods (#1) * Rename NetworkManager methods Remove unused NetworkManager methods Remove unused NetworkManager includes Reorder includes in lazyloadedimage.cpp and urlfetch.hpp * try to simplify code, might break everything * fixed some more stuff?
This commit is contained in:
+121
-193
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "credentials.hpp"
|
||||
#include "accountmanager.hpp"
|
||||
#include "credentials.hpp"
|
||||
#include "util/networkmanager.hpp"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QJsonArray>
|
||||
@@ -14,68 +15,128 @@
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace chatterino {
|
||||
namespace util {
|
||||
|
||||
namespace twitch {
|
||||
|
||||
static void get(QString url, std::function<void(QJsonObject &)> successCallback)
|
||||
static QJsonObject parseJSONFromReply(QNetworkReply *reply)
|
||||
{
|
||||
auto manager = new QNetworkAccessManager();
|
||||
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
QUrl requestUrl(url);
|
||||
QNetworkRequest request(requestUrl);
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
|
||||
request.setRawHeader("Client-ID", getDefaultClientID());
|
||||
request.setRawHeader("Accept", "application/vnd.twitchtv.v5+json");
|
||||
if (jsonDoc.isNull()) {
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
QNetworkReply *reply = manager->get(request);
|
||||
return jsonDoc.object();
|
||||
}
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
|
||||
if (!jsonDoc.isNull()) {
|
||||
QJsonObject rootNode = jsonDoc.object();
|
||||
|
||||
successCallback(rootNode);
|
||||
}
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
manager->deleteLater();
|
||||
static void urlFetchJSON(const QString &url, const QObject *caller,
|
||||
std::function<void(QJsonObject &)> successCallback)
|
||||
{
|
||||
util::NetworkRequest req(url);
|
||||
req.setCaller(caller);
|
||||
req.get([=](QNetworkReply *reply) {
|
||||
auto node = parseJSONFromReply(reply);
|
||||
successCallback(node);
|
||||
});
|
||||
}
|
||||
|
||||
static void getUserID(QString username, std::function<void(QString)> successCallback)
|
||||
static void urlFetchTimeout(const QString &url, const QObject *caller,
|
||||
std::function<void(QNetworkReply *)> successCallback, int timeoutMs)
|
||||
{
|
||||
get("https://api.twitch.tv/kraken/users?login=" + username, [=](const QJsonObject &root) {
|
||||
if (!root.value("users").isArray()) {
|
||||
qDebug() << "API Error while getting user id, users is not an array";
|
||||
return;
|
||||
QTimer *timer = new QTimer;
|
||||
timer->setSingleShot(true);
|
||||
|
||||
QEventLoop *loop = new QEventLoop;
|
||||
|
||||
util::NetworkRequest req(url);
|
||||
req.setCaller(loop);
|
||||
req.setOnReplyCreated([loop, timer](QNetworkReply *reply) {
|
||||
QObject::connect(timer, &QTimer::timeout, loop, [=]() {
|
||||
QObject::disconnect(reply, &QNetworkReply::finished, loop, &QEventLoop::quit);
|
||||
reply->abort();
|
||||
reply->deleteLater();
|
||||
});
|
||||
});
|
||||
req.get([=](QNetworkReply *reply) {
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
successCallback(reply);
|
||||
}
|
||||
|
||||
auto users = root.value("users").toArray();
|
||||
if (users.size() != 1) {
|
||||
qDebug() << "API Error while getting user id, users array size is not 1";
|
||||
return;
|
||||
}
|
||||
if (!users[0].isObject()) {
|
||||
qDebug() << "API Error while getting user id, first user is not an object";
|
||||
return;
|
||||
}
|
||||
auto firstUser = users[0].toObject();
|
||||
auto id = firstUser.value("_id");
|
||||
if (!id.isString()) {
|
||||
qDebug()
|
||||
<< "API Error: while getting user id, first user object `_id` key is not a string";
|
||||
return;
|
||||
}
|
||||
successCallback(id.toString());
|
||||
reply->deleteLater();
|
||||
loop->quit();
|
||||
});
|
||||
|
||||
QObject::connect(timer, SIGNAL(timeout()), loop, SLOT(quit()));
|
||||
|
||||
timer->start(timeoutMs);
|
||||
loop->exec();
|
||||
delete timer;
|
||||
delete loop;
|
||||
}
|
||||
|
||||
static void urlFetchJSONTimeout(const QString &url, const QObject *caller,
|
||||
std::function<void(QJsonObject &)> successCallback, int timeoutMs)
|
||||
{
|
||||
urlFetchTimeout(url, caller,
|
||||
[=](QNetworkReply *reply) {
|
||||
auto node = parseJSONFromReply(reply);
|
||||
successCallback(node);
|
||||
},
|
||||
timeoutMs);
|
||||
}
|
||||
|
||||
namespace twitch {
|
||||
|
||||
static void get(QString url, const QObject *caller,
|
||||
std::function<void(QJsonObject &)> successCallback)
|
||||
{
|
||||
util::NetworkRequest req(url);
|
||||
req.setCaller(caller);
|
||||
req.setRawHeader("Client-ID", getDefaultClientID());
|
||||
req.setRawHeader("Accept", "application/vnd.twitchtv.v5+json");
|
||||
req.get([=](QNetworkReply *reply) {
|
||||
auto node = parseJSONFromReply(reply);
|
||||
successCallback(node);
|
||||
});
|
||||
}
|
||||
|
||||
static void getUserID(QString username, const QObject *caller,
|
||||
std::function<void(QString)> successCallback)
|
||||
{
|
||||
get("https://api.twitch.tv/kraken/users?login=" + username, caller,
|
||||
[=](const QJsonObject &root) {
|
||||
if (!root.value("users").isArray()) {
|
||||
qDebug() << "API Error while getting user id, users is not an array";
|
||||
return;
|
||||
}
|
||||
|
||||
auto users = root.value("users").toArray();
|
||||
if (users.size() != 1) {
|
||||
qDebug() << "API Error while getting user id, users array size is not 1";
|
||||
return;
|
||||
}
|
||||
if (!users[0].isObject()) {
|
||||
qDebug() << "API Error while getting user id, first user is not an object";
|
||||
return;
|
||||
}
|
||||
auto firstUser = users[0].toObject();
|
||||
auto id = firstUser.value("_id");
|
||||
if (!id.isString()) {
|
||||
qDebug() << "API Error: while getting user id, first user object `_id` key is not "
|
||||
"a string";
|
||||
return;
|
||||
}
|
||||
successCallback(id.toString());
|
||||
});
|
||||
}
|
||||
static void put(QUrl url, std::function<void(QJsonObject)> successCallback)
|
||||
{
|
||||
@@ -84,157 +145,24 @@ static void put(QUrl url, std::function<void(QJsonObject)> successCallback)
|
||||
|
||||
request.setRawHeader("Client-ID", getDefaultClientID());
|
||||
request.setRawHeader("Accept", "application/vnd.twitchtv.v5+json");
|
||||
request.setRawHeader("Authorization", "OAuth " +
|
||||
AccountManager::getInstance().getTwitchUser().getOAuthToken().toUtf8());
|
||||
QNetworkReply *reply = manager->put(request,"");
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=](){
|
||||
if(reply->error() == QNetworkReply::NetworkError::NoError)
|
||||
{
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
if(!jsonDoc.isNull())
|
||||
{
|
||||
QJsonObject rootNode = jsonDoc.object();
|
||||
request.setRawHeader(
|
||||
"Authorization",
|
||||
"OAuth " + AccountManager::getInstance().getTwitchUser().getOAuthToken().toUtf8());
|
||||
|
||||
successCallback(rootNode);
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
manager->deleteLater();
|
||||
NetworkManager::urlPut(std::move(request), [=](QNetworkReply *reply) {
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
if (!jsonDoc.isNull()) {
|
||||
QJsonObject rootNode = jsonDoc.object();
|
||||
|
||||
successCallback(rootNode);
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace twitch
|
||||
|
||||
static void urlFetch(const QString &url, std::function<void(QNetworkReply &)> successCallback,
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
successCallback(*reply);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
if (!customManager) {
|
||||
manager->deleteLater();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void urlFetchJSON(const QString &url, std::function<void(QJsonObject &)> successCallback,
|
||||
QNetworkAccessManager *manager = nullptr)
|
||||
{
|
||||
urlFetch(url,
|
||||
[=](QNetworkReply &reply) {
|
||||
QByteArray data = reply.readAll();
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
|
||||
|
||||
if (jsonDoc.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject rootNode = jsonDoc.object();
|
||||
|
||||
successCallback(rootNode);
|
||||
},
|
||||
manager);
|
||||
}
|
||||
|
||||
static void urlFetchTimeout(const QString &url,
|
||||
std::function<void(QNetworkReply &)> 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;
|
||||
}
|
||||
*/
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
successCallback(*reply);
|
||||
}
|
||||
|
||||
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<void(QJsonObject &)> 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
|
||||
} // namespace chatterino
|
||||
|
||||
Reference in New Issue
Block a user