From 1d8ed2e09890729fe905776d37fb27b1633bf64f Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Thu, 7 Jan 2021 15:14:40 +0100
Subject: [PATCH] metno: Use compat 2.0 API

Version 1.9, which we were using, was deprecated and will be removed soon,
so migrate to the compat XML output of the v2.0 API.

Closes: #65

This patch also includes some follow-up commits included in 3.36.2.
---
diff -urp libgweather-3.34.0.orig/libgweather/gweather-private.c libgweather-3.34.0/libgweather/gweather-private.c
--- libgweather-3.34.0.orig/libgweather/gweather-private.c	2019-10-08 03:57:31.000000000 -0500
+++ libgweather-3.34.0/libgweather/gweather-private.c	2021-06-04 14:10:55.915157663 -0500
@@ -22,8 +22,19 @@
 
 #include "gweather-private.h"
 
-/*
-  There is no code here: the purpose of this header is so that
-  gnome-builder knows how to pick up the include flags to parse
-  gweather-private.h properly.
-*/
+/* sign, 3 digits, separator, 4 decimals, nul-char */
+#define DEGREES_STR_SIZE (1 + 3 + 1 + 4 + 1)
+
+char *
+_radians_to_degrees_str (gdouble radians)
+{
+  char *str;
+  double degrees;
+
+  str = g_malloc0 (DEGREES_STR_SIZE);
+  /* Max 4 decimals */
+  degrees = (double) ((int) (RADIANS_TO_DEGREES (radians) * 10000)) / 10000;
+  /* Too many digits */
+  g_return_val_if_fail (degrees <= 1000 || degrees >= -1000, NULL);
+  return g_ascii_formatd (str, G_ASCII_DTOSTR_BUF_SIZE, "%g", degrees);
+}
diff -urp libgweather-3.34.0.orig/libgweather/gweather-private.h libgweather-3.34.0/libgweather/gweather-private.h
--- libgweather-3.34.0.orig/libgweather/gweather-private.h	2019-10-08 03:57:31.000000000 -0500
+++ libgweather-3.34.0/libgweather/gweather-private.h	2021-06-04 14:10:55.915157663 -0500
@@ -167,6 +167,9 @@ struct _GWeatherInfoPrivate {
 #define RADIANS_TO_DEGREES(rad)		((rad) * 180. / M_PI)
 #define RADIANS_TO_HOURS(rad)		((rad) * 12. / M_PI)
 
+GWEATHER_EXTERN
+char           *_radians_to_degrees_str (gdouble radians);
+
 /*
  * Planetary Mean Orbit and their progressions from J2000 are based on the
  * values in http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf
diff -urp libgweather-3.34.0.orig/libgweather/gweather-weather.c libgweather-3.34.0/libgweather/gweather-weather.c
--- libgweather-3.34.0.orig/libgweather/gweather-weather.c	2021-06-04 13:49:46.180368946 -0500
+++ libgweather-3.34.0/libgweather/gweather-weather.c	2021-06-04 14:14:34.752327682 -0500
@@ -586,6 +586,30 @@ dump_and_unref_cache (SoupCache *cache)
 
 static SoupSession *static_session;
 
+static const char *
+app_id (void)
+{
+    GApplication *app = g_application_get_default ();
+    const char *id;
+
+    if (app) {
+        id = g_application_get_application_id (app);
+        if (id)
+            return id;
+    }
+
+    return g_get_prgname ();
+}
+
+static const char *
+user_agent (void)
+{
+    static char *ua = NULL;
+    if (ua == NULL)
+        ua = g_strdup_printf ("libgweather/%s (+https://gitlab.gnome.org/GNOME/libgweather/) (%s) ", LIBGWEATHER_VERSION, app_id ());
+    return ua;
+}
+
 static SoupSession *
 ref_session (void)
 {
@@ -598,8 +622,7 @@ ref_session (void)
 	return g_object_ref (session);
 
     session = soup_session_new ();
-    g_object_set (G_OBJECT (session), SOUP_SESSION_USER_AGENT,
-                  "libgweather/" LIBGWEATHER_VERSION " (+https://gitlab.gnome.org/GNOME/libgweather/) ", NULL);
+    g_object_set (G_OBJECT (session), SOUP_SESSION_USER_AGENT, user_agent (), NULL);
 
     cache = get_cache ();
     if (cache != NULL) {
Only in libgweather-3.34.0/libgweather: gweather-weather.c.orig
diff -urp libgweather-3.34.0.orig/libgweather/gweather-weather.h libgweather-3.34.0/libgweather/gweather-weather.h
--- libgweather-3.34.0.orig/libgweather/gweather-weather.h	2019-10-08 03:57:31.000000000 -0500
+++ libgweather-3.34.0/libgweather/gweather-weather.h	2021-06-04 14:13:51.040093964 -0500
@@ -46,7 +46,7 @@ typedef enum { /*< flags, underscore_nam
     GWEATHER_PROVIDER_YAHOO = 1 << 3,
     GWEATHER_PROVIDER_YR_NO = 1 << 4,
     GWEATHER_PROVIDER_OWM = 1 << 5,
-    GWEATHER_PROVIDER_ALL = 31
+    GWEATHER_PROVIDER_ALL = (GWEATHER_PROVIDER_METAR | GWEATHER_PROVIDER_IWIN | GWEATHER_PROVIDER_YAHOO | GWEATHER_PROVIDER_YR_NO | GWEATHER_PROVIDER_OWM)
 } GWeatherProvider;
 
 typedef struct _GWeatherInfo GWeatherInfo;
diff -urp libgweather-3.34.0.orig/libgweather/test_libgweather.c libgweather-3.34.0/libgweather/test_libgweather.c
--- libgweather-3.34.0.orig/libgweather/test_libgweather.c	2019-10-08 03:57:31.000000000 -0500
+++ libgweather-3.34.0/libgweather/test_libgweather.c	2021-06-04 14:10:55.919157685 -0500
@@ -26,6 +26,7 @@
 #include <gweather-version.h>
 #include "gweather-location.h"
 #include "gweather-weather.h"
+#include "gweather-private.h"
 
 extern void _gweather_location_reset_world (void);
 
@@ -639,6 +640,20 @@ test_duplicate_weather_stations (void)
 }
 
 static void
+test_radians_to_degrees_str (void)
+{
+    char long_version[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *short_version = NULL;
+    double coord = 1.260765526077;
+
+    g_ascii_dtostr (long_version, G_ASCII_DTOSTR_BUF_SIZE, RADIANS_TO_DEGREES (coord));
+    short_version = _radians_to_degrees_str (coord);
+
+    g_assert_cmpint (strlen (long_version), >, strlen (short_version));
+    g_assert_cmpstr (short_version, ==, "72.2365");
+}
+
+static void
 log_handler (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer user_data)
 {
 	g_print ("%s\n", message);
@@ -660,6 +675,7 @@ main (int argc, char *argv[])
 		  FALSE);
 	set_gsettings ();
 
+	g_test_add_func ("/weather/radians-to-degrees_str", test_radians_to_degrees_str);
 	g_test_add_func ("/weather/named-timezones", test_named_timezones);
 	g_test_add_func ("/weather/named-timezones-deserialized", test_named_timezones_deserialized);
 	g_test_add_func ("/weather/no-code-serialize", test_no_code_serialize);
Only in libgweather-3.34.0/libgweather: test_libgweather.c.orig
diff -urp libgweather-3.34.0.orig/libgweather/weather-iwin.c libgweather-3.34.0/libgweather/weather-iwin.c
--- libgweather-3.34.0.orig/libgweather/weather-iwin.c	2021-06-04 13:49:40.084336346 -0500
+++ libgweather-3.34.0/libgweather/weather-iwin.c	2021-06-04 14:10:55.919157685 -0500
@@ -353,7 +353,8 @@ iwin_start_open (GWeatherInfo *info)
     SoupMessage *msg;
     struct tm tm;
     time_t now;
-    gchar latstr[G_ASCII_DTOSTR_BUF_SIZE], lonstr[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *latstr = NULL;
+    g_autofree char *lonstr = NULL;
 
     g_assert (info != NULL);
 
@@ -376,8 +377,8 @@ iwin_start_open (GWeatherInfo *info)
     now = time (NULL);
     localtime_r (&now, &tm);
 
-    g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
-    g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
+    latstr = _radians_to_degrees_str (loc->latitude);
+    lonstr = _radians_to_degrees_str (loc->longitude);
     url = g_strdup_printf ("https://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?&lat=%s&lon=%s&format=24+hourly&startDate=%04d-%02d-%02d&numDays=7",
 			   latstr, lonstr, 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday);
     g_debug ("iwin_start_open, requesting: %s", url);
diff -urp libgweather-3.34.0.orig/libgweather/weather-owm.c libgweather-3.34.0/libgweather/weather-owm.c
--- libgweather-3.34.0.orig/libgweather/weather-owm.c	2021-06-04 13:49:40.088336368 -0500
+++ libgweather-3.34.0/libgweather/weather-owm.c	2021-06-04 14:10:55.919157685 -0500
@@ -428,7 +428,8 @@ owm_start_open (GWeatherInfo *info)
     gchar *url;
     SoupMessage *message;
     WeatherLocation *loc;
-    gchar latstr[G_ASCII_DTOSTR_BUF_SIZE], lonstr[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *latstr = NULL;
+    g_autofree char *lonstr = NULL;
 
     priv = info->priv;
     loc = &priv->location;
@@ -438,8 +439,8 @@ owm_start_open (GWeatherInfo *info)
 
     /* see the description here: http://bugs.openweathermap.org/projects/api/wiki/Api_2_5_forecast */
 
-    g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
-    g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
+    latstr = _radians_to_degrees_str (loc->latitude);
+    lonstr = _radians_to_degrees_str (loc->longitude);
 
 #define TEMPLATE_START "https://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&mode=xml&units=metric"
 #ifdef OWM_APIKEY
diff -urp libgweather-3.34.0.orig/libgweather/weather-yrno.c libgweather-3.34.0/libgweather/weather-yrno.c
--- libgweather-3.34.0.orig/libgweather/weather-yrno.c	2021-06-04 13:49:40.088336368 -0500
+++ libgweather-3.34.0/libgweather/weather-yrno.c	2021-06-04 14:14:58.440454338 -0500
@@ -37,55 +37,58 @@
 
 #define XC(t) ((const xmlChar *)(t))
 
-/* Reference for symbols at http://om.yr.no/forklaring/symbol/ */
+/* As per https://gitlab.gnome.org/GNOME/libgweather/-/issues/59#note_1004747 */
+#define API_ENDPOINT_DOMAIN "aa037rv1tsaszxi6o.api.met.no"
+
+/* Reference for symbols at https://api.met.no/weatherapi/weathericon/2.0/ */
 typedef struct {
-    int code;
+    const char *code;
     GWeatherSky sky;
     GWeatherConditions condition;
 } 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 */
+    { "clearsky",  GWEATHER_SKY_CLEAR,     { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Sun */
+    { "fair",  GWEATHER_SKY_BROKEN,    { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* LightCloud */
+    { "partlycloudy",  GWEATHER_SKY_SCATTERED, { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* PartlyCloudy */
+    { "cloudy",  GWEATHER_SKY_OVERCAST,  { FALSE, GWEATHER_PHENOMENON_NONE, GWEATHER_QUALIFIER_NONE } }, /* Cloudy */
+    { "rainshowers",  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_LIGHT } }, /* LightRainSun */
+    { "rainshowersandthunder",  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunderSun */
+    { "sleetshowers",  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* SleetSun */
+    { "snowshowers",  GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* SnowSun */
+    { "rain",  GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_LIGHT } }, /* SnowSun */
+    { "heavyrain", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* Rain */
+    { "heavyrainandthunder", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunder */
+    { "sleet", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_NONE } }, /* Sleet */
+    { "snow", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_NONE } }, /* Snow */
+    { "snowandthunder", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowThunder */
+    { "fog", GWEATHER_SKY_CLEAR,     { TRUE, GWEATHER_PHENOMENON_FOG, GWEATHER_QUALIFIER_NONE } }, /* Fog */
+    { "sleetshowersandthunder", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetSunThunder */
+    { "snowshowersandthunder", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SnowSunThunder */
+    { "rainandthunder", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* LightRainThunder */
+    { "sleetandthunder", GWEATHER_SKY_OVERCAST,  { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* SleetThunder */
+    { "lightrainshowersandthunder", GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunderSun */
+    { "heavyrainshowersandthunder", GWEATHER_SKY_BROKEN,  { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* RainThunderSun */
+    { "lightssleetshowersandthunder", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunderSun */
+    { "heavysleetshowersandthunder", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunderSun */
+    { "lightssnowshowersandthunder", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunderSun */
+    { "heavysnowshowersandthunder", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunderSun */
+    { "lightrainandthunder", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_THUNDERSTORM } }, /* DrizzleThunder */
+    { "lightsleetandthunder", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetThunder */
+    { "heavysleetandthunder", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetThunder */
+    { "lightsnowandthunder", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowThunder */
+    { "heavysnowandthunder", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowThunder */
+    { "lightrainshowers", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* DrizzleSun */
+    { "heavyrainshowers", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_RAIN, GWEATHER_QUALIFIER_NONE } }, /* RainSun */
+    { "lightsleetshowers", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleetSun */
+    { "heavysleetshowers", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleetSun */
+    { "lightsnowshowers", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnowSun */
+    { "heavysnowshowers", GWEATHER_SKY_BROKEN,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySnowSun */
+    { "lightrain", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_DRIZZLE, GWEATHER_QUALIFIER_NONE } }, /* Drizzle */
+    { "lightsleet", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_LIGHT } }, /* LightSleet */
+    { "heavysleet", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_ICE_PELLETS, GWEATHER_QUALIFIER_HEAVY } }, /* HeavySleet */
+    { "lightsnow", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_LIGHT } }, /* LightSnow */
+    { "heavysnow", GWEATHER_SKY_OVERCAST,    { TRUE, GWEATHER_PHENOMENON_SNOW, GWEATHER_QUALIFIER_HEAVY } } /* HeavySnow */
 };
 
 static struct {
@@ -146,21 +149,18 @@ date_to_time_t (const xmlChar *str, cons
 }
 
 static YrnoSymbol *
-symbol_search (int code)
+symbol_search (const char *code)
 {
-    int a = 0;
-    int b = G_N_ELEMENTS (symbols);
+    unsigned int i;
+
+    for (i = 0; i < G_N_ELEMENTS (symbols); i++) {
+        YrnoSymbol *s = symbols + i;
 
-    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;
+        if (strcmp (code, s->code) == 0)
+            return s;
+
+        if (strstr (code, s->code) == code && code[strlen (s->code)] == '_')
+            return s;
     }
 
     return NULL;
@@ -174,9 +174,9 @@ read_symbol (GWeatherInfo *info,
     YrnoSymbol* symbol;
     GWeatherInfoPrivate *priv = info->priv;
 
-    val = xmlGetProp (node, XC("number"));
+    val = xmlGetProp (node, XC("code"));
 
-    symbol = symbol_search (strtol ((char*) val, NULL, 0));
+    symbol = symbol_search ((char *)val);
     if (symbol != NULL) {
 	priv->valid = TRUE;
 	priv->sky = symbol->sky;
@@ -435,7 +435,8 @@ yrno_start_open (GWeatherInfo *info)
     gchar *url;
     SoupMessage *message;
     WeatherLocation *loc;
-    gchar latstr[G_ASCII_DTOSTR_BUF_SIZE], lonstr[G_ASCII_DTOSTR_BUF_SIZE];
+    g_autofree char *latstr = NULL;
+    g_autofree char *lonstr = NULL;
 
     priv = info->priv;
     loc = &priv->location;
@@ -443,12 +444,12 @@ yrno_start_open (GWeatherInfo *info)
     if (!loc->latlon_valid)
 	return FALSE;
 
-    /* see the description here: https://api.met.no/ */
+    /* see the description here: https://api.met.no/weatherapi/locationforecast/2.0/documentation */
 
-    g_ascii_dtostr (latstr, sizeof(latstr), RADIANS_TO_DEGREES (loc->latitude));
-    g_ascii_dtostr (lonstr, sizeof(lonstr), RADIANS_TO_DEGREES (loc->longitude));
+    latstr = _radians_to_degrees_str (loc->latitude);
+    lonstr = _radians_to_degrees_str (loc->longitude);
 
-    url = g_strdup_printf("https://api.met.no/weatherapi/locationforecast/1.9/?lat=%s;lon=%s", latstr, lonstr);
+    url = g_strdup_printf("https://" API_ENDPOINT_DOMAIN "/weatherapi/locationforecast/2.0/classic?lat=%s&lon=%s", latstr, lonstr);
     g_debug ("yrno_start_open, requesting: %s", url);
 
     message = soup_message_new ("GET", url);
