From 375f6e2306e5079bdbdb4e0bf658ec0726ef123d Mon Sep 17 00:00:00 2001 From: Mariusz Bialonczyk Date: Mon, 13 May 2019 15:12:30 +0100 Subject: [PATCH] Add json-c dependency Summary: Old API retired => use yahoo weather JSON API The new API is returning data in JSON format. This commit is switching it over (currently SSL server) and parsing to have the data in par with previous data. Example data: https://www.yahoo.com/news/_tdnews/api/resource/WeatherService;woeids=839722 Fix millibar to inches of mercury divider Merge branch 'json-api' Reviewers: vtorri, bu5hm4n, stephenmhouston Reviewed By: vtorri Subscribers: raster, vtorri Differential Revision: https://phab.enlightenment.org/D8095 --- .gitignore | 1 + INSTALL | 16 +- Makefile.am | 32 ---- autogen.sh | 17 --- configure.ac | 72 --------- e_modules-forecasts.spec.in | 48 ------ m4/.svnignore | 0 meson.build | 75 ++++++++++ module.desktop.in => module.desktop | 0 po/LINGUAS | 1 - po/Makevars | 41 ------ po/POTFILES.in | 4 - po/meson.build | 11 ++ src/Makefile.am | 20 --- src/e_mod_config.c | 14 +- src/e_mod_main.c | 218 +++++++++------------------- src/meson.build | 10 ++ 17 files changed, 173 insertions(+), 407 deletions(-) delete mode 100644 Makefile.am delete mode 100755 autogen.sh delete mode 100644 configure.ac delete mode 100644 e_modules-forecasts.spec.in delete mode 100644 m4/.svnignore create mode 100644 meson.build rename module.desktop.in => module.desktop (100%) delete mode 100644 po/LINGUAS delete mode 100644 po/Makevars delete mode 100644 po/POTFILES.in create mode 100644 po/meson.build delete mode 100644 src/Makefile.am create mode 100644 src/meson.build diff --git a/.gitignore b/.gitignore index a91aea0..2f27f62 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build *~ ABOUT-NLS Makefile diff --git a/INSTALL b/INSTALL index 8919fc2..7b1a1a6 100644 --- a/INSTALL +++ b/INSTALL @@ -1,11 +1,5 @@ -COMPILING and INSTALLING: - -If you got a official release tar archive do: - ./autogen.sh - -Then to compile: - make - -To install: - make install - +To build using meson: + meson build + cd build + ninja + ninja install diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 2e3ae8c..0000000 --- a/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -ACLOCAL_AMFLAGS = -I m4 -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \ - config.sub configure depcomp install-sh ltmain.sh \ - missing module.desktop config.rpath mkinstalldirs - -SUBDIRS = src - -if HAVE_PO - -SUBDIRS += po - -endif - -EDJE_FLAGS = -id $(top_srcdir)/images - -filesdir = $(datadir) -files_DATA = module.desktop e-module-forecasts.edj forecasts.edj - -EXTRA_DIST = module.desktop.in \ - e_modules-forecasts.spec.in \ - e-module-forecasts.edc \ - forecasts.edc \ - $(wildcard images/*.png) - -%.edj: %.edc - $(EDJE_CC) $(EDJE_FLAGS) $< $@ - -clean-local: - rm -rf forecasts.edj e-module-forecasts.edj module.desktop e_modules-forecasts.spec *~ - -uninstall: - rm -rf $(DESTDIR)$(datadir) diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index ae01364..0000000 --- a/autogen.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f aclocal.m4 ltmain.sh - -touch README - -echo "Running autopoint..." ; autopoint -f || : -echo "Running aclocal..." ; aclocal -I m4 $ACLOCAL_FLAGS || exit 1 -echo "Running autoheader..." ; autoheader || exit 1 -echo "Running autoconf..." ; autoconf || exit 1 -echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1 -echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1 - -if [ -z "$NOCONFIGURE" ]; then - ./configure "$@" -fi diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 82b9744..0000000 --- a/configure.ac +++ /dev/null @@ -1,72 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -# get rid of that stupid cache mechanism -rm -f config.cache - -AC_INIT(forecasts, 0.2.0, viktor@bloka.org) -AC_PREREQ(2.52) -AC_CONFIG_SRCDIR(configure.ac) -AC_CANONICAL_BUILD -AC_CANONICAL_HOST -AC_ISC_POSIX - -AM_INIT_AUTOMAKE(1.6) -AC_CONFIG_HEADERS(config.h) - -AC_PROG_CC -AC_HEADER_STDC -AC_C_CONST - -define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl -define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl -AC_PROG_LIBTOOL - -m4_ifdef([AM_GNU_GETTEXT_VERSION], [ -AM_GNU_GETTEXT_VERSION([0.14]) -]) - -m4_ifdef([AM_GNU_GETTEXT], [ -AM_GNU_GETTEXT([external]) -po_makefile_in=po/Makefile.in -AM_CONDITIONAL([HAVE_PO], [true]) -],[ -AM_CONDITIONAL([HAVE_PO], [false]) -]) -AC_SUBST(LTLIBINTL) - -PKG_CHECK_MODULES(E, [enlightenment]) -release=$(pkg-config --variable=release enlightenment) -MODULE_ARCH="$host_os-$host_cpu-$release" -AC_SUBST(MODULE_ARCH) -AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture") - -# Find edje_cc -PKG_CHECK_MODULES(EDJE, [edje >= 0.5.0]) -AC_ARG_WITH(edje-cc, - AC_HELP_STRING([--with-edje-cc=PATH], [specify a specific path to edje_cc]), - [ - v=$withval; - EDJE_CC=$v - ],[ - EDJE_CC=$(pkg-config --variable=prefix edje)/bin/edje_cc - ] -) -AC_SUBST(EDJE_CC) -AC_MSG_CHECKING([Which edje_cc to use]) -AC_MSG_RESULT(${EDJE_CC}) - -datadir=$(pkg-config --variable=modules enlightenment)/${PACKAGE} -AC_ARG_ENABLE(homedir-install, - AS_HELP_STRING([--enable-homedir-install], [Install module in homedir]), - [ datadir="${HOME}/.e/e/modules/${PACKAGE}" ] -) - -AC_OUTPUT([ -Makefile -src/Makefile -module.desktop -e_modules-forecasts.spec -$po_makefile_in -], [ -]) - diff --git a/e_modules-forecasts.spec.in b/e_modules-forecasts.spec.in deleted file mode 100644 index f24a389..0000000 --- a/e_modules-forecasts.spec.in +++ /dev/null @@ -1,48 +0,0 @@ -%define module_name forecasts -%{!?_rel:%{expand:%%global _rel 0.enl%{?dist}}} - -Summary: %{module_name} module for the Enlightenment window manager -Name: e_modules-%{module_name} -Version: @VERSION@ -Release: %{_rel} -License: BSD -Group: User Interface/Desktops -URL: http://www.enlightenment.org/ -Source: ftp://ftp.enlightenment.org/pub/enlightenment/%{module_name}-%{version}.tar.gz -Packager: %{?_packager:%{_packager}}%{!?_packager:Michael Jennings } -Vendor: %{?_vendorinfo:%{_vendorinfo}}%{!?_vendorinfo:The Enlightenment Project (http://www.enlightenment.org/)} -Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}} -BuildRequires: ecore-devel, evas-devel, edje-bin -BuildRequires: edje-devel, eet-devel, enlightenment-devel >= 0.16.999 -Requires: enlightenment >= 0.16.999 -BuildRoot: %{_tmppath}/%{name}-%{version}-root - -%description -%{module_name} module for the Enlightenment window manager. - -%prep -%setup -q -n %{module_name}-%{version} - -%build -%{configure} -%{__make} %{?_smp_mflags} %{?mflags} - -%install -%{__make} %{?mflags_install} DESTDIR=$RPM_BUILD_ROOT install -%{find_lang} %{module_name} || true > %{module_name}.lang - -%clean -test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT - -%post -/sbin/ldconfig - -%postun -/sbin/ldconfig - -%files -f %{module_name}.lang -%defattr(-, root, root) -%doc AUTHORS ChangeLog COPYING* INSTALL NEWS README -%{_libdir}/enlightenment/modules/%{module_name}* - -%changelog diff --git a/m4/.svnignore b/m4/.svnignore deleted file mode 100644 index e69de29..0000000 diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..68cd960 --- /dev/null +++ b/meson.build @@ -0,0 +1,75 @@ +project('forecasts', 'c') + +e = dependency('enlightenment') + +dir_module_e = e.get_pkgconfig_variable('modules') +release = e.get_pkgconfig_variable('release') +host_os = host_machine.system() +cc = meson.get_compiler('c') + +if host_os == 'linux' + if cc.has_header_symbol('features.h', '__UCLIBC__') + host_os = 'linux-uclibc' + elif cc.has_header_symbol('features.h', '__dietlibc__') + host_os = 'linux-dietlibc' + else + host_os = 'linux-gnu' + endif +endif +module_arch = '@0@-@1@-@2@'.format(host_os, host_machine.cpu_family(), release) +edje_cmd = find_program('edje_cc') + +install_mod_dir = join_paths(dir_module_e, meson.project_name()) +install_dir = join_paths(install_mod_dir, module_arch) + +config_data = configuration_data() +config_data.set_quoted('MODULE_DIR', install_dir) + +use_translations = false +intl_lib = cc.find_library('intl', required: false) +if intl_lib.found() + config_data.set('ENABLE_NLS', 1) + terminology_dependencies += [intl_lib] + use_translations = true +else + gettext_code = ''' + #include + int main(int argc, char *argv[]) { + (void)ngettext("", "", 0); + return 0; + } + ''' + if cc.links(gettext_code) + config_data.set('ENABLE_NLS', 1) + use_translations = true + endif +endif + +subdir('src') + +configure_file(output: 'config.h', install: false, configuration: config_data) + +install_data('module.desktop', install_dir : install_mod_dir) + +cmd = [ edje_cmd, + '-id', join_paths(meson.source_root(), 'images'), + '@INPUT@', '@OUTPUT@' + ] +custom_target('e-module-forecasts.edj', + input : 'e-module-forecasts.edc', + output : 'e-module-forecasts.edj', + command : cmd, + install_dir: install_mod_dir, + install : true + ) +custom_target('forecasts.edj', + input : 'forecasts.edc', + output : 'forecasts.edj', + command : cmd, + install_dir: install_mod_dir, + install : true + ) + +if use_translations + subdir('po') +endif diff --git a/module.desktop.in b/module.desktop similarity index 100% rename from module.desktop.in rename to module.desktop diff --git a/po/LINGUAS b/po/LINGUAS deleted file mode 100644 index a8dbd71..0000000 --- a/po/LINGUAS +++ /dev/null @@ -1 +0,0 @@ -ar bg ca cs de el eo es fi fr gl he hr hu it ja ko lt nb nl pl pt pt_BR ru sk sl sr sv tr uk zh_CN diff --git a/po/Makevars b/po/Makevars deleted file mode 100644 index 9275c25..0000000 --- a/po/Makevars +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile variables for PO directory in any package using GNU gettext. - -# Usually the message domain is the same as the package name. -DOMAIN = $(PACKAGE) - -# These two variables depend on the location of this directory. -subdir = po -top_builddir = .. - -# These options get passed to xgettext. -XGETTEXT_OPTIONS = --keyword=N_ --keyword=D_ --from-code=UTF-8 --foreign-user - -# This is the copyright holder that gets inserted into the header of the -# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding -# package. (Note that the msgstr strings, extracted from the package's -# sources, belong to the copyright holder of the package.) Translators are -# expected to transfer the copyright for their translations to this person -# or entity, or to disclaim their copyright. The empty string stands for -# the public domain; in this case the translators are expected to disclaim -# their copyright. -COPYRIGHT_HOLDER = Enlightenment development team - -# This is the email address or URL to which the translators shall report -# bugs in the untranslated strings: -# - Strings which are not entire sentences, see the maintainer guidelines -# in the GNU gettext documentation, section 'Preparing Strings'. -# - Strings which use unclear terms or require additional context to be -# understood. -# - Strings which make invalid assumptions about notation of date, time or -# money. -# - Pluralisation problems. -# - Incorrect English spelling. -# - Incorrect formatting. -# It can be your email address, or a mailing list address where translators -# can write to without being subscribed, or the URL of a web page through -# which the translators can contact you. -MSGID_BUGS_ADDRESS = enlightenment-devel@lists.sourceforge.net - -# This is the list of locale categories, beyond LC_MESSAGES, for which the -# message catalogs shall be used. It is usually empty. -EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index e485344..0000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,4 +0,0 @@ -src/e_mod_config.c -src/e_mod_config.h -src/e_mod_main.c -src/e_mod_main.h diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000..da87a00 --- /dev/null +++ b/po/meson.build @@ -0,0 +1,11 @@ +i18n = import('i18n') +i18n.gettext('forecasts', + languages: [ + 'ar','bg','ca','cs','de','el','eo','es','fi','fr','gl','he','hr','hu','it','ja','ko','lt','nb','nl','pl','pt','pt_BR','ru','sk','sl','sr','sv','tr','uk','zh_CN' + ], + args: [ + '--keyword=N_', + '--keyword=D_', + '--from-code=UTF-8', + '--foreign-user' + ]) diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index e56e019..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in - -INCLUDES = -I. \ - -I$(top_srcdir) \ - -I$(includedir) \ - @E_CFLAGS@ - -pkgdir = $(datadir)/$(MODULE_ARCH) -pkg_LTLIBRARIES = module.la -module_la_SOURCES = e_mod_main.c \ - e_mod_main.h \ - e_mod_config.c \ - e_mod_config.h - -module_la_LIBADD = @E_LIBS@ -module_la_LDFLAGS = -module -avoid-version -module_la_DEPENDENCIES = $(top_builddir)/config.h - -clean-local: - rm -rf *~ diff --git a/src/e_mod_config.c b/src/e_mod_config.c index c5fb58d..1cc2606 100644 --- a/src/e_mod_config.c +++ b/src/e_mod_config.c @@ -82,7 +82,6 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, { Evas_Object *o, *of, *ob; E_Radio_Group *dg; - char buf[4096]; o = e_widget_list_add(evas, 0, 0); of = e_widget_framelist_add(evas, D_("Display Settings"), 0); @@ -106,16 +105,15 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, e_widget_framelist_object_append(of, ob); e_widget_list_object_append(o, of, 1, 1, 0.5); - of = e_widget_frametable_add(evas, D_("Weather.com Forecasts Code"), 0); - ob = e_widget_label_add(evas, D_("Forecasts Code/US Zip Code")); - e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 0, 1, 0); - ob = e_widget_entry_add(evas, &cfdata->code, NULL, NULL, NULL); + of = e_widget_frametable_add(evas, D_("Yahoo Weather Forecasts Code"), 0); + ob = e_widget_label_add(evas, D_("Forecasts Code")); + e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 0, 0, 0); + ob = e_widget_entry_add(cfd->dia->win, &cfdata->code, NULL, NULL, NULL); e_widget_size_min_set(ob, 100, 20); e_widget_frametable_object_append(of, ob, 1, 0, 1, 1, 1, 0, 1, 0); - ob = e_widget_label_add(evas, D_("To find the code for your area, go to:")); + ob = e_widget_label_add(evas, D_("To find the code go to: http://weather.yahoo.com")); e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0); - snprintf(buf, sizeof(buf), D_("%s, find your area, and look at the URL"), "http://www.weather.com"); - ob = e_widget_label_add(evas, buf); + ob = e_widget_label_add(evas, D_("search your location and the code is last few digits after the hyphen in the URL")); e_widget_frametable_object_append(of, ob, 0, 2, 2, 1, 1, 0, 1, 0); e_widget_list_object_append(o, of, 1, 1, 0.5); diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 4f4522d..4335c2c 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -1,9 +1,13 @@ #include #include "e_mod_main.h" +#include + +#define _XOPEN_SOURCE +#include #define FORECASTS 2 #define KM_TO_MI 1.609344 -#define MB_TO_IN 68.946497518 +#define MB_TO_IN 33.864 #define GOLDEN_RATIO 1.618033989 @@ -370,7 +374,7 @@ _forecasts_config_item_get(const char *id) ci->id = eina_stringshare_add(id); ci->poll_time = 60.0; ci->degrees = DEGREES_C; - ci->host = eina_stringshare_add("query.yahooapis.com"); + ci->host = eina_stringshare_add("www.yahoo.com"); ci->code = eina_stringshare_add("839722"); ci->show_text = 1; ci->popup_on_hover = 1; @@ -424,7 +428,7 @@ e_modapi_init(E_Module *m) ci = E_NEW(Config_Item, 1); ci->poll_time = 60.0; ci->degrees = DEGREES_C; - ci->host = eina_stringshare_add("query.yahooapis.com"); + ci->host = eina_stringshare_add("www.yahoo.com"); ci->code = eina_stringshare_add("839722"); ci->id = eina_stringshare_add("0"); ci->show_text = 1; @@ -580,7 +584,7 @@ _forecasts_cb_check(void *data) proxy.host, proxy.port, inst); else inst->server = - ecore_con_server_connect(ECORE_CON_REMOTE_NODELAY, inst->ci->host, 80, inst); + ecore_con_server_connect(ECORE_CON_REMOTE_NODELAY | ECORE_CON_USE_MIXED, inst->ci->host, 443, inst); if (!inst->server) return EINA_FALSE; return EINA_TRUE; @@ -593,7 +597,6 @@ _forecasts_server_add(void *data, int type, void *event) Ecore_Con_Event_Server_Add *ev; char buf[1024]; char forecast[1024]; - char degrees; inst = data; if (!inst) @@ -603,13 +606,8 @@ _forecasts_server_add(void *data, int type, void *event) if ((!inst->server) || (inst->server != ev->server)) return EINA_TRUE; - if (inst->ci->degrees == DEGREES_F) - degrees = 'f'; - else - degrees = 'c'; - - snprintf(forecast, sizeof(forecast), "/v1/public/yql?q=select+%%2A+from+weather.forecast+where+woeid%%3D%s+and+u%%3D%%27%c%%27", inst->ci->code, degrees); - snprintf(buf, sizeof(buf), "GET http://%s%s HTTP/1.1\r\n" + snprintf(forecast, sizeof(forecast), "/news/_tdnews/api/resource/WeatherService;woeids=%s", inst->ci->code); + snprintf(buf, sizeof(buf)-strlen(forecast)-(strlen(inst->ci->host)*2), "GET https://%s%s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n\r\n", inst->ci->host, forecast, inst->ci->host); @@ -647,7 +645,6 @@ _forecasts_server_data(void *data, int type, void *event) { Instance *inst; Ecore_Con_Event_Server_Data *ev; - void *tmp; inst = data; ev = event; @@ -663,12 +660,7 @@ _forecasts_parse(void *data) { Instance *inst; char *needle; - char city[256]; - char region[256]; - char *region_ptr; - char location[512]; - float visibility; - int i; + int secs, i; inst = data; if (!inst) @@ -676,151 +668,71 @@ _forecasts_parse(void *data) if (!inst->buffer) return 0; - /* Location */ - needle = strstr(eina_strbuf_string_get(inst->buffer), "buffer), "\r\n\r\n"); if (!needle) goto error; - needle = strstr(needle, "city=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%255[^\"]\"", city); + needle += 4; - region[0] = '\0'; - needle = strstr(needle, "region=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%255[^\"]\"", region); - region_ptr = region; - //get rid of leading white space - if (region[0] = ' ') - region_ptr++; + /* parse data to json object */ + json_object *obj_root = json_tokener_parse(needle); + json_object *obj_weathers = json_object_object_get(obj_root, "weathers"); + if (json_object_get_type(obj_weathers) != json_type_array || json_object_array_length(obj_weathers) != 1) + goto error; + json_object *obj_main = json_object_array_get_idx(obj_weathers, 0); - if (strlen(region_ptr)) - snprintf(location, 512, "%s, %s", city, region_ptr); - else - snprintf(location, 512, "%s", city); + /* we have data in imperial units by default, so set it accordingly */ + inst->units.temp = 'F'; + snprintf(inst->units.distance, 3, "mi"); + snprintf(inst->units.pressure, 3, "in"); + snprintf(inst->units.speed, 4, "mph"); - eina_stringshare_replace(&inst->location, location); + json_object *obj_location = json_object_object_get(obj_main, "location"); + eina_stringshare_replace(&inst->location, json_object_get_string(json_object_object_get(obj_location, "displayName"))); - /* Units */ - needle = strstr(eina_strbuf_string_get(inst->buffer), "units.distance); - needle = strstr(needle, "pressure=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%2[^\"]\"", inst->units.pressure); - needle = strstr(needle, "speed=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%4[^\"]\"", inst->units.speed); - needle = strstr(needle, "temperature=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%c\"", &inst->units.temp); + json_object *obj_sunmoon = json_object_object_get(obj_main, "sunAndMoon"); + secs = json_object_get_int(json_object_object_get(obj_sunmoon, "sunrise")); + snprintf(inst->details.astronomy.sunrise, 7, "%02d:%02d", secs/3600, (secs%3600)/60); + secs = json_object_get_int(json_object_object_get(obj_sunmoon, "sunset")); + snprintf(inst->details.astronomy.sunset, 7, "%02d:%02d", secs/3600, (secs%3600)/60); /* Current conditions */ - needle = strstr(eina_strbuf_string_get(inst->buffer), "condition.code); - needle = strstr(needle, "date=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%51[^\"]\"", inst->condition.update); - needle = strstr(needle, "temp=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%d\"", &inst->condition.temp); - needle = strstr(needle, "text=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%255[^\"]\"", inst->condition.desc); + json_object *obj_observation = json_object_object_get(obj_main, "observation"); + inst->details.atmosphere.pressure = json_object_get_double(json_object_object_get(obj_observation, "barometricPressure")); + inst->details.atmosphere.humidity = json_object_get_int(json_object_object_get(obj_observation, "humidity")); + inst->details.atmosphere.visibility = json_object_get_double(json_object_object_get(obj_observation, "visibility")); + inst->condition.code = json_object_get_int(json_object_object_get(obj_observation, "conditionCode")); + strncpy(inst->condition.desc, json_object_get_string(json_object_object_get(obj_observation, "conditionDescription")), 255); + inst->details.wind.direction = json_object_get_int(json_object_object_get(obj_observation, "windDirection")); + inst->details.wind.speed = json_object_get_int(json_object_object_get(obj_observation, "windSpeed")); - /* Details */ - /* Wind */ - needle = strstr(eina_strbuf_string_get(inst->buffer), "details.wind.chill); - needle = strstr(needle, "direction=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%d\"", &inst->details.wind.direction); - needle = strstr(needle, "speed=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%d\"", &inst->details.wind.speed); + json_object *obj_observation_temp = json_object_object_get(obj_observation, "temperature"); + inst->condition.temp = json_object_get_int(json_object_object_get(obj_observation_temp, "now")); + inst->details.wind.chill = json_object_get_int(json_object_object_get(obj_observation_temp, "feelsLike")); - /* Atmosphere */ - needle = strstr(eina_strbuf_string_get(inst->buffer), "details.atmosphere.humidity); - needle = strstr(needle, "pressure=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%f\"", &inst->details.atmosphere.pressure); - needle = strstr(needle, "rising=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%d\"", &inst->details.atmosphere.rising); - needle = strstr(needle, "visibility=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%f\"", &visibility); - inst->details.atmosphere.visibility = visibility; - - /* Astronomy */ - needle = strstr(eina_strbuf_string_get(inst->buffer), "details.astronomy.sunrise); - needle = strstr(needle, "sunset=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%8[^\"]\"", inst->details.astronomy.sunset); + json_object *obj_observation_time = json_object_object_get(obj_observation, "observationTime"); + strncpy(inst->condition.update, json_object_get_string(json_object_object_get(obj_observation_time, "timestamp")), 51); /* Forecasts */ - for (i = 0; i < FORECASTS; i++) - { - needle = strstr(needle, "forecast[i].code); - needle = strstr(needle, "date=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%12[^\"]\"", inst->forecast[i].date); - needle = strstr(needle, "day=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%4[^\"]\"", inst->forecast[i].day); - needle = strstr(needle, "high=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%d\"", &inst->forecast[i].high); - needle = strstr(needle, "low=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%d\"", &inst->forecast[i].low); - needle = strstr(needle, "text=\""); - if (!needle) goto error; - needle = strstr(needle, "\""); - sscanf(needle, "\"%255[^\"]\"", inst->forecast[i].desc); - } + json_object *obj_forecasts = json_object_object_get(obj_main, "forecasts"); + json_object *obj_forecasts_daily = json_object_object_get(obj_forecasts, "daily"); + for (i = 0; i < FORECASTS; i++) { + json_object *obj_forecast = json_object_array_get_idx(obj_forecasts_daily, i); + inst->forecast[i].code = json_object_get_int(json_object_object_get(obj_forecast, "conditionCode")); + strncpy(inst->forecast[i].desc, json_object_get_string(json_object_object_get(obj_forecast, "conditionDescription")), 255); + + json_object *obj_observation_time = json_object_object_get(obj_forecast, "observationTime"); + strncpy(inst->forecast[i].day, json_object_get_string(json_object_object_get(obj_observation_time, "day")), 3); + struct tm tm; + memset(&tm, 0, sizeof(struct tm)); + strptime(json_object_get_string(json_object_object_get(obj_observation_time, "timestamp")), "%Y-%m-%dT%H:%M:%S", &tm); + strftime(inst->forecast[i].date, 12, "%d %b %Y", &tm); + + json_object *obj_observation_temp = json_object_object_get(obj_forecast, "temperature"); + inst->forecast[i].high = json_object_get_int(json_object_object_get(obj_observation_temp, "high")); + inst->forecast[i].low = json_object_get_int(json_object_object_get(obj_observation_temp, "low")); + } + + json_object_put(obj_root); return 1; error: diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..bbb9b20 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,10 @@ +e = dependency('enlightenment') +json = dependency('json-c') + +module = shared_module('module', + 'e_mod_main.c', 'e_mod_config.c', + dependencies : [e, json], + install_dir: install_dir, + install: true, + name_prefix: '', + link_args: '-Wl,--unresolved-symbols=ignore-in-object-files')