diff --git a/ChangeLog b/ChangeLog
index 6190b74e..7e9d08dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2009-08-03
+ * Added support for $weather_forecast (experimental)
+
2009-08-01
* Added support for out_to_ncurses
diff --git a/doc/variables.xml b/doc/variables.xml
index b797373d..8b969a76 100644
--- a/doc/variables.xml
+++ b/doc/variables.xml
@@ -540,7 +540,10 @@
- Change drawing color to color
+ Change drawing color to 'color' which is a name of
+ a color or a hexcode preceded with # (for example #0A1B2C ).
+ If you use ncurses only the following colors are supported:
+ red,green,yellow,blue,magenta,cyan,black,white.
@@ -3423,6 +3426,79 @@
and can be subject to many future changes.
+
+
+
+
+
+
+
+
+ Download, parse and display weather forecast data
+ for a given day (daytime only).
+ For the 'URI', for the time being only
+ http://xoap.weather.com/weather/local/ is
+ supported. See 'weather' above for details of usage
+ 'locID', see 'weather' above.
+ 'day' is a number from 0 (today) to 4 (3 days
+ after tomorrow).
+ 'data_type' must be one of the following:
+
+
+ low
+
+
+
+ high
+
+
+
+ icon
+
+
+
+ forecast
+
+
+
+ wind_speed
+
+
+
+ wind_dir
+
+
+
+ wind_dir_DEG
+
+
+
+ humidity
+
+
+
+ precipitation
+
+
+
+ 'delay_in_minutes' (optional, default 150) cannot
+ be lower than 150 min.
+ This object is threaded, and once a thread is
+ created it can't be explicitely destroyed. One thread
+ will run for each URI specified. You can use any
+ protocol that Curl supports.
+ Note that these variables are still EXPERIMENTAL
+ and can be subject to many future changes.
+
+
diff --git a/src/conky.c b/src/conky.c
index da733326..d26cb78f 100644
--- a/src/conky.c
+++ b/src/conky.c
@@ -68,6 +68,9 @@
#ifdef NCURSES
#include
#endif
+#ifdef XOAP
+#include
+#endif /* XOAP */
/* local headers */
#include "algebra.h"
@@ -992,6 +995,12 @@ static void free_text_objects(struct text_object *root, int internal)
free(data.weather.data_type);
break;
#endif
+#ifdef XOAP
+ case OBJ_weather_forecast:
+ free(data.weather_forecast.uri);
+ free(data.weather_forecast.data_type);
+ break;
+#endif
#ifdef HAVE_LUA
case OBJ_lua:
case OBJ_lua_parse:
@@ -1780,6 +1789,30 @@ static struct text_object *construct_text_object(const char *s,
current_text_color = obj->data.l;
}
#endif /* X11 */
+#ifdef NCURSES
+ if (output_methods & TO_NCURSES) {
+ obj->data.l = COLOR_WHITE;
+ if(arg) {
+ if(strcasecmp(arg, "red") == 0) {
+ obj->data.l = COLOR_RED;
+ }else if(strcasecmp(arg, "green") == 0) {
+ obj->data.l = COLOR_GREEN;
+ }else if(strcasecmp(arg, "yellow") == 0) {
+ obj->data.l = COLOR_YELLOW;
+ }else if(strcasecmp(arg, "blue") == 0) {
+ obj->data.l = COLOR_BLUE;
+ }else if(strcasecmp(arg, "magenta") == 0) {
+ obj->data.l = COLOR_MAGENTA;
+ }else if(strcasecmp(arg, "cyan") == 0) {
+ obj->data.l = COLOR_CYAN;
+ }else if(strcasecmp(arg, "black") == 0) {
+ obj->data.l = COLOR_BLACK;
+ }
+ }
+ current_text_color = obj->data.l;
+ init_pair(obj->data.l, obj->data.l, COLOR_BLACK);
+ }
+#endif /* NCURSES */
END OBJ(color0, 0)
obj->data.l = color0;
current_text_color = obj->data.l;
@@ -2985,7 +3018,7 @@ static struct text_object *construct_text_object(const char *s,
argc = sscanf(arg, "%119s %8s %31s %f", uri, locID, data_type, &interval);
if (argc >= 3) {
- if (process_weather_uri(uri, locID)) {
+ if (process_weather_uri(uri, locID, 0)) {
free(data_type);
free(uri);
free(locID);
@@ -3017,6 +3050,57 @@ static struct text_object *construct_text_object(const char *s,
CRIT_ERR(obj, free_at_crash, "weather needs arguments: [interval in minutes]");
}
#endif
+#ifdef XOAP
+ END OBJ(weather_forecast, 0)
+ if (arg) {
+ int argc;
+ unsigned int day;
+ float interval = 0;
+ char *locID = (char *) malloc(9 * sizeof(char));
+ char *uri = (char *) malloc(128 * sizeof(char));
+ char *data_type = (char *) malloc(32 * sizeof(char));
+
+ argc = sscanf(arg, "%119s %8s %1u %31s %f", uri, locID, &day, data_type, &interval);
+
+ if (argc >= 4) {
+ if (process_weather_uri(uri, locID, 1)) {
+ free(data_type);
+ free(uri);
+ free(locID);
+ CRIT_ERR(obj, free_at_crash, \
+ "could not recognize the weather forecast uri");
+ }
+
+ obj->data.weather_forecast.uri = uri;
+ obj->data.weather_forecast.data_type = data_type;
+
+ /* Limit the day between 0 (today) and FORECAST_DAYS */
+ if (day >= FORECAST_DAYS) {
+ day = FORECAST_DAYS-1;
+ }
+ obj->data.weather_forecast.day = day;
+
+ /* Limit the data retrieval interval to 2 hours and an half */
+ if (interval < 150) {
+ interval = 150;
+ }
+
+ /* Convert to seconds */
+ obj->data.weather_forecast.interval = interval * 60;
+ free(locID);
+
+ DBGP("weather_forecast: fetching %s for day %d from %s every %d seconds", \
+ data_type, day, uri, obj->data.weather_forecast.interval);
+ } else {
+ free(data_type);
+ free(uri);
+ free(locID);
+ CRIT_ERR(obj, free_at_crash, "wrong number of arguments for $weather_forecast");
+ }
+ } else {
+ CRIT_ERR(obj, free_at_crash, "weather_forecast needs arguments: [interval in minutes]");
+ }
+#endif
#ifdef HAVE_LUA
END OBJ(lua, 0)
if (arg) {
@@ -4098,9 +4182,11 @@ static void generate_text_internal(char *p, int p_max_size,
new_graph(p, obj->a, obj->b, obj->c, obj->d, cur->loadavg[0],
obj->e, 1, obj->char_a, obj->char_b);
}
+#endif /* X11 */
OBJ(color) {
new_fg(p, obj->data.l);
}
+#ifdef X11
OBJ(color0) {
new_fg(p, color0);
}
@@ -4787,6 +4873,15 @@ static void generate_text_internal(char *p, int p_max_size,
}
}
#endif
+#ifdef XOAP
+ OBJ(weather_forecast) {
+ if (obj->data.weather_forecast.uri != NULL) {
+ weather_forecast_process_info(p, p_max_size, obj->data.weather_forecast.uri, obj->data.weather_forecast.day, obj->data.weather_forecast.data_type, obj->data.weather_forecast.interval);
+ } else {
+ NORM_ERR("error processing weather forecast data, check that you have a valid XOAP key if using XOAP.");
+ }
+ }
+#endif
#ifdef HAVE_LUA
OBJ(lua) {
char *str = llua_getstring(obj->data.s);
@@ -6474,15 +6569,23 @@ static int text_size_updater(char *s, int special_index)
last_font_height = font_height();
return special_index;
}
+#endif /* X11 */
static inline void set_foreground_color(long c)
{
- if ((output_methods & TO_X) == 0)
- return;
- current_color = c;
- XSetForeground(display, window.gc, c);
-}
+#ifdef X11
+ if (output_methods & TO_X) {
+ current_color = c;
+ XSetForeground(display, window.gc, c);
+ }
#endif /* X11 */
+#ifdef NCURSES
+ if (output_methods & TO_NCURSES) {
+ attron(COLOR_PAIR(c));
+ }
+#endif /* NCURSES */
+ return;
+}
static void draw_string(const char *s)
{
@@ -6519,7 +6622,7 @@ static void draw_string(const char *s)
}
#ifdef NCURSES
if ((output_methods & TO_NCURSES) && draw_mode == FG) {
- printw("%s\n", s_with_newlines);
+ printw("%s", s_with_newlines);
}
#endif
free(s_with_newlines);
@@ -6599,18 +6702,21 @@ static void draw_string(const char *s)
memcpy(tmpstring1, s, text_buffer_size);
}
-#ifdef X11
int draw_each_line_inner(char *s, int special_index, int last_special_applied)
{
+#ifdef X11
int font_h = font_height();
int cur_y_add = 0;
+#endif /* X11 */
char *recurse = 0;
char *p = s;
int last_special_needed = -1;
int orig_special_index = special_index;
+#ifdef X11
cur_x = text_start_x;
cur_y += font_ascent();
+#endif /* X11 */
while (*p) {
if (*p == SECRIT_MULTILINE_CHAR) {
@@ -6620,7 +6726,9 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
break;
}
if (*p == SPECIAL_CHAR || last_special_applied > -1) {
+#ifdef X11
int w = 0;
+#endif /* X11 */
/* draw string before special, unless we're dealing multiline
* specials */
@@ -6634,6 +6742,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
}
/* draw special */
switch (specials[special_index].type) {
+#ifdef X11
case HORIZONTAL_LINE:
{
int h = specials[special_index].height;
@@ -6928,12 +7037,14 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
font_h = font_height();
break;
}
+#endif /* X11 */
case FG:
if (draw_mode == FG) {
set_foreground_color(specials[special_index].arg);
}
break;
+#ifdef X11
case BG:
if (draw_mode == BG) {
set_foreground_color(specials[special_index].arg);
@@ -7015,9 +7126,12 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
last_special_needed = special_index;
break;
}
+#endif /* X11 */
}
+#ifdef X11
cur_x += w;
+#endif /* X11 */
if (special_index != last_special_applied) {
special_index++;
@@ -7029,31 +7143,40 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
p++;
}
+#ifdef X11
cur_y += cur_y_add;
+#endif /* X11 */
draw_string(s);
+#ifdef NCURSES
+ if (output_methods & TO_NCURSES) {
+ printw("\n");
+ }
+#endif /* NCURSES */
+#ifdef X11
cur_y += font_descent();
+#endif /* X11 */
if (recurse && *recurse) {
special_index = draw_each_line_inner(recurse, special_index, last_special_needed);
*(recurse - 1) = SECRIT_MULTILINE_CHAR;
}
return special_index;
}
-#endif /* X11 */
static int draw_line(char *s, int special_index)
{
#ifdef X11
- if ((output_methods & TO_X) == 0) {
-#endif /* X11 */
- draw_string(s);
- //'special_index - special_index' instead of 0 otherwise gcc complains about not using special_index when build without X11
- return special_index - special_index;
-#ifdef X11
+ if (output_methods & TO_X) {
+ return draw_each_line_inner(s, special_index, -1);
}
-
- /* find specials and draw stuff */
- return draw_each_line_inner(s, special_index, -1);
#endif /* X11 */
+#ifdef NCURSES
+ if (output_methods & TO_NCURSES) {
+ return draw_each_line_inner(s, special_index, -1);
+ }
+#endif /* NCURSES */
+ draw_string(s);
+ //'special_index - special_index' instead of 0 otherwise gcc complains about not using special_index when build without X11
+ return special_index - special_index;
}
static void draw_text(void)
@@ -7088,6 +7211,10 @@ static void draw_text(void)
}
setup_fonts();
#endif /* X11 */
+#ifdef NCURSES
+ init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
+ attron(COLOR_PAIR(COLOR_WHITE));
+#endif /* NCURSES */
for_each_line(text_buffer, draw_line);
#if defined(HAVE_LUA) && defined(X11)
llua_draw_post_hook();
@@ -7790,6 +7917,9 @@ void clean_up(void *memtofree1, void* memtofree2)
#ifdef IMLIB2
cimlib_deinit();
#endif /* IMLIB2 */
+#ifdef XOAP
+ xmlCleanupParser();
+#endif /* XOAP */
if (specials) {
for (i = 0; i < special_count; i++) {
@@ -8499,6 +8629,7 @@ char load_config_file(const char *f)
CONF("out_to_ncurses") {
if(string_to_bool(value)) {
initscr();
+ start_color();
output_methods |= TO_NCURSES;
}
}
@@ -9415,6 +9546,9 @@ void initialisation(int argc, char **argv) {
#ifdef HAVE_LUA
llua_setup_info(&info, update_interval);
#endif /* HAVE_LUA */
+#ifdef XOAP
+ xmlInitParser();
+#endif /* XOAP */
/* Set signal handlers */
act.sa_handler = signal_handler;
diff --git a/src/specials.c b/src/specials.c
index a76cd417..71df3de0 100644
--- a/src/specials.c
+++ b/src/specials.c
@@ -351,15 +351,21 @@ void new_stippled_hr(char *buf, int a, int b)
s->height = b;
s->arg = a;
}
+#endif /* X11 */
void new_fg(char *buf, long c)
{
- if ((output_methods & TO_X) == 0)
- return;
-
- new_special(buf, FG)->arg = c;
+#ifdef X11
+ if (output_methods & TO_X)
+ new_special(buf, FG)->arg = c;
+#endif /* X11 */
+#ifdef NCURSES
+ if (output_methods & TO_NCURSES)
+ new_special(buf, FG)->arg = c;
+#endif /* NCURSES */
}
+#ifdef X11
void new_bg(char *buf, long c)
{
if ((output_methods & TO_X) == 0)
diff --git a/src/text_object.h b/src/text_object.h
index 46d62ff0..519c3184 100644
--- a/src/text_object.h
+++ b/src/text_object.h
@@ -386,6 +386,9 @@ enum text_object_type {
#ifdef WEATHER
OBJ_weather,
#endif /* WEATHER */
+#ifdef XOAP
+ OBJ_weather_forecast,
+#endif /* XOAP */
#ifdef HAVE_LUA
OBJ_lua,
OBJ_lua_parse,
@@ -561,6 +564,14 @@ struct text_object {
char *data_type;
int interval;
} weather;
+#endif
+#ifdef XOAP
+ struct {
+ char *uri;
+ unsigned int day;
+ char *data_type;
+ int interval;
+ } weather_forecast;
#endif
struct {
char *text;
diff --git a/src/weather.c b/src/weather.c
index a2141d8e..671d5265 100644
--- a/src/weather.c
+++ b/src/weather.c
@@ -24,11 +24,6 @@
*
*/
-/*
- * TODO: Add weather forecast info from weather.com
- *
- */
-
#include "conky.h"
#include "logging.h"
#include "weather.h"
@@ -44,12 +39,20 @@
#include
/* Xpath expressions for XOAP xml parsing */
-#define NUM_XPATH_EXPRESSIONS 8
-const char *xpath_expression[NUM_XPATH_EXPRESSIONS] = {
+#define NUM_XPATH_EXPRESSIONS_CC 8
+const char *xpath_expression_cc[NUM_XPATH_EXPRESSIONS_CC] = {
"/weather/cc/lsup", "/weather/cc/tmp", "/weather/cc/t",
"/weather/cc/bar/r", "/weather/cc/wind/s", "/weather/cc/wind/d",
"/weather/cc/hmid", "/weather/cc/icon"
};
+
+#define NUM_XPATH_EXPRESSIONS_DF 8
+const char *xpath_expression_df[NUM_XPATH_EXPRESSIONS_DF] = {
+ "/weather/dayf/day[*]/hi", "/weather/dayf/day[*]/low",
+ "/weather/dayf/day[*]/part[1]/icon", "/weather/dayf/day[*]/part[1]/t",
+ "/weather/dayf/day[*]/part[1]/wind/s","/weather/dayf/day[*]/part[1]/wind/d",
+ "/weather/dayf/day[*]/part[1]/ppcp", "/weather/dayf/day[*]/part[1]/hmid"
+};
#endif /* XOAP */
/* Possible sky conditions */
@@ -73,11 +76,17 @@ const char *WC_CODES[NUM_WC_CODES] = {
"FC", "PO", "SQ", "SS", "DS"
};
-static ccurl_location_t *locations_head = 0;
+static ccurl_location_t *locations_head_cc = 0;
+#ifdef XOAP
+static ccurl_location_t *locations_head_df = 0;
+#endif
void weather_free_info(void)
{
- ccurl_free_locations(&locations_head);
+ ccurl_free_locations(&locations_head_cc);
+#ifdef XOAP
+ ccurl_free_locations(&locations_head_df);
+#endif
}
int rel_humidity(int dew_point, int air) {
@@ -93,46 +102,113 @@ int rel_humidity(int dew_point, int air) {
}
#ifdef XOAP
+static void parse_df(PWEATHER_FORECAST *res, xmlXPathContextPtr xpathCtx)
+{
+ int i, j, k;
+ char *content;
+ xmlXPathObjectPtr xpathObj;
+
+ for (i = 0; i < NUM_XPATH_EXPRESSIONS_DF; i++) {
+ xpathObj = xmlXPathEvalExpression((xmlChar *)xpath_expression_df[i], xpathCtx);
+ if (xpathObj != NULL) {
+ xmlNodeSetPtr nodes = xpathObj->nodesetval;
+ k = 0;
+ for (j = 0; j < nodes->nodeNr; ++j) {
+ if (nodes->nodeTab[j]->type == XML_ELEMENT_NODE) {
+ content = (char *)xmlNodeGetContent(nodes->nodeTab[k]);
+ switch(i) {
+ case 0:
+ res->hi[k] = atoi(content);
+ break;
+ case 1:
+ res->low[k] = atoi(content);
+ break;
+ case 2:
+ strncpy(res->icon[k], content, 2);
+ case 3:
+ strncpy(res->xoap_t[k], content, 31);
+ break;
+ case 4:
+ res->wind_s[k] = atoi(content);
+ break;
+ case 5:
+ res->wind_d[k] = atoi(content);
+ break;
+ case 6:
+ res->ppcp[k] = atoi(content);
+ break;
+ case 7:
+ res->hmid[k] = atoi(content);
+ }
+ xmlFree(content);
+ if (++k == FORECAST_DAYS) break;
+ }
+ }
+ xmlXPathFreeObject(xpathObj);
+ }
+ }
+ return;
+}
+
+static void parse_weather_forecast_xml(PWEATHER_FORECAST *res, const char *data)
+{
+ xmlDocPtr doc;
+ xmlXPathContextPtr xpathCtx;
+
+ if (!(doc = xmlReadMemory(data, strlen(data), "", NULL, 0))) {
+ NORM_ERR("weather_forecast: can't read xml data");
+ return;
+ }
+
+ xpathCtx = xmlXPathNewContext(doc);
+ if(xpathCtx == NULL) {
+ NORM_ERR("weather_forecast: unable to create new XPath context");
+ xmlFreeDoc(doc);
+ return;
+ }
+
+ parse_df(res, xpathCtx);
+ xmlXPathFreeContext(xpathCtx);
+ xmlFreeDoc(doc);
+ return;
+}
+
static void parse_cc(PWEATHER *res, xmlXPathContextPtr xpathCtx)
{
int i;
char *content;
xmlXPathObjectPtr xpathObj;
- for (i = 0; i < NUM_XPATH_EXPRESSIONS; i++) {
- xpathObj = xmlXPathEvalExpression((xmlChar *)xpath_expression[i], xpathCtx);
+ for (i = 0; i < NUM_XPATH_EXPRESSIONS_CC; i++) {
+ xpathObj = xmlXPathEvalExpression((xmlChar *)xpath_expression_cc[i], xpathCtx);
if ((xpathObj != NULL) && (xpathObj->nodesetval->nodeTab[0]->type == XML_ELEMENT_NODE)) {
- content = (char *)xmlNodeGetContent(xpathObj->nodesetval->nodeTab[0]);
- switch(i) {
- case 0:
- strncpy(res->lastupd, content, 31);
- break;
- case 1:
- res->temp = atoi(content);
- break;
- case 2:
- if(res->xoap_t[0] == '\0') {
- strncpy(res->xoap_t, content, 31);
- }
- break;
- case 3:
- res->bar = atoi(content);
- break;
- case 4:
- res->wind_s = atoi(content);
- break;
- case 5:
- if (isdigit((char)content[0])) {
- res->wind_d = atoi(content);
- }
- break;
- case 6:
- res->hmid = atoi(content);
+ content = (char *)xmlNodeGetContent(xpathObj->nodesetval->nodeTab[0]);
+ switch(i) {
+ case 0:
+ strncpy(res->lastupd, content, 31);
break;
- case 7:
- strncpy(res->icon, content, 2);
- }
- xmlFree(content);
+ case 1:
+ res->temp = atoi(content);
+ break;
+ case 2:
+ strncpy(res->xoap_t, content, 31);
+ break;
+ case 3:
+ res->bar = atoi(content);
+ break;
+ case 4:
+ res->wind_s = atoi(content);
+ break;
+ case 5:
+ res->wind_d = atoi(content);
+ break;
+ case 6:
+ res->hmid = atoi(content);
+ break;
+ case 7:
+ strncpy(res->icon, content, 2);
+ }
+ xmlFree(content);
}
xmlXPathFreeObject(xpathObj);
}
@@ -453,6 +529,20 @@ static inline void parse_token(PWEATHER *res, char *token) {
}
}
+#ifdef XOAP
+void parse_weather_forecast(void *result, const char *data)
+{
+ PWEATHER_FORECAST *res = (PWEATHER_FORECAST*)result;
+ /* Reset results */
+ memset(res, 0, sizeof(PWEATHER_FORECAST));
+
+ //Check if it is an xml file
+ if ( strncmp(data, "= 349) || (wind_deg < 12)) {
+ strncpy(p, "N", p_max_size);
+ } else if (wind_deg < 33) {
+ strncpy(p, "NNE", p_max_size);
+ } else if (wind_deg < 57) {
+ strncpy(p, "NE", p_max_size);
+ } else if (wind_deg < 79) {
+ strncpy(p, "ENE", p_max_size);
+ } else if (wind_deg < 102) {
+ strncpy(p, "E", p_max_size);
+ } else if (wind_deg < 124) {
+ strncpy(p, "ESE", p_max_size);
+ } else if (wind_deg < 147) {
+ strncpy(p, "SE", p_max_size);
+ } else if (wind_deg < 169) {
+ strncpy(p, "SSE", p_max_size);
+ } else if (wind_deg < 192) {
+ strncpy(p, "S", p_max_size);
+ } else if (wind_deg < 214) {
+ strncpy(p, "SSW", p_max_size);
+ } else if (wind_deg < 237) {
+ strncpy(p, "SW", p_max_size);
+ } else if (wind_deg < 259) {
+ strncpy(p, "WSW", p_max_size);
+ } else if (wind_deg < 282) {
+ strncpy(p, "W", p_max_size);
+ } else if (wind_deg < 304) {
+ strncpy(p, "WNW", p_max_size);
+ } else if (wind_deg < 327) {
+ strncpy(p, "NW", p_max_size);
+ } else if (wind_deg < 349) {
+ strncpy(p, "NNW", p_max_size);
+ };
+}
+
+#ifdef XOAP
+void weather_forecast_process_info(char *p, int p_max_size, char *uri, unsigned int day, char *data_type, int interval)
+{
+ PWEATHER_FORECAST *data;
+
+ ccurl_location_t *curloc = ccurl_find_location(&locations_head_df, uri);
+ if (!curloc->p_timed_thread) {
+ curloc->result = malloc(sizeof(PWEATHER_FORECAST));
+ memset(curloc->result, 0, sizeof(PWEATHER_FORECAST));
+ curloc->process_function = &parse_weather_forecast;
+ ccurl_init_thread(curloc, interval);
+ if (!curloc->p_timed_thread) {
+ NORM_ERR("error setting up weather_forecast thread");
+ }
+ }
+
+ timed_thread_lock(curloc->p_timed_thread);
+ data = (PWEATHER_FORECAST*)curloc->result;
+ if (strcmp(data_type, "hi") == EQUAL) {
+ temp_print(p, p_max_size, data->hi[day], TEMP_CELSIUS);
+ } else if (strcmp(data_type, "low") == EQUAL) {
+ temp_print(p, p_max_size, data->low[day], TEMP_CELSIUS);
+ } else if (strcmp(data_type, "icon") == EQUAL) {
+ strncpy(p, data->icon[day], p_max_size);
+ } else if (strcmp(data_type, "forecast") == EQUAL) {
+ strncpy(p, data->xoap_t[day], p_max_size);
+ } else if (strcmp(data_type, "wind_speed") == EQUAL) {
+ snprintf(p, p_max_size, "%d", data->wind_s[day]);
+ } else if (strcmp(data_type, "wind_dir") == EQUAL) {
+ wind_deg_to_dir(p, p_max_size, data->wind_d[day]);
+ } else if (strcmp(data_type, "wind_dir_DEG") == EQUAL) {
+ snprintf(p, p_max_size, "%d", data->wind_d[day]);
+ } else if (strcmp(data_type, "humidity") == EQUAL) {
+ snprintf(p, p_max_size, "%d", data->hmid[day]);
+ } else if (strcmp(data_type, "precipitation") == EQUAL) {
+ snprintf(p, p_max_size, "%d", data->ppcp[day]);
+ }
+
+ timed_thread_unlock(curloc->p_timed_thread);
+}
+#endif /* XOAP */
+
void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, int interval)
{
static const char *wc[] = {
@@ -507,7 +675,7 @@ void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, i
};
PWEATHER *data;
- ccurl_location_t *curloc = ccurl_find_location(&locations_head, uri);
+ ccurl_location_t *curloc = ccurl_find_location(&locations_head_cc, uri);
if (!curloc->p_timed_thread) {
curloc->result = malloc(sizeof(PWEATHER));
memset(curloc->result, 0, sizeof(PWEATHER));
@@ -554,39 +722,7 @@ void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, i
} else if (strcmp(data_type, "wind_speed") == EQUAL) {
snprintf(p, p_max_size, "%d", data->wind_s);
} else if (strcmp(data_type, "wind_dir") == EQUAL) {
- if ((data->wind_d >= 349) || (data->wind_d < 12)) {
- strncpy(p, "N", p_max_size);
- } else if (data->wind_d < 33) {
- strncpy(p, "NNE", p_max_size);
- } else if (data->wind_d < 57) {
- strncpy(p, "NE", p_max_size);
- } else if (data->wind_d < 79) {
- strncpy(p, "ENE", p_max_size);
- } else if (data->wind_d < 102) {
- strncpy(p, "E", p_max_size);
- } else if (data->wind_d < 124) {
- strncpy(p, "ESE", p_max_size);
- } else if (data->wind_d < 147) {
- strncpy(p, "SE", p_max_size);
- } else if (data->wind_d < 169) {
- strncpy(p, "SSE", p_max_size);
- } else if (data->wind_d < 192) {
- strncpy(p, "S", p_max_size);
- } else if (data->wind_d < 214) {
- strncpy(p, "SSW", p_max_size);
- } else if (data->wind_d < 237) {
- strncpy(p, "SW", p_max_size);
- } else if (data->wind_d < 259) {
- strncpy(p, "WSW", p_max_size);
- } else if (data->wind_d < 282) {
- strncpy(p, "W", p_max_size);
- } else if (data->wind_d < 304) {
- strncpy(p, "WNW", p_max_size);
- } else if (data->wind_d < 327) {
- strncpy(p, "NW", p_max_size);
- } else if (data->wind_d < 349) {
- strncpy(p, "NNW", p_max_size);
- };
+ wind_deg_to_dir(p, p_max_size, data->wind_d);
} else if (strcmp(data_type, "wind_dir_DEG") == EQUAL) {
snprintf(p, p_max_size, "%d", data->wind_d);
@@ -602,7 +738,8 @@ void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, i
#ifdef XOAP
/* xoap suffix for weather from weather.com */
-static char *xoap = NULL;
+static char *xoap_cc = NULL;
+static char *xoap_df = NULL;
/*
* TODO: make the xoap keys file readable from the config file
@@ -612,34 +749,39 @@ static char *xoap = NULL;
void load_xoap_keys(void)
{
FILE *fp;
- char *par = (char *) malloc(11 * sizeof(char));
- char *key = (char *) malloc(17 * sizeof(char));
+ char *par = (char *) malloc(11 * sizeof(char));
+ char *key = (char *) malloc(17 * sizeof(char));
+ char *xoap = (char *) malloc(64 * sizeof(char));
- xoap = (char *) malloc(64 * sizeof(char));
to_real_path(xoap, XOAP_FILE);
fp = fopen(xoap, "r");
if (fp != NULL) {
if (fscanf(fp, "%10s %16s", par, key) == 2) {
- strcpy(xoap, "?cc=*&link=xoap&prod=xoap&par=");
- strcat(xoap, par);
- strcat(xoap, "&key=");
- strcat(xoap, key);
- strcat(xoap, "&unit=m");
- } else {
- free(xoap);
- xoap = NULL;
+ xoap_cc = (char *) malloc(128 * sizeof(char));
+ xoap_df = (char *) malloc(128 * sizeof(char));
+
+ strcpy(xoap_cc, "?cc=*&link=xoap&prod=xoap&par=");
+ strcat(xoap_cc, par);
+ strcat(xoap_cc, "&key=");
+ strcat(xoap_cc, key);
+ strcat(xoap_cc, "&unit=m");
+
+ /* TODO: Use FORECAST_DAYS instead of 5 */
+ strcpy(xoap_df, "?dayf=5&link=xoap&prod=xoap&par=");
+ strcat(xoap_df, par);
+ strcat(xoap_df, "&key=");
+ strcat(xoap_df, key);
+ strcat(xoap_df, "&unit=m");
}
fclose(fp);
- } else {
- free(xoap);
- xoap = NULL;
}
free(par);
free(key);
+ free(xoap);
}
#endif /* XOAP */
-int process_weather_uri(char *uri, char *locID)
+int process_weather_uri(char *uri, char *locID, int dayf)
{
/* locID MUST BE upper-case */
char *tmp_p = locID;
@@ -651,9 +793,12 @@ int process_weather_uri(char *uri, char *locID)
/* Construct complete uri */
#ifdef XOAP
if (strstr(uri, "xoap.weather.com")) {
- if (xoap != NULL) {
+ if ((dayf == 0) && (xoap_cc != NULL)) {
strcat(uri, locID);
- strcat(uri, xoap);
+ strcat(uri, xoap_cc);
+ } else if ((dayf == 1) && (xoap_df != NULL)) {
+ strcat(uri, locID);
+ strcat(uri, xoap_df);
} else {
free(uri);
uri = NULL;
@@ -668,4 +813,3 @@ int process_weather_uri(char *uri, char *locID)
}
return 0;
}
-
diff --git a/src/weather.h b/src/weather.h
index fa418d0e..d70ec196 100644
--- a/src/weather.h
+++ b/src/weather.h
@@ -49,10 +49,27 @@ typedef struct PWEATHER_ {
int wc;
} PWEATHER;
+#ifdef XOAP
+#define FORECAST_DAYS 5
+typedef struct PWEATHER_FORECAST_ {
+ int hi[FORECAST_DAYS];
+ int low[FORECAST_DAYS];
+ char icon[FORECAST_DAYS][3];
+ char xoap_t[FORECAST_DAYS][32];
+ int wind_s[FORECAST_DAYS];
+ int wind_d[FORECAST_DAYS];
+ int hmid[FORECAST_DAYS];
+ int ppcp[FORECAST_DAYS];
+} PWEATHER_FORECAST;
+#endif /* XOAP */
+
/* Prototypes */
void weather_free_info(void);
void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, int interval);
-int process_weather_uri(char *uri, char *locID);
+#ifdef XOAP
+void weather_forecast_process_info(char *p, int p_max_size, char *uri, unsigned int day, char *data_type, int interval);
+#endif /* XOAP */
+int process_weather_uri(char *uri, char *locID, int dayf);
#ifdef XOAP
void load_xoap_keys(void);