From c711ab50d949eda0092a86c676deb39b1b2b8b9f Mon Sep 17 00:00:00 2001
From: Giovanni Campagna <gcampagna@src.gnome.org>
Date: Tue, 9 Sep 2014 14:15:43 -0700
Subject: [PATCH 1/2] Yr.no: update to version 1.9 of the online API

The old version has been discontinued (without notice), start
using the new one.

https://bugzilla.gnome.org/show_bug.cgi?id=736334
---
 libgweather/weather-yrno.c | 69 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 54 insertions(+), 15 deletions(-)

diff --git a/libgweather/weather-yrno.c b/libgweather/weather-yrno.c
index 05d43a9..741e260 100644
--- a/libgweather/weather-yrno.c
+++ b/libgweather/weather-yrno.c
@@ -44,25 +44,46 @@ static struct {
     GWeatherSky sky;
     GWeatherConditions condition;
 } symbols[] = {
-    { GWEATHER_SKY_CLEAR,     { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Sun / clear sky */
-    { GWEATHER_SKY_BROKEN,    { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Fair */
-    { GWEATHER_SKY_SCATTERED, { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Partly cloudy */
+    { GWEATHER_SKY_CLEAR,     { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Sun */
+    { GWEATHER_SKY_BROKEN,    { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* LightCloud */
+    { GWEATHER_SKY_SCATTERED, { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* PartlyCloudy */
     { GWEATHER_SKY_OVERCAST,  { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Cloudy */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_SHOWERS } }, /* Rain showers */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* Rain showers with thunder */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_SHOWERS } }, /* Sleet showers */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_SHOWERS } }, /* Snow showers */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_LIGHT } }, /* LightRainSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunderSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* SleetSun */
+    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* SnowSun */
     { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* Rain */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_HEAVY } }, /* Heavy rain */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* Rain and thunder */
+    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunder */
     { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* Sleet */
     { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* Snow */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* Snow and thunder */
+    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowThunder */
     { GWEATHER_SKY_CLEAR,     { TRUE, GWEATHER_PHENOMENON_FOG, GWEATHER_QUALIFIER_NONE } }, /* Fog */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* Sleet showers and thunder */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* Snow showers and thunder */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_HEAVY } }, /* Rain and thunder */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } } /* Sleet and thunder */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetSunThunder */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowSunThunder */
+    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunder */
+    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetThunder */
+    { GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunderSun */
+    { GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunderSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunderSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunderSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunderSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunderSun */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunder */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunder */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunder */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunder */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunder */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* DrizzleSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* RainSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowSun */
+    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowSun */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* Drizzle */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleet */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleet */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnow */
+    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } } /* HeavySnow */
 };
 
 static struct {
@@ -207,6 +228,22 @@ read_pressure (GWeatherInfo *info,
 }
 
 static inline void
+read_humidity (GWeatherInfo *info,
+	       xmlNodePtr    node)
+{
+    xmlChar *val;
+    double percent;
+
+    val = xmlGetProp (node, XC("value"));
+    if (val == NULL)
+	return;
+
+    percent = g_ascii_strtod ((char*) val, NULL);
+    info->priv->humidity = percent;
+    info->priv->hasHumidity = TRUE;
+}
+
+static inline void
 read_child_node (GWeatherInfo *info,
 		 xmlNodePtr    node)
 {
@@ -220,6 +257,8 @@ read_child_node (GWeatherInfo *info,
 	read_temperature (info, node);
     else if (strcmp ((char*) node->name, "pressure") == 0)
 	read_pressure (info, node);
+    else if (strcmp ((char*) node->name, "humidity") == 0)
+	read_humidity (info, node);
 }
 
 static inline void
@@ -537,7 +576,7 @@ yrno_start_open_new (GWeatherInfo *info)
     g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
     g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
 
-    url = g_strdup_printf("http://api.yr.no/weatherapi/locationforecast/1.8/?lat=%s;lon=%s", latstr, lonstr);
+    url = g_strdup_printf("http://api.yr.no/weatherapi/locationforecast/1.9/?lat=%s;lon=%s", latstr, lonstr);
 
     message = soup_message_new ("GET", url);
     _gweather_info_begin_request (info, message);
-- 
1.8.5.2


From cba95ab4365997ba432eacda5be8a6e8519f5f95 Mon Sep 17 00:00:00 2001
From: Giovanni Campagna <gcampagna@src.gnome.org>
Date: Fri, 10 Oct 2014 16:17:47 -0700
Subject: [PATCH 2/2] yrno: actually update to the 1.9 API

The 1.9 API, unlike the 1.8 one, uses non consecutive numbers for
symbol codes, so we need to write down which codes correspond
to which symbols and use a binary search to find out what the server
gave us.

https://bugzilla.gnome.org/show_bug.cgi?id=738307
---
 libgweather/weather-yrno.c | 119 +++++++++++++++++++++++++++------------------
 1 file changed, 72 insertions(+), 47 deletions(-)

diff --git a/libgweather/weather-yrno.c b/libgweather/weather-yrno.c
index 741e260..9548683 100644
--- a/libgweather/weather-yrno.c
+++ b/libgweather/weather-yrno.c
@@ -40,50 +40,54 @@
 #define XC(t) ((const xmlChar *)(t))
 
 /* Reference for symbols at http://om.yr.no/forklaring/symbol/ */
-static struct {
+typedef struct {
+    int code;
     GWeatherSky sky;
     GWeatherConditions condition;
-} symbols[] = {
-    { GWEATHER_SKY_CLEAR,     { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Sun */
-    { GWEATHER_SKY_BROKEN,    { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* LightCloud */
-    { GWEATHER_SKY_SCATTERED, { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* PartlyCloudy */
-    { GWEATHER_SKY_OVERCAST,  { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Cloudy */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_LIGHT } }, /* LightRainSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunderSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* SleetSun */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* SnowSun */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* Rain */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunder */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* Sleet */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* Snow */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowThunder */
-    { GWEATHER_SKY_CLEAR,     { TRUE, GWEATHER_PHENOMENON_FOG, GWEATHER_QUALIFIER_NONE } }, /* Fog */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetSunThunder */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowSunThunder */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunder */
-    { GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetThunder */
-    { GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunderSun */
-    { GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunderSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunderSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunderSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunderSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunderSun */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunder */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunder */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunder */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunder */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunder */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* DrizzleSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* RainSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowSun */
-    { GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowSun */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* Drizzle */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleet */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleet */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnow */
-    { GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } } /* HeavySnow */
+} YrnoSymbol;
+
+static YrnoSymbol symbols[] = {
+    { 1,  GWEATHER_SKY_CLEAR,     { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Sun */
+    { 2,  GWEATHER_SKY_BROKEN,    { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* LightCloud */
+    { 3,  GWEATHER_SKY_SCATTERED, { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* PartlyCloudy */
+    { 4,  GWEATHER_SKY_OVERCAST,  { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Cloudy */
+    { 5,  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_LIGHT } }, /* LightRainSun */
+    { 6,  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunderSun */
+    { 7,  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* SleetSun */
+    { 8,  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* SnowSun */
+    { 9,  GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_LIGHT } }, /* SnowSun */
+    { 10, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* Rain */
+    { 11, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunder */
+    { 12, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* Sleet */
+    { 13, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* Snow */
+    { 14, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowThunder */
+    { 15, GWEATHER_SKY_CLEAR,     { TRUE, GWEATHER_PHENOMENON_FOG, GWEATHER_QUALIFIER_NONE } }, /* Fog */
+    { 20, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetSunThunder */
+    { 21, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowSunThunder */
+    { 22, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunder */
+    { 23, GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetThunder */
+    { 24, GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunderSun */
+    { 25, GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunderSun */
+    { 26, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunderSun */
+    { 27, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunderSun */
+    { 28, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunderSun */
+    { 29, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunderSun */
+    { 30, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunder */
+    { 31, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunder */
+    { 32, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunder */
+    { 33, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunder */
+    { 34, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunder */
+    { 40, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* DrizzleSun */
+    { 41, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* RainSun */
+    { 42, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetSun */
+    { 43, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetSun */
+    { 44, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowSun */
+    { 45, GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowSun */
+    { 46, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* Drizzle */
+    { 47, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleet */
+    { 48, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleet */
+    { 49, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnow */
+    { 50, GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } } /* HeavySnow */
 };
 
 static struct {
@@ -143,21 +147,42 @@ date_to_time_t (const xmlChar *str, const char * tzid)
     return rval;
 }
 
+static YrnoSymbol *
+symbol_search (int code)
+{
+    int a = 0;
+    int b = G_N_ELEMENTS (symbols);
+
+    while (a < b) {
+	int c = (a + b)/2;
+	YrnoSymbol *yc = symbols + c;
+
+	if (yc->code == code)
+	    return yc;
+	if (yc->code < code)
+	    a = c+1;
+	else
+	    b = c;
+    }
+
+    return NULL;
+}
+
 static inline void
 read_symbol (GWeatherInfo *info,
 	     xmlNodePtr    node)
 {
     xmlChar *val;
-    int symbol;
+    YrnoSymbol* symbol;
     GWeatherInfoPrivate *priv = info->priv;
 
     val = xmlGetProp (node, XC("number"));
 
-    symbol = strtol ((char*) val, NULL, 0) - 1;
-    if (symbol >= 0 && symbol < G_N_ELEMENTS (symbols)) {
+    symbol = symbol_search (strtol ((char*) val, NULL, 0));
+    if (symbol != NULL) {
 	priv->valid = TRUE;
-	priv->sky = symbols[symbol].sky;
-	priv->cond = symbols[symbol].condition;
+	priv->sky = symbol->sky;
+	priv->cond = symbol->condition;
     }
 }
 
-- 
1.8.5.2

