weather-tool: Use a geoip service to get location
Since OpenWeather doesn't provide this with their API, we query ip-api.com, which has a free geoip location service and we can even restrict the data pulled in from it so we're not storing more sensitive data than just a city. Seems to work okay in Japan, but I'll try it from other locations...
This commit is contained in:
parent
fd7f8f103b
commit
14027e83dc
@ -10,8 +10,13 @@
|
|||||||
|
|
||||||
typedef struct JSON_Value Value;
|
typedef struct JSON_Value Value;
|
||||||
|
|
||||||
|
#define WEATHER_CONF_PATH "/etc/weather.json"
|
||||||
|
#define WEATHER_DATA_PATH "/tmp/weather-data.json"
|
||||||
|
#define WEATHER_OUT_PATH "/tmp/weather-parsed.conf"
|
||||||
|
#define LOCATION_DATA_PATH "/tmp/location-data.json"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
Value * config = json_parse_file("/etc/weather.json");
|
Value * config = json_parse_file(WEATHER_CONF_PATH);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
fprintf(stderr, "No weather config data\n");
|
fprintf(stderr, "No weather config data\n");
|
||||||
return 1;
|
return 1;
|
||||||
@ -20,19 +25,41 @@ int main(int argc, char * argv[]) {
|
|||||||
char * city = JSON_KEY(config, "city")->string;
|
char * city = JSON_KEY(config, "city")->string;
|
||||||
char * key = JSON_KEY(config, "key")->string;
|
char * key = JSON_KEY(config, "key")->string;
|
||||||
char * units = JSON_KEY(config, "units")->string;
|
char * units = JSON_KEY(config, "units")->string;
|
||||||
|
|
||||||
char cmdline[1024];
|
char cmdline[1024];
|
||||||
sprintf(cmdline, "fetch -o /tmp/weather-data.json \"http://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=%s\"", city, key, units);
|
|
||||||
|
/* If the city is 'guess', we'll make a single query to a separate service to
|
||||||
|
* get a location from the user's external IP... */
|
||||||
|
if (!strcmp(city, "guess")) {
|
||||||
|
/* See if the location data already exists... */
|
||||||
|
if (access(LOCATION_DATA_PATH, R_OK)) {
|
||||||
|
sprintf(cmdline, "fetch -o \"" LOCATION_DATA_PATH "\" \"http://ip-api.com/json/?fields=countryCode,regionName,city\"");
|
||||||
|
system(cmdline);
|
||||||
|
}
|
||||||
|
Value * locationData = json_parse_file(LOCATION_DATA_PATH);
|
||||||
|
if (!locationData) {
|
||||||
|
fprintf(stderr, "%s: city field was set to 'guess' but failed to acquire data from IP geolocation service\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * cityName = JSON_KEY(locationData, "city")->string;
|
||||||
|
char * regionName = JSON_KEY(locationData, "regionName")->string;
|
||||||
|
char * countryCode = JSON_KEY(locationData, "countryCode")->string;
|
||||||
|
|
||||||
|
city = malloc(strlen(cityName) + strlen(regionName) + strlen(countryCode) + 10);
|
||||||
|
sprintf(city, "%s, %s, %s", cityName, regionName, countryCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(cmdline, "fetch -o \"" WEATHER_DATA_PATH "\" \"http://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=%s\"", city, key, units);
|
||||||
system(cmdline);
|
system(cmdline);
|
||||||
|
|
||||||
Value * result = json_parse_file("/tmp/weather-data.json");
|
Value * result = json_parse_file(WEATHER_DATA_PATH);
|
||||||
assert(result && result->type == JSON_TYPE_OBJECT);
|
assert(result && result->type == JSON_TYPE_OBJECT);
|
||||||
|
|
||||||
Value * _main = JSON_KEY(result,"main");
|
Value * _main = JSON_KEY(result,"main");
|
||||||
Value * conditions = (JSON_KEY(result,"weather") && JSON_KEY(result,"weather")->array->length > 0) ?
|
Value * conditions = (JSON_KEY(result,"weather") && JSON_KEY(result,"weather")->array->length > 0) ?
|
||||||
JSON_IND(JSON_KEY(result,"weather"),0) : NULL;
|
JSON_IND(JSON_KEY(result,"weather"),0) : NULL;
|
||||||
|
|
||||||
FILE * out = fopen("/tmp/weather-parsed.conf", "w");
|
FILE * out = fopen(WEATHER_OUT_PATH, "w");
|
||||||
fprintf(out, "%.2lf\n", JSON_KEY(_main,"temp")->number);
|
fprintf(out, "%.2lf\n", JSON_KEY(_main,"temp")->number);
|
||||||
fprintf(out, "%d\n", (int)JSON_KEY(_main,"temp")->number);
|
fprintf(out, "%d\n", (int)JSON_KEY(_main,"temp")->number);
|
||||||
fprintf(out, "%s\n", conditions ? JSON_KEY(conditions,"main")->string : "");
|
fprintf(out, "%s\n", conditions ? JSON_KEY(conditions,"main")->string : "");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"city": "Tokyo",
|
"city": "guess",
|
||||||
"units": "metric",
|
"units": "metric",
|
||||||
|
|
||||||
"--comment": "The key below is provided for use in ToaruOS for free from OpenWeatherMap.org. We must provide the key so that the weather widget can make API queries. Use of this key for other purposes is against OpenWeatherMap's terms of service.",
|
"--comment": "The key below is provided for use in ToaruOS for free from OpenWeatherMap.org. We must provide the key so that the weather widget can make API queries. Use of this key for other purposes is against OpenWeatherMap's terms of service.",
|
||||||
|
Loading…
Reference in New Issue
Block a user