diff --git a/src/common/NetworkPrivate.cpp b/src/common/NetworkPrivate.cpp index 44cb87102..f0a74ed5a 100644 --- a/src/common/NetworkPrivate.cpp +++ b/src/common/NetworkPrivate.cpp @@ -72,12 +72,12 @@ void writeToCache(const std::shared_ptr<NetworkData> &data, } } -void loadUncached(const std::shared_ptr<NetworkData> &data) +void loadUncached(std::shared_ptr<NetworkData> &&data) { DebugCount::increase("http request started"); NetworkRequester requester; - NetworkWorker *worker = new NetworkWorker; + auto *worker = new NetworkWorker; worker->moveToThread(&NetworkManager::workerThread); @@ -89,7 +89,7 @@ void loadUncached(const std::shared_ptr<NetworkData> &data) data->timer_->start(data->timeoutMS_); } - auto reply = [&]() -> QNetworkReply * { + auto *reply = [&]() -> QNetworkReply * { switch (data->requestType_) { case NetworkRequestType::Get: @@ -245,12 +245,16 @@ void loadUncached(const std::shared_ptr<NetworkData> &data) if (data->onSuccess_) { if (data->executeConcurrently_) + { QtConcurrent::run([onSuccess = std::move(data->onSuccess_), result = std::move(result)] { onSuccess(result); }); + } else + { data->onSuccess_(result); + } } // log("finished {}", data->request_.url().toString()); @@ -276,11 +280,15 @@ void loadUncached(const std::shared_ptr<NetworkData> &data) if (data->finally_) { if (data->executeConcurrently_) + { QtConcurrent::run([finally = std::move(data->finally_)] { finally(); }); + } else + { data->finally_(); + } } }; @@ -316,87 +324,87 @@ void loadUncached(const std::shared_ptr<NetworkData> &data) } // First tried to load cached, then uncached. -void loadCached(const std::shared_ptr<NetworkData> &data) +void loadCached(std::shared_ptr<NetworkData> &&data) { QFile cachedFile(getPaths()->cacheDirectory() + "/" + data->getHash()); if (!cachedFile.exists() || !cachedFile.open(QIODevice::ReadOnly)) { // File didn't exist OR File could not be opened - loadUncached(data); + loadUncached(std::move(data)); return; } - else - { - // XXX: check if bytes is empty? - QByteArray bytes = cachedFile.readAll(); - NetworkResult result(bytes, 200); - qCDebug(chatterinoHTTP) - << QString("%1 [CACHED] 200 %2") - .arg(networkRequestTypes.at(int(data->requestType_)), - data->request_.url().toString()); - if (data->onSuccess_) + // XXX: check if bytes is empty? + QByteArray bytes = cachedFile.readAll(); + NetworkResult result(bytes, 200); + + qCDebug(chatterinoHTTP) + << QString("%1 [CACHED] 200 %2") + .arg(networkRequestTypes.at(int(data->requestType_)), + data->request_.url().toString()); + if (data->onSuccess_) + { + if (data->executeConcurrently_ || isGuiThread()) { - if (data->executeConcurrently_ || isGuiThread()) + // XXX: If outcome is Failure, we should invalidate the cache file + // somehow/somewhere + /*auto outcome =*/ + if (data->hasCaller_ && !data->caller_.get()) { - // XXX: If outcome is Failure, we should invalidate the cache file - // somehow/somewhere - /*auto outcome =*/ + return; + } + data->onSuccess_(result); + } + else + { + postToThread([data, result]() { if (data->hasCaller_ && !data->caller_.get()) { return; } + data->onSuccess_(result); - } - else - { - postToThread([data, result]() { - if (data->hasCaller_ && !data->caller_.get()) - { - return; - } - - data->onSuccess_(result); - }); - } + }); } + } - if (data->finally_) + if (data->finally_) + { + if (data->executeConcurrently_ || isGuiThread()) { - if (data->executeConcurrently_ || isGuiThread()) + if (data->hasCaller_ && !data->caller_.get()) { + return; + } + + data->finally_(); + } + else + { + postToThread([data]() { if (data->hasCaller_ && !data->caller_.get()) { return; } data->finally_(); - } - else - { - postToThread([data]() { - if (data->hasCaller_ && !data->caller_.get()) - { - return; - } - - data->finally_(); - }); - } + }); } } } -void load(const std::shared_ptr<NetworkData> &data) +void load(std::shared_ptr<NetworkData> &&data) { if (data->cache_) { - QtConcurrent::run(loadCached, data); + QtConcurrent::run([data = std::move(data)]() mutable { + loadCached(std::move(data)); + }); } else { - loadUncached(data); + loadUncached(std::move(data)); } } diff --git a/src/common/NetworkPrivate.hpp b/src/common/NetworkPrivate.hpp index 03d4a705e..3fe841bc2 100644 --- a/src/common/NetworkPrivate.hpp +++ b/src/common/NetworkPrivate.hpp @@ -68,6 +68,6 @@ private: QString hash_; }; -void load(const std::shared_ptr<NetworkData> &data); +void load(std::shared_ptr<NetworkData> &&data); } // namespace chatterino diff --git a/src/common/NetworkRequest.cpp b/src/common/NetworkRequest.cpp index cfe0cd177..d856faf1e 100644 --- a/src/common/NetworkRequest.cpp +++ b/src/common/NetworkRequest.cpp @@ -1,14 +1,8 @@ #include "common/NetworkRequest.hpp" #include "common/NetworkPrivate.hpp" -#include "common/Outcome.hpp" #include "common/QLogging.hpp" #include "common/Version.hpp" -#include "debug/AssertInGuiThread.hpp" -#include "providers/twitch/TwitchCommon.hpp" -#include "singletons/Paths.hpp" -#include "util/DebugCount.hpp" -#include "util/PostToThread.hpp" #include <QDebug> #include <QFile> @@ -28,7 +22,7 @@ NetworkRequest::NetworkRequest(const std::string &url, this->initializeDefaultValues(); } -NetworkRequest::NetworkRequest(QUrl url, NetworkRequestType requestType) +NetworkRequest::NetworkRequest(const QUrl &url, NetworkRequestType requestType) : data(new NetworkData) { this->data->request_.setUrl(url); @@ -37,10 +31,7 @@ NetworkRequest::NetworkRequest(QUrl url, NetworkRequestType requestType) this->initializeDefaultValues(); } -NetworkRequest::~NetworkRequest() -{ - //assert(!this->data || this->executed_); -} +NetworkRequest::~NetworkRequest() = default; NetworkRequest NetworkRequest::type(NetworkRequestType newRequestType) && { @@ -63,25 +54,25 @@ NetworkRequest NetworkRequest::caller(const QObject *caller) && NetworkRequest NetworkRequest::onReplyCreated(NetworkReplyCreatedCallback cb) && { - this->data->onReplyCreated_ = cb; + this->data->onReplyCreated_ = std::move(cb); return std::move(*this); } NetworkRequest NetworkRequest::onError(NetworkErrorCallback cb) && { - this->data->onError_ = cb; + this->data->onError_ = std::move(cb); return std::move(*this); } NetworkRequest NetworkRequest::onSuccess(NetworkSuccessCallback cb) && { - this->data->onSuccess_ = cb; + this->data->onSuccess_ = std::move(cb); return std::move(*this); } NetworkRequest NetworkRequest::finally(NetworkFinallyCallback cb) && { - this->data->finally_ = cb; + this->data->finally_ = std::move(cb); return std::move(*this); } @@ -106,6 +97,13 @@ NetworkRequest NetworkRequest::header(const char *headerName, return std::move(*this); } +NetworkRequest NetworkRequest::header(QNetworkRequest::KnownHeaders header, + const QVariant &value) && +{ + this->data->request_.setHeader(header, value); + return std::move(*this); +} + NetworkRequest NetworkRequest::headerList( const std::vector<std::pair<QByteArray, QByteArray>> &headers) && { @@ -129,20 +127,6 @@ NetworkRequest NetworkRequest::concurrent() && return std::move(*this); } -NetworkRequest NetworkRequest::authorizeTwitchV5(const QString &clientID, - const QString &oauthToken) && -{ - // TODO: make two overloads, with and without oauth token - auto tmp = std::move(*this) - .header("Client-ID", clientID) - .header("Accept", "application/vnd.twitchtv.v5+json"); - - if (!oauthToken.isEmpty()) - return std::move(tmp).header("Authorization", "OAuth " + oauthToken); - else - return tmp; -} - NetworkRequest NetworkRequest::multiPart(QHttpMultiPart *payload) && { payload->setParent(this->data->lifetimeManager_); @@ -207,10 +191,28 @@ void NetworkRequest::initializeDefaultValues() this->data->request_.setRawHeader("User-Agent", userAgent); } -// Helper creator functions -NetworkRequest NetworkRequest::twitchRequest(QUrl url) +NetworkRequest NetworkRequest::json(const QJsonArray &root) && { - return NetworkRequest(url).authorizeTwitchV5(getDefaultClientID()); + return std::move(*this).json(QJsonDocument(root)); +} + +NetworkRequest NetworkRequest::json(const QJsonObject &root) && +{ + return std::move(*this).json(QJsonDocument(root)); +} + +NetworkRequest NetworkRequest::json(const QJsonDocument &document) && +{ + return std::move(*this).json(document.toJson(QJsonDocument::Compact)); +} + +NetworkRequest NetworkRequest::json(const QByteArray &payload) && +{ + return std::move(*this) + .payload(payload) + .header(QNetworkRequest::ContentTypeHeader, "application/json") + .header(QNetworkRequest::ContentLengthHeader, payload.length()) + .header("Accept", "application/json"); } } // namespace chatterino diff --git a/src/common/NetworkRequest.hpp b/src/common/NetworkRequest.hpp index 85f34782a..9d55cf1b7 100644 --- a/src/common/NetworkRequest.hpp +++ b/src/common/NetworkRequest.hpp @@ -6,6 +6,10 @@ #include <memory> +class QJsonArray; +class QJsonObject; +class QJsonDocument; + namespace chatterino { struct NetworkData; @@ -24,8 +28,8 @@ public: explicit NetworkRequest( const std::string &url, NetworkRequestType requestType = NetworkRequestType::Get); - explicit NetworkRequest( - QUrl url, NetworkRequestType requestType = NetworkRequestType::Get); + explicit NetworkRequest(const QUrl &url, NetworkRequestType requestType = + NetworkRequestType::Get); // Enable move NetworkRequest(NetworkRequest &&other) = default; @@ -54,23 +58,25 @@ public: NetworkRequest header(const char *headerName, const char *value) &&; NetworkRequest header(const char *headerName, const QByteArray &value) &&; NetworkRequest header(const char *headerName, const QString &value) &&; + NetworkRequest header(QNetworkRequest::KnownHeaders header, + const QVariant &value) &&; NetworkRequest headerList( const std::vector<std::pair<QByteArray, QByteArray>> &headers) &&; NetworkRequest timeout(int ms) &&; NetworkRequest concurrent() &&; - NetworkRequest authorizeTwitchV5(const QString &clientID, - const QString &oauthToken = QString()) &&; NetworkRequest multiPart(QHttpMultiPart *payload) &&; /** * This will change `RedirectPolicyAttribute`. * `QNetworkRequest`'s defaults are used by default (Qt 5: no-follow, Qt 6: follow). */ NetworkRequest followRedirects(bool on) &&; + NetworkRequest json(const QJsonObject &root) &&; + NetworkRequest json(const QJsonArray &root) &&; + NetworkRequest json(const QJsonDocument &document) &&; + NetworkRequest json(const QByteArray &payload) &&; void execute(); - static NetworkRequest twitchRequest(QUrl url); - private: void initializeDefaultValues(); }; diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 4dc4f1222..662484c98 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -52,7 +52,7 @@ void Helix::fetchUsers(QStringList userIds, QStringList userLogins, } // TODO: set on success and on error - this->makeRequest("users", urlQuery) + this->makeGet("users", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -142,7 +142,7 @@ void Helix::fetchUsersFollows( } // TODO: set on success and on error - this->makeRequest("users/follows", urlQuery) + this->makeGet("users/follows", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); if (root.empty()) @@ -186,7 +186,7 @@ void Helix::fetchStreams( } // TODO: set on success and on error - this->makeRequest("streams", urlQuery) + this->makeGet("streams", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -279,7 +279,7 @@ void Helix::fetchGames(QStringList gameIds, QStringList gameNames, } // TODO: set on success and on error - this->makeRequest("games", urlQuery) + this->makeGet("games", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -315,7 +315,7 @@ void Helix::searchGames(QString gameName, QUrlQuery urlQuery; urlQuery.addQueryItem("query", gameName); - this->makeRequest("search/categories", urlQuery) + this->makeGet("search/categories", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -372,8 +372,7 @@ void Helix::createClip(QString channelId, QUrlQuery urlQuery; urlQuery.addQueryItem("broadcaster_id", channelId); - this->makeRequest("clips", urlQuery) - .type(NetworkRequestType::Post) + this->makePost("clips", urlQuery) .header("Content-Type", "application/json") .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); @@ -425,7 +424,7 @@ void Helix::getChannel(QString broadcasterId, QUrlQuery urlQuery; urlQuery.addQueryItem("broadcaster_id", broadcasterId); - this->makeRequest("channels", urlQuery) + this->makeGet("channels", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -460,10 +459,8 @@ void Helix::createStreamMarker( } payload.insert("user_id", QJsonValue(broadcasterId)); - this->makeRequest("streams/markers", QUrlQuery()) - .type(NetworkRequestType::Post) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePost("streams/markers", QUrlQuery()) + .json(payload) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -515,7 +512,7 @@ void Helix::loadBlocks(QString userId, urlQuery.addQueryItem("broadcaster_id", userId); urlQuery.addQueryItem("first", "100"); - this->makeRequest("users/blocks", urlQuery) + this->makeGet("users/blocks", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -551,8 +548,7 @@ void Helix::blockUser(QString targetUserId, QUrlQuery urlQuery; urlQuery.addQueryItem("target_user_id", targetUserId); - this->makeRequest("users/blocks", urlQuery) - .type(NetworkRequestType::Put) + this->makePut("users/blocks", urlQuery) .onSuccess([successCallback](auto /*result*/) -> Outcome { successCallback(); return Success; @@ -571,8 +567,7 @@ void Helix::unblockUser(QString targetUserId, QUrlQuery urlQuery; urlQuery.addQueryItem("target_user_id", targetUserId); - this->makeRequest("users/blocks", urlQuery) - .type(NetworkRequestType::Delete) + this->makeDelete("users/blocks", urlQuery) .onSuccess([successCallback](auto /*result*/) -> Outcome { successCallback(); return Success; @@ -590,7 +585,6 @@ void Helix::updateChannel(QString broadcasterId, QString gameId, HelixFailureCallback failureCallback) { QUrlQuery urlQuery; - auto data = QJsonDocument(); auto obj = QJsonObject(); if (!gameId.isEmpty()) { @@ -611,12 +605,9 @@ void Helix::updateChannel(QString broadcasterId, QString gameId, return; } - data.setObject(obj); urlQuery.addQueryItem("broadcaster_id", broadcasterId); - this->makeRequest("channels", urlQuery) - .type(NetworkRequestType::Patch) - .header("Content-Type", "application/json") - .payload(data.toJson()) + this->makePatch("channels", urlQuery) + .json(obj) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { successCallback(result); return Success; @@ -638,10 +629,8 @@ void Helix::manageAutoModMessages( payload.insert("msg_id", msgID); payload.insert("action", action); - this->makeRequest("moderation/automod/message", QUrlQuery()) - .type(NetworkRequestType::Post) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePost("moderation/automod/message", QUrlQuery()) + .json(payload) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { successCallback(); return Success; @@ -697,7 +686,7 @@ void Helix::getCheermotes( urlQuery.addQueryItem("broadcaster_id", broadcasterId); - this->makeRequest("bits/cheermotes", urlQuery) + this->makeGet("bits/cheermotes", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); auto data = root.value("data"); @@ -735,7 +724,7 @@ void Helix::getEmoteSetData(QString emoteSetId, urlQuery.addQueryItem("emote_set_id", emoteSetId); - this->makeRequest("chat/emotes/set", urlQuery) + this->makeGet("chat/emotes/set", urlQuery) .onSuccess([successCallback, failureCallback, emoteSetId](auto result) -> Outcome { QJsonObject root = result.parseJson(); @@ -767,7 +756,7 @@ void Helix::getChannelEmotes( QUrlQuery urlQuery; urlQuery.addQueryItem("broadcaster_id", broadcasterId); - this->makeRequest("chat/emotes", urlQuery) + this->makeGet("chat/emotes", urlQuery) .onSuccess([successCallback, failureCallback](NetworkResult result) -> Outcome { QJsonObject root = result.parseJson(); @@ -807,10 +796,8 @@ void Helix::updateUserChatColor( payload.insert("user_id", QJsonValue(userID)); payload.insert("color", QJsonValue(color)); - this->makeRequest("chat/color", QUrlQuery()) - .type(NetworkRequestType::Put) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePut("chat/color", QUrlQuery()) + .json(payload) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto obj = result.parseJson(); if (result.status() != 204) @@ -887,8 +874,7 @@ void Helix::deleteChatMessages( urlQuery.addQueryItem("message_id", messageID); } - this->makeRequest("moderation/chat", urlQuery) - .type(NetworkRequestType::Delete) + this->makeDelete("moderation/chat", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -966,8 +952,7 @@ void Helix::addChannelModerator( urlQuery.addQueryItem("broadcaster_id", broadcasterID); urlQuery.addQueryItem("user_id", userID); - this->makeRequest("moderation/moderators", urlQuery) - .type(NetworkRequestType::Post) + this->makePost("moderation/moderators", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1055,8 +1040,7 @@ void Helix::removeChannelModerator( urlQuery.addQueryItem("broadcaster_id", broadcasterID); urlQuery.addQueryItem("user_id", userID); - this->makeRequest("moderation/moderators", urlQuery) - .type(NetworkRequestType::Delete) + this->makeDelete("moderation/moderators", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1142,10 +1126,8 @@ void Helix::sendChatAnnouncement( std::string{magic_enum::enum_name<HelixAnnouncementColor>(color)}; body.insert("color", QString::fromStdString(colorStr).toLower()); - this->makeRequest("chat/announcements", urlQuery) - .type(NetworkRequestType::Post) - .header("Content-Type", "application/json") - .payload(QJsonDocument(body).toJson(QJsonDocument::Compact)) + this->makePost("chat/announcements", urlQuery) + .json(body) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1214,8 +1196,7 @@ void Helix::addChannelVIP( urlQuery.addQueryItem("broadcaster_id", broadcasterID); urlQuery.addQueryItem("user_id", userID); - this->makeRequest("channels/vips", urlQuery) - .type(NetworkRequestType::Post) + this->makePost("channels/vips", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1293,8 +1274,7 @@ void Helix::removeChannelVIP( urlQuery.addQueryItem("broadcaster_id", broadcasterID); urlQuery.addQueryItem("user_id", userID); - this->makeRequest("channels/vips", urlQuery) - .type(NetworkRequestType::Delete) + this->makeDelete("channels/vips", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1383,8 +1363,7 @@ void Helix::unbanUser( urlQuery.addQueryItem("moderator_id", moderatorID); urlQuery.addQueryItem("user_id", userID); - this->makeRequest("moderation/bans", urlQuery) - .type(NetworkRequestType::Delete) + this->makeDelete("moderation/bans", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1489,8 +1468,7 @@ void Helix::startRaid( urlQuery.addQueryItem("from_broadcaster_id", fromBroadcasterID); urlQuery.addQueryItem("to_broadcaster_id", toBroadcasterID); - this->makeRequest("raids", urlQuery) - .type(NetworkRequestType::Post) + this->makePost("raids", urlQuery) .onSuccess( [successCallback, failureCallback](auto /*result*/) -> Outcome { successCallback(); @@ -1570,8 +1548,7 @@ void Helix::cancelRaid( urlQuery.addQueryItem("broadcaster_id", broadcasterID); - this->makeRequest("raids", urlQuery) - .type(NetworkRequestType::Delete) + this->makeDelete("raids", urlQuery) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -1731,10 +1708,8 @@ void Helix::updateChatSettings( urlQuery.addQueryItem("broadcaster_id", broadcasterID); urlQuery.addQueryItem("moderator_id", moderatorID); - this->makeRequest("chat/settings", urlQuery) - .type(NetworkRequestType::Patch) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePatch("chat/settings", urlQuery) + .json(payload) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -1857,7 +1832,7 @@ void Helix::fetchChatters( urlQuery.addQueryItem("after", after); } - this->makeRequest("chat/chatters", urlQuery) + this->makeGet("chat/chatters", urlQuery) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -1966,7 +1941,7 @@ void Helix::fetchModerators( urlQuery.addQueryItem("after", after); } - this->makeRequest("moderation/moderators", urlQuery) + this->makeGet("moderation/moderators", urlQuery) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2051,10 +2026,8 @@ void Helix::banUser(QString broadcasterID, QString moderatorID, QString userID, payload["data"] = data; } - this->makeRequest("moderation/bans", urlQuery) - .type(NetworkRequestType::Post) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePost("moderation/bans", urlQuery) + .json(payload) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2150,10 +2123,8 @@ void Helix::sendWhisper( QJsonObject payload; payload["message"] = message; - this->makeRequest("whispers", urlQuery) - .type(NetworkRequestType::Post) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePost("whispers", urlQuery) + .json(payload) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 204) { @@ -2295,8 +2266,7 @@ void Helix::getChannelVIPs( // as the mod list can go over 100 (I assume, I see no limit) urlQuery.addQueryItem("first", "100"); - this->makeRequest("channels/vips", urlQuery) - .type(NetworkRequestType::Get) + this->makeGet("channels/vips", urlQuery) .header("Content-Type", "application/json") .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) @@ -2383,10 +2353,8 @@ void Helix::startCommercial( payload.insert("broadcaster_id", QJsonValue(broadcasterID)); payload.insert("length", QJsonValue(length)); - this->makeRequest("channels/commercial", QUrlQuery()) - .type(NetworkRequestType::Post) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePost("channels/commercial", QUrlQuery()) + .json(payload) .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto obj = result.parseJson(); if (obj.isEmpty()) @@ -2476,7 +2444,7 @@ void Helix::getGlobalBadges( { using Error = HelixGetGlobalBadgesError; - this->makeRequest("chat/badges/global", QUrlQuery()) + this->makeGet("chat/badges/global", QUrlQuery()) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2523,7 +2491,7 @@ void Helix::getChannelBadges( QUrlQuery urlQuery; urlQuery.addQueryItem("broadcaster_id", broadcasterID); - this->makeRequest("chat/badges", urlQuery) + this->makeGet("chat/badges", urlQuery) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2575,10 +2543,8 @@ void Helix::updateShieldMode( QJsonObject payload; payload["is_active"] = isActive; - this->makeRequest("moderation/shield_mode", urlQuery) - .type(NetworkRequestType::Put) - .header("Content-Type", "application/json") - .payload(QJsonDocument(payload).toJson(QJsonDocument::Compact)) + this->makePut("moderation/shield_mode", urlQuery) + .json(payload) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2631,7 +2597,8 @@ void Helix::updateShieldMode( .execute(); } -NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery) +NetworkRequest Helix::makeRequest(const QString &url, const QUrlQuery &urlQuery, + NetworkRequestType type) { assert(!url.startsWith("/")); @@ -2655,13 +2622,38 @@ NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery) fullUrl.setQuery(urlQuery); - return NetworkRequest(fullUrl) + return NetworkRequest(fullUrl, type) .timeout(5 * 1000) .header("Accept", "application/json") .header("Client-ID", this->clientId) .header("Authorization", "Bearer " + this->oauthToken); } +NetworkRequest Helix::makeGet(const QString &url, const QUrlQuery &urlQuery) +{ + return this->makeRequest(url, urlQuery, NetworkRequestType::Get); +} + +NetworkRequest Helix::makeDelete(const QString &url, const QUrlQuery &urlQuery) +{ + return this->makeRequest(url, urlQuery, NetworkRequestType::Delete); +} + +NetworkRequest Helix::makePost(const QString &url, const QUrlQuery &urlQuery) +{ + return this->makeRequest(url, urlQuery, NetworkRequestType::Post); +} + +NetworkRequest Helix::makePut(const QString &url, const QUrlQuery &urlQuery) +{ + return this->makeRequest(url, urlQuery, NetworkRequestType::Put); +} + +NetworkRequest Helix::makePatch(const QString &url, const QUrlQuery &urlQuery) +{ + return this->makeRequest(url, urlQuery, NetworkRequestType::Patch); +} + void Helix::update(QString clientId, QString oauthToken) { this->clientId = std::move(clientId); diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 0492b0560..f6dcc8f02 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -1361,7 +1361,13 @@ protected: FailureCallback<HelixGetModeratorsError, QString> failureCallback); private: - NetworkRequest makeRequest(QString url, QUrlQuery urlQuery); + NetworkRequest makeRequest(const QString &url, const QUrlQuery &urlQuery, + NetworkRequestType type); + NetworkRequest makeGet(const QString &url, const QUrlQuery &urlQuery); + NetworkRequest makeDelete(const QString &url, const QUrlQuery &urlQuery); + NetworkRequest makePost(const QString &url, const QUrlQuery &urlQuery); + NetworkRequest makePut(const QString &url, const QUrlQuery &urlQuery); + NetworkRequest makePatch(const QString &url, const QUrlQuery &urlQuery); QString clientId; QString oauthToken;