[gnome-contacts] Port contacts-esd-setup to Vala.



commit 4294cd7cfec747d888e323ef5a029ef09cc6dc74
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Mon Dec 25 14:50:54 2017 +0100

    Port contacts-esd-setup to Vala.

 meson.build                 |    1 +
 po/POTFILES.in              |    2 +-
 src/contacts-contact.vala   |    8 +-
 src/contacts-esd-setup.c    |  323 -------------------------------------------
 src/contacts-esd-setup.h    |   11 --
 src/contacts-esd-setup.vala |  193 ++++++++++++++++++++++++++
 src/meson.build             |   14 +--
 vapi/custom.vapi            |   18 ---
 8 files changed, 202 insertions(+), 368 deletions(-)
---
diff --git a/meson.build b/meson.build
index 8cd97db..2746fec 100644
--- a/meson.build
+++ b/meson.build
@@ -81,6 +81,7 @@ conf.set_quoted('PACKAGE_VERSION', meson.project_version())
 conf.set_quoted('PKGDATADIR', pkgdatadir)
 conf.set_quoted('PKGLIBDIR', pkglibdir)
 conf.set_quoted('VERSION', meson.project_version())
+conf.set('GOA_API_IS_SUBJECT_TO_CHANGE', true)
 configure_file(output: 'config.h', configuration: conf)
 
 # Post-install scripts
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 778d939..1ac14a4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -22,7 +22,7 @@ src/contacts-contact-list.vala
 src/contacts-contact-pane.vala
 src/contacts-contact-sheet.vala
 src/contacts-contact.vala
-src/contacts-esd-setup.c
+src/contacts-esd-setup.vala
 src/contacts-linked-accounts-dialog.vala
 src/contacts-link-suggestion-grid.vala
 src/contacts-settings.vala
diff --git a/src/contacts-contact.vala b/src/contacts-contact.vala
index e7180ee..08dcc12 100644
--- a/src/contacts-contact.vala
+++ b/src/contacts-contact.vala
@@ -655,9 +655,9 @@ public class Contacts.Contact : GLib.Object  {
 
   public static string format_persona_store_name (PersonaStore store) {
     if (store.type_id == "eds") {
-      unowned string? eds_name = lookup_esource_name_by_uid (store.id);
+      string? eds_name = lookup_esource_name_by_uid (store.id);
       if (eds_name != null)
-       return eds_name;
+        return eds_name;
     }
 #if HAVE_TELEPATHY
     if (store.type_id == "telepathy") {
@@ -750,9 +750,9 @@ public class Contacts.Contact : GLib.Object  {
       else if (persona_is_google_other (persona))
        return _("Google");
 
-      unowned string? eds_name = lookup_esource_name_by_uid_for_contact (store.id);
+      string? eds_name = lookup_esource_name_by_uid_for_contact (store.id);
       if (eds_name != null)
-       return eds_name;
+        return eds_name;
     }
 #if HAVE_TELEPATHY
     if (store.type_id == "telepathy") {
diff --git a/src/contacts-esd-setup.vala b/src/contacts-esd-setup.vala
new file mode 100644
index 0000000..51ba791
--- /dev/null
+++ b/src/contacts-esd-setup.vala
@@ -0,0 +1,193 @@
+/*
+ * This code is ported to Vala from evolution with this license:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+// FIXME: the async bindings seem to be broken for this function.
+extern void e_trust_prompt_run_for_source (Gtk.Window parent, E.Source source, string certificate_pem, 
GLib.TlsCertificateFlags certificate_errors, string? error_text, bool allow_source_save, GLib.Cancellable? 
cancellable, AsyncReadyCallback callback);
+extern bool e_trust_prompt_run_for_source_finish (E.Source source, AsyncResult result, out 
E.TrustPromptResponse response) throws GLib.Error;
+
+namespace Contacts {
+
+public E.SourceRegistry? eds_source_registry = null;
+private E.CredentialsPrompter? eds_credentials_prompter = null;
+
+public bool ensure_eds_accounts (bool allow_interaction) {
+  if (eds_source_registry != null)
+    return true;
+
+  // XXX This blocks while connecting to the D-Bus service.
+  // Maybe it should be created in the Contacts class and passed in as needed?
+
+  try {
+    eds_source_registry = new E.SourceRegistry.sync (null);
+  } catch (Error e) { // If this fails it's game over.
+    warning ("Couldn't load EDS SourceRegistry: %s", e.message);
+    return false;
+  }
+
+  eds_credentials_prompter = new E.CredentialsPrompter (eds_source_registry);
+
+  if (!allow_interaction)
+      eds_credentials_prompter.set_auto_prompt (false);
+
+  var credentials_provider = eds_credentials_prompter.get_provider ();
+
+  // First disable credentials prompt for all but addressbook sources...
+  foreach (var source in eds_source_registry.list_sources (null)) {
+    // Mark for skip also currently disabled sources
+    if (!source.has_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK))
+      eds_credentials_prompter.set_auto_prompt_disabled_for (source, true);
+  }
+
+  // ...then enable credentials prompt for credential source of the addressbook sources,
+  //   which can be a collection source.
+  foreach (var source in eds_source_registry.list_sources (E.SOURCE_EXTENSION_ADDRESS_BOOK)) {
+    var cred_source = credentials_provider.ref_credentials_source (source);
+    if (cred_source != null && !source.equal (cred_source))
+      eds_credentials_prompter.set_auto_prompt_disabled_for (cred_source, false);
+  }
+
+  // The eds_credentials_prompter responses to REQUIRED and REJECTED reasons,
+  // the SSL_FAILED should be handled elsewhere.
+  eds_source_registry.credentials_required.connect((src, reason, cert_pem, cert_err, err) => {
+    on_credentials_required.begin (src, reason, cert_pem, cert_err, err);
+  });
+
+  eds_credentials_prompter.process_awaiting_credentials ();
+
+  return true;
+}
+
+private async void on_credentials_required (E.Source source, E.SourceCredentialsReason reason, string 
cert_pem, TlsCertificateFlags cert_errors, Error err) {
+  if (eds_credentials_prompter.get_auto_prompt_disabled_for (source))
+    return;
+
+  if (reason == E.SourceCredentialsReason.ERROR && err != null) {
+    warning ("Failed to autheticate for source \"%s\": %s", source.display_name, err.message);
+    return;
+  }
+
+  if (reason == E.SourceCredentialsReason.SSL_FAILED) {
+    e_trust_prompt_run_for_source (eds_credentials_prompter.get_dialog_parent (),
+        source, cert_pem, cert_errors, (err != null)? err.message : null, true,
+        null, (obj, res) => on_source_trust_prompt_has_run.begin (source, res));
+  }
+}
+
+private async void on_source_trust_prompt_has_run (E.Source source, AsyncResult res) {
+  try {
+    e_trust_prompt_run_for_source_finish (source, res, null);
+  } catch (Error e) {
+    warning ("Failed to prompt for trust for source \"%s\": %s", source.display_name, e.message);
+    return;
+  }
+
+  try {
+    // Use null credentials to reuse those from the last time.
+    yield source.invoke_authenticate (null, null);
+  } catch (Error e) {
+    warning ("Failed to invoke authenticate() for source \"%s\": %s", source.display_name, e.message);
+  }
+}
+
+public bool has_goa_account () {
+  foreach (var source in eds_source_registry.list_sources (E.SOURCE_EXTENSION_GOA)) {
+    // Ignore disabled accounts.
+    if (!source.enabled)
+      continue;
+
+    // All ESources with a [GNOME Online Accounts] extension
+    // should also have a [Collection] extension.  Verify it.
+    if (!source.has_extension (E.SOURCE_EXTENSION_COLLECTION))
+      continue;
+
+    // This corresponds to the Contacts ON/OFF switch in GOA. */
+    if (((E.SourceCollection) source.get_extension (E.SOURCE_EXTENSION_COLLECTION)).contacts_enabled) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+public bool esource_uid_is_google (string uid) {
+  var source = eds_source_registry.ref_source (uid);
+  if (source == null)
+    return false;
+
+  /* Make sure it's really an address book. */
+  if (source.has_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK)) {
+    var extension = source.get_extension (E.SOURCE_EXTENSION_ADDRESS_BOOK);
+    return ((E.SourceBackend) extension).backend_name == "google";
+  }
+
+  return false;
+}
+
+public string? lookup_esource_name_by_uid (string uid) {
+  var source = eds_source_registry.ref_source (uid);
+  if (source == null)
+    return null;
+
+  var builtin_address_book = eds_source_registry.ref_builtin_address_book ();
+
+  if (source.equal (builtin_address_book))
+    return _("Local Address Book");
+
+  if (esource_uid_is_google (uid))
+    return _("Google");
+
+  return source.display_name;
+}
+
+public string? lookup_esource_name_by_uid_for_contact (string uid) {
+  var source = eds_source_registry.ref_source (uid);
+  if (source == null)
+    return null;
+
+  var builtin_address_book = eds_source_registry.ref_builtin_address_book ();
+  if (source.equal (builtin_address_book))
+    return _("Local Contact");
+
+  if (esource_uid_is_google (uid))
+    return _("Google");
+
+  return source.display_name;
+}
+
+public Gtk.Image? get_icon_for_goa_account (string goa_id) {
+  Goa.Client client;
+  try {
+    client = new Goa.Client.sync (null);
+  } catch (Error e) {
+    debug ("Couldn't load GOA client \"%s\": %s", goa_id, e.message);
+    return null;
+  }
+
+  var goa_object = client.lookup_by_id (goa_id);
+
+  Icon provider_icon;
+  try {
+    provider_icon = Icon.new_for_string (goa_object.account.provider_icon);
+  } catch (Error e) {
+    debug ("Couldn't load icon for GOA provider \"%s\"", goa_id);
+    return null;
+  }
+
+  return new Gtk.Image.from_gicon (provider_icon, Gtk.IconSize.DIALOG);
+}
+}
diff --git a/src/meson.build b/src/meson.build
index b072ad0..14f2604 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -15,6 +15,7 @@ contacts_vala_sources = [
   'contacts-contact-pane.vala',
   'contacts-contact-sheet.vala',
   'contacts-contact.vala',
+  'contacts-esd-setup.vala',
   'contacts-in-app-notification.vala',
   'contacts-link-suggestion-grid.vala',
   'contacts-linked-accounts-dialog.vala',
@@ -38,7 +39,6 @@ contacts_vala_args = [
 
 contacts_c_sources = [
   'cc-crop-area.c',
-  'contacts-esd-setup.c',
 ]
 
 contacts_c_args = [
@@ -96,23 +96,15 @@ executable('gnome-contacts', contacts_sources,
 )
 
 # The search provider
-contact_search_provider_vala_sources = [
+contact_search_provider_sources = [
   'contacts-contact.vala',
+  'contacts-esd-setup.vala',
   'contacts-shell-search-provider.vala',
   'contacts-store.vala',
   'contacts-types.vala',
   'contacts-utils.vala',
 ]
 
-contact_search_provider_c_sources = [
-  'contacts-esd-setup.c',
-]
-
-contact_search_provider_sources = [
-  contact_search_provider_vala_sources,
-  contact_search_provider_c_sources,
-]
-
 executable('gnome-contacts-search-provider', contact_search_provider_sources,
   include_directories: config_h_dir,
   vala_args: contacts_vala_args,
diff --git a/vapi/custom.vapi b/vapi/custom.vapi
index 5fe3561..c48e3e8 100644
--- a/vapi/custom.vapi
+++ b/vapi/custom.vapi
@@ -1,21 +1,3 @@
-[CCode (cprefix = "Contacts", lower_case_cprefix = "contacts_", cheader_filename = "contacts-esd-setup.h")]
-namespace Contacts {
-       [CCode (cname = "contacts_ensure_eds_accounts")]
-       public static bool ensure_eds_accounts (bool allow_interaction);
-       [CCode (cname = "contacts_lookup_esource_name_by_uid")]
-       public static unowned string? lookup_esource_name_by_uid (string uid);
-       [CCode (cname = "contacts_lookup_esource_name_by_uid_for_contact")]
-       public static unowned string? lookup_esource_name_by_uid_for_contact (string uid);
-       [CCode (cname = "contacts_esource_uid_is_google")]
-       public static bool esource_uid_is_google (string uid);
-       [CCode (cname = "contacts_has_goa_account")]
-       public static bool has_goa_account ();
-       [CCode (cname = "eds_source_registry")]
-       public static E.SourceRegistry eds_source_registry;
-       [CCode (cname = "contacts_get_icon_for_goa_account")]
-       public static unowned Gtk.Widget get_icon_for_goa_account (string goa_id);
-}
-
 [CCode (cprefix = "Cc", lower_case_cprefix = "cc_", cheader_filename = "cc-crop-area.h")]
 namespace Cc {
        public class CropArea : Gtk.DrawingArea {


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