[Xfce4-commits] <xfce4-weather-plugin:master> Astrological data: Add functions for parsing XML data.
Harald Judt
noreply at xfce.org
Tue Jul 31 13:26:01 CEST 2012
Updating branch refs/heads/master
to f93f9b9c6df05e9a21c14a9a9e08f56606fa205c (commit)
from 695283e0396bd7256bd4d9d0cd5b6c5b2eb96359 (commit)
commit f93f9b9c6df05e9a21c14a9a9e08f56606fa205c
Author: Harald Judt <h.judt at gmx.at>
Date: Tue Jul 31 10:59:59 2012 +0200
Astrological data: Add functions for parsing XML data.
Sunrise/sunset calculations are rather tricky, so let's just use
http://api.yr.no/weatherapi/sunrise/1.0/documentation.
This way we get moonrise, moonset and moon phase for free.
panel-plugin/weather-parsers.c | 137 ++++++++++++++++++++++++++++++++++++++++
panel-plugin/weather-parsers.h | 23 ++++++-
2 files changed, 157 insertions(+), 3 deletions(-)
diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c
index 7de38eb..a3988ca 100644
--- a/panel-plugin/weather-parsers.c
+++ b/panel-plugin/weather-parsers.c
@@ -92,6 +92,132 @@ parse_weather(xmlNode *cur_node)
}
+time_t
+parse_xml_timestring(gchar* ts, gchar* format) {
+ time_t t;
+ struct tm tm;
+
+ memset(&t, 0, sizeof(time_t));
+ if (ts == NULL)
+ return t;
+
+ /* standard format */
+ if (format == NULL)
+ format = "%Y-%m-%dT%H:%M:%SZ";
+
+ memset(&tm, 0, sizeof(struct tm));
+ tm.tm_isdst = -1;
+
+ if (strptime(ts, format, &tm) == NULL)
+ return t;
+
+ t = my_timegm(&tm);
+ return t;
+}
+
+
+void
+parse_astro_location(xmlNode *cur_node,
+ xml_astro *astro)
+{
+ xmlNode *child_node;
+ time_t sunrise_t, sunset_t, moonrise_t, moonset_t;
+ gchar *sunrise, *sunset, *moonrise, *moonset;
+ gchar *never_rises, *never_sets;
+
+ for (child_node = cur_node->children; child_node;
+ child_node = child_node->next) {
+ if (NODE_IS_TYPE(child_node, "sun")) {
+ never_rises = PROP(child_node, "never_rise");
+ if (never_rises &&
+ (!strcmp(never_rises, "true") ||
+ !strcmp(never_rises, "1")))
+ astro->sun_never_rises = TRUE;
+ else
+ astro->sun_never_rises = FALSE;
+ xmlFree(never_rises);
+
+ never_sets = PROP(child_node, "never_set");
+ if (never_sets &&
+ (!strcmp(never_sets, "true") ||
+ !strcmp(never_sets, "1")))
+ astro->sun_never_sets = TRUE;
+ else
+ astro->sun_never_sets = FALSE;
+ xmlFree(never_sets);
+
+ sunrise = PROP(child_node, "rise");
+ astro->sunrise = parse_xml_timestring(sunrise, NULL);
+ xmlFree(sunrise);
+
+ sunset = PROP(child_node, "set");
+ astro->sunset = parse_xml_timestring(sunset, NULL);
+ xmlFree(sunset);
+ }
+
+ if (NODE_IS_TYPE(child_node, "moon")) {
+ never_rises = PROP(child_node, "never_rise");
+ if (never_rises &&
+ (!strcmp(never_rises, "true") ||
+ !strcmp(never_rises, "1")))
+ astro->moon_never_rises = TRUE;
+ else
+ astro->moon_never_rises = FALSE;
+ xmlFree(never_rises);
+
+ never_sets = PROP(child_node, "never_set");
+ if (never_sets &&
+ (!strcmp(never_sets, "true") ||
+ !strcmp(never_sets, "1")))
+ astro->moon_never_sets = TRUE;
+ else
+ astro->moon_never_sets = FALSE;
+ xmlFree(never_sets);
+
+ moonrise = PROP(child_node, "rise");
+ astro->moonrise = parse_xml_timestring(moonrise, NULL);
+ xmlFree(moonrise);
+
+ moonset = PROP(child_node, "set");
+ astro->moonset = parse_xml_timestring(moonset, NULL);
+ xmlFree(moonset);
+
+ astro->moon_phase = PROP(child_node, "phase");
+ }
+ }
+}
+
+
+/*
+ * Look at http://api.yr.no/weatherapi/sunrise/1.0/schema for information
+ * of elements and attributes to expect.
+ */
+xml_astro *
+parse_astro(xmlNode *cur_node)
+{
+ xmlNode *child_node, *time_node = NULL, *location_node = NULL;
+ xml_astro *astro = g_slice_new0(xml_astro);
+ guint i = 0;
+
+ if (G_UNLIKELY(astro == NULL))
+ return NULL;
+
+ for (child_node = cur_node->children; child_node;
+ child_node = child_node->next)
+ if (NODE_IS_TYPE (child_node, "time")) {
+ time_node = child_node;
+ break;
+ }
+
+ if (G_LIKELY(time_node))
+ for (child_node = time_node->children; child_node;
+ child_node = child_node->next)
+ if (NODE_IS_TYPE (child_node, "location"))
+ parse_astro_location(child_node, astro);
+ return astro;
+}
+
+
void
parse_time(xmlNode * cur_node,
xml_weather * data)
@@ -317,3 +443,14 @@ xml_weather_free(xml_weather *data)
g_slice_free(xml_weather, data);
data = NULL;
}
+
+void
+xml_astro_free(xml_astro *astro)
+{
+ g_assert(astro != NULL);
+ if (G_UNLIKELY(astro == NULL))
+ return;
+ g_free(astro->moon_phase);
+ g_slice_free(xml_astro, astro);
+ astro = NULL;
+}
diff --git a/panel-plugin/weather-parsers.h b/panel-plugin/weather-parsers.h
index 33361c1..2e50a7a 100644
--- a/panel-plugin/weather-parsers.h
+++ b/panel-plugin/weather-parsers.h
@@ -24,11 +24,11 @@
G_BEGIN_DECLS
-#define DATA(node) \
+#define DATA(node) \
((gchar *) xmlNodeListGetString(node->doc, node->children, 1))
-#define PROP(node, prop) \
+#define PROP(node, prop) \
((gchar *) xmlGetProp((node), (const xmlChar *) (prop)))
-#define NODE_IS_TYPE(node, type) \
+#define NODE_IS_TYPE(node, type) \
(xmlStrEqual(node->name, (const xmlChar *) type))
#define MAX_TIMESLICE 500
@@ -83,9 +83,24 @@ typedef struct {
xml_time *current_conditions;
} xml_weather;
+typedef struct {
+ time_t sunrise;
+ time_t sunset;
+ gboolean sun_never_rises;
+ gboolean sun_never_sets;
+
+ time_t moonrise;
+ time_t moonset;
+ gboolean moon_never_rises;
+ gboolean moon_never_sets;
+ gchar *moon_phase;
+} xml_astro;
+
xml_weather *parse_weather(xmlNode *cur_node);
+xml_astro *parse_astro(xmlNode *cur_node);
+
void parse_time(xmlNode *cur_node,
xml_weather *data);
@@ -100,6 +115,8 @@ void xml_time_free(xml_time *timeslice);
void xml_weather_free(xml_weather *data);
+void xml_astro_free(xml_astro *astro);
+
G_END_DECLS
#endif
More information about the Xfce4-commits
mailing list