weather-service: Reorganize file
This commit is contained in:
+153
-176
@@ -109,20 +109,6 @@ struct _GcalWeatherService
|
||||
static void on_gweather_update_cb (GWeatherInfo *info,
|
||||
GcalWeatherService *self);
|
||||
|
||||
static void schedule_midnight (GcalWeatherService *self);
|
||||
|
||||
static void start_timer (GcalWeatherService *self);
|
||||
|
||||
static void stop_timer (GcalWeatherService *self);
|
||||
|
||||
static gboolean has_valid_weather_infos (GcalWeatherService *self);
|
||||
|
||||
static void update_weather (GcalWeatherService *self,
|
||||
GWeatherInfo *info,
|
||||
gboolean reuse_old_on_error);
|
||||
|
||||
static gssize get_normalized_icon_name_len (const gchar *str);
|
||||
|
||||
G_DEFINE_TYPE (GcalWeatherService, gcal_weather_service, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
@@ -145,6 +131,31 @@ static guint signals[N_SIGNALS] = { 0 };
|
||||
* Auxiliary methods
|
||||
*/
|
||||
|
||||
static gssize
|
||||
get_normalized_icon_name_len (const gchar *str)
|
||||
{
|
||||
const gchar *suffix1 = "-symbolic";
|
||||
const gssize suffix1_len = strlen (suffix1);
|
||||
|
||||
const gchar *suffix2 = "-night";
|
||||
const gssize suffix2_len = strlen (suffix2);
|
||||
|
||||
gssize clean_len;
|
||||
gssize str_len;
|
||||
|
||||
str_len = strlen (str);
|
||||
|
||||
clean_len = str_len - suffix1_len;
|
||||
if (clean_len >= 0 && memcmp (suffix1, str + clean_len, suffix1_len) == 0)
|
||||
str_len = clean_len;
|
||||
|
||||
clean_len = str_len - suffix2_len;
|
||||
if (clean_len >= 0 && memcmp (suffix2, str + clean_len, suffix2_len) == 0)
|
||||
str_len = clean_len;
|
||||
|
||||
return str_len;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
get_normalized_icon_name (GWeatherInfo* wi,
|
||||
gboolean is_night_icon)
|
||||
@@ -193,6 +204,18 @@ get_normalized_icon_name (GWeatherInfo* wi,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_valid_weather_infos (GcalWeatherService *self)
|
||||
{
|
||||
gint64 now;
|
||||
|
||||
if (self->gweather_info == NULL || self->weather_infos_upated < 0)
|
||||
return FALSE;
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
return (now - self->weather_infos_upated) / 1000000 <= self->valid_timespan;
|
||||
}
|
||||
|
||||
static void
|
||||
update_timeout_interval (GcalWeatherService *self)
|
||||
{
|
||||
@@ -257,31 +280,6 @@ stop_timer (GcalWeatherService *self)
|
||||
gcal_timer_stop (self->midnight_timer);
|
||||
}
|
||||
|
||||
static gssize
|
||||
get_normalized_icon_name_len (const gchar *str)
|
||||
{
|
||||
const gchar *suffix1 = "-symbolic";
|
||||
const gssize suffix1_len = strlen (suffix1);
|
||||
|
||||
const gchar *suffix2 = "-night";
|
||||
const gssize suffix2_len = strlen (suffix2);
|
||||
|
||||
gssize clean_len;
|
||||
gssize str_len;
|
||||
|
||||
str_len = strlen (str);
|
||||
|
||||
clean_len = str_len - suffix1_len;
|
||||
if (clean_len >= 0 && memcmp (suffix1, str + clean_len, suffix1_len) == 0)
|
||||
str_len = clean_len;
|
||||
|
||||
clean_len = str_len - suffix2_len;
|
||||
if (clean_len >= 0 && memcmp (suffix2, str + clean_len, suffix2_len) == 0)
|
||||
str_len = clean_len;
|
||||
|
||||
return str_len;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_icon_name_sortkey (const gchar *icon_name,
|
||||
gboolean *supports_night_icon)
|
||||
@@ -469,79 +467,6 @@ compute_weather_info_data (GSList *samples,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_location (GcalWeatherService *self,
|
||||
GWeatherLocation *location)
|
||||
{
|
||||
if (gcal_timer_is_running (self->duration_timer))
|
||||
stop_timer (self);
|
||||
|
||||
if (self->gweather_info != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_data (self->gweather_info, self);
|
||||
g_clear_object (&self->gweather_info);
|
||||
}
|
||||
|
||||
if (!location)
|
||||
{
|
||||
g_debug ("Could not retrieve current location");
|
||||
update_weather (self, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Got new weather service location: '%s'",
|
||||
!location ? "<null>" : gweather_location_get_name (location));
|
||||
|
||||
self->gweather_info = gweather_info_new (location);
|
||||
|
||||
/*
|
||||
* NOTE: We do not get detailed infos for GWEATHER_PROVIDER_ALL.
|
||||
* This combination works fine, though. We should open a bug / investigate
|
||||
* what is going on.
|
||||
*/
|
||||
gweather_info_set_enabled_providers (self->gweather_info, GWEATHER_PROVIDER_METAR | GWEATHER_PROVIDER_OWM | GWEATHER_PROVIDER_YR_NO);
|
||||
g_signal_connect_object (self->gweather_info, "updated", (GCallback) on_gweather_update_cb, self, 0);
|
||||
|
||||
/*
|
||||
* gweather_info_update might or might not trigger a
|
||||
* GWeatherInfo::update() signal. Therefore, we have to
|
||||
* remove weather information before querying new one.
|
||||
* This might result in icon flickering on screen.
|
||||
* We probably want to introduce a "unknown" or "loading"
|
||||
* state in gweather-info to soften the effect.
|
||||
*/
|
||||
update_weather (self, NULL, FALSE);
|
||||
gweather_info_update (self->gweather_info);
|
||||
|
||||
start_timer (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_gclue_location (GcalWeatherService *self,
|
||||
GClueLocation *location)
|
||||
{
|
||||
GWeatherLocation *wlocation = NULL; /* owned */
|
||||
|
||||
if (location)
|
||||
{
|
||||
GWeatherLocation *wworld; /* unowned */
|
||||
gdouble latitude;
|
||||
gdouble longitude;
|
||||
|
||||
latitude = gclue_location_get_latitude (location);
|
||||
longitude = gclue_location_get_longitude (location);
|
||||
|
||||
/* nearest-city works more closely to gnome weather. */
|
||||
wworld = gweather_location_get_world ();
|
||||
wlocation = gweather_location_find_nearest_city (wworld, latitude, longitude);
|
||||
}
|
||||
|
||||
update_location (self, wlocation);
|
||||
|
||||
g_clear_pointer (&wlocation, gweather_location_unref);
|
||||
}
|
||||
|
||||
static GPtrArray*
|
||||
preprocess_gweather_reports (GcalWeatherService *self,
|
||||
GSList *samples)
|
||||
@@ -645,6 +570,122 @@ preprocess_gweather_reports (GcalWeatherService *self,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
update_weather (GcalWeatherService *self,
|
||||
GWeatherInfo *info,
|
||||
gboolean reuse_old_on_error)
|
||||
{
|
||||
GSList *gwforecast = NULL; /* unowned */
|
||||
|
||||
/* Compute a list of newly received weather infos. */
|
||||
if (!info)
|
||||
{
|
||||
g_debug ("Could not retrieve valid weather");
|
||||
}
|
||||
else if (gweather_info_is_valid (info))
|
||||
{
|
||||
g_debug ("Received valid weather information");
|
||||
gwforecast = gweather_info_get_forecast_list (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autofree gchar* location_name = gweather_info_get_location_name (info);
|
||||
g_debug ("Could not retrieve valid weather for location '%s'", location_name);
|
||||
}
|
||||
|
||||
if (!gwforecast && self->weather_infos_upated >= 0)
|
||||
{
|
||||
if (!reuse_old_on_error || !has_valid_weather_infos (self))
|
||||
{
|
||||
g_clear_pointer (&self->weather_infos, g_ptr_array_unref);
|
||||
self->weather_infos_upated = -1;
|
||||
|
||||
g_signal_emit (self, signals[SIG_WEATHER_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
else if (gwforecast)
|
||||
{
|
||||
g_clear_pointer (&self->weather_infos, g_ptr_array_unref);
|
||||
self->weather_infos = preprocess_gweather_reports (self, gwforecast);
|
||||
self->weather_infos_upated = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (self, signals[SIG_WEATHER_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_location (GcalWeatherService *self,
|
||||
GWeatherLocation *location)
|
||||
{
|
||||
if (gcal_timer_is_running (self->duration_timer))
|
||||
stop_timer (self);
|
||||
|
||||
if (self->gweather_info != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_data (self->gweather_info, self);
|
||||
g_clear_object (&self->gweather_info);
|
||||
}
|
||||
|
||||
if (!location)
|
||||
{
|
||||
g_debug ("Could not retrieve current location");
|
||||
update_weather (self, NULL, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Got new weather service location: '%s'",
|
||||
!location ? "<null>" : gweather_location_get_name (location));
|
||||
|
||||
self->gweather_info = gweather_info_new (location);
|
||||
|
||||
/*
|
||||
* NOTE: We do not get detailed infos for GWEATHER_PROVIDER_ALL.
|
||||
* This combination works fine, though. We should open a bug / investigate
|
||||
* what is going on.
|
||||
*/
|
||||
gweather_info_set_enabled_providers (self->gweather_info, GWEATHER_PROVIDER_METAR | GWEATHER_PROVIDER_OWM | GWEATHER_PROVIDER_YR_NO);
|
||||
g_signal_connect_object (self->gweather_info, "updated", (GCallback) on_gweather_update_cb, self, 0);
|
||||
|
||||
/*
|
||||
* gweather_info_update might or might not trigger a
|
||||
* GWeatherInfo::update() signal. Therefore, we have to
|
||||
* remove weather information before querying new one.
|
||||
* This might result in icon flickering on screen.
|
||||
* We probably want to introduce a "unknown" or "loading"
|
||||
* state in gweather-info to soften the effect.
|
||||
*/
|
||||
update_weather (self, NULL, FALSE);
|
||||
gweather_info_update (self->gweather_info);
|
||||
|
||||
start_timer (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_gclue_location (GcalWeatherService *self,
|
||||
GClueLocation *location)
|
||||
{
|
||||
GWeatherLocation *wlocation = NULL; /* owned */
|
||||
|
||||
if (location)
|
||||
{
|
||||
GWeatherLocation *wworld; /* unowned */
|
||||
gdouble latitude;
|
||||
gdouble longitude;
|
||||
|
||||
latitude = gclue_location_get_latitude (location);
|
||||
longitude = gclue_location_get_longitude (location);
|
||||
|
||||
/* nearest-city works more closely to gnome weather. */
|
||||
wworld = gweather_location_get_world ();
|
||||
wlocation = gweather_location_find_nearest_city (wworld, latitude, longitude);
|
||||
}
|
||||
|
||||
update_location (self, wlocation);
|
||||
|
||||
g_clear_pointer (&wlocation, gweather_location_unref);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callbacks
|
||||
@@ -804,70 +845,6 @@ gwc2str (GWeatherInfo *gwi)
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
has_valid_weather_infos (GcalWeatherService *self)
|
||||
{
|
||||
gint64 now;
|
||||
|
||||
if (self->gweather_info == NULL || self->weather_infos_upated < 0)
|
||||
return FALSE;
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
return (now - self->weather_infos_upated) / 1000000 <= self->valid_timespan;
|
||||
}
|
||||
|
||||
/* update_weather:
|
||||
* @self: A #GcalWeatherService instance.
|
||||
* @info: (nullable): Newly received weather information or %NULL.
|
||||
* @reuse_old_on_error: Whether to re-use old but not outdated weather
|
||||
* information in case we could not fetch new data.
|
||||
*
|
||||
* Retrieves weather information for @location and triggers
|
||||
* #GcalWeatherService::weather-changed.
|
||||
*/
|
||||
static void
|
||||
update_weather (GcalWeatherService *self,
|
||||
GWeatherInfo *info,
|
||||
gboolean reuse_old_on_error)
|
||||
{
|
||||
GSList *gwforecast = NULL; /* unowned */
|
||||
|
||||
/* Compute a list of newly received weather infos. */
|
||||
if (!info)
|
||||
{
|
||||
g_debug ("Could not retrieve valid weather");
|
||||
}
|
||||
else if (gweather_info_is_valid (info))
|
||||
{
|
||||
g_debug ("Received valid weather information");
|
||||
gwforecast = gweather_info_get_forecast_list (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autofree gchar* location_name = gweather_info_get_location_name (info);
|
||||
g_debug ("Could not retrieve valid weather for location '%s'", location_name);
|
||||
}
|
||||
|
||||
if (!gwforecast && self->weather_infos_upated >= 0)
|
||||
{
|
||||
if (!reuse_old_on_error || !has_valid_weather_infos (self))
|
||||
{
|
||||
g_clear_pointer (&self->weather_infos, g_ptr_array_unref);
|
||||
self->weather_infos_upated = -1;
|
||||
|
||||
g_signal_emit (self, signals[SIG_WEATHER_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
else if (gwforecast)
|
||||
{
|
||||
g_clear_pointer (&self->weather_infos, g_ptr_array_unref);
|
||||
self->weather_infos = preprocess_gweather_reports (self, gwforecast);
|
||||
self->weather_infos_upated = g_get_monotonic_time ();
|
||||
|
||||
g_signal_emit (self, signals[SIG_WEATHER_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GObject overrides
|
||||
|
||||
Reference in New Issue
Block a user