From 74bbf6ef146137803f6e1349d9da14d006ce5137 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 18 Nov 2010 18:53:48 -0500 Subject: [PATCH] Add an ESource extension for the vcf backend. --- addressbook/backends/vcf/Makefile.am | 4 +- .../backends/vcf/e-book-backend-vcf-factory.c | 2 + addressbook/backends/vcf/e-book-backend-vcf.c | 46 +++--- addressbook/backends/vcf/e-source-vcf.c | 182 +++++++++++++++++++++ addressbook/backends/vcf/e-source-vcf.h | 69 ++++++++ 5 files changed, 275 insertions(+), 28 deletions(-) create mode 100644 addressbook/backends/vcf/e-source-vcf.c create mode 100644 addressbook/backends/vcf/e-source-vcf.h diff --git a/addressbook/backends/vcf/Makefile.am b/addressbook/backends/vcf/Makefile.am index 0f0266b..91dc099 100644 --- a/addressbook/backends/vcf/Makefile.am +++ b/addressbook/backends/vcf/Makefile.am @@ -14,7 +14,9 @@ libebookbackendvcf_la_CPPFLAGS = \ libebookbackendvcf_la_SOURCES = \ e-book-backend-vcf.c \ e-book-backend-vcf.h \ - e-book-backend-vcf-factory.c + e-book-backend-vcf-factory.c \ + e-source-vcf.c \ + e-source-vcf.h libebookbackendvcf_la_LIBADD = \ $(top_builddir)/addressbook/libebook/libebook-1.2.la \ diff --git a/addressbook/backends/vcf/e-book-backend-vcf-factory.c b/addressbook/backends/vcf/e-book-backend-vcf-factory.c index d041e86..bd1ed2f 100644 --- a/addressbook/backends/vcf/e-book-backend-vcf-factory.c +++ b/addressbook/backends/vcf/e-book-backend-vcf-factory.c @@ -27,6 +27,7 @@ #include #include "e-book-backend-vcf.h" +#include "e-source-vcf.h" #define FACTORY_NAME "vcf" @@ -65,6 +66,7 @@ e_book_backend_vcf_factory_init (EBookBackendFactory *factory) G_MODULE_EXPORT void e_module_load (GTypeModule *type_module) { + e_source_vcf_type_register (type_module); e_book_backend_vcf_factory_register_type (type_module); } diff --git a/addressbook/backends/vcf/e-book-backend-vcf.c b/addressbook/backends/vcf/e-book-backend-vcf.c index 7f27d7c..9d76099 100644 --- a/addressbook/backends/vcf/e-book-backend-vcf.c +++ b/addressbook/backends/vcf/e-book-backend-vcf.c @@ -49,6 +49,7 @@ #include "libedata-book/e-book-backend-sexp.h" #include "e-book-backend-vcf.h" +#include "e-source-vcf.h" #define E_BOOK_BACKEND_VCF_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -572,23 +573,6 @@ e_book_backend_vcf_stop_book_view (EBookBackend *backend, g_thread_join (closure->thread); } -static gchar * -e_book_backend_vcf_extract_path_from_uri (const gchar *uri) -{ - g_assert (g_ascii_strncasecmp (uri, "vcf://", 6) == 0); - - return g_strdup (uri + 6); -} - -static void -e_book_backend_vcf_authenticate_user (EBookBackendSync *backend, - GCancellable *cancellable, - ECredentials *credentials, - GError **perror) -{ - /* Success */ -} - #ifdef CREATE_DEFAULT_VCARD # include #endif @@ -602,15 +586,17 @@ e_book_backend_vcf_open (EBookBackendSync *backend, { EBookBackendVCF *bvcf = E_BOOK_BACKEND_VCF (backend); ESource *source; + ESourceVCF *vcf_extension; + const gchar *extension_name; gchar *dirname; gboolean readonly = TRUE; - gchar *uri; gint fd; source = e_backend_get_source (E_BACKEND (backend)); - uri = e_source_get_uri (source); + extension_name = E_SOURCE_EXTENSION_VCF_BACKEND; + vcf_extension = e_source_get_extension (source, extension_name); - dirname = e_book_backend_vcf_extract_path_from_uri (uri); + dirname = e_source_vcf_dup_path (vcf_extension); bvcf->priv->filename = g_build_filename (dirname, "addressbook.vcf", NULL); fd = g_open (bvcf->priv->filename, O_RDWR | O_BINARY, 0); @@ -638,7 +624,7 @@ e_book_backend_vcf_open (EBookBackendSync *backend, } else { g_propagate_error (perror, e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR, "Failed to make directory %s: %s", dirname, g_strerror (errno))); } - return; + goto exit; } fd = g_open (bvcf->priv->filename, O_CREAT | O_BINARY, 0666); @@ -660,11 +646,14 @@ e_book_backend_vcf_open (EBookBackendSync *backend, } if (fd == -1) { - g_warning ("Failed to open addressbook at uri `%s'", uri); + g_warning ("Failed to open addressbook at `%s'", dirname); g_warning ("error == %s", g_strerror(errno)); - g_propagate_error (perror, e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR, "Failed to open addressbook at uri '%s': %s", uri, g_strerror (errno))); - g_free (uri); - return; + g_propagate_error ( + perror, e_data_book_create_error_fmt ( + E_DATA_BOOK_STATUS_OTHER_ERROR, + "Failed to open addressbook at '%s': %s", + dirname, g_strerror (errno))); + goto exit; } load_file (bvcf, fd); @@ -673,7 +662,8 @@ e_book_backend_vcf_open (EBookBackendSync *backend, e_book_backend_notify_online (E_BOOK_BACKEND (backend), TRUE); e_book_backend_notify_opened (E_BOOK_BACKEND (backend), NULL); - g_free (uri); +exit: + g_free (dirname); } static gboolean @@ -772,9 +762,11 @@ e_book_backend_vcf_class_init (EBookBackendVCFClass *class) sync_class->modify_contacts_sync = e_book_backend_vcf_modify_contacts; sync_class->get_contact_sync = e_book_backend_vcf_get_contact; sync_class->get_contact_list_sync = e_book_backend_vcf_get_contact_list; - sync_class->authenticate_user_sync = e_book_backend_vcf_authenticate_user; object_class->finalize = e_book_backend_vcf_finalize; + + /* Register our ESource extension. */ + E_TYPE_SOURCE_VCF; } static void diff --git a/addressbook/backends/vcf/e-source-vcf.c b/addressbook/backends/vcf/e-source-vcf.c new file mode 100644 index 0000000..f0b6ed1 --- /dev/null +++ b/addressbook/backends/vcf/e-source-vcf.c @@ -0,0 +1,182 @@ +/* + * e-source-vcf.c + * + * 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 + * + */ + +#include "e-source-vcf.h" + +#include + +#define E_SOURCE_VCF_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SOURCE_VCF, ESourceVCFPrivate)) + +struct _ESourceVCFPrivate { + GMutex *property_lock; + gchar *path; +}; + +enum { + PROP_0, + PROP_PATH +}; + +G_DEFINE_DYNAMIC_TYPE ( + ESourceVCF, + e_source_vcf, + E_TYPE_SOURCE_EXTENSION) + +static void +source_vcf_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_PATH: + e_source_vcf_set_path ( + E_SOURCE_VCF (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_vcf_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_PATH: + g_value_take_string ( + value, + e_source_vcf_dup_path ( + E_SOURCE_VCF (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_vcf_finalize (GObject *object) +{ + ESourceVCFPrivate *priv; + + priv = E_SOURCE_VCF_GET_PRIVATE (object); + + g_mutex_free (priv->property_lock); + + g_free (priv->path); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_source_vcf_parent_class)->finalize (object); +} + +static void +e_source_vcf_class_init (ESourceVCFClass *class) +{ + GObjectClass *object_class; + ESourceExtensionClass *extension_class; + + g_type_class_add_private (class, sizeof (ESourceVCFPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = source_vcf_set_property; + object_class->get_property = source_vcf_get_property; + object_class->finalize = source_vcf_finalize; + + extension_class = E_SOURCE_EXTENSION_CLASS (class); + extension_class->name = E_SOURCE_EXTENSION_VCF_BACKEND; + + g_object_class_install_property ( + object_class, + PROP_PATH, + g_param_spec_string ( + "path", + "Path", + "Path to VCF file", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + E_SOURCE_PARAM_SETTING)); +} + +static void +e_source_vcf_class_finalize (ESourceVCFClass *class) +{ +} + +static void +e_source_vcf_init (ESourceVCF *extension) +{ + extension->priv = E_SOURCE_VCF_GET_PRIVATE (extension); + extension->priv->property_lock = g_mutex_new (); +} + +void +e_source_vcf_type_register (GTypeModule *type_module) +{ + /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration + * function, so we have to wrap it with a public function in + * order to register types from a separate compilation unit. */ + e_source_vcf_register_type (type_module); +} + +const gchar * +e_source_vcf_get_path (ESourceVCF *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_VCF (extension), NULL); + + return extension->priv->path; +} + +gchar * +e_source_vcf_dup_path (ESourceVCF *extension) +{ + const gchar *protected; + gchar *duplicate; + + g_return_val_if_fail (E_IS_SOURCE_VCF (extension), NULL); + + g_mutex_lock (extension->priv->property_lock); + + protected = e_source_vcf_get_path (extension); + duplicate = g_strdup (protected); + + g_mutex_unlock (extension->priv->property_lock); + + return duplicate; +} + +void +e_source_vcf_set_path (ESourceVCF *extension, + const gchar *path) +{ + g_return_if_fail (E_IS_SOURCE_VCF (extension)); + + g_mutex_lock (extension->priv->property_lock); + + g_free (extension->priv->path); + extension->priv->path = e_util_strdup_strip (path); + + g_mutex_unlock (extension->priv->property_lock); + + g_object_notify (G_OBJECT (extension), "path"); +} diff --git a/addressbook/backends/vcf/e-source-vcf.h b/addressbook/backends/vcf/e-source-vcf.h new file mode 100644 index 0000000..d84ad4a --- /dev/null +++ b/addressbook/backends/vcf/e-source-vcf.h @@ -0,0 +1,69 @@ +/* + * e-source-vcf.h + * + * 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 + * + */ + +#ifndef E_SOURCE_VCF_H +#define E_SOURCE_VCF_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_SOURCE_VCF \ + (e_source_vcf_get_type ()) +#define E_SOURCE_VCF(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SOURCE_VCF, ESourceVCF)) +#define E_SOURCE_VCF_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SOURCE_VCF, ESourceVCFClass)) +#define E_IS_SOURCE_VCF(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SOURCE_VCF)) +#define E_IS_SOURCE_VCF_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SOURCE_VCF)) +#define E_SOURCE_VCF_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SOURCE_VCF, ESourceVCFClass)) + +#define E_SOURCE_EXTENSION_VCF_BACKEND "VCF Backend" + +G_BEGIN_DECLS + +typedef struct _ESourceVCF ESourceVCF; +typedef struct _ESourceVCFClass ESourceVCFClass; +typedef struct _ESourceVCFPrivate ESourceVCFPrivate; + +struct _ESourceVCF { + ESourceExtension parent; + ESourceVCFPrivate *priv; +}; + +struct _ESourceVCFClass { + ESourceExtensionClass parent_class; +}; + +GType e_source_vcf_get_type (void); +void e_source_vcf_type_register (GTypeModule *type_module); +const gchar * e_source_vcf_get_path (ESourceVCF *extension); +gchar * e_source_vcf_dup_path (ESourceVCF *extension); +void e_source_vcf_set_path (ESourceVCF *extension, + const gchar *path); + +G_END_DECLS + +#endif /* E_SOURCE_VCF_H */ -- 2.7.4