[evolution-data-server] I#12 - vCard REV attribute should be a timestamp



commit 8a5044ea9c3e5cb5d4b98478e7bed16455a592e8
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jun 21 15:56:18 2018 +0200

    I#12 - vCard REV attribute should be a timestamp
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/12

 .../backends/file/e-book-backend-file.c            | 14 ++++---
 .../backends/google/e-book-backend-google.c        | 22 +++++++++--
 .../backends/google/e-book-google-utils.c          | 43 ++++++++++++++--------
 .../backends/google/e-book-google-utils.h          |  4 +-
 4 files changed, 57 insertions(+), 26 deletions(-)
---
diff --git a/src/addressbook/backends/file/e-book-backend-file.c 
b/src/addressbook/backends/file/e-book-backend-file.c
index 18efecb50..2f4a1ab17 100644
--- a/src/addressbook/backends/file/e-book-backend-file.c
+++ b/src/addressbook/backends/file/e-book-backend-file.c
@@ -80,7 +80,7 @@ struct _EBookBackendFilePrivate {
        gchar     *photo_dirname;
        gchar     *revision;
        gchar     *locale;
-       gint       rev_counter;
+       volatile gint rev_counter;
        gboolean   revision_guards;
        GRWLock    lock;
        GList     *cursors;
@@ -643,7 +643,8 @@ e_book_backend_file_create_unique_id (void)
 }
 
 static gchar *
-e_book_backend_file_new_revision (EBookBackendFile *bf)
+e_book_backend_file_new_revision (EBookBackendFile *bf,
+                                 gboolean with_counter)
 {
        gchar time_string[100] = {0};
        const struct tm *tm = NULL;
@@ -654,7 +655,10 @@ e_book_backend_file_new_revision (EBookBackendFile *bf)
        if (tm)
                strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", tm);
 
-       return g_strdup_printf ("%s(%d)", time_string, bf->priv->rev_counter++);
+       if (with_counter)
+               return g_strdup_printf ("%s(%d)", time_string, g_atomic_int_add (&bf->priv->rev_counter, 1));
+
+       return g_strdup (time_string);
 }
 
 /* For now just bump the revision and set it in the DB every
@@ -670,7 +674,7 @@ e_book_backend_file_bump_revision (EBookBackendFile *bf,
        gchar *new_revision;
        gboolean success;
 
-       new_revision = e_book_backend_file_new_revision (bf);
+       new_revision = e_book_backend_file_new_revision (bf, TRUE);
        success = e_book_sqlite_set_key_value (
                bf->priv->sqlitedb,
                SQLITE_REVISION_KEY,
@@ -734,7 +738,7 @@ set_revision (EBookBackendFile *bf,
 {
        gchar *rev;
 
-       rev = e_book_backend_file_new_revision (bf);
+       rev = e_book_backend_file_new_revision (bf, FALSE);
        e_contact_set (contact, E_CONTACT_REV, rev);
        g_free (rev);
 }
diff --git a/src/addressbook/backends/google/e-book-backend-google.c 
b/src/addressbook/backends/google/e-book-backend-google.c
index d627cb476..4d83428f6 100644
--- a/src/addressbook/backends/google/e-book-backend-google.c
+++ b/src/addressbook/backends/google/e-book-backend-google.c
@@ -33,6 +33,15 @@
 #include "e-book-backend-google.h"
 #include "e-book-google-utils.h"
 
+#ifdef G_OS_WIN32
+#ifdef gmtime_r
+#undef gmtime_r
+#endif
+
+/* The gmtime() in Microsoft's C library is MT-safe */
+#define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
+#endif
+
 #define URI_GET_CONTACTS "https://www.google.com/m8/feeds/contacts/default/full";
 
 /* Local cache data version. Change it to re-download whole book content */
@@ -571,7 +580,9 @@ ebb_google_get_changes_sync (EBookMetaBackend *meta_backend,
                                if (cached_contact) {
                                        gchar *old_etag;
 
-                                       old_etag = e_contact_get (cached_contact, E_CONTACT_REV);
+                                       old_etag = e_vcard_util_dup_x_attribute (E_VCARD (cached_contact), 
E_GOOGLE_X_ETAG);
+                                       if (!old_etag)
+                                               old_etag = e_contact_get (cached_contact, E_CONTACT_REV);
 
                                        if (g_strcmp0 (gdata_entry_get_etag (GDATA_ENTRY (gdata_contact)), 
old_etag) == 0) {
                                                g_object_unref (cached_contact);
@@ -589,8 +600,8 @@ ebb_google_get_changes_sync (EBookMetaBackend *meta_backend,
                                g_rec_mutex_unlock (&bbgoogle->priv->groups_lock);
 
                                if (new_contact) {
-                                       const gchar *revision, *photo_etag;
-                                       gchar *object, *extra;
+                                       const gchar *etag, *photo_etag;
+                                       gchar *object, *revision, *extra;
 
                                        photo_etag = gdata_contacts_contact_get_photo_etag (gdata_contact);
                                        if (photo_etag && cached_contact) {
@@ -647,7 +658,9 @@ ebb_google_get_changes_sync (EBookMetaBackend *meta_backend,
                                                }
                                        }
 
-                                       revision = gdata_entry_get_etag (GDATA_ENTRY (gdata_contact));
+                                       etag = gdata_entry_get_etag (GDATA_ENTRY (gdata_contact));
+                                       e_vcard_util_set_x_attribute (E_VCARD (new_contact), E_GOOGLE_X_ETAG, 
etag);
+                                       revision = e_book_google_utils_time_to_revision 
(gdata_entry_get_updated (GDATA_ENTRY (gdata_contact)));
                                        e_contact_set (new_contact, E_CONTACT_REV, revision);
                                        object = e_vcard_to_string (E_VCARD (new_contact), 
EVC_FORMAT_VCARD_30);
                                        extra = gdata_parsable_get_xml (GDATA_PARSABLE (gdata_contact));
@@ -660,6 +673,7 @@ ebb_google_get_changes_sync (EBookMetaBackend *meta_backend,
                                                        e_book_meta_backend_info_new (uid, revision, object, 
extra));
                                        }
 
+                                       g_free (revision);
                                        g_free (object);
                                        g_free (extra);
                                }
diff --git a/src/addressbook/backends/google/e-book-google-utils.c 
b/src/addressbook/backends/google/e-book-google-utils.c
index 098a85c77..650cb624d 100644
--- a/src/addressbook/backends/google/e-book-google-utils.c
+++ b/src/addressbook/backends/google/e-book-google-utils.c
@@ -581,6 +581,8 @@ e_contact_new_from_gdata_entry (GDataEntry *entry,
        GHashTable *extended_props;
        GList *websites, *events;
        GDate bdate;
+       GDateTime *dt;
+       gchar *rev = NULL;
        gboolean bdate_has_year;
        gboolean have_uri_home = FALSE, have_uri_blog = FALSE;
 
@@ -603,27 +605,23 @@ e_contact_new_from_gdata_entry (GDataEntry *entry,
        attr = e_vcard_attribute_new (NULL, EVC_UID);
        e_vcard_add_attribute_with_value (vcard, attr, uid);
 
+       if (gdata_entry_get_etag (entry))
+               e_vcard_util_set_x_attribute (vcard, E_GOOGLE_X_ETAG, gdata_entry_get_etag (entry));
+
        /* REV */
        attr = e_vcard_attribute_new (NULL, EVC_REV);
-       if (gdata_entry_get_etag (entry)) {
-               e_vcard_add_attribute_with_value (vcard, attr, gdata_entry_get_etag (entry));
-       } else {
-               GDateTime *dt;
-               gchar *rev = NULL;
-
-               dt = g_date_time_new_from_unix_utc (gdata_entry_get_updated (entry));
-               if (dt) {
-                       rev = g_date_time_format (dt, "%Y-%m-%dT%H:%M:%S");
-                       g_date_time_unref (dt);
-               }
+       dt = g_date_time_new_from_unix_utc (gdata_entry_get_updated (entry));
+       if (dt) {
+               rev = g_date_time_format (dt, "%Y-%m-%dT%H:%M:%SZ");
+               g_date_time_unref (dt);
+       }
 
-               if (!rev)
-                       rev = g_strdup_printf ("%" G_GINT64_FORMAT, gdata_entry_get_updated (entry));
+       if (!rev)
+               rev = g_strdup_printf ("%" G_GINT64_FORMAT, gdata_entry_get_updated (entry));
 
-               e_vcard_add_attribute_with_value (vcard, attr, rev);
+       e_vcard_add_attribute_with_value (vcard, attr, rev);
 
-               g_free (rev);
-       }
+       g_free (rev);
 
        /* FN, N */
        name = gdata_contacts_contact_get_name (GDATA_CONTACTS_CONTACT (entry));
@@ -1734,3 +1732,16 @@ e_book_google_utils_uid_from_entry (GDataEntry *entry)
 
        return id;
 }
+
+gchar *
+e_book_google_utils_time_to_revision (gint64 unix_time)
+{
+       struct tm stm;
+       time_t tt = (time_t) unix_time;
+       gchar time_string[100] = { 0 };
+
+       gmtime_r (&tt, &stm);
+       strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", &stm);
+
+       return g_strdup (time_string);
+}
diff --git a/src/addressbook/backends/google/e-book-google-utils.h 
b/src/addressbook/backends/google/e-book-google-utils.h
index 29e005d97..302731ba5 100644
--- a/src/addressbook/backends/google/e-book-google-utils.h
+++ b/src/addressbook/backends/google/e-book-google-utils.h
@@ -24,7 +24,8 @@
 
 #include "e-book-backend-google.h"
 
-#define E_GOOGLE_X_PHOTO_ETAG "X-EVOLUTION-GOOGLE-PHOTO-ETAG"
+#define E_GOOGLE_X_ETAG                "X-EVOLUTION-GOOGLE-ETAG"
+#define E_GOOGLE_X_PHOTO_ETAG  "X-EVOLUTION-GOOGLE-PHOTO-ETAG"
 
 G_BEGIN_DECLS
 
@@ -61,6 +62,7 @@ gchar *e_contact_sanitise_google_group_id (const gchar *group_id) G_GNUC_MALLOC
 gchar *e_contact_sanitise_google_group_name (GDataEntry *group) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 const gchar *  e_book_google_utils_uid_from_entry      (GDataEntry *entry);
+gchar *                e_book_google_utils_time_to_revision    (gint64 unix_time);
 
 G_END_DECLS
 


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