[Xfce4-commits] <xfce4-weather-plugin:master> * Start parsing yr.no xml

Colin Leroy noreply at xfce.org
Wed Nov 16 22:34:03 CET 2011


Updating branch refs/heads/master
         to ed6d594891ab2d3b3cd0267d99f5f564fc1d5450 (commit)
       from 74d870f5e7445622acdc3eafae39fa7f12acf123 (commit)

commit ed6d594891ab2d3b3cd0267d99f5f564fc1d5450
Author: Colin Leroy <colin at colino.net>
Date:   Tue Nov 15 21:39:38 2011 +0100

    * Start parsing yr.no xml

 panel-plugin/weather-parsers.c |  557 +++++++++++-----------------------------
 panel-plugin/weather-parsers.h |  120 +++------
 2 files changed, 193 insertions(+), 484 deletions(-)

diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c
index 1493153..eabd255 100644
--- a/panel-plugin/weather-parsers.c
+++ b/panel-plugin/weather-parsers.c
@@ -21,8 +21,26 @@
 
 #include "weather-parsers.h"
 #include <libxfce4panel/libxfce4panel.h>
+#define _XOPEN_SOURCE
+#include <time.h>
+#include <stdlib.h>
 
+static time_t my_timegm(struct tm *tm)
+{
+	time_t ret;
+	char *tz;
 
+	tz = getenv("TZ");
+	setenv("TZ", "", 1);
+	tzset();
+	ret = mktime(tm);
+	if (tz)
+		setenv("TZ", tz, 1);
+	else
+		unsetenv("TZ");
+	tzset();
+	return ret;
+}
 
 xml_weather *
 parse_weather (xmlNode *cur_node)
@@ -31,7 +49,7 @@ parse_weather (xmlNode *cur_node)
   xmlNode     *child_node;
   guint        i = 0;
 
-  if (!NODE_IS_TYPE (cur_node, "weather"))
+  if (!NODE_IS_TYPE (cur_node, "weatherdata"))
     {
       return NULL;
     }
@@ -39,30 +57,26 @@ parse_weather (xmlNode *cur_node)
   if ((ret = g_slice_new0 (xml_weather)) == NULL)
     return NULL;
 
+  ret->num_timeslices = 0;
   for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
     {
       if (cur_node->type != XML_ELEMENT_NODE)
         continue;
 
-      if (NODE_IS_TYPE (cur_node, "cc"))
-        ret->cc = parse_cc (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "loc"))
-        ret->loc = parse_loc (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "lnks"))
-        ret->lnk = parse_lnk (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "dayf"))
+      if (NODE_IS_TYPE (cur_node, "product"))
         {
+	  gchar *class = xmlGetProp (cur_node, (const xmlChar *) "class");
+	  if (xmlStrcasecmp(class, "pointData")) {
+		xmlFree(class);
+		continue;
+	  }
+	  g_free(class);
           for (child_node = cur_node->children; child_node;
                child_node = child_node->next)
             {
-              if (NODE_IS_TYPE (child_node, "day"))
+              if (NODE_IS_TYPE (child_node, "time"))
                 {
-                  if (i >= XML_WEATHER_DAYF_N)
-                    break;
-
-                  ret->dayf[i] = parse_dayf (child_node);
-
-                  i++;
+                  parse_time(child_node, ret);
                 }
             }
         }
@@ -71,409 +85,146 @@ parse_weather (xmlNode *cur_node)
   return ret;
 }
 
+void parse_time (xmlNode * cur_node, xml_weather * data) {
+	gchar *datatype = xmlGetProp (cur_node, (const xmlChar *) "datatype");
+	gchar *start = xmlGetProp (cur_node, (const xmlChar *) "from");
+	gchar *end = xmlGetProp (cur_node, (const xmlChar *) "to");
+	struct tm start_t, end_t;
+	time_t start_ts, end_ts;
+	time_t cur_ts;
 
-
-xml_loc *
-parse_loc (xmlNode *cur_node)
-{
-  xml_loc *ret;
-
-  if ((ret = g_slice_new0 (xml_loc)) == NULL)
-    return NULL;
-
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "dnam"))
-        ret->dnam = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "sunr"))
-        ret->sunr = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "suns"))
-        ret->suns = DATA (cur_node);
-    }
-
-  return ret;
-}
-
-xml_lnk *
-parse_lnk (xmlNode *cur_node)
-{
-  xml_lnk *ret;
-  int i = 0;
-  if ((ret = g_slice_new0 (xml_lnk)) == NULL)
-    return NULL;
-
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "link")) {
-        xmlNode *l_node;
-        if (i < 4) {
-	  for (l_node = cur_node->children; l_node; l_node = l_node->next) {
-              if (NODE_IS_TYPE (l_node, "l"))
-		ret->lnk[i] = DATA(l_node);
-	      else if (NODE_IS_TYPE (l_node, "t"))
-		ret->lnk_txt[i] = DATA(l_node);
-	  }
+	if (xmlStrcasecmp(datatype, "forecast")) {
+		xmlFree(datatype);
+		xmlFree(start);
+		xmlFree(end);
+		return;
 	}
-	i++;
-      }
-    }
-
-  return ret;
-}
-
-
-
-static xml_uv *
-parse_uv (xmlNode *cur_node)
-{
-  xml_uv *ret;
-
-  if ((ret = g_slice_new0 (xml_uv)) == NULL)
-    return NULL;
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "i"))
-        ret->i = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "t"))
-        ret->t = DATA (cur_node);
-    }
-
-  return ret;
-}
-
-
-
-static xml_bar *
-parse_bar (xmlNode *cur_node)
-{
-  xml_bar *ret;
-
-  if ((ret = g_slice_new0 (xml_bar)) == NULL)
-    return NULL;
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "r"))
-        ret->r = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "d"))
-        ret->d = DATA (cur_node);
-    }
-
-  return ret;
-}
-
-
-
-static xml_wind *
-parse_wind (xmlNode *cur_node)
-{
-  xml_wind *ret;
-
-  if ((ret = g_slice_new0 (xml_wind)) == NULL)
-    return NULL;
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "s"))
-        ret->s = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "gust"))
-        ret->gust = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "d"))
-        ret->d = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "t"))
-        ret->t = DATA (cur_node);
-    }
-
-  return ret;
-}
-
-
-
-xml_cc *
-parse_cc (xmlNode *cur_node)
-{
-  xml_cc *ret;
-
-  if ((ret = g_slice_new0 (xml_cc)) == NULL)
-    return NULL;
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "tmp"))
-        ret->tmp = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "icon"))
-        ret->icon = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "t"))
-        ret->t = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "flik"))
-        ret->flik = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "bar"))
-        ret->bar = parse_bar (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "wind"))
-        ret->wind = parse_wind (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "hmid"))
-        ret->hmid = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "vis"))
-        ret->vis = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "uv"))
-        ret->uv = parse_uv (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "dewp"))
-        ret->dewp = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "lsup"))
-        ret->lsup = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "obst"))
-        ret->obst = DATA (cur_node);
-    }
-
-  return ret;
-}
-
 
+	xmlFree(datatype);
 
-static xml_part *
-parse_part (xmlNode *cur_node)
-{
-  xml_part *ret;
-
-  if ((ret = g_slice_new0 (xml_part)) == NULL)
-    return NULL;
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "icon"))
-        ret->icon = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "t"))
-        ret->t = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "wind"))
-        ret->wind = parse_wind (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "ppcp"))
-        ret->ppcp = DATA (cur_node);
-      else if (NODE_IS_TYPE (cur_node, "hmid"))
-        ret->hmid = DATA (cur_node);
-    }
-
-  return ret;
-}
-
-
-
-xml_dayf *
-parse_dayf (xmlNode *cur_node)
-{
-  xml_dayf *ret;
-  gchar    *value;
-
-  if ((ret = g_slice_new0 (xml_dayf)) == NULL)
-    return NULL;
-
-  ret->day = (gchar *) xmlGetProp (cur_node, (const xmlChar *) "t");
-  ret->date = (gchar *) xmlGetProp (cur_node, (const xmlChar *) "dt");
-
-  for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
-    {
-      if (cur_node->type != XML_ELEMENT_NODE)
-        continue;
-
-      if (NODE_IS_TYPE (cur_node, "hi"))
-        {
-          ret->hi = DATA (cur_node);
-          g_assert (ret->hi != NULL);
-        }
-      else if (NODE_IS_TYPE (cur_node, "low"))
-        {
-          ret->low = DATA (cur_node);
-        }
-      else if (NODE_IS_TYPE (cur_node, "part"))
-        {
-          value = (gchar *) xmlGetProp (cur_node, (const xmlChar *) "p");
-
-          if (xmlStrEqual ((const xmlChar *) value, (const xmlChar *) "d"))
-            ret->part[0] = parse_part (cur_node);
-          else
-            if (xmlStrEqual ((const xmlChar *) value, (const xmlChar *) "n"))
-            ret->part[1] = parse_part (cur_node);
-
-          g_free (value);
-        }
-    }
-
-  return ret;
-}
-
-
-
-static void
-xml_uv_free (xml_uv * data)
-{
-  g_free (data->i);
-  g_free (data->t);
-
-  g_slice_free (xml_uv, data);
-}
-
-
-
-static void
-xml_wind_free (xml_wind * data)
-{
-  g_free (data->s);
-  g_free (data->gust);
-  g_free (data->d);
-  g_free (data->t);
-
-  g_slice_free (xml_wind, data);
-}
-
-
-
-static void
-xml_bar_free (xml_bar * data)
-{
-  g_free (data->r);
-  g_free (data->d);
-
-  g_slice_free (xml_bar, data);
-}
-
-
-
-static void
-xml_cc_free (xml_cc * data)
-{
-  g_free (data->obst);
-  g_free (data->lsup);
-  g_free (data->flik);
-  g_free (data->t);
-  g_free (data->icon);
-  g_free (data->tmp);
-  g_free (data->hmid);
-  g_free (data->vis);
-  g_free (data->dewp);
-
-  if (data->uv)
-    xml_uv_free (data->uv);
-
-  if (data->wind)
-    xml_wind_free (data->wind);
-
-  if (data->bar)
-    xml_bar_free (data->bar);
-
-  g_slice_free (xml_cc, data);
-}
-
-
-
-static void
-xml_loc_free (xml_loc *data)
-{
-  g_free (data->dnam);
-  g_free (data->sunr);
-  g_free (data->suns);
-
-  g_slice_free (xml_loc, data);
-}
-
-static void
-xml_lnk_free (xml_lnk *data)
-{
-  int i;
-  for (i = 0; i < 4; i++) {
-    g_free (data->lnk[i]);
-    g_free (data->lnk_txt[i]);
-  }
-  g_slice_free (xml_lnk, data);
-}
-
-static void
-xml_part_free (xml_part *data)
-{
-  if (!data)
-    return;
-
-  g_free (data->icon);
-  g_free (data->t);
-  g_free (data->ppcp);
-  g_free (data->hmid);
+	if (strptime(start, "%Y-%m-%dT%H:%M:%SZ", &start_t) == NULL) {
+		xmlFree(start);
+		xmlFree(end);
+		return;
+	}
 
-  if (data->wind)
-    xml_wind_free (data->wind);
+	if (strptime(end, "%Y-%m-%dT%H:%M:%SZ", &end_t) == NULL) {
+		xmlFree(start);
+		xmlFree(end);
+		return;
+	}
 
-  g_slice_free (xml_part, data);
+	xmlFree(start);
+	xmlFree(end);
+
+	start_ts = my_timegm(&start_t);
+	end_ts = my_timegm(&end_t);
+	
+	/* split per-hour */
+	for (cur_ts = start_ts; cur_ts < end_ts; cur_ts += 3600) {
+		xml_time *timeslice = get_timeslice(data, cur_ts, cur_ts + 3600);
+		xmlNode *child_node;
+
+		if (!timeslice)
+			return;
+		for (child_node = cur_node->children; child_node;
+		     child_node = child_node->next) {
+			if (NODE_IS_TYPE (child_node, "location")) {
+				if (timeslice->location == NULL)
+					timeslice->location =
+						g_slice_new0(xml_location);
+				parse_location(child_node, timeslice->location);
+			}
+		}
+	}
 }
 
-
-
-static void
-xml_dayf_free (xml_dayf *data)
+xml_time *get_timeslice(xml_weather *data, time_t start, time_t end)
 {
-  if (!data)
-    return;
-
-  g_free (data->day);
-  g_free (data->date);
-  g_free (data->hi);
-  g_free (data->low);
-
-  if (data->part[0])
-    xml_part_free (data->part[0]);
-
-  if (data->part[1])
-    xml_part_free (data->part[1]);
-
-  g_slice_free (xml_dayf, data);
+	int i;
+	for (i = 0; i < data->num_timeslices; i++) {
+		if (data->timeslice[i]->start == start
+		 && data->timeslice[i]->end == end)
+			return data->timeslice[i];
+	}
+	if (data->num_timeslices == MAX_TIMESLICE -1)
+		return NULL;
+
+	data->timeslice[data->num_timeslices] = g_slice_new0(xml_time);
+	data->num_timeslices++;
+
+	return data->timeslice[data->num_timeslices - 1];
+}
+
+void parse_location (xmlNode * cur_node, xml_location *loc)
+{
+	xmlNode *child_node;
+
+	for (child_node = cur_node->children; child_node;
+	     child_node = child_node->next) {
+		if (NODE_IS_TYPE (child_node, "temperature")) {
+			g_free(loc->temperature_unit);
+			g_free(loc->temperature_value);
+			loc->temperature_unit = PROP(child_node, "unit");
+			loc->temperature_value = PROP(child_node, "value");
+		}
+		if (NODE_IS_TYPE (child_node, "windDirection")) {
+			g_free(loc->wind_dir_deg);
+			g_free(loc->wind_dir_name);
+			loc->wind_dir_deg = PROP(child_node, "deg");
+			loc->wind_dir_name = PROP(child_node, "name");
+		}
+		if (NODE_IS_TYPE (child_node, "windSpeed")) {
+			g_free(loc->wind_speed_mps);
+			g_free(loc->wind_speed_beaufort);
+			loc->wind_speed_mps = PROP(child_node, "mps");
+			loc->wind_speed_beaufort = PROP(child_node, "beaufort");
+		}
+		if (NODE_IS_TYPE (child_node, "humidity")) {
+			g_free(loc->humidity_unit);
+			g_free(loc->humidity_value);
+			loc->humidity_unit = PROP(child_node, "unit");
+			loc->humidity_value = PROP(child_node, "value");
+		}
+		if (NODE_IS_TYPE (child_node, "pressure")) {
+			g_free(loc->pressure_unit);
+			g_free(loc->pressure_value);
+			loc->pressure_unit = PROP(child_node, "unit");
+			loc->pressure_value = PROP(child_node, "value");
+		}
+		if (NODE_IS_TYPE (child_node, "fog")) {
+			g_free(loc->fog_percent);
+			loc->fog_percent = PROP(child_node, "percent");
+		}
+		if (NODE_IS_TYPE (child_node, "lowClouds")) {
+			g_free(loc->cloudiness_percent[CLOUDINESS_LOW]);
+			loc->cloudiness_percent[CLOUDINESS_LOW] = PROP(child_node, "percent");
+		}
+		if (NODE_IS_TYPE (child_node, "mediumClouds")) {
+			g_free(loc->cloudiness_percent[CLOUDINESS_MED]);
+			loc->cloudiness_percent[CLOUDINESS_MED] = PROP(child_node, "percent");
+		}
+		if (NODE_IS_TYPE (child_node, "highClouds")) {
+			g_free(loc->cloudiness_percent[CLOUDINESS_HIGH]);
+			loc->cloudiness_percent[CLOUDINESS_HIGH] = PROP(child_node, "percent");
+		}
+		if (NODE_IS_TYPE (child_node, "precipitation")) {
+			g_free(loc->precipitation_unit);
+			g_free(loc->precipitation_value);
+			loc->precipitation_unit = PROP(child_node, "unit");
+			loc->precipitation_value = PROP(child_node, "value");
+		}
+		if (NODE_IS_TYPE (child_node, "symbol")) {
+			g_free(loc->symbol);
+			loc->symbol = PROP(child_node, "id");
+		}
+	}
 }
 
-
-
 void
 xml_weather_free (xml_weather *data)
 {
   guint i;
 
-  if (data->cc)
-    xml_cc_free (data->cc);
-
-  if (data->loc)
-    xml_loc_free (data->loc);
-
-  if (data->lnk)
-    xml_lnk_free (data->lnk);
-
-  if (data->dayf)
-    {
-      for (i = 0; i < XML_WEATHER_DAYF_N; i++)
-        {
-          if (!data->dayf[i])
-            break;
-
-          xml_dayf_free (data->dayf[i]);
-        }
-    }
-
   g_slice_free (xml_weather, data);
 }
diff --git a/panel-plugin/weather-parsers.h b/panel-plugin/weather-parsers.h
index 95b8ed1..3f2edc9 100644
--- a/panel-plugin/weather-parsers.h
+++ b/panel-plugin/weather-parsers.h
@@ -24,109 +24,67 @@
 
 G_BEGIN_DECLS
 #define DATA(node) (gchar *) xmlNodeListGetString(node->doc, node->children, 1)
+#define PROP(node, prop) ((gchar *) xmlGetProp ((node), (const xmlChar *) (prop)))
 #define NODE_IS_TYPE(node, type) xmlStrEqual (node->name, (const xmlChar *) type)
-#define XML_WEATHER_DAYF_N 5
+#define MAX_TIMESLICE 250
 
-typedef struct
-{
-  gchar *dnam;
-  gchar *sunr;
-  gchar *suns;
-}
-xml_loc;
-
-typedef struct
+enum
 {
-  gchar *lnk[4];
-  gchar *lnk_txt[4];
-}
-xml_lnk;
+	CLOUDINESS_LOW = 0,
+	CLOUDINESS_MED,
+	CLOUDINESS_HIGH,
+	NUM_CLOUDINESS
+};
 
 typedef struct
 {
-  gchar *i;
-  gchar *t;
+	gchar *temperature_value;
+	gchar *temperature_unit;
+	
+	gchar *wind_dir_deg;
+	gchar *wind_dir_name;
+	gchar *wind_speed_mps;
+	gchar *wind_speed_beaufort;
+
+	gchar *humidity_value;
+	gchar *humidity_unit;
+	
+	gchar *pressure_value;
+	gchar *pressure_unit;
+	
+	gchar *cloudiness_percent[NUM_CLOUDINESS];
+	gchar *fog_percent;
+	
+	gchar *precipitation_value;
+	gchar *precipitation_unit;
+
+	gchar *symbol;
 }
-xml_uv;
+xml_location;
 
 typedef struct
 {
-  gchar *s;
-  gchar *gust;
-  gchar *d;
-  gchar *t;
+	time_t start;
+	time_t end;
+	xml_location *location;
 }
-xml_wind;
+xml_time;
 
 typedef struct
 {
-  gchar *r;
-  gchar *d;
-}
-xml_bar;
-
-typedef struct
-{
-  gchar *lsup;
-  gchar *obst;
-  gchar *flik;
-  gchar *t;
-  gchar *icon;
-  gchar *tmp;
-
-  gchar *hmid;
-  gchar *vis;
-
-  xml_uv *uv;
-  xml_wind *wind;
-  xml_bar *bar;
-
-  gchar *dewp;
-}
-xml_cc;
-
-typedef struct
-{
-  gchar *icon;
-  gchar *t;
-  gchar *ppcp;
-  gchar *hmid;
-
-  xml_wind *wind;
-}
-xml_part;
-
-typedef struct
-{
-  gchar *day;
-  gchar *date;
-
-  gchar *hi;
-  gchar *low;
-
-  xml_part *part[2];
-}
-xml_dayf;
-
-typedef struct
-{
-  xml_loc *loc;
-  xml_lnk *lnk;
-  xml_cc *cc;
-  xml_dayf *dayf[XML_WEATHER_DAYF_N];
+  xml_time *timeslice[MAX_TIMESLICE];
+  guint num_timeslices;
 }
 xml_weather;
 
 
 xml_weather *parse_weather (xmlNode * cur_node);
 
-xml_loc *parse_loc (xmlNode * cur_node);
-
-xml_lnk *parse_lnk (xmlNode * cur_node);
+void parse_time (xmlNode * cur_node, xml_weather * data);
 
-xml_cc *parse_cc (xmlNode * cur_node);
+void parse_location (xmlNode * cur_node, xml_location *location);
 
-xml_dayf *parse_dayf (xmlNode * cur_node);
+xml_time *get_timeslice(xml_weather *data, time_t start, time_t end);
 
 void xml_weather_free (xml_weather * data);
 


More information about the Xfce4-commits mailing list