[evolution-couchdb] Add REV field to VCARDs for SyncEvolution compatibility



commit cd3b5632532600e430094742fab5ce9b73a3a2c9
Author: Rodrigo Moya <rodrigo gnome-db org>
Date:   Wed Mar 24 17:05:12 2010 +0100

    Add REV field to VCARDs for SyncEvolution compatibility

 addressbook/e-book-backend-couchdb.c |   86 ++++++++++++++++++++++++++++-----
 1 files changed, 73 insertions(+), 13 deletions(-)
---
diff --git a/addressbook/e-book-backend-couchdb.c b/addressbook/e-book-backend-couchdb.c
index f02950b..145c2a3 100644
--- a/addressbook/e-book-backend-couchdb.c
+++ b/addressbook/e-book-backend-couchdb.c
@@ -34,6 +34,18 @@
 
 G_DEFINE_TYPE (EBookBackendCouchDB, e_book_backend_couchdb, E_TYPE_BOOK_BACKEND);
 
+static void
+get_current_time (gchar time_string[100])
+{
+	const struct tm *tm = NULL;
+	time_t t;
+
+	t = time (NULL);
+	tm = gmtime (&t);
+	if (tm)
+		strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", tm);
+}
+
 static char *
 vcard_from_couch_document (CouchdbDocument *document)
 {
@@ -60,6 +72,7 @@ vcard_from_couch_document (CouchdbDocument *document)
 			if (private_annotations != NULL) {
 				if (couchdb_struct_field_has_field (private_annotations, "deleted")
 				    && couchdb_struct_field_get_boolean_field (private_annotations, "deleted"))
+					couchdb_struct_field_unref (app_annotations);
 					return NULL;
 			}
 		}
@@ -425,16 +438,39 @@ vcard_from_couch_document (CouchdbDocument *document)
 	}
 
 	/* application annotations */
-	if (couchdb_document_has_field (document, "application_annotations")) {
-		CouchdbStructField *annotations = desktopcouch_document_get_application_annotations (document);
+	if (app_annotations != NULL) {
+		/* Always have a REV field on the VCARD, for SyncEvolution (bug LP:#479110) */
+		CouchdbStructField *evo_annotations;
+		gchar time_string[100] = {0};
+
+		evo_annotations = couchdb_struct_field_get_struct_field (app_annotations, "Evolution");
+		if (evo_annotations != NULL) {
+			if (couchdb_struct_field_has_field (evo_annotations, "revision")) {
+				e_contact_set (contact, E_CONTACT_REV,
+					       couchdb_struct_field_get_string_field (evo_annotations, "revision"));
+			} else {
+				get_current_time (time_string);
+				e_contact_set (contact, E_CONTACT_REV, time_string);
+			}
+		} else {
+			get_current_time (time_string);
+			e_contact_set (contact, E_CONTACT_REV, time_string);
+		}
 
-		str = couchdb_struct_field_to_string (annotations);
+		/* Save the entire app_annotations field as a string on the VCARD */
+		str = couchdb_struct_field_to_string (app_annotations);
 		e_vcard_add_attribute_with_value (E_VCARD (contact),
 						  e_vcard_attribute_new (NULL, COUCHDB_APPLICATION_ANNOTATIONS_PROP),
 						  str);
 
 		g_free (str);
-		couchdb_struct_field_unref (annotations);
+		couchdb_struct_field_unref (app_annotations);
+	} else {
+		/* Always have a REV field on the VCARD, for SyncEvolution (bug LP:#479110) */
+		gchar time_string[100] = {0};
+
+		get_current_time (time_string);
+		e_contact_set (contact, E_CONTACT_REV, time_string);
 	}
 
 	/* convert the contact to a VCARD string to be returned */
@@ -653,6 +689,31 @@ contact_im_to_struct_field (EVCardAttribute *attr, const gchar *protocol)
 	return desktopcouch_document_contact_im_new (uuid, address, description, protocol);
 }
 
+static void
+set_vcard_revision (CouchdbStructField *app_annotations, EContact *contact)
+{
+	CouchdbStructField *evo_annotations;
+	const gchar *rev;
+
+	if (couchdb_struct_field_has_field (app_annotations, "Evolution"))
+		evo_annotations = couchdb_struct_field_get_struct_field (app_annotations, "Evolution");
+	else
+		evo_annotations = couchdb_struct_field_new ();
+
+	rev = e_contact_get_const (contact,  E_CONTACT_REV);
+	if (rev && *rev) {
+		couchdb_struct_field_set_string_field (evo_annotations, "revision", rev);
+	} else { 
+		gchar time_string[100] = {0};
+
+		get_current_time (time_string);
+		couchdb_struct_field_set_string_field (evo_annotations, "revision", time_string);
+	}
+
+	couchdb_struct_field_set_struct_field (app_annotations, "Evolution", evo_annotations);
+	couchdb_struct_field_unref (evo_annotations);
+}
+
 static CouchdbDocument *
 couch_document_from_contact (EBookBackendCouchDB *couchdb_backend, EContact *contact)
 {
@@ -662,7 +723,7 @@ couch_document_from_contact (EBookBackendCouchDB *couchdb_backend, EContact *con
 	const char *str;
 	CouchdbDocument *document;
 	gint i;
-	CouchdbStructField *postal_address;
+	CouchdbStructField *postal_address, *app_annotations;
 
 	/* create the CouchDBDocument to put on the database */
 	document = desktopcouch_document_contact_new (couchdb_backend->couchdb);
@@ -843,15 +904,14 @@ couch_document_from_contact (EBookBackendCouchDB *couchdb_backend, EContact *con
 
 	/* application annotations */
 	str = e_vcard_attribute_get_value (e_vcard_get_attribute (E_VCARD (contact), COUCHDB_APPLICATION_ANNOTATIONS_PROP));
-	if (str) {
-		CouchdbStructField *annotations;
+	if (str)
+		app_annotations = couchdb_struct_field_new_from_string (str);
+	else
+		app_annotations = couchdb_struct_field_new ();
 
-		annotations = couchdb_struct_field_new_from_string (str);
-		if (annotations) {
-			desktopcouch_document_set_application_annotations (document, annotations);
-			couchdb_struct_field_unref (annotations);
-		}
-	}
+	set_vcard_revision (app_annotations, contact);
+	desktopcouch_document_set_application_annotations (document, app_annotations);
+	couchdb_struct_field_unref (app_annotations);
 
 	return document;
 }



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