diff --git a/cache.h b/cache.h index a4ef19d..fece0b9 100644 --- a/cache.h +++ b/cache.h @@ -54,6 +54,7 @@ public: class Cache { public: std::string code; + int internal_id; Position pos; std::string name; Status status; @@ -86,6 +87,7 @@ public: int age_when_found = -1; int age_now = -1; int trail = 0; + bool ftf = 0; void set_date(const std::tm& t); void set_date_hidden(const std::tm& t); diff --git a/geostat.cpp b/geostat.cpp index d517d77..98b6889 100644 --- a/geostat.cpp +++ b/geostat.cpp @@ -201,7 +201,8 @@ int main(int argc, char** argv) { if (use_oc) { if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { Okapi OCpl(ocpl_url, ocpl_key); - if (!ocpl_user.empty()) ocpl_user_uuid = OCpl.get_uuid(ocpl_user); + int uid; + if (!ocpl_user.empty()) ocpl_user_uuid = OCpl.get_uuid(ocpl_user, &uid); Caches tmp = OCpl.get_user_caches(ocpl_user_uuid, 0); t.read_from_json("powertrails.json"); @@ -217,6 +218,8 @@ int main(int argc, char** argv) { } } + OCpl.get_ftf(uid, tmp); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); ocpl_user_profile = OCpl.get_profile_url(ocpl_user_uuid); } @@ -346,6 +349,7 @@ int main(int argc, char** argv) { pCaches caches_by_fav; pCaches caches_by_fav_perc; pCaches caches_by_finds; + pCaches caches_ftf; // pCaches caches_by_rating; pCaches fcc; @@ -369,7 +373,8 @@ int main(int argc, char** argv) { caches_by_fav_perc.push_back(&*i); caches_by_finds.push_back(&*i); // caches_by_rating.push_back(&*i); - + if (i->ftf) + caches_ftf.push_back(&*i); i++; } std::sort(caches_by_fav.begin(), caches_by_fav.end(), [&](const Cache* a, const Cache* b) { return a->fav > b->fav; }); @@ -910,6 +915,34 @@ int main(int argc, char** argv) { std::cout << "Number of started power trails: " << tt.size() << "
\n"; std::cout << "\n"; + std::cout << "

FTF

\n"; + std::cout << "\n"; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << "\n"; + + n = 1; + + for (auto i : caches_ftf) { + std::cout << " "; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << ""; + std::cout << "\n"; + n++; +// if (n > LIST_MAX) break; + } + std::cout << "
CacheTypeRegionDate hiddenFinds
" << n << "" << i->link_name() << "" << i->type << "" << i->region << "" << i->date_hidden << "" << i->founds << "
\n"; + std::cout << "
\n"; +// std::cout << "Number of FTFs: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.ftf; }) << "
\n"; + std::cout << "Number of FTFs: " << caches_ftf.size() << "
\n"; + std::cout << "
\n"; } // end of main if if (get_not_found) { diff --git a/okapi.cpp b/okapi.cpp index 2f3e6a2..fa6f7cb 100644 --- a/okapi.cpp +++ b/okapi.cpp @@ -93,7 +93,7 @@ void Okapi::get_user_caches_json(const std::string& uuid, int count, int offset) 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|country2|size2|date_created|recommendations|rating|founds|status"; + std::string query = "consumer_key=" + key + "&cache_codes=" + codes + "&fields=code|name|location|type|status|difficulty|terrain|owner|region|country2|size2|date_created|recommendations|rating|founds|status|internal_id"; curl_post(service, query); } @@ -153,6 +153,7 @@ Caches Okapi::get_caches(const std::set& codes) const { for (auto& el : j.items()) { if (el.value().is_null()) continue; c.code = el.value()["code"]; + c.internal_id = el.value()["internal_id"]; c.name = el.value()["name"]; c.type = el.value()["type"]; c.size = el.value()["size2"]; @@ -310,13 +311,14 @@ void Okapi::update_caches_ratings(Caches& cc) const { } } -std::string Okapi::get_uuid(const std::string& username) const { +std::string Okapi::get_uuid(const std::string& username, int* id) const { std::string service = url + OKAPI_username; char* user_esc = curl_easy_escape(curl, username.c_str(), username.size()); - std::string query = "consumer_key=" + key + "&username=" + user_esc + "&fields=uuid"; + std::string query = "consumer_key=" + key + "&username=" + user_esc + "&fields=uuid|internal_id"; curl_free(user_esc); curl_post(service, query); json j = json::parse(curl_output); + if (id) *id = j["internal_id"]; return j["uuid"]; } @@ -334,3 +336,29 @@ std::string Okapi::get_changelog_json(int revision) const { curl_post(service, query); return curl_output; } + +void Okapi::get_ftf(int id, Caches& cc) const { + std::string url = "https://opencaching.pl/UserProfile/getUserFtfsAjax/" + std::to_string(id); + CURLcode res; + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ""); + curl_output.clear(); + + res = curl_easy_perform(curl); + if (res != CURLE_OK) { + Debug(1) << "Connection failed: " << curl_easy_strerror(res) << '\n'; + curl_easy_cleanup(curl); + std::exit(EXIT_FAILURE); + } + + Debug(5) << "FTF query result: " << curl_output; + json j = json::parse(curl_output); + for (auto& el : j.items()) { + if (el.value().is_null()) continue; + int id = std::stoi(el.value()["cache_id"].get()); + auto res = std::find_if(cc.begin(), cc.end(), [&](const auto& a) { return a.internal_id == id; }); + if (res != std::end(cc)) + res->ftf = 1; + } +} diff --git a/okapi.h b/okapi.h index 42e7555..c0db747 100644 --- a/okapi.h +++ b/okapi.h @@ -40,6 +40,7 @@ public: void update_caches(Caches& cc) const; void update_caches_ratings(Caches& cc) const; - std::string get_uuid(const std::string& username) const; + std::string get_uuid(const std::string& username, int* id = nullptr) const; std::string get_profile_url(const std::string& uuid) const; + void get_ftf(int id, Caches& cc) const; };