diff --git a/cache.cpp b/cache.cpp index f937cd1..de708d8 100644 --- a/cache.cpp +++ b/cache.cpp @@ -1,20 +1,6 @@ #include "cache.h" -#include "common.h" #include -#include - -Position Cache::home; - -Position::Position(std::string loc) { - int pos = loc.find("|"); - lat = stof(loc.substr(0, pos)); - lon = stof(loc.substr(pos + 1)); -} - -static float degtorad(float x) { - return x * M_PI / 180; -} void Cache::show() const { std::cout << "Cache:\t" << code << ' ' << name << " ("; @@ -87,7 +73,3 @@ void Cache::set_date_hidden(const std::tm& t) { age_now = (std::time(nullptr) - date_hidden_t) / (60 * 60 * 24); } - -float cache_distance(const Cache& a, const Cache& b) { - return 2 * Earth_radius * asin(sqrt(pow(sin(degtorad((a.pos.lat - b.pos.lat) / 2)), 2) + cos(degtorad(a.pos.lat)) * cos(degtorad(b.pos.lat)) * pow(sin(degtorad((a.pos.lon - b.pos.lon) / 2)), 2))); -} diff --git a/cache.h b/cache.h index b3bbfbc..a57849e 100644 --- a/cache.h +++ b/cache.h @@ -1,12 +1,11 @@ #pragma once #include -#include -#include -#include #include #include +#include "common.h" + // enum Service { // gc, // ocpl, @@ -41,16 +40,6 @@ enum Status { const uint Earth_radius = 6378; const uint Moon_dist = 384400; -class Position { -public: - float lat = 0; - float lon = 0; - - Position() = default; - Position(float y, float x) : lat(y), lon(x) {} - explicit Position(std::string loc); -}; - class Cache { public: std::string code; @@ -100,9 +89,3 @@ public: std::string safe_name() const; float distance() const; }; - -typedef std::vector Caches; -typedef std::vector pCaches; -typedef std::multimap Date_Caches; - -float cache_distance(const Cache& a, const Cache& b); diff --git a/common.cpp b/common.cpp index a4392c1..6305bfe 100644 --- a/common.cpp +++ b/common.cpp @@ -1,10 +1,16 @@ #include "common.h" +#include "cache.h" #include "debug.h" #include #include #include #include +#include + +float degtorad(float x) { + return x * M_PI / 180; +} void htmlencode(std::string& data) { std::string tmp; @@ -343,3 +349,15 @@ void footer_html() { std::cout << "\n"; std::cout << "\n\n"; } + +Position Cache::home; + +Position::Position(std::string loc) { + int pos = loc.find("|"); + lat = stof(loc.substr(0, pos)); + lon = stof(loc.substr(pos + 1)); +} + +float cache_distance(const Cache& a, const Cache& b) { + return 2 * Earth_radius * asin(sqrt(pow(sin(degtorad((a.pos.lat - b.pos.lat) / 2)), 2) + cos(degtorad(a.pos.lat)) * cos(degtorad(b.pos.lat)) * pow(sin(degtorad((a.pos.lon - b.pos.lon) / 2)), 2))); +} diff --git a/common.h b/common.h index ed35911..f32e741 100644 --- a/common.h +++ b/common.h @@ -1,9 +1,20 @@ #pragma once -#include "cache.h" -#include "powertrail.h" +// #include "cache.h" +// #include "powertrail.h" #include +#include +#include +#include +#include +#include + +class Cache; + +typedef std::vector Caches; +typedef std::vector pCaches; +typedef std::multimap Date_Caches; const std::string ocpl_url = "https://opencaching.pl/okapi/"; const std::string ocde_url = "https://www.opencaching.de/okapi/"; @@ -45,3 +56,18 @@ int count_caches(const Caches& cc, std::string& codes, std::function #include @@ -47,38 +42,14 @@ int main(int argc, char** argv) { std::string heat_file; int heat_stamp_size = 15; std::string heat_map = "Poland"; + User user; bool heat_exp = 0; bool trail = 0; bool anim = 0; - bool use_oc = 0; - bool use_ocdb = 0; - bool get_not_found = 0; - bool get_owned = 0; - bool exclude_quiz = 0; - std::time_t start_time = 0; - std::time_t end_time = std::time(nullptr); - bool time_filter = 0; - - std::string ocpl_user; - std::string ocde_user; - std::string ocus_user; - std::string ocnl_user; - std::string ocro_user; - std::string ocuk_user; - - std::string ocpl_user_profile; - std::string ocde_user_profile; - std::string ocus_user_profile; - std::string ocnl_user_profile; - std::string ocro_user_profile; - std::string ocuk_user_profile; - -// std::string gpx_file; - -#include "config_user.h" if (argc == 1) show_usage(); + int o; while ((o = getopt(argc, argv, "qNOQD:o::p:d:u:n:r:k:i:f:H:s:m:etah?")) != -1) switch (o) { @@ -89,53 +60,53 @@ int main(int argc, char** argv) { // gpx_file = optarg; // break; case 'o': - use_oc = 1; + user.use_oc = 1; if (optarg) { - ocpl_user = optarg; - ocde_user = optarg; - ocus_user = optarg; - ocnl_user = optarg; - ocro_user = optarg; - ocuk_user = optarg; + user.ocpl_user = optarg; + user.ocde_user = optarg; + user.ocus_user = optarg; + user.ocnl_user = optarg; + user.ocro_user = optarg; + user.ocuk_user = optarg; } break; case 'p': - ocpl_user = optarg; + user.ocpl_user = optarg; break; case 'd': - ocde_user = optarg; + user.ocde_user = optarg; break; case 'u': - ocus_user = optarg; + user.ocus_user = optarg; break; case 'n': - ocnl_user = optarg; + user.ocnl_user = optarg; break; case 'r': - ocro_user = optarg; + user.ocro_user = optarg; break; case 'k': - ocuk_user = optarg; + user.ocuk_user = optarg; break; case 'q': - use_ocdb = 1; + user.use_ocdb = 1; break; case 'i': - start_time = get_num('i', optarg); - time_filter = 1; + user.start_time = get_num('i', optarg); + user.time_filter = 1; break; case 'f': - end_time = get_num('f', optarg); - time_filter = 1; + user.end_time = get_num('f', optarg); + user.time_filter = 1; break; case 'N': - get_not_found = 1; + user.get_not_found = 1; break; case 'O': - get_owned = 1; + user.get_owned = 1; break; case 'Q': - exclude_quiz = 1; + user.exclude_quiz = 1; break; case 'H': heat_file = optarg; @@ -161,22 +132,15 @@ int main(int argc, char** argv) { show_usage(); } - Caches cc; - PowertrailDB t; - Caches_in_Powertrails tc; - pPowertrails tt; - - std::map region_count; - - if (get_not_found || get_owned) { - use_oc = 0; - use_ocdb = 1; + if (user.get_not_found || user.get_owned) { + user.use_oc = 0; + user.use_ocdb = 1; trail = 0; - if (ocpl_user_uuid.empty() && ocpl_user.empty() && ocde_user_uuid.empty() && ocde_user.empty()) { + if (user.ocpl_user_uuid.empty() && user.ocpl_user.empty() && user.ocde_user_uuid.empty() && user.ocde_user.empty()) { std::cout << "Options \"-N\" or \"-O\" work only with OCpl or OCde.\n"; std::exit(EXIT_FAILURE); } - if (get_not_found && get_owned) { + if (user.get_not_found && user.get_owned) { std::cout << "Options \"-N\" and \"-O\" are mutually exclusive.\n"; std::exit(EXIT_FAILURE); } @@ -187,228 +151,20 @@ int main(int argc, char** argv) { std::exit(EXIT_FAILURE); } - if (use_oc) { - if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { - Okapi OCpl(ocpl_url, ocpl_key); - uint uid; - if (!ocpl_user.empty()) ocpl_user_uuid = OCpl.get_uuid(ocpl_user, &uid); - Caches tmp = OCpl.get_user_caches(ocpl_user_uuid, 0); + user.get_caches(); - t.read_from_json("powertrails.json"); - tc.read_from_json("caches_in_power.json"); - - std::unordered_map tt_map; // Needed to deduplicate trails - - for (auto& c : tmp) { - if (tc.data.count(c.code) > 0) { - c.trail = tc.data[c.code]; - t.data[c.trail].found++; - if (c.status == ok) - t.data[c.trail].active_caches_not_found--; - tt_map[c.trail] = &(t.data[c.trail]); - } - } - for (const auto& i : tt_map) { - i.second->completed_perc = (100 * i.second->found / i.second->caches.size()); - if (i.second->found >= i.second->treshold ) - i.second->completed = 1; - else - i.second->needed = i.second->treshold - i.second->found; - tt.push_back(i.second); - } - std::sort(tt.begin(), tt.end(), [&](const auto& a, const auto& b) { return a->completed_perc > b->completed_perc; }); - - 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); - } - if (!ocde_user_uuid.empty() || !ocde_user.empty()) { - Okapi OCde(ocde_url, ocde_key); - if (!ocde_user.empty()) ocde_user_uuid = OCde.get_uuid(ocde_user); - Caches tmp = OCde.get_user_caches(ocde_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - ocde_user_profile = OCde.get_profile_url(ocde_user_uuid); - } - if (!ocus_user_uuid.empty() || !ocus_user.empty()) { - Okapi OCus(ocus_url, ocus_key); - if (!ocus_user.empty()) ocus_user_uuid = OCus.get_uuid(ocus_user); - Caches tmp = OCus.get_user_caches(ocus_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - ocus_user_profile = OCus.get_profile_url(ocus_user_uuid); - } - if (!ocnl_user_uuid.empty() || !ocnl_user.empty()) { - Okapi OCnl(ocnl_url, ocnl_key); - if (!ocnl_user.empty()) ocnl_user_uuid = OCnl.get_uuid(ocnl_user); - Caches tmp = OCnl.get_user_caches(ocnl_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - ocnl_user_profile = OCnl.get_profile_url(ocnl_user_uuid); - } - if (!ocro_user_uuid.empty() || !ocro_user.empty()) { - Okapi OCro(ocro_url, ocro_key); - if (!ocro_user.empty()) ocro_user_uuid = OCro.get_uuid(ocro_user); - Caches tmp = OCro.get_user_caches(ocro_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - ocro_user_profile = OCro.get_profile_url(ocro_user_uuid); - } - if (!ocuk_user_uuid.empty() || !ocuk_user.empty()) { - Okapi OCuk(ocuk_url, ocuk_key); - if (!ocuk_user.empty()) ocuk_user_uuid = OCuk.get_uuid(ocuk_user); - Caches tmp = OCuk.get_user_caches(ocuk_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - ocuk_user_profile = OCuk.get_profile_url(ocuk_user_uuid); - } - } - -// if (!gpx_file.empty()) { -// GPX gpxfile(gpx_file); -// Caches tmp = gpxfile.get_user_caches(); -// std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); -// } - - if (use_ocdb) { - if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { - OCdb db(Database_pl); - if (!ocpl_user.empty()) { - Okapi OCpl(ocpl_url, ocpl_key); - ocpl_user_uuid = OCpl.get_uuid(ocpl_user); - ocpl_user_profile = OCpl.get_profile_url(ocpl_user_uuid); - } - if (get_not_found) { - Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid); - Okapi OCpl(ocpl_url, ocpl_key); - OCpl.update_caches(tmp); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - region_count = db.get_region_stats(); - } else if (get_owned) { - Caches tmp = db.get_user_caches_owned(ocpl_user_uuid); - Okapi OCpl(ocpl_url, ocpl_key); - OCpl.update_caches(tmp); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } else { - Caches tmp = db.get_user_caches(ocpl_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - } - if (!ocde_user_uuid.empty() || !ocde_user.empty()) { - OCdb db(Database_de); - if (!ocde_user.empty()) { - Okapi OCde(ocde_url, ocde_key); - ocde_user_uuid = OCde.get_uuid(ocde_user); - ocde_user_profile = OCde.get_profile_url(ocde_user_uuid); - } - if (get_not_found) { - Caches tmp = db.get_user_caches_not_found(ocde_user_uuid); - Okapi OCde(ocde_url, ocde_key); - OCde.update_caches(tmp); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); -// region_count = db.get_region_stats(); - } else if (get_owned) { - Caches tmp = db.get_user_caches_owned(ocde_user_uuid); - Okapi OCde(ocde_url, ocde_key); - OCde.update_caches(tmp); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } else { - Caches tmp = db.get_user_caches(ocde_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - } - } - - // TODO: some cache deduplication is needed - - Debug(2) << "Caches read: " << cc.size() << '\n'; - if (cc.size() == 0) { + if (user.caches_count == 0) { std::cout << "No caches found, aborting.\n"; std::exit(EXIT_FAILURE); } - // Prepare a set of regions - Country poland({ "dolnoslaskie", - "gornoslaskie", - "kujawsko-pomorskie", - "lodzkie", - "lubelskie", - "lubuskie", - "malopolskie", - "mazowieckie", - "opolskie", - "podkarpackie", - "podlaskie", - "pomorskie", - "swietokrzyskie", - "warminsko-mazurskie", - "wielkopolskie", - "zachodniopomorskie" }); - - // Prepare sorted list of caches, excluding moving caches - std::map dates; - Date_Caches sorted_caches; - Date_Caches sorted_fcaches; - Date_Caches sorted_caches_by_hidden; - pCaches caches_by_fav; - pCaches caches_by_fav_perc; - pCaches caches_by_finds; - pCaches caches_ftf; - // pCaches caches_by_rating; - pCaches fcc; - - if (!get_not_found) { - for (auto i = cc.begin(); i != cc.end();) { - if (time_filter && (i->date_t > end_time || i->date_t < start_time)) { - i = cc.erase(i); - continue; - } - - poland.locate(*i); - - dates[i->date]++; - sorted_caches.insert({ i->date_t, &*i }); - if ((i->type != "Moving" && i->type != "Own") || get_owned) { - sorted_fcaches.insert({ i->date_t, &*i }); - fcc.push_back(&*i); - } - sorted_caches_by_hidden.insert({ i->date_hidden_t, &*i }); - caches_by_fav.push_back(&*i); - 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; }); - std::sort(caches_by_fav_perc.begin(), caches_by_fav_perc.end(), [&](const Cache* a, const Cache* b) { return 1.0 * a->fav / a->founds > 1.0 * b->fav / b->founds; }); - std::sort(caches_by_finds.begin(), caches_by_finds.end(), [&](const Cache* a, const Cache* b) { return a->founds > b->founds; }); - // std::sort(caches_by_rating.begin(), caches_by_rating.end(), [&](const Cache* a, const Cache* b) { return a->rating > b->rating; }); - } else { - for (auto& i : cc) { - if (i.type != "Moving" && i.type != "Own" && (!exclude_quiz || i.type != "Quiz")) { - fcc.push_back(&i); - poland.locate(i); - } - } - } + user.prepare_lists_of_caches(); header_html(); + user.header(); - std::cout << "
\n"; - std::cout << "

Geocaching stats for user profiles:

\n"; - if (!ocpl_user.empty()) - std::cout << "\"OCpl\" " << ocpl_user << "
\n"; - if (!ocde_user.empty()) - std::cout << "\"OCde\" " << ocde_user << "
\n"; - if (!ocus_user.empty()) - std::cout << "\"OCna\" " << ocus_user << "
\n"; - if (!ocnl_user.empty()) - std::cout << "\"OCnl\" " << ocnl_user << "
\n"; - if (!ocro_user.empty()) - std::cout << "\"OCro\" " << ocro_user << "
\n"; - if (!ocuk_user.empty()) - std::cout << "\"OCuk\" " << ocuk_user << "
\n"; - - if (time_filter) { - std::cout << "for time range " << std::put_time(std::localtime(&start_time), "%x") << "—" << std::put_time(std::localtime(&end_time), "%x"); + if (user.time_filter) { + std::cout << "for time range " << std::put_time(std::localtime(&user.start_time), "%x") << "—" << std::put_time(std::localtime(&user.end_time), "%x"); } std::cout << "
\n"; @@ -423,15 +179,15 @@ int main(int argc, char** argv) { } Heat hmap(chosen_map); if (trail) { - if (sorted_fcaches.size() < 2) { + if (user.sorted_fcaches.size() < 2) { std::cout << "You need at least 2 caches for a trail.\n"; std::exit(EXIT_FAILURE); } - hmap.generate_path(heat_file, sorted_fcaches); + hmap.generate_path(heat_file, user.sorted_fcaches); } else if (anim) - hmap.generate_anim(heat_file, sorted_fcaches, heat_stamp_size); + hmap.generate_anim(heat_file, user.sorted_fcaches, heat_stamp_size); else - hmap.generate(heat_file, fcc, heat_stamp_size, (heat_exp == 1 ? "exp" : "soft")); + hmap.generate(heat_file, user.fcc, heat_stamp_size, (heat_exp == 1 ? "exp" : "soft")); if (!anim) std::cout << "
\n\"heat\n
\n"; else { @@ -443,50 +199,50 @@ int main(int argc, char** argv) { } } - if (!get_not_found && !get_owned) { + if (!user.get_not_found && !user.get_owned) { short count; std::string codes; int n; std::cout << "
\n"; - std::cout << "Number of caches found: " << cc.size() << "
\n"; + std::cout << "Number of caches found: " << user.cc.size() << "
\n"; - auto best_day = std::max_element(dates.begin(), dates.end(), [&](const auto& a, const auto& b) { return a.second < b.second; }); - std::cout << "Number of caching days: " << dates.size() << "
\n"; - std::cout << "Average caches per caching day: " << std::setprecision(3) << (1.0 * cc.size()) / dates.size() << "
\n"; + auto best_day = std::max_element(user.dates.begin(), user.dates.end(), [&](const auto& a, const auto& b) { return a.second < b.second; }); + std::cout << "Number of caching days: " << user.dates.size() << "
\n"; + std::cout << "Average caches per caching day: " << std::setprecision(3) << (1.0 * user.cc.size()) / user.dates.size() << "
\n"; std::cout << std::resetiosflags(std::cout.flags()); - std::cout << "Number of caches that are now archived: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.status == archived; }) << "
\n"; + std::cout << "Number of caches that are now archived: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.status == archived; }) << "
\n"; std::cout << "
Best caching day: " << best_day->first << ", found " << best_day->second << " caches\n"; std::cout << "

\n"; - for (const auto& i : dates) + for (const auto& i : user.dates) std::cout << i.first << ", found " << i.second << " caches
\n"; std::cout << "

\n
\n"; std::time_t streak; - int longest_str = find_streak(sorted_caches, streak); + int longest_str = find_streak(user.sorted_caches, streak); char str_tmp[20]; std::tm* str_tm = std::localtime(&streak); std::strftime(str_tmp, 20, "%F", str_tm); std::cout << "Longest caching streak: " << longest_str << " starting on " << str_tmp << "
\n"; float tot_dist = 0; - for (auto i = sorted_fcaches.begin(); i != std::prev(sorted_fcaches.end()); i++) { + for (auto i = user.sorted_fcaches.begin(); i != std::prev(user.sorted_fcaches.end()); i++) { //std::cout << "Distance between " << i->second->name << " and " << std::next(i)->second->name << " is " << cache_distance(*i->second, *std::next(i)->second) << "
"; tot_dist += cache_distance(*i->second, *std::next(i)->second); } std::cout << "Total distance between caches: " << std::fixed << tot_dist << " km (equivalent to " << tot_dist / (2 * M_PI * Earth_radius) << "x trips around Earth or " << tot_dist / Moon_dist << "x trips to the Moon)
\n"; std::cout << std::resetiosflags(std::cout.flags()); - if (sorted_fcaches.size() > 1) - std::cout << "Average distance between caches: " << tot_dist / (sorted_fcaches.size() - 1) << " km
\n"; + if (user.sorted_fcaches.size() > 1) + std::cout << "Average distance between caches: " << tot_dist / (user.sorted_fcaches.size() - 1) << " km
\n"; std::cout << "
\n"; - short y_min = std::min_element(cc.begin(), cc.end(), [&](const Cache& a, const Cache& b) { return a.date_tm.tm_year < b.date_tm.tm_year; })->date_tm.tm_year; - short y_max = std::max_element(cc.begin(), cc.end(), [&](const Cache& a, const Cache& b) { return a.date_tm.tm_year < b.date_tm.tm_year; })->date_tm.tm_year; + short y_min = std::min_element(user.cc.begin(), user.cc.end(), [&](const Cache& a, const Cache& b) { return a.date_tm.tm_year < b.date_tm.tm_year; })->date_tm.tm_year; + short y_max = std::max_element(user.cc.begin(), user.cc.end(), [&](const Cache& a, const Cache& b) { return a.date_tm.tm_year < b.date_tm.tm_year; })->date_tm.tm_year; long max = 0; // maximal value for histogram for (int i = y_min; i <= y_max; i++) for (int j = 1; j <= 12; j++) - max = std::max(max, std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.date_tm.tm_year == i && c.date_tm.tm_mon == j - 1); })); + max = std::max(max, std::count_if(user.cc.begin(), user.cc.end(), [i, j](Cache c) { return (c.date_tm.tm_year == i && c.date_tm.tm_mon == j - 1); })); if (max > 0) { std::cout << "

Caching timeline

\n"; @@ -500,7 +256,7 @@ int main(int argc, char** argv) { for (int i = y_min; i <= y_max; i++) { // i -> years in rows std::cout << "" << i + 1900 << " "; for (int j = 1; j <= 12; j++) { // j -> months in cols - count = std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.date_tm.tm_year == i && c.date_tm.tm_mon == j - 1); }); + count = std::count_if(user.cc.begin(), user.cc.end(), [i, j](Cache c) { return (c.date_tm.tm_year == i && c.date_tm.tm_mon == j - 1); }); std::cout << "" << count << ""; } std::cout << "\n"; @@ -522,7 +278,7 @@ int main(int argc, char** argv) { std::cout << "" << i + 1900 << " "; for (int j = 1; j <= 12; j++) { // j -> months in cols std::map days_count; - for (auto el : cc) { + for (auto el : user.cc) { if (el.date_tm.tm_mon == j - 1 && el.date_tm.tm_year == i) days_count[el.date_tm.tm_mday]++; } @@ -541,21 +297,21 @@ int main(int argc, char** argv) { // far->show(); // show_histogram(cc, &Cache::year_month, "Caching timeline", 1, 0); - show_histogram(cc, &Cache::owner, "Cache owners", 1); - show_histogram(cc, &Cache::type, "Cache types", 1); - show_histogram(cc, &Cache::size, "Cache sizes", 1); + show_histogram(user.cc, &Cache::owner, "Cache owners", 1); + show_histogram(user.cc, &Cache::type, "Cache types", 1); + show_histogram(user.cc, &Cache::size, "Cache sizes", 1); // show_histogram(fcc, &Cache::region, "Regions", 1); // show_histogram(fcc, &Cache::subregion, "Subregions", 1); - show_histogram(fcc, &Cache::country, "Countries", 1); - show_nested_histogram(fcc, &Cache::region, &Cache::subregion, "Regions", 1); - show_histogram(cc, &Cache::day_of_week, "Days of the week", 1, 0); - show_histogram(cc, &Cache::mon, "Months", 1, 0); - show_histogram(cc, &Cache::year, "Years", 1, 0); + show_histogram(user.fcc, &Cache::country, "Countries", 1); + show_nested_histogram(user.fcc, &Cache::region, &Cache::subregion, "Regions", 1); + show_histogram(user.cc, &Cache::day_of_week, "Days of the week", 1, 0); + show_histogram(user.cc, &Cache::mon, "Months", 1, 0); + show_histogram(user.cc, &Cache::year, "Years", 1, 0); - auto N = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); - auto S = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); - auto E = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); - auto W = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto N = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto S = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto E = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto W = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); std::cout << "

Geographically extreme caches

\n"; std::cout << "\n"; @@ -583,7 +339,7 @@ int main(int argc, char** argv) { std::cout << ""; std::cout << "\n"; - for (auto i = sorted_caches_by_hidden.begin(); i != sorted_caches_by_hidden.end(); i++) { + for (auto i = user.sorted_caches_by_hidden.begin(); i != user.sorted_caches_by_hidden.end(); i++) { std::cout << " "; std::cout << ""; std::cout << ""; @@ -608,7 +364,7 @@ int main(int argc, char** argv) { std::cout << ""; std::cout << "\n"; - for (auto i = sorted_caches_by_hidden.rbegin(); i != sorted_caches_by_hidden.rend(); i++) { + for (auto i = user.sorted_caches_by_hidden.rbegin(); i != user.sorted_caches_by_hidden.rend(); i++) { std::cout << " "; std::cout << ""; std::cout << ""; @@ -622,13 +378,13 @@ int main(int argc, char** argv) { std::cout << "
Date found
" << n << "" << i->second->link_name() << "" << i->second->type << "Date found
" << n << "" << i->second->link_name() << "" << i->second->type << "
\n"; std::cout << "
\n"; - std::cout << "Average age of cache at the moment of finding: " << average(cc, &Cache::age_when_found) / 365 * 12 << " months
\n"; - std::cout << "Number of caches found within first 24h: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found == 0; }) << "
\n"; - std::cout << "Number of caches found within first 48h: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found <= 1; }) << "
\n"; - std::cout << "Number of caches found during first week: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found < 7; }) << "
\n"; - std::cout << "Number of caches found during first month: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found < 30; }) << "
\n"; - std::cout << "Number of caches found after more than 5 years: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 5; }) << "
\n"; - std::cout << "Number of caches found after more than 10 years: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 10; }) << "
\n"; + std::cout << "Average age of cache at the moment of finding: " << average(user.cc, &Cache::age_when_found) / 365 * 12 << " months
\n"; + std::cout << "Number of caches found within first 24h: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found == 0; }) << "
\n"; + std::cout << "Number of caches found within first 48h: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found <= 1; }) << "
\n"; + std::cout << "Number of caches found during first week: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found < 7; }) << "
\n"; + std::cout << "Number of caches found during first month: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found < 30; }) << "
\n"; + std::cout << "Number of caches found after more than 5 years: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 5; }) << "
\n"; + std::cout << "Number of caches found after more than 10 years: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 10; }) << "
\n"; std::cout << "
\n"; n = 1; @@ -644,7 +400,7 @@ int main(int argc, char** argv) { std::cout << "%"; std::cout << "\n"; - for (auto i : caches_by_fav) { + for (auto i : user.caches_by_fav) { std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; std::cout << "" << i->type << ""; @@ -658,7 +414,7 @@ int main(int argc, char** argv) { } std::cout << "\n"; - average_html(cc, &Cache::fav, "number of recommendations"); + average_html(user.cc, &Cache::fav, "number of recommendations"); n = 1; @@ -673,7 +429,7 @@ int main(int argc, char** argv) { std::cout << "%"; std::cout << "\n"; - for (auto i : caches_by_fav_perc) { + for (auto i : user.caches_by_fav_perc) { std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; std::cout << "" << i->type << ""; @@ -728,7 +484,7 @@ int main(int argc, char** argv) { std::cout << "Finds"; std::cout << "\n"; - for (auto i : caches_by_finds) { + for (auto i : user.caches_by_finds) { std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; std::cout << "" << i->type << ""; @@ -741,7 +497,7 @@ int main(int argc, char** argv) { } std::cout << "\n"; - average_html(cc, &Cache::founds, "number of finds"); + average_html(user.cc, &Cache::founds, "number of finds"); n = 1; @@ -755,7 +511,7 @@ int main(int argc, char** argv) { std::cout << "Finds"; std::cout << "\n"; - for (auto i = caches_by_finds.rbegin(); i != caches_by_finds.rend(); i++) { + for (auto i = user.caches_by_finds.rbegin(); i != user.caches_by_finds.rend(); i++) { std::cout << "" << n << " "; std::cout << "" << (*i)->link_name() << ""; std::cout << "" << (*i)->type << ""; @@ -782,7 +538,7 @@ int main(int argc, char** argv) { for (int i = 2; i <= 10; i++) { // i -> diff in rows std::cout << "" << i / 2.0 << " "; for (int j = 2; j <= 10; j++) { // j -> terr in cols - count = count_caches(cc, codes, [i, j](const Cache& c) -> bool { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); + count = count_caches(user.cc, codes, [i, j](const Cache& c) -> bool { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); if (count == 0) std::cout << "" << 0 << ""; else { @@ -796,8 +552,8 @@ int main(int argc, char** argv) { std::cout << "
\n"; std::cout << "Total " << n << " combinations found out of 81 (" << std::setprecision(3) << n / 0.81 << "%).
\n"; - std::cout << "Average difficulty: " << average(cc, &Cache::diff) << "
\n"; - std::cout << "Average terrain: " << average(cc, &Cache::terr) << "
\n"; + std::cout << "Average difficulty: " << average(user.cc, &Cache::diff) << "
\n"; + std::cout << "Average terrain: " << average(user.cc, &Cache::terr) << "
\n"; std::cout << "
\n"; // Days matrix @@ -815,7 +571,7 @@ int main(int argc, char** argv) { int m = 0; std::cout << "" << i << " "; for (int j = 1; j <= 31; j++) { // j -> days in cols - count = count_caches(cc, codes, [i, j](const Cache& c) -> bool { return (c.date_tm.tm_mon == i - 1 && c.date_tm.tm_mday == j); }); + count = count_caches(user.cc, codes, [i, j](const Cache& c) -> bool { return (c.date_tm.tm_mon == i - 1 && c.date_tm.tm_mday == j); }); if (count == 0) { if ((j == 31 && (i == 2 || i == 4 || i == 6 || i == 9 || i == 11)) || (j == 30 && i == 2)) std::cout << ""; @@ -853,8 +609,8 @@ int main(int argc, char** argv) { // Hidden months matrix n = 0; - y_min = std::min_element(cc.begin(), cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; - y_max = std::max_element(cc.begin(), cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; + y_min = std::min_element(user.cc.begin(), user.cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; + y_max = std::max_element(user.cc.begin(), user.cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; std::cout << "

Caches by hidden month matrix

\n"; std::cout << "\n"; @@ -871,10 +627,10 @@ int main(int argc, char** argv) { int m = 0; std::cout << " "; for (int j = 1; j <= 12; j++) { // j -> months in cols - count = count_caches(cc, codes, [i, j](const Cache& c) -> bool { return (c.date_hidden_tm.tm_year == i && c.date_hidden_tm.tm_mon == j - 1); }); + count = count_caches(user.cc, codes, [i, j](const Cache& c) -> bool { return (c.date_hidden_tm.tm_year == i && c.date_hidden_tm.tm_mon == j - 1); }); if (count == 0) { - if ((!ocpl_user_uuid.empty() && ocde_user_uuid.empty() && i + 1900 == 2006 && j < 5) || - (!ocde_user_uuid.empty() && i + 1900 == 2005 && j < 8)) + if ((!user.ocpl_user_uuid.empty() && user.ocde_user_uuid.empty() && i + 1900 == 2006 && j < 5) || + (!user.ocde_user_uuid.empty() && i + 1900 == 2005 && j < 8)) std::cout << ""; else std::cout << ""; @@ -895,12 +651,12 @@ int main(int argc, char** argv) { std::cout << "
" << i + 1900 << "" << 0 << "
\n"; if (now_tm) { - if (!ocpl_user_uuid.empty() && ocde_user_uuid.empty()) { + if (!user.ocpl_user_uuid.empty() && user.ocde_user_uuid.empty()) { int m_count = (now_tm->tm_year - 106 - 1) * 12 + 8 + now_tm->tm_mon + 1; // 106 corresponds to 2006, 8 is no. of months since may till dec, +1 since tm_mon starts at 0 std::cout << "
\n"; std::cout << "Total " << n << " months out of " << m_count << " (" << std::setprecision(3) << n * 100.0 / m_count << "%).\n"; std::cout << "
\n"; - } else if (!ocde_user_uuid.empty()) { + } else if (!user.ocde_user_uuid.empty()) { int m_count = (now_tm->tm_year - 105 - 1) * 12 + 5 + now_tm->tm_mon + 1; // 106 corresponds to 2005, 8 is no. of months since aug till dec, +1 since tm_mon starts at 0 std::cout << "
\n"; std::cout << "Total " << n << " months out of " << m_count << " (" << std::setprecision(3) << n * 100.0 / m_count << "%).\n"; @@ -908,7 +664,7 @@ int main(int argc, char** argv) { } } - if (!ocpl_user_uuid.empty()) { + if (!user.ocpl_user_uuid.empty()) { n = 1; std::cout << "

Power trails (by completion percentage)

\n"; @@ -923,7 +679,7 @@ int main(int argc, char** argv) { std::cout << "Available"; std::cout << "\n"; - for (auto& i : tt) { + for (auto& i : user.tt) { std::cout << ""; std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; @@ -953,8 +709,8 @@ int main(int argc, char** argv) { // show_histogram(tt, "Power trails (completion percentage)", 1); std::cout << "
\n"; - std::cout << "Number of completed power trails: " << std::count_if(tt.begin(), tt.end(), [&](const auto& a) { return a->completed; }) << "
\n"; - std::cout << "Number of started power trails: " << tt.size() << "
\n"; + std::cout << "Number of completed power trails: " << std::count_if(user.tt.begin(), user.tt.end(), [&](const auto& a) { return a->completed; }) << "
\n"; + std::cout << "Number of started power trails: " << user.tt.size() << "
\n"; std::cout << "
\n"; std::cout << "

FTF

\n"; @@ -969,7 +725,7 @@ int main(int argc, char** argv) { n = 1; - for (auto i : caches_ftf) { + for (auto i : user.caches_ftf) { std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; std::cout << "" << i->type << ""; @@ -982,46 +738,46 @@ int main(int argc, char** argv) { } std::cout << "\n"; std::cout << "
\n"; - std::cout << "Number of FTFs: " << caches_ftf.size() << "
\n"; + std::cout << "Number of FTFs: " << user.caches_ftf.size() << "
\n"; std::cout << "
\n"; } } // end of main if - if (get_not_found) { + if (user.get_not_found) { std::cout << "
\n"; - std::cout << "Still " << cc.size() << " caches to be found...
\n"; + std::cout << "Still " << user.cc.size() << " caches to be found...
\n"; std::cout << "
\n"; - show_nested_histogram(fcc, &Cache::region, &Cache::subregion, "Regions", 1); + show_nested_histogram(user.fcc, &Cache::region, &Cache::subregion, "Regions", 1); std::map region_found_count; - for (auto el : fcc) + for (auto el : user.fcc) region_found_count[el->region]++; - for (auto& i : region_count) + for (auto& i : user.region_count) if (i.second != 0) i.second = region_found_count[i.first] * 100 / i.second; - show_histogram(region_count, "Percentage", 1); + show_histogram(user.region_count, "Percentage", 1); } // end of "not found" if - if (get_owned) { + if (user.get_owned) { short count; std::string codes; int n; std::cout << "
\n"; - std::cout << "Number of caches created: " << cc.size() << "
\n"; - std::cout << "Number of caches that are disabled: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.status == disabled; }) << "
\n"; - std::cout << "Number of caches that are archived: " << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.status == archived; }) << "
\n"; - std::cout << "Average finds per cache per day: " << std::setprecision(3) << std::accumulate(cc.begin(), cc.end(), 0., [&](const float& a, const Cache& b) { return std::move(a) + 1.0 * b.founds / std::max(b.age_now, 1); }) / cc.size() << "
\n"; + std::cout << "Number of caches created: " << user.cc.size() << "
\n"; + std::cout << "Number of caches that are disabled: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.status == disabled; }) << "
\n"; + std::cout << "Number of caches that are archived: " << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.status == archived; }) << "
\n"; + std::cout << "Average finds per cache per day: " << std::setprecision(3) << std::accumulate(user.cc.begin(), user.cc.end(), 0., [&](const float& a, const Cache& b) { return std::move(a) + 1.0 * b.founds / std::max(b.age_now, 1); }) / user.caches_count << "
\n"; std::cout << std::resetiosflags(std::cout.flags()); std::cout << "
\n"; - short y_min = std::min_element(cc.begin(), cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; - short y_max = std::max_element(cc.begin(), cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; + short y_min = std::min_element(user.cc.begin(), user.cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; + short y_max = std::max_element(user.cc.begin(), user.cc.end(), [&](const Cache& a, const Cache& b) { return a.date_hidden_tm.tm_year < b.date_hidden_tm.tm_year; })->date_hidden_tm.tm_year; long max = 0; // maximal value for histogram for (int i = y_min; i <= y_max; i++) for (int j = 1; j <= 12; j++) - max = std::max(max, std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.date_hidden_tm.tm_year == i && c.date_hidden_tm.tm_mon == j - 1); })); + max = std::max(max, std::count_if(user.cc.begin(), user.cc.end(), [i, j](Cache c) { return (c.date_hidden_tm.tm_year == i && c.date_hidden_tm.tm_mon == j - 1); })); if (max > 0) { std::cout << "

Cache creation timeline

\n"; @@ -1034,7 +790,7 @@ int main(int argc, char** argv) { for (int i = y_min; i <= y_max; i++) { // i -> years in rows std::cout << "" << i + 1900 << " "; for (int j = 1; j <= 12; j++) { // j -> months in cols - count = std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.date_hidden_tm.tm_year == i && c.date_hidden_tm.tm_mon == j - 1); }); + count = std::count_if(user.cc.begin(), user.cc.end(), [i, j](Cache c) { return (c.date_hidden_tm.tm_year == i && c.date_hidden_tm.tm_mon == j - 1); }); std::cout << "" << count << ""; } std::cout << "\n"; @@ -1050,14 +806,14 @@ int main(int argc, char** argv) { // std::cout << "Furthest cache: " << far->distance() << " km\n"; // far->show(); - show_histogram(cc, &Cache::type, "Cache types", 1); - show_histogram(cc, &Cache::size, "Cache sizes", 1); - show_nested_histogram(fcc, &Cache::region, &Cache::subregion, "Regions", 1); + show_histogram(user.cc, &Cache::type, "Cache types", 1); + show_histogram(user.cc, &Cache::size, "Cache sizes", 1); + show_nested_histogram(user.fcc, &Cache::region, &Cache::subregion, "Regions", 1); - auto N = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); - auto S = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); - auto E = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); - auto W = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto N = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto S = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto E = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto W = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); std::cout << "

Geographically extreme caches

\n"; std::cout << "\n"; @@ -1085,7 +841,7 @@ int main(int argc, char** argv) { std::cout << ""; std::cout << "\n"; - for (auto i : caches_by_fav) { + for (auto i : user.caches_by_fav) { std::cout << " "; std::cout << ""; std::cout << ""; @@ -1101,8 +857,8 @@ int main(int argc, char** argv) { } std::cout << "
%
" << n << "" << i->link_name() << "" << i->type << "
\n"; - average_html(cc, &Cache::fav, "number of recommendations"); - sum_html(cc, &Cache::fav, "number of recommendations"); + average_html(user.cc, &Cache::fav, "number of recommendations"); + sum_html(user.cc, &Cache::fav, "number of recommendations"); n = 1; @@ -1116,7 +872,7 @@ int main(int argc, char** argv) { std::cout << "%"; std::cout << "\n"; - for (auto i : caches_by_fav_perc) { + for (auto i : user.caches_by_fav_perc) { std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; std::cout << "" << i->type << ""; @@ -1170,7 +926,7 @@ int main(int argc, char** argv) { std::cout << "Finds"; std::cout << "\n"; - for (auto i : caches_by_finds) { + for (auto i : user.caches_by_finds) { std::cout << "" << n << " "; std::cout << "" << i->link_name() << ""; std::cout << "" << i->type << ""; @@ -1182,8 +938,8 @@ int main(int argc, char** argv) { } std::cout << "\n"; - average_html(cc, &Cache::founds, "number of finds"); - sum_html(cc, &Cache::founds, "number of finds"); + average_html(user.cc, &Cache::founds, "number of finds"); + sum_html(user.cc, &Cache::founds, "number of finds"); n = 1; @@ -1196,7 +952,7 @@ int main(int argc, char** argv) { std::cout << "Finds"; std::cout << "\n"; - for (auto i = caches_by_finds.rbegin(); i != caches_by_finds.rend(); i++) { + for (auto i = user.caches_by_finds.rbegin(); i != user.caches_by_finds.rend(); i++) { std::cout << "" << n << " "; std::cout << "" << (*i)->link_name() << ""; std::cout << "" << (*i)->type << ""; @@ -1222,7 +978,7 @@ int main(int argc, char** argv) { for (int i = 2; i <= 10; i++) { // i -> diff in rows std::cout << "" << i / 2.0 << " "; for (int j = 2; j <= 10; j++) { // j -> terr in cols - count = count_caches(cc, codes, [i, j](const Cache& c) -> bool { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); + count = count_caches(user.cc, codes, [i, j](const Cache& c) -> bool { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); if (count == 0) std::cout << "" << 0 << ""; else { @@ -1236,8 +992,8 @@ int main(int argc, char** argv) { std::cout << "
\n"; std::cout << "Total " << n << " combinations created out of 81 (" << std::setprecision(3) << n / 0.81 << "%).
\n"; - std::cout << "Average difficulty: " << average(cc, &Cache::diff) << "
\n"; - std::cout << "Average terrain: " << average(cc, &Cache::terr) << "
\n"; + std::cout << "Average difficulty: " << average(user.cc, &Cache::diff) << "
\n"; + std::cout << "Average terrain: " << average(user.cc, &Cache::terr) << "
\n"; std::cout << "
\n"; } // end of "owned" if diff --git a/geostat_cli.cpp b/geostat_cli.cpp index 8bef4c9..5d7fd74 100644 --- a/geostat_cli.cpp +++ b/geostat_cli.cpp @@ -1,11 +1,7 @@ -#include "okapi.h" -#include "gpx.h" -#include "cache.h" +#include "user.h" #include "debug.h" #include "heat.h" -#include "ocdb.h" #include "common.h" -#include "region.h" #include #include @@ -45,6 +41,7 @@ void show_usage() { } int main(int argc, char** argv) { + User user; bool show_minmax = 0; bool show_dist = 0; bool show_list = 0; @@ -58,17 +55,6 @@ int main(int argc, char** argv) { bool heat_exp = 0; bool trail = 0; bool anim = 0; - bool use_oc = 0; - bool use_ocdb = 0; - bool get_not_found = 0; - bool get_owned = 0; - - std::string ocpl_user; - std::string ocde_user; - std::string ocus_user; - std::string ocnl_user; - std::string ocro_user; - std::string ocuk_user; std::string gpx_file; @@ -82,46 +68,46 @@ int main(int argc, char** argv) { // case 'd': // Debug::set_debug_level(get_num('d',optarg)); // break; - case 'g': - gpx_file = optarg; +// case 'g': +// gpx_file = optarg; break; case 'o': - use_oc = 1; + user.use_oc = 1; if (optarg) { - ocpl_user = optarg; - ocde_user = optarg; - ocus_user = optarg; - ocnl_user = optarg; - ocro_user = optarg; - ocuk_user = optarg; + user.ocpl_user = optarg; + user.ocde_user = optarg; + user.ocus_user = optarg; + user.ocnl_user = optarg; + user.ocro_user = optarg; + user.ocuk_user = optarg; } break; case 'p': - ocpl_user = optarg; + user.ocpl_user = optarg; break; case 'd': - ocde_user = optarg; + user.ocde_user = optarg; break; case 'u': - ocus_user = optarg; + user.ocus_user = optarg; break; case 'n': - ocnl_user = optarg; + user.ocnl_user = optarg; break; case 'r': - ocro_user = optarg; + user.ocro_user = optarg; break; case 'k': - ocuk_user = optarg; + user.ocuk_user = optarg; break; case 'q': - use_ocdb = 1; + user.use_ocdb = 1; break; case 'N': - get_not_found = 1; + user.get_not_found = 1; break; case 'O': - get_owned = 1; + user.get_owned = 1; break; case 'M': show_minmax = 1; @@ -168,17 +154,15 @@ int main(int argc, char** argv) { show_usage(); } - Caches cc; - - if (get_not_found || get_owned) { - use_oc = 0; - use_ocdb = 1; + if (user.get_not_found || user.get_owned) { + user.use_oc = 0; + user.use_ocdb = 1; // trail = 0; - if (ocpl_user_uuid.empty() && ocpl_user.empty() && ocde_user_uuid.empty() && ocde_user.empty()) { + if (user.ocpl_user_uuid.empty() && user.ocpl_user.empty() && user.ocde_user_uuid.empty() && user.ocde_user.empty()) { std::cout << "Options \"-N\" or \"-O\" work only with OCpl or OCde.\n"; std::exit(EXIT_FAILURE); } - if (get_not_found && get_owned) { + if (user.get_not_found && user.get_owned) { std::cout << "Options \"-N\" and \"-O\" are mutually exclusive.\n"; std::exit(EXIT_FAILURE); } @@ -189,136 +173,14 @@ int main(int argc, char** argv) { std::exit(EXIT_FAILURE); } - 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); - Caches tmp = OCpl.get_user_caches(ocpl_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - if (!ocde_user_uuid.empty() || !ocde_user.empty()) { - Okapi OCde(ocde_url, ocde_key); - if (!ocde_user.empty()) ocde_user_uuid = OCde.get_uuid(ocde_user); - Caches tmp = OCde.get_user_caches(ocde_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - if (!ocus_user_uuid.empty() || !ocus_user.empty()) { - Okapi OCus(ocus_url, ocus_key); - if (!ocus_user.empty()) ocus_user_uuid = OCus.get_uuid(ocus_user); - Caches tmp = OCus.get_user_caches(ocus_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - if (!ocnl_user_uuid.empty() || !ocnl_user.empty()) { - Okapi OCnl(ocnl_url, ocnl_key); - if (!ocnl_user.empty()) ocnl_user_uuid = OCnl.get_uuid(ocnl_user); - Caches tmp = OCnl.get_user_caches(ocnl_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - if (!ocro_user_uuid.empty() || !ocro_user.empty()) { - Okapi OCro(ocro_url, ocro_key); - if (!ocro_user.empty()) ocro_user_uuid = OCro.get_uuid(ocro_user); - Caches tmp = OCro.get_user_caches(ocro_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - if (!ocuk_user_uuid.empty() || !ocuk_user.empty()) { - Okapi OCuk(ocuk_url, ocuk_key); - if (!ocuk_user.empty()) ocuk_user_uuid = OCuk.get_uuid(ocuk_user); - Caches tmp = OCuk.get_user_caches(ocuk_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - } + user.get_caches(); - if (!gpx_file.empty()) { - GPX gpxfile(gpx_file); - Caches tmp = gpxfile.get_user_caches(); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - - if (use_ocdb) { - if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { - OCdb db(Database_pl); - if (!ocpl_user.empty()) { - Okapi OCpl(ocpl_url, ocpl_key); - ocpl_user_uuid = OCpl.get_uuid(ocpl_user); - } - if (get_not_found) { - Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } else if (get_owned) { - Caches tmp = db.get_user_caches_owned(ocpl_user_uuid); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } else { - Caches tmp = db.get_user_caches(ocpl_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - } - if (!ocde_user_uuid.empty() || !ocde_user.empty()) { - OCdb db(Database_de); - if (!ocde_user.empty()) { - Okapi OCde(ocde_url, ocde_key); - ocde_user_uuid = OCde.get_uuid(ocde_user); - } - if (get_not_found) { - Caches tmp = db.get_user_caches_not_found(ocde_user_uuid); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } else if (get_owned) { - Caches tmp = db.get_user_caches_owned(ocde_user_uuid); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } else { - Caches tmp = db.get_user_caches(ocde_user_uuid, 0); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); - } - } - } - - // TODO: some cache deduplication is needed - - Debug(2) << "Caches read: " << cc.size() << '\n'; - if (cc.size() == 0) { + if (user.caches_count == 0) { std::cout << "No caches found, aborting.\n"; std::exit(EXIT_FAILURE); } - // Prepare a set of regions - Country poland({ "dolnoslaskie", - "gornoslaskie", - "kujawsko-pomorskie", - "lodzkie", - "lubelskie", - "lubuskie", - "malopolskie", - "mazowieckie", - "opolskie", - "podkarpackie", - "podlaskie", - "pomorskie", - "swietokrzyskie", - "warminsko-mazurskie", - "wielkopolskie", - "zachodniopomorskie" }); - - // Prepare sorted list of caches, excluding moving caches -// std::map dates; - Date_Caches sorted_caches; - pCaches fcc; - - if (!get_not_found) { - for (auto& i : cc) { - poland.locate(i); - -// dates[i.date]++; - if (i.type != "Moving" && i.type != "Own") { - sorted_caches.insert({ i.date_t, &i }); - fcc.push_back(&i); - } - } - } else { - for (auto& i : cc) { - if (i.type != "Moving" && i.type != "Own") { - fcc.push_back(&i); - } - } - } + user.prepare_lists_of_caches(); if (!heat_file.empty()) { const Map* chosen_map; @@ -330,24 +192,24 @@ int main(int argc, char** argv) { } Heat hmap(chosen_map); if (trail) - hmap.generate_path(heat_file, sorted_caches); + hmap.generate_path(heat_file, user.sorted_caches); else if (anim) - hmap.generate_anim(heat_file, sorted_caches, heat_stamp_size); + hmap.generate_anim(heat_file, user.sorted_caches, heat_stamp_size); else - hmap.generate(heat_file, fcc, heat_stamp_size, (heat_exp == 1 ? "exp" : "soft")); + hmap.generate(heat_file, user.fcc, heat_stamp_size, (heat_exp == 1 ? "exp" : "soft")); } - if (!get_not_found) { + if (!user.get_not_found) { if (show_list) { - for (auto el : sorted_caches) + for (auto el : user.sorted_caches) el.second->show(); } if (show_minmax) { - auto N = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); - auto S = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); - auto E = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); - auto W = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto N = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto S = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lat < b->pos.lat; }); + auto E = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); + auto W = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->pos.lon < b->pos.lon; }); std::cout << "Most N:\n"; N->show(); @@ -360,8 +222,8 @@ int main(int argc, char** argv) { } if (show_dist) { - auto far = *std::max_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->distance() < b->distance(); }); - auto near = *std::min_element(fcc.begin(), fcc.end(), [&](const Cache* a, const Cache* b) { return a->distance() < b->distance(); }); + auto far = *std::max_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->distance() < b->distance(); }); + auto near = *std::min_element(user.fcc.begin(), user.fcc.end(), [&](const Cache* a, const Cache* b) { return a->distance() < b->distance(); }); std::cout << "Nearest cache: " << near->distance() << " km\n"; near->show(); @@ -370,20 +232,20 @@ int main(int argc, char** argv) { } if (show_owners) { - show_histogram(cc, &Cache::owner, "Cache owners"); + show_histogram(user.cc, &Cache::owner, "Cache owners"); } if (show_types) { - show_histogram(cc, &Cache::type, "Cache types"); - show_histogram(cc, &Cache::size, "Cache sizes"); - show_histogram(cc, &Cache::origin, "Services"); - show_histogram(cc, &Cache::region, "Regions"); + show_histogram(user.cc, &Cache::type, "Cache types"); + show_histogram(user.cc, &Cache::size, "Cache sizes"); + show_histogram(user.cc, &Cache::origin, "Services"); + show_histogram(user.cc, &Cache::region, "Regions"); } if (show_calendar) { - show_histogram(cc, &Cache::day_of_week, "Days of the week", 0, 0); - show_histogram(cc, &Cache::mon, "Months", 0, 0); - show_histogram(cc, &Cache::year, "Years", 0, 0); + show_histogram(user.cc, &Cache::day_of_week, "Days of the week", 0, 0); + show_histogram(user.cc, &Cache::mon, "Months", 0, 0); + show_histogram(user.cc, &Cache::year, "Years", 0, 0); } if (show_dt) { @@ -398,7 +260,7 @@ int main(int argc, char** argv) { for (int i = 2; i <= 10; i++) { // i -> diff in rows std::cout << std::setw(5) << i / 2.0; for (int j = 2; j <= 10; j++) { // j -> terr in cols - dt_table[i][j] = std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); + dt_table[i][j] = std::count_if(user.cc.begin(), user.cc.end(), [i, j](Cache c) { return (c.diff == i / 2.0 && c.terr == j / 2.0); }); std::cout << std::setw(5) << dt_table[i][j]; } std::cout << '\n'; @@ -406,7 +268,7 @@ int main(int argc, char** argv) { } } else { if (show_list) { - for (auto el : cc) + for (auto el : user.cc) el.show(); } } diff --git a/meson.build b/meson.build index fdca94e..972714b 100644 --- a/meson.build +++ b/meson.build @@ -23,7 +23,7 @@ src_cli = ['geostat_cli.cpp', 'gpx.cpp'] src_db = ['geodb.cpp'] src_traildb = ['traildb.cpp'] -lib_geostat = library('okapi', ['okapi.cpp', 'debug.cpp', 'cache.cpp', 'powertrail.cpp', 'common.cpp', 'heat.cpp', 'ocdb.cpp', 'region.cpp'], dependencies : [curl_dep, json_dep, magick_dep, sqlite_dep, boost_dep], link_args: link, install: true) +lib_geostat = library('okapi', ['okapi.cpp', 'debug.cpp', 'cache.cpp', 'powertrail.cpp', 'common.cpp', 'heat.cpp', 'ocdb.cpp', 'region.cpp', 'user.cpp'], dependencies : [curl_dep, json_dep, magick_dep, sqlite_dep, boost_dep], link_args: link, install: true) executable('geostat', src, link_args: link, install: true, link_with : lib_geostat) executable('geofriends', src_fr, install: true, link_with : lib_geostat) diff --git a/user.cpp b/user.cpp new file mode 100644 index 0000000..98277e6 --- /dev/null +++ b/user.cpp @@ -0,0 +1,216 @@ +#include "user.h" +#include "ocdb.h" +#include "okapi.h" +// #include "gpx.h" +#include "debug.h" + +void User::get_caches() { +#include "config_user.h" + + if (use_oc) { + if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { + Okapi OCpl(ocpl_url, ocpl_key); + uint uid; + if (!ocpl_user.empty()) ocpl_user_uuid = OCpl.get_uuid(ocpl_user, &uid); + Caches tmp = OCpl.get_user_caches(ocpl_user_uuid, 0); + + traildb.read_from_json("powertrails.json"); + tc.read_from_json("caches_in_power.json"); + + std::unordered_map tt_map; // Needed to deduplicate trails + + for (auto& c : tmp) { + if (tc.data.count(c.code) > 0) { + c.trail = tc.data[c.code]; + traildb.data[c.trail].found++; + if (c.status == ok) + traildb.data[c.trail].active_caches_not_found--; + tt_map[c.trail] = &(traildb.data[c.trail]); + } + } + for (const auto& i : tt_map) { + i.second->completed_perc = (100 * i.second->found / i.second->caches.size()); + if (i.second->found >= i.second->treshold ) + i.second->completed = 1; + else + i.second->needed = i.second->treshold - i.second->found; + tt.push_back(i.second); + } + std::sort(tt.begin(), tt.end(), [&](const auto& a, const auto& b) { return a->completed_perc > b->completed_perc; }); + + 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); + } + if (!ocde_user_uuid.empty() || !ocde_user.empty()) { + Okapi OCde(ocde_url, ocde_key); + if (!ocde_user.empty()) ocde_user_uuid = OCde.get_uuid(ocde_user); + Caches tmp = OCde.get_user_caches(ocde_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + ocde_user_profile = OCde.get_profile_url(ocde_user_uuid); + } + if (!ocus_user_uuid.empty() || !ocus_user.empty()) { + Okapi OCus(ocus_url, ocus_key); + if (!ocus_user.empty()) ocus_user_uuid = OCus.get_uuid(ocus_user); + Caches tmp = OCus.get_user_caches(ocus_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + ocus_user_profile = OCus.get_profile_url(ocus_user_uuid); + } + if (!ocnl_user_uuid.empty() || !ocnl_user.empty()) { + Okapi OCnl(ocnl_url, ocnl_key); + if (!ocnl_user.empty()) ocnl_user_uuid = OCnl.get_uuid(ocnl_user); + Caches tmp = OCnl.get_user_caches(ocnl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + ocnl_user_profile = OCnl.get_profile_url(ocnl_user_uuid); + } + if (!ocro_user_uuid.empty() || !ocro_user.empty()) { + Okapi OCro(ocro_url, ocro_key); + if (!ocro_user.empty()) ocro_user_uuid = OCro.get_uuid(ocro_user); + Caches tmp = OCro.get_user_caches(ocro_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + ocro_user_profile = OCro.get_profile_url(ocro_user_uuid); + } + if (!ocuk_user_uuid.empty() || !ocuk_user.empty()) { + Okapi OCuk(ocuk_url, ocuk_key); + if (!ocuk_user.empty()) ocuk_user_uuid = OCuk.get_uuid(ocuk_user); + Caches tmp = OCuk.get_user_caches(ocuk_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + ocuk_user_profile = OCuk.get_profile_url(ocuk_user_uuid); + } + } + +// if (!gpx_file.empty()) { +// GPX gpxfile(gpx_file); +// Caches tmp = gpxfile.get_user_caches(); +// std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); +// } + + if (use_ocdb) { + if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) { + OCdb db(Database_pl); + if (!ocpl_user.empty()) { + Okapi OCpl(ocpl_url, ocpl_key); + ocpl_user_uuid = OCpl.get_uuid(ocpl_user); + ocpl_user_profile = OCpl.get_profile_url(ocpl_user_uuid); + } + if (get_not_found) { + Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid); + Okapi OCpl(ocpl_url, ocpl_key); + OCpl.update_caches(tmp); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + region_count = db.get_region_stats(); + } else if (get_owned) { + Caches tmp = db.get_user_caches_owned(ocpl_user_uuid); + Okapi OCpl(ocpl_url, ocpl_key); + OCpl.update_caches(tmp); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + } else { + Caches tmp = db.get_user_caches(ocpl_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + } + } + if (!ocde_user_uuid.empty() || !ocde_user.empty()) { + OCdb db(Database_de); + if (!ocde_user.empty()) { + Okapi OCde(ocde_url, ocde_key); + ocde_user_uuid = OCde.get_uuid(ocde_user); + ocde_user_profile = OCde.get_profile_url(ocde_user_uuid); + } + if (get_not_found) { + Caches tmp = db.get_user_caches_not_found(ocde_user_uuid); + Okapi OCde(ocde_url, ocde_key); + OCde.update_caches(tmp); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); +// region_count = db.get_region_stats(); + } else if (get_owned) { + Caches tmp = db.get_user_caches_owned(ocde_user_uuid); + Okapi OCde(ocde_url, ocde_key); + OCde.update_caches(tmp); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + } else { + Caches tmp = db.get_user_caches(ocde_user_uuid, 0); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(cc)); + } + } + } + + // TODO: some cache deduplication is needed + + Debug(2) << "Caches read: " << cc.size() << '\n'; + caches_count = cc.size(); +} + +void User::prepare_lists_of_caches() { + // Prepare a set of regions + Country poland({ "dolnoslaskie", + "gornoslaskie", + "kujawsko-pomorskie", + "lodzkie", + "lubelskie", + "lubuskie", + "malopolskie", + "mazowieckie", + "opolskie", + "podkarpackie", + "podlaskie", + "pomorskie", + "swietokrzyskie", + "warminsko-mazurskie", + "wielkopolskie", + "zachodniopomorskie" }); + + if (!get_not_found) { + for (auto i = cc.begin(); i != cc.end();) { + if (time_filter && (i->date_t > end_time || i->date_t < start_time)) { + i = cc.erase(i); + continue; + } + + poland.locate(*i); + + dates[i->date]++; + sorted_caches.insert({ i->date_t, &*i }); + if ((i->type != "Moving" && i->type != "Own") || get_owned) { + sorted_fcaches.insert({ i->date_t, &*i }); + fcc.push_back(&*i); + } + sorted_caches_by_hidden.insert({ i->date_hidden_t, &*i }); + caches_by_fav.push_back(&*i); + 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; }); + std::sort(caches_by_fav_perc.begin(), caches_by_fav_perc.end(), [&](const Cache* a, const Cache* b) { return 1.0 * a->fav / a->founds > 1.0 * b->fav / b->founds; }); + std::sort(caches_by_finds.begin(), caches_by_finds.end(), [&](const Cache* a, const Cache* b) { return a->founds > b->founds; }); + // std::sort(caches_by_rating.begin(), caches_by_rating.end(), [&](const Cache* a, const Cache* b) { return a->rating > b->rating; }); + } else { + for (auto& i : cc) { + if (i.type != "Moving" && i.type != "Own" && (!exclude_quiz || i.type != "Quiz")) { + fcc.push_back(&i); + poland.locate(i); + } + } + } +} + +void User::header() { + std::cout << "
\n"; + std::cout << "

Geocaching stats for user profiles:

\n"; + if (!ocpl_user.empty()) + std::cout << "\"OCpl\" " << ocpl_user << "
\n"; + if (!ocde_user.empty()) + std::cout << "\"OCde\" " << ocde_user << "
\n"; + if (!ocus_user.empty()) + std::cout << "\"OCna\" " << ocus_user << "
\n"; + if (!ocnl_user.empty()) + std::cout << "\"OCnl\" " << ocnl_user << "
\n"; + if (!ocro_user.empty()) + std::cout << "\"OCro\" " << ocro_user << "
\n"; + if (!ocuk_user.empty()) + std::cout << "\"OCuk\" " << ocuk_user << "
\n"; +} diff --git a/user.h b/user.h new file mode 100644 index 0000000..2785c36 --- /dev/null +++ b/user.h @@ -0,0 +1,67 @@ +#pragma once + +#include "common.h" +#include "cache.h" +#include "powertrail.h" +#include "region.h" + +#include + +class User { +private: + PowertrailDB traildb; + Caches_in_Powertrails tc; + +public: + // Position home; + std::string ocpl_user_uuid = ""; + std::string ocde_user_uuid = ""; + std::string ocus_user_uuid = ""; + std::string ocnl_user_uuid = ""; + std::string ocro_user_uuid = ""; + std::string ocuk_user_uuid = ""; + + bool use_oc = 0; + bool use_ocdb = 0; + std::string ocpl_user; + std::string ocde_user; + std::string ocus_user; + std::string ocnl_user; + std::string ocro_user; + std::string ocuk_user; +// std::string gpx_file; + + std::string ocpl_user_profile; + std::string ocde_user_profile; + std::string ocus_user_profile; + std::string ocnl_user_profile; + std::string ocro_user_profile; + std::string ocuk_user_profile; + + bool get_not_found = 0; + bool get_owned = 0; + bool exclude_quiz = 0; + std::time_t start_time = 0; + std::time_t end_time = std::time(nullptr); + bool time_filter = 0; + + Caches cc; + int caches_count; + std::map dates; + Date_Caches sorted_caches; + Date_Caches sorted_fcaches; + Date_Caches sorted_caches_by_hidden; + pCaches caches_by_fav; + pCaches caches_by_fav_perc; + pCaches caches_by_finds; + pCaches caches_ftf; + // pCaches caches_by_rating; + pCaches fcc; + pPowertrails tt; + std::map region_count; + + void get_caches(); + void prepare_lists_of_caches(); // Prepare sorted list of caches, excluding moving caches + + void header(); +};