[epiphany/wip/ephy-sync: 126/126] Implement the sync logic
- From: Gabriel - Cristian Ivascu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/ephy-sync: 126/126] Implement the sync logic
- Date: Fri, 19 Aug 2016 17:42:09 +0000 (UTC)
commit d7a55ebcb4fd6906f7082c6f27a05c1c80f6bcf0
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Fri Aug 19 20:31:46 2016 +0300
Implement the sync logic
src/ephy-bookmark-properties-grid.c | 66 ++++-
src/ephy-bookmark.c | 25 ++-
src/ephy-bookmark.h | 4 +
src/ephy-bookmarks-manager.c | 7 +-
src/ephy-shell.c | 18 +-
src/ephy-shell.h | 2 +-
src/ephy-sync-crypto.c | 29 +--
src/ephy-sync-service.c | 570 +++++++++++++++++++++--------------
src/ephy-sync-service.h | 89 +++---
src/prefs-dialog.c | 15 +-
10 files changed, 524 insertions(+), 301 deletions(-)
---
diff --git a/src/ephy-bookmark-properties-grid.c b/src/ephy-bookmark-properties-grid.c
index d3ec69f..8f311ce 100644
--- a/src/ephy-bookmark-properties-grid.c
+++ b/src/ephy-bookmark-properties-grid.c
@@ -24,6 +24,7 @@
#include "ephy-bookmarks-manager.h"
#include "ephy-debug.h"
#include "ephy-shell.h"
+#include "ephy-sync-service.h"
#include "ephy-type-builtins.h"
#include <libsoup/soup.h>
@@ -46,6 +47,10 @@ struct _EphyBookmarkPropertiesGrid {
GtkWidget *add_tag_entry;
GtkWidget *add_tag_button;
GtkWidget *remove_bookmark_button;
+
+ char *prev_name;
+ char *prev_address;
+ GSequence *prev_tags;
};
G_DEFINE_TYPE (EphyBookmarkPropertiesGrid, ephy_bookmark_properties_grid, GTK_TYPE_GRID)
@@ -234,10 +239,13 @@ ephy_bookmarks_properties_grid_actions_remove_bookmark (GSimpleAction *action,
GVariant *value,
gpointer user_data)
{
+ EphySyncService *service;
EphyBookmarkPropertiesGrid *self = user_data;
g_assert (EPHY_IS_BOOKMARK_PROPERTIES_GRID (self));
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
+ ephy_sync_service_delete_bookmark (service, self->bookmark, FALSE);
ephy_bookmarks_manager_remove_bookmark (self->manager, self->bookmark);
gtk_widget_destroy (self->parent);
@@ -328,6 +336,7 @@ ephy_bookmark_properties_grid_constructed (GObject *object)
/* Set text for name entry */
gtk_entry_set_text (GTK_ENTRY (self->name_entry),
ephy_bookmark_get_title (self->bookmark));
+ self->prev_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->name_entry)));
g_object_bind_property (GTK_ENTRY (self->name_entry), "text",
self->bookmark, "title",
@@ -337,6 +346,7 @@ ephy_bookmark_properties_grid_constructed (GObject *object)
if (self->type == EPHY_BOOKMARK_PROPERTIES_GRID_TYPE_DIALOG) {
address = get_address (ephy_bookmark_get_url (self->bookmark));
gtk_entry_set_text (GTK_ENTRY (self->address_entry), address);
+ self->prev_address = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->address_entry)));
g_free (address);
g_object_bind_property (GTK_ENTRY (self->address_entry), "text",
@@ -349,6 +359,7 @@ ephy_bookmark_properties_grid_constructed (GObject *object)
G_BINDING_DEFAULT);
/* Create tag widgets */
+ self->prev_tags = g_sequence_new (g_free);
tags = ephy_bookmarks_manager_get_tags (self->manager);
bookmark_tags = ephy_bookmark_get_tags (self->bookmark);
for (iter = g_sequence_get_begin_iter (tags);
@@ -361,8 +372,11 @@ ephy_bookmark_properties_grid_constructed (GObject *object)
if (g_sequence_lookup (bookmark_tags,
(gpointer)tag,
(GCompareDataFunc)ephy_bookmark_tags_compare,
- NULL))
+ NULL)) {
selected = TRUE;
+ g_sequence_insert_sorted (self->prev_tags, g_strdup (tag),
+ (GCompareDataFunc)ephy_bookmark_tags_compare, NULL);
+ }
widget = ephy_bookmark_properties_grid_create_tag_widget (self, tag, selected);
gtk_flow_box_insert (GTK_FLOW_BOX (self->tags_box), widget, -1);
@@ -380,8 +394,58 @@ ephy_bookmark_properties_grid_destroy (GtkWidget *widget)
{
EphyBookmarkPropertiesGrid *self = EPHY_BOOKMARK_PROPERTIES_GRID (widget);
+ if (ephy_bookmark_is_uploaded (self->bookmark) == FALSE)
+ goto out;
+
+ /* Check if any actual changes were made to the name, address or tags. If yes,
+ * set the uploaded flag to FALSE. */
+
+ if (self->prev_name != NULL) {
+ if (g_strcmp0 (self->prev_name, ephy_bookmark_get_title (self->bookmark)) != 0) {
+ ephy_bookmark_set_uploaded (self->bookmark, FALSE);
+ goto out;
+ }
+ }
+
+ if (self->prev_address != NULL) {
+ if (g_strcmp0 (self->prev_address, ephy_bookmark_get_url (self->bookmark)) != 0) {
+ ephy_bookmark_set_uploaded (self->bookmark, FALSE);
+ goto out;
+ }
+ }
+
+ if (self->prev_tags != NULL) {
+ GSequence *tags = ephy_bookmark_get_tags (self->bookmark);
+ GSequenceIter *iter;
+
+ /* Check for added tags. */
+ for (iter = g_sequence_get_begin_iter (tags);
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+ if (!g_sequence_lookup (self->prev_tags, g_sequence_get (iter),
+ (GCompareDataFunc)ephy_bookmark_tags_compare, NULL)) {
+ ephy_bookmark_set_uploaded (self->bookmark, FALSE);
+ goto out;
+ }
+ }
+
+ /* Check for deleted tags. */
+ for (iter = g_sequence_get_begin_iter (self->prev_tags);
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+ if (!g_sequence_lookup (tags, g_sequence_get (iter),
+ (GCompareDataFunc)ephy_bookmark_tags_compare, NULL)) {
+ ephy_bookmark_set_uploaded (self->bookmark, FALSE);
+ goto out;
+ }
+ }
+ }
+
+out:
ephy_bookmarks_manager_save_to_file_async (self->manager, NULL, NULL, NULL);
+ g_clear_pointer (&self->prev_name, g_free);
+ g_clear_pointer (&self->prev_address, g_free);
+ g_clear_pointer (&self->prev_tags, g_sequence_free);
+
GTK_WIDGET_CLASS (ephy_bookmark_properties_grid_parent_class)->destroy (widget);
}
diff --git a/src/ephy-bookmark.c b/src/ephy-bookmark.c
index 51f1a41..d737e34 100644
--- a/src/ephy-bookmark.c
+++ b/src/ephy-bookmark.c
@@ -35,6 +35,7 @@ struct _EphyBookmark {
char *id;
double modified;
+ gboolean uploaded;
};
static JsonSerializableIface *serializable_iface = NULL;
@@ -365,6 +366,23 @@ ephy_bookmark_get_modified (EphyBookmark *self)
}
void
+ephy_bookmark_set_uploaded (EphyBookmark *self,
+ gboolean uploaded)
+{
+ g_return_if_fail (EPHY_IS_BOOKMARK (self));
+
+ self->uploaded = uploaded;
+}
+
+gboolean
+ephy_bookmark_is_uploaded (EphyBookmark *self)
+{
+ g_return_val_if_fail (EPHY_IS_BOOKMARK (self), FALSE);
+
+ return self->uploaded;
+}
+
+void
ephy_bookmark_add_tag (EphyBookmark *self,
const char *tag)
{
@@ -481,7 +499,7 @@ ephy_bookmark_to_bso (EphyBookmark *self)
g_return_val_if_fail (EPHY_IS_BOOKMARK (self), NULL);
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
sync_key = ephy_sync_crypto_decode_hex (ephy_sync_service_get_token (service, TOKEN_KB));
serialized = json_gobject_to_data (G_OBJECT (self), NULL);
encrypted = ephy_sync_crypto_aes_256 (AES_256_MODE_ENCRYPT, sync_key,
@@ -511,13 +529,13 @@ ephy_bookmark_from_bso (JsonObject *bso)
g_return_val_if_fail (bso != NULL, NULL);
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
sync_key = ephy_sync_crypto_decode_hex (ephy_sync_service_get_token (service, TOKEN_KB));
decoded = ephy_sync_crypto_base64_urlsafe_decode (json_object_get_string_member (bso, "payload"),
&decoded_len, FALSE);
decrypted = (char *) ephy_sync_crypto_aes_256 (AES_256_MODE_DECRYPT, sync_key,
decoded, decoded_len, NULL);
- object = json_gobject_from_data (EPHY_TYPE_BOOKMARK, decrypted, -1, &error);
+ object = json_gobject_from_data (EPHY_TYPE_BOOKMARK, decrypted, strlen (decrypted), &error);
if (object == NULL) {
g_warning ("Failed to create GObject from data: %s", error->message);
@@ -528,6 +546,7 @@ ephy_bookmark_from_bso (JsonObject *bso)
bookmark = EPHY_BOOKMARK (object);
ephy_bookmark_set_id (bookmark, json_object_get_string_member (bso, "id"));
ephy_bookmark_set_modified (bookmark, json_object_get_double_member (bso, "modified"));
+ ephy_bookmark_set_uploaded (bookmark, TRUE);
out:
g_free (decoded);
diff --git a/src/ephy-bookmark.h b/src/ephy-bookmark.h
index c76dffe..5d2c797 100644
--- a/src/ephy-bookmark.h
+++ b/src/ephy-bookmark.h
@@ -51,6 +51,10 @@ void ephy_bookmark_set_modified (EphyBookmark *self,
double modified);
double ephy_bookmark_get_modified (EphyBookmark *self);
+void ephy_bookmark_set_uploaded (EphyBookmark *self,
+ gboolean uploaded);
+gboolean ephy_bookmark_is_uploaded (EphyBookmark *self);
+
void ephy_bookmark_add_tag (EphyBookmark *self,
const char *tag);
void ephy_bookmark_remove_tag (EphyBookmark *self,
diff --git a/src/ephy-bookmarks-manager.c b/src/ephy-bookmarks-manager.c
index 5d801c0..cfef26e 100644
--- a/src/ephy-bookmarks-manager.c
+++ b/src/ephy-bookmarks-manager.c
@@ -68,12 +68,13 @@ build_variant (EphyBookmark *bookmark)
GSequence *tags;
GSequenceIter *iter;
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(xssdas)"));
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(xssdbas)"));
g_variant_builder_add (&builder, "x", ephy_bookmark_get_time_added (bookmark));
g_variant_builder_add (&builder, "s", ephy_bookmark_get_title (bookmark));
g_variant_builder_add (&builder, "s", ephy_bookmark_get_id (bookmark));
g_variant_builder_add (&builder, "d", ephy_bookmark_get_modified (bookmark));
+ g_variant_builder_add (&builder, "b", ephy_bookmark_is_uploaded (bookmark));
g_variant_builder_open (&builder, G_VARIANT_TYPE ("as"));
tags = ephy_bookmark_get_tags (bookmark);
@@ -561,11 +562,12 @@ ephy_bookmarks_manager_load_from_file (EphyBookmarksManager *self)
gint64 time_added;
char *id;
double modified;
+ gboolean uploaded;
/* Obtain the correspoding GVariant. */
value = gvdb_table_get_value (table, list[i]);
- g_variant_get (value, "(x&s&sdas)", &time_added, &title, &id, &modified, &iter);
+ g_variant_get (value, "(x&s&sdbas)", &time_added, &title, &id, &modified, &uploaded, &iter);
/* Add all stored tags in a GSequence. */
tags = g_sequence_new (g_free);
@@ -581,6 +583,7 @@ ephy_bookmarks_manager_load_from_file (EphyBookmarksManager *self)
ephy_bookmark_set_time_added (bookmark, time_added);
ephy_bookmark_set_id (bookmark, id);
ephy_bookmark_set_modified (bookmark, modified);
+ ephy_bookmark_set_uploaded (bookmark, uploaded);
g_sequence_prepend (bookmarks, bookmark);
}
ephy_bookmarks_manager_add_bookmarks (self, bookmarks);
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index eca6273..910b170 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -561,6 +561,15 @@ ephy_shell_init (EphyShell *shell)
ephy_shell = shell;
g_object_add_weak_pointer (G_OBJECT (ephy_shell),
(gpointer *)ptr);
+
+ ephy_shell->sync_service = ephy_sync_service_new ();
+ /* Do a start up sync and set a periodical sync afterwards. */
+ if (ephy_sync_service_is_signed_in (ephy_shell->sync_service) == TRUE) {
+ ephy_sync_service_do_periodical_sync (ephy_shell->sync_service);
+ g_timeout_add_seconds (ephy_sync_service_get_sync_frequency (ephy_shell->sync_service),
+ (GSourceFunc)ephy_sync_service_do_periodical_sync,
+ ephy_shell->sync_service);
+ }
}
static void
@@ -605,20 +614,17 @@ ephy_shell_finalize (GObject *object)
}
/**
- * ephy_shell_get_global_sync_service:
+ * ephy_shell_get_sync_service:
*
* Retrieve the default #EphySyncService object
*
- * Return value: (transfer none):
+ * Return value: (transfer none): the default #EphySyncService
**/
EphySyncService *
-ephy_shell_get_global_sync_service (EphyShell *shell)
+ephy_shell_get_sync_service (EphyShell *shell)
{
g_return_val_if_fail (EPHY_IS_SHELL (shell), NULL);
- if (shell->sync_service == NULL)
- shell->sync_service = ephy_sync_service_new ();
-
return shell->sync_service;
}
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 6dafee6..84f1eda 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -106,7 +106,7 @@ GtkWidget *ephy_shell_get_bookmarks_editor (EphyShell *shell);
EphyBookmarksManager *ephy_shell_get_bookmarks_manager (EphyShell *shell);
-EphySyncService *ephy_shell_get_global_sync_service (EphyShell *shell);
+EphySyncService *ephy_shell_get_sync_service (EphyShell *shell);
GtkWidget *ephy_shell_get_history_window (EphyShell *shell);
diff --git a/src/ephy-sync-crypto.c b/src/ephy-sync-crypto.c
index 3e4a0fb..73a2f30 100644
--- a/src/ephy-sync-crypto.c
+++ b/src/ephy-sync-crypto.c
@@ -879,35 +879,28 @@ ephy_sync_crypto_aes_256 (EphySyncCryptoAES256Mode mode,
gsize *out_len)
{
struct aes256_ctx aes;
- gsize padded_len;
+ gsize padded_len = data_len;
guint8 *padded_data;
guint8 *out;
g_return_val_if_fail (key != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
- if (mode == AES_256_MODE_DECRYPT)
- g_assert (data_len % AES_BLOCK_SIZE == 0);
-
- padded_len = data_len;
- if (data_len % AES_BLOCK_SIZE != 0)
+ if (mode == AES_256_MODE_ENCRYPT)
padded_len = data_len + (AES_BLOCK_SIZE - data_len % AES_BLOCK_SIZE);
+ else if (mode == AES_256_MODE_DECRYPT)
+ g_assert (data_len % AES_BLOCK_SIZE == 0);
- out = g_malloc (padded_len);
+ out = g_malloc0 (padded_len);
padded_data = g_malloc0 (padded_len);
memcpy (padded_data, data, data_len);
- switch (mode) {
- case AES_256_MODE_ENCRYPT:
- aes256_set_encrypt_key (&aes, key);
- aes256_encrypt (&aes, padded_len, out, padded_data);
- break;
- case AES_256_MODE_DECRYPT:
- aes256_set_decrypt_key (&aes, key);
- aes256_decrypt (&aes, padded_len, out, padded_data);
- break;
- default:
- g_assert_not_reached ();
+ if (mode == AES_256_MODE_ENCRYPT) {
+ aes256_set_encrypt_key (&aes, key);
+ aes256_encrypt (&aes, padded_len, out, padded_data);
+ } else if (mode == AES_256_MODE_DECRYPT) {
+ aes256_set_decrypt_key (&aes, key);
+ aes256_decrypt (&aes, padded_len, out, padded_data);
}
if (out_len != NULL)
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index 6c9fc2e..2e9a366 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -32,16 +32,14 @@
#define MOZILLA_TOKEN_SERVER_URL "https://token.services.mozilla.com/1.0/sync/1.5"
#define MOZILLA_FXA_SERVER_URL "https://api.accounts.firefox.com/v1/"
-
-#define DUMMY_BOOKMARK_ID "00000000000000000000000000000000"
#define EPHY_BOOKMARKS_COLLECTION "ephy-bookmarks"
-
#define EMAIL_REGEX "^[a-zA-Z0-9_]([a-zA-Z0-9._]+[a-zA-Z0-9_])?@[a-z0-9.-]+$"
struct _EphySyncService {
GObject parent_instance;
SoupSession *session;
+ guint sync_frequency;
gchar *uid;
gchar *sessionToken;
@@ -54,7 +52,7 @@ struct _EphySyncService {
double sync_time;
gint64 auth_at;
- gboolean is_locked;
+ gboolean locked;
gchar *storage_endpoint;
gchar *storage_credentials_id;
gchar *storage_credentials_key;
@@ -596,6 +594,7 @@ ephy_sync_service_init (EphySyncService *self)
self->session = soup_session_new ();
self->storage_queue = g_queue_new ();
+ self->sync_frequency = 15 * 60;
email = g_settings_get_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_USER);
@@ -664,6 +663,23 @@ ephy_sync_service_set_sync_time (EphySyncService *self,
g_settings_set_double (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_TIME, time);
}
+guint
+ephy_sync_service_get_sync_frequency (EphySyncService *self)
+{
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), G_MAXUINT);
+
+ return self->sync_frequency;
+}
+
+void
+ephy_sync_service_set_sync_frequency (EphySyncService *self,
+ guint sync_frequency)
+{
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+
+ self->sync_frequency = sync_frequency;
+}
+
gchar *
ephy_sync_service_get_token (EphySyncService *self,
EphySyncTokenType type)
@@ -914,8 +930,8 @@ ephy_sync_service_send_storage_message (EphySyncService *self,
/* If there is currently another message being transmitted, then the new
* message has to wait in the queue, otherwise, it is free to go.
*/
- if (self->is_locked == FALSE) {
- self->is_locked = TRUE;
+ if (self->locked == FALSE) {
+ self->locked = TRUE;
ephy_sync_service_issue_storage_request (self, data);
} else {
g_queue_push_tail (self->storage_queue, data);
@@ -927,7 +943,7 @@ ephy_sync_service_release_next_storage_message (EphySyncService *self)
{
g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
/* We should never reach this with the service not being locked. */
- g_assert (self->is_locked == TRUE);
+ g_assert (self->locked == TRUE);
/* If there are other messages waiting in the queue, we release the next one
* and keep the service locked, else, we mark the service as not locked.
@@ -935,107 +951,179 @@ ephy_sync_service_release_next_storage_message (EphySyncService *self)
if (g_queue_is_empty (self->storage_queue) == FALSE)
ephy_sync_service_issue_storage_request (self, g_queue_pop_head (self->storage_queue));
else
- self->is_locked = FALSE;
+ self->locked = FALSE;
}
static void
-log_all_message_info (const gchar *text,
- SoupMessage *message)
+upload_bookmark_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
- LOG ("%s:", text);
- LOG ("status_code: %u", message->status_code);
- LOG ("response_body: %s", message->response_body->data);
- LOG ("Retry-After: %s", soup_message_headers_get_one (message->response_headers, "Retry-After"));
- LOG ("X-Weave-Backoff: %s", soup_message_headers_get_one (message->response_headers, "X-Weave-Backoff"));
- LOG ("X-Last-Modified: %s", soup_message_headers_get_one (message->response_headers, "X-Last-Modified"));
- LOG ("X-Weave-Timestamp: %s", soup_message_headers_get_one (message->response_headers,
"X-Weave-Timestamp"));
- LOG ("X-Weave-Records: %s", soup_message_headers_get_one (message->response_headers, "X-Weave-Records"));
- LOG ("X-Weave-Next-Offset: %s", soup_message_headers_get_one (message->response_headers,
"X-Weave-Next-Offset"));
- LOG ("X-Weave-Quota-Remaining: %s", soup_message_headers_get_one (message->response_headers,
"X-Weave-Quota-Remaining"));
- LOG ("X-Weave-Alert: %s", soup_message_headers_get_one (message->response_headers, "X-Weave-Alert"));
+ EphySyncService *service;
+ EphyBookmarksManager *manager;
+ EphyBookmark *bookmark;
+ double last_modified;
+
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
+ manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
+ bookmark = EPHY_BOOKMARK (user_data);
+
+ if (msg->status_code == 200) {
+ last_modified = g_ascii_strtod (msg->response_body->data, NULL);
+ ephy_bookmark_set_modified (bookmark, last_modified);
+ ephy_bookmark_set_uploaded (bookmark, TRUE);
+ ephy_bookmarks_manager_save_to_file_async (manager, NULL, NULL, NULL);
+
+ LOG ("Successfully uploaded to server");
+ } else if (msg->status_code == 412) {
+ ephy_sync_service_download_bookmark (service, bookmark);
+ } else {
+ LOG ("Failed to upload to server. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ }
+
+ ephy_sync_service_release_next_storage_message (service);
+}
+
+void
+ephy_sync_service_upload_bookmark (EphySyncService *self,
+ EphyBookmark *bookmark,
+ gboolean force)
+{
+ gchar *endpoint;
+ gchar *bso;
+ double modified;
+
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (ephy_sync_service_is_signed_in (self));
+ g_return_if_fail (EPHY_IS_BOOKMARK (bookmark));
+
+ endpoint = g_strdup_printf ("storage/%s/%s",
+ EPHY_BOOKMARKS_COLLECTION,
+ ephy_bookmark_get_id (bookmark));
+ bso = ephy_bookmark_to_bso (bookmark);
+ modified = ephy_bookmark_get_modified (bookmark);
+ ephy_sync_service_send_storage_message (self, endpoint,
+ SOUP_METHOD_PUT, bso, -1,
+ force ? -1 : modified,
+ upload_bookmark_response_cb,
+ bookmark);
+
+ g_free (endpoint);
+ g_free (bso);
}
static void
-create_bookmarks_storage_collection_response_cb (SoupSession *session,
- SoupMessage *message,
- gpointer user_data)
+download_bookmark_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
EphySyncService *service;
+ EphyBookmarksManager *manager;
+ EphyBookmark *bookmark;
+ GSequenceIter *iter;
+ JsonParser *parser;
+ JsonObject *bso;
+ const gchar *id;
- /* Code 412 means that the BSO already exists. Don't treat this as an error. */
- if (message->status_code != 200 && message->status_code != 412)
- LOG ("Failed to add the dummy BSO. Status code: %u, response: %s",
- message->status_code, message->response_body->data);
+ if (msg->status_code != 200) {
+ LOG ("Failed to download from server. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ goto out;
+ }
+
+ parser = json_parser_new ();
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
+ bso = json_node_get_object (json_parser_get_root (parser));
+ bookmark = ephy_bookmark_from_bso (bso);
+ id = ephy_bookmark_get_id (bookmark);
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ /* Overwrite any local bookmark. */
+ manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
+ ephy_bookmarks_manager_remove_bookmark (manager,
+ ephy_bookmarks_manager_get_bookmark_by_id (manager, id));
+ ephy_bookmarks_manager_add_bookmark (manager, bookmark);
+
+ /* We have to manually add the tags to the bookmarks manager. */
+ for (iter = g_sequence_get_begin_iter (ephy_bookmark_get_tags (bookmark));
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
+ ephy_bookmarks_manager_add_tag (manager, g_sequence_get (iter));
+
+ g_object_unref (parser);
+
+out:
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
ephy_sync_service_release_next_storage_message (service);
}
void
-ephy_sync_service_create_bookmarks_storage_collection (EphySyncService *self)
+ephy_sync_service_download_bookmark (EphySyncService *self,
+ EphyBookmark *bookmark)
{
- EphyBookmark *dummy;
gchar *endpoint;
- gchar *bso;
g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
g_return_if_fail (ephy_sync_service_is_signed_in (self));
+ g_return_if_fail (EPHY_IS_BOOKMARK (bookmark));
- endpoint = g_strdup_printf ("storage/%s/%s", EPHY_BOOKMARKS_COLLECTION, DUMMY_BOOKMARK_ID);
- dummy = ephy_bookmark_new (g_strdup (DUMMY_BOOKMARK_ID),
- g_strdup (DUMMY_BOOKMARK_ID),
- g_sequence_new (g_free));
- ephy_bookmark_set_id (dummy, DUMMY_BOOKMARK_ID);
- bso = ephy_bookmark_to_bso (dummy);
-
- /* Send a dummy BSO to the Storage Server so it will create the
- * EPHY_BOOKMARKS_COLLECTION collection if it doesn't exist already.
- */
- ephy_sync_service_send_storage_message (self, endpoint, SOUP_METHOD_PUT,
- bso, -1, 0,
- create_bookmarks_storage_collection_response_cb, NULL);
+ endpoint = g_strdup_printf ("storage/%s/%s",
+ EPHY_BOOKMARKS_COLLECTION,
+ ephy_bookmark_get_id (bookmark));
+ ephy_sync_service_send_storage_message (self, endpoint,
+ SOUP_METHOD_GET, NULL, -1, -1,
+ download_bookmark_response_cb, NULL);
g_free (endpoint);
- g_free (bso);
}
static void
-upload_bookmark_to_server_response_cb (SoupSession *session,
- SoupMessage *message,
- gpointer user_data)
+delete_bookmark_conditional_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
EphySyncService *service;
- EphyBookmarksManager *manager;
EphyBookmark *bookmark;
- double last_modified;
+ EphyBookmarksManager *manager;
- if (message->status_code == 200) {
- bookmark = EPHY_BOOKMARK (user_data);
- last_modified = g_ascii_strtod (message->response_body->data, NULL);
- ephy_bookmark_set_modified (bookmark, last_modified);
- manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
- ephy_bookmarks_manager_save_to_file_async (manager, NULL, NULL, NULL);
+ bookmark = EPHY_BOOKMARK (user_data);
+ manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
- LOG ("Successfully uploaded bookmark to server.");
- } else if (message->status_code == 412) {
- /* FIXME: A more recent value is on the server. See how to handle this. */
+ if (msg->status_code == 404) {
+ ephy_bookmarks_manager_remove_bookmark (manager, bookmark);
+ } else if (msg->status_code == 200) {
+ LOG ("The bookmark still exists on the server, don't delete it");
} else {
- LOG ("Failed to upload bookmark to the server. Status code: %u, response: %s",
- message->status_code, message->response_body->data);
+ LOG ("Failed to delete conditionally. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
}
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
+ ephy_sync_service_release_next_storage_message (service);
+}
+
+static void
+delete_bookmark_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ EphySyncService *service;
+
+ if (msg->status_code == 200)
+ LOG ("Successfully deleted the bookmark from the server");
+ else
+ LOG ("Failed to delete. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
ephy_sync_service_release_next_storage_message (service);
}
void
-ephy_sync_service_upload_bookmark_to_server (EphySyncService *self,
- EphyBookmark *bookmark,
- gboolean force)
+ephy_sync_service_delete_bookmark (EphySyncService *self,
+ EphyBookmark *bookmark,
+ gboolean conditional)
{
gchar *endpoint;
- gchar *bso;
- double modified;
g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
g_return_if_fail (ephy_sync_service_is_signed_in (self));
@@ -1044,230 +1132,264 @@ ephy_sync_service_upload_bookmark_to_server (EphySyncService *self,
endpoint = g_strdup_printf ("storage/%s/%s",
EPHY_BOOKMARKS_COLLECTION,
ephy_bookmark_get_id (bookmark));
- bso = ephy_bookmark_to_bso (bookmark);
- modified = ephy_bookmark_get_modified (bookmark);
- ephy_sync_service_send_storage_message (self, endpoint,
- SOUP_METHOD_PUT, bso, -1,
- force ? -1 : modified,
- upload_bookmark_to_server_response_cb,
- bookmark);
+
+ /* If the bookmark does not exist on the server, delete it from the local
+ * instance too. */
+ if (conditional == TRUE) {
+ ephy_sync_service_send_storage_message (self, endpoint,
+ SOUP_METHOD_GET, NULL, -1, -1,
+ delete_bookmark_conditional_response_cb,
+ bookmark);
+ } else {
+ ephy_sync_service_send_storage_message (self, endpoint,
+ SOUP_METHOD_DELETE, NULL, -1, -1,
+ delete_bookmark_response_cb, NULL);
+ }
g_free (endpoint);
- g_free (bso);
}
static void
-merge_local_and_remote_bookmarks_response_cb (SoupSession *session,
- SoupMessage *message,
- gpointer user_data)
+sync_bookmarks_first_time_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
EphySyncService *service;
EphyBookmarksManager *manager;
GSequence *bookmarks;
+ GSequenceIter *iter;
+ GHashTable *marked;
JsonParser *parser;
JsonArray *array;
- GList *remotes = NULL;
- GList *locals = NULL;
const gchar *timestamp;
- gboolean *marked_locals = NULL;
- gboolean *marked_remotes = NULL;
double server_time;
- gsize i;
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
bookmarks = ephy_bookmarks_manager_get_bookmarks (manager);
+ marked = 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);
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
- if (message->status_code != 200) {
- LOG ("Failed to merge local and remote bookmarks. Status code: %u, response: %s",
- message->status_code, message->response_body->data);
+ if (msg->status_code != 200) {
+ LOG ("Failed to do a first time sync. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
goto out;
}
- /* Convert all BSOs to EphyBookmark objects. */
array = json_node_get_array (json_parser_get_root (parser));
- for (i = 0; i < json_array_get_length (array); i++) {
+ 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);
+ EphyBookmark *remote = ephy_bookmark_from_bso (bso);
+ EphyBookmark *local;
- if (g_strcmp0 (ephy_bookmark_get_id (bookmark), DUMMY_BOOKMARK_ID) == 0)
- g_object_unref (bookmark);
- else
- remotes = g_list_append (remotes, bookmark);
- }
+ if (remote == NULL)
+ continue;
- /* If we have no remote bookmarks, then we directly upload all the local
- * bookmarks to the server.
- */
- if (g_list_length (remotes) == 0) {
- for (GSequenceIter *iter = g_sequence_get_begin_iter (bookmarks);
- !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
- ephy_sync_service_upload_bookmark_to_server (service, g_sequence_get (iter), TRUE);
- goto out;
- }
+ local = ephy_bookmarks_manager_get_bookmark_by_id (manager, ephy_bookmark_get_id (remote));
- /* 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 (GList *r = remotes; r != NULL; r = r->next)
- ephy_bookmarks_manager_add_bookmark (manager, EPHY_BOOKMARK (r->data));
- goto out;
- }
+ if (local == NULL) {
+ local = ephy_bookmarks_manager_get_bookmark_by_url (manager, ephy_bookmark_get_url (remote));
- /* If we have both local and remote bookmarks, then we merge them in the
- * nicest way possible (see the two cases below).
- */
- for (GSequenceIter *iter = g_sequence_get_begin_iter (bookmarks);
- !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
- locals = g_list_append (locals, g_sequence_get (iter));
-
- marked_locals = g_malloc0 (g_list_length (locals) * sizeof (gboolean));
- marked_remotes = g_malloc0 (g_list_length (remotes) * sizeof (gboolean));
-
- i = 0;
- for (GList *l = locals; l != NULL; l = l->next, i++) {
- EphyBookmark *local = EPHY_BOOKMARK (l->data);
- 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);
- gsize j = 0;
-
- for (GList *r = remotes; r != NULL; r = r->next, j++) {
- if (marked_remotes[j] == FALSE) {
- EphyBookmark *remote = EPHY_BOOKMARK (r->data);
- 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);
-
- /* 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 (local_id, remote_id) == 0) {
- if (local_modified > remote_modified) {
- ephy_sync_service_upload_bookmark_to_server (service, local, TRUE);
- } else if (remote_modified > local_modified) {
- ephy_bookmarks_manager_remove_bookmark (manager, local);
- ephy_bookmarks_manager_add_bookmark (manager, remote);
- } else {
- g_object_unref (remote);
- }
- marked_locals[i] = marked_remotes[j] = TRUE;
- break;
- }
+ /* If there is no local equivalent of the remote bookmark, then add it to
+ * the local instance together with its tags. */
+ if (local == NULL) {
+ ephy_bookmarks_manager_add_bookmark (manager, remote);
+
+ /* We have to manually add the tags to the bookmarks manager. */
+ for (iter = g_sequence_get_begin_iter (ephy_bookmark_get_tags (remote));
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
+ ephy_bookmarks_manager_add_tag (manager, g_sequence_get (iter));
- /* Case 2: different ids, same urls.
- * Merge tags into the local bookmark, keep the remote id and upload it
- * to server. The add_tag functions will ignore the duplicates themselves.
- */
- if (g_strcmp0 (local_url, remote_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);
- ephy_bookmark_add_tag (local, tag);
- ephy_bookmarks_manager_add_tag (manager, tag);
- }
-
- ephy_bookmark_set_id (local, remote_id);
- ephy_sync_service_upload_bookmark_to_server (service, local, TRUE);
- g_object_unref (remote);
- marked_locals[i] = marked_remotes[j] = TRUE;
- break;
+ g_hash_table_add (marked, remote);
+ }
+ /* If there is a local bookmark with the same url as the remote one, then
+ * merge tags into the local one, keep the remote id and upload it to the
+ * server. */
+ else {
+ for (iter = g_sequence_get_begin_iter (ephy_bookmark_get_tags (remote));
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+ ephy_bookmark_add_tag (local, g_sequence_get (iter));
+ ephy_bookmarks_manager_add_tag (manager, g_sequence_get (iter));
}
+
+ ephy_bookmark_set_id (local, ephy_bookmark_get_id (remote));
+ ephy_sync_service_upload_bookmark (service, local, TRUE);
+ g_object_unref (remote);
+ g_hash_table_add (marked, local);
+ }
+ }
+ /* Having a local bookmark with the same id as the remote one means that the
+ * bookmark has been synced before in the past. Keep the one with the most
+ * recent modified timestamp. */
+ else {
+ if (ephy_bookmark_get_modified (remote) > ephy_bookmark_get_modified (local)) {
+ ephy_bookmarks_manager_remove_bookmark (manager, local);
+ ephy_bookmarks_manager_add_bookmark (manager, remote);
+
+ /* We have to manually add the tags to the bookmarks manager. */
+ for (iter = g_sequence_get_begin_iter (ephy_bookmark_get_tags (remote));
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
+ ephy_bookmarks_manager_add_tag (manager, g_sequence_get (iter));
+
+ g_hash_table_add (marked, remote);
+ } else {
+ if (ephy_bookmark_get_modified (local) > ephy_bookmark_get_modified (remote))
+ ephy_sync_service_upload_bookmark (service, local, TRUE);
+
+ g_hash_table_add (marked, local);
+ g_object_unref (remote);
}
}
}
- /* The remaining unmarked local bookmarks will be directly uploaded to the server. */
- i = 0;
- for (GList *l = locals; l != NULL; l = l->next, i++)
- if (marked_locals[i] == FALSE)
- ephy_sync_service_upload_bookmark_to_server (service, EPHY_BOOKMARK (l->data), TRUE);
+ /* Upload the remaining local bookmarks to the server. */
+ for (iter = g_sequence_get_begin_iter (bookmarks);
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+ EphyBookmark *bookmark = g_sequence_get (iter);
- /* The remaining unmarked remote bookmarks will be added to the local instance. */
- i = 0;
- for (GList *r = remotes; r != NULL; r = r->next, i++)
- if (marked_remotes[i] == FALSE)
- ephy_bookmarks_manager_add_bookmark (manager, EPHY_BOOKMARK (r->data));
+ if (g_hash_table_contains (marked, bookmark) == FALSE)
+ ephy_sync_service_upload_bookmark (service, bookmark, TRUE);
+ }
/* Save changes to file. */
ephy_bookmarks_manager_save_to_file_async (manager, NULL, NULL, NULL);
/* Set the sync time. */
- timestamp = soup_message_headers_get_one (message->response_headers, "X-Weave-Timestamp");
+ timestamp = soup_message_headers_get_one (msg->response_headers, "X-Weave-Timestamp");
server_time = g_ascii_strtod (timestamp, NULL);
ephy_sync_service_set_sync_time (service, server_time);
out:
g_object_unref (parser);
- g_list_free (locals);
- g_list_free (remotes);
- g_free (marked_locals);
- g_free (marked_remotes);
+ g_hash_table_unref (marked);
ephy_sync_service_release_next_storage_message (service);
}
-void
-ephy_sync_service_merge_local_and_remote_bookmarks (EphySyncService *self)
+static void
+sync_bookmarks_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
- gchar *endpoint;
+ EphySyncService *service;
+ EphyBookmarksManager *manager;
+ GSequence *bookmarks;
+ GSequenceIter *iter;
+ JsonParser *parser;
+ JsonArray *array;
+ const gchar *timestamp;
+ double server_time;
- g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
- g_return_if_fail (ephy_sync_service_is_signed_in (self));
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
+ manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
+ bookmarks = ephy_bookmarks_manager_get_bookmarks (manager);
+ parser = json_parser_new ();
+ json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
- endpoint = g_strdup_printf ("storage/%s?full=true", EPHY_BOOKMARKS_COLLECTION);
- ephy_sync_service_send_storage_message (self, endpoint,
- SOUP_METHOD_GET, NULL, -1, -1,
- merge_local_and_remote_bookmarks_response_cb, NULL);
- g_free (endpoint);
-}
+ /* Code 304 indicates that the resource has not been modifiedf. Therefore,
+ * only upload the local bookmarks that were not uploaded. */
+ if (msg->status_code == 304)
+ goto handle_local_bookmarks;
-static void
-storage_server_response_default_cb (SoupSession *session,
- SoupMessage *message,
- gpointer user_data)
-{
- EphySyncService *service;
+ if (msg->status_code != 200) {
+ LOG ("Failed to sync bookmarks. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ goto out;
+ }
+
+ array = json_node_get_array (json_parser_get_root (parser));
+ 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);
+ EphyBookmark *local;
+
+ if (remote == NULL)
+ continue;
+
+ local = ephy_bookmarks_manager_get_bookmark_by_id (manager, ephy_bookmark_get_id (remote));
+
+ if (local == NULL) {
+ ephy_bookmarks_manager_add_bookmark (manager, remote);
+
+ /* We have to manually add the tags to the bookmarks manager. */
+ for (iter = g_sequence_get_begin_iter (ephy_bookmark_get_tags (remote));
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
+ ephy_bookmarks_manager_add_tag (manager, g_sequence_get (iter));
+ } else {
+ if (ephy_bookmark_get_modified (remote) > ephy_bookmark_get_modified (local)) {
+ ephy_bookmarks_manager_remove_bookmark (manager, local);
+ ephy_bookmarks_manager_add_bookmark (manager, remote);
+
+ /* We have to manually add the tags to the bookmarks manager. */
+ for (iter = g_sequence_get_begin_iter (ephy_bookmark_get_tags (remote));
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter))
+ ephy_bookmarks_manager_add_tag (manager, g_sequence_get (iter));
+ } else {
+ if (ephy_bookmark_get_modified (local) > ephy_bookmark_get_modified (remote))
+ ephy_sync_service_upload_bookmark (service, local, TRUE);
+
+ g_object_unref (remote);
+ }
+ }
+ }
+
+handle_local_bookmarks:
+ for (iter = g_sequence_get_begin_iter (bookmarks);
+ !g_sequence_iter_is_end (iter); iter = g_sequence_iter_next (iter)) {
+ EphyBookmark *bookmark = EPHY_BOOKMARK (g_sequence_get (iter));
+
+ if (ephy_bookmark_is_uploaded (bookmark) == TRUE)
+ ephy_sync_service_delete_bookmark (service, bookmark, TRUE);
+ else
+ ephy_sync_service_upload_bookmark (service, bookmark, FALSE);
+ }
+
+ /* Save changes to file. */
+ ephy_bookmarks_manager_save_to_file_async (manager, NULL, NULL, NULL);
+
+ /* Set the sync time. */
+ timestamp = soup_message_headers_get_one (msg->response_headers, "X-Weave-Timestamp");
+ server_time = g_ascii_strtod (timestamp, NULL);
+ ephy_sync_service_set_sync_time (service, server_time);
- log_all_message_info ("storage_server_response_default_cb", message);
+out:
+ g_object_unref (parser);
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
ephy_sync_service_release_next_storage_message (service);
}
void
-ephy_sync_service_check_bookmarks_storage_collection (EphySyncService *self)
+ephy_sync_service_sync_bookmarks (EphySyncService *self,
+ gboolean first)
{
gchar *endpoint;
g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
g_return_if_fail (ephy_sync_service_is_signed_in (self));
- endpoint = g_strdup_printf ("storage/%s", EPHY_BOOKMARKS_COLLECTION);
- ephy_sync_service_send_storage_message (self, endpoint,
- SOUP_METHOD_GET, NULL, -1, -1,
- storage_server_response_default_cb, NULL);
+ endpoint = g_strdup_printf ("storage/%s?full=true", EPHY_BOOKMARKS_COLLECTION);
+
+ if (first == TRUE) {
+ ephy_sync_service_send_storage_message (self, endpoint,
+ SOUP_METHOD_GET, NULL, -1, -1,
+ sync_bookmarks_first_time_response_cb, NULL);
+ } else {
+ ephy_sync_service_send_storage_message (self, endpoint,
+ SOUP_METHOD_GET, NULL,
+ ephy_sync_service_get_sync_time (self), -1,
+ sync_bookmarks_response_cb, NULL);
+ }
+
g_free (endpoint);
}
-void
-ephy_sync_service_delete_bookmarks_storage_collection (EphySyncService *self)
+gboolean
+ephy_sync_service_do_periodical_sync (EphySyncService *self)
{
- gchar *endpoint;
+ g_return_val_if_fail (EPHY_IS_SYNC_SERVICE (self), G_SOURCE_REMOVE);
- g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
- g_return_if_fail (ephy_sync_service_is_signed_in (self));
+ ephy_sync_service_sync_bookmarks (self, FALSE);
- endpoint = g_strdup_printf ("storage/%s", EPHY_BOOKMARKS_COLLECTION);
- ephy_sync_service_send_storage_message (self, endpoint,
- SOUP_METHOD_DELETE, NULL, -1, -1,
- storage_server_response_default_cb, NULL);
- g_free (endpoint);
+ return G_SOURCE_CONTINUE;
}
diff --git a/src/ephy-sync-service.h b/src/ephy-sync-service.h
index 7d794e7..2bb0561 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -31,47 +31,54 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphySyncService, ephy_sync_service, EPHY, SYNC_SERVICE, GObject)
-EphySyncService *ephy_sync_service_new (void);
-gboolean ephy_sync_service_is_signed_in (EphySyncService *self);
-gchar *ephy_sync_service_get_user_email (EphySyncService *self);
-void ephy_sync_service_set_user_email (EphySyncService *self,
- const gchar *email);
-double ephy_sync_service_get_sync_time (EphySyncService *self);
-void ephy_sync_service_set_sync_time (EphySyncService *self,
- double time);
-gchar *ephy_sync_service_get_token (EphySyncService *self,
- EphySyncTokenType type);
-void ephy_sync_service_set_token (EphySyncService *self,
- gchar *value,
- EphySyncTokenType type);
-void ephy_sync_service_set_and_store_tokens (EphySyncService *self,
- gchar *value,
- EphySyncTokenType type,
- ...) G_GNUC_NULL_TERMINATED;
-void ephy_sync_service_clear_storage_credentials (EphySyncService *self);
-void ephy_sync_service_clear_tokens (EphySyncService *self);
-void ephy_sync_service_destroy_session (EphySyncService *self,
- const gchar *sessionToken);
-gboolean ephy_sync_service_fetch_sync_keys (EphySyncService *self,
- const gchar *email,
- const gchar *keyFetchToken,
- const gchar *unwrapBKey);
-void ephy_sync_service_send_storage_message (EphySyncService *self,
- gchar *endpoint,
- const gchar *method,
- gchar *request_body,
- double modified_since,
- double
unmodified_since,
- SoupSessionCallback callback,
- gpointer user_data);
-void ephy_sync_service_release_next_storage_message (EphySyncService *self);
-void ephy_sync_service_create_bookmarks_storage_collection (EphySyncService *self);
-void ephy_sync_service_upload_bookmark_to_server (EphySyncService *self,
- EphyBookmark *bookmark,
- gboolean force);
-void ephy_sync_service_merge_local_and_remote_bookmarks (EphySyncService *self);
-void ephy_sync_service_check_bookmarks_storage_collection (EphySyncService *self);
-void ephy_sync_service_delete_bookmarks_storage_collection (EphySyncService *self);
+EphySyncService *ephy_sync_service_new (void);
+gboolean ephy_sync_service_is_signed_in (EphySyncService *self);
+gchar *ephy_sync_service_get_user_email (EphySyncService *self);
+void ephy_sync_service_set_user_email (EphySyncService *self,
+ const gchar *email);
+double ephy_sync_service_get_sync_time (EphySyncService *self);
+void ephy_sync_service_set_sync_time (EphySyncService *self,
+ double time);
+guint ephy_sync_service_get_sync_frequency (EphySyncService *self);
+void ephy_sync_service_set_sync_frequency (EphySyncService *self,
+ guint sync_frequency);
+gchar *ephy_sync_service_get_token (EphySyncService *self,
+ EphySyncTokenType type);
+void ephy_sync_service_set_token (EphySyncService *self,
+ gchar *value,
+ EphySyncTokenType type);
+void ephy_sync_service_set_and_store_tokens (EphySyncService *self,
+ gchar *value,
+ EphySyncTokenType type,
+ ...) G_GNUC_NULL_TERMINATED;
+void ephy_sync_service_clear_storage_credentials (EphySyncService *self);
+void ephy_sync_service_clear_tokens (EphySyncService *self);
+void ephy_sync_service_destroy_session (EphySyncService *self,
+ const gchar *sessionToken);
+gboolean ephy_sync_service_fetch_sync_keys (EphySyncService *self,
+ const gchar *email,
+ const gchar *keyFetchToken,
+ const gchar *unwrapBKey);
+void ephy_sync_service_send_storage_message (EphySyncService *self,
+ gchar *endpoint,
+ const gchar *method,
+ gchar *request_body,
+ double modified_since,
+ double unmodified_since,
+ SoupSessionCallback callback,
+ gpointer user_data);
+void ephy_sync_service_release_next_storage_message (EphySyncService *self);
+void ephy_sync_service_upload_bookmark (EphySyncService *self,
+ EphyBookmark *bookmark,
+ gboolean force);
+void ephy_sync_service_download_bookmark (EphySyncService *self,
+ EphyBookmark *bookmark);
+void ephy_sync_service_delete_bookmark (EphySyncService *self,
+ EphyBookmark *bookmark,
+ gboolean conditional);
+void ephy_sync_service_sync_bookmarks (EphySyncService *self,
+ gboolean first);
+gboolean ephy_sync_service_do_periodical_sync (EphySyncService *self);
G_END_DECLS
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index d473129..50b06e8 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -243,7 +243,7 @@ server_message_received_cb (WebKitUserContentManager *manager,
inject_data_to_server (dialog, "message", "login", NULL);
gtk_widget_set_visible (dialog->sync_sign_in_details, FALSE);
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
/* Extract tokens. */
data = json_object_get_object_member (detail, "data");
@@ -295,8 +295,13 @@ server_message_received_cb (WebKitUserContentManager *manager,
g_strdup (sessionToken), TOKEN_SESSIONTOKEN,
NULL);
- /* Create our own bookmarks BSO collection on the Storage Server. */
- ephy_sync_service_create_bookmarks_storage_collection (service);
+ /* Do a first time sync. */
+ ephy_sync_service_sync_bookmarks (service, TRUE);
+
+ /* Set a periodical sync. */
+ g_timeout_add_seconds (ephy_sync_service_get_sync_frequency (service),
+ (GSourceFunc) ephy_sync_service_do_periodical_sync,
+ service);
/* Translators: the %s refers to the email of the currently logged in user. */
gtk_label_set_markup (GTK_LABEL (dialog->sync_sign_out_details),
@@ -351,7 +356,7 @@ on_sync_sign_out_button_clicked (GtkWidget *button,
{
EphySyncService *service;
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
/* Destroy session and delete tokens. */
ephy_sync_service_destroy_session (service, NULL);
@@ -1490,7 +1495,7 @@ setup_sync_page (PrefsDialog *dialog)
{
EphySyncService *service;
- service = ephy_shell_get_global_sync_service (ephy_shell_get_default ());
+ service = ephy_shell_get_sync_service (ephy_shell_get_default ());
if (ephy_sync_service_is_signed_in (service) == FALSE) {
setup_fxa_sign_in_view (dialog);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]