Remove authenticated get function from urlfetch

Implement twitch account emote getter function in TwitchAccount
This commit is contained in:
Rasmus Karlsson 2018-06-27 00:16:30 +00:00
parent d333da3dfa
commit f76512c31e
7 changed files with 86 additions and 52 deletions

@ -1 +1 @@
Subproject commit 8309a17041777dde281da617a5e4460df42ba5b9 Subproject commit 29accdf9dea05947d687112594ad06bf6001ee0a

View file

@ -18,10 +18,12 @@ struct Serialize<QString> {
template <> template <>
struct Deserialize<QString> { struct Deserialize<QString> {
static QString get(const rapidjson::Value &value) static QString get(const rapidjson::Value &value, bool *error = nullptr)
{ {
if (!value.IsString()) { if (!value.IsString()) {
throw std::runtime_error("Deserialized rapidjson::Value is not a string"); PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Deserialized rapidjson::Value is not a string");
return QString{};
} }
try { try {
@ -35,7 +37,7 @@ struct Deserialize<QString> {
// int y = 5; // int y = 5;
} }
return QString(); return QString{};
} }
}; };

View file

@ -50,21 +50,6 @@ static void twitchApiGet2(QString url, const QObject *caller, bool useQuickLoadC
}); });
} }
static void twitchApiGetAuthorized(QString url, const QString &clientID, const QString &oauthToken,
const QObject *caller,
std::function<void(const QJsonObject &)> successCallback)
{
NetworkRequest req(url);
req.setCaller(caller);
req.setRawHeader("Client-ID", clientID.toUtf8());
req.setRawHeader("Authorization", "OAuth " + oauthToken.toUtf8());
req.setRawHeader("Accept", "application/vnd.twitchtv.v5+json");
req.getJSON([=](const QJsonObject &node) {
successCallback(node); //
});
}
static void twitchApiGetUserID(QString username, const QObject *caller, static void twitchApiGetUserID(QString username, const QObject *caller,
std::function<void(QString)> successCallback) std::function<void(QString)> successCallback)
{ {

View file

@ -256,4 +256,42 @@ std::set<TwitchUser> TwitchAccount::getIgnores() const
return this->ignores; return this->ignores;
} }
void TwitchAccount::loadEmotes(std::function<void(const rapidjson::Document &)> cb)
{
Log("Loading Twitch emotes for user {}", this->getUserName());
const auto &clientID = this->getOAuthClient();
const auto &oauthToken = this->getOAuthToken();
if (clientID.isEmpty() || oauthToken.isEmpty()) {
Log("Missing Client ID or OAuth token");
return;
}
QString url("https://api.twitch.tv/kraken/users/" + this->getUserId() + "/emotes");
NetworkRequest req(url);
req.setRequestType(NetworkRequest::GetRequest);
req.setCaller(QThread::currentThread());
req.makeAuthorizedV5(this->getOAuthClient(), this->getOAuthToken());
req.onError([=](int errorCode) {
Log("Error {}", errorCode);
if (errorCode == 203) {
// onFinished(FollowResult_NotFollowing);
} else {
// onFinished(FollowResult_Failed);
}
return true;
});
req.onSuccess([=](const rapidjson::Document &document) {
cb(document);
return true;
});
req.execute();
}
} // namespace chatterino } // namespace chatterino

View file

@ -3,9 +3,12 @@
#include "controllers/accounts/Account.hpp" #include "controllers/accounts/Account.hpp"
#include "providers/twitch/TwitchUser.hpp" #include "providers/twitch/TwitchUser.hpp"
#include <rapidjson/document.h>
#include <QColor> #include <QColor>
#include <QString> #include <QString>
#include <functional>
#include <mutex>
#include <set> #include <set>
namespace chatterino { namespace chatterino {
@ -65,6 +68,8 @@ public:
std::set<TwitchUser> getIgnores() const; std::set<TwitchUser> getIgnores() const;
void loadEmotes(std::function<void(const rapidjson::Document &)> cb);
QColor color; QColor color;
private: private:

View file

@ -142,17 +142,7 @@ EmoteData TwitchEmotes::getEmoteById(const QString &id, const QString &emoteName
void TwitchEmotes::refresh(const std::shared_ptr<TwitchAccount> &user) void TwitchEmotes::refresh(const std::shared_ptr<TwitchAccount> &user)
{ {
Log("Loading Twitch emotes for user {}", user->getUserName());
const auto &roomID = user->getUserId(); const auto &roomID = user->getUserId();
const auto &clientID = user->getOAuthClient();
const auto &oauthToken = user->getOAuthToken();
if (clientID.isEmpty() || oauthToken.isEmpty()) {
Log("Missing Client ID or OAuth token");
return;
}
TwitchAccountEmoteData &emoteData = this->emotes[roomID]; TwitchAccountEmoteData &emoteData = this->emotes[roomID];
if (emoteData.filled) { if (emoteData.filled) {
@ -160,24 +150,44 @@ void TwitchEmotes::refresh(const std::shared_ptr<TwitchAccount> &user)
return; return;
} }
QString url("https://api.twitch.tv/kraken/users/" + roomID + "/emotes"); auto loadEmotes = [=, &emoteData](const rapidjson::Document &root) {
auto loadEmotes = [=, &emoteData](const QJsonObject &root) {
emoteData.emoteSets.clear(); emoteData.emoteSets.clear();
emoteData.emoteCodes.clear(); emoteData.emoteCodes.clear();
auto emoticonSets = root.value("emoticon_sets").toObject(); auto emoticonSets = root.FindMember("emoticon_sets");
for (QJsonObject::iterator it = emoticonSets.begin(); it != emoticonSets.end(); ++it) { if (emoticonSets == root.MemberEnd() || !emoticonSets->value.IsObject()) {
Log("No emoticon_sets in load emotes response");
return;
}
for (const auto &emoteSetJSON : emoticonSets->value.GetObject()) {
auto emoteSet = std::make_shared<EmoteSet>(); auto emoteSet = std::make_shared<EmoteSet>();
emoteSet->key = it.key(); emoteSet->key = emoteSetJSON.name.GetString();
loadSetData(emoteSet); loadSetData(emoteSet);
for (QJsonValue emoteValue : it.value().toArray()) { for (const rapidjson::Value &emoteJSON : emoteSetJSON.value.GetArray()) {
QJsonObject emoticon = emoteValue.toObject(); if (!emoteJSON.IsObject()) {
QString id = QString::number(emoticon["id"].toInt()); Log("Emote value was invalid");
QString code = emoticon["code"].toString(); return;
}
QString id, code;
uint64_t idNumber;
if (!rj::getSafe(emoteJSON, "id", idNumber)) {
Log("No ID key found in Emote value");
return;
}
if (!rj::getSafe(emoteJSON, "code", code)) {
Log("No code key found in Emote value");
return;
}
id = QString::number(idNumber);
auto cleanCode = cleanUpCode(code); auto cleanCode = cleanUpCode(code);
emoteSet->emotes.emplace_back(id, cleanCode); emoteSet->emotes.emplace_back(id, cleanCode);
@ -193,7 +203,7 @@ void TwitchEmotes::refresh(const std::shared_ptr<TwitchAccount> &user)
emoteData.filled = true; emoteData.filled = true;
}; };
twitchApiGetAuthorized(url, clientID, oauthToken, QThread::currentThread(), loadEmotes); user->loadEmotes(loadEmotes);
} }
void TwitchEmotes::loadSetData(std::shared_ptr<TwitchEmotes::EmoteSet> emoteSet) void TwitchEmotes::loadSetData(std::shared_ptr<TwitchEmotes::EmoteSet> emoteSet)

View file

@ -77,25 +77,19 @@ bool getSafe(const rapidjson::Value &obj, const char *key, Type &out)
return false; return false;
} }
try { bool error = false;
out = pajlada::Settings::Deserialize<Type>::get(obj[key]); out = pajlada::Settings::Deserialize<Type>::get(obj[key], &error);
} catch (const std::runtime_error &) {
return false;
}
return true; return !error;
} }
template <typename Type> template <typename Type>
bool getSafe(const rapidjson::Value &value, Type &out) bool getSafe(const rapidjson::Value &value, Type &out)
{ {
try { bool error = false;
out = pajlada::Settings::Deserialize<Type>::get(value); out = pajlada::Settings::Deserialize<Type>::get(value, &error);
} catch (const std::runtime_error &) {
return false;
}
return true; return !error;
} }
std::string stringify(const rapidjson::Value &value); std::string stringify(const rapidjson::Value &value);