/** * goa_client_lookup_by_id: * @client: A #GoaClient. * @id: The ID to look for. * * Finds and returns the #GoaObject instance whose * <link * linkend="gdbus-property-org-gnome-OnlineAccounts-Account.Id">"Id"</link> * D-Bus property matches @id. * * Returns: (transfer full): A #GoaObject. Free the returned * object with g_object_unref(). * * Since: 3.6 */ GoaObject * goa_client_lookup_by_id (GoaClient *client, const gchar *id) { GList *accounts; GList *l; GoaObject *ret; ret = NULL; accounts = goa_client_get_accounts (client); for (l = accounts; l != NULL; l = g_list_next (l)) { GoaAccount *account; GoaObject *object = GOA_OBJECT (l->data); account = goa_object_peek_account (object); if (account == NULL) continue; if (g_strcmp0 (goa_account_get_id (account), id) == 0) { ret = g_object_ref (object); break; } } g_list_free_full (accounts, g_object_unref); return ret; }
static gboolean on_account_handle_ensure_credentials (GoaAccount *account, GDBusMethodInvocation *invocation, gpointer user_data) { GoaDaemon *daemon = GOA_DAEMON (user_data); GoaProvider *provider; GoaObject *object; object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (account))); provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account)); if (provider == NULL) { g_dbus_method_invocation_return_error (invocation, GOA_ERROR, GOA_ERROR_FAILED, "Unsupported account type %s for id %s (no provider)", goa_account_get_provider_type (account), goa_account_get_id (account)); goto out; } goa_provider_ensure_credentials (provider, object, NULL, /* GCancellable */ (GAsyncReadyCallback) ensure_credentials_cb, ensure_data_new (daemon, object, invocation)); out: return TRUE; /* invocation was handled */ }
static void sync_accounts (GisGoaPage *page) { GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page); GList *accounts, *l; accounts = goa_client_get_accounts (priv->goa_client); for (l = accounts; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); GoaAccount *account = goa_object_get_account (object); const char *account_type = goa_account_get_provider_type (account); ProviderWidget *provider_widget; provider_widget = g_hash_table_lookup (priv->providers, account_type); if (!provider_widget) continue; priv->accounts_exist = TRUE; if (provider_widget->displayed_account) continue; provider_widget->displayed_account = account; sync_provider_widget (provider_widget); } g_list_free_full (accounts, (GDestroyNotify) g_object_unref); sync_visibility (page); gis_page_set_skippable (GIS_PAGE (page), !priv->accounts_exist); gis_page_set_complete (GIS_PAGE (page), priv->accounts_exist); }
gboolean goa_utils_check_duplicate (GoaClient *client, const gchar *identity, const gchar *presentation_identity, const gchar *provider_type, GoaPeekInterfaceFunc func, GError **error) { GList *accounts; GList *l; gboolean ret; ret = FALSE; accounts = goa_client_get_accounts (client); for (l = accounts; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); GoaAccount *account; gpointer *interface; const gchar *identity_from_object; const gchar *presentation_identity_from_object; const gchar *provider_type_from_object; account = goa_object_peek_account (object); interface = (*func) (object); if (interface == NULL) continue; provider_type_from_object = goa_account_get_provider_type (account); if (g_strcmp0 (provider_type_from_object, provider_type) != 0) continue; identity_from_object = goa_account_get_identity (account); presentation_identity_from_object = goa_account_get_presentation_identity (account); if (g_strcmp0 (identity_from_object, identity) == 0 && g_strcmp0 (presentation_identity_from_object, presentation_identity) == 0) { const gchar *provider_name; provider_name = goa_account_get_provider_name (account); g_set_error (error, GOA_ERROR, GOA_ERROR_ACCOUNT_EXISTS, _("A %s account already exists for %s"), provider_name, presentation_identity); goto out; } } ret = TRUE; out: g_list_free_full (accounts, g_object_unref); return ret; }
static void on_object_removed (GDBusObjectManager *manager, GDBusObject *object, gpointer user_data) { GoaClient *client = GOA_CLIENT (user_data); if (goa_object_peek_account (GOA_OBJECT (object)) != NULL) g_signal_emit (client, signals[ACCOUNT_REMOVED_SIGNAL], 0, object); }
static void on_interface_added (GDBusObjectManager *manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { GoaClient *client = GOA_CLIENT (user_data); if (goa_object_peek_account (GOA_OBJECT (object)) != NULL) g_signal_emit (client, signals[ACCOUNT_CHANGED_SIGNAL], 0, object); }
static void on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager, GDBusObjectProxy *object_proxy, GDBusProxy *interface_proxy, GVariant *changed_properties, const gchar* const *invalidated_properties, gpointer user_data) { GoaClient *client = GOA_CLIENT (user_data); if (goa_object_peek_account (GOA_OBJECT (object_proxy)) != NULL) g_signal_emit (client, signals[ACCOUNT_CHANGED_SIGNAL], 0, object_proxy); }
static gboolean on_handle_get_password (GoaPasswordBased *interface, GDBusMethodInvocation *invocation, const gchar *id, gpointer user_data) { GoaObject *object; GoaAccount *account; GoaProvider *provider; GError *error; GVariant *credentials; gchar *password; /* TODO: maybe log what app is requesting access */ password = NULL; credentials = NULL; object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface))); account = goa_object_peek_account (object); provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account)); error = NULL; credentials = goa_utils_lookup_credentials_sync (provider, object, NULL, /* GCancellable* */ &error); if (credentials == NULL) { g_dbus_method_invocation_take_error (invocation, error); goto out; } if (!g_variant_lookup (credentials, "password", "s", &password)) { g_dbus_method_invocation_return_error (invocation, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Did not find password with username `%s' in credentials"), id); goto out; } goa_password_based_complete_get_password (interface, invocation, password); out: g_free (password); if (credentials != NULL) g_variant_unref (credentials); g_object_unref (provider); return TRUE; /* invocation was handled */ }
static void photos_source_manager_refresh_accounts (PhotosSourceManager *self) { PhotosSourceManagerPrivate *priv = self->priv; GHashTable *new_sources; GList *accounts; GList *l; accounts = goa_client_get_accounts (priv->client); new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); for (l = accounts; l != NULL; l = l->next) { GoaAccount *account; GoaObject *object = GOA_OBJECT (l->data); PhotosSource *source; const gchar *id; account = goa_object_peek_account (object); if (account == NULL) continue; if (goa_account_get_photos_disabled (account)) continue; if (goa_object_peek_photos (object) == NULL) continue; source = photos_source_new_from_goa_object (GOA_OBJECT (l->data)); id = photos_filterable_get_id (PHOTOS_FILTERABLE (source)); g_hash_table_insert (new_sources, g_strdup (id), g_object_ref (source)); g_object_unref (source); } photos_base_manager_process_new_objects (PHOTOS_BASE_MANAGER (self), new_sources); g_hash_table_unref (new_sources); g_list_free_full (accounts, g_object_unref); }
static void init_model (GoaPanelAccountsModel *model) { GList *accounts; GList *l; accounts = goa_client_get_accounts (model->client); for (l = accounts; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); add_account (model, object); } g_list_foreach (accounts, (GFunc) g_object_unref, NULL); g_list_free (accounts); }
static gboolean build_object (GoaProvider *provider, GoaObjectSkeleton *object, GKeyFile *key_file, const gchar *group, GDBusConnection *connection, gboolean just_added, GError **error) { GoaAccount *account; gboolean chat_enabled; gboolean ret; account = NULL; ret = FALSE; /* Chain up */ if (!GOA_PROVIDER_CLASS (goa_telepathy_provider_parent_class)->build_object (provider, object, key_file, group, connection, just_added, error)) goto out; account = goa_object_get_account (GOA_OBJECT (object)); /* Chat */ chat_enabled = g_key_file_get_boolean (key_file, group, "ChatEnabled", NULL); goa_object_skeleton_attach_chat (object, chat_enabled); if (just_added) { goa_account_set_chat_disabled (account, !chat_enabled); g_signal_connect (account, "notify::chat-disabled", G_CALLBACK (goa_util_account_notify_property_cb), "ChatEnabled"); } ret = TRUE; out: g_clear_object (&account); return ret; }
/** * goa_client_get_manager: * @client: A #GoaClient. * * Gets the #GoaManager for @client. * * Returns: (transfer none): A #GoaManager. Do not free, the returned * object belongs to @client. */ GoaManager * goa_client_get_manager (GoaClient *client) { GDBusObject *object; GoaManager *manager; manager = NULL; object = g_dbus_object_manager_get_object (client->object_manager, "/org/gnome/OnlineAccounts/Manager"); if (object == NULL) goto out; manager = goa_object_peek_manager (GOA_OBJECT (object)); out: if (object != NULL) g_object_unref (object); return manager; }
/** * goa_client_get_accounts: * @client: A #GoaClient. * * Gets all accounts that @client knows about. The result is a list of * #GoaObject instances where each object at least has an #GoaAccount * interface (that can be obtained via the goa_object_get_account() * method) but may also implement other interfaces such as * #GoaMail or #GoaFiles. * * Returns: (transfer full) (element-type GoaObject): A list of * #GoaObject instances that must be freed with g_list_free() after * each element has been freed with g_object_unref(). */ GList * goa_client_get_accounts (GoaClient *client) { GList *ret; GList *objects; GList *l; g_return_val_if_fail (GOA_IS_CLIENT (client), NULL); ret = NULL; objects = g_dbus_object_manager_get_objects (client->object_manager); for (l = objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); if (goa_object_peek_account (object) != NULL) ret = g_list_prepend (ret, g_object_ref (object)); } g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); return ret; }
/* returns FALSE if object is not (or no longer) valid */ static gboolean update_account_object (GoaDaemon *daemon, GoaObjectSkeleton *object, const gchar *path, const gchar *group, GKeyFile *key_file, gboolean just_added) { GoaAccount *account; GoaProvider *provider; gboolean ret; gchar *identity; gchar *presentation_identity; gchar *type; gchar *name; GIcon *icon; gchar *serialized_icon; GError *error; g_return_val_if_fail (GOA_IS_DAEMON (daemon), FALSE); g_return_val_if_fail (G_IS_DBUS_OBJECT_SKELETON (object), FALSE); g_return_val_if_fail (group != NULL, FALSE); g_return_val_if_fail (key_file != NULL, FALSE); ret = FALSE; identity = NULL; type = NULL; account = NULL; name = NULL; icon = NULL; serialized_icon = NULL; g_debug ("updating %s %d", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)), just_added); type = g_key_file_get_string (key_file, group, "Provider", NULL); identity = g_key_file_get_string (key_file, group, "Identity", NULL); presentation_identity = g_key_file_get_string (key_file, group, "PresentationIdentity", NULL); if (just_added) { account = goa_account_skeleton_new (); goa_object_skeleton_set_account (object, account); } else { account = goa_object_get_account (GOA_OBJECT (object)); } provider = goa_provider_get_for_provider_type (type); if (provider == NULL) { g_warning ("Unsupported account type %s for identity %s (no provider)", type, identity); goto out; } goa_account_set_id (account, g_strrstr (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)), "/") + 1); goa_account_set_provider_type (account, type); goa_account_set_identity (account, identity); goa_account_set_presentation_identity (account, presentation_identity); error = NULL; if (!goa_provider_build_object (provider, object, key_file, group, daemon->connection, just_added, &error)) { g_warning ("Error parsing account: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); goto out; } name = goa_provider_get_provider_name (provider, GOA_OBJECT (object)); goa_account_set_provider_name (account, name); icon = goa_provider_get_provider_icon (provider, GOA_OBJECT (object)); serialized_icon = g_icon_to_string (icon); goa_account_set_provider_icon (account, serialized_icon); ret = TRUE; out: g_free (serialized_icon); if (icon != NULL) g_object_unref (icon); g_free (name); if (provider != NULL) g_object_unref (provider); g_object_unref (account); g_free (type); g_free (identity); return ret; }
static GoaObject * add_account (GoaProvider *provider, GoaClient *client, GtkDialog *dialog, GtkBox *vbox, GError **error) { AddAccountData data; GVariantBuilder credentials; GVariantBuilder details; GoaEwsClient *ews_client; GoaObject *ret; gboolean accept_ssl_errors; const gchar *email_address; const gchar *server; const gchar *password; const gchar *username; const gchar *provider_type; gint response; ews_client = NULL; accept_ssl_errors = FALSE; ret = NULL; memset (&data, 0, sizeof (AddAccountData)); data.loop = g_main_loop_new (NULL, FALSE); data.dialog = dialog; data.error = NULL; create_account_details_ui (provider, dialog, vbox, TRUE, &data); gtk_widget_show_all (GTK_WIDGET (vbox)); ews_client = goa_ews_client_new (); ews_again: response = gtk_dialog_run (dialog); if (response != GTK_RESPONSE_OK) { g_set_error (&data.error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED, _("Dialog was dismissed")); goto out; } email_address = gtk_entry_get_text (GTK_ENTRY (data.email_address)); password = gtk_entry_get_text (GTK_ENTRY (data.password)); username = gtk_entry_get_text (GTK_ENTRY (data.username)); server = gtk_entry_get_text (GTK_ENTRY (data.server)); /* See if there's already an account of this type with the * given identity */ provider_type = goa_provider_get_provider_type (provider); if (!goa_utils_check_duplicate (client, username, provider_type, (GoaPeekInterfaceFunc) goa_object_peek_password_based, &data.error)) goto out; goa_ews_client_autodiscover (ews_client, email_address, password, username, server, accept_ssl_errors, NULL, autodiscover_cb, &data); goa_spinner_button_start (GOA_SPINNER_BUTTON (data.spinner_button)); g_main_loop_run (data.loop); if (data.error != NULL) { gchar *markup; if (data.error->code == GOA_ERROR_SSL) { goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Ignore")); accept_ssl_errors = TRUE; } else { goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Try Again")); accept_ssl_errors = FALSE; } markup = g_strdup_printf ("<b>%s:</b> %s", _("Error connecting to Microsoft Exchange server"), data.error->message); g_clear_error (&data.error); gtk_label_set_markup (GTK_LABEL (data.cluebar_label), markup); g_free (markup); gtk_expander_set_expanded (GTK_EXPANDER (data.expander), TRUE); gtk_widget_set_no_show_all (data.cluebar, FALSE); gtk_widget_show_all (data.cluebar); goto ews_again; } gtk_widget_hide (GTK_WIDGET (dialog)); g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&credentials, "{sv}", "password", g_variant_new_string (password)); g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); g_variant_builder_add (&details, "{ss}", "MailEnabled", "true"); g_variant_builder_add (&details, "{ss}", "CalendarEnabled", "true"); g_variant_builder_add (&details, "{ss}", "ContactsEnabled", "true"); g_variant_builder_add (&details, "{ss}", "Host", server); g_variant_builder_add (&details, "{ss}", "AcceptSslErrors", (accept_ssl_errors) ? "true" : "false"); /* OK, everything is dandy, add the account */ /* we want the GoaClient to update before this method returns (so it * can create a proxy for the new object) so run the mainloop while * waiting for this to complete */ goa_manager_call_add_account (goa_client_get_manager (client), goa_provider_get_provider_type (provider), username, email_address, g_variant_builder_end (&credentials), g_variant_builder_end (&details), NULL, /* GCancellable* */ (GAsyncReadyCallback) add_account_cb, &data); g_main_loop_run (data.loop); if (data.error != NULL) goto out; ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client), data.account_object_path)); out: /* We might have an object even when data.error is set. * eg., if we failed to store the credentials in the keyring. */ if (data.error != NULL) g_propagate_error (error, data.error); else g_assert (ret != NULL); g_free (data.account_object_path); if (data.loop != NULL) g_main_loop_unref (data.loop); if (ews_client != NULL) g_object_unref (ews_client); return ret; }
static gboolean build_object (GoaProvider *provider, GoaObjectSkeleton *object, GKeyFile *key_file, const gchar *group, GDBusConnection *connection, gboolean just_added, GError **error) { GoaAccount *account; GoaCalendar *calendar; GoaContacts *contacts; GoaExchange *exchange; GoaMail *mail; GoaPasswordBased *password_based; gboolean calendar_enabled; gboolean contacts_enabled; gboolean mail_enabled; gboolean ret; account = NULL; calendar = NULL; contacts = NULL; exchange = NULL; mail = NULL; password_based = NULL; ret = FALSE; /* Chain up */ if (!GOA_PROVIDER_CLASS (goa_exchange_provider_parent_class)->build_object (provider, object, key_file, group, connection, just_added, error)) goto out; password_based = goa_object_get_password_based (GOA_OBJECT (object)); if (password_based == NULL) { password_based = goa_password_based_skeleton_new (); /* Ensure D-Bus method invocations run in their own thread */ g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (password_based), G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); goa_object_skeleton_set_password_based (object, password_based); g_signal_connect (password_based, "handle-get-password", G_CALLBACK (on_handle_get_password), NULL); } account = goa_object_get_account (GOA_OBJECT (object)); /* Email */ mail = goa_object_get_mail (GOA_OBJECT (object)); mail_enabled = g_key_file_get_boolean (key_file, group, "MailEnabled", NULL); if (mail_enabled) { if (mail == NULL) { const gchar *email_address; email_address = goa_account_get_presentation_identity (account); mail = goa_mail_skeleton_new (); g_object_set (G_OBJECT (mail), "email-address", email_address, NULL); goa_object_skeleton_set_mail (object, mail); } } else { if (mail != NULL) goa_object_skeleton_set_mail (object, NULL); } /* Calendar */ calendar = goa_object_get_calendar (GOA_OBJECT (object)); calendar_enabled = g_key_file_get_boolean (key_file, group, "CalendarEnabled", NULL); if (calendar_enabled) { if (calendar == NULL) { calendar = goa_calendar_skeleton_new (); goa_object_skeleton_set_calendar (object, calendar); } } else { if (calendar != NULL) goa_object_skeleton_set_calendar (object, NULL); } /* Contacts */ contacts = goa_object_get_contacts (GOA_OBJECT (object)); contacts_enabled = g_key_file_get_boolean (key_file, group, "ContactsEnabled", NULL); if (contacts_enabled) { if (contacts == NULL) { contacts = goa_contacts_skeleton_new (); goa_object_skeleton_set_contacts (object, contacts); } } else { if (contacts != NULL) goa_object_skeleton_set_contacts (object, NULL); } /* Exchange */ exchange = goa_object_get_exchange (GOA_OBJECT (object)); if (exchange == NULL) { gchar *host; host = g_key_file_get_string (key_file, group, "Host", NULL); exchange = goa_exchange_skeleton_new (); g_object_set (G_OBJECT (exchange), "host", host, NULL); goa_object_skeleton_set_exchange (object, exchange); g_free (host); } if (just_added) { goa_account_set_mail_disabled (account, !mail_enabled); goa_account_set_calendar_disabled (account, !calendar_enabled); goa_account_set_contacts_disabled (account, !contacts_enabled); g_signal_connect (account, "notify::mail-disabled", G_CALLBACK (goa_util_account_notify_property_cb), "MailEnabled"); g_signal_connect (account, "notify::calendar-disabled", G_CALLBACK (goa_util_account_notify_property_cb), "CalendarEnabled"); g_signal_connect (account, "notify::contacts-disabled", G_CALLBACK (goa_util_account_notify_property_cb), "ContactsEnabled"); } ret = TRUE; out: if (exchange != NULL) g_object_unref (exchange); if (contacts != NULL) g_object_unref (contacts); if (calendar != NULL) g_object_unref (calendar); if (mail != NULL) g_object_unref (mail); if (password_based != NULL) g_object_unref (password_based); return ret; }
static void goa_daemon_update_notifications (GoaDaemon *daemon) { gboolean show_notification; GList *objects; GList *l; show_notification = FALSE; objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager)); for (l = objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); GoaAccount *account; account = goa_object_peek_account (object); if (account != NULL) { if (goa_account_get_attention_needed (account)) { show_notification = TRUE; break; } } } if (show_notification) { if (daemon->notification == NULL) { GError *error; daemon->notification = notify_notification_new (_("An online account needs attention"), NULL, NULL); notify_notification_set_timeout (daemon->notification, NOTIFY_EXPIRES_NEVER); g_object_set (daemon->notification, "icon-name", "gtk-dialog-error", NULL); notify_notification_add_action (daemon->notification, "open-online-accounts", _("Open Online Accounts..."), notification_cb, daemon, NULL); /* GFreeFunc */ error = NULL; if (!notify_notification_show (daemon->notification, &error)) { goa_warning ("Error showing notification: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); g_object_unref (daemon->notification); daemon->notification = NULL; } else { g_signal_connect (daemon->notification, "closed", G_CALLBACK (on_notification_closed), daemon); } } } else { if (daemon->notification != NULL) { GError *error; error = NULL; if (!notify_notification_close (daemon->notification, &error)) { goa_warning ("Error closing notification: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); } g_signal_handlers_disconnect_by_func (daemon->notification, G_CALLBACK (on_notification_closed), daemon); g_object_unref (daemon->notification); daemon->notification = NULL; } } g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); }
static void gfbgraph_goa_authorizer_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { switch (prop_id) { case PROP_GOA_OBJECT: gfbgraph_goa_authorizer_set_goa_object (GFBGRAPH_GOA_AUTHORIZER (object), GOA_OBJECT (g_value_get_object (value))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void process_config_entries (GoaDaemon *daemon, GHashTable *group_name_to_key_file_data) { GHashTableIter iter; const gchar *id; KeyFileData *key_file_data; GList *existing_object_paths; GList *config_object_paths; GList *added; GList *removed; GList *unchanged; GList *l; existing_object_paths = NULL; { GList *existing_objects; existing_objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager)); for (l = existing_objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); const gchar *object_path; object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); if (g_str_has_prefix (object_path, "/org/gnome/OnlineAccounts/Accounts/")) existing_object_paths = g_list_prepend (existing_object_paths, g_strdup (object_path)); } g_list_foreach (existing_objects, (GFunc) g_object_unref, NULL); g_list_free (existing_objects); } config_object_paths = NULL; g_hash_table_iter_init (&iter, group_name_to_key_file_data); while (g_hash_table_iter_next (&iter, (gpointer*) &id, (gpointer*) &key_file_data)) { gchar *object_path; /* create and validate object path */ object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id + sizeof "Account " - 1); if (strstr (id + sizeof "Account " - 1, "/") != NULL || !g_variant_is_object_path (object_path)) { g_warning ("`%s' is not a valid account identifier", id); g_free (object_path); continue; } /* steals object_path variable */ config_object_paths = g_list_prepend (config_object_paths, object_path); } existing_object_paths = g_list_sort (existing_object_paths, (GCompareFunc) g_strcmp0); config_object_paths = g_list_sort (config_object_paths, (GCompareFunc) g_strcmp0); diff_sorted_lists (existing_object_paths, config_object_paths, (GCompareFunc) g_strcmp0, &added, &removed, &unchanged); for (l = removed; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObject *object; object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path)); g_warn_if_fail (object != NULL); g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); g_debug ("removing %s", object_path); g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); } for (l = added; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObjectSkeleton *object; gchar *group; g_debug ("adding %s", object_path); group = object_path_to_group (object_path); key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); object = goa_object_skeleton_new (object_path); if (update_account_object (daemon, object, key_file_data->path, group, key_file_data->key_file, TRUE)) { g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object)); g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)), "handle-remove", G_CALLBACK (on_account_handle_remove), daemon); g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)), "handle-ensure-credentials", G_CALLBACK (on_account_handle_ensure_credentials), daemon); } g_object_unref (object); g_free (group); } for (l = unchanged; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObject *object; gchar *group; g_debug ("unchanged %s", object_path); group = object_path_to_group (object_path); key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path)); g_warn_if_fail (object != NULL); if (!update_account_object (daemon, GOA_OBJECT_SKELETON (object), key_file_data->path, group, key_file_data->key_file, FALSE)) { g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_ensure_credentials), daemon); g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); } g_object_unref (object); g_free (group); } g_list_free (removed); g_list_free (added); g_list_free (unchanged); g_list_foreach (existing_object_paths, (GFunc) g_free, NULL); g_list_free (existing_object_paths); g_list_foreach (config_object_paths, (GFunc) g_free, NULL); g_list_free (config_object_paths); }
gint main (void) { GDataDocumentsFeed *feed = NULL; GDataDocumentsQuery *query = NULL; GDataDocumentsService *service = NULL; GError *error = NULL; GList *accounts = NULL; GList *entries; GList *l; GoaClient *client = NULL; client = goa_client_new_sync (NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_error_free (error); goto out; } accounts = goa_client_get_accounts (client); for (l = accounts; l != NULL; l = l->next) { GoaAccount *account; GoaObject *object = GOA_OBJECT (l->data); const gchar *provider_type; account = goa_object_peek_account (object); provider_type = goa_account_get_provider_type (account); if (g_strcmp0 (provider_type, "google") == 0) { GDataGoaAuthorizer *authorizer; authorizer = gdata_goa_authorizer_new (object); service = gdata_documents_service_new (GDATA_AUTHORIZER (authorizer)); g_object_unref (authorizer); } } if (service == NULL) { g_warning ("Account not found"); goto out; } query = gdata_documents_query_new_with_limits (NULL, 1, 10); gdata_documents_query_set_show_folders (query, TRUE); while (TRUE) { feed = gdata_documents_service_query_documents (service, query, NULL, NULL, NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_error_free (error); goto out; } entries = gdata_feed_get_entries (GDATA_FEED (feed)); if (entries == NULL) { goto out; } for (l = entries; l != NULL; l = l->next) { GDataEntry *entry = GDATA_ENTRY (l->data); const gchar *title; title = gdata_entry_get_title (entry); g_message ("%s", title); } gdata_query_next_page (GDATA_QUERY (query)); g_object_unref (feed); } out: g_clear_object (&feed); g_clear_object (&query); g_clear_object (&service); g_clear_object (&client); g_list_free_full (accounts, g_object_unref); return 0; }