[epiphany/wip/ephy-sync] sync-bookmarks: Function to merge the local bookmarks with the remote ones



commit afb17f393bef698ab523824056c45a7cd7011a5f
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Mon Aug 8 21:14:29 2016 +0300

    sync-bookmarks: Function to merge the local bookmarks with the remote ones

 src/ephy-sync-bookmarks.c |  132 +++++++++++++++++++++++++++++++++++++++++++++
 src/ephy-sync-bookmarks.h |    2 +
 2 files changed, 134 insertions(+), 0 deletions(-)
---
diff --git a/src/ephy-sync-bookmarks.c b/src/ephy-sync-bookmarks.c
index 742f27a..2c1c48e 100644
--- a/src/ephy-sync-bookmarks.c
+++ b/src/ephy-sync-bookmarks.c
@@ -162,6 +162,138 @@ ephy_sync_bookmarks_upload_bookmark_to_server (EphyBookmark *bookmark,
 }
 
 static void
+merge_locals_with_remotes_response_cb (SoupSession *session,
+                                       SoupMessage *message,
+                                       gpointer     user_data)
+{
+  EphySyncService *service;
+  EphyBookmarksManager *manager;
+  GSequence *bookmarks;
+  JsonParser *parser;
+  JsonArray *array;
+  GHashTable *bookmarks_to_upload;
+  GHashTableIter ht_iter;
+  gpointer key;
+
+  manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
+  bookmarks = ephy_bookmarks_manager_get_bookmarks (manager);
+  bookmarks_to_upload = g_hash_table_new (g_direct_hash, g_direct_equal);
+  parser = json_parser_new ();
+  json_parser_load_from_data (parser, message->response_body->data, -1, NULL);
+  array = json_node_get_array (json_parser_get_root (parser));
+
+  /* If we have no remote bookmarks, then we directly upload all the local
+   * bookmarks to the server.
+   */
+  if (json_array_get_length (array) == 0) {
+    for (GSequenceIter *iter = g_sequence_get_begin_iter (bookmarks);
+       !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+      ephy_sync_bookmarks_upload_bookmark_to_server (g_sequence_get (iter), TRUE);
+    }
+    goto out;
+  }
+
+  /* If we have no local bookmarks, then we add all the remote bookmarks to the
+   * local instance.
+   */
+  if (g_sequence_is_empty (bookmarks) == TRUE) {
+    for (gsize i = 0; i < json_array_get_length (array); i++) {
+      JsonObject *bso = json_array_get_object_element (array, i);
+      EphyBookmark *bookmark = ephy_bookmark_from_bso (bso);
+
+      ephy_bookmarks_manager_add_bookmark (manager, bookmark);
+    }
+    goto out;
+  }
+
+  /* If we have both local and remote bookmarks, then we merge them in the
+   * nicest way possible (see the three cases below).
+   */
+  for (gsize i = 0; i < json_array_get_length (array); i++) {
+    JsonObject *bso = json_array_get_object_element (array, i);
+    EphyBookmark *remote = ephy_bookmark_from_bso (bso);
+    const gchar *remote_id = ephy_bookmark_get_id (remote);
+    double remote_modified = ephy_bookmark_get_modified (remote);
+    const gchar *remote_url = ephy_bookmark_get_url (remote);
+
+    for (GSequenceIter *iter = g_sequence_get_begin_iter (bookmarks);
+       !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+      EphyBookmark *local = g_sequence_get (iter);
+      const gchar *local_id = ephy_bookmark_get_id (local);
+      double local_modified = ephy_bookmark_get_modified (local);
+      const gchar *local_url = ephy_bookmark_get_url (local);
+
+      /* Case 1: same ids.
+       * Since ids are globally unique, having a bookmark on the server with the
+       * same id means that the bookmark has been synced before in the past.
+       * Keep the one with most recent modified timestamp.
+       */
+      if (g_strcmp0 (remote_id, local_id) == 0) {
+        if (remote_modified > local_modified) {
+          ephy_bookmarks_manager_remove_bookmark (manager, local);
+          ephy_bookmarks_manager_add_bookmark (manager, remote);
+        } else if (local_modified > remote_modified) {
+          ephy_sync_bookmarks_upload_bookmark_to_server (local, TRUE);
+        }
+      }
+      /* Case 2: different ids, same urls.
+       * Merge tags into the local bookmark, keep the remote id and upload it
+       * to server.
+       */
+      else if (g_strcmp0 (remote_url, local_url) == 0) {
+        GSequence *tags = ephy_bookmark_get_tags (remote);
+
+        for (GSequenceIter *it = g_sequence_get_begin_iter (tags);
+             !g_sequence_iter_is_end (it); it = g_sequence_iter_next (it)) {
+          const gchar *tag = g_sequence_get (it);
+
+          /* The *_add_tag functions will handle the duplicates for us. */
+          ephy_bookmark_add_tag (local, tag);
+          ephy_bookmarks_manager_add_tag (manager, tag);
+        }
+
+        ephy_bookmark_set_id (local, remote_id);
+        ephy_sync_bookmarks_upload_bookmark_to_server (local, TRUE);
+        g_object_unref (remote);
+      }
+      /* Case 3: different ids, different urls.
+       * These are two different bookmarks. Add the remote one to the local
+       * instance and mark the local one to be later uploaded to the server.
+       */
+      else {
+        g_hash_table_add (bookmarks_to_upload, local);
+        ephy_bookmarks_manager_add_bookmark (manager, remote);
+      }
+    }
+  }
+
+  /* Send to the server the local bookmarks that have been marked for upload. */
+  g_hash_table_iter_init (&ht_iter, bookmarks_to_upload);
+  while (g_hash_table_iter_next (&ht_iter, &key, NULL) == TRUE)
+    ephy_sync_bookmarks_upload_bookmark_to_server (EPHY_BOOKMARK (key), TRUE);
+
+out:
+  g_object_unref (parser);
+  g_hash_table_unref (bookmarks_to_upload);
+  service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+  ephy_sync_service_release_next_storage_message (service);
+}
+
+void
+ephy_sync_bookmarks_merge_locals_with_remotes (void)
+{
+  EphySyncService *service;
+  gchar *endpoint;
+
+  service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+  endpoint = g_strdup_printf ("storage/%s?full=true", EPHY_BOOKMARKS_COLLECTION);
+  ephy_sync_service_send_storage_message (service, endpoint,
+                                          SOUP_METHOD_GET, NULL, -1, -1,
+                                          merge_locals_with_remotes_response_cb, NULL);
+  g_free (endpoint);
+}
+
+static void
 storage_server_response_default_cb (SoupSession *session,
                                     SoupMessage *message,
                                     gpointer     user_data)
diff --git a/src/ephy-sync-bookmarks.h b/src/ephy-sync-bookmarks.h
index db64bdf..4fce698 100644
--- a/src/ephy-sync-bookmarks.h
+++ b/src/ephy-sync-bookmarks.h
@@ -31,6 +31,8 @@ void ephy_sync_bookmarks_create_storage_collection (void);
 void ephy_sync_bookmarks_upload_bookmark_to_server (EphyBookmark *bookmark,
                                                     gboolean      force_upload);
 
+void ephy_sync_bookmarks_merge_locals_with_remotes (void);
+
 void ephy_sync_bookmarks_check_storage_collection  (void);
 
 void ephy_sync_bookmarks_delete_storage_collection (void);


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