Initial support for processing owned cache lists

sql-rework
Tomasz Golinski 2020-08-01 23:00:50 +02:00
rodzic 3c188ca1ff
commit c1958baa11
2 zmienionych plików z 232 dodań i 12 usunięć

Wyświetl plik

@ -48,6 +48,7 @@ int main(int argc, char** argv) {
bool use_oc = 0;
bool use_ocpl_db = 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);
@ -83,7 +84,7 @@ int main(int argc, char** argv) {
if (argc == 1) show_usage();
int o;
while ((o = getopt(argc, argv, "qNQD:o::p:d:u:n:r:k:i:f:H:s:m:eth?")) != -1)
while ((o = getopt(argc, argv, "qNOQD:o::p:d:u:n:r:k:i:f:H:s:m:eth?")) != -1)
switch (o) {
case 'D':
Debug::set_debug_level(get_num('d',optarg));
@ -134,6 +135,9 @@ int main(int argc, char** argv) {
case 'N':
get_not_found = 1;
break;
case 'O':
get_owned = 1;
break;
case 'Q':
exclude_quiz = 1;
break;
@ -161,16 +165,19 @@ int main(int argc, char** argv) {
Caches cc;
std::map<std::string, int> region_count;
if (get_not_found) {
if (get_not_found || get_owned) {
use_oc = 0;
use_ocpl_db = 1;
trail = 0;
if (ocpl_user_uuid.empty() && ocpl_user.empty()) {
std::cout << "Option \"-N\" works only with OCpl\n";
std::cout << "Options \"-N\" or \"-O\" work only with OCpl\n";
std::exit(EXIT_FAILURE);
}
if (get_not_found && get_owned) {
std::cout << "Options \"-N\" and \"-O\" are mutually exclusive.\n";
std::exit(EXIT_FAILURE);
}
}
if (use_oc) {
if (!ocpl_user_uuid.empty() || !ocpl_user.empty()) {
Okapi OCpl(ocpl_url, ocpl_key);
@ -233,6 +240,9 @@ int main(int argc, char** argv) {
Caches tmp = db.get_user_caches_not_found(ocpl_user_uuid);
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);
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));
@ -288,7 +298,7 @@ int main(int argc, char** argv) {
dates[i->date]++;
sorted_caches.insert({ i->date_t, &*i });
if (i->type != "Moving" && i->type != "Own") {
if ((i->type != "Moving" && i->type != "Own") || get_owned) {
sorted_fcaches.insert({ i->date_t, &*i });
fcc.push_back(&*i);
}
@ -359,7 +369,7 @@ int main(int argc, char** argv) {
std::cout << "<figure>\n<img class=\"heatmap\" src=\"" << heat_file << "\" alt=\"heat map\">\n</figure>\n";
}
if (!get_not_found) {
if (!get_not_found && !get_owned) {
short count;
int n;
@ -744,6 +754,205 @@ int main(int argc, char** argv) {
show_histogram(region_count, "Percentage", 1);
}
if (get_owned) {
short count;
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(), [&](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(), [&](auto& a) { return a.status == archived; }) << "</span><br>\n";
// std::cout << "<h2>Cache creation timeline</h2>\n";
// std::cout << "<table class=\"calendar_tab\">\n";
// std::cout << "<tr><th></th>";
// for (int j = 1; j <= 12; j++) { // print table month headers
// std::cout << "<th>" << j << "</th>";
// }
// std::cout << "</tr>\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;
//
// 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); }));
//
// 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); });
// std::cout << "<td style=\"--percent: " << count * 100 / max << "%\"><span>" << count << "</span></td>";
// }
// std::cout << "</tr>\n";
// }
// std::cout << "</table>\n";
// 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(); });
//
// std::cout << "Nearest cache: " << near->distance() << " km\n";
// near->show();
// 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);
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; });
std::cout << "<h2>Geographically extreme caches</h2>\n";
std::cout << "<table class=\"list\">\n";
std::cout << "<tr>\n";
std::cout << " <th>North:</th><td>" << N->link_name() << "</td><td>" << N->pos.lat << "</td>\n";
std::cout << "</tr><tr>\n";
std::cout << " <th>South:</th><td>" << S->link_name() << "</td><td>" << S->pos.lat << "</td>\n";
std::cout << "</tr><tr>\n";
std::cout << " <th>East:</th> <td>" << E->link_name() << "</td><td>" << E->pos.lon << "</td>\n";
std::cout << "</tr><tr>\n";
std::cout << " <th>West:</th> <td>" << W->link_name() << "</td><td>" << W->pos.lon << "</td>\n";
std::cout << "</tr>\n";
std::cout << "</table>\n";
// const int LIST_MAX = 15;
// n = 1;
// std::cout << "<h2>Caches with most recommendations</h2>\n";
// std::cout << "<table class=\"list\">\n";
// std::cout << "<tr><th></th>";
// std::cout << "<th>Cache</th>";
// std::cout << "<th>Type</th>";
// std::cout << "<th>Rec.</th>";
// std::cout << "<th>Finds</th>";
// std::cout << "<th>%</th>";
// std::cout << "</tr>\n";
//
// for (auto i : caches_by_fav) {
// std::cout << "<tr><th>" << n << "</th> ";
// std::cout << "<td>" << i->link_name() << "</td>";
// std::cout << "<td>" << i->type << "</td>";
// std::cout << "<td>" << i->fav << "</td>";
// std::cout << "<td>" << i->founds << "</td>";
// std::cout << "<td>" << std::setprecision(3) << 100.0 * i->fav / i->founds << "%</td>";
// std::cout << "</tr>\n";
// n++;
// if (n > LIST_MAX) break;
// }
// std::cout << "</table>\n";
//
// average_html(cc, &Cache::fav, "number of recommendations");
//
// n = 1;
//
// std::cout << "<h2>Caches with most recommendations (percentage)</h2>\n";
// std::cout << "<table class=\"list\">\n";
// std::cout << "<tr><th></th>";
// std::cout << "<th>Cache</th>";
// std::cout << "<th>Type</th>";
// std::cout << "<th>Rec.</th>";
// std::cout << "<th>Finds</th>";
// std::cout << "<th>%</th>";
// std::cout << "</tr>\n";
//
// for (auto i : caches_by_fav_perc) {
// std::cout << "<tr><th>" << n << "</th> ";
// std::cout << "<td>" << i->link_name() << "</td>";
// std::cout << "<td>" << i->type << "</td>";
// std::cout << "<td>" << i->fav << "</td>";
// std::cout << "<td>" << i->founds << "</td>";
// std::cout << "<td>" << std::setprecision(3) << 100.0 * i->fav / i->founds << "%</td>";
// std::cout << "</tr>\n";
// n++;
// if (n > LIST_MAX) break;
// }
// std::cout << "</table>\n";
//
// n = 1;
//
// std::cout << "<h2>Caches with most finds</h2>\n";
// std::cout << "<table class=\"list\">\n";
// std::cout << "<tr><th></th>";
// std::cout << "<th>Cache</th>";
// std::cout << "<th>Type</th>";
// std::cout << "<th>Date hidden</th>";
// std::cout << "<th>Finds</th>";
// std::cout << "</tr>\n";
//
// for (auto i : caches_by_finds) {
// std::cout << "<tr><th>" << n << "</th> ";
// std::cout << "<td>" << i->link_name() << "</td>";
// std::cout << "<td>" << i->type << "</td>";
// std::cout << "<td>" << i->date_hidden << "</td>";
// std::cout << "<td>" << i->founds << "</td>";
// std::cout << "</tr>\n";
// n++;
// if (n > LIST_MAX) break;
// }
// std::cout << "</table>\n";
//
// average_html(cc, &Cache::founds, "number of finds");
//
// n = 1;
//
// std::cout << "<h2>Caches with least finds</h2>\n";
// std::cout << "<table class=\"list\">\n";
// std::cout << "<tr><th></th>";
// std::cout << "<th>Cache</th>";
// std::cout << "<th>Type</th>";
// std::cout << "<th>Date hidden</th>";
// std::cout << "<th>Finds</th>";
// std::cout << "</tr>\n";
//
// for (auto i = caches_by_finds.rbegin(); i != caches_by_finds.rend(); i++) {
// std::cout << "<tr><th>" << n << "</th> ";
// std::cout << "<td>" << (*i)->link_name() << "</td>";
// std::cout << "<td>" << (*i)->type << "</td>";
// std::cout << "<td>" << (*i)->date_hidden << "</td>";
// std::cout << "<td>" << (*i)->founds << "</td>";
// std::cout << "</tr>\n";
// n++;
// if (n > LIST_MAX) break;
// }
// std::cout << "</table>\n";
// D/T matrix
n = 0;
std::cout << "<h2>Difficulty / terrain matrix</h2>\n";
std::cout << "<table class=\"dt\">\n";
std::cout << "<tr><th></th>";
for (int j = 2; j <= 10; j++) { // print table terr headers
std::cout << "<th>" << j / 2.0 << "</th>";
}
std::cout << "</tr>\n";
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 = std::count_if(cc.begin(), cc.end(), [i, j](Cache c) { return (c.diff == i / 2.0 && c.terr == j / 2.0); });
if (count == 0)
std::cout << "<td class=\"dt_zero\">" << 0 << "</td>";
else {
std::cout << "<td>" << count << "</td>";
n++;
}
}
std::cout << "</tr>\n";
}
std::cout << "</table>\n";
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 << "</div>\n";
} // end of "owned" if
std::cout << "<footer>\n";
std::cout << "Stats generated by <a href=\"https://gitlab.com/tomaszg/geostat\">GeoStat</a>.<br>\n";
std::cout << "Data obtained from Opencaching sites via <a href=\"https://github.com/opencaching/okapi/\">OKAPI</a>:<br>\n";

Wyświetl plik

@ -59,6 +59,7 @@ int main(int argc, char** argv) {
bool use_oc = 0;
bool use_ocpl_db = 0;
bool get_not_found = 0;
bool get_owned = 0;
std::string ocpl_user;
std::string ocde_user;
@ -83,7 +84,7 @@ int main(int argc, char** argv) {
if (argc == 1) show_usage();
int o;
while ((o = getopt(argc, argv, "qNg:o::p:d:u:n:r:k:MDCOH:s:m:etLTYh?")) != -1)
while ((o = getopt(argc, argv, "qNOg:o::p:d:u:n:r:k:MDCH:s:m:etLTYh?")) != -1)
switch (o) {
// case 'd':
// Debug::set_debug_level(get_num('d',optarg));
@ -126,6 +127,9 @@ int main(int argc, char** argv) {
case 'N':
get_not_found = 1;
break;
case 'O':
get_owned = 1;
break;
case 'M':
show_minmax = 1;
break;
@ -135,9 +139,9 @@ int main(int argc, char** argv) {
case 'C':
show_calendar = 1;
break;
case 'O':
show_owners = 1;
break;
// case 'O':
// show_owners = 1;
// break;
case 'Y':
show_types = 1;
break;
@ -170,12 +174,16 @@ int main(int argc, char** argv) {
Caches cc;
if (get_not_found) {
if (get_not_found || get_owned) {
use_oc = 0;
use_ocpl_db = 1;
// trail = 0;
if (ocpl_user_uuid.empty() && ocpl_user.empty()) {
std::cout << "Option \"-N\" works only with OCpl\n";
std::cout << "Options \"-N\" or \"-O\" work only with OCpl\n";
std::exit(EXIT_FAILURE);
}
if (get_not_found && get_owned) {
std::cout << "Options \"-N\" and \"-O\" are mutually exclusive.\n";
std::exit(EXIT_FAILURE);
}
}
@ -234,6 +242,9 @@ int main(int argc, char** argv) {
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));