Try to support other OC servers

It changed options layout, so beware. It also removed an option to set debug level.

Moreover some/all services seem to need some deduplication in cache codes in their OKAPI queries.
sql-rework
Tomasz Golinski 2020-01-02 00:37:28 +01:00
rodzic 4ee02fd2ee
commit 1c3e1ec0f1
3 zmienionych plików z 140 dodań i 62 usunięć

Wyświetl plik

@ -14,28 +14,33 @@ A sample web interface to play with the tool is available at http://tomaszg.pl/g
The main tool is called `geostat`. It is able to access `opencaching.pl` via `OKAPI` or from local database dump maintained by `geodb`. It can also partially read `GPX` files, e.g. exported from `C:GEO`. It produces various statistics (either as text output, or in a HTML form) and renders a heat map of found/not found caches in a selected region. HTML output requires a style sheet. Sample one is included as `geo.css`.
```
Usage: geostat [-p] [-g file] [-qn] [-MDHLTOYh] [-s size] [-m map]
Usage: geostat [-o] [-g file] [-qn] [-MDHLTOYh] [-s size] [-m map]
Generate stats from Opencaching data or GPX files.
* Data source:
-p use opencaching.pl
-u user user for Opencaching
-g file use specified gpx file
-q use local SQLite file
-n get only unfound caches (works only with SQLite)
* Data sources:
-o[user] use Opencaching; if specified user will be a user name used for all OC instances
-p user user for opencaching.pl
-d user user for opencaching.de
-u user user for opencaching.us
-n user user for opencaching.nl
-r user user for opencaching.ro
-k user user for opencaching.uk
-g file use specified gpx file
-q use local SQLite file with dump of OC database
* Output:
-M print geographically extreme caches
-D print furthest and closest caches
-H file render a heat map to a file
-s n stamp size for a heat map (default = 15)
-e use exponential to flatten the heat map
-m map chosen map: Poland, Poland_relief, Poland_big, Europe or a name of voivodeship (default = Poland)
-L print all caches
-T print D/T matrix
-O print owner count for found caches
-Y print types count for found caches
-W output all data in HTML format
-h display this help screen
-W output all data in HTML format
-N compute stats only for unfound caches (works only with SQLite)
-M print geographically extreme caches
-D print furthest and closest caches
-H file render a heat map to a file
-s n stamp size for a heat map (default = 15)
-e use exponential to flatten the heat map
-m map chosen map: Poland, Poland_relief, Poland_big, Europe or a name of voivodeship (default = Poland)
-L print all caches
-T print D/T matrix
-O print owner count for found caches
-Y print types count for found caches
-h display this help screen
```
There is a helper program `geodb` which manages local SQLite database. It can initialize the database from full data dump or update it according to changelogs grabbed from OKAPI.

Wyświetl plik

@ -1,10 +1,20 @@
#pragma once
// Default OCPL user to use when -u is not used
// Default OC user to use when command line switches are not used
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 = "";
// Consumer key for OCPL API
// Consumer key for OKAPI instances
std::string ocpl_key = "";
std::string ocde_key = "";
std::string ocus_key = "";
std::string ocnl_key = "";
std::string ocro_key = "";
std::string ocuk_key = "";
// Home location
Cache::home = { 0, 0 };

Wyświetl plik

@ -14,27 +14,32 @@
const int HIST_MAX = 20;
void show_usage() {
std::cout << "Usage: geostat [-p] [-g file] [-qn] [-MDHLTOYh] [-s size] [-m map]\n";
std::cout << "Usage: geostat [-o] [-g file] [-qn] [-MDHLTOYh] [-s size] [-m map]\n";
std::cout << "Generate stats from Opencaching data or GPX files.\n\n";
std::cout << " * Data source:\n";
std::cout << "\t-p\tuse opencaching.pl\n";
std::cout << "\t-u user\tuser for Opencaching\n";
std::cout << "\t-g file\tuse specified gpx file\n";
std::cout << "\t-q\tuse local SQLite file\n";
std::cout << "\t-n\tget only unfound caches (works only with SQLite)\n";
std::cout << " * Data sources:\n";
std::cout << "\t-o[user]\tuse Opencaching; if specified user will be a user name used for all OC instances\n";
std::cout << "\t-p user\t\tuser for opencaching.pl\n";
std::cout << "\t-d user\t\tuser for opencaching.de\n";
std::cout << "\t-u user\t\tuser for opencaching.us\n";
std::cout << "\t-n user\t\tuser for opencaching.nl\n";
std::cout << "\t-r user\t\tuser for opencaching.ro\n";
std::cout << "\t-k user\t\tuser for opencaching.uk\n";
std::cout << "\t-g file\t\tuse specified gpx file\n";
std::cout << "\t-q\t\tuse local SQLite file with dump of OC database\n";
std::cout << " * Output:\n";
std::cout << "\t-M\tprint geographically extreme caches\n";
std::cout << "\t-D\tprint furthest and closest caches\n";
std::cout << "\t-H file\trender a heat map to a file\n";
std::cout << "\t-s n\tstamp size for a heat map (default = 15)\n";
std::cout << "\t-e\tuse exponential to flatten the heat map\n";
std::cout << "\t-m map\tchosen map: Poland, Poland_relief, Poland_big, Europe or a name of voivodeship (default = Poland)\n";
std::cout << "\t-L\tprint all caches\n";
std::cout << "\t-T\tprint D/T matrix\n";
std::cout << "\t-O\tprint owner count for found caches\n";
std::cout << "\t-Y\tprint types count for found caches\n";
std::cout << "\t-W\toutput all data in HTML format\n";
std::cout << "\t-h\tdisplay this help screen\n";
std::cout << "\t-W\t\toutput all data in HTML format\n";
std::cout << "\t-N\t\tcompute stats only for unfound caches (works only with SQLite)\n";
std::cout << "\t-M\t\tprint geographically extreme caches\n";
std::cout << "\t-D\t\tprint furthest and closest caches\n";
std::cout << "\t-H file\t\trender a heat map to a file\n";
std::cout << "\t-s n\t\tstamp size for a heat map (default = 15)\n";
std::cout << "\t-e\t\tuse exponential to flatten the heat map\n";
std::cout << "\t-m map\t\tchosen map: Poland, Poland_relief, Poland_big, Europe or a name of voivodeship (default = Poland)\n";
std::cout << "\t-L\t\tprint all caches\n";
std::cout << "\t-T\t\tprint D/T matrix\n";
std::cout << "\t-O\t\tprint owner count for found caches\n";
std::cout << "\t-Y\t\tprint types count for found caches\n";
std::cout << "\t-h\t\tdisplay this help screen\n";
std::exit(EXIT_FAILURE);
}
@ -100,11 +105,21 @@ int main(int argc, char** argv) {
int heat_stamp_size = 15;
std::string heat_map = "Poland";
bool heat_exp = 0;
bool use_ocpl = 0;
bool use_oc = 0;
bool use_ocpl_db = 0;
bool get_not_found = 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_url = "https://opencaching.pl/okapi/";
std::string ocde_url = "https://www.opencaching.de/okapi/";
std::string ocus_url = "http://www.opencaching.us/okapi/";
std::string ocnl_url = "http://www.opencaching.nl/okapi/";
std::string ocro_url = "http://www.opencaching.ro/okapi/";
std::string ocuk_url = "https://opencache.uk/okapi/";
const std::string Database = "ocpl.sqlite";
std::string gpx_file;
@ -113,33 +128,56 @@ int main(int argc, char** argv) {
if (argc == 1) show_usage();
int o;
while ((o = getopt(argc, argv, "qng:d:pu:MDOH:s:m:eLTYWh?")) != -1)
while ((o = getopt(argc, argv, "qng:o::p:d:u:n:r:k:MDOH:s:m:eLTYWh?")) != -1)
switch (o) {
case 'd':
try {
if (std::stoi(optarg) > 0) {
// Debug(1) << "Setting debug level to " << optarg;
Debug::set_debug_level(std::stoi(optarg));
}
}
catch (...) {
std::cout << "Option \"-d\" requires a valid number as an argument\n";
std::exit(EXIT_FAILURE);
}
break;
// case 'd':
// try {
// if (std::stoi(optarg) > 0) {
// // Debug(1) << "Setting debug level to " << optarg;
// Debug::set_debug_level(std::stoi(optarg));
// }
// }
// catch (...) {
// std::cout << "Option \"-d\" requires a valid number as an argument\n";
// std::exit(EXIT_FAILURE);
// }
// break;
case 'g':
gpx_file = optarg;
break;
case 'o':
use_oc = 1;
if (optarg) {
ocpl_user = optarg;
ocde_user = optarg;
ocus_user = optarg;
ocnl_user = optarg;
ocro_user = optarg;
ocuk_user = optarg;
}
break;
case 'p':
use_ocpl = 1;
ocpl_user = optarg;
break;
case 'd':
ocde_user = optarg;
break;
case 'u':
ocpl_user = optarg;
ocus_user = optarg;
break;
case 'n':
ocnl_user = optarg;
break;
case 'r':
ocro_user = optarg;
break;
case 'k':
ocuk_user = optarg;
break;
case 'q':
use_ocpl_db = 1;
break;
case 'n':
case 'N':
get_not_found = 1;
break;
case 'M':
@ -199,12 +237,37 @@ int main(int argc, char** argv) {
Caches cc;
if (use_ocpl) {
Okapi OCpl(ocpl_url, ocpl_key);
if (!ocpl_user.empty()) {
ocpl_user_uuid = OCpl.get_uuid(ocpl_user);
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);
cc.merge(OCpl.get_user_caches(ocpl_user_uuid, 0));
}
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);
cc.merge(OCde.get_user_caches(ocde_user_uuid, 0));
}
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);
cc.merge(OCus.get_user_caches(ocus_user_uuid, 0));
}
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);
cc.merge(OCnl.get_user_caches(ocnl_user_uuid, 0));
}
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);
cc.merge(OCro.get_user_caches(ocro_user_uuid, 0));
}
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);
cc.merge(OCuk.get_user_caches(ocuk_user_uuid, 0));
}
cc.merge(OCpl.get_user_caches(ocpl_user_uuid, 0));
}
if (!gpx_file.empty()) {