diff options
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | config.def.h | 2 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | wcli-gen.c | 147 | ||||
-rwxr-xr-x | wcli-query | 9 | ||||
-rw-r--r-- | wcli.c | 192 |
6 files changed, 377 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd9869f --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +include config.mk + +build: config.h + ${CC} -ljson-c wcli-gen.c -o wcli-gen + ${CC} wcli.c -o wcli + +config.h: config.def.h + cp config.def.h config.h + +install: build + mkdir -p $(PREFIX)/bin + cp -f wcli wcli-gen wcli-query $(PREFIX)/bin + chmod 755 ${PREFIX}/bin/wcli + chmod 755 ${PREFIX}/bin/wcli-gen + chmod 755 ${PREFIX}/bin/wcli-query + +uninstall: + rm -f ${PREFIX}/bin/wcli\ + ${PREFIX}/bin/wcli-gen\ + ${PREFIX}/bin/wcli-query + +clean: + rm wcli wcli-gen + +.PHONY: build install uninstall clean diff --git a/config.def.h b/config.def.h new file mode 100644 index 0000000..0f2f277 --- /dev/null +++ b/config.def.h @@ -0,0 +1,2 @@ +static char* working_dir="~/.local/share/wcli/"; +#define VERBOSE diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..79c37b0 --- /dev/null +++ b/config.mk @@ -0,0 +1,2 @@ +PREFIX = ~/.local +CC = cc diff --git a/wcli-gen.c b/wcli-gen.c new file mode 100644 index 0000000..b872255 --- /dev/null +++ b/wcli-gen.c @@ -0,0 +1,147 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <json-c/json.h> + +#define VERBOSE + +#include "config.h" +char *wdir; + +void error(const char* restrict format, ...); +int printv(const char* restrict format, ...); +static int _printv(const char* restrict format, va_list args); + +void +error(const char* restrict format, ...) +{ + va_list args; + va_start(args,format); + _printv(format,args); + va_end(args); + + exit(1); + return; +} + +int +printv(const char* restrict format, ...) +{ + va_list args; + va_start(args,format); + int ret = _printv(format,args); + va_end(args); + + return ret; +} + +int +_printv(const char* restrict format, va_list args) +{ +#ifndef VERBOSE + return 0; +#endif + + int ret = vprintf(format,args); + return ret; +} + +void +str_conc_const(const char *s1, const char *s2, char *res) +{ + const size_t l1 = strlen(s1); + const size_t l2 = strlen(s2); + + memcpy(res,s1,l1); + memcpy(res+l1,s2,l2+1); + return; +} + +char* +str_conc(const char *s1, const char *s2) +{ + const size_t l1 = strlen(s1); + const size_t l2 = strlen(s2); + + char* res = malloc(l1 + l2 + 1); + if (res == NULL) + error("Error while concatenating \"%s\" and \"%s\".\n", s1, s2); + + str_conc_const(s1, s2, res); + return res; +} + +void +parse(char *fn) +{ + json_object *weather, *root, *day, *hly, *hour; + char *file, *pref, suf[3]; + FILE *fl; + int i, j, s, h; + root = json_object_from_file(fn); + if (!root) + error("Error\n"); + /* Assuming no errors */ + + weather = json_object_object_get(root, "weather"); + s = json_object_array_length(weather); + suf[0] = '-'; + suf[2] = '\0'; + for (i = 0; i < s; i++) { + day = json_object_array_get_idx(weather,i); + hly = json_object_object_get(day, "hourly"); + + if (!i) + pref = str_conc(wdir,json_object_get_string(json_object_object_get(day, "date"))); + else + str_conc_const(wdir,json_object_get_string(json_object_object_get(day, "date")),pref); + + h = json_object_array_length(hly); + for (j = 0; j < h; j++) { + suf[1] = j+'0'; + if (!i && !j) + file = str_conc(pref,suf); + else + str_conc_const(pref,suf,file); + + hour = json_object_array_get_idx(hly,j); + fl = fopen(file,"w"); + + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "tempC"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "tempF"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "FeelsLikeC"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "FeelsLikeF"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "windspeedKmph"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "WindGustKmph"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "winddir16Point"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "winddirDegree"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "visibility"))); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "weatherCode"))); + hour = json_object_array_get_idx(json_object_object_get(hour, "weatherDesc"),0); + fprintf(fl, "%s\n", json_object_get_string(json_object_object_get(hour, "value"))); + fclose(fl); + } + } + + free(file); + free(pref); + + json_object_put(root); + return; +} + +int +main(int argc, char** argv) +{ + if (argc < 2) + error("Not enough arguments.\n"); + + if (working_dir[0] == '~') { + wdir = str_conc(getenv("HOME"), &working_dir[1]); + } else { + wdir = working_dir; + } + + parse(argv[1]); +} diff --git a/wcli-query b/wcli-query new file mode 100755 index 0000000..109723f --- /dev/null +++ b/wcli-query @@ -0,0 +1,9 @@ +#!/bin/sh + +dir="$HOME/.local/share/wcli" +file="$dir/$(date +info_%F_%H-%M.json)" +country="" + +mkdir -p "$dir" || exit 1 +curl "wttr.in/${country}?format=j1" -o "$file" || exit 1 +wcli-gen "$file" @@ -0,0 +1,192 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> + +#include "config.h" + +#define DLEN 25 + +time_t rawtime; +struct tm *timeinfo; + +struct data { + int temp_c; + int temp_f; + int feel_temp_c; + int feel_temp_f; + int wind_speed; + int wind_gust; + char wind_dir_16[4]; + int wind_dir_deg; + int vis; + int weather_code; + char weather_desc[DLEN]; +} w; + +void +error() +{ + printf("doom"); + exit(1); + return; +} + +void +str_conc_const(const char *s1, const char *s2, char *res) +{ + const size_t l1 = strlen(s1); + const size_t l2 = strlen(s2); + + memcpy(res,s1,l1); + memcpy(res+l1,s2,l2+1); + return; +} + +char* +str_conc(const char *s1, const char *s2) +{ + const size_t l1 = strlen(s1); + const size_t l2 = strlen(s2); + + char* res = malloc(l1 + l2 + 1); + if (res == NULL) + error(); + + str_conc_const(s1, s2, res); + + return res; +} + +char +get_dig(short int u, int x) +{ + while (--x) + u /= 10; + return (u % 10) + '0'; +} + +void +get_file(char *file) +{ + int i, of; + of = 0; + + for (i = 0; i < 4; ++i) + file[of++] = get_dig(timeinfo->tm_year+1900, 4-i); + file[of++] = '-'; + + for (i = 0; i < 2; ++i) + file[of++] = get_dig(timeinfo->tm_mon+1, 2-i); + file[of++] = '-'; + + for (i = 0; i < 2; ++i) + file[of++] = get_dig(timeinfo->tm_mday, 2-i); + file[of++] = '-'; + + file[of++] = (timeinfo->tm_hour/3) + '0'; + file[of] = '\0'; +} + +void +read_data(char *file) +{ + FILE *f = fopen(file, "r"); + if (!f) + error(); + + fscanf(f, "%d\n", &w.temp_c); + fscanf(f, "%d\n", &w.temp_f); + fscanf(f, "%d\n", &w.feel_temp_c); + fscanf(f, "%d\n", &w.feel_temp_f); + fscanf(f, "%d\n", &w.wind_speed); + fscanf(f, "%d\n", &w.wind_gust); + fscanf(f, "%s\n", w.wind_dir_16); + fscanf(f, "%d\n", &w.wind_dir_deg); + fscanf(f, "%d\n", &w.vis); + fscanf(f, "%d\n", &w.weather_code); + fgets(w.weather_desc, DLEN, f); + if (strlen(w.weather_desc) && + w.weather_desc[strlen(w.weather_desc)-1] == '\n') + w.weather_desc[strlen(w.weather_desc)-1] = '\0'; + + fclose(f); + return; +} + +void +place_holder(char c) +{ + switch(c) { + case 'c': printf("%d", w.temp_c); break; + case 'f': printf("%d", w.temp_f); break; + case 'C': printf("%d", w.feel_temp_c); break; + case 'F': printf("%d", w.feel_temp_f); break; + case 's': printf("%d", w.wind_speed); break; + case 'g': printf("%d", w.wind_gust); break; + case 'd': printf("%s", w.wind_dir_16); break; + case 'D': printf("%d", w.wind_dir_deg); break; + case 'v': printf("%d", w.vis); break; + case 'w': printf("%d", w.weather_code); break; + case 'W': printf("%s", w.weather_desc); break; + case '%': printf("%c", '%'); break; + } + return; +} + +void +print(char *f) +{ + short int sp = 0; + int p = 0; + + while (f[p] != '\0') { + if (sp) { + place_holder(f[p]); + sp = 0; + } else { + if (f[p] == '%') + sp = 1; + else + printf("%c", f[p]); + } + + ++p; + } + + return; +} + + +int +main(int argc, char** argv) +{ + char file[28]; + char *filename, *tempn; + + if (argc < 2) + error(); + + time(&rawtime); + rawtime += (time_t)5400; /* adds 1.5h because time between data is 3 hours */ + timeinfo = localtime(&rawtime); + + get_file(file); + + if (working_dir[0] == '~') { + tempn = str_conc(getenv("HOME"), &working_dir[1]); + filename = str_conc(tempn,file); + free(tempn); + } else { + filename = str_conc(working_dir,file); + } + + + read_data(filename); + free(filename); + + print(argv[1]); + + return 0; +} |