[gnome-todo] todoist: fix network issues



commit a5c131d148296801a361cd82480df8a53550c795
Author: Rohit Kaushik <kaushikrohit325 gmail com>
Date:   Tue Jun 26 23:25:04 2018 +0530

    todoist: fix network issues
    
    This patch add following changes:-
            1) Add a network monitor to keep track of network connectivity
               to Todoist.
            2) Do an initial check, if user is connected to internet only then
               load Todoist Providers.
            3) Remove Todoist providers when user lose internet connectivity or
               Todoist is Unreachable.
            4) Calls the callback on network-changed signal in an async way.

 plugins/todoist/gtd-plugin-todoist.c | 180 ++++++++++++++++++++++++++++++++++-
 1 file changed, 178 insertions(+), 2 deletions(-)
---
diff --git a/plugins/todoist/gtd-plugin-todoist.c b/plugins/todoist/gtd-plugin-todoist.c
index 366ac34..bc139f2 100644
--- a/plugins/todoist/gtd-plugin-todoist.c
+++ b/plugins/todoist/gtd-plugin-todoist.c
@@ -19,6 +19,7 @@
 
 #define G_LOG_DOMAIN "GtdPluginTodoist"
 
+#include "gtd-debug.h"
 #include "gtd-plugin-todoist.h"
 #include "gtd-provider-todoist.h"
 #include "gtd-todoist-preferences-panel.h"
@@ -39,6 +40,8 @@ struct _GtdPluginTodoist
 
   GoaClient          *goa_client;
 
+  gboolean            active;
+
   /* Providers */
   GList              *providers;
 };
@@ -99,6 +102,16 @@ gtd_plugin_todoist_get_providers (GtdActivatable *activatable)
   return plugin->providers;
 }
 
+static void
+emit_connection_error (void)
+{
+  gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                  _("GNOME To Do cannot connect to Todoist due to network issue"),
+                                  _("Not able to communicate with Todoist. Please check your internet 
connectivity."),
+                                  NULL,
+                                  NULL);
+}
+
 static void
 on_account_added_cb (GoaClient        *client,
                      GoaObject        *account_object,
@@ -108,6 +121,9 @@ on_account_added_cb (GoaClient        *client,
   GoaAccount *goa_account;
   const gchar *provider_name;
 
+  if (!self->active)
+    return;
+
   goa_account = goa_object_get_account (account_object);
   provider_name = goa_account_get_provider_name (goa_account);
 
@@ -132,6 +148,9 @@ on_account_removed_cb (GoaClient        *client,
   const gchar *provider_name;
   GList *l;
 
+  if (!self->active)
+    return;
+
   goa_account = goa_object_get_account (account_object);
   provider_name = goa_account_get_provider_name (goa_account);
   l = NULL;
@@ -174,6 +193,11 @@ on_goa_client_ready_cb (GObject          *source,
       return;
     }
 
+  gtd_todoist_preferences_panel_set_client (GTD_TODOIST_PREFERENCES_PANEL (self->preferences), 
self->goa_client);
+
+  if (!self->active)
+    return;
+
   accounts = goa_client_get_accounts (self->goa_client);
 
   for (l = accounts; l != NULL; l = l->next)
@@ -194,11 +218,153 @@ on_goa_client_ready_cb (GObject          *source,
   g_signal_connect (self->goa_client, "account-added", G_CALLBACK (on_account_added_cb), self);
   g_signal_connect (self->goa_client, "account-removed", G_CALLBACK (on_account_removed_cb), self);
 
-  gtd_todoist_preferences_panel_set_client (GTD_TODOIST_PREFERENCES_PANEL (self->preferences), 
self->goa_client);
-
   g_list_free_full (accounts, g_object_unref);
 }
 
+static void
+remove_providers (GtdPluginTodoist *self)
+{
+  GList *l;
+
+  GTD_ENTRY;
+
+  self->active = FALSE;
+
+  for (l = self->providers; l != NULL; l = l->next)
+    {
+      GtdProviderTodoist *provider;
+
+      provider = GTD_PROVIDER_TODOIST (l->data);
+
+      self->providers = g_list_remove (self->providers, l->data);
+
+      g_signal_emit_by_name (self, "provider-removed", provider);
+    }
+
+  /* Disconnect handlers */
+  g_signal_handlers_disconnect_by_func (self->goa_client, on_account_added_cb, self);
+  g_signal_handlers_disconnect_by_func (self->goa_client, on_account_removed_cb, self);
+
+  GTD_RETURN ();
+}
+
+static void
+readd_providers (GtdPluginTodoist *self)
+{
+  GList *accounts;
+  GList *l;
+
+  GTD_ENTRY;
+
+  self->active = TRUE;
+  accounts = goa_client_get_accounts (self->goa_client);
+
+  for (l = accounts; l != NULL; l = l->next)
+    {
+      GoaAccount *account;
+      const gchar *provider_type;
+
+      account = goa_object_get_account (l->data);
+      provider_type = goa_account_get_provider_type (account);
+
+      if (g_strcmp0 (provider_type, "todoist") == 0)
+        on_account_added_cb (self->goa_client, l->data, self);
+
+      g_object_unref (account);
+    }
+
+  /* Connect signals */
+  g_signal_connect (self->goa_client, "account-added", G_CALLBACK (on_account_added_cb), self);
+  g_signal_connect (self->goa_client, "account-removed", G_CALLBACK (on_account_removed_cb), self);
+
+  GTD_RETURN ();
+}
+
+static void
+can_reach_todoist_cb (GNetworkMonitor  *monitor,
+                      GAsyncResult     *result,
+                      GtdPluginTodoist *self)
+{
+  g_autoptr (GError) error = NULL;
+  gboolean reachable;
+
+  reachable = g_network_monitor_can_reach_finish (monitor, result, &error);
+
+  if (!reachable && self->active)
+    {
+      remove_providers (self);
+      self->active = FALSE;
+      emit_connection_error ();
+    }
+  else if (reachable && !self->active)
+    {
+      readd_providers (self);
+      self->active = TRUE;
+    }
+}
+
+static void
+can_reach_todoist (GtdPluginTodoist  *self,
+                   GNetworkMonitor   *monitor)
+{
+  GSocketConnectable *addr;
+  gboolean status;
+  gboolean connected;
+
+  GTD_ENTRY;
+
+  addr = g_network_address_new ("www.todoist.com", 80);
+  connected = FALSE;
+
+  status = g_network_monitor_get_connectivity (monitor);
+
+  switch (status)
+    {
+      case G_NETWORK_CONNECTIVITY_LOCAL:
+        g_debug ("G_NETWORK_CONNECTIVITY_LOCAL");
+        connected = FALSE;
+        break;
+
+      case G_NETWORK_CONNECTIVITY_LIMITED:
+        g_debug ("G_NETWORK_CONNECTIVITY_LIMITED");
+        connected = FALSE;
+        break;
+
+      case G_NETWORK_CONNECTIVITY_PORTAL:
+        g_debug ("G_NETWORK_CONNECTIVITY_PORTAL");
+        connected = FALSE;
+        break;
+
+      case G_NETWORK_CONNECTIVITY_FULL:
+        connected = TRUE;
+        break;
+    }
+
+  if (connected)
+    {
+      g_network_monitor_can_reach_async (monitor, addr, NULL, (GAsyncReadyCallback) can_reach_todoist_cb, 
self);
+    }
+  else if (self->active)
+    {
+      remove_providers (self);
+      self->active = FALSE;
+      emit_connection_error ();
+    }
+}
+
+static void
+connectivity_changed (GNetworkMonitor  *monitor,
+                      gboolean          available,
+                      GtdPluginTodoist *self)
+{
+  /*
+   * Handles the removal and adding of providers if connectivity to Todoist changes
+   * Sends an error message before removing the providers if the plugin goes from
+   * active to inactive state
+   */
+  can_reach_todoist (self, monitor);
+}
+
 static void
 gtd_activatable_iface_init (GtdActivatableInterface *iface)
 {
@@ -262,6 +428,16 @@ gtd_plugin_todoist_init (GtdPluginTodoist *self)
   self->preferences = GTK_WIDGET (gtd_todoist_preferences_panel_new ());
 
   goa_client_new (NULL, (GAsyncReadyCallback) on_goa_client_ready_cb, self);
+
+  /*
+   * Need to check if Todoist is reachable. By Default the plugin is in inactive state
+   * i.e (self->active = FALSE) If connection to Todoist can be established the providers
+   * are added in the can_reach_todoist callback
+   */
+  can_reach_todoist (self, g_network_monitor_get_default ());
+
+  /* Connect network-changed signal */
+  g_signal_connect (g_network_monitor_get_default (), "network-changed", G_CALLBACK (connectivity_changed), 
self);
 }
 
 /* Empty class_finalize method */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]