From b7ac7a509ab67c9ff752838a65c10d5041edadb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Sun, 3 Mar 2024 12:00:10 +0700 Subject: [PATCH] xfce4-weather-plugin: update to 0.11.1. --- ...01-Do-not-translate-warning-messages.patch | 144 +++ .../patches/0002-Fix-moon_phases-array.patch | 22 + .../0003-Fix-remove_timezone_offset.patch | 23 + ...-less-verbose-about-network-requests.patch | 73 ++ .../0005-Migration-to-Sunrise-API-3.0.patch | 1064 +++++++++++++++++ ...-leaks-around-remove_timezone_offset.patch | 68 ++ ...s-Generalise-input-to-array-of-gchar.patch | 261 ++++ .../0008-libsoup-Port-to-libsoup-3.0.patch | 557 +++++++++ srcpkgs/xfce4-weather-plugin/template | 13 +- 9 files changed, 2221 insertions(+), 4 deletions(-) create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0001-Do-not-translate-warning-messages.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0002-Fix-moon_phases-array.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0003-Fix-remove_timezone_offset.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0004-Be-less-verbose-about-network-requests.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0005-Migration-to-Sunrise-API-3.0.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0006-Fix-leaks-around-remove_timezone_offset.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0007-parsers-Generalise-input-to-array-of-gchar.patch create mode 100644 srcpkgs/xfce4-weather-plugin/patches/0008-libsoup-Port-to-libsoup-3.0.patch diff --git a/srcpkgs/xfce4-weather-plugin/patches/0001-Do-not-translate-warning-messages.patch b/srcpkgs/xfce4-weather-plugin/patches/0001-Do-not-translate-warning-messages.patch new file mode 100644 index 00000000000000..a0b8e5df00993a --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0001-Do-not-translate-warning-messages.patch @@ -0,0 +1,144 @@ +From b4b91ce053171b788cec0ee046d664db3a5999e6 Mon Sep 17 00:00:00 2001 +From: Gaël Bonithon +Date: Thu, 28 Sep 2023 20:25:07 +0200 +Subject: [PATCH 1/8] Do not translate warning messages + +(cherry picked from commit 97ce07dc0e32e4d31489d142fdc4f0e73857e926) +--- + panel-plugin/weather-icon.c | 2 +- + panel-plugin/weather-search.c | 4 ++-- + panel-plugin/weather-summary.c | 6 +++--- + panel-plugin/weather.c | 24 ++++++++++++------------ + 4 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/panel-plugin/weather-icon.c b/panel-plugin/weather-icon.c +index 2474742..5e39069 100644 +--- a/panel-plugin/weather-icon.c ++++ b/panel-plugin/weather-icon.c +@@ -186,7 +186,7 @@ get_icon(const icon_theme *theme, + + g_assert(theme != NULL); + if (G_UNLIKELY(!theme)) { +- g_warning(_("No icon theme!")); ++ g_warning("No icon theme!"); + return NULL; + } + +diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c +index f21ba4d..0e66e67 100644 +--- a/panel-plugin/weather-search.c ++++ b/panel-plugin/weather-search.c +@@ -166,7 +166,7 @@ search_cb(GtkWidget *widget, + g_free(sane_str); + + gtk_tree_view_column_set_title(dialog->column, _("Searching...")); +- g_message(_("getting %s"), url); ++ g_message("getting %s", url); + weather_http_queue_request(dialog->session, url, cb_searchdone, dialog); + g_free(url); + } +@@ -434,6 +434,6 @@ void weather_search_by_ip(SoupSession *session, + data->cb = gui_cb; + data->user_data = user_data; + +- g_message(_("getting %s"), url); ++ g_message("getting %s", url); + weather_http_queue_request(session, url, cb_geolocation, data); + } +diff --git a/panel-plugin/weather-summary.c b/panel-plugin/weather-summary.c +index 66c0506..f8c7797 100644 +--- a/panel-plugin/weather-summary.c ++++ b/panel-plugin/weather-summary.c +@@ -245,9 +245,9 @@ logo_fetched(SoupSession *session, + gint scale_factor; + if (!g_file_set_contents(path, msg->response_body->data, + msg->response_body->length, &error)) { +- g_warning(_("Error downloading met.no logo image to %s, " +- "reason: %s\n"), path, +- error ? error->message : _("unknown")); ++ g_warning("Error downloading met.no logo image to %s, " ++ "reason: %s\n", path, ++ error ? error->message : "unknown"); + g_error_free(error); + g_free(path); + return; +diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c +index 919064e..d49dbf8 100644 +--- a/panel-plugin/weather.c ++++ b/panel-plugin/weather.c +@@ -515,10 +515,10 @@ cb_astro_update(SoupSession *session, + xmlFreeDoc(doc); + } + if (parsing_error) +- g_warning(_("Error parsing astronomical data!")); ++ g_warning("Error parsing astronomical data!"); + } else +- g_warning(_("Download of astronomical data failed with " +- "HTTP Status Code %d, Reason phrase: %s"), ++ g_warning("Download of astronomical data failed with " ++ "HTTP Status Code %d, Reason phrase: %s", + msg->status_code, msg->reason_phrase); + data->astro_update->next = calc_next_download_time(data->astro_update, + now_t); +@@ -568,11 +568,11 @@ cb_weather_update(SoupSession *session, + xmlFreeDoc(doc); + } + if (parsing_error) +- g_warning(_("Error parsing weather data!")); ++ g_warning("Error parsing weather data!"); + } else + g_warning +- (_("Download of weather data failed with HTTP Status Code %d, " +- "Reason phrase: %s"), msg->status_code, msg->reason_phrase); ++ ("Download of weather data failed with HTTP Status Code %d, " ++ "Reason phrase: %s", msg->status_code, msg->reason_phrase); + data->weather_update->next = calc_next_download_time(data->weather_update, + now_t); + +@@ -644,7 +644,7 @@ update_handler(gpointer user_data) + data->forecast_days); + + /* start receive thread */ +- g_message(_("getting %s"), url); ++ g_message("getting %s", url); + weather_http_queue_request(data->session, url, + cb_astro_update, data); + g_free(url); +@@ -665,7 +665,7 @@ update_handler(gpointer user_data) + data->lat, data->lon, data->msl); + + /* start receive thread */ +- g_message(_("getting %s"), url); ++ g_message("getting %s", url); + weather_http_queue_request(data->session, url, + cb_weather_update, data); + g_free(url); +@@ -1197,7 +1197,7 @@ write_cache_file(plugin_data *data) + } + + if (!g_file_set_contents(file, out->str, -1, NULL)) +- g_warning(_("Error writing cache file %s!"), file); ++ g_warning("Error writing cache file %s!", file); + else + weather_debug("Cache file %s has been written.", file); + +@@ -1657,7 +1657,7 @@ xfceweather_dialog_response(GtkWidget *dlg, + PLUGIN_WEBSITE, NULL); + + if (G_UNLIKELY(result == FALSE)) +- g_warning(_("Unable to open the following url: %s"), ++ g_warning("Unable to open the following url: %s", + PLUGIN_WEBSITE); + } else { + /* free stuff used in config dialog */ +@@ -1962,8 +1962,8 @@ xfceweather_create_control(XfcePanelPlugin *plugin) + data->iconimage = gtk_image_new_from_surface(icon); + cairo_surface_destroy(icon); + } else +- g_warning(_("No default icon theme? " +- "This should not happen, plugin will crash!")); ++ g_warning("No default icon theme? " ++ "This should not happen, plugin will crash!"); + + data->labels = g_array_new(FALSE, TRUE, sizeof(data_types)); + diff --git a/srcpkgs/xfce4-weather-plugin/patches/0002-Fix-moon_phases-array.patch b/srcpkgs/xfce4-weather-plugin/patches/0002-Fix-moon_phases-array.patch new file mode 100644 index 00000000000000..9a85846815b464 --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0002-Fix-moon_phases-array.patch @@ -0,0 +1,22 @@ +From 3bc83a8d5ca5410e4f061bd1f1265c2a8bcc860c Mon Sep 17 00:00:00 2001 +From: Gaël Bonithon +Date: Thu, 28 Sep 2023 20:26:28 +0200 +Subject: [PATCH 2/8] Fix moon_phases array + +(cherry picked from commit 187ea01e8d98ad253c44f1d1dae32865e0c87a6d) +--- + panel-plugin/weather-translate.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/panel-plugin/weather-translate.c b/panel-plugin/weather-translate.c +index 9f4e1dd..2fe1f95 100644 +--- a/panel-plugin/weather-translate.c ++++ b/panel-plugin/weather-translate.c +@@ -42,7 +42,6 @@ static const gchar *moon_phases[] = { + N_("Waning gibbous"), + N_("Third quarter"), + N_("Waning crescent"), +- NULL + }; + #define NUM_MOON_PHASES (sizeof(moon_phases) / sizeof(gchar *)) + diff --git a/srcpkgs/xfce4-weather-plugin/patches/0003-Fix-remove_timezone_offset.patch b/srcpkgs/xfce4-weather-plugin/patches/0003-Fix-remove_timezone_offset.patch new file mode 100644 index 00000000000000..c14d4655c9b621 --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0003-Fix-remove_timezone_offset.patch @@ -0,0 +1,23 @@ +From 0660d0316a2b936694574444830221c312eaf5fa Mon Sep 17 00:00:00 2001 +From: Gaël Bonithon +Date: Thu, 28 Sep 2023 20:44:26 +0200 +Subject: [PATCH 3/8] Fix remove_timezone_offset() + +(cherry picked from commit 22e2d20c671823683e5a8656f1a96fac8283e5dd) +--- + panel-plugin/weather-parsers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c +index ad5fb61..4a44397 100644 +--- a/panel-plugin/weather-parsers.c ++++ b/panel-plugin/weather-parsers.c +@@ -89,7 +89,7 @@ remove_timezone_offset(gchar *date) + if (re != NULL && g_regex_match(re, date, 0, NULL)) { + res = g_regex_replace(re, date, -1, 0, "Z", 0, NULL); + } else { +- res = date; ++ res = g_strdup(date); + } + g_regex_unref(re); + return res; diff --git a/srcpkgs/xfce4-weather-plugin/patches/0004-Be-less-verbose-about-network-requests.patch b/srcpkgs/xfce4-weather-plugin/patches/0004-Be-less-verbose-about-network-requests.patch new file mode 100644 index 00000000000000..968b82debeb959 --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0004-Be-less-verbose-about-network-requests.patch @@ -0,0 +1,73 @@ +From 47f872cedf33815deef1ba617d8c38564c3f58fd Mon Sep 17 00:00:00 2001 +From: Gaël Bonithon +Date: Sun, 18 Feb 2024 18:37:59 +0100 +Subject: [PATCH 4/8] Be less verbose about network requests + +(cherry picked from commit 01ba73504c0b5b5d58a74f125bc7767f29703ce5) +--- + panel-plugin/weather-search.c | 4 ++-- + panel-plugin/weather.c | 15 ++++++++++----- + 2 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c +index 0e66e67..0e74e7e 100644 +--- a/panel-plugin/weather-search.c ++++ b/panel-plugin/weather-search.c +@@ -166,7 +166,7 @@ search_cb(GtkWidget *widget, + g_free(sane_str); + + gtk_tree_view_column_set_title(dialog->column, _("Searching...")); +- g_message("getting %s", url); ++ weather_debug("getting %s", url); + weather_http_queue_request(dialog->session, url, cb_searchdone, dialog); + g_free(url); + } +@@ -434,6 +434,6 @@ void weather_search_by_ip(SoupSession *session, + data->cb = gui_cb; + data->user_data = user_data; + +- g_message("getting %s", url); ++ weather_debug("getting %s", url); + weather_http_queue_request(session, url, cb_geolocation, data); + } +diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c +index d49dbf8..9ea8f1f 100644 +--- a/panel-plugin/weather.c ++++ b/panel-plugin/weather.c +@@ -516,10 +516,15 @@ cb_astro_update(SoupSession *session, + } + if (parsing_error) + g_warning("Error parsing astronomical data!"); +- } else +- g_warning("Download of astronomical data failed with " +- "HTTP Status Code %d, Reason phrase: %s", ++ } else { ++#if GLIB_CHECK_VERSION (2, 64, 0) ++ g_warning_once("Download of astronomical data failed with HTTP Status Code %d, Reason phrase: %s", ++ msg->status_code, msg->reason_phrase); ++#else ++ g_warning("Download of astronomical data failed with HTTP Status Code %d, Reason phrase: %s", + msg->status_code, msg->reason_phrase); ++#endif ++ } + data->astro_update->next = calc_next_download_time(data->astro_update, + now_t); + +@@ -644,7 +649,7 @@ update_handler(gpointer user_data) + data->forecast_days); + + /* start receive thread */ +- g_message("getting %s", url); ++ weather_debug("getting %s", url); + weather_http_queue_request(data->session, url, + cb_astro_update, data); + g_free(url); +@@ -665,7 +670,7 @@ update_handler(gpointer user_data) + data->lat, data->lon, data->msl); + + /* start receive thread */ +- g_message("getting %s", url); ++ weather_debug("getting %s", url); + weather_http_queue_request(data->session, url, + cb_weather_update, data); + g_free(url); diff --git a/srcpkgs/xfce4-weather-plugin/patches/0005-Migration-to-Sunrise-API-3.0.patch b/srcpkgs/xfce4-weather-plugin/patches/0005-Migration-to-Sunrise-API-3.0.patch new file mode 100644 index 00000000000000..7ecb721e170056 --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0005-Migration-to-Sunrise-API-3.0.patch @@ -0,0 +1,1064 @@ +From 392bd177842d07ee0388b762f67bc608c989dc50 Mon Sep 17 00:00:00 2001 +From: roland3939 +Date: Thu, 29 Feb 2024 16:03:50 +0000 +Subject: [PATCH 5/8] Migration to Sunrise API 3.0 + +Migration to the Sunrise API 3.0 (3.0 API outputs JSON instead of XML). +This merge request sticks as close as possible to features and behavior +of the weather panel-plugin known when using previous API for +astronomical data. + +Fixes: #66 +(cherry picked from commit e3dde9e1d65c63bfd899b2a1deaff079a8faa82f) +--- + configure.ac.in | 1 + + panel-plugin/Makefile.am | 4 +- + panel-plugin/weather-data.c | 87 +++++++-- + panel-plugin/weather-data.h | 3 +- + panel-plugin/weather-parsers.c | 338 ++++++++++++++++++++++++--------- + panel-plugin/weather-parsers.h | 10 +- + panel-plugin/weather.c | 253 +++++++++++++++++------- + panel-plugin/weather.h | 16 ++ + 8 files changed, 529 insertions(+), 183 deletions(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -77,6 +77,7 @@ XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libx + XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0]) + XDT_CHECK_PACKAGE([LIBXML], [libxml-2.0], [2.4.0]) + XDT_CHECK_PACKAGE([SOUP], [libsoup-2.4], [2.42.0]) ++XDT_CHECK_PACKAGE([JSON], [json-c], [0.13.1]) + XDT_CHECK_OPTIONAL_PACKAGE([UPOWER_GLIB], [upower-glib], [0.9.0], [upower], + [upower for adapting update interval to power state]) + +--- a/panel-plugin/Makefile.am ++++ b/panel-plugin/Makefile.am +@@ -40,6 +40,7 @@ libweather_la_CFLAGS = \ + $(XFCONF_CFLAGS) \ + $(GTK_CFLAGS) \ + $(SOUP_CFLAGS) \ ++ $(JSON_CFLAGS) \ + $(UPOWER_GLIB_CFLAGS) \ + $(LIBXML_CFLAGS) \ + -DGTK_DISABLE_SINGLE_INCLUDES \ +@@ -55,7 +56,8 @@ libweather_la_LIBADD = \ + $(XFCONF_LIBS) \ + $(GTK_LIBS) \ + $(LIBXML_LIBS) \ +- $(SOUP_LIBS) ++ $(SOUP_LIBS) \ ++ $(JSON_LIBS) + + libweather_la_LDFLAGS = \ + -avoid-version \ +--- a/panel-plugin/weather-data.c ++++ b/panel-plugin/weather-data.c +@@ -560,39 +560,72 @@ get_unit(const units_config *units, + * + * Either use the exact times for sunrise and sunset if + * available, or fallback to reasonable arbitrary values. ++ * Use timezone offset for proper time of day / night change. + */ + gboolean +-is_night_time(const xml_astro *astro) ++is_night_time(const xml_astro *astro, ++ const gchar *offset) + { + time_t now_t; +- struct tm now_tm; +- +- time(&now_t); ++ GDateTime *dt, *initial_date; ++ GTimeZone *tz; ++ gboolean ret; ++ ++ dt = g_date_time_new_now_local(); ++#if GLIB_CHECK_VERSION (2, 68, 0) ++ tz = g_time_zone_new_identifier(offset); ++#else ++ tz = g_time_zone_new(offset); ++#endif ++ g_assert(tz != NULL); ++ initial_date = g_date_time_new(tz, ++ g_date_time_get_year(dt), ++ g_date_time_get_month(dt), ++ g_date_time_get_day_of_month (dt), ++ g_date_time_get_hour(dt), ++ g_date_time_get_minute(dt), ++ 0); // sec ++ now_t = (time_t)g_date_time_to_unix(initial_date); ++ weather_debug("is_night_time ?: time_now(in the proper timezone)=%s\n", ++ g_date_time_format_iso8601(initial_date)); + + if (G_LIKELY(astro)) { ++ weather_debug("Checking difftime: astro sunrise now_t %d %d.\n", ++ astro->sunrise, now_t); ++ weather_debug("Checking difftime: astro sunset now_t %d %d.\n", ++ astro->sunset, now_t); ++ + if (astro->sun_never_rises || astro->sun_never_sets){ + /* Polar night */ + if (astro->solarnoon_elevation <= 0) +- return TRUE; ++ ret = TRUE; + /* Polar day */ + if (astro->solarmidnight_elevation > 0) +- return FALSE; ++ ret = FALSE; + } + + /* Sunrise and sunset are known */ +- if (difftime(astro->sunrise, now_t) > 0) +- return TRUE; +- +- if (difftime(astro->sunset, now_t) <= 0) +- return TRUE; +- +- return FALSE; ++ else if (difftime(astro->sunrise, now_t) > 0) { ++ ret = TRUE; ++ } ++ else if (difftime(astro->sunset, now_t) <= 0) { ++ ret = TRUE; ++ } ++ else { ++ ret = FALSE; ++ } + } + + /* no astrodata available, use fallback values */ +- now_tm = *localtime(&now_t); +- return (now_tm.tm_hour >= NIGHT_TIME_START || +- now_tm.tm_hour < NIGHT_TIME_END); ++ else ++ ret = (g_date_time_get_hour(initial_date) >= NIGHT_TIME_START || ++ g_date_time_get_hour(initial_date) < NIGHT_TIME_END); ++ ++ g_date_time_unref(dt); ++ g_date_time_unref(initial_date); ++ g_time_zone_unref(tz); ++ weather_debug("Night time status: %s\n", ret ? "true" : "false"); ++ return ret; + } + + +@@ -803,15 +836,22 @@ merge_astro(GArray *astrodata, + /* copy astro, as it may be deleted by the calling function */ + new_astro = xml_astro_copy(astro); + ++ weather_debug("Current astrodata entries: %d", astrodata->len); ++ weather_debug("new_astro->day=%s", format_date(new_astro->day, NULL,TRUE)); ++ weather_dump(weather_dump_astro, new_astro); ++ + /* check for and replace existing astrodata of the same date */ +- if ((old_astro = get_astro(astrodata, astro->day, &index))) { ++ if ((old_astro = get_astro(astrodata, new_astro->day, &index))) { + xml_astro_free(old_astro); + g_array_remove_index(astrodata, index); + g_array_insert_val(astrodata, index, new_astro); + weather_debug("Replaced existing astrodata at %d.", index); ++ weather_dump(weather_dump_astrodata, astrodata); ++ weather_debug("Current astrodata entries: %d", astrodata->len); + } else { + g_array_append_val(astrodata, new_astro); + weather_debug("Appended new astrodata to the existing data."); ++ weather_debug("Current astrodata entries: %d", astrodata->len); + } + } + +@@ -1179,11 +1219,22 @@ get_astro_data_for_day(const GArray *ast + return NULL; + + day_t = day_at_midnight(day_t, day); ++ weather_debug("Checking %d astro entries for data relevant to day %d.", ++ astrodata->len, day); + + for (i = 0; i < astrodata->len; i++) { + astro = g_array_index(astrodata, xml_astro *, i); +- if (astro && (difftime(astro->day, day_t) == 0)) ++ weather_debug("checking astro %d", i); ++ weather_debug("astro data for day:"); ++ weather_debug("%s",weather_dump_astro(astro)); ++ weather_debug("Checking difftime: astro_day day_t %d %d.", ++ astro->day, day_t); ++ ++ if (astro && (difftime(astro->day, day_t) == 0)) { ++ weather_debug("Equal difftime: astro_day day_t %d %d.", ++ astro->day, day_t); + return astro; ++ } + } + + return NULL; +--- a/panel-plugin/weather-data.h ++++ b/panel-plugin/weather-data.h +@@ -118,7 +118,8 @@ gchar *get_data(const xml_time *timeslic + const gchar *get_unit(const units_config *units, + data_types type); + +-gboolean is_night_time(const xml_astro *astro); ++gboolean is_night_time(const xml_astro *astro, ++ const gchar *offset); + + time_t time_calc(struct tm time_tm, + gint year, +--- a/panel-plugin/weather-parsers.c ++++ b/panel-plugin/weather-parsers.c +@@ -57,19 +57,17 @@ static time_t + my_timegm(struct tm *tm) + { + time_t ret; +- char *tz; ++ GDateTime *initial_date; ++ ++ initial_date = g_date_time_new_utc(tm->tm_year + 1900, ++ tm->tm_mon + 1, ++ tm->tm_mday, ++ tm->tm_hour, ++ tm->tm_min, ++ tm->tm_sec); ++ ret = g_date_time_to_unix(initial_date); ++ g_date_time_unref(initial_date); + +- tz = g_strdup(g_getenv("TZ")); +- g_setenv("TZ", "", 1); +- tzset(); +- ret = mktime(tm); +- if (tz) { +- g_setenv("TZ", tz, 1); +- g_free(tz); +- } +- else +- g_unsetenv("TZ"); +- tzset(); + return ret; + } + +@@ -96,13 +94,6 @@ remove_timezone_offset(gchar *date) + } + + +-static gdouble +-extract_double(gchar *str) +-{ +- return g_ascii_strtod (str, NULL); +-} +- +- + xml_time * + get_timeslice(xml_weather *wd, + const time_t start_t, +@@ -141,8 +132,10 @@ get_astro(const GArray *astrodata, + if (G_UNLIKELY(astrodata == NULL)) + return NULL; + ++ weather_debug("day_t=%s", format_date(day_t, NULL,TRUE)); + for (i = 0; i < astrodata->len; i++) { + astro = g_array_index(astrodata, xml_astro *, i); ++ weather_debug("astro->day=%s", format_date(astro->day, NULL,TRUE)); + if (astro && astro->day == day_t) { + if (index != NULL) + *index = i; +@@ -189,7 +182,8 @@ parse_timestring(const gchar *ts, + + + static const gchar * +-parse_moonposition (gdouble pos) { ++parse_moonposition (gdouble pos_in) { ++ gdouble pos = pos_in / 360.0 * 100.0; + if (pos < 0.0 || pos > 100.0) + return "Unknown"; + if (pos <= 12.5) +@@ -422,122 +416,265 @@ parse_weather(xmlNode *cur_node, + } + + +-static xml_astro * +-parse_astro_time(xmlNode *cur_node) ++/* ++ * Look at https://docs.api.met.no/doc/formats/SunriseJSON for information ++ * of elements and attributes to expect. ++ */ ++gboolean ++parse_astrodata_sun(json_object *cur_node, ++ GArray *astrodata) + { +- xmlNode *child_node; + xml_astro *astro; +- gchar *date, *sunrise, *sunset, *moonrise, *moonset; ++ json_object *jwhen, *jinterval, *jproperties, *jdate, *jsunrise, ++ *jsunrise_time, *jsunset, *jsunset_time, ++ *jsolarnoon, *jsolarmidnight, *jdisc_centre_elevation; ++ const gchar day_format[]="%Y-%m-%dT%H:%M:%SZ"; ++ const gchar sun_format[]="%Y-%m-%dT%H:%MZ"; ++ const gchar *date, *time; + gboolean sun_rises = FALSE, sun_sets = FALSE; +- gboolean moon_rises = FALSE, moon_sets = FALSE; +- gdouble moonposition; + + astro = g_slice_new0(xml_astro); + if (G_UNLIKELY(astro == NULL)) +- return NULL; ++ return FALSE; + +- date = PROP(cur_node, "date"); +- astro->day = parse_timestring(date, "%Y-%m-%d", TRUE); +- xmlFree(date); ++ g_assert(astrodata != NULL); ++ if (G_UNLIKELY(astrodata == NULL)) ++ return FALSE; + +- for (child_node = cur_node->children; child_node; +- child_node = child_node->next) { +- if (child_node->type == XML_ELEMENT_NODE) { +- if (NODE_IS_TYPE(child_node, "sunrise")) { +- sunrise = remove_timezone_offset(PROP(child_node, "time")); +- astro->sunrise = parse_timestring(sunrise, NULL, TRUE); +- xmlFree(sunrise); +- sun_rises = TRUE; +- } ++ jwhen = json_object_object_get(cur_node, "when"); ++ if (G_UNLIKELY(jwhen == NULL)) ++ return FALSE; + +- if (NODE_IS_TYPE(child_node, "moonset")) { +- moonset = remove_timezone_offset(PROP(child_node, "time")); +- astro->moonset = parse_timestring(moonset, NULL, TRUE); +- xmlFree(moonset); +- moon_sets = TRUE; +- } ++ jinterval = json_object_object_get(jwhen, "interval"); ++ if (G_UNLIKELY(jinterval == NULL)) ++ return FALSE; ++ if (G_UNLIKELY(json_object_array_length(jinterval)!=2)) ++ return FALSE; + +- if (NODE_IS_TYPE(child_node, "sunset")) { +- sunset = remove_timezone_offset(PROP(child_node, "time")); +- astro->sunset = parse_timestring(sunset, NULL, TRUE); +- xmlFree(sunset); +- sun_sets = TRUE; +- } ++ jdate = json_object_array_get_idx(jinterval, 0); ++ if (G_UNLIKELY(jdate == NULL)) ++ return FALSE; + +- if (NODE_IS_TYPE(child_node, "moonrise")) { +- moonrise = remove_timezone_offset(PROP(child_node, "time")); +- astro->moonrise = parse_timestring(moonrise, NULL, TRUE); +- xmlFree(moonrise); +- moon_rises = TRUE; +- } ++ date = json_object_get_string(jdate); ++ if (G_UNLIKELY(date == NULL)) ++ return FALSE; + +- if (NODE_IS_TYPE(child_node, "moonposition")) { +- moonposition = extract_double(PROP(child_node, "phase")); +- if (astro->moon_phase) { +- g_free (astro->moon_phase); +- } +- astro->moon_phase = g_strdup(parse_moonposition(moonposition)); +- } ++ /* use time info at center of day interval */ ++ astro->day = day_at_midnight(parse_timestring(date, day_format, FALSE) + 12 * 3600, 0); ++ weather_debug("sun: astro->day=%s\n", ++ format_date(astro->day, day_format,TRUE)); + +- if (NODE_IS_TYPE(child_node, "solarnoon")) { +- astro->solarnoon_elevation = extract_double(PROP(child_node, "elevation")); +- } ++ jproperties = json_object_object_get(cur_node, "properties"); ++ if (G_UNLIKELY(jproperties == NULL)) ++ return FALSE; + +- if (NODE_IS_TYPE(child_node, "solarmidnight")) { +- astro->solarmidnight_elevation = extract_double(PROP(child_node, "elevation")); +- } +- } ++ jsunrise = json_object_object_get(jproperties, "sunrise"); ++ if (G_UNLIKELY(jsunrise == NULL)) ++ return FALSE; ++ ++ jsunrise_time = json_object_object_get(jsunrise, "time"); ++ if (G_UNLIKELY(jsunrise_time == NULL)) { ++ weather_debug("sunrise time not found"); ++ } else { ++ date = json_object_get_string(jsunrise_time); ++ if (G_UNLIKELY(date == NULL)) ++ return FALSE; ++ time = remove_timezone_offset(date); ++ astro->sunrise= parse_timestring(time, sun_format, TRUE); ++ sun_rises = TRUE; ++ weather_debug("astro->sunrise=%s\n", ++ format_date(astro->sunrise, NULL,TRUE)); + } + ++ jsunset = json_object_object_get(jproperties, "sunset"); ++ if (G_UNLIKELY(jsunset == NULL)) ++ return FALSE; ++ ++ jsunset_time = json_object_object_get(jsunset, "time"); ++ if (G_UNLIKELY(jsunset_time == NULL)) { ++ weather_debug("sunset time not found"); ++ } else { ++ date = json_object_get_string(jsunset_time); ++ if (G_UNLIKELY(date == NULL)) ++ return FALSE; ++ time = remove_timezone_offset(date); ++ astro->sunset= parse_timestring(time, sun_format, TRUE); ++ sun_sets = TRUE; ++ weather_debug("astro->sunset=%s\n", ++ format_date(astro->sunset, NULL,TRUE)); ++ } ++ ++ jsolarnoon = json_object_object_get(jproperties, "solarnoon"); ++ if (G_UNLIKELY(jsolarnoon == NULL)) ++ return FALSE; ++ ++ jdisc_centre_elevation = json_object_object_get(jsolarnoon, "disc_centre_elevation"); ++ if (G_UNLIKELY(jdisc_centre_elevation == NULL)) ++ return FALSE; ++ ++ astro->solarnoon_elevation = json_object_get_double(jdisc_centre_elevation); ++ weather_debug("astro->solarnoon_elevation=%f\n", ++ astro->solarnoon_elevation); ++ ++ jsolarmidnight = json_object_object_get(jproperties, "solarmidnight"); ++ if (G_UNLIKELY(jsolarmidnight == NULL)) ++ return FALSE; ++ ++ jdisc_centre_elevation = json_object_object_get(jsolarmidnight, "disc_centre_elevation"); ++ if (G_UNLIKELY(jdisc_centre_elevation == NULL)) ++ return FALSE; ++ ++ astro->solarmidnight_elevation = json_object_get_double(jdisc_centre_elevation); ++ weather_debug("astro->solarmidnight_elevation=%f\n", ++ astro->solarmidnight_elevation); ++ + if (sun_rises) + astro->sun_never_rises = FALSE; + else + astro->sun_never_rises = TRUE; ++ + if (sun_sets) + astro->sun_never_sets = FALSE; + else + astro->sun_never_sets = TRUE; + +- if (moon_rises) +- astro->moon_never_rises = FALSE; +- else +- astro->moon_never_rises = TRUE; +- if (moon_sets) +- astro->moon_never_sets = FALSE; +- else +- astro->moon_never_sets = TRUE; +- return astro; ++ merge_astro(astrodata, astro); ++ xml_astro_free(astro); ++ return TRUE; + } + + + /* +- * Look at https://api.met.no/weatherapi/sunrise/2.0/schema for information ++ * Look at https://docs.api.met.no/doc/formats/SunriseJSON for information + * of elements and attributes to expect. + */ + gboolean +-parse_astrodata(xmlNode *cur_node, +- GArray *astrodata) ++parse_astrodata_moon(json_object *cur_node, ++ GArray *astrodata) + { +- xmlNode *child_node; + xml_astro *astro; ++ json_object *jwhen, *jinterval, *jproperties, *jdate, *jmoonrise, ++ *jmoonrise_time, *jmoonset, *jmoonset_time, *jmoonphase; ++ time_t day; ++ guint index; ++ const gchar day_format[]="%Y-%m-%dT%H:%M:%SZ"; ++ const gchar moon_format[]="%Y-%m-%dT%H:%MZ"; ++ const gchar *date, *time; ++ gboolean moon_rises = FALSE, moon_sets = FALSE; + + g_assert(astrodata != NULL); + if (G_UNLIKELY(astrodata == NULL)) + return FALSE; + +- g_assert(cur_node != NULL); +- if (G_UNLIKELY(cur_node == NULL || +- !NODE_IS_TYPE(cur_node, "location"))) ++ jwhen = json_object_object_get(cur_node, "when"); ++ if (G_UNLIKELY(jwhen == NULL)) { ++ weather_debug("when not found" ); + return FALSE; ++ } + +- for (child_node = cur_node->children; child_node; +- child_node = child_node->next) +- if (NODE_IS_TYPE(child_node, "time")) { +- if ((astro = parse_astro_time(child_node))) { +- merge_astro(astrodata, astro); +- xml_astro_free(astro); +- } +- } ++ jinterval = json_object_object_get(jwhen, "interval"); ++ if (G_UNLIKELY(jinterval == NULL)) { ++ weather_debug("interval not found" ); ++ return FALSE; ++ } ++ if (G_UNLIKELY(json_object_array_length(jinterval)!=2)) { ++ weather_debug("interval length is %d instead of %d", ++ json_object_array_length(jinterval)); ++ return FALSE; ++ } ++ ++ jdate = json_object_array_get_idx(jinterval, 0); ++ if (G_UNLIKELY(jdate == NULL)) { ++ weather_debug("jdate empty" ); ++ return FALSE; ++ } ++ ++ date = json_object_get_string(jdate); ++ if (G_UNLIKELY(date == NULL)) { ++ weather_debug("date not found" ); ++ return FALSE; ++ } ++ ++ /* use time info at center of day interval */ ++ day = day_at_midnight(parse_timestring(date, day_format, FALSE) + 12 * 3600, 0); ++ /* this data seems weird */ ++ astro = get_astro(astrodata, day, &index); ++ if (G_UNLIKELY(astro == NULL)) { ++ weather_debug("no sun astrodata for day=%s\n", ++ format_date(day, day_format,FALSE)); ++ return FALSE; ++ } ++ ++ astro->day=day; ++ weather_debug("moon: astro->day=%s\n", format_date(astro->day, day_format,TRUE)); ++ ++ jproperties = json_object_object_get(cur_node, "properties"); ++ if (G_UNLIKELY(jproperties == NULL)) { ++ weather_debug("properties not found" ); ++ return FALSE; ++ } ++ ++ jmoonrise = json_object_object_get(jproperties, "moonrise"); ++ if (G_UNLIKELY(jmoonrise == NULL)) { ++ weather_debug("moonrise not found" ); ++ return FALSE; ++ } ++ ++ jmoonrise_time = json_object_object_get(jmoonrise, "time"); ++ if (G_UNLIKELY(jmoonrise_time == NULL)) { ++ weather_debug("moonrise time not found" ); ++ } else { ++ date = json_object_get_string(jmoonrise_time); ++ if (G_UNLIKELY(date == NULL)) { ++ weather_debug("jmoonrise_time empty" ); ++ return FALSE; ++ } ++ time = remove_timezone_offset(date); ++ astro->moonrise= parse_timestring(time, moon_format, TRUE); ++ moon_rises = TRUE; ++ weather_debug("astro->moonrise=%s\n", ++ format_date(astro->moonrise, NULL,TRUE)); ++ } ++ ++ jmoonset = json_object_object_get(jproperties, "moonset"); ++ if (G_UNLIKELY(jmoonset == NULL)) { ++ weather_debug("moonset not found" ); ++ return FALSE; ++ } ++ jmoonset_time = json_object_object_get(jmoonset, "time"); ++ if (G_UNLIKELY(jmoonset_time == NULL)) { ++ weather_debug("moonset time not found" ); ++ } else { ++ date = json_object_get_string(jmoonset_time); ++ if (G_UNLIKELY(date == NULL)) { ++ weather_debug("moonset time empty" ); ++ return FALSE; ++ } ++ time = remove_timezone_offset(date); ++ astro->moonset= parse_timestring(time, moon_format, TRUE); ++ moon_sets = TRUE; ++ weather_debug("astro->moonset=%s\n", ++ format_date(astro->moonset, NULL,TRUE)); ++ } ++ ++ jmoonphase = json_object_object_get(jproperties, "moonphase"); ++ if (G_UNLIKELY(jmoonphase == NULL)) { ++ weather_debug("moonphase not found" ); ++ return FALSE; ++ } ++ astro->moon_phase =g_strdup(parse_moonposition( json_object_get_double(jmoonphase))); ++ weather_debug("astro->moonphase=%s\n",astro->moon_phase); ++ ++ if (moon_rises) ++ astro->moon_never_rises = FALSE; ++ else ++ astro->moon_never_rises = TRUE; ++ if (moon_sets) ++ astro->moon_never_sets = FALSE; ++ else ++ astro->moon_never_sets = TRUE; ++ ++ merge_astro(astrodata, astro); + return TRUE; + } + +@@ -664,6 +801,19 @@ get_xml_document(SoupMessage *msg) + return NULL; + } + ++json_object * ++get_json_tree(SoupMessage *msg) ++{ ++ json_object *res=NULL; ++ enum json_tokener_error err; ++ ++ if (G_LIKELY(msg && msg->response_body && msg->response_body->data)) { ++ res = json_tokener_parse_verbose(msg->response_body->data, &err); ++ if (err != json_tokener_success) ++ g_warning("get_json_tree: error =%d",err); ++ } ++ return res; ++} + + gpointer + parse_xml_document(SoupMessage *msg, +--- a/panel-plugin/weather-parsers.h ++++ b/panel-plugin/weather-parsers.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #define DATA_EXPIRY_TIME (24 * 3600) + +@@ -133,10 +134,11 @@ time_t parse_timestring(const gchar *ts, + gboolean parse_weather(xmlNode *cur_node, + xml_weather *wd); + +-xml_astro *parse_astro(xmlNode *cur_node); ++gboolean parse_astrodata_sun(json_object *cur_node, ++ GArray *astrodata); + +-gboolean parse_astrodata(xmlNode *cur_node, +- GArray *astrodata); ++gboolean parse_astrodata_moon(json_object *cur_node, ++ GArray *astrodata); + + xml_geolocation *parse_geolocation(xmlNode *cur_node); + +@@ -157,6 +159,8 @@ xml_astro *get_astro(const GArray *astro + + xmlDoc *get_xml_document(SoupMessage *msg); + ++json_object *get_json_tree(SoupMessage *msg); ++ + gpointer parse_xml_document(SoupMessage *msg, + XmlParseFunc parse_func); + +--- a/panel-plugin/weather.c ++++ b/panel-plugin/weather.c +@@ -29,6 +29,7 @@ + + #include + #include ++#include + + #include "weather-parsers.h" + #include "weather-data.h" +@@ -397,8 +398,10 @@ update_current_astrodata(plugin_data *da + data->current_astro = get_astro_data_for_day(data->astrodata, 0); + if (G_UNLIKELY(data->current_astro == NULL)) + weather_debug("No current astrodata available."); +- else ++ else { + weather_debug("Updated current astrodata."); ++ weather_debug("%s",weather_dump_astro(data->current_astro)); ++ } + } + } + +@@ -435,7 +438,7 @@ update_current_conditions(plugin_data *d + + /* update current astrodata */ + update_current_astrodata(data); +- data->night_time = is_night_time(data->current_astro); ++ data->night_time = is_night_time(data->current_astro, data->offset); + + /* update widgets */ + update_icon(data); +@@ -474,71 +477,134 @@ calc_next_download_time(const update_inf + interval = upi->check_interval; + } + ++ weather_debug("interval=%d", interval); ++ + return time_calc(retry_tm, 0, 0, 0, 0, 0, interval); + } + +- + /* +- * Process downloaded astro data and schedule next astro update. ++ * Process downloaded sun astro data and schedule next astro update. + */ + static void +-cb_astro_update(SoupSession *session, +- SoupMessage *msg, +- gpointer user_data) ++cb_astro_update_sun(SoupSession *session, ++ SoupMessage *msg, ++ gpointer user_data) + { + plugin_data *data = user_data; +- xmlDoc *doc; +- xmlNode *root_node, *child_node; ++ json_object *json_tree; + time_t now_t; +- gboolean parsing_error = TRUE; + +- time(&now_t); +- data->astro_update->attempt++; ++ data->msg_parse->sun_msg_processed++; + data->astro_update->http_status_code = msg->status_code; + if ((msg->status_code == 200 || msg->status_code == 203)) { +- doc = get_xml_document(msg); +- if (G_LIKELY(doc)) { +- root_node = xmlDocGetRootElement(doc); +- if (G_LIKELY(root_node)) { +- for (child_node = root_node->children; child_node; +- child_node = child_node->next) { +- if (child_node->type == XML_ELEMENT_NODE) { +- if (parse_astrodata(child_node, data->astrodata)) { +- /* schedule next update */ +- data->astro_update->attempt = 0; +- data->astro_update->last = now_t; +- parsing_error = FALSE; +- } +- } +- } ++ json_tree = get_json_tree(msg); ++ if (G_LIKELY(json_tree)) { ++ if (!parse_astrodata_sun(json_tree, data->astrodata)) { ++ data->msg_parse->sun_msg_parse_error++; ++ g_warning("Error parsing sun astronomical data!"); ++ weather_debug("data->astrodata:%s", ++ weather_dump_astrodata(data->astrodata)); ++ } else { ++ weather_dump(weather_dump_astrodata, data->astrodata); + } +- xmlFreeDoc(doc); ++ g_assert(json_object_put(json_tree) ==1); ++ } else { ++ g_warning(_("Error parsing sun astronomical data!")); ++ weather_debug("No json_tree"); + } +- if (parsing_error) +- g_warning("Error parsing astronomical data!"); + } else { ++ data->msg_parse->http_msg_fail = TRUE; + #if GLIB_CHECK_VERSION (2, 64, 0) +- g_warning_once("Download of astronomical data failed with HTTP Status Code %d, Reason phrase: %s", ++ g_warning_once("Download of sun astronomical data failed with HTTP Status Code %d, Reason phrase: %s", + msg->status_code, msg->reason_phrase); + #else +- g_warning("Download of astronomical data failed with HTTP Status Code %d, Reason phrase: %s", ++ g_warning("Download of sun astronomical data failed with HTTP Status Code %d, Reason phrase: %s", + msg->status_code, msg->reason_phrase); + #endif + } +- data->astro_update->next = calc_next_download_time(data->astro_update, +- now_t); + +- astrodata_clean(data->astrodata); +- g_array_sort(data->astrodata, (GCompareFunc) xml_astro_compare); +- update_current_astrodata(data); +- if (! parsing_error) +- weather_dump(weather_dump_astrodata, data->astrodata); ++ if (data->msg_parse->sun_msg_processed == ASTRO_FORECAST_DAYS) { ++ if (G_LIKELY(data->msg_parse->sun_msg_parse_error == 0 && !data->msg_parse->http_msg_fail)) { ++ data->msg_parse->astro_dwnld_state = ASTRO_DWNLD_MOON; ++ time(&now_t); ++ /* schedule astro moon data downloads immediately */ ++ data->astro_update->next = now_t; ++ weather_debug( "astro moon data update scheduled! \n"); ++ schedule_next_wakeup(data); ++ } else { ++ data->msg_parse->astro_dwnld_state = ASTRO_DWNLD_SUN; ++ weather_debug( "astro sun data update failed! \n"); ++ time(&now_t); ++ data->astro_update->next = calc_next_download_time(data->astro_update,now_t); ++ } ++ } ++} + +- /* update icon */ +- data->night_time = is_night_time(data->current_astro); +- update_icon(data); + +- data->astro_update->finished = TRUE; ++/* ++ * Process downloaded moon astro data and schedule next astro update. ++ */ ++static void ++cb_astro_update_moon(SoupSession *session, ++ SoupMessage *msg, ++ gpointer user_data) ++{ ++ plugin_data *data = user_data; ++ json_object *json_tree; ++ time_t now_t; ++ ++ data->msg_parse->moon_msg_processed++; ++ data->astro_update->http_status_code = msg->status_code; ++ if ((msg->status_code == 200 || msg->status_code == 203)) { ++ json_tree = get_json_tree(msg); ++ if (G_LIKELY(json_tree)) { ++ if (!parse_astrodata_moon(json_tree, data->astrodata)) { ++ data->msg_parse->moon_msg_parse_error++; ++ g_warning(_("Error parsing moon astronomical data")); ++ weather_debug("data->astrodata:%s", ++ weather_dump_astrodata(data->astrodata)); ++ } else { ++ weather_dump(weather_dump_astrodata, data->astrodata); ++ } ++ g_assert(json_object_put(json_tree) ==1); ++ } else { ++ g_warning(_("Error parsing moon astronomical data")); ++ weather_debug("No json_tree"); ++ } ++ } else { ++ data->msg_parse->http_msg_fail = TRUE; ++#if GLIB_CHECK_VERSION (2, 64, 0) ++ g_warning_once("Download of moon astronomical data failed with HTTP Status Code %d, Reason phrase: %s", ++ msg->status_code, msg->reason_phrase); ++#else ++ g_warning("Download of moon astronomical data failed with HTTP Status Code %d, Reason phrase: %s", ++ msg->status_code, msg->reason_phrase); ++#endif ++ } ++ ++ if (data->msg_parse->sun_msg_processed == ASTRO_FORECAST_DAYS && data->msg_parse->moon_msg_processed == ASTRO_FORECAST_DAYS) { ++ if (G_LIKELY(data->msg_parse->moon_msg_parse_error == 0 && !data->msg_parse->http_msg_fail)) { ++ astrodata_clean(data->astrodata); ++ g_array_sort(data->astrodata, (GCompareFunc) xml_astro_compare); ++ data->astro_update->attempt = 0; ++ weather_debug( "astro sun data update scheduled! \n"); ++ time(&now_t); ++ data->astro_update->last = now_t; ++ data->astro_update->next = calc_next_download_time(data->astro_update,now_t); ++ update_current_astrodata(data); ++ /* update icon */ ++ data->night_time = is_night_time(data->current_astro, data->offset); ++ update_icon(data); ++ data->astro_update->finished = TRUE; ++ data->msg_parse->astro_dwnld_state = ASTRO_DWNLD_SUN; ++ } else { ++ data->msg_parse->astro_dwnld_state = ASTRO_DWNLD_MOON; ++ weather_debug( "astro moon data update failed! \n"); ++ time(&now_t); ++ data->astro_update->next = calc_next_download_time(data->astro_update,now_t); ++ data->astro_update->attempt++; ++ } ++ } + } + + +@@ -600,8 +666,10 @@ update_handler(gpointer user_data) + gchar *api_version = FORECAST_API; + gchar *url; + gboolean night_time; +- time_t now_t; ++ time_t now_t, day_t; + struct tm now_tm; ++ guint day; ++ dwnld_state astro_dwnld_state = data->msg_parse->astro_dwnld_state; + + g_assert(data != NULL); + if (G_UNLIKELY(data == NULL)) +@@ -633,26 +701,64 @@ update_handler(gpointer user_data) + if (difftime(data->astro_update->next, now_t) <= 0) { + /* real next update time will be calculated when update is finished, + this is to prevent spawning multiple updates in a row */ +- data->astro_update->next = time_calc_hour(now_tm, 1); +- data->astro_update->started = TRUE; +- +- /* build url */ +- url = g_strdup_printf("https://api.met.no/weatherapi" +- "/sunrise/2.0/?lat=%s&lon=%s&" +- "date=%04d-%02d-%02d&" +- "offset=%s&days=%u", +- data->lat, data->lon, +- now_tm.tm_year + 1900, +- now_tm.tm_mon + 1, +- now_tm.tm_mday, +- data->offset, +- data->forecast_days); ++ weather_debug("Fetching astronomical data. State: %s.\n", (int)astro_dwnld_state ? "ASTRO_DWNLD_MOON" : "ASTRO_DWNLD_SUN"); ++ switch (astro_dwnld_state) { ++ case ASTRO_DWNLD_SUN: ++ data->astro_update->next = time_calc_hour(now_tm, 1); ++ data->astro_update->started = TRUE; ++ data->astro_update->attempt++; ++ data->msg_parse->sun_msg_processed = 0; ++ data->msg_parse->moon_msg_processed = 0; ++ data->msg_parse->moon_msg_parse_error = 0; ++ data->msg_parse->sun_msg_parse_error = 0; ++ data->msg_parse->http_msg_fail = FALSE; ++ /* forecast astronomical data one day in advance */ ++ for (day = 0; day < ASTRO_FORECAST_DAYS; day++) { ++ day_t = day_at_midnight(now_t, day); ++ now_tm = *localtime(&day_t); ++ /* build url */ ++ url = g_strdup_printf("https://api.met.no/weatherapi" ++ "/sunrise/3.0/sun?lat=%s&lon=%s&" ++ "date=%04d-%02d-%02d&" ++ "offset=%s", ++ data->lat, data->lon, ++ now_tm.tm_year + 1900, ++ now_tm.tm_mon + 1, ++ now_tm.tm_mday, ++ data->offset ++ ); ++ /* start receive thread */ ++ weather_debug("getting sun data:%s", url); ++ weather_http_queue_request(data->session, url, ++ cb_astro_update_sun, data); ++ g_free(url); ++ } ++ break; + +- /* start receive thread */ +- weather_debug("getting %s", url); +- weather_http_queue_request(data->session, url, +- cb_astro_update, data); +- g_free(url); ++ case ASTRO_DWNLD_MOON: ++ data->msg_parse->http_msg_fail = FALSE; ++ data->astro_update->next = time_calc_hour(now_tm, 1); ++ for (day = 0; day < ASTRO_FORECAST_DAYS; day++) { ++ day_t = day_at_midnight(now_t, day); ++ now_tm = *localtime(&day_t); ++ url = g_strdup_printf("https://api.met.no/weatherapi" ++ "/sunrise/3.0/moon?lat=%s&lon=%s&" ++ "date=%04d-%02d-%02d&" ++ "offset=%s", ++ data->lat, data->lon, ++ now_tm.tm_year + 1900, ++ now_tm.tm_mon + 1, ++ now_tm.tm_mday, ++ data->offset ++ ); ++ /* start receive thread */ ++ weather_debug("getting moon data: %s", url); ++ weather_http_queue_request(data->session, url, ++ cb_astro_update_moon, data); ++ g_free(url); ++ } ++ break; ++ } + } + + /* fetch weather data */ +@@ -694,7 +800,7 @@ update_handler(gpointer user_data) + + /* update night time status and icon */ + update_current_astrodata(data); +- night_time = is_night_time(data->current_astro); ++ night_time = is_night_time(data->current_astro, data->offset); + if (data->night_time != night_time) { + weather_debug("Night time status changed, updating icon."); + data->night_time = night_time; +@@ -1306,8 +1412,6 @@ read_cache_file(plugin_data *data) + i = 0; + group = g_strdup_printf("astrodata%d", i); + while (g_key_file_has_group(keyfile, group)) { +- if (i == 0) +- weather_debug("Reusing cached astrodata instead of downloading it."); + + astro = g_slice_new0(xml_astro); + if (G_UNLIKELY(astro == NULL)) +@@ -1315,6 +1419,8 @@ read_cache_file(plugin_data *data) + + CACHE_READ_STRING(timestring, "day"); + astro->day = parse_timestring(timestring, "%Y-%m-%d", TRUE); ++ weather_debug("cached astrodata for day=%s\n", ++ format_date(astro->day, NULL, TRUE)); + g_free(timestring); + CACHE_READ_STRING(timestring, "sunrise"); + astro->sunrise = parse_timestring(timestring, NULL, TRUE); +@@ -1349,6 +1455,16 @@ read_cache_file(plugin_data *data) + g_free(group); + group = g_strdup_printf("astrodata%d", ++i); + } ++ ++ /* downloads the astrodata of the day if necessary */ ++ if (G_LIKELY(get_astro_data_for_day(data->astrodata, DEFAULT_FORECAST_DAYS))) ++ weather_debug("Reusing cached astrodata instead of downloading it."); ++ else { ++ weather_debug("Astrodata of the day not in cache. Downloading scheduled in 30s."); ++ data->astro_update->attempt = 0; ++ data->astro_update->next = now_t += 30; ++ schedule_next_wakeup(data); ++ } + g_free(group); + group = NULL; + +@@ -1926,6 +2042,11 @@ xfceweather_create_control(XfcePanelPlug + data->single_row = TRUE; + data->power_saving = TRUE; + ++ /* Setup Message parse infos */ ++ if (data->msg_parse) ++ g_slice_free(parse_info, data->msg_parse); ++ data->msg_parse = g_slice_new0(parse_info); ++ + /* Setup update infos */ + init_update_infos(data); + data->next_wakeup = time(NULL); +--- a/panel-plugin/weather.h ++++ b/panel-plugin/weather.h +@@ -31,6 +31,7 @@ + #define PLUGIN_WEBSITE "https://docs.xfce.org/panel-plugins/xfce4-weather-plugin" + #define MAX_FORECAST_DAYS 10 + #define DEFAULT_FORECAST_DAYS 5 ++#define ASTRO_FORECAST_DAYS (DEFAULT_FORECAST_DAYS + 1) + #define MAX_SCROLLBOX_LINES 10 + #define FORECAST_API "2.0" + +@@ -93,6 +94,20 @@ typedef struct { + guint http_status_code; + } update_info; + ++typedef enum { ++ ASTRO_DWNLD_SUN = 0, ++ ASTRO_DWNLD_MOON ++} dwnld_state; ++ ++typedef struct { ++ guint sun_msg_processed; ++ guint moon_msg_processed; ++ guint sun_msg_parse_error; ++ guint moon_msg_parse_error; ++ dwnld_state astro_dwnld_state; ++ gboolean http_msg_fail; ++} parse_info; ++ + typedef struct { + XfcePanelPlugin *plugin; + XfconfChannel *channel; +@@ -130,6 +145,7 @@ typedef struct { + update_info *astro_update; + update_info *weather_update; + update_info *conditions_update; ++ parse_info *msg_parse; + time_t next_wakeup; + gchar *next_wakeup_reason; + guint update_timer; diff --git a/srcpkgs/xfce4-weather-plugin/patches/0006-Fix-leaks-around-remove_timezone_offset.patch b/srcpkgs/xfce4-weather-plugin/patches/0006-Fix-leaks-around-remove_timezone_offset.patch new file mode 100644 index 00000000000000..6902bba9acb648 --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0006-Fix-leaks-around-remove_timezone_offset.patch @@ -0,0 +1,68 @@ +From a86b1293772a6d62e5e34bc56551b3edb8f931b3 Mon Sep 17 00:00:00 2001 +From: Gaël Bonithon +Date: Thu, 29 Feb 2024 17:21:10 +0100 +Subject: [PATCH 6/8] Fix leaks around remove_timezone_offset() + +Spotted at the time of !24 and now fixed after !27. + +(cherry picked from commit 55734b4e978c22a747fbcdcda1faa037e2cd02a4) +--- + panel-plugin/weather-parsers.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c +index 1121aca..0ea5774 100644 +--- a/panel-plugin/weather-parsers.c ++++ b/panel-plugin/weather-parsers.c +@@ -430,7 +430,8 @@ parse_astrodata_sun(json_object *cur_node, + *jsolarnoon, *jsolarmidnight, *jdisc_centre_elevation; + const gchar day_format[]="%Y-%m-%dT%H:%M:%SZ"; + const gchar sun_format[]="%Y-%m-%dT%H:%MZ"; +- const gchar *date, *time; ++ const gchar *date; ++ gchar *time; + gboolean sun_rises = FALSE, sun_sets = FALSE; + + astro = g_slice_new0(xml_astro); +@@ -484,6 +485,7 @@ parse_astrodata_sun(json_object *cur_node, + sun_rises = TRUE; + weather_debug("astro->sunrise=%s\n", + format_date(astro->sunrise, NULL,TRUE)); ++ g_free(time); + } + + jsunset = json_object_object_get(jproperties, "sunset"); +@@ -502,6 +504,7 @@ parse_astrodata_sun(json_object *cur_node, + sun_sets = TRUE; + weather_debug("astro->sunset=%s\n", + format_date(astro->sunset, NULL,TRUE)); ++ g_free(time); + } + + jsolarnoon = json_object_object_get(jproperties, "solarnoon"); +@@ -559,7 +562,8 @@ parse_astrodata_moon(json_object *cur_node, + guint index; + const gchar day_format[]="%Y-%m-%dT%H:%M:%SZ"; + const gchar moon_format[]="%Y-%m-%dT%H:%MZ"; +- const gchar *date, *time; ++ const gchar *date; ++ gchar *time; + gboolean moon_rises = FALSE, moon_sets = FALSE; + + g_assert(astrodata != NULL); +@@ -634,6 +638,7 @@ parse_astrodata_moon(json_object *cur_node, + moon_rises = TRUE; + weather_debug("astro->moonrise=%s\n", + format_date(astro->moonrise, NULL,TRUE)); ++ g_free(time); + } + + jmoonset = json_object_object_get(jproperties, "moonset"); +@@ -655,6 +660,7 @@ parse_astrodata_moon(json_object *cur_node, + moon_sets = TRUE; + weather_debug("astro->moonset=%s\n", + format_date(astro->moonset, NULL,TRUE)); ++ g_free(time); + } + + jmoonphase = json_object_object_get(jproperties, "moonphase"); diff --git a/srcpkgs/xfce4-weather-plugin/patches/0007-parsers-Generalise-input-to-array-of-gchar.patch b/srcpkgs/xfce4-weather-plugin/patches/0007-parsers-Generalise-input-to-array-of-gchar.patch new file mode 100644 index 00000000000000..948f8e89658c77 --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0007-parsers-Generalise-input-to-array-of-gchar.patch @@ -0,0 +1,261 @@ +From b5287b0cc738c53846f0752dbd76618177733246 Mon Sep 17 00:00:00 2001 +From: Đoàn Trần Công Danh +Date: Fri, 1 Mar 2024 21:56:34 +0700 +Subject: [PATCH 7/8] parsers: Generalise input to array of gchar + +In a later change, we will move to libsoup-3.0, which doesn't expose +`response_body' in SoupMessage. + +Prepare for that move. + +(cherry picked from commit eaa54cc7305fa0bdeeed36f724bc7cd9075bf37d) +--- + panel-plugin/weather-config.c | 18 ++++++++++++++++-- + panel-plugin/weather-parsers.c | 26 ++++++++++++-------------- + panel-plugin/weather-parsers.h | 7 +++---- + panel-plugin/weather-search.c | 18 ++++++++++++++++-- + panel-plugin/weather.c | 26 ++++++++++++++++++++++---- + 5 files changed, 69 insertions(+), 26 deletions(-) + +diff --git a/panel-plugin/weather-config.c b/panel-plugin/weather-config.c +index de4123e..f26ce77 100644 +--- a/panel-plugin/weather-config.c ++++ b/panel-plugin/weather-config.c +@@ -241,9 +241,16 @@ cb_lookup_altitude(SoupSession *session, + xfceweather_dialog *dialog = (xfceweather_dialog *) user_data; + xml_altitude *altitude; + gdouble alt = 0; ++ const gchar *body = NULL; ++ gsize len = 0; ++ ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } + + altitude = (xml_altitude *) +- parse_xml_document(msg, (XmlParseFunc) parse_altitude); ++ parse_xml_document(body, len, (XmlParseFunc) parse_altitude); + + if (altitude) { + alt = string_to_double(altitude->altitude, -9999); +@@ -265,9 +272,16 @@ cb_lookup_timezone(SoupSession *session, + { + xfceweather_dialog *dialog = (xfceweather_dialog *) user_data; + xml_timezone *xml_tz; ++ const gchar *body = NULL; ++ gsize len = 0; ++ ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } + + xml_tz = (xml_timezone *) +- parse_xml_document(msg, (XmlParseFunc) parse_timezone); ++ parse_xml_document(body, len, (XmlParseFunc) parse_timezone); + weather_dump(weather_dump_timezone, xml_tz); + + if (xml_tz) { +diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c +index 0ea5774..422d64e 100644 +--- a/panel-plugin/weather-parsers.c ++++ b/panel-plugin/weather-parsers.c +@@ -791,30 +791,28 @@ parse_timezone(xmlNode *cur_node) + + + xmlDoc * +-get_xml_document(SoupMessage *msg) ++get_xml_document(const gchar *data, gsize len) + { +- if (G_LIKELY(msg && msg->response_body && msg->response_body->data)) { +- if (g_utf8_validate(msg->response_body->data, -1, NULL)) { ++ if (G_LIKELY(data && len)) { ++ if (g_utf8_validate(data, len, NULL)) { + /* force parsing as UTF-8, the XML encoding header may lie */ +- return xmlReadMemory(msg->response_body->data, +- strlen(msg->response_body->data), ++ return xmlReadMemory(data, len, + NULL, "UTF-8", 0); + } else { +- return xmlParseMemory(msg->response_body->data, +- strlen(msg->response_body->data)); ++ return xmlParseMemory(data, len); + } + } + return NULL; + } + + json_object * +-get_json_tree(SoupMessage *msg) ++get_json_tree(const gchar *data, gsize len) + { + json_object *res=NULL; + enum json_tokener_error err; + +- if (G_LIKELY(msg && msg->response_body && msg->response_body->data)) { +- res = json_tokener_parse_verbose(msg->response_body->data, &err); ++ if (G_LIKELY(data && len)) { ++ res = json_tokener_parse_verbose(data, &err); + if (err != json_tokener_success) + g_warning("get_json_tree: error =%d",err); + } +@@ -822,18 +820,18 @@ get_json_tree(SoupMessage *msg) + } + + gpointer +-parse_xml_document(SoupMessage *msg, ++parse_xml_document(const gchar *data, gsize len, + XmlParseFunc parse_func) + { + xmlDoc *doc; + xmlNode *root_node; + gpointer user_data = NULL; + +- g_assert(msg != NULL); +- if (G_UNLIKELY(msg == NULL)) ++ g_assert(data != NULL); ++ if (G_UNLIKELY(data == NULL || len == 0)) + return NULL; + +- doc = get_xml_document(msg); ++ doc = get_xml_document(data, len); + if (G_LIKELY(doc)) { + root_node = xmlDocGetRootElement(doc); + if (G_LIKELY(root_node)) +diff --git a/panel-plugin/weather-parsers.h b/panel-plugin/weather-parsers.h +index 33604f2..e274b04 100644 +--- a/panel-plugin/weather-parsers.h ++++ b/panel-plugin/weather-parsers.h +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + + #define DATA_EXPIRY_TIME (24 * 3600) +@@ -157,11 +156,11 @@ xml_astro *get_astro(const GArray *astrodata, + const time_t day_t, + guint *index); + +-xmlDoc *get_xml_document(SoupMessage *msg); ++xmlDoc *get_xml_document(const gchar *data, gsize len); + +-json_object *get_json_tree(SoupMessage *msg); ++json_object *get_json_tree(const gchar *data, gsize len); + +-gpointer parse_xml_document(SoupMessage *msg, ++gpointer parse_xml_document(const gchar *data, gsize len, + XmlParseFunc parse_func); + + xml_astro *xml_astro_copy(const xml_astro *src); +diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c +index 0e74e7e..0b02ebe 100644 +--- a/panel-plugin/weather-search.c ++++ b/panel-plugin/weather-search.c +@@ -87,10 +87,17 @@ cb_searchdone(SoupSession *session, + gint found = 0; + GtkTreeIter iter; + GtkTreeSelection *selection; ++ const gchar *body = NULL; ++ gsize len = 0; ++ ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } + + gtk_widget_set_sensitive(dialog->find_button, TRUE); + +- doc = get_xml_document(msg); ++ doc = get_xml_document(body, len); + if (!doc) + return; + +@@ -375,9 +382,16 @@ cb_geolocation(SoupSession *session, + xml_geolocation *geo; + gchar *full_loc; + units_config *units; ++ const gchar *body = NULL; ++ gsize len = 0; ++ ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } + + geo = (xml_geolocation *) +- parse_xml_document(msg, (XmlParseFunc) parse_geolocation); ++ parse_xml_document(body, len, (XmlParseFunc) parse_geolocation); + weather_dump(weather_dump_geolocation, geo); + + if (!geo) { +diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c +index 0a483fa..cf783f6 100644 +--- a/panel-plugin/weather.c ++++ b/panel-plugin/weather.c +@@ -493,11 +493,17 @@ cb_astro_update_sun(SoupSession *session, + plugin_data *data = user_data; + json_object *json_tree; + time_t now_t; ++ const gchar *body = NULL; ++ gsize len = 0; + + data->msg_parse->sun_msg_processed++; + data->astro_update->http_status_code = msg->status_code; + if ((msg->status_code == 200 || msg->status_code == 203)) { +- json_tree = get_json_tree(msg); ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } ++ json_tree = get_json_tree(body, len); + if (G_LIKELY(json_tree)) { + if (!parse_astrodata_sun(json_tree, data->astrodata)) { + data->msg_parse->sun_msg_parse_error++; +@@ -552,11 +558,17 @@ cb_astro_update_moon(SoupSession *session, + plugin_data *data = user_data; + json_object *json_tree; + time_t now_t; ++ const gchar *body = NULL; ++ gsize len = 0; + + data->msg_parse->moon_msg_processed++; + data->astro_update->http_status_code = msg->status_code; + if ((msg->status_code == 200 || msg->status_code == 203)) { +- json_tree = get_json_tree(msg); ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } ++ json_tree = get_json_tree(body, len); + if (G_LIKELY(json_tree)) { + if (!parse_astrodata_moon(json_tree, data->astrodata)) { + data->msg_parse->moon_msg_parse_error++; +@@ -617,17 +629,23 @@ cb_weather_update(SoupSession *session, + gpointer user_data) + { + plugin_data *data = user_data; +- xmlDoc *doc; ++ xmlDoc *doc = NULL; + xmlNode *root_node; + time_t now_t; + gboolean parsing_error = TRUE; ++ const gchar *body = NULL; ++ gsize len = 0; + + weather_debug("Processing downloaded weather data."); + time(&now_t); + data->weather_update->attempt++; + data->weather_update->http_status_code = msg->status_code; + if (msg->status_code == 200 || msg->status_code == 203) { +- doc = get_xml_document(msg); ++ if (G_LIKELY(msg->response_body && msg->response_body->data)) { ++ body = msg->response_body->data; ++ len = msg->response_body->length; ++ } ++ doc = get_xml_document(body, len); + if (G_LIKELY(doc)) { + root_node = xmlDocGetRootElement(doc); + if (G_LIKELY(root_node)) diff --git a/srcpkgs/xfce4-weather-plugin/patches/0008-libsoup-Port-to-libsoup-3.0.patch b/srcpkgs/xfce4-weather-plugin/patches/0008-libsoup-Port-to-libsoup-3.0.patch new file mode 100644 index 00000000000000..0cde60ea70cc6e --- /dev/null +++ b/srcpkgs/xfce4-weather-plugin/patches/0008-libsoup-Port-to-libsoup-3.0.patch @@ -0,0 +1,557 @@ +From e21463a147622803aed5faa9805331b89a255038 Mon Sep 17 00:00:00 2001 +From: Đoàn Trần Công Danh +Date: Fri, 1 Mar 2024 21:56:34 +0700 +Subject: [PATCH 8/8] libsoup: Port to libsoup-3.0 + +(cherry picked from commit edab1247c84c6d2824d15af6583f4da597b036c3) +--- + README | 4 +- + configure.ac.in | 2 +- + panel-plugin/weather-config.c | 32 ++++--- + panel-plugin/weather-search.c | 37 +++++--- + panel-plugin/weather-summary.c | 23 +++-- + panel-plugin/weather.c | 157 ++++++++++++++------------------- + panel-plugin/weather.h | 2 +- + 7 files changed, 132 insertions(+), 125 deletions(-) + +--- a/README ++++ b/README +@@ -152,10 +152,10 @@ using gdb or any other debugger should t + BUILD REQUIREMENTS AND DEPENDENCIES + ========================================================================== + To be able to build the plugin, the following requirements have to be +-met in addition to those of XFCE-4.14: ++met in addition to those of XFCE-4.16: + + * >=libxml-2.4.0 +-* >=libsoup-2.42.0 ++* >=libsoup-3.0.0 + * >=upower-0.9.0 (optional) + + You might also need developer libraries necessary for building other +--- a/configure.ac ++++ b/configure.ac +@@ -76,7 +76,7 @@ XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce + XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-2.0], [4.12.0]) + XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0]) + XDT_CHECK_PACKAGE([LIBXML], [libxml-2.0], [2.4.0]) +-XDT_CHECK_PACKAGE([SOUP], [libsoup-2.4], [2.42.0]) ++XDT_CHECK_PACKAGE([SOUP], [libsoup-3.0], [3.0.0]) + XDT_CHECK_PACKAGE([JSON], [json-c], [0.13.1]) + XDT_CHECK_OPTIONAL_PACKAGE([UPOWER_GLIB], [upower-glib], [0.9.0], [upower], + [upower for adapting update interval to power state]) +--- a/panel-plugin/weather-config.c ++++ b/panel-plugin/weather-config.c +@@ -234,8 +234,8 @@ sanitize_location_name(const gchar *loca + + + static void +-cb_lookup_altitude(SoupSession *session, +- SoupMessage *msg, ++cb_lookup_altitude(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + xfceweather_dialog *dialog = (xfceweather_dialog *) user_data; +@@ -243,11 +243,14 @@ cb_lookup_altitude(SoupSession *session, + gdouble alt = 0; + const gchar *body = NULL; + gsize len = 0; +- +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ GError *error = NULL; ++ GBytes *response = ++ soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error); ++ ++ if (G_UNLIKELY(error)) ++ g_error_free(error); ++ else ++ body = g_bytes_get_data(response, &len); + + altitude = (xml_altitude *) + parse_xml_document(body, len, (XmlParseFunc) parse_altitude); +@@ -262,23 +265,27 @@ cb_lookup_altitude(SoupSession *session, + else if (dialog->pd->units->altitude == FEET) + alt /= 0.3048; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_alt), alt); ++ g_bytes_unref(response); + } + + + static void +-cb_lookup_timezone(SoupSession *session, +- SoupMessage *msg, ++cb_lookup_timezone(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + xfceweather_dialog *dialog = (xfceweather_dialog *) user_data; + xml_timezone *xml_tz; + const gchar *body = NULL; + gsize len = 0; +- +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ GError *error = NULL; ++ GBytes *response = ++ soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error); ++ ++ if (G_UNLIKELY(error)) ++ g_error_free(error); ++ else ++ body = g_bytes_get_data(response, &len); + + xml_tz = (xml_timezone *) + parse_xml_document(body, len, (XmlParseFunc) parse_timezone); +@@ -290,6 +297,7 @@ cb_lookup_timezone(SoupSession *session, + xml_timezone_free(xml_tz); + } else + gtk_entry_set_text(GTK_ENTRY(dialog->text_timezone), ""); ++ g_bytes_unref(response); + } + + +--- a/panel-plugin/weather-search.c ++++ b/panel-plugin/weather-search.c +@@ -76,8 +76,8 @@ sanitize_str(const gchar *str) + + + static void +-cb_searchdone(SoupSession *session, +- SoupMessage *msg, ++cb_searchdone(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + search_dialog *dialog = (search_dialog *) user_data; +@@ -89,17 +89,22 @@ cb_searchdone(SoupSession *session, + GtkTreeSelection *selection; + const gchar *body = NULL; + gsize len = 0; +- +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ GError *error = NULL; ++ GBytes *response = ++ soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error); ++ ++ if (G_UNLIKELY(error)) ++ g_error_free(error); ++ else ++ body = g_bytes_get_data(response, &len); + + gtk_widget_set_sensitive(dialog->find_button, TRUE); + + doc = get_xml_document(body, len); +- if (!doc) ++ if (!doc) { ++ g_bytes_unref(response); + return; ++ } + + cur_node = xmlDocGetRootElement(doc); + if (cur_node) { +@@ -133,6 +138,7 @@ cb_searchdone(SoupSession *session, + } + + gtk_tree_view_column_set_title(dialog->column, _("Results")); ++ g_bytes_unref(response); + } + + +@@ -374,8 +380,8 @@ get_preferred_units(const gchar *country + + + static void +-cb_geolocation(SoupSession *session, +- SoupMessage *msg, ++cb_geolocation(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + geolocation_data *data = (geolocation_data *) user_data; +@@ -384,11 +390,14 @@ cb_geolocation(SoupSession *session, + units_config *units; + const gchar *body = NULL; + gsize len = 0; +- +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ GError *error = NULL; ++ GBytes *response = ++ soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error); ++ ++ if (G_UNLIKELY(error)) ++ g_error_free(error); ++ else ++ body = g_bytes_get_data(response, &len); + + geo = (xml_geolocation *) + parse_xml_document(body, len, (XmlParseFunc) parse_geolocation); +@@ -396,6 +405,7 @@ cb_geolocation(SoupSession *session, + + if (!geo) { + data->cb(NULL, NULL, NULL, NULL, data->user_data); ++ g_bytes_unref(response); + g_free(data); + return; + } +@@ -426,6 +436,7 @@ cb_geolocation(SoupSession *session, + g_slice_free(units_config, units); + xml_geolocation_free(geo); + g_free(full_loc); ++ g_bytes_unref(response); + g_free(data); + } + +--- a/panel-plugin/weather-summary.c ++++ b/panel-plugin/weather-summary.c +@@ -234,22 +234,29 @@ get_logo_path(void) + + + static void +-logo_fetched(SoupSession *session, +- SoupMessage *msg, ++logo_fetched(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { +- if (msg && msg->response_body && msg->response_body->length > 0) { ++ GError *error = NULL; ++ GBytes *response = ++ soup_session_send_and_read_finish(SOUP_SESSION(source), result, &error); ++ ++ if (G_LIKELY(error == NULL)) { ++ gsize len = 0; ++ const gchar *body = g_bytes_get_data(response, &len); + gchar *path = get_logo_path(); +- GError *error = NULL; + GdkPixbuf *pixbuf = NULL; + gint scale_factor; +- if (!g_file_set_contents(path, msg->response_body->data, +- msg->response_body->length, &error)) { ++ g_file_set_contents(path, body, len, &error); ++ g_bytes_unref(response); ++ if (error) { + g_warning("Error downloading met.no logo image to %s, " + "reason: %s\n", path, + error ? error->message : "unknown"); + g_error_free(error); + g_free(path); ++ g_bytes_unref(response); + return; + } + scale_factor = gtk_widget_get_scale_factor(user_data); +@@ -261,7 +268,9 @@ logo_fetched(SoupSession *session, + cairo_surface_destroy(surface); + g_object_unref(pixbuf); + } +- } ++ g_bytes_unref(response); ++ } else ++ g_error_free(error); + } + + +--- a/panel-plugin/weather.c ++++ b/panel-plugin/weather.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -106,13 +108,14 @@ static void schedule_next_wakeup(plugin_ + void + weather_http_queue_request(SoupSession *session, + const gchar *uri, +- SoupSessionCallback callback_func, ++ GAsyncReadyCallback callback_func, + gpointer user_data) + { + SoupMessage *msg; + + msg = soup_message_new("GET", uri); +- soup_session_queue_message(session, msg, callback_func, user_data); ++ soup_session_send_and_read_async(session, msg, G_PRIORITY_DEFAULT, NULL, ++ callback_func, user_data); + } + + +@@ -486,8 +489,8 @@ calc_next_download_time(const update_inf + * Process downloaded sun astro data and schedule next astro update. + */ + static void +-cb_astro_update_sun(SoupSession *session, +- SoupMessage *msg, ++cb_astro_update_sun(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + plugin_data *data = user_data; +@@ -495,14 +498,17 @@ cb_astro_update_sun(SoupSession *session + time_t now_t; + const gchar *body = NULL; + gsize len = 0; ++ SoupMessage *msg; ++ GError *error = NULL; ++ GBytes *response; + ++ msg = soup_session_get_async_result_message(SOUP_SESSION(source), result); + data->msg_parse->sun_msg_processed++; +- data->astro_update->http_status_code = msg->status_code; +- if ((msg->status_code == 200 || msg->status_code == 203)) { +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ data->astro_update->http_status_code = soup_message_get_status(msg); ++ response = soup_session_send_and_read_finish(SOUP_SESSION(source), ++ result, &error); ++ if (G_LIKELY(error == NULL)) { ++ body = g_bytes_get_data(response, &len); + json_tree = get_json_tree(body, len); + if (G_LIKELY(json_tree)) { + if (!parse_astrodata_sun(json_tree, data->astrodata)) { +@@ -518,15 +524,12 @@ cb_astro_update_sun(SoupSession *session + g_warning(_("Error parsing sun astronomical data!")); + weather_debug("No json_tree"); + } ++ g_bytes_unref(response); + } else { + data->msg_parse->http_msg_fail = TRUE; +-#if GLIB_CHECK_VERSION (2, 64, 0) +- g_warning_once("Download of sun astronomical data failed with HTTP Status Code %d, Reason phrase: %s", +- msg->status_code, msg->reason_phrase); +-#else +- g_warning("Download of sun astronomical data failed with HTTP Status Code %d, Reason phrase: %s", +- msg->status_code, msg->reason_phrase); +-#endif ++ g_warning_once("Download of sun astronomical data failed: %s", ++ error->message); ++ g_error_free(error); + } + + if (data->msg_parse->sun_msg_processed == ASTRO_FORECAST_DAYS) { +@@ -551,8 +554,8 @@ cb_astro_update_sun(SoupSession *session + * Process downloaded moon astro data and schedule next astro update. + */ + static void +-cb_astro_update_moon(SoupSession *session, +- SoupMessage *msg, ++cb_astro_update_moon(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + plugin_data *data = user_data; +@@ -560,14 +563,17 @@ cb_astro_update_moon(SoupSession *sessio + time_t now_t; + const gchar *body = NULL; + gsize len = 0; ++ SoupMessage *msg; ++ GError *error = NULL; ++ GBytes *response; + ++ msg = soup_session_get_async_result_message(SOUP_SESSION(source), result); + data->msg_parse->moon_msg_processed++; +- data->astro_update->http_status_code = msg->status_code; +- if ((msg->status_code == 200 || msg->status_code == 203)) { +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ data->astro_update->http_status_code = soup_message_get_status(msg); ++ response = soup_session_send_and_read_finish(SOUP_SESSION(source), ++ result, &error); ++ if (G_LIKELY(error == NULL)) { ++ body = g_bytes_get_data(response, &len); + json_tree = get_json_tree(body, len); + if (G_LIKELY(json_tree)) { + if (!parse_astrodata_moon(json_tree, data->astrodata)) { +@@ -583,15 +589,12 @@ cb_astro_update_moon(SoupSession *sessio + g_warning(_("Error parsing moon astronomical data")); + weather_debug("No json_tree"); + } ++ g_bytes_unref(response); + } else { + data->msg_parse->http_msg_fail = TRUE; +-#if GLIB_CHECK_VERSION (2, 64, 0) +- g_warning_once("Download of moon astronomical data failed with HTTP Status Code %d, Reason phrase: %s", +- msg->status_code, msg->reason_phrase); +-#else +- g_warning("Download of moon astronomical data failed with HTTP Status Code %d, Reason phrase: %s", +- msg->status_code, msg->reason_phrase); +-#endif ++ g_warning_once("Download of moon astronomical data failed: %s", ++ error->message); ++ g_error_free(error); + } + + if (data->msg_parse->sun_msg_processed == ASTRO_FORECAST_DAYS && data->msg_parse->moon_msg_processed == ASTRO_FORECAST_DAYS) { +@@ -624,8 +627,8 @@ cb_astro_update_moon(SoupSession *sessio + * Process downloaded weather data and schedule next weather update. + */ + static void +-cb_weather_update(SoupSession *session, +- SoupMessage *msg, ++cb_weather_update(GObject *source, ++ GAsyncResult *result, + gpointer user_data) + { + plugin_data *data = user_data; +@@ -635,16 +638,19 @@ cb_weather_update(SoupSession *session, + gboolean parsing_error = TRUE; + const gchar *body = NULL; + gsize len = 0; ++ SoupMessage *msg; ++ GError *error = NULL; ++ GBytes *response = NULL; + + weather_debug("Processing downloaded weather data."); ++ msg = soup_session_get_async_result_message(SOUP_SESSION(source), result); + time(&now_t); + data->weather_update->attempt++; +- data->weather_update->http_status_code = msg->status_code; +- if (msg->status_code == 200 || msg->status_code == 203) { +- if (G_LIKELY(msg->response_body && msg->response_body->data)) { +- body = msg->response_body->data; +- len = msg->response_body->length; +- } ++ data->weather_update->http_status_code = soup_message_get_status(msg); ++ response = soup_session_send_and_read_finish(SOUP_SESSION(source), ++ result, &error); ++ if (G_LIKELY(error == NULL)) { ++ body = g_bytes_get_data(response, &len); + doc = get_xml_document(body, len); + if (G_LIKELY(doc)) { + root_node = xmlDocGetRootElement(doc); +@@ -656,12 +662,13 @@ cb_weather_update(SoupSession *session, + } + xmlFreeDoc(doc); + } ++ g_bytes_unref(response); + if (parsing_error) + g_warning("Error parsing weather data!"); +- } else +- g_warning +- ("Download of weather data failed with HTTP Status Code %d, " +- "Reason phrase: %s", msg->status_code, msg->reason_phrase); ++ } else { ++ weather_debug("Download of weather data failed: %s", error->message); ++ g_error_free(error); ++ } + data->weather_update->next = calc_next_download_time(data->weather_update, + now_t); + +@@ -1719,32 +1726,6 @@ mi_click(GtkWidget *widget, + update_weatherdata_with_reset(data); + } + +-static void +-proxy_auth(SoupSession *session, +- SoupMessage *msg, +- SoupAuth *auth, +- gboolean retrying, +- gpointer user_data) +-{ +- SoupURI *soup_proxy_uri; +- const gchar *proxy_uri; +- +- if (!retrying) { +- if (msg->status_code == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED) { +- proxy_uri = g_getenv("HTTP_PROXY"); +- if (!proxy_uri) +- proxy_uri = g_getenv("http_proxy"); +- if (proxy_uri) { +- soup_proxy_uri = soup_uri_new(proxy_uri); +- soup_auth_authenticate(auth, +- soup_uri_get_user(soup_proxy_uri), +- soup_uri_get_password(soup_proxy_uri)); +- soup_uri_free(soup_proxy_uri); +- } +- } +- } +-} +- + + #ifdef HAVE_UPOWER_GLIB + static void +@@ -2031,9 +2012,10 @@ static plugin_data * + xfceweather_create_control(XfcePanelPlugin *plugin) + { + plugin_data *data = g_slice_new0(plugin_data); +- SoupURI *soup_proxy_uri; ++ GProxyResolver *proxy_resolver; + const gchar *proxy_uri; +- const gchar *proxy_user; ++ const gchar *no_proxy; ++ gchar **no_proxy_lst = NULL; + GtkWidget *refresh; + cairo_surface_t *icon = NULL; + data_types lbl; +@@ -2071,29 +2053,26 @@ xfceweather_create_control(XfcePanelPlug + + /* Setup session for HTTP connections */ + data->session = soup_session_new(); +- g_object_set(data->session, SOUP_SESSION_USER_AGENT, +- PACKAGE_NAME "-" PACKAGE_VERSION, NULL); +- g_object_set(data->session, SOUP_SESSION_TIMEOUT, +- CONN_TIMEOUT, NULL); ++ soup_session_set_user_agent(data->session, ++ PACKAGE_NAME "-" PACKAGE_VERSION); ++ soup_session_set_timeout(data->session, CONN_TIMEOUT); + + /* Set the proxy URI from environment */ + proxy_uri = g_getenv("HTTP_PROXY"); + if (!proxy_uri) + proxy_uri = g_getenv("http_proxy"); + if (proxy_uri) { +- soup_proxy_uri = soup_uri_new(proxy_uri); +- g_object_set(data->session, SOUP_SESSION_PROXY_URI, +- soup_proxy_uri, NULL); +- +- /* check if uri contains authentication info */ +- proxy_user = soup_uri_get_user(soup_proxy_uri); +- if (proxy_user && strlen(proxy_user) > 0) { +- g_signal_connect(G_OBJECT(data->session), "authenticate", +- G_CALLBACK(proxy_auth), NULL); +- } +- +- soup_uri_free(soup_proxy_uri); ++ no_proxy = g_getenv("no_proxy"); ++ if (!no_proxy) ++ no_proxy = g_getenv("NO_PROXY"); ++ if (no_proxy) ++ no_proxy_lst = g_strsplit(no_proxy, ",", -1); ++ proxy_resolver = g_simple_proxy_resolver_new(proxy_uri, no_proxy_lst); ++ g_strfreev(no_proxy_lst); ++ soup_session_set_proxy_resolver(data->session, proxy_resolver); ++ g_object_unref(proxy_resolver); + } ++ /* Otherwise, g_proxy_resolver_get_default() will be used */ + + data->scrollbox = gtk_scrollbox_new(); + +--- a/panel-plugin/weather.h ++++ b/panel-plugin/weather.h +@@ -184,7 +184,7 @@ extern gboolean debug_mode; + + void weather_http_queue_request(SoupSession *session, + const gchar *uri, +- SoupSessionCallback callback_func, ++ GAsyncReadyCallback callback_func, + gpointer user_data); + + void scrollbox_set_visible(plugin_data *data); diff --git a/srcpkgs/xfce4-weather-plugin/template b/srcpkgs/xfce4-weather-plugin/template index ef47f0f6143aa5..5f0d4e45772bc8 100644 --- a/srcpkgs/xfce4-weather-plugin/template +++ b/srcpkgs/xfce4-weather-plugin/template @@ -1,16 +1,21 @@ # Template file for 'xfce4-weather-plugin' pkgname=xfce4-weather-plugin -version=0.11.0 +version=0.11.1 revision=1 build_style=gnu-configure configure_args="--with-locales-dir=/usr/share/locale" -hostmakedepends="pkg-config intltool" -makedepends="libxfce4ui-devel xfce4-panel-devel libxml2-devel libsoup-devel upower-devel" +hostmakedepends="pkg-config intltool xfce4-dev-tools gettext-devel" +makedepends="libxfce4ui-devel xfce4-panel-devel libxml2-devel libsoup3-devel + json-c-devel upower-devel" depends="hicolor-icon-theme" short_desc="XFCE panel plugin to show temperature and weather" maintainer="Orphaned " license="GPL-2.0-or-later" homepage="https://goodies.xfce.org/projects/panel-plugins/xfce4-weather-plugin" distfiles="https://archive.xfce.org/src/panel-plugins/${pkgname}/${version%.*}/${pkgname}-${version}.tar.bz2" -checksum=e3242ea951d51bc0fded1d02a4f1f662bec16a1fb10c855f71bda6541a1153fc +checksum=a45146f9a0dcdc95d191c09c64ad279ae289cf8f811c4433e08e31a656845239 lib32disabled=yes + +pre_configure() { + autoreconf -fi +}