kopia lustrzana https://gitlab.com/tomaszg/geostat
Code refactor, split out class User, deduplicate some code
rodzic
653e1c31c6
commit
c584c33e07
18
cache.cpp
18
cache.cpp
|
@ -1,20 +1,6 @@
|
|||
#include "cache.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
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)));
|
||||
}
|
||||
|
|
21
cache.h
21
cache.h
|
@ -1,12 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
#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<Cache> Caches;
|
||||
typedef std::vector<const Cache*> pCaches;
|
||||
typedef std::multimap<std::time_t, const Cache*> Date_Caches;
|
||||
|
||||
float cache_distance(const Cache& a, const Cache& b);
|
||||
|
|
18
common.cpp
18
common.cpp
|
@ -1,10 +1,16 @@
|
|||
#include "common.h"
|
||||
#include "cache.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <cmath>
|
||||
|
||||
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 << "</footer>\n";
|
||||
std::cout << "</body>\n</html>\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)));
|
||||
}
|
||||
|
|
30
common.h
30
common.h
|
@ -1,9 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "cache.h"
|
||||
#include "powertrail.h"
|
||||
// #include "cache.h"
|
||||
// #include "powertrail.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
|
||||
class Cache;
|
||||
|
||||
typedef std::vector<Cache> Caches;
|
||||
typedef std::vector<const Cache*> pCaches;
|
||||
typedef std::multimap<std::time_t, const Cache*> 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<bool(const
|
|||
|
||||
void header_html();
|
||||
void footer_html();
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
float cache_distance(const Cache& a, const Cache& b);
|
||||
|
||||
float degtorad(float x);
|
||||
|
|
508
geostat.cpp
508
geostat.cpp
|
@ -1,12 +1,7 @@
|
|||
#include "okapi.h"
|
||||
// #include "gpx.h"
|
||||
#include "cache.h"
|
||||
#include "debug.h"
|
||||
#include "heat.h"
|
||||
#include "ocdb.h"
|
||||
#include "common.h"
|
||||
#include "region.h"
|
||||
#include "powertrail.h"
|
||||
#include "user.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
@ -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<std::string, int> 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<int, Powertrail*> 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<std::string, int> 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 << "<header>\n";
|
||||
std::cout << "<h1><a href=\"/geo\">Geocaching stats</a> for user profiles:</h1>\n";
|
||||
if (!ocpl_user.empty())
|
||||
std::cout << "<img alt=\"OCpl\" src=\"" << flag_pl << "\"> <a href=\"" << ocpl_user_profile << "\">" << ocpl_user << "</a><br>\n";
|
||||
if (!ocde_user.empty())
|
||||
std::cout << "<img alt=\"OCde\" src=\"" << flag_de << "\"> <a href=\"" << ocde_user_profile << "\">" << ocde_user << "</a><br>\n";
|
||||
if (!ocus_user.empty())
|
||||
std::cout << "<img alt=\"OCna\" src=\"" << flag_us << "\"> <a href=\"" << ocus_user_profile << "\">" << ocus_user << "</a><br>\n";
|
||||
if (!ocnl_user.empty())
|
||||
std::cout << "<img alt=\"OCnl\" src=\"" << flag_nl << "\"> <a href=\"" << ocnl_user_profile << "\">" << ocnl_user << "</a><br>\n";
|
||||
if (!ocro_user.empty())
|
||||
std::cout << "<img alt=\"OCro\" src=\"" << flag_ro << "\"> <a href=\"" << ocro_user_profile << "\">" << ocro_user << "</a><br>\n";
|
||||
if (!ocuk_user.empty())
|
||||
std::cout << "<img alt=\"OCuk\" src=\"" << flag_uk << "\"> <a href=\"" << ocuk_user_profile << "\">" << ocuk_user << "</a><br>\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 << "</header>\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 << "<figure>\n<img class=\"heatmap\" src=\"" << heat_file << "\" alt=\"heat map\">\n</figure>\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 << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Number of caches found: <span class=\"value\">" << cc.size() << "</span><br>\n";
|
||||
std::cout << "Number of caches found: <span class=\"value\">" << user.cc.size() << "</span><br>\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: <span class=\"value\">" << dates.size() << "</span><br>\n";
|
||||
std::cout << "Average caches per caching day: <span class=\"value\">" << std::setprecision(3) << (1.0 * cc.size()) / dates.size() << "</span><br>\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: <span class=\"value\">" << user.dates.size() << "</span><br>\n";
|
||||
std::cout << "Average caches per caching day: <span class=\"value\">" << std::setprecision(3) << (1.0 * user.cc.size()) / user.dates.size() << "</span><br>\n";
|
||||
std::cout << std::resetiosflags(std::cout.flags());
|
||||
std::cout << "Number of caches that are now archived: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.status == archived; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches that are now archived: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.status == archived; }) << "</span><br>\n";
|
||||
std::cout << "<details class=\"days\"><summary>Best caching day: <span class=\"value\">" << best_day->first << "</span>, found <span class=\"value\">" << best_day->second << "</span> caches</summary>\n";
|
||||
std::cout << " <p>\n";
|
||||
for (const auto& i : dates)
|
||||
for (const auto& i : user.dates)
|
||||
std::cout << i.first << ", found " << i.second << " caches<br>\n";
|
||||
std::cout << " </p>\n</details>\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: <span class=\"value\">" << longest_str << "</span> starting on <span class=\"value\">" << str_tmp << "</span><br>\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) << "<br>";
|
||||
tot_dist += cache_distance(*i->second, *std::next(i)->second);
|
||||
}
|
||||
std::cout << "Total distance between caches: <span class=\"value\">" << std::fixed << tot_dist << "</span> km (equivalent to <span class=\"value\">" << tot_dist / (2 * M_PI * Earth_radius) << "x</span> trips around Earth or <span class=\"value\">" << tot_dist / Moon_dist << "x</span> trips to the Moon)<br>\n";
|
||||
std::cout << std::resetiosflags(std::cout.flags());
|
||||
if (sorted_fcaches.size() > 1)
|
||||
std::cout << "Average distance between caches: <span class=\"value\">" << tot_dist / (sorted_fcaches.size() - 1) << "</span> km<br>\n";
|
||||
if (user.sorted_fcaches.size() > 1)
|
||||
std::cout << "Average distance between caches: <span class=\"value\">" << tot_dist / (user.sorted_fcaches.size() - 1) << "</span> km<br>\n";
|
||||
std::cout << "</div>\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 << "<h2>Caching timeline</h2>\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 << "<tr><th>" << i + 1900 << "</th> ";
|
||||
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 << "<td style=\"--percent: " << count * 100 / max << "%\"><span>" << count << "</span></td>";
|
||||
}
|
||||
std::cout << "</tr>\n";
|
||||
|
@ -522,7 +278,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<tr><th>" << i + 1900 << "</th> ";
|
||||
for (int j = 1; j <= 12; j++) { // j -> months in cols
|
||||
std::map<int, int> 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 << "<h2>Geographically extreme caches</h2>\n";
|
||||
std::cout << "<table class=\"list\">\n";
|
||||
|
@ -583,7 +339,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>Date found</th>";
|
||||
std::cout << "</tr>\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 << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->second->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->second->type << "</td>";
|
||||
|
@ -608,7 +364,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>Date found</th>";
|
||||
std::cout << "</tr>\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 << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->second->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->second->type << "</td>";
|
||||
|
@ -622,13 +378,13 @@ int main(int argc, char** argv) {
|
|||
std::cout << "</table>\n";
|
||||
|
||||
std::cout << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Average age of cache at the moment of finding: <span class=\"value\">" << average(cc, &Cache::age_when_found) / 365 * 12 << "</span> months<br>\n";
|
||||
std::cout << "Number of caches found within first 24h: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found == 0; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found within first 48h: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found <= 1; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found during first week: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found < 7; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found during first month: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found < 30; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found after more than 5 years: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 5; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found after more than 10 years: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 10; }) << "</span><br>\n";
|
||||
std::cout << "Average age of cache at the moment of finding: <span class=\"value\">" << average(user.cc, &Cache::age_when_found) / 365 * 12 << "</span> months<br>\n";
|
||||
std::cout << "Number of caches found within first 24h: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found == 0; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found within first 48h: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found <= 1; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found during first week: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found < 7; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found during first month: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found < 30; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found after more than 5 years: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 5; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches found after more than 10 years: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.age_when_found > 365 * 10; }) << "</span><br>\n";
|
||||
std::cout << "</div>\n";
|
||||
|
||||
n = 1;
|
||||
|
@ -644,7 +400,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>%</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto i : caches_by_fav) {
|
||||
for (auto i : user.caches_by_fav) {
|
||||
std::cout << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -658,7 +414,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
std::cout << "</table>\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 << "<th>%</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto i : caches_by_fav_perc) {
|
||||
for (auto i : user.caches_by_fav_perc) {
|
||||
std::cout << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -728,7 +484,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>Finds</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto i : caches_by_finds) {
|
||||
for (auto i : user.caches_by_finds) {
|
||||
std::cout << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -741,7 +497,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
std::cout << "</table>\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 << "<th>Finds</th>";
|
||||
std::cout << "</tr>\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 << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << (*i)->link_name() << "</td>";
|
||||
std::cout << "<td>" << (*i)->type << "</td>";
|
||||
|
@ -782,7 +538,7 @@ int main(int argc, char** argv) {
|
|||
for (int i = 2; i <= 10; i++) { // i -> diff in rows
|
||||
std::cout << "<tr><th>" << i / 2.0 << "</th> ";
|
||||
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 << "<td class=\"dt_zero\">" << 0 << "</td>";
|
||||
else {
|
||||
|
@ -796,8 +552,8 @@ int main(int argc, char** argv) {
|
|||
|
||||
std::cout << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Total <span class=\"value\">" << n << "</span> combinations found out of 81 (" << std::setprecision(3) << n / 0.81 << "%).<br>\n";
|
||||
std::cout << "Average difficulty: <span class=\"value\">" << average(cc, &Cache::diff) << "</span><br>\n";
|
||||
std::cout << "Average terrain: <span class=\"value\">" << average(cc, &Cache::terr) << "</span><br>\n";
|
||||
std::cout << "Average difficulty: <span class=\"value\">" << average(user.cc, &Cache::diff) << "</span><br>\n";
|
||||
std::cout << "Average terrain: <span class=\"value\">" << average(user.cc, &Cache::terr) << "</span><br>\n";
|
||||
std::cout << "</div>\n";
|
||||
|
||||
// Days matrix
|
||||
|
@ -815,7 +571,7 @@ int main(int argc, char** argv) {
|
|||
int m = 0;
|
||||
std::cout << "<tr><th>" << i << "</th> ";
|
||||
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 << "<td class=\"dt_null\"></td>";
|
||||
|
@ -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 << "<h2>Caches by hidden month matrix</h2>\n";
|
||||
std::cout << "<table class=\"dt\">\n";
|
||||
|
@ -871,10 +627,10 @@ int main(int argc, char** argv) {
|
|||
int m = 0;
|
||||
std::cout << "<tr><th>" << i + 1900 << "</th> ";
|
||||
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 << "<td class=\"dt_null\"></td>";
|
||||
else
|
||||
std::cout << "<td class=\"dt_zero\">" << 0 << "</td>";
|
||||
|
@ -895,12 +651,12 @@ int main(int argc, char** argv) {
|
|||
std::cout << "</table>\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 << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Total <span class=\"value\">" << n << "</span> months out of " << m_count << " (" << std::setprecision(3) << n * 100.0 / m_count << "%).\n";
|
||||
std::cout << "</div>\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 << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Total <span class=\"value\">" << n << "</span> 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 << "<h2>Power trails (by completion percentage)</h2>\n";
|
||||
|
@ -923,7 +679,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>Available</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto& i : tt) {
|
||||
for (auto& i : user.tt) {
|
||||
std::cout << "<tr>";
|
||||
std::cout << "<th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
|
@ -953,8 +709,8 @@ int main(int argc, char** argv) {
|
|||
|
||||
// show_histogram(tt, "Power trails (completion percentage)", 1);
|
||||
std::cout << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Number of completed power trails: <span class=\"value\">" << std::count_if(tt.begin(), tt.end(), [&](const auto& a) { return a->completed; }) << "</span><br>\n";
|
||||
std::cout << "Number of started power trails: <span class=\"value\">" << tt.size() << "</span><br>\n";
|
||||
std::cout << "Number of completed power trails: <span class=\"value\">" << std::count_if(user.tt.begin(), user.tt.end(), [&](const auto& a) { return a->completed; }) << "</span><br>\n";
|
||||
std::cout << "Number of started power trails: <span class=\"value\">" << user.tt.size() << "</span><br>\n";
|
||||
std::cout << "</div>\n";
|
||||
|
||||
std::cout << "<h2>FTF</h2>\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 << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -982,46 +738,46 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
std::cout << "</table>\n";
|
||||
std::cout << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Number of FTFs: <span class=\"value\">" << caches_ftf.size() << "</span><br>\n";
|
||||
std::cout << "Number of FTFs: <span class=\"value\">" << user.caches_ftf.size() << "</span><br>\n";
|
||||
std::cout << "</div>\n";
|
||||
}
|
||||
} // end of main if
|
||||
|
||||
if (get_not_found) {
|
||||
if (user.get_not_found) {
|
||||
std::cout << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Still <span class=\"value\">" << cc.size() << "</span> caches to be found...<br>\n";
|
||||
std::cout << "Still <span class=\"value\">" << user.cc.size() << "</span> caches to be found...<br>\n";
|
||||
std::cout << "</div>\n";
|
||||
|
||||
show_nested_histogram(fcc, &Cache::region, &Cache::subregion, "Regions", 1);
|
||||
show_nested_histogram(user.fcc, &Cache::region, &Cache::subregion, "Regions", 1);
|
||||
|
||||
std::map<std::string, int> 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 << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Number of caches created: <span class=\"value\">" << cc.size() << "</span><br>\n";
|
||||
std::cout << "Number of caches that are disabled: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.status == disabled; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches that are archived: <span class=\"value\">" << std::count_if(cc.begin(), cc.end(), [&](const auto& a) { return a.status == archived; }) << "</span><br>\n";
|
||||
std::cout << "Average finds per cache per day: <span class=\"value\">" << 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() << "</span><br>\n";
|
||||
std::cout << "Number of caches created: <span class=\"value\">" << user.cc.size() << "</span><br>\n";
|
||||
std::cout << "Number of caches that are disabled: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.status == disabled; }) << "</span><br>\n";
|
||||
std::cout << "Number of caches that are archived: <span class=\"value\">" << std::count_if(user.cc.begin(), user.cc.end(), [&](const auto& a) { return a.status == archived; }) << "</span><br>\n";
|
||||
std::cout << "Average finds per cache per day: <span class=\"value\">" << 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 << "</span><br>\n";
|
||||
std::cout << std::resetiosflags(std::cout.flags());
|
||||
std::cout << "</div>\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 << "<h2>Cache creation timeline</h2>\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 << "<tr><th>" << i + 1900 << "</th> ";
|
||||
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 << "<td style=\"--percent: " << count * 100 / max << "%\"><span>" << count << "</span></td>";
|
||||
}
|
||||
std::cout << "</tr>\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 << "<h2>Geographically extreme caches</h2>\n";
|
||||
std::cout << "<table class=\"list\">\n";
|
||||
|
@ -1085,7 +841,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>%</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto i : caches_by_fav) {
|
||||
for (auto i : user.caches_by_fav) {
|
||||
std::cout << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -1101,8 +857,8 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
std::cout << "</table>\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 << "<th>%</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto i : caches_by_fav_perc) {
|
||||
for (auto i : user.caches_by_fav_perc) {
|
||||
std::cout << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -1170,7 +926,7 @@ int main(int argc, char** argv) {
|
|||
std::cout << "<th>Finds</th>";
|
||||
std::cout << "</tr>\n";
|
||||
|
||||
for (auto i : caches_by_finds) {
|
||||
for (auto i : user.caches_by_finds) {
|
||||
std::cout << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << i->link_name() << "</td>";
|
||||
std::cout << "<td>" << i->type << "</td>";
|
||||
|
@ -1182,8 +938,8 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
std::cout << "</table>\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 << "<th>Finds</th>";
|
||||
std::cout << "</tr>\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 << "<tr><th>" << n << "</th> ";
|
||||
std::cout << "<td>" << (*i)->link_name() << "</td>";
|
||||
std::cout << "<td>" << (*i)->type << "</td>";
|
||||
|
@ -1222,7 +978,7 @@ int main(int argc, char** argv) {
|
|||
for (int i = 2; i <= 10; i++) { // i -> diff in rows
|
||||
std::cout << "<tr><th>" << i / 2.0 << "</th> ";
|
||||
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 << "<td class=\"dt_zero\">" << 0 << "</td>";
|
||||
else {
|
||||
|
@ -1236,8 +992,8 @@ int main(int argc, char** argv) {
|
|||
|
||||
std::cout << "<div class=\"basic_stats\">\n";
|
||||
std::cout << "Total <span class=\"value\">" << n << "</span> combinations created out of 81 (" << std::setprecision(3) << n / 0.81 << "%).<br>\n";
|
||||
std::cout << "Average difficulty: <span class=\"value\">" << average(cc, &Cache::diff) << "</span><br>\n";
|
||||
std::cout << "Average terrain: <span class=\"value\">" << average(cc, &Cache::terr) << "</span><br>\n";
|
||||
std::cout << "Average difficulty: <span class=\"value\">" << average(user.cc, &Cache::diff) << "</span><br>\n";
|
||||
std::cout << "Average terrain: <span class=\"value\">" << average(user.cc, &Cache::terr) << "</span><br>\n";
|
||||
std::cout << "</div>\n";
|
||||
} // end of "owned" if
|
||||
|
||||
|
|
236
geostat_cli.cpp
236
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 <iostream>
|
||||
#include <iomanip>
|
||||
|
@ -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<std::string, int> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<int, Powertrail*> 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 << "<header>\n";
|
||||
std::cout << "<h1><a href=\"/geo\">Geocaching stats</a> for user profiles:</h1>\n";
|
||||
if (!ocpl_user.empty())
|
||||
std::cout << "<img alt=\"OCpl\" src=\"" << flag_pl << "\"> <a href=\"" << ocpl_user_profile << "\">" << ocpl_user << "</a><br>\n";
|
||||
if (!ocde_user.empty())
|
||||
std::cout << "<img alt=\"OCde\" src=\"" << flag_de << "\"> <a href=\"" << ocde_user_profile << "\">" << ocde_user << "</a><br>\n";
|
||||
if (!ocus_user.empty())
|
||||
std::cout << "<img alt=\"OCna\" src=\"" << flag_us << "\"> <a href=\"" << ocus_user_profile << "\">" << ocus_user << "</a><br>\n";
|
||||
if (!ocnl_user.empty())
|
||||
std::cout << "<img alt=\"OCnl\" src=\"" << flag_nl << "\"> <a href=\"" << ocnl_user_profile << "\">" << ocnl_user << "</a><br>\n";
|
||||
if (!ocro_user.empty())
|
||||
std::cout << "<img alt=\"OCro\" src=\"" << flag_ro << "\"> <a href=\"" << ocro_user_profile << "\">" << ocro_user << "</a><br>\n";
|
||||
if (!ocuk_user.empty())
|
||||
std::cout << "<img alt=\"OCuk\" src=\"" << flag_uk << "\"> <a href=\"" << ocuk_user_profile << "\">" << ocuk_user << "</a><br>\n";
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "cache.h"
|
||||
#include "powertrail.h"
|
||||
#include "region.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
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<std::string, int> 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<std::string, int> region_count;
|
||||
|
||||
void get_caches();
|
||||
void prepare_lists_of_caches(); // Prepare sorted list of caches, excluding moving caches
|
||||
|
||||
void header();
|
||||
};
|
Ładowanie…
Reference in New Issue