kopia lustrzana https://gitlab.com/tomaszg/geostat
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
rodzic
4ee02fd2ee
commit
1c3e1ec0f1
43
README.md
43
README.md
|
@ -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.
|
||||
|
|
|
@ -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 };
|
||||
|
|
145
geostat.cpp
145
geostat.cpp
|
@ -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()) {
|
||||
|
|
Ładowanie…
Reference in New Issue