summaryrefslogtreecommitdiff
path: root/glabels2/src/merge-vcard.c
diff options
context:
space:
mode:
Diffstat (limited to 'glabels2/src/merge-vcard.c')
-rw-r--r--glabels2/src/merge-vcard.c383
1 files changed, 383 insertions, 0 deletions
diff --git a/glabels2/src/merge-vcard.c b/glabels2/src/merge-vcard.c
new file mode 100644
index 0000000..c0eb144
--- /dev/null
+++ b/glabels2/src/merge-vcard.c
@@ -0,0 +1,383 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
+/*
+ * (GLABELS) Label and Business Card Creation program for GNOME
+ *
+ * merge_vcard.c: vcard merge backend module
+ *
+ * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
+ * and
+ * Copyright (C) 2005 Austin Henry <ahenry@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#ifdef HAVE_LIBEBOOK
+
+
+#include "merge-vcard.h"
+#include <libebook/e-contact.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "debug.h"
+
+/*===========================================*/
+/* Private types */
+/*===========================================*/
+
+struct _glMergeVCardPrivate {
+ FILE *fp;
+};
+
+enum {
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+};
+
+/*===========================================*/
+/* Private globals */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes */
+/*===========================================*/
+
+static void gl_merge_vcard_finalize (GObject *object);
+
+static void gl_merge_vcard_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void gl_merge_vcard_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static GList *gl_merge_vcard_get_key_list (glMerge *merge);
+static gchar *gl_merge_vcard_get_primary_key (glMerge *merge);
+static void gl_merge_vcard_open (glMerge *merge);
+static void gl_merge_vcard_close (glMerge *merge);
+static glMergeRecord *gl_merge_vcard_get_record (glMerge *merge);
+static void gl_merge_vcard_copy (glMerge *dst_merge,
+ glMerge *src_merge);
+static char * parse_next_vcard (FILE *fp);
+
+
+
+/*****************************************************************************/
+/* Boilerplate object stuff. */
+/*****************************************************************************/
+G_DEFINE_TYPE (glMergeVCard, gl_merge_vcard, GL_TYPE_MERGE);
+
+static void
+gl_merge_vcard_class_init (glMergeVCardClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ glMergeClass *merge_class = GL_MERGE_CLASS (class);
+
+ gl_debug (DEBUG_MERGE, "START");
+
+ gl_merge_vcard_parent_class = g_type_class_peek_parent (class);
+
+ object_class->set_property = gl_merge_vcard_set_property;
+ object_class->get_property = gl_merge_vcard_get_property;
+
+ object_class->finalize = gl_merge_vcard_finalize;
+
+ merge_class->get_key_list = gl_merge_vcard_get_key_list;
+ merge_class->get_primary_key = gl_merge_vcard_get_primary_key;
+ merge_class->open = gl_merge_vcard_open;
+ merge_class->close = gl_merge_vcard_close;
+ merge_class->get_record = gl_merge_vcard_get_record;
+ merge_class->copy = gl_merge_vcard_copy;
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+static void
+gl_merge_vcard_init (glMergeVCard *merge_vcard)
+{
+ gl_debug (DEBUG_MERGE, "START");
+
+ merge_vcard->priv = g_new0 (glMergeVCardPrivate, 1);
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+static void
+gl_merge_vcard_finalize (GObject *object)
+{
+ glMergeVCard *merge_vcard = GL_MERGE_VCARD (object);
+
+ gl_debug (DEBUG_MERGE, "START");
+
+ g_return_if_fail (object && GL_IS_MERGE_VCARD (object));
+
+ g_free (merge_vcard->priv);
+
+ G_OBJECT_CLASS (gl_merge_vcard_parent_class)->finalize (object);
+
+ gl_debug (DEBUG_MERGE, "END");
+}
+
+/*--------------------------------------------------------------------------*/
+/* Set argument. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ glMergeVCard *merge_vcard;
+
+ merge_vcard = GL_MERGE_VCARD (object);
+
+ switch (param_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get argument. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ glMergeVCard *merge_vcard;
+
+ merge_vcard = GL_MERGE_VCARD (object);
+
+ switch (param_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+
+}
+
+/* TODO */
+/*--------------------------------------------------------------------------*/
+/* Get key list. */
+/*--------------------------------------------------------------------------*/
+static GList *
+gl_merge_vcard_get_key_list (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+ GList *key_list;
+
+ gl_debug (DEBUG_MERGE, "BEGIN");
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ /* extremely simple approach until I can list the available keys from the
+ * server, and return them. */
+ key_list = NULL;
+ key_list = g_list_append (key_list, g_strdup ("full_name"));
+ key_list = g_list_append (key_list, g_strdup ("home_address"));
+ key_list = g_list_append (key_list, g_strdup ("work_address"));
+
+ gl_debug (DEBUG_MERGE, "END");
+
+ return key_list;
+}
+
+/* TODO? */
+/*--------------------------------------------------------------------------*/
+/* Get "primary" key. */
+/*--------------------------------------------------------------------------*/
+static gchar *
+gl_merge_vcard_get_primary_key (glMerge *merge)
+{
+ /* For now, let's always assume the full name is the primary key. */
+ return g_strdup ("full_name");
+}
+
+/*--------------------------------------------------------------------------*/
+/* Open merge source. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_open (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+ gchar *src;
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ src = gl_merge_get_src (merge);
+
+ if (src != NULL) {
+ merge_vcard->priv->fp = fopen (src, "r");
+ }
+
+ g_free (src);
+
+ return;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Close merge source. */
+/*--------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_close (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ if (merge_vcard->priv->fp != NULL) {
+ fclose (merge_vcard->priv->fp);
+ merge_vcard->priv->fp = NULL;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get next record from merge source, NULL if no records left (i.e EOF) */
+/*--------------------------------------------------------------------------*/
+static glMergeRecord *
+gl_merge_vcard_get_record (glMerge *merge)
+{
+ glMergeVCard *merge_vcard;
+ glMergeRecord *record;
+ glMergeField *field;
+
+ char *vcard;
+ EContact *contact;
+
+ merge_vcard = GL_MERGE_VCARD (merge);
+
+ vcard = parse_next_vcard(merge_vcard->priv->fp);
+ if (vcard == NULL || vcard[0] == '\0') {
+ return NULL; /* EOF */
+ }
+ contact = e_contact_new_from_vcard(vcard);
+ if (contact == NULL) {
+ return NULL; /* invalid vcard */
+ }
+
+ record = g_new0 (glMergeRecord, 1);
+ record->select_flag = TRUE;
+
+ /* Take the interesting fields one by one from the contact, and put them
+ * into the glMergeRecord structure. When done, free up the resources for
+ * that contact */
+
+ /* get the full name */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("full_name");
+ field->value = g_strdup (e_contact_get_const(contact, E_CONTACT_FULL_NAME));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the home address */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("home_address");
+ field->value = g_strdup (e_contact_get_const(contact, E_CONTACT_ADDRESS_LABEL_HOME));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* get the work address */
+ field = g_new0 (glMergeField, 1);
+ field->key = g_strdup ("work_address");
+ field->value = g_strdup (e_contact_get_const(contact, E_CONTACT_ADDRESS_LABEL_WORK));
+
+ record->field_list = g_list_append (record->field_list, field);
+
+ /* free the contact */
+ g_object_unref (contact);
+ g_free(vcard);
+
+ return record;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Copy merge_vcard specific fields. */
+/*---------------------------------------------------------------------------*/
+static void
+gl_merge_vcard_copy (glMerge *dst_merge,
+ glMerge *src_merge)
+{
+ glMergeVCard *dst_merge_vcard;
+ glMergeVCard *src_merge_vcard;
+
+ dst_merge_vcard = GL_MERGE_VCARD (dst_merge);
+ src_merge_vcard = GL_MERGE_VCARD (src_merge);
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE: pull out a full VCard from the open file */
+/* Arguments: */
+/* fp - an open stream to parse in put from */
+/* Returns: */
+/* a pointer to the buffer containing the vcard, the empty string on */
+/* end-of-file or error, this buffer needs to be free by the caller */
+/*---------------------------------------------------------------------------*/
+static char *
+parse_next_vcard (FILE *fp)
+{
+ gboolean found_begin = FALSE;
+ gboolean found_end = FALSE;
+ char *vcard;
+ char line[512];
+ int size = 2048;
+ int cursize = 0;
+
+ /* if no source has been set up, don't try to read from the file */
+ if (!fp) {
+ return NULL;
+ }
+
+ vcard = g_malloc0(size);
+
+ while (fgets(line, sizeof(line), fp) && found_end == FALSE) {
+ if (found_begin == TRUE) {
+ if (g_str_has_prefix(line, "END:VCARD")) { found_end = TRUE; }
+ } else {
+ if (g_str_has_prefix(line, "BEGIN:VCARD")) { found_begin = TRUE; }
+ else { continue; }/* skip lines not in a vcard */
+ }
+
+ /* if the buffer passed us isn't big enough, reallocate it */
+ cursize += strlen(line);
+ if (cursize >= size) {
+ size *= 2;
+ vcard = (char *)g_realloc(vcard, size); /* aborts program on error */
+ }
+
+ /* add the line (or portion thereof) to the vcard */
+ strncat(vcard, line, size);
+ }
+
+ return vcard;
+}
+
+
+
+#endif /* HAVE_LIBEBOOK */