sql-rework
Tomasz Golinski 2020-08-06 23:58:14 +02:00
rodzic c4a58021c9
commit 72dc1292da
10 zmienionych plików z 103 dodań i 102 usunięć

Wyświetl plik

@ -42,7 +42,6 @@ std::string Cache::link_name() const {
return "<a href=\"" + link() + "\">" + safe_name() + " (" + code + ")</a>";
}
std::string Cache::safe_name() const {
std::string tmp = name;
htmlencode(tmp);
@ -72,9 +71,9 @@ void Cache::set_date(const std::tm& t) {
std::strftime(tmp, 20, "%F", &date_tm);
date = tmp;
// this function should be run after set_date_hidden()
// this function should be run after set_date_hidden()
if (date_hidden_t == 0) throw 1;
age_when_found = (date_t - date_hidden_t) / (60*60*24);
age_when_found = (date_t - date_hidden_t) / (60 * 60 * 24);
}
void Cache::set_date_hidden(const std::tm& t) {

Wyświetl plik

@ -37,15 +37,17 @@ void htmlencode(std::string& data) {
}
static std::string string_mangle(const std::string& str) {
std::string tmp;
tmp.reserve(str.size());
std::string tmp;
tmp.reserve(str.size());
for (size_t i = 0; i != str.size(); i++) {
if (str[i] == ' ') continue;
if (std::isupper(str[i])) tmp.push_back(std::tolower(str[i]));
else tmp.push_back(str[i]);
}
return tmp;
for (size_t i = 0; i != str.size(); i++) {
if (str[i] == ' ') continue;
if (std::isupper(str[i]))
tmp.push_back(std::tolower(str[i]));
else
tmp.push_back(str[i]);
}
return tmp;
}
void show_histogram(const pCaches& fcc, std::string Cache::*ptr, const std::string& caption, bool html, bool sort_by_val) {
@ -167,8 +169,7 @@ void show_nested_histogram(const pCaches& fcc, std::string Cache::*ptr, std::str
} else {
std::cout << "<div class=\"bar\" style=\"--percent: " << 100 * own.second / max << "%;\"><span class=\"text\">" << own.first << ": " << own.second << "</span></div>\n";
}
}
else if (i == HIST_MAX) {
} else if (i == HIST_MAX) {
std::cout << "</div>\n";
std::cout << "<details class=\"histogram_others " << string_mangle(caption) << "\">\n<summary>See more</summary>\n<p>\n";
std::cout << own.first << " (" << own.second << ")";
@ -205,7 +206,7 @@ int find_streak(const std::multimap<std::time_t, const Cache*>& cc, std::time_t&
continue;
}
// streak ended
// streak ended
if (max_str < cur_str) {
max_str = cur_str;
@ -228,7 +229,7 @@ int find_streak(const std::multimap<std::time_t, const Cache*>& cc, std::time_t&
return max_str;
}
long int get_num(char c, char* opt) {
long int get_num(char c, char* opt) {
try {
if (std::stoi(opt) > 0) {
return std::stoi(opt);
@ -244,15 +245,15 @@ long int get_num(char c, char* opt) {
}
void average_html(const Caches& cc, float Cache::*ptr, const std::string& caption) {
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Average " << caption << ": <span class=\"value\">" << average(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Average " << caption << ": <span class=\"value\">" << average(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
}
void average_html(const Caches& cc, int Cache::*ptr, const std::string& caption) {
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Average " << caption << ": <span class=\"value\">" << average(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Average " << caption << ": <span class=\"value\">" << average(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
}
float average(const Caches& cc, float Cache::*ptr) {
@ -264,15 +265,15 @@ float average(const Caches& cc, int Cache::*ptr) {
}
void sum_html(const Caches& cc, float Cache::*ptr, const std::string& caption) {
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Total " << caption << ": <span class=\"value\">" << sum(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Total " << caption << ": <span class=\"value\">" << sum(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
}
void sum_html(const Caches& cc, int Cache::*ptr, const std::string& caption) {
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Total " << caption << ": <span class=\"value\">" << sum(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Total " << caption << ": <span class=\"value\">" << sum(cc, ptr) << "</span><br>\n";
std::cout << "</div>\n";
}
float sum(const Caches& cc, float Cache::*ptr) {

Wyświetl plik

@ -32,7 +32,6 @@ int main(int argc, char** argv) {
Caches cc1 = OCpl.get_user_caches(ocpl_user_uuid1, 0);
Caches cc2 = OCpl.get_user_caches(ocpl_user_uuid2, 0);
pCaches caches_by_user1;
pCaches caches_by_user2;
@ -55,16 +54,18 @@ int main(int argc, char** argv) {
std::cout << "</header>\n";
std::cout << "<div class=\"basic_stats\">\n";
std::cout << "Number of caches created by " << ocpl_user1 << " found by " << ocpl_user2 <<": <span class=\"value\">" << caches_by_user1.size() << "</span><br>\n";
std::cout << "Number of recommendations given: <span class=\"value\">" << std::count_if(cc2.begin(), cc2.end(), [ocpl_user_uuid1](auto& c) { return (c.recommended && c.owner_uuid == ocpl_user_uuid1); }) << "</span><br>\n";;
std::cout << "Number of caches created by " << ocpl_user2 << " found by " << ocpl_user1 <<": <span class=\"value\">" << caches_by_user2.size() << "</span><br>\n";
std::cout << "Number of recommendations given: <span class=\"value\">" << std::count_if(cc1.begin(), cc1.end(), [ocpl_user_uuid2](auto& c) { return (c.recommended && c.owner_uuid == ocpl_user_uuid2); }) << "</span><br>\n";;
std::cout << "Number of caches created by " << ocpl_user1 << " found by " << ocpl_user2 << ": <span class=\"value\">" << caches_by_user1.size() << "</span><br>\n";
std::cout << "Number of recommendations given: <span class=\"value\">" << std::count_if(cc2.begin(), cc2.end(), [ocpl_user_uuid1](auto& c) { return (c.recommended && c.owner_uuid == ocpl_user_uuid1); }) << "</span><br>\n";
;
std::cout << "Number of caches created by " << ocpl_user2 << " found by " << ocpl_user1 << ": <span class=\"value\">" << caches_by_user2.size() << "</span><br>\n";
std::cout << "Number of recommendations given: <span class=\"value\">" << std::count_if(cc1.begin(), cc1.end(), [ocpl_user_uuid2](auto& c) { return (c.recommended && c.owner_uuid == ocpl_user_uuid2); }) << "</span><br>\n";
;
std::cout << "</div>\n";
// const int LIST_MAX = 100;
short int n = 1;
std::cout << "<h2>Caches created by " << ocpl_user1 << " found by " << ocpl_user2 <<"</h2>\n";
std::cout << "<h2>Caches created by " << ocpl_user1 << " found by " << ocpl_user2 << "</h2>\n";
std::cout << "<table class=\"list\">\n";
std::cout << "<tr><th></th>";
std::cout << "<th>Cache</th>";
@ -88,7 +89,7 @@ int main(int argc, char** argv) {
std::cout << "</table>\n";
n = 1;
std::cout << "<h2>Caches created by " << ocpl_user2 << " found by " << ocpl_user1 <<"</h2>\n";
std::cout << "<h2>Caches created by " << ocpl_user2 << " found by " << ocpl_user1 << "</h2>\n";
std::cout << "<table class=\"list\">\n";
std::cout << "<tr><th></th>";
std::cout << "<th>Cache</th>";

Wyświetl plik

@ -87,7 +87,7 @@ int main(int argc, char** argv) {
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));
Debug::set_debug_level(get_num('d', optarg));
break;
// case 'g':
// gpx_file = optarg;
@ -125,11 +125,11 @@ int main(int argc, char** argv) {
use_ocpl_db = 1;
break;
case 'i':
start_time = get_num('i',optarg);
start_time = get_num('i', optarg);
time_filter = 1;
break;
case 'f':
end_time = get_num('f',optarg);
end_time = get_num('f', optarg);
time_filter = 1;
break;
case 'N':
@ -145,7 +145,7 @@ int main(int argc, char** argv) {
heat_file = optarg;
break;
case 's':
heat_stamp_size = get_num('s',optarg);
heat_stamp_size = get_num('s', optarg);
break;
case 'm':
heat_map = optarg;
@ -260,24 +260,22 @@ int main(int argc, char** argv) {
}
// 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"
});
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;
@ -290,7 +288,7 @@ int main(int argc, char** argv) {
pCaches fcc;
if (!get_not_found) {
for (auto i = cc.begin(); i != cc.end(); ) {
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;
@ -455,7 +453,7 @@ int main(int argc, char** argv) {
// 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";
@ -465,8 +463,8 @@ int main(int argc, char** argv) {
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(fcc, &Cache::region, "Regions", 1);
// show_histogram(fcc, &Cache::subregion, "Subregions", 1);
// show_histogram(fcc, &Cache::region, "Regions", 1);
// show_histogram(fcc, &Cache::subregion, "Subregions", 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);
@ -647,7 +645,7 @@ int main(int argc, char** argv) {
}
std::cout << "</table>\n";
// D/T matrix
// D/T matrix
n = 0;
std::cout << "<h2>Difficulty / terrain matrix</h2>\n";
@ -679,7 +677,7 @@ int main(int argc, char** argv) {
std::cout << "Average terrain: <span class=\"value\">" << average(cc, &Cache::terr) << "</span><br>\n";
std::cout << "</div>\n";
// Days matrix
// Days matrix
n = 0;
std::cout << "<h2>Caching days matrix</h2>\n";
@ -791,7 +789,7 @@ int main(int argc, char** argv) {
// 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";

Wyświetl plik

@ -149,7 +149,7 @@ int main(int argc, char** argv) {
heat_file = optarg;
break;
case 's':
heat_stamp_size = get_num('s',optarg);
heat_stamp_size = get_num('s', optarg);
break;
case 'm':
heat_map = optarg;
@ -260,24 +260,22 @@ int main(int argc, char** argv) {
}
// 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"
});
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;

Wyświetl plik

@ -63,8 +63,8 @@ void Heat::generate_path(const std::string& filename, const Date_Caches& sorted)
const Cache* prev = sorted.begin()->second;
float h = 1./3;
float h_step = 2./3/(sorted.size()-1);
float h = 1. / 3;
float h_step = 2. / 3 / (sorted.size() - 1);
for (auto el = sorted.begin()++; el != sorted.end(); el++) {
draw.push_back(Magick::DrawableStrokeColor(Magick::ColorHSL(h, 1, 0.5)));

Wyświetl plik

@ -163,9 +163,9 @@ bool OCdb::update_cache(const json& j) {
if (j["data"].count("size2") && !j["data"]["size2"].is_null())
fields["size"] = j["data"]["size2"].get<std::string>();
if (j["data"].count("difficulty") && !j["data"]["difficulty"].is_null())
fields2["difficulty"] = 2*j["data"]["difficulty"].get<float>();
fields2["difficulty"] = 2 * j["data"]["difficulty"].get<float>();
if (j["data"].count("terrain") && !j["data"]["terrain"].is_null())
fields2["terrain"] = 2*j["data"]["terrain"].get<float>();
fields2["terrain"] = 2 * j["data"]["terrain"].get<float>();
if (j["data"].count("country") && !j["data"]["country"].is_null())
fields["country"] = j["data"]["country"].get<std::string>();
if (j["data"].count("region") && !j["data"]["region"].is_null())
@ -388,8 +388,8 @@ Caches OCdb::parse_sql_caches() const {
if (sqlite3_column_text(stmt, 1)) c.pos = Position(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));
if (sqlite3_column_text(stmt, 2)) c.type = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
if (sqlite3_column_text(stmt, 3)) c.size = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
c.diff = sqlite3_column_int(stmt, 4)/2.0;
c.terr = sqlite3_column_int(stmt, 5)/2.0;
c.diff = sqlite3_column_int(stmt, 4) / 2.0;
c.terr = sqlite3_column_int(stmt, 5) / 2.0;
//c.country = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6));
if (sqlite3_column_text(stmt, 7)) c.region = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
if (sqlite3_column_text(stmt, 8)) c.owner_uuid = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8)); // TODO: we don't know owner's nick
@ -406,7 +406,7 @@ Caches OCdb::parse_sql_caches() const {
else
c.status = unknown;
} else
c.status = unknown;
c.status = unknown;
cc.push_back(c);
res = sqlite3_step(stmt);

Wyświetl plik

@ -232,9 +232,9 @@ Caches Okapi::get_user_caches(const std::string& uuid, int count) const {
Debug(2) << "Caches read from OC: " << cc.size() << '\n';
std::map<std::string, Cache&> mcc;
for (auto& i : cc)
mcc.insert( { i.code, i } );
mcc.insert({ i.code, i });
// introduce extra data from the logs to Caches
// introduce extra data from the logs to Caches
for (auto& el : tmp_data) {
auto& it = mcc.at(el.first);
it.set_date(el.second.date);
@ -253,7 +253,7 @@ void Okapi::update_caches(Caches& cc) const {
std::string Okapi::get_uuid(const std::string& username) const {
std::string service = url + OKAPI_username;
char* user_esc = curl_easy_escape(curl, username.c_str(), username.size()) ;
char* user_esc = curl_easy_escape(curl, username.c_str(), username.size());
std::string query = "consumer_key=" + key + "&username=" + user_esc + "&fields=uuid";
curl_free(user_esc);
curl_post(service, query);

Wyświetl plik

@ -22,16 +22,16 @@ bool BoundingBox::within(Position p) const {
}
bool ContourData::within(Position p) const {
return bbox.within(p) && bg::within(point_t{p.lon, p.lat}, contour);
return bbox.within(p) && bg::within(point_t{ p.lon, p.lat }, contour);
}
ContourData::ContourData(BoundingBox bbox) : bbox(bbox) {}
void ContourData::add_point(Position p) {
bg::append(contour, point_t{p.lon, p.lat});
bg::append(contour, point_t{ p.lon, p.lat });
}
// TODO: Parse inner ring and multi-poligon
// TODO: Parse inner ring and multi-poligon
std::map<std::string, ContourData*> Region::parse_geojson(const std::string& json_file) {
if (!std::filesystem::exists(json_file)) {
throw std::runtime_error("File " + json_file + " does not exist.");
@ -56,7 +56,7 @@ std::map<std::string, ContourData*> Region::parse_geojson(const std::string& jso
}
ContourData* cont = new ContourData(BoundingBox(Position(el.value()["bbox"][1], el.value()["bbox"][0]), Position(el.value()["bbox"][3], el.value()["bbox"][2])));
for (auto& el2 : el.value()["geometry"]["coordinates"][0][0].items()) {
cont->add_point(Position(el2.value()[1],el2.value()[0]));
cont->add_point(Position(el2.value()[1], el2.value()[0]));
}
Debug(3) << "Parsed region " << name;
rr[name] = cont;
@ -71,8 +71,8 @@ Region::Region(const std::filesystem::path& geojson, const std::filesystem::path
auto geodata = parse_geojson(geojson_sub);
std::transform(geodata.begin(), geodata.end(), std::back_inserter(subregions), [&](auto a) { return new Region(a.second, a.first); });
// for (auto& el : parse_geojson(geojson_sub))
// subregions.emplace_back(new Region(el.second, el.first));
// for (auto& el : parse_geojson(geojson_sub))
// subregions.emplace_back(new Region(el.second, el.first));
}
Region::~Region() {
@ -85,16 +85,16 @@ std::string Region::find_subregion(Position p) {
auto res = std::find_if(subregions.begin(), subregions.end(), [&](auto a) { return a->within(p); });
if (res != subregions.end())
return (*res)->get_name();
return (*res)->get_name();
return "";
// else
// throw std::runtime_error("Point " + std::to_string(p.lat) + " " + std::to_string(p.lon) + " not in any of the subregions.");
// else
// throw std::runtime_error("Point " + std::to_string(p.lat) + " " + std::to_string(p.lon) + " not in any of the subregions.");
}
Country::Country(const std::vector<std::filesystem::path>& jsons) {
for (auto el : jsons) {
std::filesystem::path p1 = "geojson" / el;
std::filesystem::path p2 = p1;
std::filesystem::path p2 = p1;
p1 += ".geojson";
p2 += "_sub.geojson";
regions.emplace_back(new Region(p1, p2));

Wyświetl plik

@ -16,6 +16,7 @@ class BoundingBox {
private:
Position a;
Position b;
public:
inline bool within(Position p) const;
@ -26,6 +27,7 @@ class ContourData {
private:
bg::model::polygon<boost::geometry::model::d2::point_xy<double>> contour;
BoundingBox bbox;
public:
explicit ContourData(BoundingBox bbox);
bool within(Position p) const;
@ -39,6 +41,7 @@ private:
std::vector<Region*> subregions;
std::map<std::string, ContourData*> parse_geojson(const std::string& json_file);
public:
Region(ContourData* contour, const std::string& name) : contour(contour), name(name) {}
Region(const std::filesystem::path& geojson, const std::filesystem::path& geojson_sub);
@ -52,6 +55,7 @@ public:
class Country {
private:
std::vector<Region*> regions;
public:
explicit Country(const std::vector<std::filesystem::path>& jsons);
void locate(Cache& c);