2017-06-06 21:18:05 +02:00
|
|
|
#pragma once
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-08-19 15:37:56 +02:00
|
|
|
#include "credentials.hpp"
|
|
|
|
|
2017-06-26 15:53:43 +02:00
|
|
|
#include <QEventLoop>
|
2017-04-12 17:46:44 +02:00
|
|
|
#include <QJsonArray>
|
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QJsonObject>
|
|
|
|
#include <QJsonValue>
|
|
|
|
#include <QNetworkAccessManager>
|
|
|
|
#include <QNetworkReply>
|
|
|
|
#include <QNetworkRequest>
|
|
|
|
#include <QString>
|
2017-06-26 15:53:43 +02:00
|
|
|
#include <QTimer>
|
2017-04-12 17:46:44 +02:00
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
namespace chatterino {
|
|
|
|
namespace util {
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-08-19 15:37:56 +02:00
|
|
|
namespace twitch {
|
|
|
|
|
|
|
|
static void get(QString url, std::function<void(QJsonObject &)> successCallback)
|
|
|
|
{
|
|
|
|
auto manager = new QNetworkAccessManager();
|
|
|
|
|
|
|
|
QUrl requestUrl(url);
|
|
|
|
QNetworkRequest request(requestUrl);
|
|
|
|
|
|
|
|
request.setRawHeader("Client-ID", getDefaultClientID());
|
|
|
|
request.setRawHeader("Accept", "application/vnd.twitchtv.v5+json");
|
|
|
|
|
|
|
|
QNetworkReply *reply = manager->get(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();
|
|
|
|
|
|
|
|
successCallback(rootNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
reply->deleteLater();
|
|
|
|
manager->deleteLater();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static void getUserID(QString username, std::function<void(QString)> successCallback)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace twitch
|
|
|
|
|
2017-06-26 15:53:43 +02:00
|
|
|
static void urlFetch(const QString &url, std::function<void(QNetworkReply &)> successCallback,
|
|
|
|
QNetworkAccessManager *manager = nullptr)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2017-06-26 15:53:43 +02:00
|
|
|
bool customManager = true;
|
|
|
|
|
|
|
|
if (manager == nullptr) {
|
|
|
|
manager = new QNetworkAccessManager();
|
|
|
|
customManager = false;
|
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
|
|
|
|
QUrl requestUrl(url);
|
|
|
|
QNetworkRequest request(requestUrl);
|
|
|
|
|
|
|
|
QNetworkReply *reply = manager->get(request);
|
|
|
|
|
|
|
|
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
2017-06-06 21:18:05 +02:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
|
|
|
successCallback(*reply);
|
|
|
|
}
|
|
|
|
|
|
|
|
reply->deleteLater();
|
2017-06-26 15:53:43 +02:00
|
|
|
if (!customManager) {
|
|
|
|
manager->deleteLater();
|
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-26 15:53:43 +02:00
|
|
|
static void urlFetchJSON(const QString &url, std::function<void(QJsonObject &)> successCallback,
|
|
|
|
QNetworkAccessManager *manager = nullptr)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2017-06-26 15:53:43 +02:00
|
|
|
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;
|
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-06-26 15:53:43 +02:00
|
|
|
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);
|
2017-04-12 17:46:44 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-06-26 15:53:43 +02:00
|
|
|
*/
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-06-26 15:53:43 +02:00
|
|
|
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
|
|
|
successCallback(*reply);
|
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-06-26 15:53:43 +02:00
|
|
|
reply->deleteLater();
|
|
|
|
if (!customManager) {
|
|
|
|
manager->deleteLater();
|
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
});
|
2017-06-26 15:53:43 +02:00
|
|
|
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);
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-06-06 21:18:05 +02:00
|
|
|
} // namespace util
|
|
|
|
} // namespace chatterino
|