[epiphany/wip/sync: 20/31] sync-service: Remove some circular dependencies between functions
- From: Gabriel Ivașcu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/sync: 20/31] sync-service: Remove some circular dependencies between functions
- Date: Fri, 14 Apr 2017 15:53:14 +0000 (UTC)
commit a04c12122cad7a799f67abb2671646a2d0edeaef
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Wed Apr 12 19:22:57 2017 +0300
sync-service: Remove some circular dependencies between functions
src/sync/ephy-sync-service.c | 797 +++++++++++++++++++++---------------------
1 files changed, 397 insertions(+), 400 deletions(-)
---
diff --git a/src/sync/ephy-sync-service.c b/src/sync/ephy-sync-service.c
index 7127632..096346d 100644
--- a/src/sync/ephy-sync-service.c
+++ b/src/sync/ephy-sync-service.c
@@ -122,9 +122,6 @@ typedef struct {
} SyncAsyncData;
static void ephy_sync_service_send_next_storage_request (EphySyncService *self);
-static void ephy_sync_service_stop_periodical_sync (EphySyncService *self);
-static void sync_frequency_changed_cb (EphySyncService *self);
-static void sync_secrets_store_finished_cb (EphySyncService *self, GError *error);
static StorageRequestAsyncData *
storage_request_async_data_new (const char *endpoint,
@@ -472,6 +469,61 @@ out:
}
static void
+destroy_session_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ if (msg->status_code != 200)
+ g_warning ("Failed to destroy session. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ else
+ LOG ("Successfully destroyed session");
+}
+
+static void
+ephy_sync_service_destroy_session (EphySyncService *self)
+{
+ SyncCryptoHawkOptions *hoptions;
+ SyncCryptoHawkHeader *hheader;
+ SoupMessage *msg;
+ guint8 *tokenID;
+ guint8 *reqHMACkey;
+ guint8 *requestKey;
+ char *tokenID_hex;
+ char *url;
+ const char *content_type = "application/json";
+ const char *request_body = "{}";
+
+ g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+ g_return_if_fail (ephy_sync_service_get_secret (self, secrets[SESSION_TOKEN]));
+
+ url = g_strdup_printf ("%ssession/destroy", MOZILLA_FXA_SERVER_URL);
+ ephy_sync_crypto_process_session_token (ephy_sync_service_get_secret (self, secrets[SESSION_TOKEN]),
+ &tokenID, &reqHMACkey, &requestKey, TOKEN_LENGTH);
+ tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, TOKEN_LENGTH);
+
+ msg = soup_message_new (SOUP_METHOD_POST, url);
+ soup_message_set_request (msg, content_type, SOUP_MEMORY_STATIC,
+ request_body, strlen (request_body));
+ hoptions = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL, content_type,
+ NULL, NULL, NULL, request_body, NULL);
+ hheader = ephy_sync_crypto_compute_hawk_header (url, "POST", tokenID_hex,
+ reqHMACkey, TOKEN_LENGTH,
+ hoptions);
+ soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
+ soup_message_headers_append (msg->request_headers, "content-type", content_type);
+ soup_session_queue_message (self->session, msg, destroy_session_cb, NULL);
+
+ ephy_sync_crypto_hawk_options_free (hoptions);
+ ephy_sync_crypto_hawk_header_free (hheader);
+ g_free (tokenID_hex);
+ g_free (tokenID);
+ g_free (reqHMACkey);
+ g_free (requestKey);
+ g_free (url);
+}
+
+static void
obtain_storage_credentials_cb (SoupSession *session,
SoupMessage *msg,
gpointer user_data)
@@ -827,6 +879,348 @@ ephy_sync_service_queue_storage_request (EphySyncService *self,
}
static void
+download_synchronizable_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ EphySyncService *self;
+ EphySynchronizable *synchronizable;
+ SyncCryptoKeyBundle *bundle;
+ SyncAsyncData *data;
+ JsonNode *node;
+ GError *error = NULL;
+ GType type;
+ const char *collection;
+ gboolean is_deleted;
+
+ data = (SyncAsyncData *)user_data;
+ self = ephy_shell_get_sync_service (ephy_shell_get_default ());
+
+ if (msg->status_code != 200) {
+ g_warning ("Failed to download object. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ goto out;
+ }
+
+ node = json_from_string (msg->response_body->data, &error);
+ if (error) {
+ g_warning ("Response is not a valid JSON");
+ g_error_free (error);
+ goto out;
+ }
+
+ type = ephy_synchronizable_manager_get_synchronizable_type (data->manager);
+ collection = ephy_synchronizable_manager_get_collection_name (data->manager);
+ bundle = ephy_sync_service_get_key_bundle (self, collection);
+ synchronizable = EPHY_SYNCHRONIZABLE (ephy_synchronizable_from_bso (node, type, bundle, &is_deleted));
+ if (!synchronizable) {
+ g_warning ("Failed to create synchronizable object from BSO");
+ goto free_bundle;
+ }
+
+ /* Delete the local object and add the remote one if it is not marked as deleted. */
+ ephy_synchronizable_manager_remove (data->manager, data->synchronizable);
+ if (!is_deleted) {
+ ephy_synchronizable_manager_add (data->manager, synchronizable);
+ LOG ("Successfully downloaded from server");
+ }
+
+ g_object_unref (synchronizable);
+free_bundle:
+ ephy_sync_crypto_key_bundle_free (bundle);
+ json_node_unref (node);
+out:
+ sync_async_data_free (data);
+ ephy_sync_service_send_next_storage_request (self);
+}
+
+static void
+ephy_sync_service_download_synchronizable (EphySyncService *self,
+ EphySynchronizableManager *manager,
+ EphySynchronizable *synchronizable)
+{
+ SyncAsyncData *data;
+ char *endpoint;
+ const char *collection;
+ const char *id;
+
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+ g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
+ g_assert (EPHY_IS_SYNCHRONIZABLE (synchronizable));
+
+ id = ephy_synchronizable_get_id (synchronizable);
+ collection = ephy_synchronizable_manager_get_collection_name (manager);
+ endpoint = g_strdup_printf ("storage/%s/%s", collection, id);
+ data = sync_async_data_new (manager, synchronizable);
+
+ LOG ("Downloading object with id %s...", id);
+ ephy_sync_service_queue_storage_request (self, endpoint,
+ SOUP_METHOD_GET, NULL, -1, -1,
+ download_synchronizable_cb, data);
+
+ g_free (endpoint);
+}
+
+static void
+upload_synchronizable_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ EphySyncService *self;
+ SyncAsyncData *data;
+ double modified;
+
+ data = (SyncAsyncData *)user_data;
+ self = ephy_shell_get_sync_service (ephy_shell_get_default ());
+
+ /* Code 412 means that there is a more recent version of the object
+ * on the server. Download it. */
+ if (msg->status_code == 412) {
+ LOG ("Found a newer version of the object on the server, downloading it...");
+ ephy_sync_service_download_synchronizable (self, data->manager, data->synchronizable);
+ } else if (msg->status_code == 200) {
+ LOG ("Successfully uploaded to server");
+ modified = g_ascii_strtod (msg->response_body->data, NULL);
+ /* FIXME: Make sure the synchronizable manager commits this change to file/database. */
+ ephy_synchronizable_set_modification_time (data->synchronizable, modified);
+ } else {
+ g_warning ("Failed to upload object. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ }
+
+ sync_async_data_free (data);
+ ephy_sync_service_send_next_storage_request (self);
+}
+
+static void
+ephy_sync_service_upload_synchronizable (EphySyncService *self,
+ EphySynchronizableManager *manager,
+ EphySynchronizable *synchronizable)
+{
+ SyncCryptoKeyBundle *bundle;
+ SyncAsyncData *data;
+ JsonNode *bso;
+ char *endpoint;
+ char *body;
+ const char *collection;
+ const char *id;
+
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+ g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
+ g_assert (EPHY_IS_SYNCHRONIZABLE (synchronizable));
+
+ collection = ephy_synchronizable_manager_get_collection_name (manager);
+ bundle = ephy_sync_service_get_key_bundle (self, collection);
+ bso = ephy_synchronizable_to_bso (synchronizable, bundle);
+ id = ephy_synchronizable_get_id (synchronizable);
+ endpoint = g_strdup_printf ("storage/%s/%s", collection, id);
+ data = sync_async_data_new (manager, synchronizable);
+ body = json_to_string (bso, FALSE);
+
+ LOG ("Uploading object with id %s...", id);
+ ephy_sync_service_queue_storage_request (self, endpoint, SOUP_METHOD_PUT, body, -1,
+ ephy_synchronizable_get_modification_time (synchronizable),
+ upload_synchronizable_cb, data);
+
+ g_free (body);
+ g_free (endpoint);
+ json_node_unref (bso);
+ ephy_sync_crypto_key_bundle_free (bundle);
+}
+
+static void
+sync_collection_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ EphySyncService *self;
+ SyncCollectionAsyncData *data;
+ EphySynchronizable *remote;
+ SyncCryptoKeyBundle *bundle;
+ JsonNode *node = NULL;
+ JsonArray *array;
+ GError *error = NULL;
+ GList *remotes_updated = NULL;
+ GList *remotes_deleted = NULL;
+ GList *to_upload;
+ GType type;
+ const char *collection;
+ const char *timestamp;
+ gboolean is_deleted;
+
+ self = ephy_shell_get_sync_service (ephy_shell_get_default ());
+ data = (SyncCollectionAsyncData *)user_data;
+ collection = ephy_synchronizable_manager_get_collection_name (data->manager);
+
+ /* Code 304 means that the collection has not been modified. */
+ if (msg->status_code == 304) {
+ LOG ("There are no new remote objects");
+ goto merge_remotes;
+ }
+
+ if (msg->status_code != 200) {
+ g_warning ("Failed to get records in collection %s. Status code: %u, response: %s",
+ collection, msg->status_code, msg->response_body->data);
+ goto out;
+ }
+
+ node = json_from_string (msg->response_body->data, &error);
+ if (error) {
+ g_warning ("Response is not a valid JSON: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ if (!JSON_NODE_HOLDS_ARRAY (node)) {
+ g_warning ("JSON root does not hold an array");
+ goto free_node;
+ }
+
+ type = ephy_synchronizable_manager_get_synchronizable_type (data->manager);
+ bundle = ephy_sync_service_get_key_bundle (self, collection);
+ array = json_node_get_array (node);
+
+ for (guint i = 0; i < json_array_get_length (array); i++) {
+ remote = EPHY_SYNCHRONIZABLE (ephy_synchronizable_from_bso (json_array_get_element (array, i),
+ type, bundle, &is_deleted));
+ if (!remote) {
+ g_warning ("Failed to create synchronizable object from BSO, skipping...");
+ continue;
+ }
+ if (is_deleted)
+ remotes_deleted = g_list_prepend (remotes_deleted, remote);
+ else
+ remotes_updated = g_list_prepend (remotes_updated, remote);
+ }
+
+merge_remotes:
+ to_upload = ephy_synchronizable_manager_merge_remotes (data->manager, data->is_initial,
+ remotes_deleted, remotes_updated);
+
+ if (to_upload) {
+ LOG ("Uploading local objects to server...");
+ for (GList *l = to_upload; l && l->data; l = l->next) {
+ ephy_sync_service_upload_synchronizable (self, data->manager,
+ EPHY_SYNCHRONIZABLE (l->data));
+ }
+ }
+
+ ephy_synchronizable_manager_set_is_initial_sync (data->manager, FALSE);
+ /* Update sync time. */
+ timestamp = soup_message_headers_get_one (msg->response_headers, "X-Weave-Timestamp");
+ ephy_synchronizable_manager_set_sync_time (data->manager, g_ascii_strtod (timestamp, NULL));
+
+ g_list_free_full (to_upload, g_object_unref);
+ g_list_free_full (remotes_updated, g_object_unref);
+ g_list_free_full (remotes_deleted, g_object_unref);
+free_node:
+ if (node)
+ json_node_unref (node);
+out:
+ if (data->collection_index == data->num_collections)
+ g_signal_emit (self, signals[SYNC_FINISHED], 0);
+
+ sync_collection_async_data_free (data);
+ ephy_sync_service_send_next_storage_request (self);
+}
+
+static void
+ephy_sync_service_sync_collection (EphySyncService *self,
+ EphySynchronizableManager *manager,
+ guint collection_index,
+ guint num_collections)
+{
+ SyncCollectionAsyncData *data;
+ const char *collection;
+ char *endpoint;
+ gboolean is_initial;
+
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+ g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
+
+ collection = ephy_synchronizable_manager_get_collection_name (manager);
+ endpoint = g_strdup_printf ("storage/%s?full=true", collection);
+ is_initial = ephy_synchronizable_manager_is_initial_sync (manager);
+ data = sync_collection_async_data_new (manager, is_initial, collection_index, num_collections);
+
+ LOG ("Syncing %s collection%s...", collection, is_initial ? " first time" : "");
+ ephy_sync_service_queue_storage_request (self, endpoint, SOUP_METHOD_GET, NULL,
+ is_initial ? -1 : ephy_synchronizable_manager_get_sync_time
(manager),
+ -1, sync_collection_cb, data);
+
+ g_free (endpoint);
+}
+
+static gboolean
+ephy_sync_service_sync (gpointer user_data)
+{
+ EphySyncService *self = EPHY_SYNC_SERVICE (user_data);
+ GList *managers = NULL;
+
+ managers = ephy_shell_get_synchronizable_managers (ephy_shell_get_default ());
+ if (managers) {
+ guint num_managers = g_list_length (managers);
+ guint index = 1;
+
+ for (GList *l = managers; l && l->data; l = l->next, index++)
+ ephy_sync_service_sync_collection (self,
+ EPHY_SYNCHRONIZABLE_MANAGER (l->data),
+ index, num_managers);
+
+ g_list_free (managers);
+ } else {
+ g_signal_emit (self, signals[SYNC_FINISHED], 0);
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+ephy_sync_service_stop_periodical_sync (EphySyncService *self)
+{
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+
+ if (self->source_id != 0) {
+ g_source_remove (self->source_id);
+ self->source_id = 0;
+ }
+}
+
+static void
+ephy_sync_service_schedule_periodical_sync (EphySyncService *self)
+{
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+
+ self->source_id = g_timeout_add_seconds (g_settings_get_uint (EPHY_SETTINGS_SYNC,
+ EPHY_PREFS_SYNC_FREQUENCY) * 60,
+ ephy_sync_service_sync,
+ self);
+ LOG ("Scheduled new sync with frequency %u mins",
+ g_settings_get_uint (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_FREQUENCY));
+}
+
+static void
+sync_frequency_changed_cb (EphySyncService *self)
+{
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+
+ ephy_sync_service_stop_periodical_sync (self);
+ ephy_sync_service_schedule_periodical_sync (self);
+}
+
+static void
+sync_secrets_store_finished_cb (EphySyncService *self,
+ GError *error)
+{
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+
+ if (error) {
+ ephy_sync_service_destroy_session (self);
+ g_clear_pointer (&self->user_email, g_free);
+ g_hash_table_remove_all (self->secrets);
+ }
+}
+
+static void
ephy_sync_service_finalize (GObject *object)
{
EphySyncService *self = EPHY_SYNC_SERVICE (object);
@@ -988,61 +1382,6 @@ ephy_sync_service_set_secret (EphySyncService *self,
}
static void
-destroy_session_cb (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
-{
- if (msg->status_code != 200)
- g_warning ("Failed to destroy session. Status code: %u, response: %s",
- msg->status_code, msg->response_body->data);
- else
- LOG ("Successfully destroyed session");
-}
-
-static void
-ephy_sync_service_destroy_session (EphySyncService *self)
-{
- SyncCryptoHawkOptions *hoptions;
- SyncCryptoHawkHeader *hheader;
- SoupMessage *msg;
- guint8 *tokenID;
- guint8 *reqHMACkey;
- guint8 *requestKey;
- char *tokenID_hex;
- char *url;
- const char *content_type = "application/json";
- const char *request_body = "{}";
-
- g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
- g_return_if_fail (ephy_sync_service_get_secret (self, secrets[SESSION_TOKEN]));
-
- url = g_strdup_printf ("%ssession/destroy", MOZILLA_FXA_SERVER_URL);
- ephy_sync_crypto_process_session_token (ephy_sync_service_get_secret (self, secrets[SESSION_TOKEN]),
- &tokenID, &reqHMACkey, &requestKey, TOKEN_LENGTH);
- tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, TOKEN_LENGTH);
-
- msg = soup_message_new (SOUP_METHOD_POST, url);
- soup_message_set_request (msg, content_type, SOUP_MEMORY_STATIC,
- request_body, strlen (request_body));
- hoptions = ephy_sync_crypto_hawk_options_new (NULL, NULL, NULL, content_type,
- NULL, NULL, NULL, request_body, NULL);
- hheader = ephy_sync_crypto_compute_hawk_header (url, "POST", tokenID_hex,
- reqHMACkey, TOKEN_LENGTH,
- hoptions);
- soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
- soup_message_headers_append (msg->request_headers, "content-type", content_type);
- soup_session_queue_message (self->session, msg, destroy_session_cb, NULL);
-
- ephy_sync_crypto_hawk_options_free (hoptions);
- ephy_sync_crypto_hawk_header_free (hheader);
- g_free (tokenID_hex);
- g_free (tokenID);
- g_free (reqHMACkey);
- g_free (requestKey);
- g_free (url);
-}
-
-static void
ephy_sync_service_report_sign_in_error (EphySyncService *self,
const char *message,
gboolean clear_secrets)
@@ -1459,348 +1798,6 @@ ephy_sync_service_delete_synchronizable (EphySyncService *self,
g_free (endpoint);
}
-static void
-download_synchronizable_cb (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
-{
- EphySyncService *self;
- EphySynchronizable *synchronizable;
- SyncCryptoKeyBundle *bundle;
- SyncAsyncData *data;
- JsonNode *node;
- GError *error = NULL;
- GType type;
- const char *collection;
- gboolean is_deleted;
-
- data = (SyncAsyncData *)user_data;
- self = ephy_shell_get_sync_service (ephy_shell_get_default ());
-
- if (msg->status_code != 200) {
- g_warning ("Failed to download object. Status code: %u, response: %s",
- msg->status_code, msg->response_body->data);
- goto out;
- }
-
- node = json_from_string (msg->response_body->data, &error);
- if (error) {
- g_warning ("Response is not a valid JSON");
- g_error_free (error);
- goto out;
- }
-
- type = ephy_synchronizable_manager_get_synchronizable_type (data->manager);
- collection = ephy_synchronizable_manager_get_collection_name (data->manager);
- bundle = ephy_sync_service_get_key_bundle (self, collection);
- synchronizable = EPHY_SYNCHRONIZABLE (ephy_synchronizable_from_bso (node, type, bundle, &is_deleted));
- if (!synchronizable) {
- g_warning ("Failed to create synchronizable object from BSO");
- goto free_bundle;
- }
-
- /* Delete the local object and add the remote one if it is not marked as deleted. */
- ephy_synchronizable_manager_remove (data->manager, data->synchronizable);
- if (!is_deleted) {
- ephy_synchronizable_manager_add (data->manager, synchronizable);
- LOG ("Successfully downloaded from server");
- }
-
- g_object_unref (synchronizable);
-free_bundle:
- ephy_sync_crypto_key_bundle_free (bundle);
- json_node_unref (node);
-out:
- sync_async_data_free (data);
- ephy_sync_service_send_next_storage_request (self);
-}
-
-static void
-ephy_sync_service_download_synchronizable (EphySyncService *self,
- EphySynchronizableManager *manager,
- EphySynchronizable *synchronizable)
-{
- SyncAsyncData *data;
- char *endpoint;
- const char *collection;
- const char *id;
-
- g_assert (EPHY_IS_SYNC_SERVICE (self));
- g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
- g_assert (EPHY_IS_SYNCHRONIZABLE (synchronizable));
-
- id = ephy_synchronizable_get_id (synchronizable);
- collection = ephy_synchronizable_manager_get_collection_name (manager);
- endpoint = g_strdup_printf ("storage/%s/%s", collection, id);
- data = sync_async_data_new (manager, synchronizable);
-
- LOG ("Downloading object with id %s...", id);
- ephy_sync_service_queue_storage_request (self, endpoint,
- SOUP_METHOD_GET, NULL, -1, -1,
- download_synchronizable_cb, data);
-
- g_free (endpoint);
-}
-
-static void
-upload_synchronizable_cb (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
-{
- EphySyncService *self;
- SyncAsyncData *data;
- double modified;
-
- data = (SyncAsyncData *)user_data;
- self = ephy_shell_get_sync_service (ephy_shell_get_default ());
-
- /* Code 412 means that there is a more recent version of the object
- * on the server. Download it. */
- if (msg->status_code == 412) {
- LOG ("Found a newer version of the object on the server, downloading it...");
- ephy_sync_service_download_synchronizable (self, data->manager, data->synchronizable);
- } else if (msg->status_code == 200) {
- LOG ("Successfully uploaded to server");
- modified = g_ascii_strtod (msg->response_body->data, NULL);
- /* FIXME: Make sure the synchronizable manager commits this change to file/database. */
- ephy_synchronizable_set_modification_time (data->synchronizable, modified);
- } else {
- g_warning ("Failed to upload object. Status code: %u, response: %s",
- msg->status_code, msg->response_body->data);
- }
-
- sync_async_data_free (data);
- ephy_sync_service_send_next_storage_request (self);
-}
-
-static void
-ephy_sync_service_upload_synchronizable (EphySyncService *self,
- EphySynchronizableManager *manager,
- EphySynchronizable *synchronizable)
-{
- SyncCryptoKeyBundle *bundle;
- SyncAsyncData *data;
- JsonNode *bso;
- char *endpoint;
- char *body;
- const char *collection;
- const char *id;
-
- g_assert (EPHY_IS_SYNC_SERVICE (self));
- g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
- g_assert (EPHY_IS_SYNCHRONIZABLE (synchronizable));
-
- collection = ephy_synchronizable_manager_get_collection_name (manager);
- bundle = ephy_sync_service_get_key_bundle (self, collection);
- bso = ephy_synchronizable_to_bso (synchronizable, bundle);
- id = ephy_synchronizable_get_id (synchronizable);
- endpoint = g_strdup_printf ("storage/%s/%s", collection, id);
- data = sync_async_data_new (manager, synchronizable);
- body = json_to_string (bso, FALSE);
-
- LOG ("Uploading object with id %s...", id);
- ephy_sync_service_queue_storage_request (self, endpoint, SOUP_METHOD_PUT, body, -1,
- ephy_synchronizable_get_modification_time (synchronizable),
- upload_synchronizable_cb, data);
-
- g_free (body);
- g_free (endpoint);
- json_node_unref (bso);
- ephy_sync_crypto_key_bundle_free (bundle);
-}
-
-static void
-sync_collection_cb (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
-{
- EphySyncService *self;
- SyncCollectionAsyncData *data;
- EphySynchronizable *remote;
- SyncCryptoKeyBundle *bundle;
- JsonNode *node = NULL;
- JsonArray *array;
- GError *error = NULL;
- GList *remotes_updated = NULL;
- GList *remotes_deleted = NULL;
- GList *to_upload;
- GType type;
- const char *collection;
- const char *timestamp;
- gboolean is_deleted;
-
- self = ephy_shell_get_sync_service (ephy_shell_get_default ());
- data = (SyncCollectionAsyncData *)user_data;
- collection = ephy_synchronizable_manager_get_collection_name (data->manager);
-
- /* Code 304 means that the collection has not been modified. */
- if (msg->status_code == 304) {
- LOG ("There are no new remote objects");
- goto merge_remotes;
- }
-
- if (msg->status_code != 200) {
- g_warning ("Failed to get records in collection %s. Status code: %u, response: %s",
- collection, msg->status_code, msg->response_body->data);
- goto out;
- }
-
- node = json_from_string (msg->response_body->data, &error);
- if (error) {
- g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto out;
- }
- if (!JSON_NODE_HOLDS_ARRAY (node)) {
- g_warning ("JSON root does not hold an array");
- goto free_node;
- }
-
- type = ephy_synchronizable_manager_get_synchronizable_type (data->manager);
- bundle = ephy_sync_service_get_key_bundle (self, collection);
- array = json_node_get_array (node);
-
- for (guint i = 0; i < json_array_get_length (array); i++) {
- remote = EPHY_SYNCHRONIZABLE (ephy_synchronizable_from_bso (json_array_get_element (array, i),
- type, bundle, &is_deleted));
- if (!remote) {
- g_warning ("Failed to create synchronizable object from BSO, skipping...");
- continue;
- }
- if (is_deleted)
- remotes_deleted = g_list_prepend (remotes_deleted, remote);
- else
- remotes_updated = g_list_prepend (remotes_updated, remote);
- }
-
-merge_remotes:
- to_upload = ephy_synchronizable_manager_merge_remotes (data->manager, data->is_initial,
- remotes_deleted, remotes_updated);
-
- if (to_upload) {
- LOG ("Uploading local objects to server...");
- for (GList *l = to_upload; l && l->data; l = l->next) {
- ephy_sync_service_upload_synchronizable (self, data->manager,
- EPHY_SYNCHRONIZABLE (l->data));
- }
- }
-
- ephy_synchronizable_manager_set_is_initial_sync (data->manager, FALSE);
- /* Update sync time. */
- timestamp = soup_message_headers_get_one (msg->response_headers, "X-Weave-Timestamp");
- ephy_synchronizable_manager_set_sync_time (data->manager, g_ascii_strtod (timestamp, NULL));
-
- g_list_free_full (to_upload, g_object_unref);
- g_list_free_full (remotes_updated, g_object_unref);
- g_list_free_full (remotes_deleted, g_object_unref);
-free_node:
- if (node)
- json_node_unref (node);
-out:
- if (data->collection_index == data->num_collections)
- g_signal_emit (self, signals[SYNC_FINISHED], 0);
-
- sync_collection_async_data_free (data);
- ephy_sync_service_send_next_storage_request (self);
-}
-
-static void
-ephy_sync_service_sync_collection (EphySyncService *self,
- EphySynchronizableManager *manager,
- guint collection_index,
- guint num_collections)
-{
- SyncCollectionAsyncData *data;
- const char *collection;
- char *endpoint;
- gboolean is_initial;
-
- g_assert (EPHY_IS_SYNC_SERVICE (self));
- g_assert (EPHY_IS_SYNCHRONIZABLE_MANAGER (manager));
-
- collection = ephy_synchronizable_manager_get_collection_name (manager);
- endpoint = g_strdup_printf ("storage/%s?full=true", collection);
- is_initial = ephy_synchronizable_manager_is_initial_sync (manager);
- data = sync_collection_async_data_new (manager, is_initial, collection_index, num_collections);
-
- LOG ("Syncing %s collection%s...", collection, is_initial ? " first time" : "");
- ephy_sync_service_queue_storage_request (self, endpoint, SOUP_METHOD_GET, NULL,
- is_initial ? -1 : ephy_synchronizable_manager_get_sync_time
(manager),
- -1, sync_collection_cb, data);
-
- g_free (endpoint);
-}
-
-static void
-ephy_sync_service_stop_periodical_sync (EphySyncService *self)
-{
- g_assert (EPHY_IS_SYNC_SERVICE (self));
-
- if (self->source_id != 0) {
- g_source_remove (self->source_id);
- self->source_id = 0;
- }
-}
-
-static gboolean
-ephy_sync_service_sync (gpointer user_data)
-{
- EphySyncService *self = EPHY_SYNC_SERVICE (user_data);
- GList *managers = NULL;
-
- managers = ephy_shell_get_synchronizable_managers (ephy_shell_get_default ());
- if (managers) {
- guint num_managers = g_list_length (managers);
- guint index = 1;
-
- for (GList *l = managers; l && l->data; l = l->next, index++)
- ephy_sync_service_sync_collection (self,
- EPHY_SYNCHRONIZABLE_MANAGER (l->data),
- index, num_managers);
-
- g_list_free (managers);
- } else {
- g_signal_emit (self, signals[SYNC_FINISHED], 0);
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-static void
-ephy_sync_service_schedule_periodical_sync (EphySyncService *self)
-{
- g_assert (EPHY_IS_SYNC_SERVICE (self));
-
- self->source_id = g_timeout_add_seconds (g_settings_get_uint (EPHY_SETTINGS_SYNC,
- EPHY_PREFS_SYNC_FREQUENCY) * 60,
- ephy_sync_service_sync,
- self);
- LOG ("Scheduled new sync with frequency %u mins",
- g_settings_get_uint (EPHY_SETTINGS_SYNC, EPHY_PREFS_SYNC_FREQUENCY));
-}
-
-static void
-sync_frequency_changed_cb (EphySyncService *self)
-{
- g_assert (EPHY_IS_SYNC_SERVICE (self));
-
- ephy_sync_service_stop_periodical_sync (self);
- ephy_sync_service_schedule_periodical_sync (self);
-}
-
-static void
-sync_secrets_store_finished_cb (EphySyncService *self,
- GError *error)
-{
- g_assert (EPHY_IS_SYNC_SERVICE (self));
-
- if (error) {
- ephy_sync_service_destroy_session (self);
- g_clear_pointer (&self->user_email, g_free);
- g_hash_table_remove_all (self->secrets);
- }
-}
-
void
ephy_sync_service_do_sync (EphySyncService *self)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]