diff --git a/src/geonames.c b/src/geonames.c index 8d7750a..55c7a8a 100644 --- a/src/geonames.c +++ b/src/geonames.c @@ -1,19 +1,16 @@ +#include #include #include #include #include +#include "../config.h" #include "geonames.h" const char* username = "libastro"; const char* request_url_tpl = "http://api.geonames.org/search?name=%s&maxRows=1&username=%s&type=json&orderby=relevance"; -struct memory_block { - char *address; - size_t size; -}; - static size_t json_parse_callback(void *contents, size_t size, size_t nmemb, void *userp) { static struct json_tokener *jtok; static struct json_object *jobj; @@ -47,6 +44,16 @@ static size_t json_parse_callback(void *contents, size_t size, size_t nmemb, voi } int geonames_lookup(const char *place, struct coords *result, char *name, int n) { + +#ifdef GEONAMES_CACHE_SUPPORT + if (geonames_cache_lookup(place, result, name, n) == EXIT_SUCCESS) { +#ifdef DEBUG + printf("using cached entry\n"); +#endif + return EXIT_SUCCESS; + } +#endif + CURL *ch; CURLcode res; @@ -87,7 +94,14 @@ int geonames_lookup(const char *place, struct coords *result, char *name, int n) if (jobj) { int ret = geonames_parse(jobj, result, name, n); - json_object_put(jobj); + if (ret == EXIT_SUCCESS) { +#ifdef GEONAMES_CACHE_SUPPORT + geonames_cache_store(place, result, name, n); +#ifdef DEBUG + printf("storing cache entry\n"); +#endif +#endif + } return ret; } @@ -112,3 +126,78 @@ int geonames_parse(struct json_object *jobj, struct coords *result, char *name, return EXIT_SUCCESS; } + +int geonames_cache_lookup(const char *place, struct coords *result, char *name, int n) { + /* create filename */ + char filename[256]; + snprintf(filename, sizeof(filename), "%s/%s", getenv("HOME"), GEONAMES_CACHE_FILE); + + FILE *file = fopen(filename, "r"); /* should check the result */ + if (file == NULL) { + return EXIT_FAILURE; + } + + char line[256]; + while (fgets(line, sizeof(line), file)) { + /* replace newline at the end */ + char *end = strchr(line, '\n'); + if (end == NULL) { + return EXIT_FAILURE; + } + else { + *end = '\0'; + } + + char *tok; + int col; + for (col = 0, tok = strtok(line, "\t"); tok != NULL; tok = strtok(NULL, "\t")) { + switch (col) { + case 0: + if (strcmp(tok, place) != 0) { + continue; /* skip row */ + } + break; + + case 1: + result->lat = strtod(tok, NULL); + break; + + case 2: + result->lon = strtod(tok, NULL); + break; + + case 3: + strncpy(name, tok, n); + fclose(file); + return EXIT_SUCCESS; /* found! */ + } + col++; + } + } + + fclose(file); + return 1; /* not found */ +} + +int geonames_cache_store(const char *place, struct coords *result, char *name, int n) { + /* create filename */ + char filename[256]; + snprintf(filename, sizeof(filename), "%s/%s", getenv("HOME"), GEONAMES_CACHE_FILE); + + FILE* file = fopen(filename, "a+"); /* should check the result */ + if (file == NULL) { + return EXIT_FAILURE; + } + + /* build cache entry */ + char line[256]; + snprintf(line, sizeof(line), "%s\t%.5f\t%.5f\t%s\n", place, result->lat, result->lon, name); + + if (fputs(line, file) == EOF) { + fclose(file); + return EXIT_FAILURE; + } + + fclose(file); + return EXIT_SUCCESS; +} diff --git a/src/geonames.h b/src/geonames.h index c5bb7eb..4c26669 100644 --- a/src/geonames.h +++ b/src/geonames.h @@ -1,16 +1,19 @@ #ifndef _GEONAMES_H_ #define _GEONAMES_H_ -//#define DEBUG 1 - #include +#define GEONAMES_CACHE_SUPPORT 1 +#define GEONAMES_CACHE_FILE ".geonames.cache" /* in users home dir */ + struct coords { double lat; double lon; }; int geonames_lookup(const char *place, struct coords *coords, char *name, int n); +int geonames_cache_lookup(const char *place, struct coords *result, char *name, int n); +int geonames_cache_store(const char *place, struct coords *result, char *name, int n); int geonames_parse(struct json_object *jobj, struct coords *result, char *name, int n); #endif /* _GEONAMES_H_ */