Restructure CURL code. There is no need to initialize CURL handle for each request, it can be reused.

sql-rework
Tomasz Golinski 2020-08-06 21:53:13 +02:00
rodzic b9f611f0b1
commit 8c2d633a51
2 zmienionych plików z 45 dodań i 34 usunięć

Wyświetl plik

@ -31,6 +31,21 @@ Okapi::Okapi(const std::string& server_url, const std::string& consumer_key) : u
service = "OC.ro";
if (url.find(".uk/") != std::string::npos)
service = "OC.uk";
curl = curl_easy_init();
if (!curl) {
curl_global_cleanup();
throw 0;
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&curl_output);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
}
Okapi::~Okapi() {
curl_easy_cleanup(curl);
}
// Callback for cURL easy interface used to save received output to std::string object
@ -40,25 +55,14 @@ size_t Okapi::write_cb(char* ptr, __attribute__((unused)) size_t size, size_t nm
return nmemb;
}
std::string Okapi::curl_post(const std::string& url, const std::string& post) const {
CURL* curl;
void Okapi::curl_post(const std::string& url, const std::string& post) const {
CURLcode res;
std::string output;
Debug(5) << "API query: " << post;
curl = curl_easy_init();
if (!curl) {
curl_global_cleanup();
throw 0;
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&output);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_output.clear();
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
@ -66,21 +70,19 @@ std::string Okapi::curl_post(const std::string& url, const std::string& post) co
curl_easy_cleanup(curl);
std::exit(EXIT_FAILURE);
}
curl_easy_cleanup(curl);
Debug(5) << "API query result: " << output;
if (output.starts_with("{\"error\"")) {
json j = json::parse(output);
Debug(5) << "API query result: " << curl_output;
if (curl_output.starts_with("{\"error\"")) {
json j = json::parse(curl_output);
Debug(1) << "OKAPI error: " << j["error"]["developer_message"];
std::exit(EXIT_FAILURE);
}
return output;
}
std::string Okapi::get_user_caches_json(const std::string& uuid, int count, int offset) const {
void Okapi::get_user_caches_json(const std::string& uuid, int count, int offset) const {
std::string service = url + OKAPI_logs;
std::string query = "consumer_key=" + key + "&user_uuid=" + uuid + "&fields=cache_code|type|date|was_recommended&limit=" + std::to_string(count) + "&offset=" + std::to_string(offset);
return curl_post(service, query);
curl_post(service, query);
}
// std::string Okapi::get_cache_json(std::string code) {
@ -89,10 +91,10 @@ std::string Okapi::get_user_caches_json(const std::string& uuid, int count, int
// return curl_post(service, query);
// }
std::string Okapi::get_caches_json(const std::string& codes) const {
void Okapi::get_caches_json(const std::string& codes) const {
std::string service = url + OKAPI_caches;
std::string query = "consumer_key=" + key + "&cache_codes=" + codes + "&fields=code|name|location|type|status|difficulty|terrain|owner|region|size2|date_created|recommendations|founds|status";
return curl_post(service, query);
curl_post(service, query);
}
// Cache Okapi::get_cache(std::string code) {
@ -138,8 +140,8 @@ Caches Okapi::get_caches(const std::set<std::string>& codes) const {
}
codes_list.pop_back(); // remove trailing '|'
std::string output = get_caches_json(codes_list);
json j = json::parse(output);
get_caches_json(codes_list);
json j = json::parse(curl_output);
codes_list.clear();
for (auto& el : j.items()) {
@ -193,8 +195,8 @@ Caches Okapi::get_user_caches(const std::string& uuid, int count) const {
if (count == 0)
do {
std::string output = get_user_caches_json(uuid, MAX_LOGS, off);
j = json::parse(output);
get_user_caches_json(uuid, MAX_LOGS, off);
j = json::parse(curl_output);
for (auto& el : j.items()) {
if (el.value()["type"] == "Found it") {
@ -210,8 +212,8 @@ Caches Okapi::get_user_caches(const std::string& uuid, int count) const {
else {
int count_req = (count > MAX_LOGS) ? MAX_LOGS : count;
do {
std::string output = get_user_caches_json(uuid, count_req, off);
j = json::parse(output);
get_user_caches_json(uuid, count_req, off);
j = json::parse(curl_output);
for (auto& el : j.items()) {
if (el.value()["type"] == "Found it") {
@ -252,19 +254,22 @@ void Okapi::update_caches(Caches& cc) const {
std::string Okapi::get_uuid(const std::string& username) const {
std::string service = url + OKAPI_username;
std::string query = "consumer_key=" + key + "&username=" + username + "&fields=uuid";
json j = json::parse(curl_post(service, query));
curl_post(service, query);
json j = json::parse(curl_output);
return j["uuid"];
}
std::string Okapi::get_profile_url(const std::string& uuid) const {
std::string service = url + OKAPI_user;
std::string query = "consumer_key=" + key + "&user_uuid=" + uuid + "&fields=profile_url";
json j = json::parse(curl_post(service, query));
curl_post(service, query);
json j = json::parse(curl_output);
return j["profile_url"];
}
std::string Okapi::get_changelog_json(int revision) const {
std::string service = url + OKAPI_changelog;
std::string query = "consumer_key=" + key + "&since=" + std::to_string(revision);
return curl_post(service, query);
curl_post(service, query);
return curl_output;
}

12
okapi.h
Wyświetl plik

@ -6,6 +6,8 @@
#include <map>
#include <utility>
typedef void CURL;
class Okapi : public Api {
private:
std::string url;
@ -13,17 +15,21 @@ private:
std::string service;
CURL* curl;
mutable std::string curl_output;
static size_t write_cb(char* ptr, size_t size, size_t nmemb, void* userdata);
std::string curl_post(const std::string& url, const std::string& post) const;
std::string get_user_caches_json(const std::string& uuid, int count = 0, int offset = 0) const;
void curl_post(const std::string& url, const std::string& post) const;
void get_user_caches_json(const std::string& uuid, int count = 0, int offset = 0) const;
// std::string get_cache_json(std::string code) const;
std::string get_caches_json(const std::string& codes) const;
void get_caches_json(const std::string& codes) const;
const static int MAX_LOGS = 1000;
const static int MAX_CACHES = 500;
public:
Okapi(const std::string& server_url, const std::string& consumer_key);
~Okapi();
// Cache get_cache(std::string code);
Caches get_caches(const std::set<std::string>& codes) const;