finished geonames.org lookup

This commit is contained in:
Steffen Vogel 2012-12-08 12:18:37 +01:00
parent 73f8045943
commit fdb977717b
4 changed files with 148 additions and 1 deletions

View file

@ -1,4 +1,10 @@
bin_PROGRAMS = astro
bin_PROGRAMS = astro sun geonames
astro_SOURCES = calendar.c astro.c
astro_LDADD = -lm
sun_SOURCES = sun.c
sun_LDADD = -lm
geonames_SOURCES = geonames_test.c geonames.c
geonames_LDADD = -lcurl -ljson

106
src/geonames.c Normal file
View file

@ -0,0 +1,106 @@
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <json/json.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;
size_t realsize = size * nmemb;
/* initialize tokener */
if (jtok == NULL) {
jtok = json_tokener_new();
jtok->err = json_tokener_continue;
}
if (jtok->err == json_tokener_continue) {
#ifdef DEBUG
printf("got chunk: %d * %d = %d bytes\r\n", size, nmemb, realsize);
#endif
jobj = json_tokener_parse_ex(jtok, (char *) contents, realsize);
if (jtok->err == json_tokener_success) {
*(struct json_object **) userp = jobj;
json_tokener_free(jtok);
}
else if (jtok->err != json_tokener_continue) {
fprintf(stderr, "parse error: %s\r\n", json_tokener_errors[jtok->err]);
*(void **) userp = NULL;
json_tokener_free(jtok);
}
}
return realsize;
}
int geonames_lookup(const char *place, struct coords *result) {
CURL *ch;
CURLcode res;
struct json_object *jobj;
/* setup curl */
ch = curl_easy_init();
if (!ch) return -1;
/* prepare url */
int len = strlen(place) + strlen(request_url_tpl) + 1;
char *request_url = malloc(len);
if (!request_url) {
return -2;
}
snprintf(request_url, len, request_url_tpl, place, username);
#ifdef DEBUG
printf("request url: %s\r\n", request_url);
#endif
curl_easy_setopt(ch, CURLOPT_URL, request_url);
curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, json_parse_callback);
curl_easy_setopt(ch, CURLOPT_WRITEDATA, (void *) &jobj);
curl_easy_setopt(ch, CURLOPT_USERAGENT, "libastro/1.0");
/* perform request */
res = curl_easy_perform(ch);
/* always cleanup */
curl_easy_cleanup(ch);
if (res != CURLE_OK) {
fprintf(stderr, "request failed: %s\n", curl_easy_strerror(res));
return EXIT_FAILURE;
}
if (jobj) {
return geonames_parse(jobj, result);;
}
else {
return EXIT_FAILURE;
}
}
int geonames_parse(struct json_object *jobj, struct coords *result) {
struct json_object *jobj_place = json_object_array_get_idx(json_object_object_get(jobj, "geonames"), 0);
result->lat = json_object_get_double(json_object_object_get(jobj_place, "lat"));
result->lon = json_object_get_double(json_object_object_get(jobj_place, "lng"));
/* cleanup */
json_object_put(jobj);
return EXIT_SUCCESS;
}

16
src/geonames.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef _GEONAMES_H_
#define _GEONAMES_H_
//#define DEBUG 1
#include <json/json.h>
struct coords {
double lat;
double lon;
};
int geonames_lookup(const char *place, struct coords *coords);
int geonames_parse(struct json_object *jobj, struct coords *result);
#endif /* _GEONAMES_H_ */

19
src/geonames_test.c Normal file
View file

@ -0,0 +1,19 @@
#include <stdio.h>
#include "geonames.h"
int main(int argc, char *argv[]) {
struct coords res;
char *name = "Aachen";
if (argc == 2) {
name = argv[1];
}
if (geonames_lookup(name, &res) == 0) {
printf("%s is at (%.4f, %.4f)\r\n", name, res.lat, res.lon);
return 0;
}
return 0;
}