diff options
Diffstat (limited to 'src/modules/weather/plugin.c')
-rw-r--r-- | src/modules/weather/plugin.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/src/modules/weather/plugin.c b/src/modules/weather/plugin.c new file mode 100644 index 0000000000..abe6dd8818 --- /dev/null +++ b/src/modules/weather/plugin.c @@ -0,0 +1,234 @@ +#include <e.h> +#include "weather.h" +#include "plugin.h" +#include "plugin_openweathermap.h" + +static Eina_Bool _gather_weather_all(void *data); + +static Eina_List *plugins = NULL; +static Eina_List *weathers = NULL; +static Ecore_Timer *timer = NULL; +static Eina_Binbuf *buffer = NULL; +static Eina_List *handlers = NULL; +static Eina_List *_cur_weather = NULL; +static Eina_List *_cur_plugin = NULL; +static Weather *_cur_request = NULL; + +static void +_gather_current_plugin(void) +{ + Weather_Plugin *wp; + const char *uri; + Ecore_Con_Url *url_con; + Weather *w; + + wp = eina_list_data_get(_cur_plugin); + w = (_cur_request ? _cur_request : eina_list_data_get(_cur_weather)); + fprintf(stderr, "gather info for %s\n", w->city); + if (!w || !wp) return; + uri = wp->func.uri_get(w); + fprintf(stderr, "gather info from %s\n", uri); + url_con = ecore_con_url_new(uri); + ecore_con_url_get(url_con); + eina_stringshare_del(uri); +} + +static Eina_Bool +_gather_weather(void *data EINA_UNUSED) +{ + Weather *w; + timer = NULL; + _cur_plugin = plugins; + w = (_cur_request ? _cur_request : eina_list_data_get(_cur_weather)); + fprintf(stderr, "gather %x data %s %d\n", _cur_weather, w->city, w->translated); + _gather_current_plugin(); + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_gather_weather_all(void *data EINA_UNUSED) +{ + timer = NULL; + fprintf(stderr, "Gather weather data %d %d\n", + eina_list_count(weathers), eina_list_count(plugins)); + _cur_weather = weathers; + _gather_weather(NULL); + + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_url_complete(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + const unsigned char *buf; + size_t size; + Eina_List *l; + Instance *inst; + Weather_Plugin *wp; + Weather *w; + + if (data != buffer) return ECORE_CALLBACK_PASS_ON; + + buf = eina_binbuf_string_get(buffer); + size = eina_binbuf_length_get(buffer); + + wp = eina_list_data_get(_cur_plugin); + w = (_cur_request ? _cur_request : eina_list_data_get(_cur_weather)); + if (!wp || !w) return ECORE_CALLBACK_DONE; + fprintf(stderr, "gather complete %s %d\n", w->city, w->translated); + wp->func.parse(w, buf, size); + eina_binbuf_reset(buffer); + + EINA_LIST_FOREACH(weather_instances, l, inst) + { + if (inst->weather == w) + weather_gadget_update(inst); + } + _cur_plugin = eina_list_next(_cur_plugin); + if (!_cur_plugin) + { + if (_cur_request) + _cur_request = NULL; + _cur_weather = eina_list_next(_cur_weather); + if (!_cur_weather) + { + if (timer) + ecore_timer_del(timer); + timer = ecore_timer_add(36.0, _gather_weather_all, NULL); + } + else + { + if (timer) + ecore_timer_del(timer); + timer = ecore_timer_add(5.0, _gather_weather, NULL); + } + } + else + { + _gather_current_plugin(); + } + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_url_data(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Con_Event_Url_Data *ev; + + if (data != buffer) return ECORE_CALLBACK_PASS_ON; + ev = event; + + if (ev->size > 0) + { + eina_binbuf_append_length(buffer, ev->data, ev->size); + } + + return ECORE_CALLBACK_DONE; +} + +EINTERN void +weather_plugin_request(Weather *w) +{ + _cur_plugin = plugins; + _cur_request = w; + _gather_weather(NULL); +} + + +EINTERN void +weather_plugin_init(void) +{ + Weather_Plugin *wp; + + buffer = eina_binbuf_new(); + E_LIST_HANDLER_APPEND(handlers, ECORE_CON_EVENT_URL_COMPLETE, + _url_complete, buffer); + E_LIST_HANDLER_APPEND(handlers, ECORE_CON_EVENT_URL_DATA, + _url_data, buffer); + + wp = plugin_openweathermap_create(); + plugins = eina_list_append(plugins, wp); +} + +EINTERN void +weather_plugin_shutdown(void) +{ + Weather_Plugin *wp; + + EINA_LIST_FREE(plugins, wp) + { + eina_stringshare_del(wp->name); + free(wp); + } + + E_FREE_LIST(handlers, ecore_event_handler_del); + eina_binbuf_free(buffer); +} + +EINTERN void +weather_plugin_weather_add(Instance *inst) +{ + Weather *wl; + Eina_List *l; + + if ((!inst->cfg->city) && (!inst->cfg->country) && (!inst->cfg->geo_id)) + return; + EINA_LIST_FOREACH(weathers, l, wl) + { + if ((inst->cfg->geo_id) && (inst->cfg->geo_id == wl->geo_id)) + break; + if ((inst->cfg->city && inst->cfg->country) + && ((inst->cfg->city == wl->city) + && (inst->cfg->country == wl->country))) + break; + if ((inst->cfg->city) && (inst->cfg->city == wl->city)) + break; + } + if (l) + { + fprintf(stderr, "found weather %s %s %s\n", + inst->weather->geo_id, inst->weather->city, inst->weather->country); + inst->weather = wl; + if (timer) + { + ecore_timer_del(timer); + timer = NULL; + } + timer = ecore_timer_add(1.0, _gather_weather_all, NULL); + + return; + } + fprintf(stderr, "create a new weather %s %s %s\n", + inst->cfg->geo_id, inst->cfg->city, inst->cfg->country); + inst->weather = E_NEW(Weather, 1); + inst->weather->geo_id = eina_stringshare_add(inst->cfg->geo_id); + inst->weather->city = eina_stringshare_add(inst->cfg->city); + inst->weather->country = eina_stringshare_add(inst->cfg->country); + weathers = eina_list_append(weathers, inst->weather); + if (timer) + { + ecore_timer_del(timer); + } + timer = ecore_timer_add(1.0, _gather_weather_all, NULL); +} + +EINTERN void +weather_plugin_weather_remove(Instance *inst) +{ + Instance *inst_search; + Eina_List *l; + + if (!inst->weather) return; + EINA_LIST_FOREACH(weather_instances, l, inst_search) + { + if (inst_search->weather == inst->weather) + break; + } + if (!l) + { + weather_free(inst->weather); + weathers = eina_list_remove(weathers, inst->weather); + } +} + |