[evolution-etesync/EteSync-2.0] Update code to EteSync 2.0 (Etebase)
- From: Nour E-Din El-Nhass <nourmat src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-etesync/EteSync-2.0] Update code to EteSync 2.0 (Etebase)
- Date: Sat, 21 Nov 2020 00:48:42 +0000 (UTC)
commit 88c97ecbd30d0ff32e9dee9ba5d21f9bf437855f
Author: Nour E-Din El-Nhass <nouredinosama gmail com>
Date: Wed Sep 16 15:53:31 2020 +0200
Update code to EteSync 2.0 (Etebase)
CMakeLists.txt | 4 +-
README.md | 1 +
src/addressbook/e-book-backend-etesync.c | 750 +++-------
src/calendar/e-cal-backend-etesync.c | 901 +++---------
src/common/CMakeLists.txt | 24 +-
src/common/e-etesync-connection.c | 1499 +++++++++++---------
src/common/e-etesync-connection.h | 181 ++-
src/common/e-etesync-defines.h | 25 +-
src/{credentials => common}/e-etesync-service.c | 6 +-
src/{credentials => common}/e-etesync-service.h | 0
src/common/e-etesync-utils.c | 194 +++
src/common/e-etesync-utils.h | 49 +
src/common/e-source-etesync-account.c | 157 ++
src/common/e-source-etesync-account.h | 63 +
src/common/e-source-etesync.c | 185 ++-
src/common/e-source-etesync.h | 32 +-
src/credentials/CMakeLists.txt | 2 -
.../e-credentials-prompter-impl-etesync.c | 437 +-----
.../e-source-credentials-provider-impl-etesync.c | 11 +-
src/evolution/e-book-config-etesync.c | 63 +
src/evolution/e-cal-config-etesync.c | 89 ++
src/evolution/e-etesync-config-lookup.c | 75 +-
src/registry/e-etesync-backend.c | 593 +++++---
src/registry/module-etesync-backend.c | 2 +
24 files changed, 2667 insertions(+), 2676 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f22d1a2..f9f840d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1)
cmake_policy(VERSION 3.1)
project(evolution-etesync
- VERSION 0.5.1
+ VERSION 1.0.0
LANGUAGES C)
set(PROJECT_BUGREPORT "https://gitlab.gnome.org/GNOME/evolution-etesync/issues/")
@@ -122,7 +122,7 @@ pkg_check_modules(GNOME_PLATFORM REQUIRED
gtk+-3.0>=${gdk_minimum_version}
)
-pkg_check_modules(ETESYNC REQUIRED etesync)
+pkg_check_modules(ETESYNC REQUIRED etebase)
# ******************************
# Special directories
diff --git a/README.md b/README.md
index 59617b7..b35eadc 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+## Please Note that the repo has been moved, the official repo is now
[here](https://gitlab.gnome.org/GNOME/evolution-etesync)
# BUILD
### The development packages needed
This is for ubuntu, please check simillar development package depending on you disto
diff --git a/src/addressbook/e-book-backend-etesync.c b/src/addressbook/e-book-backend-etesync.c
index 7f790ad..02ddc5c 100644
--- a/src/addressbook/e-book-backend-etesync.c
+++ b/src/addressbook/e-book-backend-etesync.c
@@ -8,27 +8,21 @@
#include "evolution-etesync-config.h"
#include <libedataserver/libedataserver.h>
-#include <etesync.h>
+#include <etebase.h>
#include "common/e-source-etesync.h"
#include "common/e-etesync-connection.h"
+#include "common/e-etesync-utils.h"
+#include "common/e-etesync-defines.h"
#include "e-book-backend-etesync.h"
-#define FETCH_BATCH_LIMIT 50
-#define PUSH_BATCH_LIMIT 30
-
-static gulong source_changed_handler_id = 0;
-static gint backend_count = 0;
-G_LOCK_DEFINE_STATIC (backend_count);
-
struct _EBookBackendEteSyncPrivate {
EEteSyncConnection *connection;
+ EtebaseCollection *col_obj;
GRecMutex etesync_lock;
- gchar *journal_id;
gboolean fetch_from_server;
- gchar *preloaded_sync_tag;
GSList *preloaded_add; /* EBookMetaBackendInfo * */
GSList *preloaded_modify; /* EBookMetaBackendInfo * */
GSList *preloaded_delete; /* EBookMetaBackendInfo * */
@@ -36,62 +30,16 @@ struct _EBookBackendEteSyncPrivate {
G_DEFINE_TYPE_WITH_PRIVATE (EBookBackendEteSync, e_book_backend_etesync, E_TYPE_BOOK_META_BACKEND)
-static void
-ebb_etesync_setup_connection (EBookBackendEteSync *bbetesync)
-{
- ESource *source, *collection;
- ESourceRegistry *registry;
-
- source = e_backend_get_source (E_BACKEND (bbetesync));
- registry = e_book_backend_get_registry (E_BOOK_BACKEND (bbetesync));
- collection = e_source_registry_find_extension (registry, source, E_SOURCE_EXTENSION_COLLECTION);
-
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
- ESourceEteSync *etesync_extension;
-
- etesync_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
- g_free (bbetesync->priv->journal_id);
- bbetesync->priv->journal_id = e_source_etesync_dup_journal_id (etesync_extension);
- }
-
- if (collection) {
- bbetesync->priv->connection = e_etesync_connection_new_connection (collection);
- g_clear_object (&collection);
- }
-}
-
-/*
- * Should check if credentials exist, if so should validate them
- * to make sure credentials haven't changed, then copy them to the private
- */
-static ESourceAuthenticationResult
-ebb_etesync_set_credentials_sync (EBookBackendEteSync *bbetesync,
- const ENamedParameters *credentials)
+/* must be freed with g_object_unref */
+static ESource *
+ebb_etesync_ref_collection_source (EBookBackendEteSync *bbetesync)
{
ESource *source;
- ESource *collection;
ESourceRegistry *registry;
source = e_backend_get_source (E_BACKEND (bbetesync));
registry = e_book_backend_get_registry (E_BOOK_BACKEND (bbetesync));
- collection = e_source_registry_find_extension (registry, source, E_SOURCE_EXTENSION_COLLECTION);
-
- if (collection) {
- ESourceAuthentication *authentication_extension;
- ESourceCollection *collection_extension;
-
- authentication_extension = e_source_get_extension (collection,
E_SOURCE_EXTENSION_AUTHENTICATION);
- collection_extension = e_source_get_extension (collection, E_SOURCE_EXTENSION_COLLECTION);
-
- g_clear_object (&collection);
-
- g_return_val_if_fail (authentication_extension != NULL, E_SOURCE_AUTHENTICATION_ERROR);
- g_return_val_if_fail (collection_extension != NULL, E_SOURCE_AUTHENTICATION_ERROR);
-
- return e_etesync_connection_set_connection_from_sources (bbetesync->priv->connection,
credentials, authentication_extension, collection_extension);
- }
-
- return E_SOURCE_AUTHENTICATION_ERROR;
+ return e_source_registry_find_extension (registry, source, E_SOURCE_EXTENSION_COLLECTION);
}
static gboolean
@@ -104,7 +52,6 @@ ebb_etesync_connect_sync (EBookMetaBackend *meta_backend,
GError **error)
{
EBookBackendEteSync *bbetesync;
- EEteSyncConnection *connection;
gboolean success = FALSE;
g_return_val_if_fail (E_IS_BOOK_BACKEND_ETESYNC (meta_backend), FALSE);
@@ -114,28 +61,39 @@ ebb_etesync_connect_sync (EBookMetaBackend *meta_backend,
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
- if (!bbetesync->priv->connection)
- ebb_etesync_setup_connection (bbetesync);
+ if (e_etesync_connection_is_connected (bbetesync->priv->connection)) {
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ success = TRUE;
+ } else {
+ if (!bbetesync->priv->connection) {
+ ESource *collection = ebb_etesync_ref_collection_source (bbetesync);
+ bbetesync->priv->connection = e_etesync_connection_new (collection);
+ g_object_unref (collection);
+ }
- if (bbetesync->priv->connection) {
- gboolean needs_setting;
+ if (e_etesync_connection_reconnect_sync (bbetesync->priv->connection, out_auth_result,
cancellable, error))
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ }
- connection = bbetesync->priv->connection;
- needs_setting = e_etesync_connection_needs_setting (connection, credentials, out_auth_result);
+ if (*out_auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED && !bbetesync->priv->col_obj) {
+ gboolean is_read_only;
+ ESource *source = e_backend_get_source (E_BACKEND (bbetesync));
- if (needs_setting)
- *out_auth_result = ebb_etesync_set_credentials_sync (bbetesync, credentials);
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
+ ESourceEteSync *etesync_extension;
- if (*out_auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
- gboolean is_read_only;
+ etesync_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
+ bbetesync->priv->col_obj = e_etesync_utils_etebase_collection_from_base64 (
+ e_source_etesync_get_etebase_collection_b64
(etesync_extension),
+ e_etesync_connection_get_collection_manager
(bbetesync->priv->connection));
+ }
- success = e_etesync_connection_get_journal_exists (connection,
bbetesync->priv->journal_id, &is_read_only);
+ success = bbetesync->priv->col_obj? TRUE : FALSE;
- if (success)
- e_book_backend_set_writable (E_BOOK_BACKEND (bbetesync), !is_read_only);
+ if (success) {
+ is_read_only = etebase_collection_get_access_level (bbetesync->priv->col_obj) ==
ETEBASE_COLLECTION_ACCESS_LEVEL_READ_ONLY;
+ e_book_backend_set_writable (E_BOOK_BACKEND (bbetesync), !is_read_only);
}
- } else {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
}
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
@@ -153,35 +111,6 @@ ebb_etesync_disconnect_sync (EBookMetaBackend *meta_backend,
return TRUE;
}
-static void
-ebb_etesync_get_contact_uid_revision (const gchar *content,
- gchar **out_contact_uid,
- gchar **out_revision)
-{
- EContact *contact;
-
- contact = e_contact_new_from_vcard (content);
-
- if (contact) {
- *out_contact_uid = e_contact_get (contact, E_CONTACT_UID);
- *out_revision = e_contact_get (contact, E_CONTACT_REV);
-
- g_object_unref (contact);
- }
-}
-
-static void
-ebb_etesync_update_hash_tables (GHashTable *main_table,
- GHashTable *table_1,
- GHashTable *table_2,
- const gchar *uid,
- EBookMetaBackendInfo *nfo)
-{
- g_hash_table_replace (main_table, g_strdup (uid), nfo);
- g_hash_table_remove (table_1, uid);
- g_hash_table_remove (table_2, uid);
-}
-
static gboolean
ebb_etesync_list_existing_sync (EBookMetaBackend *meta_backend,
gchar **out_new_sync_tag,
@@ -190,113 +119,29 @@ ebb_etesync_list_existing_sync (EBookMetaBackend *meta_backend,
GError **error)
{
EBookBackendEteSync *bbetesync;
- EteSyncEntry **entries = NULL, **entry_iter;
- EteSyncEntryManager *entry_manager;
- EteSyncCryptoManager *crypto_manager = NULL;
EEteSyncConnection *connection;
- gchar *prev_entry_uid = NULL;
- GHashTable *existing_entry; /* gchar *uid ~> EBookMetaBackendInfo * */
- GHashTableIter iter;
- gpointer key = NULL, value = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_BOOK_BACKEND_ETESYNC (meta_backend), FALSE);
g_return_val_if_fail (out_existing_objects != NULL, FALSE);
- *out_existing_objects = NULL;
-
bbetesync = E_BOOK_BACKEND_ETESYNC (meta_backend);
connection = bbetesync->priv->connection;
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
- /* 1) Retrive entry_manager, crypto_manager and entries since "last_sync_tag", here "last_sync_tag"
will be NULL
- Failing means connection error */
- if (!e_etesync_connection_check_journal_changed_sync (connection, bbetesync->priv->journal_id, NULL,
FETCH_BATCH_LIMIT, &entries, &crypto_manager, &entry_manager)) {
- g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
- return FALSE;
- }
-
- /* 2) Check if there are entries returned from "e_etesync_connection_check_journal_changed_sync",
- if it is empty then no changes since "last_sync_tag", just free the memory and return, here
"last_sync_tag" will be NULL */
- if (!entries || !*entries) {
- g_free (entries);
- if (entry_manager)
- etesync_entry_manager_destroy (entry_manager);
- if (crypto_manager)
- etesync_crypto_manager_destroy (crypto_manager);
- g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
- return TRUE;
- }
+ success = e_etesync_connection_list_existing_sync (connection,
+ E_BACKEND (meta_backend),
+ E_ETESYNC_ADDRESSBOOK,
+ bbetesync->priv->col_obj,
+ out_new_sync_tag,
+ out_existing_objects,
+ cancellable,
+ error);
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
- /* 3) At this point, entries are not empty, then we should loop on entries and add each
- one to the hashtable as EBookMetaBackendInfo only keeping last action for each contact */
- existing_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_book_meta_backend_info_free);
- prev_entry_uid = NULL;
-
- while (entries && *entries) {
- gint batch_size = 0;
-
- for (entry_iter = entries; *entry_iter; entry_iter++, batch_size++) {
-
- EteSyncEntry *entry;
- EteSyncSyncEntry *sync_entry;
- EBookMetaBackendInfo *nfo;
- gchar *entry_uid, *action, *content, *contact_uid, *revision;
-
- entry = *entry_iter;
- sync_entry = etesync_entry_get_sync_entry (entry, crypto_manager, prev_entry_uid);
-
- action = etesync_sync_entry_get_action (sync_entry);
- content = etesync_sync_entry_get_content (sync_entry);
-
- /* create EBookMetaBackendInfo * to be stored in Hash Table */
- ebb_etesync_get_contact_uid_revision (content, &contact_uid, &revision);
- nfo = e_book_meta_backend_info_new (contact_uid, revision, content, NULL);
-
- /* check action add, change or delete */
- if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_ADD) ||
- g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_CHANGE))
- g_hash_table_replace (existing_entry, g_strdup (contact_uid), nfo);
-
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_DELETE))
- g_hash_table_remove (existing_entry, contact_uid);
-
- else
- e_book_meta_backend_info_free (nfo);
-
- entry_uid = etesync_entry_get_uid (entry);
- g_free (prev_entry_uid);
- prev_entry_uid = entry_uid;
-
- etesync_sync_entry_destroy (sync_entry);
- etesync_entry_destroy (entry);
- g_free (content);
- g_free (action);
- g_free (contact_uid);
- g_free (revision);
- }
-
- if (batch_size < FETCH_BATCH_LIMIT)
- break;
-
- g_free (entries);
- entries = etesync_entry_manager_list (entry_manager, prev_entry_uid, FETCH_BATCH_LIMIT);
- }
-
- /* 4) iterate on each hashtable and add to correspoinding GList */
- g_hash_table_iter_init (&iter, existing_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_existing_objects = g_slist_prepend (*out_existing_objects, e_book_meta_backend_info_copy
(value));
-
- g_free (entries);
- g_free (prev_entry_uid);
- etesync_entry_manager_destroy (entry_manager);
- etesync_crypto_manager_destroy (crypto_manager);
- g_hash_table_destroy (existing_entry);
-
- return TRUE;
+ return success;
}
static gboolean
@@ -312,154 +157,57 @@ ebb_etesync_get_changes_sync (EBookMetaBackend *meta_backend,
GError **error)
{
EBookBackendEteSync *bbetesync;
- EteSyncEntry **entries = NULL, **entry_iter;
- EteSyncCryptoManager *crypto_manager = NULL;
- EteSyncEntryManager *entry_manager;
EEteSyncConnection *connection;
- gchar *prev_entry_uid;
- const gchar *last_tag = NULL;
- GHashTable *created_entry, *modified_entry, *removed_entry; /* gchar *uid ~> EBookMetaBackendInfo * */
- GHashTableIter iter;
- gpointer key = NULL, value = NULL;
+ EBookCache *book_cache;
+ gboolean success = TRUE;
g_return_val_if_fail (E_IS_BOOK_BACKEND_ETESYNC (meta_backend), FALSE);
- g_return_val_if_fail (out_new_sync_tag != NULL, FALSE);
- g_return_val_if_fail (out_repeat != NULL, FALSE);
g_return_val_if_fail (out_created_objects != NULL, FALSE);
g_return_val_if_fail (out_modified_objects != NULL, FALSE);
g_return_val_if_fail (out_removed_objects != NULL, FALSE);
- bbetesync = E_BOOK_BACKEND_ETESYNC (meta_backend);
- connection = bbetesync->priv->connection;
-
*out_created_objects = NULL;
*out_modified_objects = NULL;
*out_removed_objects = NULL;
+ *out_new_sync_tag = NULL;
- g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
-
- /* Must add preloaded and updating the out_new_sync_tag */
- if (bbetesync->priv->preloaded_sync_tag) {
- *out_created_objects = bbetesync->priv->preloaded_add;
- *out_modified_objects = bbetesync->priv->preloaded_modify;
- *out_removed_objects = bbetesync->priv->preloaded_delete;
- *out_new_sync_tag = bbetesync->priv->preloaded_sync_tag; /* Made here if no chnages are
required to fetch */
- last_tag = bbetesync->priv->preloaded_sync_tag;
-
- bbetesync->priv->preloaded_sync_tag = NULL;
- bbetesync->priv->preloaded_add = NULL;
- bbetesync->priv->preloaded_modify = NULL;
- bbetesync->priv->preloaded_delete = NULL;
- }
-
- if (bbetesync->priv->fetch_from_server) {
- if (!last_tag)
- last_tag = last_sync_tag;
-
- /* 1) Retrive entry_manager, crypto_manager and entries since "last_sync_tag", here "last
tag" will be "last_sync_tag"
- Failing means connection error */
- if (!e_etesync_connection_check_journal_changed_sync (connection,
bbetesync->priv->journal_id, last_tag, FETCH_BATCH_LIMIT, &entries, &crypto_manager, &entry_manager)) {
- g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
- return FALSE;
- }
-
- /* 2) Check if there are entries returned from
"e_etesync_connection_check_journal_changed_sync",
- if it is empty then no changes since "last_sync_tag", just free the memory and return */
- if (!entries || !*entries) {
- g_free (entries);
- if (entry_manager)
- etesync_entry_manager_destroy (entry_manager);
- if (crypto_manager)
- etesync_crypto_manager_destroy (crypto_manager);
- g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
- return TRUE;
- }
-
- /* 3) At this point, entries are not empty, then we should loop on entries and add each
- one to its hashtable as EBookMetaBackendInfo depending on the action
("create/modify/delete) */
- created_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_book_meta_backend_info_free);
- modified_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_book_meta_backend_info_free);
- removed_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_book_meta_backend_info_free);
- prev_entry_uid = g_strdup (last_tag);
-
- while (entries && *entries) {
- gint batch_size = 0;
-
- for (entry_iter = entries; *entry_iter; entry_iter++, batch_size++) {
-
- EteSyncEntry *entry;
- EteSyncSyncEntry *sync_entry;
- EBookMetaBackendInfo *nfo;
- gchar *entry_uid, *action, *content, *contact_uid, *revision;
-
- entry = *entry_iter;
- sync_entry = etesync_entry_get_sync_entry (entry, crypto_manager,
prev_entry_uid);
-
- action = etesync_sync_entry_get_action (sync_entry);
- content = etesync_sync_entry_get_content (sync_entry);
-
- /* create EBookMetaBackendInfo * to be stored in Hash Table */
- ebb_etesync_get_contact_uid_revision (content, &contact_uid, &revision);
- nfo = e_book_meta_backend_info_new (contact_uid, revision, content, NULL);
-
- /* check action add, change or delete */
- if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_ADD))
- ebb_etesync_update_hash_tables (created_entry, modified_entry,
removed_entry, contact_uid, nfo);
-
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_CHANGE))
- ebb_etesync_update_hash_tables (modified_entry, created_entry
,removed_entry, contact_uid, nfo);
-
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_DELETE))
- ebb_etesync_update_hash_tables (removed_entry, created_entry,
modified_entry, contact_uid, nfo);
+ bbetesync = E_BOOK_BACKEND_ETESYNC (meta_backend);
+ connection = bbetesync->priv->connection;
- else
- e_book_meta_backend_info_free (nfo);
+ g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
- entry_uid = etesync_entry_get_uid (entry);
- g_free (prev_entry_uid);
- prev_entry_uid = entry_uid;
+ /* Must add preloaded */
+ *out_created_objects = bbetesync->priv->preloaded_add;
+ *out_modified_objects = bbetesync->priv->preloaded_modify;
+ *out_removed_objects = bbetesync->priv->preloaded_delete;
- etesync_sync_entry_destroy (sync_entry);
- etesync_entry_destroy (entry);
- g_free (content);
- g_free (action);
- g_free (contact_uid);
- g_free (revision);
- }
+ bbetesync->priv->preloaded_add = NULL;
+ bbetesync->priv->preloaded_modify = NULL;
+ bbetesync->priv->preloaded_delete = NULL;
- if (batch_size < FETCH_BATCH_LIMIT)
- break;
+ if (bbetesync->priv->fetch_from_server) {
+ book_cache = e_book_meta_backend_ref_cache (meta_backend);
- g_free (entries);
- entries = etesync_entry_manager_list (entry_manager, prev_entry_uid,
FETCH_BATCH_LIMIT);
+ if (book_cache) {
+ success = e_etesync_connection_get_changes_sync (connection,
+ E_BACKEND (meta_backend),
+ E_ETESYNC_ADDRESSBOOK,
+ last_sync_tag,
+ bbetesync->priv->col_obj,
+ E_CACHE (book_cache),
+ out_new_sync_tag,
+ out_created_objects,
+ out_modified_objects,
+ out_removed_objects,
+ cancellable,
+ error);
+ g_object_unref (book_cache);
}
-
- *out_new_sync_tag = prev_entry_uid;
-
- /* 4) iterate on each hashtable and add to correspoinding GList */
- g_hash_table_iter_init (&iter, created_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_created_objects = g_slist_prepend (*out_created_objects,
e_book_meta_backend_info_copy (value));
-
- g_hash_table_iter_init (&iter, modified_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_modified_objects = g_slist_prepend (*out_modified_objects,
e_book_meta_backend_info_copy (value));
-
- g_hash_table_iter_init (&iter, removed_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_removed_objects = g_slist_prepend (*out_removed_objects,
e_book_meta_backend_info_copy (value));
-
- g_free (entries);
- etesync_entry_manager_destroy (entry_manager);
- etesync_crypto_manager_destroy (crypto_manager);
- g_hash_table_destroy (created_entry);
- g_hash_table_destroy (modified_entry);
- g_hash_table_destroy (removed_entry);
}
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
- return TRUE;
+ return success;
}
static gboolean
@@ -513,11 +261,8 @@ ebb_etesync_save_contact_sync (EBookMetaBackend *meta_backend,
EBookBackendEteSync *bbetesync;
EEteSyncConnection *connection;
gboolean success = FALSE;
- gboolean conflict = TRUE;
- gchar *last_sync_tag, *content;
- gchar *new_sync_tag;
- EBookMetaBackendInfo *info;
- EteSyncErrorCode etesync_error;
+ gchar *content;
+ const gchar *uid;
g_return_val_if_fail (E_IS_BOOK_BACKEND_ETESYNC (meta_backend), FALSE);
g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
@@ -530,50 +275,18 @@ ebb_etesync_save_contact_sync (EBookMetaBackend *meta_backend,
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
content = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
- while (conflict) {
- last_sync_tag = e_book_meta_backend_dup_sync_tag (meta_backend);
-
- if (overwrite_existing) {
- success = e_etesync_connection_entry_write_action (connection,
bbetesync->priv->journal_id,
- last_sync_tag, content, ETESYNC_SYNC_ENTRY_ACTION_CHANGE,
&new_sync_tag, &etesync_error);
- } else {
- success = e_etesync_connection_entry_write_action (connection,
bbetesync->priv->journal_id,
- last_sync_tag, content, ETESYNC_SYNC_ENTRY_ACTION_ADD, &new_sync_tag,
&etesync_error);
- }
-
- if (success) {
- const gchar *rev, *uid;
-
- uid = e_contact_get_const (contact, E_CONTACT_UID);
- rev = e_contact_get_const (contact, E_CONTACT_REV);
- info = e_book_meta_backend_info_new (uid, rev, content, NULL);
-
- bbetesync->priv->preloaded_sync_tag = g_strdup (new_sync_tag);
- if (overwrite_existing)
- bbetesync->priv->preloaded_modify = g_slist_prepend
(bbetesync->priv->preloaded_modify, info);
- else
- bbetesync->priv->preloaded_add = g_slist_prepend
(bbetesync->priv->preloaded_add, info);
- conflict = FALSE;
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT)
- conflict = FALSE;
- else
- if (!e_book_meta_backend_refresh_sync (meta_backend, cancellable, error))
- conflict = FALSE;
- }
-
- g_free (new_sync_tag);
- g_free (last_sync_tag);
- }
-
- if (success) {
- bbetesync->priv->fetch_from_server = FALSE;
- e_book_meta_backend_refresh_sync (meta_backend, cancellable, error);
- bbetesync->priv->fetch_from_server = TRUE;
+ if (overwrite_existing) {
+ success = e_etesync_connection_item_upload_sync (connection, E_BACKEND (meta_backend),
bbetesync->priv->col_obj,
+ E_ETESYNC_ITEM_ACTION_MODIFY, content, uid, extra, out_new_extra,
cancellable, error);
+ } else {
+ success = e_etesync_connection_item_upload_sync (connection, E_BACKEND (meta_backend),
bbetesync->priv->col_obj,
+ E_ETESYNC_ITEM_ACTION_CREATE, content, uid, NULL, out_new_extra, cancellable,
error);
}
g_free (content);
+
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
return success;
@@ -592,12 +305,6 @@ ebb_etesync_remove_contact_sync (EBookMetaBackend *meta_backend,
EBookBackendEteSync *bbetesync;
EEteSyncConnection *connection;
gboolean success = FALSE;
- gboolean conflict = TRUE;
- gchar *last_sync_tag, *new_sync_tag, *content = NULL;
- EBookCache *book_cache;
- EContact *contact = NULL;
- EBookMetaBackendInfo *info;
- EteSyncErrorCode etesync_error;
g_return_val_if_fail (E_IS_BOOK_BACKEND_ETESYNC (meta_backend), FALSE);
@@ -606,53 +313,8 @@ ebb_etesync_remove_contact_sync (EBookMetaBackend *meta_backend,
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
- book_cache = e_book_meta_backend_ref_cache (meta_backend);
- if (book_cache) {
- if (e_book_cache_get_contact (book_cache, uid, FALSE, &contact, cancellable, NULL)) {
- content = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- success = TRUE;
- }
- g_object_unref (book_cache);
- }
-
- /* Checking if the contact with that uid has been found */
- if (success) {
- while (conflict) {
- last_sync_tag = e_book_meta_backend_dup_sync_tag (meta_backend);
-
- success = e_etesync_connection_entry_write_action (connection,
bbetesync->priv->journal_id,
- last_sync_tag, content, ETESYNC_SYNC_ENTRY_ACTION_DELETE, &new_sync_tag,
&etesync_error);
-
- if (success) {
- const gchar *rev;
-
- rev = e_contact_get_const (contact, E_CONTACT_REV);
- info = e_book_meta_backend_info_new (uid, rev, content, NULL);
-
- bbetesync->priv->preloaded_sync_tag = g_strdup (new_sync_tag);
- bbetesync->priv->preloaded_delete = g_slist_prepend
(bbetesync->priv->preloaded_delete, info);
- conflict = FALSE;
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT)
- conflict = FALSE;
- else
- if (!e_book_meta_backend_refresh_sync (meta_backend, cancellable,
error))
- conflict = FALSE;
- }
-
- g_free (new_sync_tag);
- g_free (last_sync_tag);
- }
-
- g_free (content);
- g_object_unref (contact);
- }
-
- if (success) {
- bbetesync->priv->fetch_from_server = FALSE;
- e_book_meta_backend_refresh_sync (meta_backend, cancellable, error);
- bbetesync->priv->fetch_from_server = TRUE;
- }
+ success = e_etesync_connection_item_upload_sync (connection, E_BACKEND (meta_backend),
bbetesync->priv->col_obj,
+ E_ETESYNC_ITEM_ACTION_DELETE, NULL, uid, extra, NULL, cancellable, error);
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
@@ -664,97 +326,95 @@ static gboolean
ebb_etesync_create_modify_contacts_sync (EBookBackendSync *backend,
const gchar * const *vcards,
GSList **out_contacts,
- const gchar *action)
+ const EteSyncAction action,
+ GCancellable *cancellable,
+ GError **error)
{
EBookBackendEteSync *bbetesync;
EEteSyncConnection *connection;
- EteSyncErrorCode etesync_error;
guint length, batch_length, batch_number = 0;
- gchar *last_sync_tag;
gboolean success = TRUE;
length = g_strv_length ((gchar **) vcards);
bbetesync = E_BOOK_BACKEND_ETESYNC (backend);
connection = bbetesync->priv->connection;
- last_sync_tag = e_book_meta_backend_dup_sync_tag (E_BOOK_META_BACKEND (bbetesync));
*out_contacts = NULL;
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
/* extract the components and mass-add them to the server */
- while (length > 0 && success){
- gboolean conflict = TRUE;
+ while (length > 0 && success) {
GSList *batch_contacts = NULL; /* EContact */
GSList *batch_info = NULL; /* EBookMetaBackendInfo */
gchar **content;
guint ii;
- batch_length = length > PUSH_BATCH_LIMIT ? PUSH_BATCH_LIMIT : length;
+ batch_length = length > E_ETESYNC_ITEM_PUSH_LIMIT ? E_ETESYNC_ITEM_PUSH_LIMIT : length;
length -= batch_length;
content = g_slice_alloc0 (batch_length * sizeof (gchar *));
for (ii = 0; ii < batch_length; ii++) {
- const gchar *id;
- const gchar *rev;
- EContact *contact;
- EBookMetaBackendInfo *info;
+ EContact *contact;
- contact = e_contact_new_from_vcard (vcards[ii + (batch_number * PUSH_BATCH_LIMIT)]);
+ contact = e_contact_new_from_vcard (vcards[ii + (batch_number *
E_ETESYNC_ITEM_PUSH_LIMIT)]);
/* Preserve original UID, create a unique UID if needed */
if (e_contact_get_const (contact, E_CONTACT_UID) == NULL) {
- gchar *uid = etesync_gen_uid ();
+ gchar *uid = e_util_generate_uid ();
e_contact_set (contact, E_CONTACT_UID, uid);
g_free (uid);
}
- id = e_contact_get_const (contact, E_CONTACT_UID);
- rev = e_contact_get_const (contact, E_CONTACT_REV);
-
content[ii] = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- info = e_book_meta_backend_info_new (id, rev, content[ii], NULL);
-
batch_contacts = g_slist_prepend (batch_contacts, contact);
- batch_info = g_slist_prepend (batch_info, info);
}
- while (conflict) {
- success = e_etesync_connection_multiple_entry_write_action (connection,
- bbetesync->priv->journal_id,
- (const gchar* const*) content,
- batch_length, action,
- &last_sync_tag, &etesync_error);
-
- if (success) {
- g_free (bbetesync->priv->preloaded_sync_tag);
- bbetesync->priv->preloaded_sync_tag = g_strdup (last_sync_tag);
- if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_ADD))
- bbetesync->priv->preloaded_add = g_slist_concat (batch_info,
bbetesync->priv->preloaded_add);
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_CHANGE))
- bbetesync->priv->preloaded_modify = g_slist_concat (batch_info,
bbetesync->priv->preloaded_modify);
- *out_contacts = g_slist_concat (batch_contacts, *out_contacts);
- conflict = FALSE;
- } else {
- g_slist_free_full (batch_contacts, g_object_unref);
- g_slist_free_full (batch_info, e_book_meta_backend_info_free);
-
- /* Repeat again if a conflict existed */
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT)
- conflict = FALSE;
- else {
- /* This will empty batch_info and update the last_sync_tag to avoid
conflict again */
- if (!e_book_meta_backend_refresh_sync (E_BOOK_META_BACKEND
(bbetesync), NULL, NULL))
- conflict = FALSE;
-
- g_free (last_sync_tag);
- last_sync_tag = e_book_meta_backend_dup_sync_tag (E_BOOK_META_BACKEND
(bbetesync));
- batch_contacts = NULL;
- batch_info = NULL;
- }
- }
+ if (action == E_ETESYNC_ITEM_ACTION_CREATE) {
+ success = e_etesync_connection_batch_create_sync (connection,
+ E_BACKEND (E_BOOK_META_BACKEND
(bbetesync)),
+ bbetesync->priv->col_obj,
+ E_ETESYNC_ADDRESSBOOK,
+ (const gchar *const*) content,
+ batch_length, /* length of content
*/
+ &batch_info,
+ cancellable,
+ error);
+
+ } else if (action == E_ETESYNC_ITEM_ACTION_MODIFY) {
+ EBookCache *book_cache;
+
+ EBookMetaBackend *meta_backend = E_BOOK_META_BACKEND (bbetesync);
+ book_cache = e_book_meta_backend_ref_cache (meta_backend);
+
+ if (book_cache) {
+ success = e_etesync_connection_batch_modify_sync (connection,
+ E_BACKEND
(E_BOOK_META_BACKEND (bbetesync)),
+ bbetesync->priv->col_obj,
+ E_ETESYNC_ADDRESSBOOK,
+ (const gchar *const*)
content,
+ batch_length, /* length of
content */
+ E_CACHE (book_cache), /*
uses book_cache if type is addressbook */
+ &batch_info,
+ cancellable,
+ error);
+ g_object_unref (book_cache);
+ } else
+ success = FALSE;
+ }
+
+ if (success) {
+ if (action == E_ETESYNC_ITEM_ACTION_CREATE)
+ bbetesync->priv->preloaded_add = g_slist_concat (batch_info,
bbetesync->priv->preloaded_add);
+ else if (action == E_ETESYNC_ITEM_ACTION_MODIFY)
+ bbetesync->priv->preloaded_modify = g_slist_concat (batch_info,
bbetesync->priv->preloaded_modify);
+ *out_contacts = g_slist_concat (batch_contacts, *out_contacts);
+ } else {
+ g_slist_free_full (batch_contacts, g_object_unref);
+ g_slist_free_full (batch_info, e_book_meta_backend_info_free);
}
+
for (ii = 0; ii < batch_length; ii++)
g_free (content[ii]);
g_slice_free1 (batch_length * sizeof (gchar *), content);
@@ -773,7 +433,6 @@ ebb_etesync_create_modify_contacts_sync (EBookBackendSync *backend,
/* free any data related to this bulk operation */
bbetesync->priv->preloaded_add = NULL;
bbetesync->priv->preloaded_modify = NULL;
- g_free (last_sync_tag);
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
@@ -796,7 +455,7 @@ ebb_etesync_create_contacts_sync (EBookBackendSync *backend,
return E_BOOK_BACKEND_SYNC_CLASS (e_book_backend_etesync_parent_class)->create_contacts_sync
(backend, vcards, opflags, out_contacts, cancellable, error);
}
- return ebb_etesync_create_modify_contacts_sync (backend, vcards,out_contacts,
ETESYNC_SYNC_ENTRY_ACTION_ADD);
+ return ebb_etesync_create_modify_contacts_sync (backend, vcards, out_contacts,
E_ETESYNC_ITEM_ACTION_CREATE, cancellable, error);
}
static gboolean
@@ -815,7 +474,7 @@ ebb_etesync_modify_contacts_sync (EBookBackendSync *backend,
return E_BOOK_BACKEND_SYNC_CLASS (e_book_backend_etesync_parent_class)->modify_contacts_sync
(backend, vcards, opflags, out_contacts, cancellable, error);
}
- return ebb_etesync_create_modify_contacts_sync (backend, vcards, out_contacts,
ETESYNC_SYNC_ENTRY_ACTION_CHANGE);
+ return ebb_etesync_create_modify_contacts_sync (backend, vcards, out_contacts,
E_ETESYNC_ITEM_ACTION_MODIFY, cancellable, error);
}
static gboolean
@@ -829,9 +488,7 @@ ebb_etesync_remove_contacts_sync (EBookBackendSync *backend,
EBookBackendEteSync *bbetesync;
EBookCache *book_cache;
EEteSyncConnection *connection;
- EteSyncErrorCode etesync_error;
guint length, batch_length, batch_number = 0;
- gchar *last_sync_tag;
gboolean success = TRUE;
g_return_val_if_fail (out_removed_uids != NULL, FALSE);
@@ -855,76 +512,53 @@ ebb_etesync_remove_contacts_sync (EBookBackendSync *backend,
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
- last_sync_tag = e_book_meta_backend_dup_sync_tag (E_BOOK_META_BACKEND (bbetesync));
-
/* extract the components and mass-add them to the server;
eventually remember them in the cbetesync->priv and use them
in the refresh/get_changes_sync(), instead of re-download them */
- while (length > 0 && success){
- gboolean conflict = TRUE;
+ while (length > 0 && success) {
GSList *batch_contacts_id = NULL; /* gchar */
GSList *batch_info = NULL; /* EBookMetaBackendInfo */
gchar **content;
guint ii;
- batch_length = length > PUSH_BATCH_LIMIT ? PUSH_BATCH_LIMIT : length;
+ batch_length = length > E_ETESYNC_ITEM_PUSH_LIMIT ? E_ETESYNC_ITEM_PUSH_LIMIT : length;
length -= batch_length;
-
*out_removed_uids = NULL;
content = g_slice_alloc0 (batch_length * sizeof (gchar *));
for (ii = 0; ii < batch_length; ii++) {
const gchar *id;
- const gchar *rev;
EContact *contact;
- EBookMetaBackendInfo *info;
- id = uids [ii + (batch_number * PUSH_BATCH_LIMIT)];
+ id = uids [ii + (batch_number * E_ETESYNC_ITEM_PUSH_LIMIT)];
e_book_cache_get_contact (book_cache, id, FALSE, &contact, cancellable, NULL);
- rev = e_contact_get_const (contact, E_CONTACT_REV);
content[ii] = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- info = e_book_meta_backend_info_new (id, rev, content[ii], NULL);
-
batch_contacts_id = g_slist_prepend (batch_contacts_id, g_strdup (id));
- batch_info = g_slist_prepend (batch_info, info);
g_object_unref (contact);
}
- while (conflict) {
- success = e_etesync_connection_multiple_entry_write_action (connection,
- bbetesync->priv->journal_id,
- (const gchar* const*) content,
- batch_length,
ETESYNC_SYNC_ENTRY_ACTION_ADD,
- &last_sync_tag, &etesync_error);
-
- if (success) {
- g_free (bbetesync->priv->preloaded_sync_tag);
- bbetesync->priv->preloaded_sync_tag = g_strdup (last_sync_tag);
- bbetesync->priv->preloaded_delete = g_slist_concat (batch_info,
bbetesync->priv->preloaded_delete);
- *out_removed_uids = g_slist_concat (batch_contacts_id, *out_removed_uids);
- conflict = FALSE;
- } else {
- g_slist_free_full (batch_contacts_id, g_object_unref);
- g_slist_free_full (batch_info, e_book_meta_backend_info_free);
-
- /* Repeat again if a conflict existed */
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT)
- conflict = FALSE;
- else {
- /* This will empty batch_info and update the last_sync_tag to avoid
conflict again */
- if (!e_book_meta_backend_refresh_sync (E_BOOK_META_BACKEND
(bbetesync), NULL, NULL))
- conflict = FALSE;
-
- g_free (last_sync_tag);
- last_sync_tag = e_book_meta_backend_dup_sync_tag (E_BOOK_META_BACKEND
(bbetesync));
- batch_contacts_id = NULL;
- batch_info = NULL;
- }
- }
+ success = e_etesync_connection_batch_delete_sync (connection,
+ E_BACKEND (E_BOOK_META_BACKEND (bbetesync)),
+ bbetesync->priv->col_obj,
+ E_ETESYNC_ADDRESSBOOK,
+ (const gchar *const*) content,
+ batch_length, /* length of content */
+ E_CACHE (book_cache), /* uses book_cache if
type is addressbook */
+ &batch_info,
+ cancellable,
+ error);
+
+ if (success) {
+ bbetesync->priv->preloaded_delete = g_slist_concat (batch_info,
bbetesync->priv->preloaded_delete);
+ *out_removed_uids = g_slist_concat (batch_contacts_id, *out_removed_uids);
+ } else {
+ g_slist_free_full (batch_contacts_id, g_object_unref);
+ g_slist_free_full (batch_info, e_book_meta_backend_info_free);
}
+
for (ii = 0; ii < batch_length; ii++)
g_free (content[ii]);
g_slice_free1 (batch_length * sizeof (gchar *), content);
@@ -942,28 +576,12 @@ ebb_etesync_remove_contacts_sync (EBookBackendSync *backend,
/* free any data related to this bulk operation */
bbetesync->priv->preloaded_delete = NULL;
- g_free (last_sync_tag);
g_object_unref (book_cache);
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
return success;
}
-/*------------------------------------------------------------*/
-
-static void
-ebb_etesync_source_changed_cb (ESourceRegistry *registry,
- ESource *source,
- gpointer user_data)
-{
- ESource *collection = e_source_registry_find_extension (registry, source,
E_SOURCE_EXTENSION_COLLECTION);
-
- if (collection) {
- e_etesync_connection_source_changed_cb (source, collection, TRUE);
-
- g_clear_object (&collection);
- }
-}
static gchar *
ebb_etesync_get_backend_property (EBookBackend *book_backend,
@@ -985,28 +603,6 @@ ebb_etesync_get_backend_property (EBookBackend *book_backend,
return E_BOOK_BACKEND_CLASS (e_book_backend_etesync_parent_class)->impl_get_backend_property
(book_backend, prop_name);
}
-static void
-e_book_backend_etesync_dispose (GObject *object)
-{
- EBookBackendEteSync *bbetesync = E_BOOK_BACKEND_ETESYNC (object);
- ESourceRegistry *registry;
-
- registry = e_book_backend_get_registry (E_BOOK_BACKEND (bbetesync));
-
- /* Only disconnect when backend_count is zero */
- G_LOCK (backend_count);
- if (registry && !--backend_count) {
- g_signal_handler_disconnect (
- registry, source_changed_handler_id);
-
- backend_count = 0;
- }
- G_UNLOCK (backend_count);
-
- /* Chain up to parent's method. */
- G_OBJECT_CLASS (e_book_backend_etesync_parent_class)->dispose (object);
-}
-
static void
e_book_backend_etesync_finalize (GObject *object)
{
@@ -1014,8 +610,7 @@ e_book_backend_etesync_finalize (GObject *object)
g_rec_mutex_lock (&bbetesync->priv->etesync_lock);
g_clear_object (&bbetesync->priv->connection);
- g_clear_pointer (&bbetesync->priv->journal_id, g_free);
- g_clear_pointer (&bbetesync->priv->preloaded_sync_tag, g_free);
+ g_clear_pointer (&bbetesync->priv->col_obj, etebase_collection_destroy);
g_rec_mutex_unlock (&bbetesync->priv->etesync_lock);
g_rec_mutex_clear (&bbetesync->priv->etesync_lock);
@@ -1027,25 +622,16 @@ e_book_backend_etesync_finalize (GObject *object)
static void
e_book_backend_etesync_constructed (GObject *object)
{
+ ESource *collection;
EBookBackendEteSync *bbetesync = E_BOOK_BACKEND_ETESYNC (object);
- ESourceRegistry *registry;
- gulong handler_id;
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_book_backend_etesync_parent_class)->constructed (object);
- registry = e_book_backend_get_registry (E_BOOK_BACKEND (bbetesync));
-
- /* Set only once when backend_count is zero to avoid multiple calls on the same file source when
changed */
- G_LOCK (backend_count);
- if (!backend_count++) {
- handler_id = g_signal_connect (
- registry, "source-changed",
- G_CALLBACK (ebb_etesync_source_changed_cb), NULL);
+ collection = ebb_etesync_ref_collection_source (bbetesync);
+ bbetesync->priv->connection = e_etesync_connection_new (collection);
- source_changed_handler_id = handler_id;
- }
- G_UNLOCK (backend_count);
+ g_object_unref (collection);
}
static void
@@ -1054,9 +640,8 @@ e_book_backend_etesync_init (EBookBackendEteSync *bbetesync)
bbetesync->priv = e_book_backend_etesync_get_instance_private (bbetesync);
g_rec_mutex_init (&bbetesync->priv->etesync_lock);
bbetesync->priv->connection = NULL;
+ bbetesync->priv->col_obj = NULL;
bbetesync->priv->fetch_from_server = TRUE;
- bbetesync->priv->journal_id = NULL;
- bbetesync->priv->preloaded_sync_tag = NULL;
bbetesync->priv->preloaded_add = NULL;
bbetesync->priv->preloaded_modify = NULL;
bbetesync->priv->preloaded_delete = NULL;
@@ -1091,7 +676,6 @@ e_book_backend_etesync_class_init (EBookBackendEteSyncClass *klass)
backend_sync_class->remove_contacts_sync = ebb_etesync_remove_contacts_sync;
object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = e_book_backend_etesync_dispose;
- object_class->finalize = e_book_backend_etesync_finalize;
object_class->constructed = e_book_backend_etesync_constructed;
+ object_class->finalize = e_book_backend_etesync_finalize;
}
diff --git a/src/calendar/e-cal-backend-etesync.c b/src/calendar/e-cal-backend-etesync.c
index 0fff57c..7ec8e13 100644
--- a/src/calendar/e-cal-backend-etesync.c
+++ b/src/calendar/e-cal-backend-etesync.c
@@ -8,27 +8,21 @@
#include "evolution-etesync-config.h"
#include <libedataserver/libedataserver.h>
-#include <etesync.h>
+#include <etebase.h>
#include "common/e-source-etesync.h"
#include "common/e-etesync-connection.h"
+#include "common/e-etesync-utils.h"
+#include "common/e-etesync-defines.h"
#include "e-cal-backend-etesync.h"
-#define FETCH_BATCH_LIMIT 50
-#define PUSH_BATCH_LIMIT 30
-
-static gulong source_changed_handler_id = 0;
-static gint backend_count = 0;
-G_LOCK_DEFINE_STATIC (backend_count);
-
struct _ECalBackendEteSyncPrivate {
EEteSyncConnection *connection;
+ EtebaseCollection *col_obj;
GRecMutex etesync_lock;
- gchar *journal_id;
gboolean fetch_from_server;
- gchar *preloaded_sync_tag;
GSList *preloaded_add; /* ECalMetaBackendInfo * */
GSList *preloaded_modify; /* ECalMetaBackendInfo * */
GSList *preloaded_delete; /* ECalMetaBackendInfo * */
@@ -36,62 +30,16 @@ struct _ECalBackendEteSyncPrivate {
G_DEFINE_TYPE_WITH_PRIVATE (ECalBackendEteSync, e_cal_backend_etesync, E_TYPE_CAL_META_BACKEND)
-static void
-ecb_etesync_setup_connection (ECalBackendEteSync *cbetesync)
-{
- ESource *source, *collection;
- ESourceRegistry *registry;
-
- source = e_backend_get_source (E_BACKEND (cbetesync));
- registry = e_cal_backend_get_registry (E_CAL_BACKEND (cbetesync));
- collection = e_source_registry_find_extension (registry, source, E_SOURCE_EXTENSION_COLLECTION);
-
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
- ESourceEteSync *etesync_extension;
-
- etesync_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
- g_free (cbetesync->priv->journal_id);
- cbetesync->priv->journal_id = e_source_etesync_dup_journal_id (etesync_extension);
- }
-
- if (collection) {
- cbetesync->priv->connection = e_etesync_connection_new_connection (collection);
- g_clear_object (&collection);
- }
-}
-
-/*
- * Should check if credentials exist, if so should validate them
- * to make sure credentials haven't changed, then copy them to the private
- */
-static ESourceAuthenticationResult
-ecb_etesync_set_credentials_sync (ECalBackendEteSync *cbetesync,
- const ENamedParameters *credentials)
+/* must be freed with g_object_unref */
+static ESource *
+ecb_etesync_ref_collection_source (ECalBackendEteSync *cbetesync)
{
ESource *source;
- ESource *collection;
ESourceRegistry *registry;
source = e_backend_get_source (E_BACKEND (cbetesync));
registry = e_cal_backend_get_registry (E_CAL_BACKEND (cbetesync));
- collection = e_source_registry_find_extension (registry, source, E_SOURCE_EXTENSION_COLLECTION);
-
- if (collection) {
- ESourceAuthentication *authentication_extension;
- ESourceCollection *collection_extension;
-
- authentication_extension = e_source_get_extension (collection,
E_SOURCE_EXTENSION_AUTHENTICATION);
- collection_extension = e_source_get_extension (collection, E_SOURCE_EXTENSION_COLLECTION);
-
- g_clear_object (&collection);
-
- g_return_val_if_fail (authentication_extension != NULL, E_SOURCE_AUTHENTICATION_ERROR);
- g_return_val_if_fail (collection_extension != NULL, E_SOURCE_AUTHENTICATION_ERROR);
-
- return e_etesync_connection_set_connection_from_sources (cbetesync->priv->connection,
credentials, authentication_extension, collection_extension);
- }
-
- return E_SOURCE_AUTHENTICATION_ERROR;
+ return e_source_registry_find_extension (registry, source, E_SOURCE_EXTENSION_COLLECTION);
}
static gboolean
@@ -104,7 +52,6 @@ ecb_etesync_connect_sync (ECalMetaBackend *meta_backend,
GError **error)
{
ECalBackendEteSync *cbetesync;
- EEteSyncConnection *connection;
gboolean success = FALSE;
g_return_val_if_fail (E_IS_CAL_BACKEND_ETESYNC (meta_backend), FALSE);
@@ -114,28 +61,40 @@ ecb_etesync_connect_sync (ECalMetaBackend *meta_backend,
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
- if (!cbetesync->priv->connection)
- ecb_etesync_setup_connection (cbetesync);
+ if (e_etesync_connection_is_connected (cbetesync->priv->connection)) {
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ success = TRUE;
+ } else {
+
+ if (!cbetesync->priv->connection) {
+ ESource *collection = ecb_etesync_ref_collection_source (cbetesync);
+ cbetesync->priv->connection = e_etesync_connection_new (collection);
+ g_object_unref (collection);
+ }
- if (cbetesync->priv->connection) {
- gboolean needs_setting;
+ if (e_etesync_connection_reconnect_sync (cbetesync->priv->connection, out_auth_result,
cancellable, error))
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ }
- connection = cbetesync->priv->connection;
- needs_setting = e_etesync_connection_needs_setting (connection, credentials, out_auth_result);
+ if (*out_auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED && !cbetesync->priv->col_obj) {
+ gboolean is_read_only;
+ ESource *source = e_backend_get_source (E_BACKEND (cbetesync));
- if (needs_setting)
- *out_auth_result = ecb_etesync_set_credentials_sync (cbetesync, credentials);
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
+ ESourceEteSync *etesync_extension;
- if (*out_auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
- gboolean is_read_only;
+ etesync_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
+ cbetesync->priv->col_obj = e_etesync_utils_etebase_collection_from_base64 (
+ e_source_etesync_get_etebase_collection_b64
(etesync_extension),
+ e_etesync_connection_get_collection_manager
(cbetesync->priv->connection));
+ }
- success = e_etesync_connection_get_journal_exists (connection,
cbetesync->priv->journal_id, &is_read_only);
+ success = cbetesync->priv->col_obj? TRUE : FALSE;
- if (success)
- e_cal_backend_set_writable (E_CAL_BACKEND (cbetesync), !is_read_only);
+ if (success) {
+ is_read_only = etebase_collection_get_access_level (cbetesync->priv->col_obj) ==
ETEBASE_COLLECTION_ACCESS_LEVEL_READ_ONLY;
+ e_cal_backend_set_writable (E_CAL_BACKEND (cbetesync), !is_read_only);
}
- } else {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
}
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
@@ -153,67 +112,6 @@ ecb_etesync_disconnect_sync (ECalMetaBackend *meta_backend,
return TRUE;
}
-static gboolean
-ecb_etesync_get_component_uid_revision (const gchar *content,
- gchar **out_component_uid,
- gchar **out_revision)
-{
- ICalComponent *vcalendar, *subcomp;
- gboolean success = FALSE;
-
- vcalendar = i_cal_component_new_from_string (content);
-
- *out_component_uid = NULL;
- *out_revision = NULL;
-
- for (subcomp = i_cal_component_get_first_component (vcalendar, I_CAL_ANY_COMPONENT);
- subcomp;
- g_object_unref (subcomp), subcomp = i_cal_component_get_next_component (vcalendar,
I_CAL_ANY_COMPONENT)) {
-
- ICalComponentKind kind = i_cal_component_isa (subcomp);
-
- if (kind == I_CAL_VEVENT_COMPONENT ||
- kind == I_CAL_VTODO_COMPONENT) {
- if (!*out_component_uid){
- *out_component_uid = g_strdup (i_cal_component_get_uid (subcomp));
- success = TRUE;
- }
-
- if (!*out_revision) {
- ICalProperty *prop;
-
- prop = i_cal_component_get_first_property (vcalendar,
I_CAL_LASTMODIFIED_PROPERTY);
- if (prop) {
- ICalTime *itt;
-
- itt = i_cal_property_get_lastmodified (prop);
- *out_revision = i_cal_time_as_ical_string (itt);
- g_clear_object (&itt);
- g_object_unref (prop);
- } else {
- *out_revision = NULL;
- }
- }
- }
- }
-
- g_object_unref (vcalendar);
-
- return success;
-}
-
-static void
-ecb_etesync_update_hash_tables (GHashTable *main_table,
- GHashTable *table_1,
- GHashTable *table_2,
- const gchar *uid,
- ECalMetaBackendInfo *nfo)
-{
- g_hash_table_replace (main_table, g_strdup (uid), nfo);
- g_hash_table_remove (table_1, uid);
- g_hash_table_remove (table_2, uid);
-}
-
static gboolean
ecb_etesync_list_existing_sync (ECalMetaBackend *meta_backend,
gchar **out_new_sync_tag,
@@ -222,113 +120,29 @@ ecb_etesync_list_existing_sync (ECalMetaBackend *meta_backend,
GError **error)
{
ECalBackendEteSync *cbetesync;
- EteSyncEntry **entries = NULL, **entry_iter;
- EteSyncEntryManager *entry_manager;
- EteSyncCryptoManager *crypto_manager = NULL;
EEteSyncConnection *connection;
- gchar *prev_entry_uid = NULL;
- GHashTable *existing_entry; /* gchar *uid ~> ECalMetaBackendInfo * */
- GHashTableIter iter;
- gpointer key = NULL, value = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_CAL_BACKEND_ETESYNC (meta_backend), FALSE);
g_return_val_if_fail (out_existing_objects != NULL, FALSE);
- *out_existing_objects = NULL;
-
cbetesync = E_CAL_BACKEND_ETESYNC (meta_backend);
connection = cbetesync->priv->connection;
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
- /* 1) Retrive entry_manager, crypto_manager and entries since "last_sync_tag", here "last_sync_tag"
will be NULL
- Failing means connection error */
- if (!e_etesync_connection_check_journal_changed_sync (connection, cbetesync->priv->journal_id, NULL,
FETCH_BATCH_LIMIT, &entries, &crypto_manager, &entry_manager)) {
- g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
- return FALSE;
- }
-
- /* 2) Check if there are entries returned from "e_etesync_connection_check_journal_changed_sync",
- if it is empty then no changes since "last_sync_tag", just free the memory and return, here
"last_sync_tag" will be NULL */
- if (!entries || !*entries) {
- g_free (entries);
- if (entry_manager)
- etesync_entry_manager_destroy (entry_manager);
- if (crypto_manager)
- etesync_crypto_manager_destroy (crypto_manager);
- g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
- return TRUE;
- }
+ success = e_etesync_connection_list_existing_sync (connection,
+ E_BACKEND (meta_backend),
+ E_ETESYNC_CALENDAR,
+ cbetesync->priv->col_obj,
+ out_new_sync_tag,
+ out_existing_objects,
+ cancellable,
+ error);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
- /* 3) At this point, entries are not empty, then we should loop on entries and add each
- one to the hashtable as ECalMetaBackendInfo only keeping last action for each component */
- existing_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_cal_meta_backend_info_free);
- prev_entry_uid = NULL;
-
- while (entries && *entries) {
- gint batch_size = 0;
-
- for (entry_iter = entries; *entry_iter; entry_iter++, batch_size++) {
-
- EteSyncEntry *entry;
- EteSyncSyncEntry *sync_entry;
- ECalMetaBackendInfo *nfo;
- gchar *entry_uid, *action, *content, *component_uid, *revision;
-
- entry = *entry_iter;
- sync_entry = etesync_entry_get_sync_entry (entry, crypto_manager, prev_entry_uid);
-
- action = etesync_sync_entry_get_action (sync_entry);
- content = etesync_sync_entry_get_content (sync_entry);
-
- /* create ECalMetaBackendInfo * to be stored in Hash Table */
- ecb_etesync_get_component_uid_revision (content, &component_uid, &revision);
- nfo = e_cal_meta_backend_info_new (component_uid, revision, content, NULL);
-
- /* check action add, change or delete */
- if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_ADD)
- || g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_CHANGE))
- g_hash_table_replace (existing_entry, g_strdup (component_uid), nfo);
-
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_DELETE))
- g_hash_table_remove (existing_entry, component_uid);
-
- else
- e_cal_meta_backend_info_free (nfo);
-
- entry_uid = etesync_entry_get_uid (entry);
- g_free (prev_entry_uid);
- prev_entry_uid = entry_uid;
-
- etesync_sync_entry_destroy (sync_entry);
- etesync_entry_destroy (entry);
- g_free (content);
- g_free (action);
- g_free (component_uid);
- g_free (revision);
- }
-
- if (batch_size < FETCH_BATCH_LIMIT)
- break;
-
- g_free (entries);
- entries = etesync_entry_manager_list (entry_manager, prev_entry_uid, FETCH_BATCH_LIMIT);
- }
-
- /* 4) iterate on each hashtable and add to correspoinding GList */
- g_hash_table_iter_init (&iter, existing_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_existing_objects = g_slist_prepend (*out_existing_objects, e_cal_meta_backend_info_copy
(value));
-
- g_free (entries);
- g_free (prev_entry_uid);
- etesync_entry_manager_destroy (entry_manager);
- etesync_crypto_manager_destroy (crypto_manager);
- g_hash_table_destroy (existing_entry);
-
- return TRUE;
+ return success;
}
static gboolean
@@ -344,154 +158,57 @@ ecb_etesync_get_changes_sync (ECalMetaBackend *meta_backend,
GError **error)
{
ECalBackendEteSync *cbetesync;
- EteSyncEntry **entries = NULL, **entry_iter;
- EteSyncCryptoManager *crypto_manager = NULL;
- EteSyncEntryManager *entry_manager;
EEteSyncConnection *connection;
- gchar *prev_entry_uid = NULL;
- const gchar *last_tag = NULL;
- GHashTable *created_entry, *modified_entry, *removed_entry; /* gchar *uid ~> ECalMetaBackendInfo * */
- GHashTableIter iter;
- gpointer key = NULL, value = NULL;
+ ECalCache *cal_cache;
+ gboolean success = TRUE;
g_return_val_if_fail (E_IS_CAL_BACKEND_ETESYNC (meta_backend), FALSE);
- g_return_val_if_fail (out_new_sync_tag != NULL, FALSE);
- g_return_val_if_fail (out_repeat != NULL, FALSE);
g_return_val_if_fail (out_created_objects != NULL, FALSE);
g_return_val_if_fail (out_modified_objects != NULL, FALSE);
g_return_val_if_fail (out_removed_objects != NULL, FALSE);
- cbetesync = E_CAL_BACKEND_ETESYNC (meta_backend);
- connection = cbetesync->priv->connection;
-
*out_created_objects = NULL;
*out_modified_objects = NULL;
*out_removed_objects = NULL;
+ *out_new_sync_tag = NULL;
- g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
-
- /* Must add preloaded and updating the out_new_sync_tag */
- if (cbetesync->priv->preloaded_sync_tag) {
- *out_created_objects = cbetesync->priv->preloaded_add;
- *out_modified_objects = cbetesync->priv->preloaded_modify;
- *out_removed_objects = cbetesync->priv->preloaded_delete;
- *out_new_sync_tag = cbetesync->priv->preloaded_sync_tag; /* Made here if no chnages are
required to fetch */
- last_tag = cbetesync->priv->preloaded_sync_tag;
-
- cbetesync->priv->preloaded_sync_tag = NULL;
- cbetesync->priv->preloaded_add = NULL;
- cbetesync->priv->preloaded_modify = NULL;
- cbetesync->priv->preloaded_delete = NULL;
- }
-
- if (cbetesync->priv->fetch_from_server) {
- if (!last_tag)
- last_tag = last_sync_tag;
- /* 1) Retrive entry_manager, crypto_manager and entries since "last_sync_tag"
- Failing means connection error */
- if (!e_etesync_connection_check_journal_changed_sync (connection,
cbetesync->priv->journal_id, last_sync_tag, FETCH_BATCH_LIMIT, &entries, &crypto_manager, &entry_manager)) {
- g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
- return FALSE;
- }
-
- /* 2) Check if there are entries returned from
"e_etesync_connection_check_journal_changed_sync",
- if it is empty then no changes since "last_sync_tag", just free the memory and return */
- if (!entries || !*entries) {
- g_free (entries);
- if (entry_manager)
- etesync_entry_manager_destroy (entry_manager);
- if (crypto_manager)
- etesync_crypto_manager_destroy (crypto_manager);
- g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
- return TRUE;
- }
-
- /* 3) At this point, entries are not empty, then we should loop on entries and add each
- one to its hashtable as ECalMetaBackendInfo depending on the action
("create/modify/delete) */
- created_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_cal_meta_backend_info_free);
- modified_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_cal_meta_backend_info_free);
- removed_entry = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
e_cal_meta_backend_info_free);
- prev_entry_uid = g_strdup (last_tag);
-
- while (entries && *entries) {
- gint batch_size = 0;
-
- for (entry_iter = entries; *entry_iter; entry_iter++, batch_size++) {
-
- EteSyncEntry *entry;
- EteSyncSyncEntry *sync_entry;
- ECalMetaBackendInfo *nfo;
- gchar *entry_uid, *action, *content, *component_uid, *revision;
-
- entry = *entry_iter;
- sync_entry = etesync_entry_get_sync_entry (entry, crypto_manager,
prev_entry_uid);
-
- action = etesync_sync_entry_get_action (sync_entry);
- content = etesync_sync_entry_get_content (sync_entry);
-
- /* create ECalMetaBackendInfo * to be stored in Hash Table */
- ecb_etesync_get_component_uid_revision (content, &component_uid, &revision);
- nfo = e_cal_meta_backend_info_new (component_uid, revision, content, NULL);
-
- /* check action add, change or delete */
- if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_ADD))
- ecb_etesync_update_hash_tables (created_entry, modified_entry,
removed_entry, component_uid, nfo);
-
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_CHANGE))
- ecb_etesync_update_hash_tables (modified_entry, created_entry
,removed_entry, component_uid, nfo);
-
- else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_DELETE))
- ecb_etesync_update_hash_tables (removed_entry, created_entry,
modified_entry, component_uid, nfo);
+ cbetesync = E_CAL_BACKEND_ETESYNC (meta_backend);
+ connection = cbetesync->priv->connection;
- else
- e_cal_meta_backend_info_free (nfo);
+ g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
- entry_uid = etesync_entry_get_uid (entry);
- g_free (prev_entry_uid);
- prev_entry_uid = entry_uid;
+ /* Must add preloaded */
+ *out_created_objects = cbetesync->priv->preloaded_add;
+ *out_modified_objects = cbetesync->priv->preloaded_modify;
+ *out_removed_objects = cbetesync->priv->preloaded_delete;
- etesync_sync_entry_destroy (sync_entry);
- etesync_entry_destroy (entry);
- g_free (content);
- g_free (action);
- g_free (component_uid);
- g_free (revision);
- }
+ cbetesync->priv->preloaded_add = NULL;
+ cbetesync->priv->preloaded_modify = NULL;
+ cbetesync->priv->preloaded_delete = NULL;
- if (batch_size < FETCH_BATCH_LIMIT)
- break;
+ if (cbetesync->priv->fetch_from_server) {
+ cal_cache = e_cal_meta_backend_ref_cache (meta_backend);
- g_free (entries);
- entries = etesync_entry_manager_list (entry_manager, prev_entry_uid,
FETCH_BATCH_LIMIT);
+ if (cal_cache) {
+ success = e_etesync_connection_get_changes_sync (connection,
+ E_BACKEND (meta_backend),
+ E_ETESYNC_CALENDAR,
+ last_sync_tag,
+ cbetesync->priv->col_obj,
+ E_CACHE (cal_cache),
+ out_new_sync_tag,
+ out_created_objects,
+ out_modified_objects,
+ out_removed_objects,
+ cancellable,
+ error);
+ g_object_unref (cal_cache);
}
-
- *out_new_sync_tag = prev_entry_uid;
-
- /* 4) iterate on each hashtable and add to correspoinding GList */
- g_hash_table_iter_init (&iter, created_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_created_objects = g_slist_prepend (*out_created_objects,
e_cal_meta_backend_info_copy (value));
-
- g_hash_table_iter_init (&iter, modified_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_modified_objects = g_slist_prepend (*out_modified_objects,
e_cal_meta_backend_info_copy (value));
-
- g_hash_table_iter_init (&iter, removed_entry);
- while (g_hash_table_iter_next (&iter, &key, &value))
- *out_removed_objects = g_slist_prepend (*out_removed_objects,
e_cal_meta_backend_info_copy (value));
-
- g_free (entries);
- etesync_entry_manager_destroy (entry_manager);
- etesync_crypto_manager_destroy (crypto_manager);
- g_hash_table_destroy (created_entry);
- g_hash_table_destroy (modified_entry);
- g_hash_table_destroy (removed_entry);
-
}
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
- return TRUE;
+ return success;
}
static gboolean
@@ -539,7 +256,7 @@ ecb_etesync_save_component_sync (ECalMetaBackend *meta_backend,
gboolean overwrite_existing,
EConflictResolution conflict_resolution,
const GSList *instances, /* ECalComponent * */
- const gchar *extra,
+ const gchar *extra, /* item_uid */
guint32 opflags,
gchar **out_new_uid,
gchar **out_new_extra,
@@ -548,14 +265,14 @@ ecb_etesync_save_component_sync (ECalMetaBackend *meta_backend,
{
ECalBackendEteSync *cbetesync;
EEteSyncConnection *connection;
+ gboolean success = FALSE;
ICalComponent *vcalendar = NULL;
- gboolean success = FALSE, conflict = TRUE;
- gchar *last_sync_tag, *content;
- gchar *new_sync_tag;
- ECalMetaBackendInfo *info;
- EteSyncErrorCode etesync_error;
+ gchar *content;
+ const gchar *uid;
g_return_val_if_fail (E_IS_CAL_BACKEND_ETESYNC (meta_backend), FALSE);
+ g_return_val_if_fail (out_new_uid != NULL, FALSE);
+ g_return_val_if_fail (out_new_extra != NULL, FALSE);
cbetesync = E_CAL_BACKEND_ETESYNC (meta_backend);
connection = cbetesync->priv->connection;
@@ -563,59 +280,28 @@ ecb_etesync_save_component_sync (ECalMetaBackend *meta_backend,
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
vcalendar = e_cal_meta_backend_merge_instances (meta_backend, instances, TRUE);
- g_return_val_if_fail (vcalendar != NULL, FALSE);
-
- content = i_cal_component_as_ical_string (vcalendar);
-
- while (conflict) {
- last_sync_tag = e_cal_meta_backend_dup_sync_tag (meta_backend);
-
- if (overwrite_existing) {
- success = e_etesync_connection_entry_write_action (connection,
cbetesync->priv->journal_id,
- last_sync_tag, content, ETESYNC_SYNC_ENTRY_ACTION_CHANGE, &new_sync_tag,
&etesync_error);
- } else {
- success = e_etesync_connection_entry_write_action (connection,
cbetesync->priv->journal_id,
- last_sync_tag, content, ETESYNC_SYNC_ENTRY_ACTION_ADD, &new_sync_tag,
&etesync_error);
- }
- if (success) {
- gchar *rev, *uid;
-
- ecb_etesync_get_component_uid_revision (content, &uid, &rev);
- info = e_cal_meta_backend_info_new (uid, rev, content, NULL);
-
- cbetesync->priv->preloaded_sync_tag = g_strdup (new_sync_tag);
- if (overwrite_existing)
- cbetesync->priv->preloaded_modify = g_slist_prepend
(cbetesync->priv->preloaded_modify, info);
- else
- cbetesync->priv->preloaded_add = g_slist_prepend
(cbetesync->priv->preloaded_add, info);
-
- conflict = FALSE;
- g_free (uid);
- g_free (rev);
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT)
- conflict = FALSE;
- else {
- if (! e_cal_meta_backend_refresh_sync (meta_backend, cancellable, error))
- conflict = FALSE;
- }
- }
-
- g_free (new_sync_tag);
- g_free (last_sync_tag);
+ if (!vcalendar) {
+ g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
+ return FALSE;
}
- if (success) {
- cbetesync->priv->fetch_from_server = FALSE;
- e_cal_meta_backend_refresh_sync (meta_backend, cancellable, error);
- cbetesync->priv->fetch_from_server = TRUE;
+ content = i_cal_component_as_ical_string (vcalendar);
+ uid = i_cal_component_get_uid (vcalendar);
+
+ if (overwrite_existing) {
+ success = e_etesync_connection_item_upload_sync (connection, E_BACKEND (meta_backend),
cbetesync->priv->col_obj,
+ E_ETESYNC_ITEM_ACTION_MODIFY, content, uid, extra, out_new_extra, cancellable, error);
+ } else {
+ success = e_etesync_connection_item_upload_sync (connection, E_BACKEND (meta_backend),
cbetesync->priv->col_obj,
+ E_ETESYNC_ITEM_ACTION_CREATE, content, uid, NULL, out_new_extra, cancellable, error);
}
g_free (content);
g_object_unref (vcalendar);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
+
return success;
}
@@ -623,7 +309,7 @@ static gboolean
ecb_etesync_remove_component_sync (ECalMetaBackend *meta_backend,
EConflictResolution conflict_resolution,
const gchar *uid,
- const gchar *extra,
+ const gchar *extra, /* item_uid */
const gchar *object,
guint32 opflags,
GCancellable *cancellable,
@@ -631,13 +317,7 @@ ecb_etesync_remove_component_sync (ECalMetaBackend *meta_backend,
{
ECalBackendEteSync *cbetesync;
EEteSyncConnection *connection;
- ICalComponent *vcalendar = NULL;
- gboolean success = FALSE, conflict = TRUE;
- gchar *last_sync_tag, *new_sync_tag, *content;
- GSList *instances = NULL;
- ECalCache *cal_cache;
- ECalMetaBackendInfo *info;
- EteSyncErrorCode etesync_error;
+ gboolean success = FALSE;
g_return_val_if_fail (E_IS_CAL_BACKEND_ETESYNC (meta_backend), FALSE);
@@ -646,60 +326,8 @@ ecb_etesync_remove_component_sync (ECalMetaBackend *meta_backend,
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
- /* Search cache data for the required component */
- cal_cache = e_cal_meta_backend_ref_cache (meta_backend);
-
- if (cal_cache) {
- if (e_cal_cache_get_components_by_uid (cal_cache, uid, &instances, cancellable, NULL)) {
- vcalendar = e_cal_meta_backend_merge_instances (meta_backend, instances, TRUE);
- content = i_cal_component_as_ical_string (vcalendar);
- success = TRUE;
- }
- g_object_unref (cal_cache);
- }
-
- /* Checking if the calendar with that uid has been found */
- if (success) {
- while (conflict) {
- last_sync_tag = e_cal_meta_backend_dup_sync_tag (meta_backend);
-
- success = e_etesync_connection_entry_write_action (connection,
cbetesync->priv->journal_id,
- last_sync_tag, content, ETESYNC_SYNC_ENTRY_ACTION_DELETE, &new_sync_tag,
&etesync_error);
-
- if (success) {
- gchar *rev, *uid;
-
- ecb_etesync_get_component_uid_revision (content, &uid, &rev);
- info = e_cal_meta_backend_info_new (uid, rev, content, NULL);
-
- cbetesync->priv->preloaded_sync_tag = g_strdup (new_sync_tag);
- cbetesync->priv->preloaded_delete = g_slist_prepend
(cbetesync->priv->preloaded_delete, info);
- conflict = FALSE;
- g_free (uid);
- g_free (rev);
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT)
- conflict = FALSE;
- else {
- if (! e_cal_meta_backend_refresh_sync (meta_backend, cancellable,
error))
- conflict = FALSE;
- }
- }
-
- g_free (new_sync_tag);
- g_free (last_sync_tag);
- }
-
- g_free (content);
- g_object_unref (vcalendar);
- g_slist_free_full (instances, g_object_unref);
- }
-
- if (success) {
- cbetesync->priv->fetch_from_server = FALSE;
- e_cal_meta_backend_refresh_sync (meta_backend, cancellable, error);
- cbetesync->priv->fetch_from_server = TRUE;
- }
+ success = e_etesync_connection_item_upload_sync (connection, E_BACKEND (meta_backend),
cbetesync->priv->col_obj,
+ E_ETESYNC_ITEM_ACTION_DELETE, NULL, uid, extra, NULL, cancellable, error);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
@@ -713,14 +341,12 @@ ecb_etesync_create_objects_sync (ECalBackendSync *backend,
GCancellable *cancellable,
const GSList *calobjs,
guint32 opflags,
- GSList **uids,
- GSList **new_components,
+ GSList **out_uids,
+ GSList **out_new_components,
GError **error)
{
ECalBackendEteSync *cbetesync;
EEteSyncConnection *connection;
- EteSyncErrorCode etesync_error;
- gchar *last_sync_tag;
gboolean success = TRUE;
const GSList *l;
@@ -728,15 +354,14 @@ ecb_etesync_create_objects_sync (ECalBackendSync *backend,
if (!calobjs || !calobjs->next) {
/* Chain up to parent's method. */
- E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_etesync_parent_class)->create_objects_sync (backend,
cal, cancellable, calobjs, opflags, uids, new_components, error);
+ E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_etesync_parent_class)->create_objects_sync (backend,
cal, cancellable, calobjs, opflags, out_uids, out_new_components, error);
return;
}
cbetesync = E_CAL_BACKEND_ETESYNC (backend);
connection = cbetesync->priv->connection;
- last_sync_tag = e_cal_meta_backend_dup_sync_tag (E_CAL_META_BACKEND (cbetesync));
- *uids = NULL;
- *new_components = NULL;
+ *out_uids = NULL;
+ *out_new_components = NULL;
l = calobjs;
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
@@ -744,21 +369,19 @@ ecb_etesync_create_objects_sync (ECalBackendSync *backend,
/* extract the components and mass-add them to the server "batch by batch" */
while (l && success) {
gchar **content;
- gboolean conflict = TRUE;
GSList *batch_uids = NULL; /* gchar* */
GSList *batch_components= NULL; /* ECalComponent* */
GSList *batch_info = NULL; /* ECalMetaBackendInfo* */
guint ii, batch_length = 0;
- content = g_slice_alloc0 (PUSH_BATCH_LIMIT * sizeof (gchar *));
+ content = g_slice_alloc0 (E_ETESYNC_ITEM_PUSH_LIMIT * sizeof (gchar *));
/* Data Preproccessing */
- for (ii = 0 ; ii < PUSH_BATCH_LIMIT && l; l = l->next, ii++) {
+ for (ii = 0 ; ii < E_ETESYNC_ITEM_PUSH_LIMIT && l; l = l->next, ii++) {
ICalComponent *icomp, *vcal;
ECalComponent *comp;
ICalTime *current;
- ECalMetaBackendInfo *info;
- gchar *comp_uid, *comp_revision;
+ gchar *comp_uid;
/* Parse the icalendar text */
icomp = i_cal_parser_parse_string ((gchar *) l->data);
@@ -770,7 +393,7 @@ ecb_etesync_create_objects_sync (ECalBackendSync *backend,
/* Preserve original UID, create a unique UID if needed */
if (!i_cal_component_get_uid (icomp)) {
- gchar *new_uid = etesync_gen_uid ();
+ gchar *new_uid = e_util_generate_uid ();
i_cal_component_set_uid (icomp, new_uid);
g_free (new_uid);
}
@@ -796,55 +419,41 @@ ecb_etesync_create_objects_sync (ECalBackendSync *backend,
} else
content[ii] = i_cal_component_as_ical_string (icomp);
- ecb_etesync_get_component_uid_revision (content[ii], &comp_uid, &comp_revision);
- info = e_cal_meta_backend_info_new (comp_uid, comp_revision, content[ii], NULL);
-
+ comp_uid = g_strdup (i_cal_component_get_uid (icomp));
batch_components = g_slist_prepend (batch_components, e_cal_component_clone (comp));
batch_uids = g_slist_prepend (batch_uids, comp_uid);
- batch_info = g_slist_prepend (batch_info, info);
- g_free (comp_revision);
g_object_unref (comp);
}
batch_length = ii;
if (success) {
- while (conflict) {
- success = e_etesync_connection_multiple_entry_write_action (connection,
- cbetesync->priv->journal_id,
- (const gchar* const*) content,
- batch_length,
ETESYNC_SYNC_ENTRY_ACTION_ADD,
- &last_sync_tag,
&etesync_error);
-
- if (success) {
- g_free (cbetesync->priv->preloaded_sync_tag);
- cbetesync->priv->preloaded_sync_tag = g_strdup (last_sync_tag);
- cbetesync->priv->preloaded_add = g_slist_concat (batch_info,
cbetesync->priv->preloaded_add);
- *new_components = g_slist_concat (*new_components, batch_components);
- *uids = g_slist_concat (*uids, batch_uids);
- conflict = FALSE;
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT) {
- g_slist_free_full (batch_components, g_object_unref);
- g_slist_free_full (batch_info, e_cal_meta_backend_info_free);
- g_slist_free_full (batch_uids, g_free);
- conflict = FALSE;
- } else { /* Repeat again if a conflict existed */
- /* This will empty batch_info and update the last_sync_tag to
avoid conflict again */
- if (!e_cal_meta_backend_refresh_sync (E_CAL_META_BACKEND
(cbetesync), NULL, NULL))
- conflict = FALSE;
-
- g_free (last_sync_tag);
- last_sync_tag = e_cal_meta_backend_dup_sync_tag
(E_CAL_META_BACKEND (cbetesync));
- }
- }
+ success = e_etesync_connection_batch_create_sync (connection,
+ E_BACKEND (E_CAL_META_BACKEND
(cbetesync)),
+ cbetesync->priv->col_obj,
+ E_ETESYNC_CALENDAR,
+ (const gchar *const*) content,
+ batch_length, /* length of content
*/
+ &batch_info,
+ cancellable,
+ error);
+
+ if (success) {
+ cbetesync->priv->preloaded_add = g_slist_concat (batch_info,
cbetesync->priv->preloaded_add);
+ *out_new_components = g_slist_concat (*out_new_components, batch_components);
+ *out_uids = g_slist_concat (*out_uids, batch_uids);
+ } else {
+ g_slist_free_full (batch_components, g_object_unref);
+ g_slist_free_full (batch_uids, g_free);
+ g_slist_free_full (batch_info, e_cal_meta_backend_info_free);
}
+
}
for (ii = 0; ii < batch_length; ii++)
g_free (content[ii]);
- g_slice_free1 (PUSH_BATCH_LIMIT * sizeof (gchar *), content);
+ g_slice_free1 (E_ETESYNC_ITEM_PUSH_LIMIT * sizeof (gchar *), content);
}
if (success) {
@@ -852,15 +461,14 @@ ecb_etesync_create_objects_sync (ECalBackendSync *backend,
e_cal_meta_backend_refresh_sync (E_CAL_META_BACKEND (cbetesync), cancellable, error);
cbetesync->priv->fetch_from_server = TRUE;
} else {
- g_slist_free_full (*new_components, g_object_unref);
- g_slist_free_full (*uids, g_free);
- *new_components = NULL;
- *uids = NULL;
+ g_slist_free_full (*out_new_components, g_object_unref);
+ g_slist_free_full (*out_uids, g_free);
+ *out_new_components = NULL;
+ *out_uids = NULL;
}
/* free any data related to this bulk operation */
cbetesync->priv->preloaded_add = NULL;
- g_free (last_sync_tag);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
@@ -874,15 +482,13 @@ ecb_etesync_modify_objects_sync (ECalBackendSync *backend,
const GSList *calobjs,
ECalObjModType mod,
guint32 opflags,
- GSList **old_components,
- GSList **new_components,
+ GSList **out_old_components,
+ GSList **out_new_components,
GError **error)
{
ECalBackendEteSync *cbetesync;
ECalCache *cal_cache;
EEteSyncConnection *connection;
- EteSyncErrorCode etesync_error;
- gchar *last_sync_tag;
gboolean success = TRUE;
const GSList *l;
@@ -890,16 +496,15 @@ ecb_etesync_modify_objects_sync (ECalBackendSync *backend,
if (!calobjs || !calobjs->next) {
/* Chain up to parent's method. */
- E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_etesync_parent_class)->modify_objects_sync (backend,
cal, cancellable, calobjs, mod, opflags, old_components, new_components, error);
+ E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_etesync_parent_class)->modify_objects_sync (backend,
cal, cancellable, calobjs, mod, opflags, out_old_components, out_new_components, error);
return;
}
cbetesync = E_CAL_BACKEND_ETESYNC (backend);
cal_cache = e_cal_meta_backend_ref_cache (E_CAL_META_BACKEND (cbetesync));
connection = cbetesync->priv->connection;
- last_sync_tag = e_cal_meta_backend_dup_sync_tag (E_CAL_META_BACKEND (cbetesync));
- *old_components = NULL;
- *new_components = NULL;
+ *out_old_components = NULL;
+ *out_new_components = NULL;
l = calobjs;
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
@@ -907,21 +512,19 @@ ecb_etesync_modify_objects_sync (ECalBackendSync *backend,
/* extract the components and mass-add them to the server "batch by batch" */
while (l && success) {
gchar **content;
- gboolean conflict = TRUE;
- GSList *batch_old_components = NULL; /* ECalComponent* */
- GSList *batch_new_components= NULL; /* ECalComponent* */
+ GSList *batch_out_old_components = NULL; /* ECalComponent* */
+ GSList *batch_out_new_components= NULL; /* ECalComponent* */
GSList *batch_info = NULL; /* ECalMetaBackendInfo* */
guint ii, batch_length = 0;
- content = g_slice_alloc0 (PUSH_BATCH_LIMIT * sizeof (gchar *));
+ content = g_slice_alloc0 (E_ETESYNC_ITEM_PUSH_LIMIT * sizeof (gchar *));
/* Data Preproccessing */
- for (ii = 0 ; ii < PUSH_BATCH_LIMIT && l; l = l->next, ii++) {
+ for (ii = 0 ; ii < E_ETESYNC_ITEM_PUSH_LIMIT && l; l = l->next, ii++) {
ICalComponent *icomp, *vcal;
ECalComponent *comp;
ICalTime *current;
- ECalMetaBackendInfo *info;
- gchar *comp_uid, *comp_revision;
+ const gchar *comp_uid;
GSList *instances;
/* Parse the icalendar text */
@@ -946,59 +549,43 @@ ecb_etesync_modify_objects_sync (ECalBackendSync *backend,
} else
content[ii] = i_cal_component_as_ical_string (icomp);
- ecb_etesync_get_component_uid_revision (content[ii], &comp_uid, &comp_revision);
-
- info = e_cal_meta_backend_info_new (comp_uid, comp_revision, content[ii], NULL);
-
- batch_new_components = g_slist_prepend (batch_new_components, e_cal_component_clone
(comp));
- batch_info = g_slist_prepend (batch_info, info);
+ comp_uid = i_cal_component_get_uid (icomp);
+ batch_out_new_components = g_slist_prepend (batch_out_new_components,
e_cal_component_clone (comp));
if (e_cal_cache_get_components_by_uid (cal_cache, comp_uid, &instances, NULL, NULL))
- batch_old_components = g_slist_concat (batch_old_components, instances);
+ batch_out_old_components = g_slist_concat (batch_out_old_components,
instances);
- g_free (comp_uid);
- g_free (comp_revision);
g_object_unref (comp);
}
batch_length = ii;
if (success) {
- while (conflict) {
- success = e_etesync_connection_multiple_entry_write_action (connection,
- cbetesync->priv->journal_id,
- (const gchar* const*) content,
- batch_length,
ETESYNC_SYNC_ENTRY_ACTION_CHANGE,
- &last_sync_tag,
&etesync_error);
-
- if (success) {
- g_free (cbetesync->priv->preloaded_sync_tag);
- cbetesync->priv->preloaded_sync_tag = g_strdup (last_sync_tag);
- cbetesync->priv->preloaded_modify = g_slist_concat (batch_info,
cbetesync->priv->preloaded_modify);
- *new_components = g_slist_concat (*new_components,
batch_new_components);
- *old_components = g_slist_concat (*old_components,
batch_old_components);
- conflict = FALSE;
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT) {
- g_slist_free_full (batch_new_components, g_object_unref);
- g_slist_free_full (batch_old_components, g_object_unref);
- g_slist_free_full (batch_info, e_cal_meta_backend_info_free);
- conflict = FALSE;
- } else { /* Repeat again if a conflict existed */
- /* This will empty batch_info and update the last_sync_tag to
avoid conflict again */
- if (!e_cal_meta_backend_refresh_sync (E_CAL_META_BACKEND
(cbetesync), NULL, NULL))
- conflict = FALSE;
-
- g_free (last_sync_tag);
- last_sync_tag = e_cal_meta_backend_dup_sync_tag
(E_CAL_META_BACKEND (cbetesync));
- }
- }
+ success = e_etesync_connection_batch_modify_sync (connection,
+ E_BACKEND (E_CAL_META_BACKEND
(cbetesync)),
+ cbetesync->priv->col_obj,
+ E_ETESYNC_CALENDAR,
+ (const gchar *const*) content,
+ batch_length, /* length of content
*/
+ E_CACHE (cal_cache), /* uses
cal_cache if type is calendar */
+ &batch_info,
+ cancellable,
+ error);
+
+ if (success) {
+ cbetesync->priv->preloaded_modify = g_slist_concat (batch_info,
cbetesync->priv->preloaded_modify);
+ *out_new_components = g_slist_concat (*out_new_components,
batch_out_new_components);
+ *out_old_components = g_slist_concat (*out_old_components,
batch_out_old_components);
+ } else {
+ g_slist_free_full (batch_out_new_components, g_object_unref);
+ g_slist_free_full (batch_out_old_components, g_object_unref);
+ g_slist_free_full (batch_info, e_cal_meta_backend_info_free);
}
}
for (ii = 0; ii < batch_length; ii++)
g_free (content[ii]);
- g_slice_free1 (PUSH_BATCH_LIMIT * sizeof (gchar *), content);
+ g_slice_free1 (E_ETESYNC_ITEM_PUSH_LIMIT * sizeof (gchar *), content);
}
if (success) {
@@ -1006,15 +593,14 @@ ecb_etesync_modify_objects_sync (ECalBackendSync *backend,
e_cal_meta_backend_refresh_sync (E_CAL_META_BACKEND (cbetesync), cancellable, error);
cbetesync->priv->fetch_from_server = TRUE;
} else {
- g_slist_free_full (*new_components, g_object_unref);
- g_slist_free_full (*old_components, g_object_unref);
- *new_components = NULL;
- *old_components = NULL;
+ g_slist_free_full (*out_new_components, g_object_unref);
+ g_slist_free_full (*out_old_components, g_object_unref);
+ *out_new_components = NULL;
+ *out_old_components = NULL;
}
/* free any data related to this bulk operation */
cbetesync->priv->preloaded_modify = NULL;
- g_free (last_sync_tag);
g_object_unref (cal_cache);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
@@ -1029,15 +615,13 @@ ecb_etesync_remove_objects_sync (ECalBackendSync *backend,
const GSList *ids,
ECalObjModType mod,
guint32 opflags,
- GSList **old_components,
- GSList **new_components,
+ GSList **out_old_components,
+ GSList **out_new_components,
GError **error)
{
ECalBackendEteSync *cbetesync;
ECalCache *cal_cache;
EEteSyncConnection *connection;
- EteSyncErrorCode etesync_error;
- gchar *last_sync_tag;
gboolean success = TRUE;
const GSList *l;
@@ -1045,16 +629,15 @@ ecb_etesync_remove_objects_sync (ECalBackendSync *backend,
if (!ids || !ids->next) {
/* Chain up to parent's method. */
- E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_etesync_parent_class)->remove_objects_sync (backend,
cal, cancellable, ids, mod, opflags, old_components, new_components, error);
+ E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_etesync_parent_class)->remove_objects_sync (backend,
cal, cancellable, ids, mod, opflags, out_old_components, out_new_components, error);
return;
}
cbetesync = E_CAL_BACKEND_ETESYNC (backend);
cal_cache = e_cal_meta_backend_ref_cache (E_CAL_META_BACKEND (cbetesync));
connection = cbetesync->priv->connection;
- last_sync_tag = e_cal_meta_backend_dup_sync_tag (E_CAL_META_BACKEND (cbetesync));
- *old_components = NULL;
- *new_components = NULL;
+ *out_old_components = NULL;
+ *out_new_components = NULL;
l = ids;
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
@@ -1062,18 +645,15 @@ ecb_etesync_remove_objects_sync (ECalBackendSync *backend,
/* extract the components and mass-add them to the server "batch by batch" */
while (l && success) {
gchar **content;
- gboolean conflict = TRUE;
- GSList *batch_old_components = NULL; /* ECalComponent* */
+ GSList *batch_out_old_components = NULL; /* ECalComponent* */
GSList *batch_info = NULL; /* ECalMetaBackendInfo* */
guint ii, batch_length = 0;
- content = g_slice_alloc0 (PUSH_BATCH_LIMIT * sizeof (gchar *));
+ content = g_slice_alloc0 (E_ETESYNC_ITEM_PUSH_LIMIT * sizeof (gchar *));
/* Data Preproccessing */
- for (ii = 0; ii < PUSH_BATCH_LIMIT && l; l = l->next, ii++) {
+ for (ii = 0; ii < E_ETESYNC_ITEM_PUSH_LIMIT && l; l = l->next, ii++) {
ICalComponent *vcal;
- ECalMetaBackendInfo *info;
- gchar *comp_uid, *comp_revision;
GSList *instances;
if (e_cal_cache_get_components_by_uid (cal_cache, e_cal_component_id_get_uid
(l->data), &instances, cancellable, NULL)) {
@@ -1085,55 +665,36 @@ ecb_etesync_remove_objects_sync (ECalBackendSync *backend,
break;
}
- ecb_etesync_get_component_uid_revision (content[ii], &comp_uid, &comp_revision);
-
- info = e_cal_meta_backend_info_new (comp_uid, comp_revision, content[ii], NULL);
-
- batch_info = g_slist_prepend (batch_info, info);
- batch_old_components = g_slist_concat (batch_old_components, instances);
- *new_components = g_slist_prepend (*new_components, NULL);
-
- g_free (comp_uid);
- g_free (comp_revision);
+ batch_out_old_components = g_slist_concat (batch_out_old_components, instances);
+ *out_new_components = g_slist_prepend (*out_new_components, NULL);
}
batch_length = ii;
if (success) {
- while (conflict) {
- success = e_etesync_connection_multiple_entry_write_action (connection,
- cbetesync->priv->journal_id,
- (const gchar* const*) content,
- batch_length,
ETESYNC_SYNC_ENTRY_ACTION_DELETE,
- &last_sync_tag,
&etesync_error);
-
- if (success) {
- g_free (cbetesync->priv->preloaded_sync_tag);
- cbetesync->priv->preloaded_sync_tag = g_strdup (last_sync_tag);
- cbetesync->priv->preloaded_delete = g_slist_concat (batch_info,
cbetesync->priv->preloaded_delete);
- *old_components = g_slist_concat (*old_components,
batch_old_components);
-
- conflict = FALSE;
- } else {
- if (etesync_error != ETESYNC_ERROR_CODE_CONFLICT) {
- g_slist_free_full (batch_old_components, g_object_unref);
- g_slist_free_full (batch_info, e_cal_meta_backend_info_free);
- conflict = FALSE;
- } else { /* Repeat again if a conflict existed */
- /* This will empty batch_info and update the last_sync_tag to
avoid conflict again */
- if (!e_cal_meta_backend_refresh_sync (E_CAL_META_BACKEND
(cbetesync), NULL, NULL))
- conflict = FALSE;
-
- g_free (last_sync_tag);
- last_sync_tag = e_cal_meta_backend_dup_sync_tag
(E_CAL_META_BACKEND (cbetesync));
- }
- }
+ success = e_etesync_connection_batch_delete_sync (connection,
+ E_BACKEND (E_CAL_META_BACKEND
(cbetesync)),
+ cbetesync->priv->col_obj,
+ E_ETESYNC_CALENDAR,
+ (const gchar *const*) content,
+ batch_length, /* length of content
*/
+ E_CACHE (cal_cache), /* uses
cal_cache if type is calendar */
+ &batch_info,
+ cancellable,
+ error);
+
+ if (success) {
+ cbetesync->priv->preloaded_delete = g_slist_concat (batch_info,
cbetesync->priv->preloaded_delete);
+ *out_old_components = g_slist_concat (*out_old_components,
batch_out_old_components);
+ } else {
+ g_slist_free_full (batch_out_old_components, g_object_unref);
+ g_slist_free_full (batch_info, e_cal_meta_backend_info_free);
}
}
for (ii = 0; ii < batch_length; ii++)
g_free (content[ii]);
- g_slice_free1 (PUSH_BATCH_LIMIT * sizeof (gchar *), content);
+ g_slice_free1 (E_ETESYNC_ITEM_PUSH_LIMIT * sizeof (gchar *), content);
}
if (success) {
@@ -1141,34 +702,18 @@ ecb_etesync_remove_objects_sync (ECalBackendSync *backend,
e_cal_meta_backend_refresh_sync (E_CAL_META_BACKEND (cbetesync), cancellable, error);
cbetesync->priv->fetch_from_server = TRUE;
} else {
- g_slist_free_full (*old_components, g_object_unref);
- *old_components = NULL;
+ g_slist_free_full (*out_old_components, g_object_unref);
+ *out_old_components = NULL;
}
/* free any data related to this bulk operation */
cbetesync->priv->preloaded_delete = NULL;
- g_free (last_sync_tag);
g_object_unref (cal_cache);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
return;
}
-/*------------------------------------------------------------*/
-
-static void
-ecb_etesync_source_changed_cb (ESourceRegistry *registry,
- ESource *source,
- gpointer user_data)
-{
- ESource *collection = e_source_registry_find_extension (registry, source,
E_SOURCE_EXTENSION_COLLECTION);
-
- if (collection) {
- e_etesync_connection_source_changed_cb (source, collection, FALSE);
-
- g_clear_object (&collection);
- }
-}
static gchar *
ecb_etesync_get_backend_property (ECalBackend *cal_backend,
@@ -1198,28 +743,6 @@ ecb_etesync_get_backend_property (ECalBackend *cal_backend,
return E_CAL_BACKEND_CLASS (e_cal_backend_etesync_parent_class)->impl_get_backend_property
(cal_backend, prop_name);
}
-static void
-e_cal_backend_etesync_dispose (GObject *object)
-{
- ECalBackendEteSync *cbetesync = E_CAL_BACKEND_ETESYNC (object);
- ESourceRegistry *registry;
-
- registry = e_cal_backend_get_registry (E_CAL_BACKEND (cbetesync));
-
- /* Only disconnect when backend_count is zero */
- G_LOCK (backend_count);
- if (registry && !--backend_count) {
- g_signal_handler_disconnect (
- registry, source_changed_handler_id);
-
- backend_count = 0;
- }
- G_UNLOCK (backend_count);
-
- /* Chain up to parent's method. */
- G_OBJECT_CLASS (e_cal_backend_etesync_parent_class)->dispose (object);
-}
-
static void
e_cal_backend_etesync_finalize (GObject *object)
{
@@ -1227,8 +750,7 @@ e_cal_backend_etesync_finalize (GObject *object)
g_rec_mutex_lock (&cbetesync->priv->etesync_lock);
g_clear_object (&cbetesync->priv->connection);
- g_clear_pointer (&cbetesync->priv->journal_id, g_free);
- g_clear_pointer (&cbetesync->priv->preloaded_sync_tag, g_free);
+ g_clear_pointer (&cbetesync->priv->col_obj, etebase_collection_destroy);
g_rec_mutex_unlock (&cbetesync->priv->etesync_lock);
g_rec_mutex_clear (&cbetesync->priv->etesync_lock);
@@ -1240,25 +762,16 @@ e_cal_backend_etesync_finalize (GObject *object)
static void
e_cal_backend_etesync_constructed (GObject *object)
{
+ ESource *collection;
ECalBackendEteSync *cbetesync = E_CAL_BACKEND_ETESYNC (object);
- ESourceRegistry *registry;
- gulong handler_id;
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_cal_backend_etesync_parent_class)->constructed (object);
- registry = e_cal_backend_get_registry (E_CAL_BACKEND (cbetesync));
-
- /* Set only once when backend_count is zero to avoid multiple calls on the same file source when
changed */
- G_LOCK (backend_count);
- if (!backend_count++) {
- handler_id = g_signal_connect (
- registry, "source-changed",
- G_CALLBACK (ecb_etesync_source_changed_cb), NULL);
+ collection = ecb_etesync_ref_collection_source (cbetesync);
+ cbetesync->priv->connection = e_etesync_connection_new (collection);
- source_changed_handler_id = handler_id;
- }
- G_UNLOCK (backend_count);
+ g_object_unref (collection);
}
static void
@@ -1267,9 +780,8 @@ e_cal_backend_etesync_init (ECalBackendEteSync *cbetesync)
cbetesync->priv = e_cal_backend_etesync_get_instance_private (cbetesync);
g_rec_mutex_init (&cbetesync->priv->etesync_lock);
cbetesync->priv->connection = NULL;
+ cbetesync->priv->col_obj = NULL;
cbetesync->priv->fetch_from_server = TRUE;
- cbetesync->priv->journal_id = NULL;
- cbetesync->priv->preloaded_sync_tag = NULL;
cbetesync->priv->preloaded_add = NULL;
cbetesync->priv->preloaded_modify = NULL;
cbetesync->priv->preloaded_delete = NULL;
@@ -1301,7 +813,6 @@ e_cal_backend_etesync_class_init (ECalBackendEteSyncClass *klass)
backend_sync_class->remove_objects_sync = ecb_etesync_remove_objects_sync;
object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = e_cal_backend_etesync_dispose;
- object_class->finalize = e_cal_backend_etesync_finalize;
object_class->constructed = e_cal_backend_etesync_constructed;
+ object_class->finalize = e_cal_backend_etesync_finalize;
}
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8f7ea1f..eda8a88 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -3,6 +3,12 @@ set(SOURCES
e-etesync-connection.h
e-source-etesync.c
e-source-etesync.h
+ e-source-etesync-account.c
+ e-source-etesync-account.h
+ e-etesync-service.c
+ e-etesync-service.h
+ e-etesync-utils.c
+ e-etesync-utils.h
e-etesync-defines.h
)
@@ -15,9 +21,13 @@ target_compile_definitions(evolution-etesync PRIVATE
)
target_compile_options(evolution-etesync PUBLIC
+ ${ETESYNC_CFLAGS}
${EVOLUTION_CALENDAR_CFLAGS}
+ ${LIBEBOOK_CFLAGS}
+ ${LIBEDATABOOK_CFLAGS}
+ ${LIBECAL_CFLAGS}
+ ${LIBEDATACAL_CFLAGS}
${LIBEDATASERVER_CFLAGS}
- ${ETESYNC_CFLAGS}
)
target_include_directories(evolution-etesync PUBLIC
@@ -26,15 +36,23 @@ target_include_directories(evolution-etesync PUBLIC
${CMAKE_BINARY_DIR}/src
${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_BINARY_DIR}
+ ${ETESYNC_INCLUDE_DIRS}
${EVOLUTION_CALENDAR_INCLUDE_DIRS}
+ ${LIBEBOOK_INCLUDE_DIRS}
+ ${LIBEDATABOOK_INCLUDE_DIRS}
+ ${LIBECAL_INCLUDE_DIRS}
+ ${LIBEDATACAL_INCLUDE_DIRS}
${LIBEDATASERVER_INCLUDE_DIRS}
- ${ETESYNC_INCLUDE_DIRS}
)
target_link_libraries(evolution-etesync
+ ${ETESYNC_LDFLAGS}
${EVOLUTION_CALENDAR_LDFLAGS}
+ ${LIBEBOOK_LDFLAGS}
+ ${LIBEDATABOOK_LDFLAGS}
+ ${LIBECAL_LDFLAGS}
+ ${LIBEDATACAL_LDFLAGS}
${LIBEDATASERVER_LDFLAGS}
- ${ETESYNC_LDFLAGS}
)
install(TARGETS evolution-etesync
diff --git a/src/common/e-etesync-connection.c b/src/common/e-etesync-connection.c
index 698f08d..ee51078 100644
--- a/src/common/e-etesync-connection.c
+++ b/src/common/e-etesync-connection.c
@@ -9,21 +9,19 @@
#include <glib/gi18n-lib.h>
#include "e-etesync-connection.h"
+#include "e-etesync-utils.h"
#include "common/e-source-etesync.h"
-#include "e-etesync-defines.h"
+#include "common/e-etesync-service.h"
static GMutex connecting;
static GHashTable *loaded_connections_permissions = NULL; /* gchar* ~> EEteSyncConnection* */
struct _EEteSyncConnectionPrivate {
- EteSync *etesync;
- EteSyncJournalManager *journal_manager;
- EteSyncAsymmetricKeyPair *keypair;
-
- gchar *token;
- gchar *derived;
- gchar *server_url;
- gchar *username;
+ EtebaseClient *etebase_client;
+ EtebaseAccount *etebase_account;
+ EtebaseCollectionManager *col_mgr;
+ gchar *session_key;
+ ESource *collection_source;
/* Hash key for the loaded_connections_permissions table. */
gchar *hash_key;
@@ -37,46 +35,52 @@ static void
e_etesync_connection_clear (EEteSyncConnection *connection)
{
g_rec_mutex_lock (&connection->priv->connection_lock);
- if (connection) {
- if (connection->priv->keypair) {
- etesync_keypair_destroy (connection->priv->keypair);
- connection->priv->keypair = NULL;
- }
- if (connection->priv->journal_manager) {
- etesync_journal_manager_destroy (connection->priv->journal_manager);
- connection->priv->journal_manager = NULL;
- }
+ if (connection->priv->col_mgr)
+ g_clear_pointer (&connection->priv->col_mgr, etebase_collection_manager_destroy);
- if (connection->priv->etesync) {
- etesync_destroy (connection->priv->etesync);
- connection->priv->etesync = NULL;
- }
+ if (connection->priv->etebase_client)
+ g_clear_pointer (&connection->priv->etebase_client, etebase_client_destroy);
- g_clear_pointer (&connection->priv->token, g_free);
- g_clear_pointer (&connection->priv->derived, g_free);
- g_clear_pointer (&connection->priv->username, g_free);
- g_clear_pointer (&connection->priv->server_url, g_free);
- }
- g_rec_mutex_unlock (&connection->priv->connection_lock);
-}
+ if (connection->priv->etebase_account)
+ g_clear_pointer (&connection->priv->etebase_account, etebase_account_destroy);
-EEteSyncConnection *
-e_etesync_connection_new (void)
-{
- return g_object_new (E_TYPE_ETESYNC_CONNECTION, NULL);
+ g_clear_pointer (&connection->priv->session_key, g_free);
+
+ g_rec_mutex_unlock (&connection->priv->connection_lock);
}
+/* Returns either a new connection object or an already existing one with the same hash_key */
EEteSyncConnection *
-e_etesync_connection_new_from_user_url (const gchar *username,
- const gchar *server_url)
+e_etesync_connection_new (ESource *collection_source)
{
EEteSyncConnection *connection;
gchar *hash_key;
+ const gchar *username = NULL, *server_url = NULL;
+
+ if (collection_source)
+ g_return_val_if_fail (E_IS_SOURCE (collection_source), NULL);
+ else
+ return g_object_new (E_TYPE_ETESYNC_CONNECTION, NULL);
+
+ if (e_source_has_extension (collection_source, E_SOURCE_EXTENSION_COLLECTION)) {
+ ESourceCollection *collection_extension;
+
+ collection_extension = e_source_get_extension (collection_source,
E_SOURCE_EXTENSION_COLLECTION);
+ server_url = e_source_collection_get_calendar_url (collection_extension);
+ }
+
+ if (e_source_has_extension (collection_source, E_SOURCE_EXTENSION_AUTHENTICATION)) {
+ ESourceAuthentication *authentication_extension;
+
+ authentication_extension = e_source_get_extension (collection_source,
E_SOURCE_EXTENSION_AUTHENTICATION);
+ username = e_source_authentication_get_user (authentication_extension);
+ }
g_return_val_if_fail (username != NULL, NULL);
g_return_val_if_fail (server_url != NULL, NULL);
+ /* Trying to find if an object has been created before, then reference that if not return a new one */
hash_key = g_strdup_printf ("%s@%s", username, server_url);
g_mutex_lock (&connecting);
@@ -96,8 +100,9 @@ e_etesync_connection_new_from_user_url (const gchar *username,
}
/* not found, so create a new connection */
- connection = e_etesync_connection_new ();
+ connection = g_object_new (E_TYPE_ETESYNC_CONNECTION, NULL);
connection->priv->hash_key = hash_key; /* takes ownership */
+ connection->priv->collection_source = g_object_ref (collection_source);
/* add the connection to the loaded_connections_permissions hash table */
if (!loaded_connections_permissions)
@@ -116,299 +121,355 @@ e_etesync_connection_new_from_user_url (const gchar *username,
* or token is invalid or issue with server
*/
ESourceAuthenticationResult
-e_etesync_connection_check_token_validation (EEteSyncConnection *connection)
+e_etesync_connection_check_session_key_validation_sync (EEteSyncConnection *connection,
+ EtebaseErrorCode *out_etebase_error,
+ GError **error)
{
- EteSyncUserInfoManager *user_info_manager;
- EteSyncUserInfo *user_info;
- EteSyncErrorCode etesync_error;
+ EtebaseFetchOptions *fetch_options;
+ EtebaseCollectionListResponse *col_list;
ESourceAuthenticationResult result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ GError *local_error = NULL;
g_return_val_if_fail (connection != NULL ,E_SOURCE_AUTHENTICATION_ERROR);
- g_return_val_if_fail (connection->priv->etesync != NULL ,E_SOURCE_AUTHENTICATION_ERROR);
- g_return_val_if_fail (connection->priv->username != NULL ,E_SOURCE_AUTHENTICATION_ERROR);
+ g_return_val_if_fail (connection->priv->etebase_account != NULL ,E_SOURCE_AUTHENTICATION_ERROR);
g_rec_mutex_lock (&connection->priv->connection_lock);
- user_info_manager = etesync_user_info_manager_new (connection->priv->etesync);
- user_info = etesync_user_info_manager_fetch (user_info_manager, connection->priv->username);
- etesync_error = etesync_get_error_code ();
+ fetch_options = etebase_fetch_options_new ();
+ etebase_fetch_options_set_prefetch(fetch_options, ETEBASE_PREFETCH_OPTION_MEDIUM);
+ etebase_fetch_options_set_limit (fetch_options, 1);
- if (user_info == NULL) {
- if (etesync_error == ETESYNC_ERROR_CODE_UNAUTHORIZED)
+ col_list = etebase_collection_manager_list_multi (connection->priv->col_mgr,
e_etesync_util_get_collection_supported_types (), EETESYNC_UTILS_SUPPORTED_TYPES_SIZE, fetch_options);
+
+ if (!col_list) {
+ EtebaseErrorCode etebase_error = etebase_error_get_code ();
+
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED)
result = E_SOURCE_AUTHENTICATION_REJECTED;
else
result = E_SOURCE_AUTHENTICATION_ERROR;
+
+ e_etesync_utils_set_io_gerror (etebase_error_get_code (), etebase_error_get_message (),
&local_error);
} else {
- etesync_user_info_destroy (user_info);
+ etebase_collection_list_response_destroy (col_list);
+ }
+ etebase_fetch_options_destroy (fetch_options);
+
+ if (local_error) {
+ g_propagate_error (error, local_error);
+
+ if (out_etebase_error)
+ *out_etebase_error = etebase_error_get_code ();
}
- etesync_user_info_manager_destroy (user_info_manager);
g_rec_mutex_unlock (&connection->priv->connection_lock);
return result;
}
-/* create: connection, journal_type, display_name */
-static gboolean
-e_etesync_connection_journal_create (EEteSyncConnection *connection,
- const gchar *journal_type,
- const gchar *display_name,
- const gchar *description,
- const gint32 color,
- EteSyncJournal **out_journal)
+gboolean
+e_etesync_connection_set_connection_from_sources (EEteSyncConnection *connection,
+ const ENamedParameters *credentials)
{
- EteSyncJournal *journal;
- EteSyncCollectionInfo *info = NULL;
- EteSyncCryptoManager *crypto_manager = NULL;
- gint32 local_error;
- gchar *uid = NULL;
+ const gchar *server_url , *session_key;
gboolean success = TRUE;
+ ESourceCollection *collection_extension;
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (display_name != NULL, FALSE);
- g_return_val_if_fail (journal_type != NULL, FALSE);
+ g_return_val_if_fail (connection != NULL ,FALSE);
g_rec_mutex_lock (&connection->priv->connection_lock);
- uid = etesync_gen_uid ();
- journal = etesync_journal_new (uid, ETESYNC_CURRENT_VERSION);
- info = etesync_collection_info_new (journal_type, display_name, description, color);
- crypto_manager = etesync_journal_get_crypto_manager (journal, connection->priv->derived,
connection->priv->keypair);
+ collection_extension = e_source_get_extension (connection->priv->collection_source,
E_SOURCE_EXTENSION_COLLECTION);
+ e_etesync_connection_clear (connection);
- etesync_journal_set_info (journal, crypto_manager, info);
- local_error = etesync_journal_manager_create (connection->priv->journal_manager, journal);
+ /* 1) get_server from ESourceAuthentication as it was saved when the user was entering credentials in
the dialog first time.
+ Set the etebase_client then for this backend so as long as the backend is alive, we don't have
to do this process again */
+ server_url = e_source_collection_get_calendar_url (collection_extension);
+ connection->priv->etebase_client = etebase_client_new (PACKAGE "/" VERSION, server_url);
- /* zero means success, other means fail */
- if (local_error)
- success = FALSE;
+ /* problem with the server_url */
+ if (!connection->priv->etebase_client) {
+ g_rec_mutex_unlock (&connection->priv->connection_lock);
+ return FALSE;
+ }
- g_free (uid);
- etesync_crypto_manager_destroy (crypto_manager);
- etesync_collection_info_destroy (info);
+ /* 2) get stored sessions from Credentials (Should be stored there) */
+ session_key = e_named_parameters_get (credentials, E_ETESYNC_CREDENTIAL_SESSION_KEY);
- if (out_journal && success)
- *out_journal = journal;
- else
- etesync_journal_destroy (journal);
+ /* 3) check if the session key is NULL, if so that may mean that the password is wrong
+ or changed, or simply the session key is not stored. */
+ if (!session_key) {
+ g_rec_mutex_unlock (&connection->priv->connection_lock);
+ return FALSE;
+ }
+
+ connection->priv->session_key = g_strdup (session_key);
+ connection->priv->etebase_account = etebase_account_restore (connection->priv->etebase_client,
session_key, NULL, 0);
+ connection->priv->col_mgr = etebase_account_get_collection_manager
(connection->priv->etebase_account);
g_rec_mutex_unlock (&connection->priv->connection_lock);
return success;
}
-/* modify: connection, journal_uid, journal_type, display_name */
-static gboolean
-e_etesync_connection_journal_modify (EEteSyncConnection *connection,
- const gchar *journal_uid,
- const gchar *journal_type,
- const gchar *display_name,
- const gchar *description,
- const gint32 color,
- EteSyncJournal **out_journal)
+gboolean
+e_etesync_connection_login_connection_sync (EEteSyncConnection *connection,
+ const gchar *username,
+ const gchar *password,
+ const gchar *server_url,
+ EtebaseErrorCode *out_etebase_error)
{
- EteSyncJournal *journal;
- EteSyncCryptoManager *crypto_manager = NULL;
- EteSyncCollectionInfo *info = NULL;
- gint32 local_error;
+ EtebaseErrorCode local_etebase_error = ETEBASE_ERROR_CODE_NO_ERROR;
+ EtebaseClient *etebase_client;
gboolean success = TRUE;
g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (journal_uid != NULL, FALSE);
- g_return_val_if_fail (journal_type != NULL, FALSE);
- g_return_val_if_fail (display_name && *display_name, FALSE);
+ g_return_val_if_fail (username, FALSE);
+ g_return_val_if_fail (password, FALSE);
+ g_return_val_if_fail (server_url && *server_url, FALSE);
g_rec_mutex_lock (&connection->priv->connection_lock);
- journal = etesync_journal_manager_fetch(connection->priv->journal_manager, journal_uid);
- info = etesync_collection_info_new (journal_type, display_name, description, color);
- crypto_manager = etesync_journal_get_crypto_manager (journal, connection->priv->derived,
connection->priv->keypair);
+ e_etesync_connection_clear (connection);
- etesync_journal_set_info (journal, crypto_manager, info);
- local_error = etesync_journal_manager_update (connection->priv->journal_manager, journal);
+ etebase_client = etebase_client_new (PACKAGE "/" VERSION, server_url);
- /* zero means success, other means fail */
- if (local_error)
- success = FALSE;
+ if (etebase_client) {
+ connection->priv->etebase_client = etebase_client;
+ connection->priv->etebase_account = etebase_account_login (etebase_client, username,
password);
- etesync_crypto_manager_destroy (crypto_manager);
- etesync_collection_info_destroy (info);
+ if (connection->priv->etebase_account) {
+ connection->priv->col_mgr = etebase_account_get_collection_manager
(connection->priv->etebase_account);
+ connection->priv->session_key = etebase_account_save
(connection->priv->etebase_account, NULL, 0);
+ } else {
+ local_etebase_error = etebase_error_get_code ();
+ success = FALSE;
+ }
+ } else {
+ /* Bad server name */
+ local_etebase_error = etebase_error_get_code ();
+ success = FALSE;
+ }
- if (out_journal && success)
- *out_journal = journal;
- else
- etesync_journal_destroy (journal);
+ if (out_etebase_error)
+ *out_etebase_error = local_etebase_error;
g_rec_mutex_unlock (&connection->priv->connection_lock);
return success;
}
-/* delete: connection, action, journal_uid */
-static gboolean
-e_etesync_connection_journal_delete (EEteSyncConnection *connection,
- const gchar *journal_uid)
+gboolean
+e_etesync_connection_is_connected (EEteSyncConnection *connection)
{
- EteSyncJournal *journal;
- EteSyncCryptoManager *crypto_manager = NULL;
- gint32 local_error;
- gboolean success = TRUE;
+ gboolean success;
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (journal_uid != NULL, FALSE);
+ if (!connection)
+ return FALSE;
g_rec_mutex_lock (&connection->priv->connection_lock);
- journal = etesync_journal_manager_fetch (connection->priv->journal_manager, journal_uid);
- crypto_manager = etesync_journal_get_crypto_manager (journal, connection->priv->derived,
connection->priv->keypair);
-
- local_error = etesync_journal_manager_delete (connection->priv->journal_manager, journal);
-
- /* zero means success, other means fail */
- if (local_error)
- success = FALSE;
-
- etesync_crypto_manager_destroy (crypto_manager);
- etesync_journal_destroy (journal);
+ success = (connection->priv->etebase_client
+ && connection->priv->etebase_account
+ && connection->priv->col_mgr) ? TRUE : FALSE;
g_rec_mutex_unlock (&connection->priv->connection_lock);
return success;
}
-/*
- * create: connection, action, journal_type, display_name, color, out_journal
- * modify: connection, action, journal_uid, journal_type, display_name, color
- * delete: connection, action, journal_uid
- * out_journal returns journal for created and modified,
- * out_journal should be freed with etesync_journal_destroy (),
- * when not needed anymore, it can be NULL if not needed
- */
-gboolean
-e_etesync_connection_write_journal_action (EEteSyncConnection *connection,
- const gchar *action,
- const gchar *journal_uid,
- const gchar *journal_type,
- const gchar *display_name,
- const gchar *description,
- const gint32 color,
- EteSyncJournal **out_journal)
-{
- gboolean success = FALSE;
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (action != NULL, FALSE);
+/* Fetches a new token and stores it in the keyring,
+ returns a new ENamedParameters with the new session key */
+static gboolean
+e_etesync_connection_refresh_token_sync (EEteSyncConnection *connection,
+ ESource *collection,
+ ENamedParameters *credentials,
+ EtebaseErrorCode *etebase_error,
+ GError **error)
+{
+ EtebaseAccount *etebase_account;
+ gboolean success;
- g_rec_mutex_lock (&connection->priv->connection_lock);
+ etebase_account = e_etesync_connection_get_etebase_account (connection);
+ success = !etebase_account_fetch_token (etebase_account);
+
+ if (success) {
+ gchar *new_session_key, *label;
+ const gchar *collection_uid;
+ ESourceAuthentication *auth_extension;
+ gboolean permanently;
+
+ new_session_key = etebase_account_save (etebase_account, NULL, 0);
+ label = e_source_dup_secret_label (collection);
+ auth_extension = e_source_get_extension (collection, E_SOURCE_EXTENSION_AUTHENTICATION);
+ permanently = e_source_authentication_get_remember_password (auth_extension);
+ collection_uid = e_source_get_uid (collection);
+
+ e_named_parameters_clear (credentials);
+ e_named_parameters_set (credentials,
+ E_ETESYNC_CREDENTIAL_SESSION_KEY, new_session_key);
+
+ e_etesync_service_store_credentials_sync (collection_uid,
+ label,
+ credentials,
+ permanently,
+ NULL, NULL);
+
+ g_free (new_session_key);
+ g_free (label);
+ } else {
+ EtebaseErrorCode local_etebase_error = etebase_error_get_code ();
- if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_ADD)) {
- success = e_etesync_connection_journal_create (connection, journal_type, display_name,
description, color, out_journal);
- } else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_CHANGE)) {
- success = e_etesync_connection_journal_modify (connection, journal_uid, journal_type,
display_name, description, color, out_journal);
- } else if (g_str_equal (action, ETESYNC_SYNC_ENTRY_ACTION_DELETE)) {
- success = e_etesync_connection_journal_delete (connection, journal_uid);
+ if (error)
+ e_etesync_utils_set_io_gerror (local_etebase_error, etebase_error_get_message (),
error);
+ if (etebase_error)
+ *etebase_error = local_etebase_error;
}
- g_rec_mutex_unlock (&connection->priv->connection_lock);
-
- /* action not known */
return success;
}
-/* This function sets the keypair in connection
- it also sets the result and error, both can be NULL */
-static gboolean
-e_etesync_connection_set_keypair (EEteSyncConnection *connection,
- ESourceAuthenticationResult *out_result,
- EteSyncErrorCode *out_etesync_error)
+/* Checks if token is valid if not it refreshes the token,
+ and it sets the connection object with the latest stored-session key */
+gboolean
+e_etesync_connection_reconnect_sync (EEteSyncConnection *connection,
+ ESourceAuthenticationResult *out_result,
+ GCancellable *cancellable,
+ GError **error)
{
- EteSyncUserInfoManager *user_info_manager;
- EteSyncUserInfo *user_info;
- EteSyncErrorCode local_etesync_error = ETESYNC_ERROR_CODE_NO_ERROR;
+ ENamedParameters *credentials = NULL;
+ const gchar *collection_uid;
ESourceAuthenticationResult local_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
- gboolean success = TRUE;
+ ESource *collection;
+ gboolean success = FALSE;
g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (connection->priv->etesync != NULL, FALSE);
- g_return_val_if_fail (connection->priv->username != NULL, FALSE);
- g_return_val_if_fail (connection->priv->derived != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
g_rec_mutex_lock (&connection->priv->connection_lock);
- user_info_manager = etesync_user_info_manager_new (connection->priv->etesync);
- user_info = etesync_user_info_manager_fetch (user_info_manager, connection->priv->username);
+ collection = connection->priv->collection_source;
+ collection_uid = e_source_get_uid (collection);
+ e_etesync_service_lookup_credentials_sync (collection_uid, &credentials, NULL, NULL);
- if (user_info) {
- EteSyncCryptoManager *user_info_crypto_manager;
+ if (e_etesync_connection_is_connected (connection)) {
+ const gchar *session_key = e_named_parameters_get (credentials,
E_ETESYNC_CREDENTIAL_SESSION_KEY);
- user_info_crypto_manager = etesync_user_info_get_crypto_manager (user_info,
connection->priv->derived);
- connection->priv->keypair = etesync_user_info_get_keypair (user_info,
user_info_crypto_manager);
+ if (session_key) {
+ if (g_strcmp0 (session_key, connection->priv->session_key) == 0) {
+ if (e_etesync_connection_check_session_key_validation_sync (connection, NULL,
error) == E_SOURCE_AUTHENTICATION_REJECTED) {
+ EtebaseErrorCode etebase_error;
- if (!connection->priv->keypair) {
- local_etesync_error = etesync_get_error_code ();
+ g_clear_error (error);
- if (local_etesync_error == ETESYNC_ERROR_CODE_ENCRYPTION_MAC)
- local_result = E_SOURCE_AUTHENTICATION_REJECTED;
- else
- local_result = E_SOURCE_AUTHENTICATION_ERROR;
- success = FALSE;
+ if (e_etesync_connection_refresh_token_sync (connection, collection,
credentials, &etebase_error, error)) {
+ local_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ } else {
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED)
+ local_result = E_SOURCE_AUTHENTICATION_REJECTED;
+ else
+ local_result = E_SOURCE_AUTHENTICATION_ERROR;
+ }
+ }
+ }
+ } else {
+ local_result = E_SOURCE_AUTHENTICATION_ERROR;
}
-
- etesync_user_info_destroy (user_info);
- etesync_crypto_manager_destroy (user_info_crypto_manager);
} else {
- local_etesync_error = etesync_get_error_code ();
- success = FALSE;
+ if (!credentials || !e_named_parameters_exists (credentials,
E_ETESYNC_CREDENTIAL_SESSION_KEY))
+ local_result = E_SOURCE_AUTHENTICATION_REJECTED;
}
- etesync_user_info_manager_destroy (user_info_manager);
+ /* Set connection from collection source */
+ if (local_result == E_SOURCE_AUTHENTICATION_ACCEPTED)
+ success = e_etesync_connection_set_connection_from_sources (connection, credentials);
- if (out_etesync_error)
- *out_etesync_error = local_etesync_error;
if (out_result)
*out_result = local_result;
+ e_named_parameters_free (credentials);
+
g_rec_mutex_unlock (&connection->priv->connection_lock);
return success;
}
-static gboolean
-e_etesync_connection_is_new_account (EEteSyncConnection *connection,
- gboolean *out_is_new_account,
- EteSyncErrorCode *out_etesync_error)
+/* Calls connection,reconnect, and requests the credentials dialog if needed */
+gboolean
+e_etesync_connection_maybe_reconnect_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ GCancellable *cancellable,
+ GError **error)
{
+ ESourceAuthenticationResult result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ gboolean success = FALSE;
+
+ success = e_etesync_connection_reconnect_sync (connection, &result, cancellable, error);
+
+ if (result == E_SOURCE_AUTHENTICATION_REJECTED) {
+ e_backend_schedule_credentials_required (backend,
+ E_SOURCE_CREDENTIALS_REASON_REJECTED, NULL, 0, NULL, NULL, G_STRFUNC);
+ }
+
+ return success;
+}
+
+/* ----- Collection create/modify/delete then push to server functions ------ */
- EteSyncUserInfoManager *user_info_manager;
- EteSyncUserInfo *user_info;
- EteSyncErrorCode local_etesync_error = ETESYNC_ERROR_CODE_NO_ERROR;
+gboolean
+e_etesync_connection_collection_create_upload_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const gchar *col_type,
+ const gchar *display_name,
+ const gchar *description,
+ const gchar *color,
+ EtebaseCollection **out_col_obj,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EtebaseCollection *col_obj;
+ EtebaseItemMetadata *item_metadata;
gboolean success = TRUE;
+ time_t now;
g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (connection->priv->etesync != NULL, FALSE);
- g_return_val_if_fail (connection->priv->username != NULL, FALSE);
- g_return_val_if_fail (out_is_new_account != NULL, FALSE);
+ g_return_val_if_fail (display_name != NULL, FALSE);
+ g_return_val_if_fail (col_type != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
g_rec_mutex_lock (&connection->priv->connection_lock);
- user_info_manager = etesync_user_info_manager_new (connection->priv->etesync);
- user_info = etesync_user_info_manager_fetch (user_info_manager, connection->priv->username);
+ item_metadata = etebase_item_metadata_new ();
+ etebase_item_metadata_set_name (item_metadata, display_name);
+ etebase_item_metadata_set_description (item_metadata, description);
+ etebase_item_metadata_set_color (item_metadata, color);
+ e_etesync_utils_get_time_now (&now);
+ etebase_item_metadata_set_mtime (item_metadata, &now);
- if (!user_info) {
- local_etesync_error = etesync_get_error_code ();
+ col_obj = etebase_collection_manager_create (connection->priv->col_mgr, col_type, item_metadata, "",
0);
+ success = !etebase_collection_manager_upload (connection->priv->col_mgr, col_obj, NULL);
- if (local_etesync_error == ETESYNC_ERROR_CODE_NOT_FOUND)
- *out_is_new_account = TRUE;
- else
- success = FALSE;
- } else {
- *out_is_new_account = FALSE;
- etesync_user_info_destroy (user_info);
+ if (!success
+ && etebase_error_get_code () == ETEBASE_ERROR_CODE_UNAUTHORIZED
+ && e_etesync_connection_maybe_reconnect_sync (connection, backend, cancellable, error)) {
+
+ success = !etebase_collection_manager_upload (connection->priv->col_mgr, col_obj, NULL);
}
- if (out_etesync_error)
- *out_etesync_error = local_etesync_error;
+ if (!success)
+ e_etesync_utils_set_io_gerror (etebase_error_get_code (), etebase_error_get_message (),
error);
- etesync_user_info_manager_destroy (user_info_manager);
+ etebase_item_metadata_destroy (item_metadata);
+
+ if (out_col_obj && success)
+ *out_col_obj = col_obj;
+ else
+ etebase_collection_destroy (col_obj);
g_rec_mutex_unlock (&connection->priv->connection_lock);
@@ -416,362 +477,468 @@ e_etesync_connection_is_new_account (EEteSyncConnection *connection,
}
gboolean
-e_etesync_connection_init_userinfo (EEteSyncConnection *connection)
+e_etesync_connection_collection_modify_upload_sync (EEteSyncConnection *connection,
+ EtebaseCollection *col_obj,
+ const gchar *display_name,
+ const gchar *description,
+ const gchar *color,
+ GError **error)
{
- EteSyncUserInfoManager *user_info_manager;
- EteSyncUserInfo *user_info;
- EteSyncErrorCode etesync_error;
+ EtebaseItemMetadata *item_metadata;
gboolean success = TRUE;
+ time_t now;
+ GError *local_error = NULL;
g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (connection->priv->etesync != NULL, FALSE);
- g_return_val_if_fail (connection->priv->username != NULL, FALSE);
- g_return_val_if_fail (connection->priv->derived != NULL, FALSE);
+ g_return_val_if_fail (col_obj != NULL, FALSE);
+ g_return_val_if_fail (display_name && *display_name, FALSE);
- user_info_manager = etesync_user_info_manager_new (connection->priv->etesync);
- user_info = etesync_user_info_manager_fetch (user_info_manager, connection->priv->username);
+ g_rec_mutex_lock (&connection->priv->connection_lock);
- etesync_error = etesync_get_error_code ();
+ item_metadata = etebase_collection_get_meta (col_obj);
+ etebase_item_metadata_set_name (item_metadata, display_name);
+ etebase_item_metadata_set_description (item_metadata, description);
+ etebase_item_metadata_set_color (item_metadata, color);
+ e_etesync_utils_get_time_now (&now);
+ etebase_item_metadata_set_mtime (item_metadata, &now);
- if (!user_info && etesync_error == ETESYNC_ERROR_CODE_NOT_FOUND) { /* Should create a user info and
upload it */
- gint32 numeric_error;
- EteSyncCryptoManager *user_info_crypto_manager;
+ etebase_collection_set_meta (col_obj, item_metadata);
+ success = !etebase_collection_manager_upload (connection->priv->col_mgr, col_obj, NULL);
- user_info = etesync_user_info_new (connection->priv->username, ETESYNC_CURRENT_VERSION);
- user_info_crypto_manager = etesync_user_info_get_crypto_manager (user_info,
connection->priv->derived);
- connection->priv->keypair = etesync_crypto_generate_keypair (connection->priv->etesync);
+ if (!success
+ && etebase_error_get_code () == ETEBASE_ERROR_CODE_UNAUTHORIZED
+ && e_etesync_connection_reconnect_sync (connection, NULL, NULL, &local_error)) {
- etesync_user_info_set_keypair (user_info, user_info_crypto_manager,
connection->priv->keypair);
- numeric_error = etesync_user_info_manager_create (user_info_manager, user_info);
+ success = !etebase_collection_manager_upload (connection->priv->col_mgr, col_obj, NULL);
+ }
- /* zero means success */
- if (numeric_error){
- etesync_error = etesync_get_error_code ();
- success = FALSE;
- } else {
- /* create defult journal for new accounts */
- e_etesync_connection_write_journal_action (connection, ETESYNC_SYNC_ENTRY_ACTION_ADD,
NULL,
- ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK, _("My Contacts"), NULL,
ETESYNC_COLLECTION_DEFAULT_COLOR, NULL);
- e_etesync_connection_write_journal_action (connection, ETESYNC_SYNC_ENTRY_ACTION_ADD,
NULL,
- ETESYNC_COLLECTION_TYPE_CALENDAR, _("My Calendar"), NULL,
ETESYNC_COLLECTION_DEFAULT_COLOR, NULL);
- e_etesync_connection_write_journal_action (connection, ETESYNC_SYNC_ENTRY_ACTION_ADD,
NULL,
- ETESYNC_COLLECTION_TYPE_TASKS, _("My Tasks"), NULL,
ETESYNC_COLLECTION_DEFAULT_COLOR, NULL);
- }
+ if (!success)
+ e_etesync_utils_set_io_gerror (etebase_error_get_code (), etebase_error_get_message (),
&local_error);
- etesync_user_info_destroy (user_info);
- etesync_crypto_manager_destroy (user_info_crypto_manager);
- } else {
- success = FALSE;
- }
- etesync_user_info_manager_destroy (user_info_manager);
+ if (local_error)
+ g_propagate_error (error, local_error);
+
+ etebase_item_metadata_destroy (item_metadata);
+
+ g_rec_mutex_unlock (&connection->priv->connection_lock);
return success;
}
-ESourceAuthenticationResult
-e_etesync_connection_set_connection_from_sources (EEteSyncConnection *connection,
- const ENamedParameters *credentials,
- ESourceAuthentication *authentication_extension,
- ESourceCollection *collection_extension)
+gboolean
+e_etesync_connection_collection_delete_upload_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ EtebaseCollection *col_obj,
+ GCancellable *cancellable,
+ GError **error)
{
- ESourceAuthenticationResult result;
- const gchar *server_url , *username, *token, *derived;
+ EtebaseItemMetadata *item_metadata;
+ gboolean success = TRUE;
+ time_t now;
- g_rec_mutex_lock (&connection->priv->connection_lock);
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (col_obj != NULL, FALSE);
- username = e_source_authentication_get_user (authentication_extension);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- e_etesync_connection_clear (connection);
+ g_rec_mutex_lock (&connection->priv->connection_lock);
- /* 1) get_server from ESourceAuthentication as it was saved when the user was entering credentials in
the dialog first time.
- Set the etesync then for this backend so as long as the backend is alive, we don't have to do
this process again */
- server_url = e_source_collection_get_calendar_url (collection_extension);
- connection->priv->etesync = etesync_new (PACKAGE "/" VERSION, server_url);
+ item_metadata = etebase_collection_get_meta (col_obj);
+ e_etesync_utils_get_time_now (&now);
+ etebase_item_metadata_set_mtime (item_metadata, &now);
- /* problem with the server_url */
- if (!connection->priv->etesync) {
- g_rec_mutex_unlock (&connection->priv->connection_lock);
- return E_SOURCE_AUTHENTICATION_ERROR;
- }
+ etebase_collection_set_meta (col_obj, item_metadata);
+ etebase_collection_delete (col_obj);
+ success = !etebase_collection_manager_upload (connection->priv->col_mgr, col_obj, NULL);
- /* 2) get token and derived key from Credentials (Should be stored there) */
- token = e_named_parameters_get (credentials, E_ETESYNC_CREDENTIAL_TOKEN);
- derived = e_named_parameters_get (credentials, E_ETESYNC_CREDENTIAL_DERIVED_KEY);
+ if (!success
+ && etebase_error_get_code () == ETEBASE_ERROR_CODE_UNAUTHORIZED
+ && e_etesync_connection_maybe_reconnect_sync (connection, backend, cancellable, error)) {
- /* 3) check if the token or the derived key are NULL, if so that means this is the first time, so we
will need
- the credintials to start getting the token and derived key, then validate that token */
- if (!token || !derived) {
- g_rec_mutex_unlock (&connection->priv->connection_lock);
- return E_SOURCE_AUTHENTICATION_REJECTED;
+ success = !etebase_collection_manager_upload (connection->priv->col_mgr, col_obj, NULL);
}
- connection->priv->username = g_strdup (username);
- connection->priv->server_url = g_strdup (server_url);
- connection->priv->token = g_strdup (token);
- connection->priv->derived = g_strdup (derived);
-
- etesync_set_auth_token(connection->priv->etesync, token);
-
- connection->priv->journal_manager = etesync_journal_manager_new (connection->priv->etesync);
+ if (!success)
+ e_etesync_utils_set_io_gerror (etebase_error_get_code (), etebase_error_get_message (),
error);
- result = e_etesync_connection_check_token_validation (connection);
-
- /* setting the keypair */
- if (result == E_SOURCE_AUTHENTICATION_ACCEPTED)
- e_etesync_connection_set_keypair (connection, &result, NULL);
- else
- e_etesync_connection_clear (connection);
+ etebase_item_metadata_destroy (item_metadata);
g_rec_mutex_unlock (&connection->priv->connection_lock);
- return result;
+ return success;
}
-gboolean
-e_etesync_connection_set_connection (EEteSyncConnection *connection,
- const gchar *username,
- const gchar *password,
- const gchar *encryption_password,
- const gchar *server_url,
- EteSyncErrorCode *out_etesync_error)
+/* ------------------- Book and calendar common function ------------------- */
+
+static gboolean
+e_etesync_connection_chunk_itemlist_fetch_sync (EtebaseItemManager *item_mgr,
+ const gchar *stoken,
+ gintptr fetch_limit,
+ EtebaseItemListResponse **out_item_list,
+ guintptr *out_item_data_len,
+ gchar **out_stoken,
+ gboolean *out_done)
{
- EteSyncErrorCode local_etesync_error;
- EteSync *etesync;
- gboolean success;
+ EtebaseFetchOptions *fetch_options = etebase_fetch_options_new ();
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (username, FALSE);
- g_return_val_if_fail (password, FALSE);
- g_return_val_if_fail (server_url && *server_url, FALSE);
+ etebase_fetch_options_set_stoken (fetch_options, stoken);
+ etebase_fetch_options_set_limit (fetch_options, fetch_limit);
- g_rec_mutex_lock (&connection->priv->connection_lock);
+ *out_item_list = etebase_item_manager_list (item_mgr, fetch_options);
- e_etesync_connection_clear (connection);
+ if (!*out_item_list) {
+ etebase_fetch_options_destroy (fetch_options);
+ return FALSE;
+ }
- etesync = etesync_new (PACKAGE "/" VERSION, server_url);
+ g_free (*out_stoken);
+ *out_stoken = g_strdup (etebase_item_list_response_get_stoken (*out_item_list));
+ *out_done = etebase_item_list_response_is_done (*out_item_list);
+ *out_item_data_len = etebase_item_list_response_get_data_length (*out_item_list);
- if (etesync) {
- connection->priv->etesync = etesync;
- connection->priv->username = g_strdup (username);
- connection->priv->server_url = g_strdup (server_url);
+ etebase_fetch_options_destroy (fetch_options);
- if (encryption_password && *encryption_password)
- connection->priv->derived = etesync_crypto_derive_key (etesync, username,
encryption_password);
+ return TRUE;
+}
- connection->priv->token = etesync_auth_get_token (etesync, username, password);
+gboolean
+e_etesync_connection_list_existing_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EteSyncType type,
+ const EtebaseCollection *col_obj,
+ gchar **out_new_sync_tag,
+ GSList **out_existing_objects,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EtebaseItemManager *item_mgr;
+ gchar *stoken = NULL;
+ gboolean done = FALSE;
+ gboolean success = TRUE;
- if (connection->priv->token) {
- gboolean is_new_account;
+ *out_existing_objects = NULL;
+ *out_new_sync_tag = NULL;
- etesync_set_auth_token (etesync, connection->priv->token);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- connection->priv->journal_manager = etesync_journal_manager_new (etesync);
- success = e_etesync_connection_is_new_account (connection, &is_new_account,
&local_etesync_error);
+ if (!col_obj) {
+ return FALSE;
+ }
+
+ item_mgr = etebase_collection_manager_get_item_manager (connection->priv->col_mgr, col_obj);
+
+ while (!done) {
+ EtebaseItem **items_data;
+ EtebaseItemListResponse *item_list;
+ guintptr items_data_len, item_iter;
+
+ if (e_etesync_connection_chunk_itemlist_fetch_sync (item_mgr, stoken,
E_ETESYNC_ITEM_FETCH_LIMIT, &item_list, &items_data_len, &stoken, &done)) {
+
+ items_data = g_alloca (sizeof (EtebaseItem *) * E_ETESYNC_ITEM_FETCH_LIMIT);
+ etebase_item_list_response_get_data (item_list, (const EtebaseItem **) items_data);
+
+ /* At this point, items_data are not empty, then we should loop on items and add each
+ one to the hashtable as meta backend info for each contact */
+ if (items_data && *items_data) {
+ for (item_iter = 0; item_iter < items_data_len; item_iter++) {
+ const EtebaseItem *item = items_data[item_iter];
+
+ /* check action add, change or delete */
+ if (!etebase_item_is_deleted (item)) {
+ gchar *content = NULL, *data_uid = NULL, *revision = NULL,
*item_cache_b64, buf[500];
+ gintptr content_len;
+
+ content_len = etebase_item_get_content (item, buf, sizeof
(buf));
+
+ if (content_len < 0) {
+ break;
+ } else if (content_len >= sizeof (buf)) {
+ content = g_slice_alloc0 (content_len+1);
+ etebase_item_get_content (item, content, content_len);
+ content[content_len] = 0;
+ } else {
+ buf[content_len] = 0;
+ content = g_strdup (buf);
+ }
+
+ item_cache_b64 = e_etesync_utils_etebase_item_to_base64
(item, item_mgr);
+
+ if (type == E_ETESYNC_ADDRESSBOOK) {
+ EBookMetaBackendInfo *nfo;
+
+ /* create EBookMetaBackendInfo * to be stored in
GSList, data_uid is contact uid */
+ e_etesync_utils_get_contact_uid_revision (content,
&data_uid, &revision);
+ nfo = e_book_meta_backend_info_new (data_uid,
revision, content, item_cache_b64);
+ *out_existing_objects = g_slist_append
(*out_existing_objects, nfo);
+ } else if (type == E_ETESYNC_CALENDAR) {
+ ECalMetaBackendInfo *nfo;
+
+ /* create ECalMetaBackendInfo * to be stored in
GSList, data_uid is component uid */
+ e_etesync_utils_get_component_uid_revision (content,
&data_uid, &revision);
+ nfo = e_cal_meta_backend_info_new (data_uid,
revision, content, item_cache_b64);
+ *out_existing_objects = g_slist_prepend
(*out_existing_objects, nfo);
+ }
+
+ g_free (data_uid);
+ g_free (revision);
+ g_slice_free1 (content_len+1, content);
+ g_free (item_cache_b64);
+ }
+ }
+ }
+ etebase_item_list_response_destroy (item_list);
- if (success && !is_new_account)
- success = connection->priv->derived? e_etesync_connection_set_keypair
(connection, NULL, &local_etesync_error) : FALSE;
- else
- /* This is a new account */
- success = FALSE;
} else {
- local_etesync_error = etesync_get_error_code ();
+ EtebaseErrorCode etebase_error;
+
+ etebase_error = etebase_error_get_code ();
success = FALSE;
+
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED)
+ success = e_etesync_connection_maybe_reconnect_sync (connection, backend,
cancellable, error);
+
+ if (!success) {
+ e_etesync_utils_set_io_gerror (etebase_error, etebase_error_get_message (),
error);
+ break;
+ } else /* as collection manager may have changed */
+ item_mgr = etebase_collection_manager_get_item_manager
(connection->priv->col_mgr, col_obj);
}
- } else {
- /* Bad server name */
- local_etesync_error = etesync_get_error_code ();
- success = FALSE;
}
- if (out_etesync_error)
- *out_etesync_error = local_etesync_error;
-
- g_rec_mutex_unlock (&connection->priv->connection_lock);
+ etebase_item_manager_destroy (item_mgr);
+ *out_new_sync_tag = stoken;
return success;
}
-/* This function checks if the connection is set or not
- and if it needs setting or not */
gboolean
-e_etesync_connection_needs_setting (EEteSyncConnection *connection,
- const ENamedParameters *credentials,
- ESourceAuthenticationResult *out_result)
+e_etesync_connection_get_changes_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EteSyncType type,
+ const gchar *last_sync_tag,
+ const EtebaseCollection *col_obj,
+ ECache *cache,
+ gchar **out_new_sync_tag,
+ GSList **out_created_objects, /* EBookMetaBackendInfo* or
ECalMetaBackendInfo* */
+ GSList **out_modified_objects, /* EBookMetaBackendInfo* or
ECalMetaBackendInfo* */
+ GSList **out_removed_objects, /* EBookMetaBackendInfo* or
ECalMetaBackendInfo* */
+ GCancellable *cancellable,
+ GError **error)
{
- gboolean needs_setting = FALSE;
- ESourceAuthenticationResult local_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ EtebaseItemManager *item_mgr;
+ gchar *stoken;
+ gboolean done = FALSE;
+ gboolean success = TRUE;
- g_return_val_if_fail (credentials != NULL, E_SOURCE_AUTHENTICATION_ERROR);
+ stoken = g_strdup (last_sync_tag);
- g_rec_mutex_lock (&connection->priv->connection_lock);
-
- if (connection && connection->priv->etesync) {
- const gchar *cred_token = e_named_parameters_get (credentials, E_ETESYNC_CREDENTIAL_TOKEN);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- if (cred_token) {
- if (!g_strcmp0 (cred_token, connection->priv->token)) {
- local_result = e_etesync_connection_check_token_validation (connection);
+ if (!col_obj) {
+ return FALSE;
+ }
- /* This is kinda of a hack, if the token is invalid we need to first pull
update
- credentials using REQUIRED, as there might me another connection object
that
- update it, so before getting another token we check if one had been got */
- if (!connection->priv->requested_credentials && local_result ==
E_SOURCE_AUTHENTICATION_REJECTED) {
- connection->priv->requested_credentials = TRUE;
- local_result = E_SOURCE_AUTHENTICATION_REQUIRED;
+ item_mgr = etebase_collection_manager_get_item_manager (connection->priv->col_mgr, col_obj);
+
+ while (!done) {
+ EtebaseItem **items_data;
+ EtebaseItemListResponse *item_list;
+ guintptr items_data_len, item_iter;
+
+ if (e_etesync_connection_chunk_itemlist_fetch_sync (item_mgr, stoken,
E_ETESYNC_ITEM_FETCH_LIMIT, &item_list, &items_data_len, &stoken, &done)) {
+
+ items_data = g_alloca (sizeof (EtebaseItem *) * E_ETESYNC_ITEM_FETCH_LIMIT);
+ etebase_item_list_response_get_data (item_list, (const EtebaseItem **) items_data);
+
+ /* At this point, items_data are not empty, then we should loop on items and add each
+ one to the hashtable as meta backend info for each contact */
+ if (items_data && *items_data) {
+ for (item_iter = 0; item_iter < items_data_len; item_iter++) {
+ const EtebaseItem *item = items_data[item_iter];
+ gchar *content = NULL, *data_uid = NULL, *revision = NULL,
*item_cache_b64, buf[500];
+ gintptr content_len;
+ gboolean is_exist = FALSE;
+
+ content_len = etebase_item_get_content (item, buf, sizeof (buf));
+
+ if (content_len < 0) {
+ break;
+ } else if (content_len >= sizeof (buf)) {
+ content = g_slice_alloc0 (content_len+1);
+ etebase_item_get_content (item, content, content_len);
+ content[content_len] = 0;
+ } else {
+ buf[content_len] = 0;
+ content = g_strdup (buf);
+ }
+
+ item_cache_b64 = e_etesync_utils_etebase_item_to_base64 (item,
item_mgr);
+
+ if (type == E_ETESYNC_ADDRESSBOOK) {
+ EBookMetaBackendInfo *nfo;
+
+ /* create EBookMetaBackendInfo * to be stored in GSList, data
uid is contact uid */
+ e_etesync_utils_get_contact_uid_revision (content, &data_uid,
&revision);
+
+ nfo = e_book_meta_backend_info_new (data_uid, revision,
content, item_cache_b64);
+ is_exist = e_cache_contains (cache, data_uid,
E_CACHE_EXCLUDE_DELETED);
+
+ /* data with uid exist, then it is modified or deleted, else
it is new data */
+ if (is_exist) {
+ if (etebase_item_is_deleted (item))
+ *out_removed_objects = g_slist_prepend
(*out_removed_objects, nfo);
+ else
+ *out_modified_objects = g_slist_prepend
(*out_modified_objects, nfo);
+ } else {
+ if (!etebase_item_is_deleted (item))
+ *out_created_objects = g_slist_prepend
(*out_created_objects, nfo);
+ else
+ e_book_meta_backend_info_free (nfo);
+ }
+ } else if (type == E_ETESYNC_CALENDAR) {
+ ECalMetaBackendInfo *nfo;
+
+ /* create ECalMetaBackendInfo * to be stored in GSList, data
uid is compounent uid */
+ e_etesync_utils_get_component_uid_revision (content,
&data_uid, &revision);
+
+ nfo = e_cal_meta_backend_info_new (data_uid, revision,
content, item_cache_b64);
+ is_exist = e_cache_contains (cache, data_uid,
E_CACHE_EXCLUDE_DELETED);
+
+ /* data with uid exist, then it is modified or deleted, else
it is new data */
+ if (is_exist) {
+ if (etebase_item_is_deleted (item))
+ *out_removed_objects = g_slist_prepend
(*out_removed_objects, nfo);
+ else
+ *out_modified_objects = g_slist_prepend
(*out_modified_objects, nfo);
+ } else {
+ if (!etebase_item_is_deleted (item))
+ *out_created_objects = g_slist_prepend
(*out_created_objects, nfo);
+ else
+ e_cal_meta_backend_info_free (nfo);
+ }
+ }
+
+ g_free (revision);
+ g_slice_free1 (content_len+1, content);
+ g_free (data_uid);
+ g_free (item_cache_b64);
}
- } else
- if (cred_token)
- needs_setting = TRUE;
- } else
- local_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- } else {
- if (credentials && e_named_parameters_count (credentials) >= 4) {
- needs_setting = TRUE;
- } else {
- if (connection->priv->requested_credentials) {
- local_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else {
- connection->priv->requested_credentials = TRUE;
- local_result = E_SOURCE_AUTHENTICATION_REQUIRED;
}
- }
- }
+ etebase_item_list_response_destroy (item_list);
- if (out_result)
- *out_result = local_result;
- if (local_result == E_SOURCE_AUTHENTICATION_ACCEPTED)
- connection->priv->requested_credentials = FALSE;
-
- g_rec_mutex_unlock (&connection->priv->connection_lock);
-
- return needs_setting;
-}
-
-/* ------------------- Book and calendar common function ------------------- */
-
-void
-e_etesync_connection_source_changed_cb (ESource *source,
- ESource *collection,
- gboolean is_contact)
-{
- g_return_if_fail (E_IS_SOURCE (source));
- g_return_if_fail (E_IS_SOURCE (collection));
-
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
- const gchar *extension_name = NULL;
- const gchar *journal_type = NULL;
- gboolean success = TRUE;
-
- /* To avoid duplication (run in one of the callbacks in calendar/book backend) */
- if (is_contact) {
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
- extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
- journal_type = ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK;
- }
} else {
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR)) {
- extension_name = E_SOURCE_EXTENSION_CALENDAR;
- journal_type = ETESYNC_COLLECTION_TYPE_CALENDAR;
- } else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST)) {
- extension_name = E_SOURCE_EXTENSION_TASK_LIST;
- journal_type = ETESYNC_COLLECTION_TYPE_TASKS;
- }
- }
+ EtebaseErrorCode etebase_error;
- if (journal_type == NULL) {
+ etebase_error = etebase_error_get_code ();
success = FALSE;
+
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED)
+ success = e_etesync_connection_maybe_reconnect_sync (connection, backend,
cancellable, error);
+
+ if (!success) {
+ e_etesync_utils_set_io_gerror (etebase_error, etebase_error_get_message (),
error);
+ break;
+ } else /* as collection manager may have changed */
+ item_mgr = etebase_collection_manager_get_item_manager
(connection->priv->col_mgr, col_obj);
}
+ }
- if (success) {
- gchar *display_name = NULL;
- gint32 color = ETESYNC_COLLECTION_DEFAULT_COLOR;
- const gchar *journal_id = NULL;
- EEteSyncConnection *connection;
+ etebase_item_manager_destroy (item_mgr);
+ *out_new_sync_tag = stoken;
- connection = e_etesync_connection_new_connection (collection);
+ return success;
+}
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
- ESourceEteSync *etesync_extension;
+/* ------------------------ Uploading item functions -----------------------*/
- etesync_extension = e_source_get_extension (source,
E_SOURCE_EXTENSION_ETESYNC);
- journal_id = e_source_etesync_get_journal_id (etesync_extension);
- }
+gboolean
+e_etesync_connection_item_upload_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncAction action,
+ const gchar *content,
+ const gchar *uid,
+ const gchar *extra, /* item_cache_b64 */
+ gchar **out_new_extra,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EtebaseItemManager *item_mgr;
+ gboolean success = TRUE;
+ const gchar *item_cache_b64 = extra;
- if (!g_str_equal (extension_name, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
- ESourceBackend *source_backend;
- const gchar *source_color = NULL;
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (col_obj != NULL, FALSE);
- source_backend = e_source_get_extension (source, extension_name);
- source_color = e_source_selectable_get_color (E_SOURCE_SELECTABLE
(source_backend));
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- if (source_color) {
- color = g_ascii_strtoll (&source_color[1], NULL, 16);
- color |= 0xFF000000;
- }
- }
+ g_rec_mutex_lock (&connection->priv->connection_lock);
- display_name = e_source_dup_display_name (source);
+ item_mgr = etebase_collection_manager_get_item_manager (connection->priv->col_mgr, col_obj);
- success = e_etesync_connection_write_journal_action (connection,
- ETESYNC_SYNC_ENTRY_ACTION_CHANGE,
- journal_id,
- journal_type,
- display_name,
- NULL,
- color,
- NULL);
+ if (item_mgr) {
+ EtebaseItemMetadata *item_metadata = NULL;
+ EtebaseItem *item;
+ time_t now;
- g_free (display_name);
- g_object_unref (connection);
- }
- }
-}
+ e_etesync_utils_get_time_now (&now);
-EEteSyncConnection *
-e_etesync_connection_new_connection (ESource *collection)
-{
- const gchar *username = NULL, *server_url = NULL;
+ if (action == E_ETESYNC_ITEM_ACTION_CREATE) {
+ item_metadata = etebase_item_metadata_new ();
- g_return_val_if_fail (E_IS_SOURCE (collection), NULL);
+ etebase_item_metadata_set_name (item_metadata, uid);
+ etebase_item_metadata_set_mtime (item_metadata, &now);
- if (e_source_has_extension (collection, E_SOURCE_EXTENSION_COLLECTION)) {
- ESourceCollection *collection_extension;
+ item = etebase_item_manager_create (item_mgr, item_metadata, content, strlen
(content));
+ } else {
+ item = e_etesync_utils_etebase_item_from_base64 (item_cache_b64, item_mgr);
+ if (!item) {
+ success = FALSE;
+ g_clear_error (error);
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Item not
found"));
+ } else {
+ item_metadata = etebase_item_get_meta (item);
- collection_extension = e_source_get_extension (collection, E_SOURCE_EXTENSION_COLLECTION);
- server_url = e_source_collection_get_calendar_url (collection_extension);
- }
+ etebase_item_metadata_set_mtime (item_metadata, &now);
+ etebase_item_set_meta(item, item_metadata);
- if (e_source_has_extension (collection, E_SOURCE_EXTENSION_AUTHENTICATION)) {
- ESourceAuthentication *authentication_extension;
+ if (action == E_ETESYNC_ITEM_ACTION_MODIFY)
+ etebase_item_set_content (item, content, strlen (content));
+ else if (action == E_ETESYNC_ITEM_ACTION_DELETE)
+ etebase_item_delete (item);
+ }
+ }
- authentication_extension = e_source_get_extension (collection,
E_SOURCE_EXTENSION_AUTHENTICATION);
- username = e_source_authentication_get_user (authentication_extension);
- }
+ /* This could fail when trying to fetch an item and it wasn't found in modify/delete */
+ if (success) {
+ success = !etebase_item_manager_batch (item_mgr, (const EtebaseItem **) &item, 1,
NULL);
- return e_etesync_connection_new_from_user_url (username, server_url);
-}
+ if (!success) {
+ EtebaseErrorCode etebase_error = etebase_error_get_code ();
+ /* This is used to check if the error was due to expired token, if so try to
get a new token, then try again */
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED
+ && e_etesync_connection_maybe_reconnect_sync (connection, backend,
cancellable, error)) {
-gboolean
-e_etesync_connection_get_journal_exists (EEteSyncConnection *connection,
- const gchar *journal_id,
- gboolean *out_is_read_only)
-{
- EteSyncJournal *journal;
- gboolean success = TRUE;
+ success = !etebase_item_manager_batch (item_mgr, (const EtebaseItem
**) &item, 1, NULL);
+ }
- g_return_val_if_fail (connection->priv->journal_manager != NULL, FALSE);
- g_return_val_if_fail (journal_id && *journal_id, FALSE);
+ if (!success)
+ e_etesync_utils_set_io_gerror (etebase_error,
etebase_error_get_message (), error);
+ }
- g_rec_mutex_lock (&connection->priv->connection_lock);
+ if (out_new_extra)
+ *out_new_extra = success ? e_etesync_utils_etebase_item_to_base64 (item,
item_mgr) : NULL;
- journal = etesync_journal_manager_fetch (connection->priv->journal_manager, journal_id);
+ if (item_metadata)
+ etebase_item_metadata_destroy (item_metadata);
+ etebase_item_destroy (item);
+ }
- if (journal) {
- *out_is_read_only = etesync_journal_is_read_only (journal);
- etesync_journal_destroy (journal);
- } else {
- /* Journal ID is wrong or does not exist */
- success = FALSE;
+ etebase_item_manager_destroy (item_mgr);
}
g_rec_mutex_unlock (&connection->priv->connection_lock);
@@ -779,115 +946,114 @@ e_etesync_connection_get_journal_exists (EEteSyncConnection *connection,
return success;
}
-/*
- * returns True if it succeeded in reaching the server
- * False if there was a network error or the journal ID doesn't exist anymore
- * If *entries is null (first pointer in the array) then no changes else there are changes since last sync
- */
-gboolean
-e_etesync_connection_check_journal_changed_sync (EEteSyncConnection *connection,
- const gchar *journal_id,
- const gchar *last_sync_tag,
- gint limit,
- EteSyncEntry ***out_entries,
- EteSyncCryptoManager **out_crypto_manager,
- EteSyncEntryManager **out_entry_manager)
+static gboolean
+e_etesync_connection_batch_modify_delete_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncAction action,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ ECache *cache,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error)
{
- EteSyncJournal *journal;
- gchar* journal_last_uid;
-
- g_return_val_if_fail (connection, FALSE);
- g_return_val_if_fail (journal_id, FALSE);
+ EtebaseItemManager *item_mgr;
+ gboolean success = TRUE;
- g_rec_mutex_lock (&connection->priv->connection_lock);
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (col_obj != NULL, FALSE);
- *out_crypto_manager = NULL;
- *out_entry_manager = NULL;
- *out_entries = NULL;
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- journal = etesync_journal_manager_fetch (connection->priv->journal_manager, journal_id);
+ g_rec_mutex_lock (&connection->priv->connection_lock);
- /* Failed to connect to server or journal doesn't exist anymore */
- if (!journal) {
- g_rec_mutex_unlock (&connection->priv->connection_lock);
- return FALSE;
- }
+ item_mgr = etebase_collection_manager_get_item_manager (connection->priv->col_mgr, col_obj);
- journal_last_uid = etesync_journal_get_last_uid (journal);
+ if (item_mgr) {
+ EtebaseItem *items[content_len];
+ guint ii;
+ time_t now;
- /* If equal, it returns zero */
- if (g_strcmp0 (journal_last_uid, last_sync_tag) != 0) {
- *out_entry_manager = etesync_entry_manager_new (connection->priv->etesync, journal_id);
- *out_entries = etesync_entry_manager_list (*out_entry_manager, last_sync_tag, limit);
+ e_etesync_utils_get_time_now (&now);
- if (*out_entries && **out_entries) {
- *out_crypto_manager = etesync_journal_get_crypto_manager (journal,
- connection->priv->derived, connection->priv->keypair);
- }
- }
+ memset (items, 0, content_len);
- g_free (journal_last_uid);
- etesync_journal_destroy (journal);
+ for (ii = 0; ii < content_len && success; ii++) {
+ EtebaseItemMetadata *item_metadata = NULL;
+ gchar *data_uid = NULL, *revision = NULL, *item_cache_b64 = NULL;
- g_rec_mutex_unlock (&connection->priv->connection_lock);
+ if (type == E_ETESYNC_ADDRESSBOOK) {/* Contact */
+ e_etesync_utils_get_contact_uid_revision (content[ii], &data_uid, &revision);
+ e_book_cache_get_contact_extra (E_BOOK_CACHE (cache), data_uid,
&item_cache_b64, NULL, NULL);
+ } else if (type == E_ETESYNC_CALENDAR) {/* Calendar */
+ e_etesync_utils_get_component_uid_revision (content[ii], &data_uid,
&revision);
+ e_cal_cache_get_component_extra (E_CAL_CACHE (cache), data_uid, NULL,
&item_cache_b64, NULL, NULL);
+ }
- return TRUE;
-}
+ items[ii] = e_etesync_utils_etebase_item_from_base64 (item_cache_b64, item_mgr);
-/* This function is used to write query to server to
- add/modify/delete an entry inside a journal */
-gboolean
-e_etesync_connection_entry_write_action (EEteSyncConnection *connection,
- const gchar *journal_id,
- const gchar *last_sync_tag,
- const gchar *content,
- const gchar *action,
- gchar **out_last_sync_tag,
- EteSyncErrorCode *out_etesync_error)
-{
- EteSyncJournal *journal;
- gboolean success = FALSE;
+ if (!items[ii]) {
+ success = FALSE;
+ g_clear_error (error);
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Item not
found"));
+ } else {
+ item_metadata = etebase_item_get_meta (items[ii]);
- g_return_val_if_fail (connection != NULL, FALSE);
+ etebase_item_metadata_set_mtime (item_metadata, &now);
+ etebase_item_set_meta(items[ii], item_metadata);
- g_rec_mutex_lock (&connection->priv->connection_lock);
+ if (action == E_ETESYNC_ITEM_ACTION_MODIFY) /* Modify */
+ etebase_item_set_content (items[ii], content[ii], strlen
(content[ii]));
+ else if (action == E_ETESYNC_ITEM_ACTION_DELETE) /* Delete */
+ etebase_item_delete (items[ii]);
- journal = etesync_journal_manager_fetch (connection->priv->journal_manager, journal_id);
+ g_free (item_cache_b64);
+ item_cache_b64 = e_etesync_utils_etebase_item_to_base64 (items[ii], item_mgr);
- if (journal) {
- EteSyncEntryManager *entry_manager;
- EteSyncCryptoManager *crypto_manager;
+ if (type == E_ETESYNC_ADDRESSBOOK) { /* Contact */
+ EBookMetaBackendInfo *nfo;
- entry_manager = etesync_entry_manager_new (connection->priv->etesync, journal_id);
- crypto_manager = etesync_journal_get_crypto_manager (journal, connection->priv->derived,
connection->priv->keypair);
+ nfo = e_book_meta_backend_info_new (data_uid, revision, content[ii],
item_cache_b64);
+ *out_batch_info = g_slist_prepend (*out_batch_info, nfo);
+ } else if (type == E_ETESYNC_CALENDAR) { /* Calendar */
+ ECalMetaBackendInfo *nfo;
- if (crypto_manager) {
- EteSyncSyncEntry *sync_entry;
- EteSyncEntry *entries[2];
+ nfo = e_cal_meta_backend_info_new (data_uid, revision, content[ii],
item_cache_b64);
+ *out_batch_info = g_slist_prepend (*out_batch_info, nfo);
+ }
+ }
+ g_free (data_uid);
+ g_free (revision);
+ g_free (item_cache_b64);
+ if (item_metadata)
+ etebase_item_metadata_destroy (item_metadata);
+ }
- /* create sync entry (data) and turn it to entry to save (encrypted) */
- sync_entry = etesync_sync_entry_new (action, content);
+ /* This could fail when trying to fetch an item and it wasn't found in modify */
+ if (success) {
+ success = !etebase_item_manager_batch (item_mgr, (const EtebaseItem **) items,
ETEBASE_UTILS_C_ARRAY_LEN (items), NULL);
- entries[0] = etesync_entry_from_sync_entry (crypto_manager, sync_entry,
last_sync_tag);
- entries[1] = NULL;
+ if (!success) {
+ EtebaseErrorCode etebase_error = etebase_error_get_code ();
- *out_last_sync_tag = etesync_entry_get_uid (entries[0]);
- success = !etesync_entry_manager_create (entry_manager, (const EteSyncEntry* const*)
entries, last_sync_tag);
+ /* This is used to check if the error was due to expired token, if so try to
get a new token, then try again */
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED
+ && e_etesync_connection_maybe_reconnect_sync (connection, backend,
cancellable, error)) {
- *out_etesync_error = etesync_get_error_code();
+ success = !etebase_item_manager_batch (item_mgr, (const EtebaseItem
**) items, ETEBASE_UTILS_C_ARRAY_LEN (items), NULL);
+ }
- etesync_entry_destroy (entries[0]);
- etesync_sync_entry_destroy (sync_entry);
- etesync_crypto_manager_destroy (crypto_manager);
- } else {
- /* Failed to save contact at etesync_journal_get_crypto_manager */
+ if (!success)
+ e_etesync_utils_set_io_gerror (etebase_error,
etebase_error_get_message (), error);
+ }
}
-
- etesync_entry_manager_destroy (entry_manager);
- etesync_journal_destroy (journal);
- } else {
- /* Failed to save contact at etesync_journal_manager_fetch */
+ for (ii = 0; ii < content_len && items[ii]; ii++)
+ etebase_item_destroy (items[ii]);
}
+ etebase_item_manager_destroy (item_mgr);
g_rec_mutex_unlock (&connection->priv->connection_lock);
@@ -895,75 +1061,127 @@ e_etesync_connection_entry_write_action (EEteSyncConnection *connection,
}
gboolean
-e_etesync_connection_multiple_entry_write_action (EEteSyncConnection *connection,
- const gchar *journal_id,
- const gchar * const * content,
- guint length, /* length of content */
- const gchar *action,
- gchar **out_last_sync_tag,
- EteSyncErrorCode *out_etesync_error)
+e_etesync_connection_batch_create_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error)
{
- EteSyncJournal *journal;
- gboolean success = FALSE;
+ EtebaseItemManager *item_mgr;
+ gboolean success = TRUE;
g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (col_obj != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
g_rec_mutex_lock (&connection->priv->connection_lock);
- journal = etesync_journal_manager_fetch (connection->priv->journal_manager, journal_id);
+ item_mgr = etebase_collection_manager_get_item_manager (connection->priv->col_mgr, col_obj);
- if (journal) {
- EteSyncCryptoManager *crypto_manager;
+ if (item_mgr) {
+ EtebaseItem *items[content_len];
+ guint ii;
+ time_t now;
- crypto_manager = etesync_journal_get_crypto_manager (journal,
- connection->priv->derived,
- connection->priv->keypair);
- if (crypto_manager) {
- EteSyncEntryManager *entry_manager;
- EteSyncEntry **entries;
- guint ii;
+ e_etesync_utils_get_time_now (&now);
- entry_manager = etesync_entry_manager_new (connection->priv->etesync, journal_id);
- entries = g_slice_alloc0 ((length + 1) * sizeof (EteSyncEntry *));
+ for (ii = 0; ii < content_len; ii++) {
+ EtebaseItemMetadata *item_metadata = NULL;
+ gchar *data_uid = NULL, *revision = NULL;
+ gchar *item_cache_b64;
- for (ii = 0; ii < length; ii++) {
- EteSyncSyncEntry *sync_entry;
+ if (type == E_ETESYNC_ADDRESSBOOK) /* Contact */
+ e_etesync_utils_get_contact_uid_revision (content[ii], &data_uid, &revision);
+ else if (type == E_ETESYNC_CALENDAR) /* Calendar */
+ e_etesync_utils_get_component_uid_revision (content[ii], &data_uid,
&revision);
- /* create sync entry (data) and turn it to entry to save (encrypted) */
- sync_entry = etesync_sync_entry_new (action, content[ii]);
- entries [ii] = etesync_entry_from_sync_entry (crypto_manager, sync_entry,
*out_last_sync_tag);
+ item_metadata = etebase_item_metadata_new ();
- if (ii + 1 < length) {
- g_free (*out_last_sync_tag);
- *out_last_sync_tag = etesync_entry_get_uid (entries [ii]);
- }
+ etebase_item_metadata_set_name (item_metadata, data_uid);
+ etebase_item_metadata_set_mtime (item_metadata, &now);
+
+ items[ii] = etebase_item_manager_create (item_mgr, item_metadata, content[ii], strlen
(content[ii]));
+ item_cache_b64 = e_etesync_utils_etebase_item_to_base64 (items[ii], item_mgr);
+
+ if (type == E_ETESYNC_ADDRESSBOOK) { /* Contact */
+ EBookMetaBackendInfo *nfo;
- etesync_sync_entry_destroy (sync_entry);
+ nfo = e_book_meta_backend_info_new (data_uid, revision, content[ii],
item_cache_b64);
+ *out_batch_info = g_slist_prepend (*out_batch_info, nfo);
+ } else if (type == E_ETESYNC_CALENDAR) { /* Calendar */
+ ECalMetaBackendInfo *nfo;
+
+ nfo = e_cal_meta_backend_info_new (data_uid, revision, content[ii],
item_cache_b64);
+ *out_batch_info = g_slist_prepend (*out_batch_info, nfo);
}
+ g_free (data_uid);
+ g_free (revision);
+ g_free (item_cache_b64);
+ etebase_item_metadata_destroy (item_metadata);
+ }
- entries[ii] = NULL;
- success = !etesync_entry_manager_create (entry_manager, (const EteSyncEntry* const*)
entries, *out_last_sync_tag);
+ success = !etebase_item_manager_batch (item_mgr, (const EtebaseItem **) items,
ETEBASE_UTILS_C_ARRAY_LEN (items), NULL);
- g_free (*out_last_sync_tag);
- *out_last_sync_tag = etesync_entry_get_uid (entries [length -1]);
+ if (!success) {
+ EtebaseErrorCode etebase_error = etebase_error_get_code ();
- *out_etesync_error = etesync_get_error_code();
+ /* This is used to check if the error was due to expired token, if so try to get a
new token, then try again */
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED
+ && e_etesync_connection_maybe_reconnect_sync (connection, backend,
cancellable, error)) {
- for (ii = 0; ii < length; ii++)
- etesync_entry_destroy (entries[ii]);
- g_slice_free1 ((length + 1) * sizeof (EteSyncEntry *), entries);
- etesync_entry_manager_destroy (entry_manager);
- etesync_crypto_manager_destroy (crypto_manager);
+ success = !etebase_item_manager_batch (item_mgr, (const EtebaseItem **)
items, ETEBASE_UTILS_C_ARRAY_LEN (items), NULL);
+ }
+
+ if (!success)
+ e_etesync_utils_set_io_gerror (etebase_error, etebase_error_get_message (),
error);
}
- etesync_journal_destroy (journal);
+ for (ii = 0; ii < content_len && success; ii++)
+ etebase_item_destroy (items[ii]);
}
+ etebase_item_manager_destroy (item_mgr);
g_rec_mutex_unlock (&connection->priv->connection_lock);
return success;
}
+gboolean
+e_etesync_connection_batch_modify_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ ECache *cache,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return e_etesync_connection_batch_modify_delete_sync (connection, backend, col_obj,
E_ETESYNC_ITEM_ACTION_MODIFY, type, content, content_len, cache, out_batch_info, cancellable, error);
+}
+
+gboolean
+e_etesync_connection_batch_delete_sync (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ ECache *cache,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return e_etesync_connection_batch_modify_delete_sync (connection, backend, col_obj,
E_ETESYNC_ITEM_ACTION_DELETE, type, content, content_len, cache, out_batch_info, cancellable, error);
+}
+
/*----------------------------GObject functions----------------------*/
static void
@@ -986,6 +1204,7 @@ etesync_connection_finalize (GObject *object)
g_rec_mutex_lock (&connection->priv->connection_lock);
e_etesync_connection_clear (connection);
g_free (connection->priv->hash_key);
+ g_clear_object (&connection->priv->collection_source);
g_rec_mutex_unlock (&connection->priv->connection_lock);
g_rec_mutex_clear (&connection->priv->connection_lock);
@@ -1016,35 +1235,21 @@ e_etesync_connection_init (EEteSyncConnection *connection)
/* ---------------------Encapsulation functions------------------- */
const gchar *
-e_etesync_connection_get_token (EEteSyncConnection *connection)
-{
- g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
-
- return connection->priv->token;
-}
-
-const gchar *
-e_etesync_connection_get_derived_key (EEteSyncConnection *connection)
-{
- g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
-
- return connection->priv->derived;
-}
-
-const gchar *
-e_etesync_connection_get_server_url (EEteSyncConnection *connection)
+e_etesync_connection_get_session_key (EEteSyncConnection *connection)
{
g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
- return connection->priv->server_url;
+ return connection->priv->session_key;
}
-const gchar *
-e_etesync_connection_get_username (EEteSyncConnection *connection)
+void
+e_etesync_connection_set_session_key (EEteSyncConnection *connection,
+ const gchar* session_key)
{
- g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
+ g_return_if_fail (E_IS_ETESYNC_CONNECTION (connection));
- return connection->priv->username;
+ g_free (connection->priv->session_key);
+ connection->priv->session_key = g_strdup (session_key);
}
gboolean
@@ -1055,26 +1260,26 @@ e_etesync_connection_get_requested_credentials (EEteSyncConnection *connection)
return connection->priv->requested_credentials;
}
-EteSync *
-e_etesync_connection_get_etesync (EEteSyncConnection *connection)
+EtebaseClient *
+e_etesync_connection_get_etebase_client (EEteSyncConnection *connection)
{
g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
- return connection->priv->etesync;
+ return connection->priv->etebase_client;
}
-EteSyncJournalManager *
-e_etesync_connection_get_journal_manager (EEteSyncConnection *connection)
+EtebaseAccount *
+e_etesync_connection_get_etebase_account (EEteSyncConnection *connection)
{
g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
- return connection->priv->journal_manager;
+ return connection->priv->etebase_account;
}
-EteSyncAsymmetricKeyPair *
-e_etesync_connection_get_keypair (EEteSyncConnection *connection)
+EtebaseCollectionManager *
+e_etesync_connection_get_collection_manager (EEteSyncConnection *connection)
{
g_return_val_if_fail (E_IS_ETESYNC_CONNECTION (connection), NULL);
- return connection->priv->keypair;
+ return connection->priv->col_mgr;
}
diff --git a/src/common/e-etesync-connection.h b/src/common/e-etesync-connection.h
index 7baee42..ea2291d 100644
--- a/src/common/e-etesync-connection.h
+++ b/src/common/e-etesync-connection.h
@@ -9,7 +9,10 @@
#define E_ETESYNC_CONNECTION_H
#include <libedataserver/libedataserver.h>
-#include <etesync.h>
+#include <libedata-book/libedata-book.h>
+#include <libedata-cal/libedata-cal.h>
+#include "e-etesync-defines.h"
+#include <etebase.h>
/* Standard GObject macros */
#define E_TYPE_ETESYNC_CONNECTION \
@@ -46,95 +49,141 @@ struct _EEteSyncConnectionClass {
};
EEteSyncConnection *
- e_etesync_connection_new (void);
-EEteSyncConnection *
- e_etesync_connection_new_from_user_url
- (const gchar* username,
- const gchar* server_url);
+ e_etesync_connection_new (ESource *collection);
ESourceAuthenticationResult
- e_etesync_connection_check_token_validation
- (EEteSyncConnection *connection);
-gboolean e_etesync_connection_init_userinfo
- (EEteSyncConnection *connection);
-gboolean e_etesync_connection_set_connection
+ e_etesync_connection_check_session_key_validation_sync
+ (EEteSyncConnection *connection,
+ EtebaseErrorCode *out_etebase_error,
+ GError **error);
+gboolean e_etesync_connection_set_connection_from_sources
+ (EEteSyncConnection *connection,
+ const ENamedParameters *credentials);
+gboolean e_etesync_connection_login_connection_sync
(EEteSyncConnection *connection,
const gchar *username,
const gchar *password,
- const gchar *encryption_password,
const gchar *server_url,
- EteSyncErrorCode *out_etesync_error);
-ESourceAuthenticationResult
- e_etesync_connection_set_connection_from_sources
+ EtebaseErrorCode *out_etebase_error);
+gboolean e_etesync_connection_is_connected
+ (EEteSyncConnection *connection);
+gboolean e_etesync_connection_reconnect_sync
(EEteSyncConnection *connection,
- const ENamedParameters *credentials,
- ESourceAuthentication *authentication_extension,
- ESourceCollection *collection_extension);
-gboolean e_etesync_connection_needs_setting
+ ESourceAuthenticationResult *out_result,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_maybe_reconnect_sync
(EEteSyncConnection *connection,
- const ENamedParameters *credentials,
- ESourceAuthenticationResult *result);
-void e_etesync_connection_source_changed_cb
- (ESource *source,
- ESource *collection,
- gboolean is_contact);
-EEteSyncConnection *
- e_etesync_connection_new_connection
- (ESource *collection);
-gboolean e_etesync_connection_get_journal_exists
+ EBackend *backend,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_collection_create_upload_sync
(EEteSyncConnection *connection,
- const gchar *journal_id,
- gboolean *is_read_only);
-gboolean e_etesync_connection_check_journal_changed_sync
+ EBackend *backend,
+ const gchar *col_type,
+ const gchar *display_name,
+ const gchar *description,
+ const gchar *color,
+ EtebaseCollection **out_col_obj,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_collection_modify_upload_sync
(EEteSyncConnection *connection,
- const gchar *journal_id,
- const gchar *last_sync_tag,
- gint limit,
- EteSyncEntry ***out_entries,
- EteSyncCryptoManager **out_crypto_manager,
- EteSyncEntryManager **out_entry_manager);
-gboolean e_etesync_connection_entry_write_action
+ EtebaseCollection *col_obj,
+ const gchar *display_name,
+ const gchar *description,
+ const gchar *color,
+ GError **error);
+gboolean e_etesync_connection_collection_delete_upload_sync
+ (EEteSyncConnection *connection,
+ EBackend *backend,
+ EtebaseCollection *col_obj,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_list_existing_sync
(EEteSyncConnection *connection,
- const gchar *journal_id,
+ EBackend *backend,
+ const EteSyncType type,
+ const EtebaseCollection *col_obj,
+ gchar **out_new_sync_tag,
+ GSList **out_existing_objects,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_get_changes_sync
+ (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EteSyncType type,
const gchar *last_sync_tag,
+ const EtebaseCollection *col_obj,
+ ECache *cache,
+ gchar **out_new_sync_tag,
+ GSList **out_created_objects, /* EBookMetaBackendInfo* or
ECalMetaBackendInfo* */
+ GSList **out_modified_objects, /* EBookMetaBackendInfo* or
ECalMetaBackendInfo* */
+ GSList **out_removed_objects,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_item_upload_sync
+ (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncAction action,
const gchar *content,
- const gchar *action,
- gchar **out_last_sync_tag,
- EteSyncErrorCode *out_etesync_error);
-gboolean e_etesync_connection_multiple_entry_write_action
+ const gchar *uid,
+ const gchar *extra,
+ gchar **out_new_extra,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_batch_create_sync
(EEteSyncConnection *connection,
- const gchar *journal_id,
- const gchar * const * content,
- guint length,
- const gchar *action,
- gchar **out_last_sync_tag,
- EteSyncErrorCode *out_etesync_error);
-gboolean e_etesync_connection_write_journal_action
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_batch_modify_sync
(EEteSyncConnection *connection,
- const gchar *action,
- const gchar *journal_uid,
- const gchar *journal_type,
- const gchar *display_name,
- const gchar *description,
- gint32 color,
- EteSyncJournal **out_journal);
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ ECache *cache,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_etesync_connection_batch_delete_sync
+ (EEteSyncConnection *connection,
+ EBackend *backend,
+ const EtebaseCollection *col_obj,
+ const EteSyncType type,
+ const gchar *const *content,
+ guint content_len,
+ ECache *cache,
+ GSList **out_batch_info,
+ GCancellable *cancellable,
+ GError **error);
GType e_etesync_connection_get_type (void) G_GNUC_CONST;
const gchar * e_etesync_connection_get_token (EEteSyncConnection *connection);
const gchar * e_etesync_connection_get_derived_key
(EEteSyncConnection *connection);
-const gchar * e_etesync_connection_get_server_url
- (EEteSyncConnection *connection);
-const gchar * e_etesync_connection_get_username
+const gchar *
+ e_etesync_connection_get_session_key
(EEteSyncConnection *connection);
+void e_etesync_connection_set_session_key
+ (EEteSyncConnection *connection,
+ const gchar* session_key);
gboolean e_etesync_connection_get_requested_credentials
(EEteSyncConnection *connection);
-EteSync * e_etesync_connection_get_etesync
+EtebaseClient * e_etesync_connection_get_etebase_client
(EEteSyncConnection *connection);
-EteSyncJournalManager *
- e_etesync_connection_get_journal_manager
+EtebaseAccount *
+ e_etesync_connection_get_etebase_account
(EEteSyncConnection *connection);
-EteSyncAsymmetricKeyPair *
- e_etesync_connection_get_keypair
+EtebaseCollectionManager *
+ e_etesync_connection_get_collection_manager
(EEteSyncConnection *connection);
G_END_DECLS
diff --git a/src/common/e-etesync-defines.h b/src/common/e-etesync-defines.h
index fffb86a..1a48db8 100644
--- a/src/common/e-etesync-defines.h
+++ b/src/common/e-etesync-defines.h
@@ -8,8 +8,27 @@
#ifndef E_ETESYNC_DEFINES_H
#define E_ETESYNC_DEFINES_H
-#define E_ETESYNC_CREDENTIAL_ENCRYPTION_PASSWORD "encryption_password"
-#define E_ETESYNC_CREDENTIAL_TOKEN "token"
-#define E_ETESYNC_CREDENTIAL_DERIVED_KEY "derived_key"
+typedef enum {
+ E_ETESYNC_ITEM_ACTION_CREATE,
+ E_ETESYNC_ITEM_ACTION_MODIFY,
+ E_ETESYNC_ITEM_ACTION_DELETE,
+} EteSyncAction;
+
+typedef enum {
+ E_ETESYNC_ADDRESSBOOK,
+ E_ETESYNC_CALENDAR
+} EteSyncType;
+
+#define E_ETESYNC_CREDENTIAL_SESSION_KEY "session_key"
+
+#define E_ETESYNC_COLLECTION_TYPE_CALENDAR "etebase.vevent"
+#define E_ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK "etebase.vcard"
+#define E_ETESYNC_COLLECTION_TYPE_TASKS "etebase.vtodo"
+
+#define E_ETESYNC_COLLECTION_DEFAULT_COLOR "#8BC34A"
+
+#define E_ETESYNC_COLLECTION_FETCH_LIMIT 30
+#define E_ETESYNC_ITEM_FETCH_LIMIT 50
+#define E_ETESYNC_ITEM_PUSH_LIMIT 30
#endif /* E_ETESYNC_DEFINES_H */
diff --git a/src/credentials/e-etesync-service.c b/src/common/e-etesync-service.c
similarity index 97%
rename from src/credentials/e-etesync-service.c
rename to src/common/e-etesync-service.c
index 43af269..0f0c1f5 100644
--- a/src/credentials/e-etesync-service.c
+++ b/src/common/e-etesync-service.c
@@ -83,10 +83,10 @@ e_etesync_service_lookup_password_sync (const gchar *uid,
return FALSE;
}
- *out_password = g_strdup (secret);
-
- if (out_password)
+ if (out_password) {
+ *out_password = g_strdup (secret);
success = TRUE;
+ }
e_util_safe_free_string (secret);
diff --git a/src/credentials/e-etesync-service.h b/src/common/e-etesync-service.h
similarity index 100%
rename from src/credentials/e-etesync-service.h
rename to src/common/e-etesync-service.h
diff --git a/src/common/e-etesync-utils.c b/src/common/e-etesync-utils.c
new file mode 100644
index 0000000..878008a
--- /dev/null
+++ b/src/common/e-etesync-utils.c
@@ -0,0 +1,194 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-etesync-utils.c
+ *
+ * SPDX-FileCopyrightText: (C) 2020 Nour E-Din El-Nhass <nouredinosama.gmail.com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-etesync-config.h"
+
+#include <libedata-book/libedata-book.h>
+#include <libedata-cal/libedata-cal.h>
+#include "e-etesync-defines.h"
+#include "e-etesync-utils.h"
+
+static const gchar *const collection_supported_types[] = {
+ E_ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK,
+ E_ETESYNC_COLLECTION_TYPE_CALENDAR,
+ E_ETESYNC_COLLECTION_TYPE_TASKS };
+static const gchar *const collection_supported_types_default_names[] = {
+ "My Contacts",
+ "My Calendar",
+ "My Tasks" };
+
+void
+e_etesync_utils_get_time_now (time_t *now)
+{
+ *now = g_get_real_time() / 1000;
+}
+
+gboolean
+e_etesync_utils_get_component_uid_revision (const gchar *content,
+ gchar **out_component_uid,
+ gchar **out_revision)
+{
+ ICalComponent *vcalendar, *subcomp;
+ gboolean success = FALSE;
+
+ vcalendar = i_cal_component_new_from_string (content);
+
+ *out_component_uid = NULL;
+ *out_revision = NULL;
+
+ for (subcomp = i_cal_component_get_first_component (vcalendar, I_CAL_ANY_COMPONENT);
+ subcomp && (!*out_component_uid || !*out_revision);
+ g_object_unref (subcomp), subcomp = i_cal_component_get_next_component (vcalendar,
I_CAL_ANY_COMPONENT)) {
+
+ ICalComponentKind kind = i_cal_component_isa (subcomp);
+
+ if (kind == I_CAL_VEVENT_COMPONENT ||
+ kind == I_CAL_VTODO_COMPONENT) {
+ if (!*out_component_uid){
+ *out_component_uid = g_strdup (i_cal_component_get_uid (subcomp));
+ success = TRUE;
+ }
+
+ if (!*out_revision) {
+ ICalProperty *prop;
+
+ prop = i_cal_component_get_first_property (vcalendar,
I_CAL_LASTMODIFIED_PROPERTY);
+ if (prop) {
+ ICalTime *itt;
+
+ itt = i_cal_property_get_lastmodified (prop);
+ *out_revision = i_cal_time_as_ical_string (itt);
+ g_clear_object (&itt);
+ g_object_unref (prop);
+ } else {
+ *out_revision = NULL;
+ }
+ }
+ }
+ }
+
+ if (subcomp)
+ g_object_unref (subcomp);
+ g_object_unref (vcalendar);
+
+ return success;
+}
+
+void
+e_etesync_utils_get_contact_uid_revision (const gchar *content,
+ gchar **out_contact_uid,
+ gchar **out_revision)
+{
+ EContact *contact;
+
+ contact = e_contact_new_from_vcard (content);
+
+ if (contact) {
+ *out_contact_uid = e_contact_get (contact, E_CONTACT_UID);
+ *out_revision = e_contact_get (contact, E_CONTACT_REV);
+
+ g_object_unref (contact);
+ }
+}
+
+void
+e_etesync_utils_set_io_gerror (EtebaseErrorCode etebase_error,
+ const gchar* etesync_message,
+ GError **error)
+{
+ if (etebase_error == ETEBASE_ERROR_CODE_TEMPORARY_SERVER_ERROR)
+ return;
+
+ g_clear_error (error);
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, etesync_message);
+}
+
+gchar *
+e_etesync_utils_etebase_item_to_base64 (const EtebaseItem *item,
+ EtebaseItemManager *item_mgr)
+{
+ gchar *item_cache_b64;
+ guintptr item_cache_size;
+ void *item_cache_blob;
+
+ /* cache item as base64 in extra paremater as it will be used for modification and deletion */
+ item_cache_blob = etebase_item_manager_cache_save (item_mgr, item, &item_cache_size);
+ item_cache_b64 = g_malloc (ETEBASE_UTILS_TO_BASE64_MAX_LEN (item_cache_size));
+ etebase_utils_to_base64 (item_cache_blob, item_cache_size, item_cache_b64,
+ ETEBASE_UTILS_TO_BASE64_MAX_LEN (item_cache_size));
+
+ g_free (item_cache_blob);
+
+ return item_cache_b64;
+}
+
+EtebaseItem *
+e_etesync_utils_etebase_item_from_base64 (const gchar *item_cache_b64,
+ EtebaseItemManager *item_mgr)
+{
+ EtebaseItem *item;
+ void *item_cache_blob;
+ guintptr item_cache_size = 0, len;
+
+ /* get cached item from base64 to EtebaseItem in extra paremater as it will be used for modification
and deletion */
+ len = ETEBASE_UTILS_FROM_BASE64_MAX_LEN (strlen (item_cache_b64));
+ item_cache_blob = g_slice_alloc0 (len);
+ etebase_utils_from_base64 (item_cache_b64, item_cache_blob, ETEBASE_UTILS_FROM_BASE64_MAX_LEN (strlen
(item_cache_b64)), &item_cache_size);
+ item = etebase_item_manager_cache_load (item_mgr, item_cache_blob, item_cache_size);
+
+ g_slice_free1 (len, item_cache_blob);
+
+ return item;
+}
+
+gchar *
+e_etesync_utils_etebase_collection_to_base64 (const EtebaseCollection *collection,
+ EtebaseCollectionManager *col_mgr)
+{
+ gchar *collection_cache_b64;
+ guintptr collection_cache_size;
+ void *collection_cache_blob;
+
+ collection_cache_blob = etebase_collection_manager_cache_save (col_mgr, collection,
&collection_cache_size);
+ collection_cache_b64 = g_malloc (ETEBASE_UTILS_TO_BASE64_MAX_LEN (collection_cache_size));
+ etebase_utils_to_base64 (collection_cache_blob, collection_cache_size, collection_cache_b64,
+ ETEBASE_UTILS_TO_BASE64_MAX_LEN (collection_cache_size));
+
+ g_free (collection_cache_blob);
+
+ return collection_cache_b64;
+}
+
+EtebaseCollection *
+e_etesync_utils_etebase_collection_from_base64 (const gchar *collection_cache_b64,
+ EtebaseCollectionManager *col_mgr)
+{
+ EtebaseCollection *collection;
+ void *collection_cache_blob;
+ guintptr collection_cache_size = 0, len;
+
+ len = ETEBASE_UTILS_FROM_BASE64_MAX_LEN (strlen (collection_cache_b64));
+ collection_cache_blob = g_malloc (len);
+ etebase_utils_from_base64 (collection_cache_b64, collection_cache_blob,
ETEBASE_UTILS_FROM_BASE64_MAX_LEN (strlen (collection_cache_b64)), &collection_cache_size);
+ collection = etebase_collection_manager_cache_load (col_mgr, collection_cache_blob,
collection_cache_size);
+
+ g_slice_free1 (len, collection_cache_blob);
+
+ return collection;
+}
+
+const gchar *const *
+e_etesync_util_get_collection_supported_types (void)
+{
+ return collection_supported_types;
+}
+
+const gchar *const *
+e_etesync_util_get_collection_supported_types_default_names (void)
+{
+ return collection_supported_types_default_names;
+}
\ No newline at end of file
diff --git a/src/common/e-etesync-utils.h b/src/common/e-etesync-utils.h
new file mode 100644
index 0000000..11e35bb
--- /dev/null
+++ b/src/common/e-etesync-utils.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-etesync-utils.h
+ *
+ * SPDX-FileCopyrightText: (C) 2020 Nour E-Din El-Nhass <nouredinosama.gmail.com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef E_ETESYNC_UTILS_H
+#define E_ETESYNC_UTILS_H
+
+#include <libedataserver/libedataserver.h>
+#include <etebase.h>
+
+#define EETESYNC_UTILS_SUPPORTED_TYPES_SIZE 3
+
+G_BEGIN_DECLS
+
+void e_etesync_utils_get_time_now (time_t *now);
+gboolean e_etesync_utils_get_component_uid_revision
+ (const gchar *content,
+ gchar **out_component_uid,
+ gchar **out_revision);
+void e_etesync_utils_get_contact_uid_revision
+ (const gchar *content,
+ gchar **out_contact_uid,
+ gchar **out_revision);
+void e_etesync_utils_set_io_gerror (EtebaseErrorCode etesync_error,
+ const gchar* etesync_message,
+ GError **error);
+gchar * e_etesync_utils_etebase_item_to_base64
+ (const EtebaseItem *item,
+ EtebaseItemManager *item_mgr);
+EtebaseItem * e_etesync_utils_etebase_item_from_base64
+ (const gchar *item_cache_b64,
+ EtebaseItemManager *item_mgr);
+gchar * e_etesync_utils_etebase_collection_to_base64
+ (const EtebaseCollection *collection,
+ EtebaseCollectionManager *col_mgr);
+EtebaseCollection *
+ e_etesync_utils_etebase_collection_from_base64
+ (const gchar *collection_cache_b64,
+ EtebaseCollectionManager *col_mgr);
+const gchar *const *
+ e_etesync_util_get_collection_supported_types (void);
+const gchar *const *
+ e_etesync_util_get_collection_supported_types_default_names (void);
+
+G_END_DECLS
+#endif /* E_ETESYNC_UTILS_H */
diff --git a/src/common/e-source-etesync-account.c b/src/common/e-source-etesync-account.c
new file mode 100644
index 0000000..5510b74
--- /dev/null
+++ b/src/common/e-source-etesync-account.c
@@ -0,0 +1,157 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-source-etesync-account.c
+ *
+ * SPDX-FileCopyrightText: (C) 2020 Nour E-Din El-Nhass <nouredinosama.gmail.com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-etesync-config.h"
+
+#include "e-source-etesync-account.h"
+
+struct _ESourceEteSyncAccountPrivate {
+ gchar *collection_stoken;
+};
+
+enum {
+ PROP_0,
+ PROP_COLLECTION_STOKEN
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (ESourceEteSyncAccount, e_source_etesync_account, E_TYPE_SOURCE_EXTENSION)
+
+static void
+source_etesync_account_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COLLECTION_STOKEN:
+ e_source_etesync_account_set_collection_stoken (
+ E_SOURCE_ETESYNC_ACCOUNT (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_etesync_account_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COLLECTION_STOKEN:
+ g_value_take_string (
+ value,
+ e_source_etesync_account_dup_collection_stoken (
+ E_SOURCE_ETESYNC_ACCOUNT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_etesync_account_finalize (GObject *object)
+{
+ ESourceEteSyncAccount *etesync_account = E_SOURCE_ETESYNC_ACCOUNT (object);
+
+ g_free (etesync_account->priv->collection_stoken);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_source_etesync_account_parent_class)->finalize (object);
+}
+
+static void
+e_source_etesync_account_class_init (ESourceEteSyncAccountClass *class)
+{
+ GObjectClass *object_class;
+ ESourceExtensionClass *extension_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = source_etesync_account_set_property;
+ object_class->get_property = source_etesync_account_get_property;
+ object_class->finalize = source_etesync_account_finalize;
+
+ extension_class = E_SOURCE_EXTENSION_CLASS (class);
+ extension_class->name = E_SOURCE_EXTENSION_ETESYNC_ACCOUNT;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COLLECTION_STOKEN,
+ g_param_spec_string (
+ "collection-stoken",
+ "Collection stoken",
+ "This is the account collection stoken, used to get changes,"
+ "instead of getting the whole list of existing collections",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+}
+
+static void
+e_source_etesync_account_init (ESourceEteSyncAccount *extension)
+{
+ extension->priv = e_source_etesync_account_get_instance_private (extension);
+}
+
+void
+e_source_etesync_account_type_register (GTypeModule *type_module)
+{
+ /* We need to ensure this is registered, because it's looked up
+ * by name in e_source_get_extension(). */
+ g_type_ensure (E_TYPE_SOURCE_ETESYNC_ACCOUNT);
+}
+
+const gchar *
+e_source_etesync_account_get_collection_stoken (ESourceEteSyncAccount *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_ETESYNC_ACCOUNT (extension), NULL);
+
+ return extension->priv->collection_stoken;
+}
+
+gchar *
+e_source_etesync_account_dup_collection_stoken (ESourceEteSyncAccount *extension)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (E_IS_SOURCE_ETESYNC_ACCOUNT (extension), NULL);
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ protected = e_source_etesync_account_get_collection_stoken (extension);
+ duplicate = g_strdup (protected);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ return duplicate;
+}
+
+void
+e_source_etesync_account_set_collection_stoken (ESourceEteSyncAccount *extension,
+ const gchar *collection_stoken)
+{
+ g_return_if_fail (E_IS_SOURCE_ETESYNC_ACCOUNT (extension));
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ if (e_util_strcmp0 (extension->priv->collection_stoken, collection_stoken) == 0) {
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+ return;
+ }
+
+ g_free (extension->priv->collection_stoken);
+ extension->priv->collection_stoken = e_util_strdup_strip (collection_stoken);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ g_object_notify (G_OBJECT (extension), "collection-stoken");
+}
diff --git a/src/common/e-source-etesync-account.h b/src/common/e-source-etesync-account.h
new file mode 100644
index 0000000..a753765
--- /dev/null
+++ b/src/common/e-source-etesync-account.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-source-etesync-account.h
+ *
+ * SPDX-FileCopyrightText: (C) 2020 Nour E-Din El-Nhass <nouredinosama.gmail.com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef E_SOURCE_ETESYNC_ACCOUNT_H
+#define E_SOURCE_ETESYNC_ACCOUNT_H
+
+#include <libedataserver/libedataserver.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_ETESYNC_ACCOUNT \
+ (e_source_etesync_account_get_type ())
+#define E_SOURCE_ETESYNC_ACCOUNT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SOURCE_ETESYNC_ACCOUNT, ESourceEteSyncAccount))
+#define E_SOURCE_ETESYNC_ACCOUNT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SOURCE_ETESYNC_ACCOUNT, ESourceEteSyncAccountClass))
+#define E_IS_SOURCE_ETESYNC_ACCOUNT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SOURCE_ETESYNC_ACCOUNT))
+#define E_IS_SOURCE_ETESYNC_ACCOUNT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SOURCE_ETESYNC_ACCOUNT))
+#define E_SOURCE_ETESYNC_ACCOUNT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SOURCE_ETESYNC_ACCOUNT, ESourceEteSyncAccountClass))
+
+#define E_SOURCE_EXTENSION_ETESYNC_ACCOUNT "EteSync Account"
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceEteSyncAccount ESourceEteSyncAccount;
+typedef struct _ESourceEteSyncAccountClass ESourceEteSyncAccountClass;
+typedef struct _ESourceEteSyncAccountPrivate ESourceEteSyncAccountPrivate;
+
+struct _ESourceEteSyncAccount {
+ ESourceExtension parent;
+ ESourceEteSyncAccountPrivate *priv;
+};
+
+struct _ESourceEteSyncAccountClass {
+ ESourceExtensionClass parent_class;
+};
+
+GType e_source_etesync_account_get_type
+ (void) G_GNUC_CONST;
+void e_source_etesync_account_type_register
+ (GTypeModule *type_module);
+const gchar * e_source_etesync_account_get_collection_stoken
+ (ESourceEteSyncAccount *extension);
+gchar * e_source_etesync_account_dup_collection_stoken
+ (ESourceEteSyncAccount *extension);
+void e_source_etesync_account_set_collection_stoken
+ (ESourceEteSyncAccount *extension,
+ const gchar *collection_stoken);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_ETESYNC_ACCOUNT_H */
diff --git a/src/common/e-source-etesync.c b/src/common/e-source-etesync.c
index ed4c5b2..d230d5f 100644
--- a/src/common/e-source-etesync.c
+++ b/src/common/e-source-etesync.c
@@ -7,20 +7,22 @@
#include "evolution-etesync-config.h"
-#include <etesync.h>
+#include "e-etesync-defines.h"
#include "e-source-etesync.h"
struct _ESourceEteSyncPrivate {
- gchar *journal_id;
- gint32 color;
+ gchar *collection_id;
+ gchar *color;
gchar *description;
+ gchar *etebase_collection_b64;
};
enum {
PROP_0,
PROP_COLOR,
PROP_DESCRIPTION,
- PROP_JOURNAL_ID
+ PROP_COLLECTION_ID,
+ PROP_ETEBASE_COLLECTION_B64
};
G_DEFINE_TYPE_WITH_PRIVATE (ESourceEteSync, e_source_etesync, E_TYPE_SOURCE_EXTENSION)
@@ -33,19 +35,24 @@ source_etesync_set_property (GObject *object,
{
switch (property_id) {
case PROP_COLOR:
- e_source_etesync_set_journal_color (
+ e_source_etesync_set_collection_color (
E_SOURCE_ETESYNC (object),
- g_value_get_int (value));
+ g_value_get_string (value));
return;
case PROP_DESCRIPTION:
- e_source_etesync_set_journal_description (
+ e_source_etesync_set_collection_description (
E_SOURCE_ETESYNC (object),
g_value_get_string (value));
return;
- case PROP_JOURNAL_ID:
- e_source_etesync_set_journal_id (
+ case PROP_COLLECTION_ID:
+ e_source_etesync_set_collection_id (
+ E_SOURCE_ETESYNC (object),
+ g_value_get_string (value));
+ return;
+ case PROP_ETEBASE_COLLECTION_B64:
+ e_source_etesync_set_etebase_collection_b64 (
E_SOURCE_ETESYNC (object),
g_value_get_string (value));
return;
@@ -64,23 +71,29 @@ source_etesync_get_property (GObject *object,
{
switch (property_id) {
case PROP_COLOR:
- g_value_set_int (
+ g_value_take_string (
value,
- e_source_etesync_get_journal_color (
+ e_source_etesync_dup_collection_color (
E_SOURCE_ETESYNC (object)));
return;
case PROP_DESCRIPTION:
g_value_take_string (
value,
- e_source_etesync_dup_journal_description (
+ e_source_etesync_dup_collection_description (
E_SOURCE_ETESYNC (object)));
return;
- case PROP_JOURNAL_ID:
+ case PROP_COLLECTION_ID:
g_value_take_string (
value,
- e_source_etesync_dup_journal_id (
+ e_source_etesync_dup_collection_id (
+ E_SOURCE_ETESYNC (object)));
+ return;
+ case PROP_ETEBASE_COLLECTION_B64:
+ g_value_take_string (
+ value,
+ e_source_etesync_dup_etebase_collection_b64 (
E_SOURCE_ETESYNC (object)));
return;
}
@@ -95,8 +108,10 @@ source_etesync_finalize (GObject *object)
priv = e_source_etesync_get_instance_private (E_SOURCE_ETESYNC (object));
- g_free (priv->journal_id);
+ g_free (priv->collection_id);
g_free (priv->description);
+ g_free (priv->color);
+ g_free (priv->etebase_collection_b64);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_source_etesync_parent_class)->finalize (object);
@@ -118,11 +133,11 @@ e_source_etesync_class_init (ESourceEteSyncClass *class)
g_object_class_install_property (
object_class,
- PROP_JOURNAL_ID,
+ PROP_COLLECTION_ID,
g_param_spec_string (
- "journal-id",
- "Journal ID",
- "This is the journal ID, used when submitting changes or getting data using EteSync
API",
+ "collection-id",
+ "Collection ID",
+ "This is the collection ID, used when submitting changes or getting data using
EteSync API",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
@@ -135,7 +150,7 @@ e_source_etesync_class_init (ESourceEteSyncClass *class)
g_param_spec_string (
"description",
"Description",
- "Description of the journal",
+ "Description of the collection",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
@@ -145,11 +160,24 @@ e_source_etesync_class_init (ESourceEteSyncClass *class)
g_object_class_install_property (
object_class,
PROP_COLOR,
- g_param_spec_int (
+ g_param_spec_string (
"color",
"Color",
- "Color of the EteSync journal resource",
- G_MININT, G_MAXINT, ETESYNC_COLLECTION_DEFAULT_COLOR,
+ "Color of the EteSync collection resource",
+ E_ETESYNC_COLLECTION_DEFAULT_COLOR,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ETEBASE_COLLECTION_B64,
+ g_param_spec_string (
+ "etebase-collection",
+ "Etebase Collection B64",
+ "Etebase collection object cached as string in base64",
+ NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS |
@@ -171,15 +199,15 @@ e_source_etesync_type_register (GTypeModule *type_module)
}
const gchar *
-e_source_etesync_get_journal_id (ESourceEteSync *extension)
+e_source_etesync_get_collection_id (ESourceEteSync *extension)
{
g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
- return extension->priv->journal_id;
+ return extension->priv->collection_id;
}
gchar *
-e_source_etesync_dup_journal_id (ESourceEteSync *extension)
+e_source_etesync_dup_collection_id (ESourceEteSync *extension)
{
const gchar *protected;
gchar *duplicate;
@@ -187,7 +215,7 @@ e_source_etesync_dup_journal_id (ESourceEteSync *extension)
g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
- protected = e_source_etesync_get_journal_id (extension);
+ protected = e_source_etesync_get_collection_id (extension);
duplicate = g_strdup (protected);
e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
@@ -196,28 +224,28 @@ e_source_etesync_dup_journal_id (ESourceEteSync *extension)
}
void
-e_source_etesync_set_journal_id (ESourceEteSync *extension,
- const gchar *journal_id)
+e_source_etesync_set_collection_id (ESourceEteSync *extension,
+ const gchar *collection_id)
{
g_return_if_fail (E_IS_SOURCE_ETESYNC (extension));
e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
- if (e_util_strcmp0 (extension->priv->journal_id, journal_id) == 0) {
+ if (e_util_strcmp0 (extension->priv->collection_id, collection_id) == 0) {
e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
return;
}
- g_free (extension->priv->journal_id);
- extension->priv->journal_id = e_util_strdup_strip (journal_id);
+ g_free (extension->priv->collection_id);
+ extension->priv->collection_id = e_util_strdup_strip (collection_id);
e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
- g_object_notify (G_OBJECT (extension), "journal-id");
+ g_object_notify (G_OBJECT (extension), "collection-id");
}
const gchar *
-e_source_etesync_get_journal_description (ESourceEteSync *extension)
+e_source_etesync_get_collection_description (ESourceEteSync *extension)
{
g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
@@ -225,7 +253,7 @@ e_source_etesync_get_journal_description (ESourceEteSync *extension)
}
gchar *
-e_source_etesync_dup_journal_description (ESourceEteSync *extension)
+e_source_etesync_dup_collection_description (ESourceEteSync *extension)
{
const gchar *protected;
gchar *duplicate;
@@ -234,7 +262,7 @@ e_source_etesync_dup_journal_description (ESourceEteSync *extension)
e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
- protected = e_source_etesync_get_journal_description (extension);
+ protected = e_source_etesync_get_collection_description (extension);
duplicate = g_strdup (protected);
e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
@@ -243,8 +271,8 @@ e_source_etesync_dup_journal_description (ESourceEteSync *extension)
}
void
-e_source_etesync_set_journal_description (ESourceEteSync *extension,
- const gchar *description)
+e_source_etesync_set_collection_description (ESourceEteSync *extension,
+ const gchar *description)
{
g_return_if_fail (E_IS_SOURCE_ETESYNC (extension));
@@ -263,25 +291,94 @@ e_source_etesync_set_journal_description (ESourceEteSync *extension,
g_object_notify (G_OBJECT (extension), "description");
}
-gint32
-e_source_etesync_get_journal_color (ESourceEteSync *extension)
+const gchar *
+e_source_etesync_get_collection_color (ESourceEteSync *extension)
{
- g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), ETESYNC_COLLECTION_DEFAULT_COLOR);
+ g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
return extension->priv->color;
}
+gchar *
+e_source_etesync_dup_collection_color (ESourceEteSync *extension)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ protected = e_source_etesync_get_collection_color (extension);
+ duplicate = g_strdup (protected);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ return duplicate;
+}
+
void
-e_source_etesync_set_journal_color (ESourceEteSync *extension,
- const gint32 color)
+e_source_etesync_set_collection_color (ESourceEteSync *extension,
+ const gchar *color)
{
g_return_if_fail (E_IS_SOURCE_ETESYNC (extension));
e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
- extension->priv->color = color;
+ if (e_util_strcmp0 (extension->priv->color, color) == 0) {
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+ return;
+ }
+
+ g_free (extension->priv->color);
+ extension->priv->color = e_util_strdup_strip (color);
e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
g_object_notify (G_OBJECT (extension), "color");
}
+
+const gchar *
+e_source_etesync_get_etebase_collection_b64 (ESourceEteSync *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
+
+ return extension->priv->etebase_collection_b64;
+}
+
+gchar *
+e_source_etesync_dup_etebase_collection_b64 (ESourceEteSync *extension)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (E_IS_SOURCE_ETESYNC (extension), NULL);
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ protected = e_source_etesync_get_etebase_collection_b64 (extension);
+ duplicate = g_strdup (protected);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ return duplicate;
+}
+
+void
+e_source_etesync_set_etebase_collection_b64 (ESourceEteSync *extension,
+ const gchar *etebase_collection_b64)
+{
+ g_return_if_fail (E_IS_SOURCE_ETESYNC (extension));
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ if (e_util_strcmp0 (extension->priv->etebase_collection_b64, etebase_collection_b64) == 0) {
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+ return;
+ }
+
+ g_free (extension->priv->etebase_collection_b64);
+ extension->priv->etebase_collection_b64 = e_util_strdup_strip (etebase_collection_b64);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ g_object_notify (G_OBJECT (extension), "etebase-collection");
+}
diff --git a/src/common/e-source-etesync.h b/src/common/e-source-etesync.h
index 8d291b3..fc80e3c 100644
--- a/src/common/e-source-etesync.h
+++ b/src/common/e-source-etesync.h
@@ -48,22 +48,34 @@ struct _ESourceEteSyncClass {
GType e_source_etesync_get_type (void) G_GNUC_CONST;
void e_source_etesync_type_register (GTypeModule *type_module);
-const gchar * e_source_etesync_get_journal_id (ESourceEteSync *extension);
-gchar * e_source_etesync_dup_journal_id (ESourceEteSync *extension);
-void e_source_etesync_set_journal_id (ESourceEteSync *extension,
- const gchar *journal_id);
-const gchar * e_source_etesync_get_journal_description
+const gchar * e_source_etesync_get_collection_id
(ESourceEteSync *extension);
-gchar * e_source_etesync_dup_journal_description
+gchar * e_source_etesync_dup_collection_id
(ESourceEteSync *extension);
-void e_source_etesync_set_journal_description
+void e_source_etesync_set_collection_id
+ (ESourceEteSync *extension,
+ const gchar *collection_id);
+const gchar * e_source_etesync_get_collection_description
+ (ESourceEteSync *extension);
+gchar * e_source_etesync_dup_collection_description
+ (ESourceEteSync *extension);
+void e_source_etesync_set_collection_description
(ESourceEteSync *extension,
const gchar *description);
-gint32 e_source_etesync_get_journal_color
+const gchar * e_source_etesync_get_collection_color
+ (ESourceEteSync *extension);
+gchar * e_source_etesync_dup_collection_color
+ (ESourceEteSync *extension);
+void e_source_etesync_set_collection_color
+ (ESourceEteSync *extension,
+ const gchar *color);
+const gchar * e_source_etesync_get_etebase_collection_b64
+ (ESourceEteSync *extension);
+gchar * e_source_etesync_dup_etebase_collection_b64
(ESourceEteSync *extension);
-void e_source_etesync_set_journal_color
+void e_source_etesync_set_etebase_collection_b64
(ESourceEteSync *extension,
- const gint32 color);
+ const gchar *etebase_collection_b64);
G_END_DECLS
#endif /* E_SOURCE_ETESYNC_H */
diff --git a/src/credentials/CMakeLists.txt b/src/credentials/CMakeLists.txt
index 36c0860..91405e8 100644
--- a/src/credentials/CMakeLists.txt
+++ b/src/credentials/CMakeLists.txt
@@ -1,7 +1,5 @@
set(extra_deps)
set(sources
- e-etesync-service.h
- e-etesync-service.c
e-credentials-prompter-impl-etesync.c
e-credentials-prompter-impl-etesync.h
e-source-credentials-provider-impl-etesync.c
diff --git a/src/credentials/e-credentials-prompter-impl-etesync.c
b/src/credentials/e-credentials-prompter-impl-etesync.c
index ca6cd4e..d830e9c 100644
--- a/src/credentials/e-credentials-prompter-impl-etesync.c
+++ b/src/credentials/e-credentials-prompter-impl-etesync.c
@@ -13,15 +13,6 @@
#include "common/e-etesync-defines.h"
#include "common/e-etesync-connection.h"
-typedef enum {
- TYPE_NO_ERROR,
- TYPE_NO_PASSWORD,
- TYPE_NO_ENCRYPTION_PASSWORD,
- TYPE_WRONG_PASSWORD,
- TYPE_WRONG_ENCRYPTION_PASSWORD,
- TYPE_NEW_ACCOUNT
-} DialogErrorType;
-
struct _ECredentialsPrompterImplEteSyncPrivate {
GMutex property_lock;
@@ -33,8 +24,6 @@ struct _ECredentialsPrompterImplEteSyncPrivate {
GtkDialog *dialog;
gulong show_dialog_idle_id;
-
- DialogErrorType dialog_error;
};
G_DEFINE_DYNAMIC_TYPE_EXTENDED (
@@ -49,7 +38,6 @@ typedef struct {
EEteSyncConnection *connection;
gchar *username;
gchar *password;
- gchar *encryption_password;
gchar *server_url;
gboolean out_success;
} AuthenticationData;
@@ -77,7 +65,6 @@ cpi_etesync_token_thread_data_free (gpointer user_data)
e_weak_ref_free (data->prompter_etesync);
g_free (data->username);
g_free (data->password);
- g_free (data->encryption_password);
g_free (data->server_url);
g_slice_free (AuthenticationData, data);
}
@@ -96,27 +83,14 @@ cpi_etesync_get_token_set_credentials_thread (GTask *task,
prompter_etesync = g_weak_ref_get (data->prompter_etesync);
- data->out_success = data->username && data->password &&
- e_etesync_connection_set_connection (data->connection,
- data->username,
- data->password,
- data->encryption_password,
- data->server_url,
- NULL);
-
- if (prompter_etesync->priv->dialog_error == TYPE_NEW_ACCOUNT) {
- data->out_success = e_etesync_connection_get_derived_key (data->connection) ?
- e_etesync_connection_init_userinfo (data->connection) : FALSE;
- }
+ data->out_success = data->username && *data->username && data->password && *data->password &&
+ e_etesync_connection_login_connection_sync (data->connection,
+ data->username,
+ data->password,
+ data->server_url,
+ NULL);
if (prompter_etesync) {
-
- e_named_parameters_clear (prompter_etesync->priv->credentials);
- e_named_parameters_set (prompter_etesync->priv->credentials,
- E_SOURCE_CREDENTIAL_PASSWORD, data->password);
- e_named_parameters_set (prompter_etesync->priv->credentials,
- E_ETESYNC_CREDENTIAL_ENCRYPTION_PASSWORD, data->encryption_password);
-
g_clear_pointer (&prompter_etesync->priv->error_text, g_free);
if (!data->out_success) {
prompter_etesync->priv->error_text = g_strdup_printf (
@@ -124,9 +98,7 @@ cpi_etesync_get_token_set_credentials_thread (GTask *task,
data->username);
} else {
e_named_parameters_set (prompter_etesync->priv->credentials,
- E_ETESYNC_CREDENTIAL_TOKEN, e_etesync_connection_get_token
(data->connection));
- e_named_parameters_set (prompter_etesync->priv->credentials,
- E_ETESYNC_CREDENTIAL_DERIVED_KEY, e_etesync_connection_get_derived_key
(data->connection));
+ E_ETESYNC_CREDENTIAL_SESSION_KEY, e_etesync_connection_get_session_key
(data->connection));
}
}
g_clear_object (&prompter_etesync);
@@ -161,8 +133,7 @@ static void
credentials_prompter_impl_etesync_get_prompt_strings (ESourceRegistry *registry,
ESource *source,
gchar **prompt_title,
- GString **prompt_description,
- DialogErrorType dialog_error)
+ GString **prompt_description)
{
GString *description;
const gchar *message;
@@ -182,34 +153,8 @@ credentials_prompter_impl_etesync_get_prompt_strings (ESourceRegistry *registry,
message = _("EteSync account authentication request");
- switch (dialog_error) {
- case TYPE_NO_PASSWORD:
- g_string_append_printf (description,
- _("Please enter the password for account “%s”."), display_name);
- break;
- case TYPE_NO_ENCRYPTION_PASSWORD:
- g_string_append_printf (description,
- _("Please enter the encryption password for account “%s”."), display_name);
- break;
- case TYPE_WRONG_PASSWORD:
- g_string_append_printf (description,
- _("Wrong password!\n\nPlease enter the correct password for account “%s”."),
display_name);
- break;
- case TYPE_WRONG_ENCRYPTION_PASSWORD:
- g_string_append_printf (description,
- _("Wrong encryption password!\n\nPlease enter the correct encryption password
for account “%s”."), display_name);
- break;
- case TYPE_NEW_ACCOUNT:
- g_string_append_printf (description,
- _("Welcome to EteSync!\n\n"
- "Please set an encryption password below for account “%s”, and make sure you
got it right, "
- "as it can't be recovered if lost!"), display_name);
- break;
- default: /* generic account prompt */
- g_string_append_printf (description,
- _("Please enter the correct credentials for account “%s”."), display_name);
- break;
- }
+ g_string_append_printf (description,
+ _("Please enter the correct credentials for account “%s”."), display_name);
if (host_name != NULL) {
/* Translators: This is part of a credential prompt, constructing for example: "Please enter
the correct credentials for account “%s”.\n(host: hostname)" */
@@ -229,229 +174,6 @@ credentials_prompter_impl_etesync_get_prompt_strings (ESourceRegistry *registry,
g_free (host_name);
}
-static gboolean
-e_credentials_prompter_impl_etesync_show_new_account_dialog (ECredentialsPrompterImplEteSync
*prompter_etesync)
-{
- GtkWidget *dialog, *content_area, *widget;
- GtkGrid *grid;
- GtkEntry *encryption_password_entry1;
- GtkEntry *encryption_password_entry2;
- GtkToggleButton *remember_toggle = NULL;
- GtkWindow *dialog_parent;
- ECredentialsPrompter *prompter;
- gchar *title;
- GString *info_markup;
- gint row = 0;
- ESourceAuthentication *auth_extension = NULL;
- gboolean success, is_scratch_source = TRUE;
-
- g_return_val_if_fail (E_IS_CREDENTIALS_PROMPTER_IMPL_ETESYNC (prompter_etesync), FALSE);
- g_return_val_if_fail (prompter_etesync->priv->prompt_id != NULL, FALSE);
- g_return_val_if_fail (prompter_etesync->priv->dialog == NULL, FALSE);
-
- prompter = e_credentials_prompter_impl_get_credentials_prompter (E_CREDENTIALS_PROMPTER_IMPL
(prompter_etesync));
- g_return_val_if_fail (prompter != NULL, FALSE);
-
- dialog_parent = e_credentials_prompter_get_dialog_parent (prompter);
-
- credentials_prompter_impl_etesync_get_prompt_strings (
- e_credentials_prompter_get_registry (prompter),
- prompter_etesync->priv->auth_source, &title, &info_markup,
prompter_etesync->priv->dialog_error);
- if (prompter_etesync->priv->error_text && *prompter_etesync->priv->error_text) {
- gchar *escaped = g_markup_printf_escaped ("%s", prompter_etesync->priv->error_text);
-
- g_string_append_printf (info_markup, "\n\n%s", escaped);
- g_free (escaped);
- }
-
- dialog = gtk_dialog_new_with_buttons (title, dialog_parent, GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT,
- _("_Cancel"), GTK_RESPONSE_CANCEL,
- _("_OK"), GTK_RESPONSE_OK,
- NULL);
-
- prompter_etesync->priv->dialog = GTK_DIALOG (dialog);
- gtk_dialog_set_default_response (prompter_etesync->priv->dialog, GTK_RESPONSE_OK);
- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
- if (dialog_parent)
- gtk_window_set_transient_for (GTK_WINDOW (dialog), dialog_parent);
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
-
- content_area = gtk_dialog_get_content_area (prompter_etesync->priv->dialog);
-
- /* Override GtkDialog defaults */
- gtk_box_set_spacing (GTK_BOX (content_area), 12);
- gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
-
- grid = GTK_GRID (gtk_grid_new ());
- gtk_grid_set_column_spacing (grid, 12);
- gtk_grid_set_row_spacing (grid, 6);
-
- gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (grid), FALSE, TRUE, 0);
-
- /* Password Image */
- widget = gtk_image_new_from_icon_name ("dialog-password", GTK_ICON_SIZE_DIALOG);
- g_object_set (
- G_OBJECT (widget),
- "halign", GTK_ALIGN_START,
- "vexpand", TRUE,
- "valign", GTK_ALIGN_START,
- NULL);
-
- gtk_grid_attach (grid, widget, 0, row, 1, 1);
-
- /* Encryotion password Label */
- widget = gtk_label_new (NULL);
- gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
- gtk_label_set_markup (GTK_LABEL (widget), info_markup->str);
- g_object_set (
- G_OBJECT (widget),
- "hexpand", TRUE,
- "halign", GTK_ALIGN_FILL,
- "valign", GTK_ALIGN_CENTER,
- "width-chars", 60,
- "max-width-chars", 80,
- "xalign", 0.0,
- NULL);
-
- gtk_grid_attach (grid, widget, 1, row, 1, 1);
- row++;
-
- if (e_source_has_extension (prompter_etesync->priv->cred_source, E_SOURCE_EXTENSION_AUTHENTICATION)) {
- GDBusObject *dbus_object;
-
- dbus_object = e_source_ref_dbus_object (prompter_etesync->priv->cred_source);
- is_scratch_source = !dbus_object;
- g_clear_object (&dbus_object);
-
- auth_extension = e_source_get_extension (prompter_etesync->priv->cred_source,
E_SOURCE_EXTENSION_AUTHENTICATION);
- }
-
- /* Setting encryption password entry 1 */
- encryption_password_entry1 = GTK_ENTRY (gtk_entry_new ());
- gtk_entry_set_visibility (encryption_password_entry1, FALSE);
- gtk_entry_set_activates_default (encryption_password_entry1, TRUE);
- g_object_set (
- G_OBJECT (encryption_password_entry1),
- "hexpand", TRUE,
- "halign", GTK_ALIGN_FILL,
- NULL);
-
- gtk_grid_attach (grid, GTK_WIDGET (encryption_password_entry1), 1, row, 1, 1);
- row++;
-
- /* Setting encryption password entry 2 */
- encryption_password_entry2 = GTK_ENTRY (gtk_entry_new ());
- gtk_entry_set_visibility (encryption_password_entry2, FALSE);
- gtk_entry_set_activates_default (encryption_password_entry2, TRUE);
- g_object_set (
- G_OBJECT (encryption_password_entry2),
- "hexpand", TRUE,
- "halign", GTK_ALIGN_FILL,
- NULL);
-
- gtk_grid_attach (grid, GTK_WIDGET (encryption_password_entry2), 1, row, 1, 1);
- row++;
-
-
- if (encryption_password_entry1 && encryption_password_entry2) {
- widget = gtk_label_new_with_mnemonic (_("_Encryption Password:"));
- g_object_set (
- G_OBJECT (widget),
- "hexpand", FALSE,
- "vexpand", FALSE,
- "halign", GTK_ALIGN_END,
- "valign", GTK_ALIGN_CENTER,
- NULL);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), GTK_WIDGET (encryption_password_entry1));
- gtk_grid_attach (grid, widget, 0, row - 2, 1, 1);
-
- widget = gtk_label_new_with_mnemonic (_("Encryption _Password again:"));
- g_object_set (
- G_OBJECT (widget),
- "hexpand", FALSE,
- "vexpand", FALSE,
- "halign", GTK_ALIGN_END,
- "valign", GTK_ALIGN_CENTER,
- NULL);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), GTK_WIDGET (encryption_password_entry2));
- gtk_grid_attach (grid, widget, 0, row - 1, 1, 1);
- }
-
- if (auth_extension && !is_scratch_source) {
- /* Remember password check */
- widget = gtk_check_button_new_with_mnemonic (_("_Add this password to your keyring"));
- remember_toggle = GTK_TOGGLE_BUTTON (widget);
- gtk_toggle_button_set_active (remember_toggle, e_source_authentication_get_remember_password
(auth_extension));
- g_object_set (
- G_OBJECT (widget),
- "hexpand", TRUE,
- "halign", GTK_ALIGN_FILL,
- "valign", GTK_ALIGN_FILL,
- "margin-top", 12,
- NULL);
-
- gtk_grid_attach (grid, widget, 1, row, 1, 1);
- }
-
- g_signal_connect (dialog, "map-event", G_CALLBACK (etesync_dialog_map_event_cb),
encryption_password_entry1);
-
- gtk_widget_show_all (GTK_WIDGET (grid));
- success = gtk_dialog_run (prompter_etesync->priv->dialog) == GTK_RESPONSE_OK;
-
- g_mutex_lock (&prompter_etesync->priv->property_lock);
- if (success) {
- /* In this part we should have username, password, encryption_password
- We need to get token and derived key and store them */
- AuthenticationData *data;
- ESourceCollection *collection_extension;
- GTask *task;
-
- data = g_slice_new0 (AuthenticationData);
- data->connection = e_etesync_connection_new ();
- data->prompter_etesync = e_weak_ref_new (prompter_etesync);
-
- /* Need to set password and encryption as they are always stored to retrive proper error
message when dialog opens */
- data->password = g_strdup (e_named_parameters_get (prompter_etesync->priv->credentials,
E_SOURCE_CREDENTIAL_PASSWORD));
- data->encryption_password = g_strdup ("");
-
- if (!g_strcmp0 (gtk_entry_get_text (encryption_password_entry1),
- gtk_entry_get_text (encryption_password_entry2))) {
- collection_extension = e_source_get_extension (prompter_etesync->priv->cred_source,
E_SOURCE_EXTENSION_COLLECTION);
-
- g_free (data->encryption_password);
- data->encryption_password = g_strdup (gtk_entry_get_text
(encryption_password_entry1));
-
- data->username = e_source_authentication_dup_user (auth_extension);
- data->server_url = e_source_collection_dup_contacts_url (collection_extension);
-
- if (auth_extension && remember_toggle) {
- e_source_authentication_set_remember_password (auth_extension,
- gtk_toggle_button_get_active (remember_toggle));
- }
- }
-
- /* We must in either way invoke this thread, as in it's callback it calls finish,
- if encryption_password_entries didn't match, just send a dummy data (empty connection)
- which will fail and open another dialog */
- task = g_task_new (NULL, NULL, cpi_etesync_get_token_set_credentials_cb, prompter_etesync);
- g_task_set_task_data (task, data, cpi_etesync_token_thread_data_free);
- g_task_run_in_thread (task, cpi_etesync_get_token_set_credentials_thread);
- g_object_unref (task);
- }
- prompter_etesync->priv->dialog = NULL;
- g_mutex_unlock (&prompter_etesync->priv->property_lock);
-
- gtk_widget_destroy (dialog);
-
- g_string_free (info_markup, TRUE);
- g_free (title);
-
- return success;
-}
-
static gboolean
e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompterImplEteSync
*prompter_etesync)
{
@@ -459,7 +181,6 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
GtkGrid *grid;
GtkEntry *username_entry = NULL;
GtkEntry *password_entry;
- GtkEntry *encryption_password_entry;
GtkToggleButton *remember_toggle = NULL;
GtkWindow *dialog_parent;
ECredentialsPrompter *prompter;
@@ -480,7 +201,7 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
credentials_prompter_impl_etesync_get_prompt_strings (
e_credentials_prompter_get_registry (prompter),
- prompter_etesync->priv->auth_source, &title, &info_markup,
prompter_etesync->priv->dialog_error);
+ prompter_etesync->priv->auth_source, &title, &info_markup);
if (prompter_etesync->priv->error_text && *prompter_etesync->priv->error_text) {
gchar *escaped = g_markup_printf_escaped ("%s", prompter_etesync->priv->error_text);
@@ -509,7 +230,7 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
grid = GTK_GRID (gtk_grid_new ());
gtk_grid_set_column_spacing (grid, 12);
- gtk_grid_set_row_spacing (grid, 7);
+ gtk_grid_set_row_spacing (grid, 6);
gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (grid), FALSE, TRUE, 0);
@@ -597,29 +318,11 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
"hexpand", TRUE,
"halign", GTK_ALIGN_FILL,
NULL);
- if (e_named_parameters_get (prompter_etesync->priv->credentials, E_SOURCE_CREDENTIAL_PASSWORD))
- gtk_entry_set_text (password_entry, e_named_parameters_get
(prompter_etesync->priv->credentials, E_SOURCE_CREDENTIAL_PASSWORD));
gtk_grid_attach (grid, GTK_WIDGET (password_entry), 1, row, 1, 1);
row++;
- /* Setting encryption_password entry */
- encryption_password_entry = GTK_ENTRY (gtk_entry_new ());
- gtk_entry_set_visibility (encryption_password_entry, FALSE);
- gtk_entry_set_activates_default (encryption_password_entry, TRUE);
- g_object_set (
- G_OBJECT (encryption_password_entry),
- "hexpand", TRUE,
- "halign", GTK_ALIGN_FILL,
- NULL);
- if (e_named_parameters_get (prompter_etesync->priv->credentials,
E_ETESYNC_CREDENTIAL_ENCRYPTION_PASSWORD))
- gtk_entry_set_text (encryption_password_entry, e_named_parameters_get
(prompter_etesync->priv->credentials, E_ETESYNC_CREDENTIAL_ENCRYPTION_PASSWORD));
-
- gtk_grid_attach (grid, GTK_WIDGET (encryption_password_entry), 1, row, 1, 1);
- row++;
-
-
- if (username_entry && password_entry && encryption_password_entry) {
+ if (username_entry && password_entry) {
widget = gtk_label_new_with_mnemonic (_("_User Name:"));
g_object_set (
G_OBJECT (widget),
@@ -630,7 +333,7 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
NULL);
gtk_label_set_mnemonic_widget (GTK_LABEL (widget), GTK_WIDGET (username_entry));
- gtk_grid_attach (grid, widget, 0, row - 3, 1, 1);
+ gtk_grid_attach (grid, widget, 0, row - 2, 1, 1);
widget = gtk_label_new_with_mnemonic (_("_Password:"));
g_object_set (
@@ -642,18 +345,6 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
NULL);
gtk_label_set_mnemonic_widget (GTK_LABEL (widget), GTK_WIDGET (password_entry));
- gtk_grid_attach (grid, widget, 0, row - 2, 1, 1);
-
- widget = gtk_label_new_with_mnemonic (_("_Encryption Password:"));
- g_object_set (
- G_OBJECT (widget),
- "hexpand", FALSE,
- "vexpand", FALSE,
- "halign", GTK_ALIGN_END,
- "valign", GTK_ALIGN_CENTER,
- NULL);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), GTK_WIDGET (encryption_password_entry));
gtk_grid_attach (grid, widget, 0, row - 1, 1, 1);
}
@@ -673,20 +364,15 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
gtk_grid_attach (grid, widget, 1, row, 1, 1);
}
- if (username_entry && g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (username_entry)), "") == 0)
- g_signal_connect (dialog, "map-event", G_CALLBACK (etesync_dialog_map_event_cb),
username_entry);
- else if (prompter_etesync->priv->dialog_error == TYPE_NO_PASSWORD ||
prompter_etesync->priv->dialog_error == TYPE_WRONG_PASSWORD)
- g_signal_connect (dialog, "map-event", G_CALLBACK (etesync_dialog_map_event_cb),
password_entry);
- else if (prompter_etesync->priv->dialog_error == TYPE_NO_ENCRYPTION_PASSWORD ||
prompter_etesync->priv->dialog_error == TYPE_WRONG_ENCRYPTION_PASSWORD)
- g_signal_connect (dialog, "map-event", G_CALLBACK (etesync_dialog_map_event_cb),
encryption_password_entry);
+ g_signal_connect (dialog, "map-event", G_CALLBACK (etesync_dialog_map_event_cb), password_entry);
gtk_widget_show_all (GTK_WIDGET (grid));
success = gtk_dialog_run (prompter_etesync->priv->dialog) == GTK_RESPONSE_OK;
g_mutex_lock (&prompter_etesync->priv->property_lock);
if (success) {
- /* In this part we should have username, password, encryption_password
- We need to get token and derived key and store them */
+ /* In this part we should have username, password
+ We need to get session key and store it */
AuthenticationData *data;
ESourceCollection *collection_extension;
GTask *task;
@@ -695,10 +381,9 @@ e_credentials_prompter_impl_etesync_show_credentials_dialog (ECredentialsPrompte
data = g_slice_new0 (AuthenticationData);
data->prompter_etesync = e_weak_ref_new (prompter_etesync);
- data->connection = e_etesync_connection_new ();
+ data->connection = e_etesync_connection_new (prompter_etesync->priv->cred_source);
data->username = g_strdup (gtk_entry_get_text (username_entry));
data->password = g_strdup (gtk_entry_get_text (password_entry));
- data->encryption_password = g_strdup (gtk_entry_get_text (encryption_password_entry));
data->server_url = g_strdup (e_source_collection_get_contacts_url (collection_extension));
task = g_task_new (NULL, NULL, cpi_etesync_get_token_set_credentials_cb, prompter_etesync);
@@ -741,10 +426,7 @@ e_credentials_prompter_impl_etesync_show_dialog_idle_cb (gpointer user_data)
g_warn_if_fail (prompter_etesync->priv->dialog == NULL);
- if (prompter_etesync->priv->dialog_error == TYPE_NEW_ACCOUNT)
- success = e_credentials_prompter_impl_etesync_show_new_account_dialog
(prompter_etesync);
- else
- success = e_credentials_prompter_impl_etesync_show_credentials_dialog
(prompter_etesync);
+ success = e_credentials_prompter_impl_etesync_show_credentials_dialog (prompter_etesync);
if (!success) {
e_credentials_prompter_impl_prompt_finish (
@@ -777,51 +459,51 @@ cpi_etesync_set_dialog_error_thread (GTask *task,
GCancellable *cancellable)
{
ECredentialsPrompterImplEteSync *prompter_etesync = task_data;
- ESourceCollection *collection_extension;
- ESourceAuthentication *auth_extension;
EEteSyncConnection *connection = NULL;
- const gchar *username, *password = NULL, *encryption_password = NULL, *server_url;
+ const gchar *username, *password = NULL, *server_url;
gboolean success = FALSE;
- EteSyncErrorCode etesync_error = ETESYNC_ERROR_CODE_NO_ERROR;
+ EtebaseErrorCode etebase_error = ETEBASE_ERROR_CODE_NO_ERROR;
- collection_extension = e_source_get_extension (prompter_etesync->priv->cred_source,
E_SOURCE_EXTENSION_COLLECTION);
- auth_extension = e_source_get_extension (prompter_etesync->priv->cred_source,
E_SOURCE_EXTENSION_AUTHENTICATION);
+ connection = e_etesync_connection_new (prompter_etesync->priv->cred_source);
- connection = e_etesync_connection_new ();
- username = e_source_authentication_get_user (auth_extension);
- server_url = e_source_collection_get_contacts_url (collection_extension);
- password = e_named_parameters_get (prompter_etesync->priv->credentials, E_SOURCE_CREDENTIAL_PASSWORD);
- encryption_password = e_named_parameters_get (prompter_etesync->priv->credentials,
E_ETESYNC_CREDENTIAL_ENCRYPTION_PASSWORD);
+ /* We don't store E_SOURCE_CREDENTIAL_PASSWORD normally, it only happens the first time after the
+ user adds his/her account, then we store in the credentials the E_ETESYNC_CREDENTIAL_SESSION_KEY
+ so if E_SOURCE_CREDENTIAL_PASSWORD exist, then this is the first time, so we need to use it to get
session key
+ without showing the dialog and asking for the password again */
+ if (e_named_parameters_exists (prompter_etesync->priv->credentials,
E_ETESYNC_CREDENTIAL_SESSION_KEY)) {
+ if (e_etesync_connection_set_connection_from_sources (connection,
prompter_etesync->priv->credentials)) {
+ EtebaseAccount* etebase_account;
- if (!password || !*password) {
- prompter_etesync->priv->dialog_error = TYPE_NO_PASSWORD;
- } else {
- success = e_etesync_connection_set_connection (connection, username, password,
encryption_password, server_url, &etesync_error);
-
- switch (etesync_error) {
- case ETESYNC_ERROR_CODE_HTTP:
- case ETESYNC_ERROR_CODE_UNAUTHORIZED:
- prompter_etesync->priv->dialog_error = TYPE_WRONG_PASSWORD;
- break;
- case ETESYNC_ERROR_CODE_ENCRYPTION_MAC:
- prompter_etesync->priv->dialog_error = TYPE_WRONG_ENCRYPTION_PASSWORD;
- break;
- case ETESYNC_ERROR_CODE_NOT_FOUND:
- prompter_etesync->priv->dialog_error = TYPE_NEW_ACCOUNT;
- break;
- default:
- prompter_etesync->priv->dialog_error = !encryption_password ||
!*encryption_password ? TYPE_NO_ENCRYPTION_PASSWORD : TYPE_NO_ERROR;
- break;
+ etebase_account = e_etesync_connection_get_etebase_account (connection);
+ success = !etebase_account_fetch_token (etebase_account);
+
+ if (success) {
+ gchar* new_session_key = etebase_account_save (etebase_account, NULL, 0);
+
+ e_etesync_connection_set_session_key (connection, new_session_key);
+ g_free (new_session_key);
+ }
}
+ } else if (e_named_parameters_exists (prompter_etesync->priv->credentials,
E_SOURCE_CREDENTIAL_PASSWORD)) {
+ ESourceCollection *collection_extension;
+ ESourceAuthentication *auth_extension;
+
+ collection_extension = e_source_get_extension (prompter_etesync->priv->cred_source,
E_SOURCE_EXTENSION_COLLECTION);
+ auth_extension = e_source_get_extension (prompter_etesync->priv->cred_source,
E_SOURCE_EXTENSION_AUTHENTICATION);
+
+ username = e_source_authentication_get_user (auth_extension);
+ server_url = e_source_collection_get_contacts_url (collection_extension);
+ password = e_named_parameters_get (prompter_etesync->priv->credentials,
E_SOURCE_CREDENTIAL_PASSWORD);
+ success = e_etesync_connection_login_connection_sync (connection, username, password,
server_url, &etebase_error);
}
- if (success)
+ if (success) {
g_task_return_pointer (task, g_object_ref (connection), (GDestroyNotify) g_object_unref);
- else {
- /* Since there was a problem error, and we got a token then invalidate that token
+ } else {
+ /* Since there was a problem error, and we got a session-key then invalidate that session-key
Because will get a new one after the user enters the data, as this one will be lost. */
- if (e_etesync_connection_get_token (connection))
- etesync_auth_invalidate_token (e_etesync_connection_get_etesync (connection),
e_etesync_connection_get_token (connection));
+ if (e_etesync_connection_get_etebase_account (connection))
+ etebase_account_logout (e_etesync_connection_get_etebase_account (connection));
g_task_return_pointer (task, NULL, NULL);
}
@@ -843,11 +525,10 @@ cpi_etesync_set_dialog_error_cb (GObject *source,
/* if there is an error then pop the dialog to the user,
if not then the credentials are ok, but need to add new token only */
- if (prompter_etesync->priv->dialog_error == TYPE_NO_ERROR && connection){
- e_named_parameters_set (prompter_etesync->priv->credentials,
- E_ETESYNC_CREDENTIAL_TOKEN, e_etesync_connection_get_token (connection));
+ if (connection){
+ e_named_parameters_clear (prompter_etesync->priv->credentials);
e_named_parameters_set (prompter_etesync->priv->credentials,
- E_ETESYNC_CREDENTIAL_DERIVED_KEY, e_etesync_connection_get_derived_key
(connection));
+ E_ETESYNC_CREDENTIAL_SESSION_KEY, e_etesync_connection_get_session_key
(connection));
cpi_etesync_get_token_set_credentials_cb (NULL, NULL, prompter_etesync);
} else {
@@ -856,11 +537,11 @@ cpi_etesync_set_dialog_error_cb (GObject *source,
prompter_etesync);
}
+ g_mutex_unlock (&prompter_etesync->priv->property_lock);
+
g_object_unref (prompter_etesync);
if (connection)
g_object_unref (connection);
-
- g_mutex_unlock (&prompter_etesync->priv->property_lock);
}
static void
diff --git a/src/credentials/e-source-credentials-provider-impl-etesync.c
b/src/credentials/e-source-credentials-provider-impl-etesync.c
index d2467c5..9c49af1 100644
--- a/src/credentials/e-source-credentials-provider-impl-etesync.c
+++ b/src/credentials/e-source-credentials-provider-impl-etesync.c
@@ -10,7 +10,7 @@
#include <glib/gi18n-lib.h>
#include "e-source-credentials-provider-impl-etesync.h"
-#include "e-etesync-service.h"
+#include "common/e-etesync-service.h"
#include "common/e-etesync-defines.h"
struct _ESourceCredentialsProviderImplEteSyncPrivate {
@@ -160,9 +160,10 @@ e_source_credentials_provider_impl_etesync_lookup_sync (ESourceCredentialsProvid
}
/* This means that this is the first time for authentication
- in which we haven't yet stored the credentials as NamedParameters
- so we have to retrieve the password as text */
- if (e_named_parameters_count (*out_credentials) == 1) {
+ in which we haven't yet stored the credentials as NamedParameters.
+ So we have to retrieve the password as text, we check if session key exists.
+ Ss normally we don't store the password itself in the NamedParameters */
+ if (!e_named_parameters_exists (*out_credentials, E_ETESYNC_CREDENTIAL_SESSION_KEY)) {
gchar *out_password = NULL;
e_named_parameters_clear (*out_credentials);
@@ -189,8 +190,6 @@ e_source_credentials_provider_impl_etesync_store_sync (ESourceCredentialsProvide
g_return_val_if_fail (E_IS_SOURCE_CREDENTIALS_PROVIDER_IMPL_ETESYNC (provider_impl), FALSE);
g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
g_return_val_if_fail (credentials != NULL, FALSE);
- g_return_val_if_fail (e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_PASSWORD) != NULL,
FALSE);
- g_return_val_if_fail (e_named_parameters_get (credentials, E_ETESYNC_CREDENTIAL_ENCRYPTION_PASSWORD)
!= NULL, FALSE);
return e_source_cpi_etesync_store_credentials_sync (source, credentials ,permanently, cancellable,
error);
}
diff --git a/src/evolution/e-book-config-etesync.c b/src/evolution/e-book-config-etesync.c
index dfe0ea2..6c84a12 100644
--- a/src/evolution/e-book-config-etesync.c
+++ b/src/evolution/e-book-config-etesync.c
@@ -8,6 +8,11 @@
#include "evolution-etesync-config.h"
#include "e-book-config-etesync.h"
+#include "common/e-etesync-connection.h"
+#include "common/e-etesync-service.h"
+#include "common/e-etesync-utils.h"
+#include "common/e-etesync-defines.h"
+#include "common/e-source-etesync.h"
G_DEFINE_DYNAMIC_TYPE (
EBookConfigEteSync,
@@ -30,6 +35,63 @@ book_config_etesync_insert_widgets (ESourceConfigBackend *backend,
e_source_config_add_refresh_interval (e_source_config_backend_get_config (backend), scratch_source);
}
+static void
+book_config_etesync_commit_changes (ESourceConfigBackend *backend,
+ ESource *scratch_source)
+{
+ ESource *collection_source;
+ ESourceConfig *config;
+
+ config = e_source_config_backend_get_config (backend);
+ collection_source = e_source_config_get_collection_source (config);
+
+ /* Get collection source */
+ if (collection_source) {
+ EEteSyncConnection *connection;
+ ENamedParameters *credentials = NULL;
+ const gchar *collection_uid;
+
+ collection_uid = e_source_get_uid (collection_source);
+ connection = e_etesync_connection_new (collection_source);
+
+ /* Get credentials and Set connection object */
+ if (e_etesync_service_lookup_credentials_sync (collection_uid, &credentials, NULL, NULL) &&
+ e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK) &&
+ e_etesync_connection_set_connection_from_sources (connection, credentials)) {
+ ESourceEteSync *etesync_extension;
+ gchar *display_name = NULL;
+ EtebaseCollection *col_obj;
+ EtebaseCollectionManager *col_mgr;
+
+ col_mgr = e_etesync_connection_get_collection_manager (connection);
+ display_name = e_source_dup_display_name (scratch_source);
+ etesync_extension = e_source_get_extension (scratch_source,
E_SOURCE_EXTENSION_ETESYNC);
+ col_obj = e_etesync_utils_etebase_collection_from_base64 (
+ e_source_etesync_get_etebase_collection_b64
(etesync_extension),
+ col_mgr);
+
+ /* push modification to server */
+ if (e_etesync_connection_collection_modify_upload_sync (connection,
+ col_obj,
+ display_name,
+ NULL,
+ NULL,
+ NULL)) {
+ e_source_etesync_set_etebase_collection_b64 (
+ etesync_extension,
+ e_etesync_utils_etebase_collection_to_base64
(col_obj, col_mgr));
+ }
+
+ etebase_collection_destroy (col_obj);
+ g_free (display_name);
+ }
+
+ g_object_unref (connection);
+ g_clear_object (&collection_source);
+ e_named_parameters_free (credentials);
+ }
+}
+
static void
e_book_config_etesync_class_init (EBookConfigEteSyncClass *class)
{
@@ -43,6 +105,7 @@ e_book_config_etesync_class_init (EBookConfigEteSyncClass *class)
backend_class->backend_name = "etesync";
backend_class->allow_creation = book_config_etesync_allow_creation;
backend_class->insert_widgets = book_config_etesync_insert_widgets;
+ backend_class->commit_changes = book_config_etesync_commit_changes;
}
static void
diff --git a/src/evolution/e-cal-config-etesync.c b/src/evolution/e-cal-config-etesync.c
index 7065171..f29952f 100644
--- a/src/evolution/e-cal-config-etesync.c
+++ b/src/evolution/e-cal-config-etesync.c
@@ -8,6 +8,11 @@
#include "evolution-etesync-config.h"
#include "e-cal-config-etesync.h"
+#include "common/e-etesync-connection.h"
+#include "common/e-etesync-service.h"
+#include "common/e-etesync-utils.h"
+#include "common/e-etesync-defines.h"
+#include "common/e-source-etesync.h"
G_DEFINE_DYNAMIC_TYPE (
ECalConfigEteSync,
@@ -50,6 +55,89 @@ cal_config_etesync_insert_widgets (ESourceConfigBackend *backend,
e_source_config_add_refresh_interval (e_source_config_backend_get_config (backend), scratch_source);
}
+static void
+cal_config_etesync_commit_changes (ESourceConfigBackend *backend,
+ ESource *scratch_source)
+{
+ ESource *collection_source;
+ ESourceConfig *config;
+
+ config = e_source_config_backend_get_config (backend);
+ collection_source = e_source_config_get_collection_source (config);
+
+ /* Get collection source */
+ if (collection_source) {
+ EEteSyncConnection *connection;
+ ENamedParameters *credentials = NULL;
+ const gchar *collection_uid;
+
+ collection_uid = e_source_get_uid (collection_source);
+ connection = e_etesync_connection_new (collection_source);
+
+ /* Get credentials and set connection object */
+ if (e_etesync_service_lookup_credentials_sync (collection_uid, &credentials, NULL, NULL) &&
+ e_etesync_connection_set_connection_from_sources (connection, credentials)) {
+ const gchar *extension_name = NULL;
+ const gchar *col_type = NULL;
+
+ if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_CALENDAR)) {
+ extension_name = E_SOURCE_EXTENSION_CALENDAR;
+ col_type = E_ETESYNC_COLLECTION_TYPE_CALENDAR;
+ }
+
+ if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_TASK_LIST)) {
+ extension_name = E_SOURCE_EXTENSION_TASK_LIST;
+ col_type = E_ETESYNC_COLLECTION_TYPE_TASKS;
+ }
+
+ if (col_type) {
+ ESourceBackend *source_backend;
+ ESourceEteSync *etesync_extension;
+ gchar *display_name = NULL;
+ gchar *color = g_strdup (E_ETESYNC_COLLECTION_DEFAULT_COLOR);
+ const gchar *source_color = NULL;
+ EtebaseCollection *col_obj;
+ EtebaseCollectionManager *col_mgr;
+
+ display_name = e_source_dup_display_name (scratch_source);
+ source_backend = e_source_get_extension (scratch_source, extension_name);
+ source_color = e_source_selectable_get_color (E_SOURCE_SELECTABLE
(source_backend));
+ col_mgr = e_etesync_connection_get_collection_manager (connection);
+
+ if (source_color) {
+ g_free (color);
+ color = g_strdup (source_color);
+ }
+
+ etesync_extension = e_source_get_extension (scratch_source,
E_SOURCE_EXTENSION_ETESYNC);
+ col_obj = e_etesync_utils_etebase_collection_from_base64 (
+ e_source_etesync_get_etebase_collection_b64
(etesync_extension),
+ col_mgr);
+
+ /* push modification to server */
+ if (e_etesync_connection_collection_modify_upload_sync (connection,
+ col_obj,
+ display_name,
+ NULL,
+ color,
+ NULL)) {
+ e_source_etesync_set_etebase_collection_b64 (
+ etesync_extension,
+ e_etesync_utils_etebase_collection_to_base64
(col_obj, col_mgr));
+ }
+
+ etebase_collection_destroy (col_obj);
+ g_free (display_name);
+ g_free (color);
+ }
+ }
+
+ g_object_unref (connection);
+ g_clear_object (&collection_source);
+ e_named_parameters_free (credentials);
+ }
+}
+
static void
e_cal_config_etesync_class_init (ECalConfigEteSyncClass *class)
{
@@ -63,6 +151,7 @@ e_cal_config_etesync_class_init (ECalConfigEteSyncClass *class)
backend_class->backend_name = "etesync";
backend_class->allow_creation = cal_config_etesync_allow_creation;
backend_class->insert_widgets = cal_config_etesync_insert_widgets;
+ backend_class->commit_changes = cal_config_etesync_commit_changes;
}
static void
diff --git a/src/evolution/e-etesync-config-lookup.c b/src/evolution/e-etesync-config-lookup.c
index 4e47d74..e09215e 100644
--- a/src/evolution/e-etesync-config-lookup.c
+++ b/src/evolution/e-etesync-config-lookup.c
@@ -9,8 +9,11 @@
#include <glib/gi18n-lib.h>
#include <e-util/e-util.h>
+#include "common/e-etesync-defines.h"
+#include "common/e-etesync-connection.h"
+#include "common/e-etesync-utils.h"
#include "e-etesync-config-lookup.h"
-#include <etesync.h>
+#include <etebase.h>
/* Standard GObject macros */
#define E_TYPE_ETESYNC_CONFIG_LOOKUP \
@@ -97,9 +100,9 @@ etesync_config_lookup_worker_result (EConfigLookupWorker *lookup_worker,
"calendar-url", servers);
} else {
e_config_lookup_result_simple_add_string (lookup_result, E_SOURCE_EXTENSION_COLLECTION,
- "contacts-url", etesync_get_server_url ());
+ "contacts-url", etebase_get_default_server_url ());
e_config_lookup_result_simple_add_string (lookup_result, E_SOURCE_EXTENSION_COLLECTION,
- "calendar-url", etesync_get_server_url ());
+ "calendar-url", etebase_get_default_server_url ());
}
e_config_lookup_add_result (config_lookup, lookup_result);
@@ -110,55 +113,69 @@ etesync_config_lookup_discover (const ENamedParameters *params,
GError **error)
{
gboolean success = TRUE;
- const gchar *email_address, *server_url;
- EteSync *etesync = NULL;
+ const gchar *email_address, *server_url, *default_server_url;
+ EtebaseClient *etebase_client;
email_address = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_EMAIL_ADDRESS);
server_url = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_SERVERS);
+ default_server_url = etebase_get_default_server_url ();
if (!email_address)
return FALSE;
- etesync = etesync_new (PACKAGE "/" VERSION, server_url && *server_url ? server_url :
etesync_get_server_url ());
+ if (!server_url || !*server_url)
+ server_url = default_server_url;
- if (etesync) {
- if (!e_named_parameters_exists (params, E_CONFIG_LOOKUP_PARAM_PASSWORD)) {
+ etebase_client = etebase_client_new (PACKAGE "/" VERSION, server_url);
+
+ if (etebase_client) {
+ gint32 etebase_server_check = 0;
+
+ if (!g_str_equal (server_url, default_server_url))
+ etebase_server_check = etebase_client_check_etebase_server (etebase_client);
+
+ /* Returns 0 if client is pointing an etebase server, 1 if not, -1 on error */
+ if (etebase_server_check != 0) {
+ if (etebase_server_check == 1)
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Etebase server
not found."));
+ else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed
connecting to server."));
+ success = FALSE;
+
+ } else if (!e_named_parameters_exists (params, E_CONFIG_LOOKUP_PARAM_PASSWORD)) {
g_set_error_literal (error, E_CONFIG_LOOKUP_WORKER_ERROR,
E_CONFIG_LOOKUP_WORKER_ERROR_REQUIRES_PASSWORD,
_("Requires password to continue."));
success = FALSE;
} else {
+ EtebaseErrorCode etebase_error;
+ EEteSyncConnection *connection;
const gchar *password;
- gchar *token = NULL;
+ connection = e_etesync_connection_new (NULL);
password = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_PASSWORD);
- token = etesync_auth_get_token(etesync, email_address, password);
- if (!token || !*token) {
- EteSyncErrorCode etesync_error;
- const gchar *error_message;
+ if (e_etesync_connection_login_connection_sync (connection, email_address, password,
server_url, &etebase_error)) {
- etesync_error = etesync_get_error_code ();
- success = FALSE;
+ /* The connection was successfully set, but need to check permession denied
error using token valid */
+ if (e_etesync_connection_check_session_key_validation_sync (connection,
&etebase_error, NULL) != E_SOURCE_AUTHENTICATION_ACCEPTED)
+ success = FALSE;
- switch (etesync_error) {
- case ETESYNC_ERROR_CODE_HTTP:
- case ETESYNC_ERROR_CODE_CONNECTION:
- error_message = server_url ? _("Wrong username, password or
server.") : _("Wrong username or password.");
- break;
- default:
- error_message = etesync_get_error_message ();
- break;
- }
-
- g_set_error_literal (error, E_CONFIG_LOOKUP_WORKER_ERROR,
E_CONFIG_LOOKUP_WORKER_ERROR_REQUIRES_PASSWORD, error_message);
+ etebase_account_logout (e_etesync_connection_get_etebase_account
(connection));
} else
- etesync_auth_invalidate_token (etesync, token);
+ success = FALSE;
+
+ if (!success) {
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED)
+ g_set_error_literal (error, E_CONFIG_LOOKUP_WORKER_ERROR,
E_CONFIG_LOOKUP_WORKER_ERROR_REQUIRES_PASSWORD, etebase_error_get_message ());
+ else
+ e_etesync_utils_set_io_gerror (etebase_error,
etebase_error_get_message (), error);
+ }
- g_free (token);
+ g_object_unref (connection);
}
- etesync_destroy(etesync);
+ etebase_client_destroy (etebase_client);
} else {
if (server_url) {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
diff --git a/src/registry/e-etesync-backend.c b/src/registry/e-etesync-backend.c
index 3f0bf53..d2d4423 100644
--- a/src/registry/e-etesync-backend.c
+++ b/src/registry/e-etesync-backend.c
@@ -7,12 +7,19 @@
#include "evolution-etesync-config.h"
-#include <etesync.h>
+#include <etebase.h>
#include "e-etesync-backend.h"
#include "common/e-source-etesync.h"
+#include "common/e-source-etesync-account.h"
#include "common/e-etesync-connection.h"
#include "common/e-etesync-defines.h"
+#include "common/e-etesync-service.h"
+#include "common/e-etesync-utils.h"
+
+static gulong source_removed_handler_id = 0;
+static gint backend_count = 0;
+G_LOCK_DEFINE_STATIC (backend_count);
struct _EEteSyncBackendPrivate {
EEteSyncConnection *connection;
@@ -31,7 +38,7 @@ etesync_backend_dup_resource_id (ECollectionBackend *backend,
extension_name = E_SOURCE_EXTENSION_ETESYNC;
extension = e_source_get_extension (child_source, extension_name);
- return e_source_etesync_dup_journal_id (extension);
+ return e_source_etesync_dup_collection_id (extension);
}
static void
@@ -117,64 +124,72 @@ etesync_backend_populate (ECollectionBackend *backend)
static ESource *
etesync_backend_new_child (EEteSyncBackend *backend,
- EteSyncJournal *journal,
- EteSyncCollectionInfo *info)
+ const EtebaseCollection *col_obj,
+ EtebaseItemMetadata *item_metadata)
{
ECollectionBackend *collection_backend;
ESourceExtension *extension;
ESourceBackend *source_backend;
ESource *source;
- gchar *journal_uid, *display_name, *type, *description;
+ gchar *col_obj_b64 = NULL, *type = NULL;
+ const gchar *collection_uid, *display_name, *description, *color;
const gchar *extension_name;
- gint32 color;
- journal_uid = etesync_journal_get_uid (journal);
- display_name = etesync_collection_info_get_display_name (info);
- type = etesync_collection_info_get_type (info);
- description = etesync_collection_info_get_description (info);
- color = etesync_collection_info_get_color (info);
+ collection_uid = etebase_collection_get_uid (col_obj);
+ type = etebase_collection_get_collection_type (col_obj);
+ display_name = etebase_item_metadata_get_name (item_metadata);
+ description = etebase_item_metadata_get_description (item_metadata);
+ color = etebase_item_metadata_get_color (item_metadata);
collection_backend = E_COLLECTION_BACKEND (backend);
- source = e_collection_backend_new_child (collection_backend, journal_uid);
+ source = e_collection_backend_new_child (collection_backend, collection_uid);
e_source_set_display_name (source, display_name);
- if (g_str_equal (type, ETESYNC_COLLECTION_TYPE_CALENDAR)) {
+ if (g_str_equal (type, E_ETESYNC_COLLECTION_TYPE_CALENDAR)) {
extension_name = E_SOURCE_EXTENSION_CALENDAR;
- } else if (g_str_equal (type, ETESYNC_COLLECTION_TYPE_TASKS)) {
+ } else if (g_str_equal (type, E_ETESYNC_COLLECTION_TYPE_TASKS)) {
extension_name = E_SOURCE_EXTENSION_TASK_LIST;
- } else if (g_str_equal (type, ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK)) {
+ } else if (g_str_equal (type, E_ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK)) {
extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
} else {
g_object_unref (source);
- g_return_val_if_reached (NULL);
+ return NULL;
}
extension = e_source_get_extension (source, extension_name);
source_backend = E_SOURCE_BACKEND (extension);
+ col_obj_b64 = e_etesync_utils_etebase_collection_to_base64 (
+ col_obj,
+ e_etesync_connection_get_collection_manager
(backend->priv->connection));
e_source_backend_set_backend_name (source_backend, "etesync");
etesync_backend_update_enabled (source, e_backend_get_source (E_BACKEND (backend)));
/* Set color for calendar and task only */
if (!g_str_equal (extension_name, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
- if (color) {
+ if (color && !(color[0] == 0)) {
gchar *safe_color;
- safe_color = g_strdup_printf ("#%06X", (0xFFFFFF & color));
+ /* Copying first 7 chars as color is stored in format #RRGGBBAA */
+ safe_color = g_strndup (color, 7);
e_source_selectable_set_color (E_SOURCE_SELECTABLE (source_backend), safe_color);
g_free (safe_color);
- }
+ } else
+ e_source_selectable_set_color (E_SOURCE_SELECTABLE (source_backend),
E_ETESYNC_COLLECTION_DEFAULT_COLOR);
+
}
extension_name = E_SOURCE_EXTENSION_ETESYNC;
extension = e_source_get_extension (source, extension_name);
- e_source_etesync_set_journal_id (
- E_SOURCE_ETESYNC (extension), journal_uid);
- e_source_etesync_set_journal_description (
+ e_source_etesync_set_collection_id (
+ E_SOURCE_ETESYNC (extension), collection_uid);
+ e_source_etesync_set_collection_description (
E_SOURCE_ETESYNC (extension), description);
- e_source_etesync_set_journal_color (
+ e_source_etesync_set_collection_color (
E_SOURCE_ETESYNC (extension), color);
+ e_source_etesync_set_etebase_collection_b64 (
+ E_SOURCE_ETESYNC (extension), col_obj_b64);
extension_name = E_SOURCE_EXTENSION_OFFLINE;
extension = e_source_get_extension (source, extension_name);
@@ -184,10 +199,8 @@ etesync_backend_new_child (EEteSyncBackend *backend,
e_server_side_source_set_remote_deletable (
E_SERVER_SIDE_SOURCE (source), TRUE);
- g_free (journal_uid);
- g_free (display_name);
+ g_free (col_obj_b64);
g_free (type);
- g_free (description);
return source;
}
@@ -202,42 +215,35 @@ etesync_backend_new_child (EEteSyncBackend *backend,
*/
static void
etesync_check_create_modify (EEteSyncBackend *backend,
- EteSyncJournal *journal,
- EteSyncCollectionInfo *info,
- GHashTable *known_sources,
+ const EtebaseCollection *col_obj,
+ EtebaseItemMetadata *item_metadata,
+ ESource *source,
ECollectionBackend *collection_backend,
ESourceRegistryServer *server)
{
- gchar *journal_uid;
- ESource *source;
-
g_return_if_fail (E_IS_ETESYNC_BACKEND (backend));
- g_return_if_fail (journal != NULL);
-
- journal_uid = etesync_journal_get_uid (journal);
-
- source = g_hash_table_lookup (known_sources, journal_uid);
+ g_return_if_fail (col_obj != NULL);
/* if exists check if needs modification
else create the source */
if (source != NULL) {
ESourceExtension *extension;
ESourceBackend *source_backend;
- gchar *display_name, *description;
+ const gchar *display_name, *description;
const gchar *extension_name = NULL;
- gint32 color;
+ const gchar *color;
- display_name = etesync_collection_info_get_display_name (info);
- description = etesync_collection_info_get_description (info);
- color = etesync_collection_info_get_color (info);
+ display_name = etebase_item_metadata_get_name (item_metadata);
+ description = etebase_item_metadata_get_description (item_metadata);
+ color = etebase_item_metadata_get_color (item_metadata);
extension_name = E_SOURCE_EXTENSION_ETESYNC;
extension = e_source_get_extension (source, extension_name);
/* Set source data */
e_source_set_display_name (source, display_name);
- e_source_etesync_set_journal_description ( E_SOURCE_ETESYNC (extension), description);
- e_source_etesync_set_journal_color (E_SOURCE_ETESYNC (extension), color);
+ e_source_etesync_set_collection_description ( E_SOURCE_ETESYNC (extension), description);
+ e_source_etesync_set_collection_color (E_SOURCE_ETESYNC (extension), color);
extension_name = NULL;
@@ -251,29 +257,26 @@ etesync_check_create_modify (EEteSyncBackend *backend,
if (extension_name) {
source_backend = e_source_get_extension (source, extension_name);
- if (color) {
+ if (color && *color) {
gchar *safe_color;
- safe_color = g_strdup_printf ("#%06X", (0xFFFFFF & color));
+ /* Copying first 7 chars as color is stored in format #RRGGBBAA */
+ safe_color = g_strndup (color, 7);
e_source_selectable_set_color (E_SOURCE_SELECTABLE (source_backend),
safe_color);
g_free (safe_color);
- }
+ } else
+ e_source_selectable_set_color (E_SOURCE_SELECTABLE (source_backend),
E_ETESYNC_COLLECTION_DEFAULT_COLOR);
}
- e_server_side_source_set_remote_deletable (
- E_SERVER_SIDE_SOURCE (source), TRUE);
-
- g_free (display_name);
- g_free (description);
} else {
- source = etesync_backend_new_child (backend, journal, info);
- e_source_registry_server_add_source (server, source);
- g_object_unref (source);
- }
+ source = etesync_backend_new_child (backend, col_obj, item_metadata);
- g_hash_table_remove (known_sources, journal_uid);
- g_free (journal_uid);
+ if (source) {
+ e_source_registry_server_add_source (server, source);
+ g_object_unref (source);
+ }
+ }
}
static void
@@ -303,14 +306,17 @@ etesync_backend_fill_known_sources (EEteSyncBackend *backend,
if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
ESourceEteSync *extension;
- gchar *journal_id;
+ gchar *collection_id;
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
- journal_id = e_source_etesync_dup_journal_id (extension);
+ collection_id = e_source_etesync_dup_collection_id (extension);
- if (journal_id)
- g_hash_table_insert (known_sources, journal_id, g_object_ref (source));
+ if (collection_id)
+ g_hash_table_insert (known_sources, collection_id, g_object_ref (source));
}
+
+ e_server_side_source_set_remote_deletable (
+ E_SERVER_SIDE_SOURCE (source), TRUE);
}
g_list_free_full (sources, g_object_unref);
@@ -320,81 +326,231 @@ etesync_backend_fill_known_sources (EEteSyncBackend *backend,
if (e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC)) {
ESourceEteSync *extension;
- gchar *journal_id;
+ gchar *collection_id;
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
- journal_id = e_source_etesync_dup_journal_id (extension);
+ collection_id = e_source_etesync_dup_collection_id (extension);
- if (journal_id)
- g_hash_table_insert (known_sources, journal_id, g_object_ref (source));
+ if (collection_id)
+ g_hash_table_insert (known_sources, collection_id, g_object_ref (source));
}
+
+ e_server_side_source_set_remote_deletable (
+ E_SERVER_SIDE_SOURCE (source), TRUE);
}
g_list_free_full (sources, g_object_unref);
}
+/* Creates a default EtebaseCollection and upload it to the server, then
+ adds it to Evolution EteSync account */
+static const gchar*
+etesync_backend_create_and_add_collection_sync (EEteSyncBackend *backend,
+ ESourceRegistryServer *server,
+ const gchar *type,
+ const gchar *name,
+ GCancellable *cancellable)
+{
+ EBackend *e_backend = E_BACKEND (backend);
+ EtebaseCollection *col_obj;
+ const gchar* stoken = NULL;
+
+ if (e_etesync_connection_collection_create_upload_sync (backend->priv->connection, e_backend,
+ type, name, NULL, E_ETESYNC_COLLECTION_DEFAULT_COLOR, &col_obj, cancellable, NULL)) {
+
+ ESource *source;
+ EtebaseItemMetadata *item_metadata;
+
+ item_metadata = etebase_collection_get_meta (col_obj);
+ source = etesync_backend_new_child (backend, col_obj, item_metadata);
+
+ if (source) {
+ e_source_registry_server_add_source (server, source);
+ g_object_unref (source);
+ }
+
+ if (col_obj) {
+ etebase_collection_destroy (col_obj);
+ stoken = etebase_collection_get_stoken (col_obj);
+ }
+ if (item_metadata)
+ etebase_item_metadata_destroy (item_metadata);
+ }
+
+ return stoken;
+}
+
static gboolean
-etesync_backend_sync_folders (EEteSyncBackend *backend,
- GCancellable *cancellable,
- GError **error)
+etesync_backend_sync_folders_sync (EEteSyncBackend *backend,
+ gboolean check_rec,
+ GCancellable *cancellable,
+ GError **error)
{
- EteSyncJournal **journals;
EEteSyncConnection *connection = backend->priv->connection;
- gboolean success = TRUE;
+ ECollectionBackend *collection_backend;
+ ESourceEteSyncAccount *etesync_account_extention;
+ ESourceRegistryServer *server;
+ EtebaseFetchOptions *fetch_options;
+ GHashTable *known_sources; /* Collection ID -> ESource */
+ gboolean success = TRUE, done = FALSE, is_first_time = FALSE;
+ gchar *stoken = NULL;
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
g_rec_mutex_lock (&backend->priv->etesync_lock);
- journals = etesync_journal_manager_list (e_etesync_connection_get_journal_manager (connection));
+ collection_backend = E_COLLECTION_BACKEND (backend);
+ server = e_collection_backend_ref_server (collection_backend);
+ etesync_account_extention = e_source_get_extension (e_backend_get_source (E_BACKEND (backend)),
E_SOURCE_EXTENSION_ETESYNC_ACCOUNT);
+ fetch_options = etebase_fetch_options_new();
+ known_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
/*
- 1) Get all sources in a hashtable.
- 2) loop on the journals, check if it is new (create), or old (maybe modified).
- 3) remove these two from the hashtable while looping.
- 4) what is left in the hashtable should be deleted.
+ 1) Get all known-sources (loaded in evo before) in a hashtable to easily lookup.
+ 2) Keep getting list of changes until "done" is true
+ 3) From the list we got, delete removed membership collection sources.
+ 4) loop on the collections, check if it is deleted
+ 5) if not deleted then check if it is new (create), or old (maybe modified).
+ 6) remove what is deleted or has removed member-ship
*/
- if (journals) {
- gpointer key = NULL, value = NULL;
- ECollectionBackend *collection_backend;
- EteSyncJournal **journal_iter;
- ESourceRegistryServer *server;
- GHashTable *known_sources; /* Journal ID -> ESource */
- GHashTableIter iter;
+ etebase_fetch_options_set_prefetch(fetch_options, ETEBASE_PREFETCH_OPTION_MEDIUM);
+ etebase_fetch_options_set_limit (fetch_options, E_ETESYNC_COLLECTION_FETCH_LIMIT);
+ etesync_backend_fill_known_sources (backend, known_sources); /* (1) */
+
+ stoken = g_hash_table_size (known_sources) > 0 ? e_source_etesync_account_dup_collection_stoken
(etesync_account_extention) : NULL;
+
+ /* if stoken is null, then it is first time to fetch data from server */
+ if (!stoken)
+ is_first_time = TRUE;
+
+ while (!done) {
+ EtebaseCollectionListResponse *col_list;
+
+ etebase_fetch_options_set_stoken (fetch_options, stoken);
+ col_list = etebase_collection_manager_list_multi
(e_etesync_connection_get_collection_manager (connection),
+
e_etesync_util_get_collection_supported_types (),
+ EETESYNC_UTILS_SUPPORTED_TYPES_SIZE,
+ fetch_options); /* (2) */
+
+ if (col_list) {
+ guintptr col_objs_len = etebase_collection_list_response_get_data_length (col_list);
+ const EtebaseCollection *col_objs[col_objs_len];
+ guintptr col_iter, col_list_rmv_membership_len;
+
+ g_free (stoken);
+
+ stoken = g_strdup (etebase_collection_list_response_get_stoken (col_list));
+ done = etebase_collection_list_response_is_done (col_list);
+ col_list_rmv_membership_len =
etebase_collection_list_response_get_removed_memberships_length (col_list);
+
+ etebase_collection_list_response_get_data (col_list, col_objs);
+
+ if (col_list_rmv_membership_len > 0) { /* (3) */
+ const EtebaseRemovedCollection
*col_list_rmv_membership[col_list_rmv_membership_len];
+
+ /* Creating a hashed table to easily look up if a collection has removed
membership or not */
+ if (etebase_collection_list_response_get_removed_memberships (col_list,
col_list_rmv_membership) == 0) {
+
+ for (col_iter = 0; col_iter < col_list_rmv_membership_len;
col_iter++) {
+ ESource *source = g_hash_table_lookup (known_sources,
etebase_removed_collection_get_uid (col_list_rmv_membership[col_iter]));
- collection_backend = E_COLLECTION_BACKEND (backend);
- server = e_collection_backend_ref_server (collection_backend);
- known_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
- etesync_backend_fill_known_sources (backend, known_sources);
+ if (source)
+ etesync_backend_delete_source (source);
+ }
+ } else {
+ success = FALSE;
+ etebase_collection_list_response_destroy (col_list);
+ break;
+ }
+ }
+
+ /* Loop each collection to see should we remove or check it, depending if it is
deleted or removed membership */
+ for (col_iter = 0; col_iter < col_objs_len; col_iter++) { /* (4) */
+ ESource *source;
+ const EtebaseCollection *col_obj;
+ const gchar *collection_uid;
- for (journal_iter = journals ;*journal_iter ;journal_iter++) {
- EteSyncJournal *journal = *journal_iter;
- EteSyncCryptoManager *crypto_manager;
- EteSyncCollectionInfo *info;
+ col_obj = col_objs[col_iter];
+ collection_uid = etebase_collection_get_uid (col_obj);
+ source = g_hash_table_lookup (known_sources, collection_uid);
- crypto_manager = etesync_journal_get_crypto_manager (journal,
- e_etesync_connection_get_derived_key (connection),
- e_etesync_connection_get_keypair (connection));
- info = etesync_journal_get_info (journal, crypto_manager);
+ if (!etebase_collection_is_deleted (col_obj)) { /* (5) */
+ EtebaseItemMetadata *item_metadata;
- etesync_check_create_modify (backend, journal, info, known_sources,
collection_backend, server);
+ item_metadata = etebase_collection_get_meta (col_obj);
+ etesync_check_create_modify (backend, col_obj, item_metadata, source,
collection_backend, server);
- etesync_collection_info_destroy (info);
- etesync_crypto_manager_destroy (crypto_manager);
- etesync_journal_destroy (journal);
+ etebase_item_metadata_destroy (item_metadata);
+ } else /* (6) */
+ etesync_backend_delete_source (source);
+ }
+
+ etebase_collection_list_response_destroy (col_list);
+ } else {
+ /* error 500 or 503 */
+ success = FALSE;
+ break;
}
+ }
- /* this is step 4 */
- g_hash_table_iter_init (&iter, known_sources);
- while (g_hash_table_iter_next (&iter, &key, &value))
- etesync_backend_delete_source (value);
+ /* If this is the first time to sync, then try fetching supported types, if success then don't create
default collections */
+ if (is_first_time) {
+ EtebaseCollectionListResponse *col_list;
+ EtebaseFetchOptions *fetch_options;
- g_hash_table_destroy (known_sources);
- g_free (journals);
- g_object_unref (server);
- } else {
- /* error 500 or 503 */
- success = FALSE;
+ fetch_options = etebase_fetch_options_new();
+ etebase_fetch_options_set_prefetch(fetch_options, ETEBASE_PREFETCH_OPTION_MEDIUM);
+ etebase_fetch_options_set_stoken (fetch_options, NULL);
+ etebase_fetch_options_set_limit (fetch_options, 1);
+
+ col_list = etebase_collection_manager_list_multi
(e_etesync_connection_get_collection_manager (connection),
+
e_etesync_util_get_collection_supported_types (),
+ EETESYNC_UTILS_SUPPORTED_TYPES_SIZE,
+ fetch_options);
+
+ if (etebase_collection_list_response_get_data_length (col_list) == 0) {
+ gint ii = 0;
+ const gchar *temp_stoken;
+ const gchar *const *collection_supported_types;
+ const gchar *const *collection_supported_types_default_names;
+
+ collection_supported_types = e_etesync_util_get_collection_supported_types ();
+ collection_supported_types_default_names =
e_etesync_util_get_collection_supported_types_default_names ();
+
+ for (ii = 0; ii < EETESYNC_UTILS_SUPPORTED_TYPES_SIZE; ii++)
+ temp_stoken = etesync_backend_create_and_add_collection_sync (backend,
server, collection_supported_types[ii], collection_supported_types_default_names[ii], cancellable);
+
+ if (temp_stoken) {
+ g_free (stoken);
+ stoken = g_strdup (temp_stoken);
+ }
+ }
+
+ etebase_collection_list_response_destroy (col_list);
+ etebase_fetch_options_destroy (fetch_options);
}
+ if (success)
+ e_source_etesync_account_set_collection_stoken (etesync_account_extention, stoken);
+ else {
+ EtebaseErrorCode etebase_error = etebase_error_get_code ();
+
+ e_etesync_utils_set_io_gerror (etebase_error, etebase_error_get_message (), error);
+ if (etebase_error == ETEBASE_ERROR_CODE_UNAUTHORIZED && check_rec) {
+ EBackend *e_backend = E_BACKEND (backend);
+
+ if (e_etesync_connection_maybe_reconnect_sync (connection, e_backend, cancellable,
error))
+ success = etesync_backend_sync_folders_sync (backend, FALSE, cancellable,
error);
+ }
+ }
+
+ g_object_unref (server);
+ g_hash_table_destroy (known_sources);
+ etebase_fetch_options_destroy (fetch_options);
+ g_free (stoken);
+
g_rec_mutex_unlock (&backend->priv->etesync_lock);
return success;
@@ -408,9 +564,9 @@ etesync_backend_create_resource_sync (ECollectionBackend *backend,
{
EEteSyncConnection *connection;
EEteSyncBackend *etesync_backend;
- EteSyncJournal *new_journal = NULL;
+ EtebaseCollection *new_col_obj = NULL;
const gchar *extension_name = NULL;
- const gchar *journal_type = NULL;
+ const gchar *col_type = NULL;
gboolean success = TRUE;
etesync_backend = E_ETESYNC_BACKEND (backend);
@@ -423,26 +579,27 @@ etesync_backend_create_resource_sync (ECollectionBackend *backend,
if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
- journal_type = ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK;
+ col_type = E_ETESYNC_COLLECTION_TYPE_ADDRESS_BOOK;
}
if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR)) {
extension_name = E_SOURCE_EXTENSION_CALENDAR;
- journal_type = ETESYNC_COLLECTION_TYPE_CALENDAR;
+ col_type = E_ETESYNC_COLLECTION_TYPE_CALENDAR;
}
if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST)) {
extension_name = E_SOURCE_EXTENSION_TASK_LIST;
- journal_type = ETESYNC_COLLECTION_TYPE_TASKS;
+ col_type = E_ETESYNC_COLLECTION_TYPE_TASKS;
}
- if (journal_type == NULL) {
+ if (col_type == NULL) {
success = FALSE;
}
if (success) {
gchar *display_name = NULL;
- gint32 color = ETESYNC_COLLECTION_DEFAULT_COLOR;
+ gchar *color = NULL;
+ EBackend *e_backend = E_BACKEND (backend);
if (!g_str_equal (extension_name, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
ESourceBackend *source_backend;
@@ -452,49 +609,46 @@ etesync_backend_create_resource_sync (ECollectionBackend *backend,
source_color = e_source_selectable_get_color (E_SOURCE_SELECTABLE (source_backend));
if (source_color) {
- color = g_ascii_strtoll (&source_color[1], NULL, 16);
- color |= 0xFF000000;
+ g_free (color);
+ color = g_strdup (source_color);
}
}
display_name = e_source_dup_display_name (source);
- success = e_etesync_connection_write_journal_action (connection,
- ETESYNC_SYNC_ENTRY_ACTION_ADD,
- NULL,
- journal_type,
- display_name,
- NULL,
- color,
- &new_journal);
+ success = e_etesync_connection_collection_create_upload_sync (connection,
+ e_backend,
+ col_type,
+ display_name,
+ NULL,
+ color ? color :
E_ETESYNC_COLLECTION_DEFAULT_COLOR,
+ &new_col_obj,
+ cancellable,
+ error);
g_free (display_name);
+ g_free (color);
}
if (success) {
ESourceRegistryServer *server;
- EteSyncCryptoManager *crypto_manager;
- EteSyncCollectionInfo *info;
+ EtebaseItemMetadata *item_metadata;
ESource *new_source;
- crypto_manager = etesync_journal_get_crypto_manager (new_journal,
- e_etesync_connection_get_derived_key (connection),
- e_etesync_connection_get_keypair (connection));
- info = etesync_journal_get_info (new_journal, crypto_manager);
+ item_metadata = etebase_collection_get_meta (new_col_obj);
- new_source = etesync_backend_new_child (etesync_backend, new_journal, info);
+ new_source = etesync_backend_new_child (etesync_backend, new_col_obj, item_metadata);
server = e_collection_backend_ref_server (backend);
e_source_registry_server_add_source (server, new_source);
- etesync_collection_info_destroy (info);
- etesync_crypto_manager_destroy (crypto_manager);
+ etebase_item_metadata_destroy (item_metadata);
g_object_unref (new_source);
g_object_unref (server);
}
- if (new_journal)
- etesync_journal_destroy (new_journal);
+ if (new_col_obj)
+ etebase_collection_destroy (new_col_obj);
g_rec_mutex_unlock (&etesync_backend->priv->etesync_lock);
@@ -508,120 +662,132 @@ etesync_backend_delete_resource_sync (ECollectionBackend *backend,
GError **error)
{
EEteSyncBackend *etesync_backend;
+ EBackend *e_backend;
+ EEteSyncConnection *connection;
ESourceEteSync *extension;
- gchar *journal_uid;
+ EtebaseCollection *col_obj;
gboolean success;
etesync_backend = E_ETESYNC_BACKEND (backend);
+ e_backend = E_BACKEND (backend);
g_return_val_if_fail (etesync_backend->priv->connection != NULL, FALSE);
g_rec_mutex_lock (&etesync_backend->priv->etesync_lock);
+ connection = etesync_backend->priv->connection;
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ETESYNC);
- journal_uid = e_source_etesync_dup_journal_id (extension);
+ col_obj = e_etesync_utils_etebase_collection_from_base64 (
+ e_source_etesync_get_etebase_collection_b64 (extension),
+ e_etesync_connection_get_collection_manager (connection));
- success = e_etesync_connection_write_journal_action (etesync_backend->priv->connection,
- ETESYNC_SYNC_ENTRY_ACTION_DELETE,
- journal_uid, NULL, NULL, NULL, 0, NULL);
+ success = e_etesync_connection_collection_delete_upload_sync (connection, e_backend, col_obj,
cancellable, error);
if (success)
etesync_backend_delete_source (source);
- g_free (journal_uid);
+ if (col_obj)
+ etebase_collection_destroy (col_obj);
+
g_rec_mutex_unlock (&etesync_backend->priv->etesync_lock);
return success;
}
static ESourceAuthenticationResult
-etesync_backend_set_credentials_sync (EEteSyncBackend *backend,
- const ENamedParameters *credentials)
+etesync_backend_authenticate_sync (EBackend *backend,
+ const ENamedParameters *credentials,
+ gchar **out_certificate_pem,
+ GTlsCertificateFlags *out_certificate_errors,
+ GCancellable *cancellable,
+ GError **error)
{
- ESource *source;
- ESourceAuthentication *authentication_extension;
- ESourceCollection *collection_extension;
- EEteSyncConnection *connection = backend->priv->connection;
+ EEteSyncBackend *etesync_backend;
+ ESourceAuthenticationResult result = E_SOURCE_AUTHENTICATION_ERROR;
- source = e_backend_get_source (E_BACKEND (backend));
- authentication_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
- collection_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION);
+ g_return_val_if_fail (E_IS_ETESYNC_BACKEND (backend), E_SOURCE_AUTHENTICATION_ERROR);
- return e_etesync_connection_set_connection_from_sources (connection, credentials,
authentication_extension, collection_extension);
-}
+ etesync_backend = E_ETESYNC_BACKEND (backend);
-static void
-etesync_backend_setup_connection (EEteSyncBackend *etesync_backend)
-{
- EBackend *backend;
- ESource *source;
- const gchar *username = NULL, *server_url = NULL;
+ g_rec_mutex_lock (&etesync_backend->priv->etesync_lock);
- backend = E_BACKEND (etesync_backend);
- source = e_backend_get_source (backend);
+ if (e_etesync_connection_is_connected (etesync_backend->priv->connection))
+ result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ else {
+ ESource *source = e_backend_get_source (backend);
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION)) {
- ESourceCollection *collection_extension;
+ if (!etesync_backend->priv->connection)
+ etesync_backend->priv->connection = e_etesync_connection_new (source);
- collection_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION);
- server_url = e_source_collection_get_calendar_url (collection_extension);
- }
+ if (e_etesync_connection_reconnect_sync (etesync_backend->priv->connection, &result,
cancellable, error))
+ result = E_SOURCE_AUTHENTICATION_ACCEPTED;
- if (e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION)) {
- ESourceAuthentication *authentication_extension;
+ }
- authentication_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
- username = e_source_authentication_get_user (authentication_extension);
+ if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
+ /* Getting the journals here, and updating the Sources */
+ if (etesync_backend_sync_folders_sync (etesync_backend, TRUE, cancellable, error))
+ e_collection_backend_authenticate_children (E_COLLECTION_BACKEND (backend),
credentials);
+ else
+ result = E_SOURCE_AUTHENTICATION_ERROR;
}
- etesync_backend->priv->connection = e_etesync_connection_new_from_user_url (username, server_url);
+ g_rec_mutex_unlock (&etesync_backend->priv->etesync_lock);
+
+ return result;
}
-static ESourceAuthenticationResult
-etesync_backend_authenticate_sync (EBackend *backend,
- const ENamedParameters *credentials,
- gchar **out_certificate_pem,
- GTlsCertificateFlags *out_certificate_errors,
- GCancellable *cancellable,
- GError **error)
+/* This function is a call back for "source-removed" signal, it makes sure
+ that the account logs-out after being removed */
+static void
+etesync_backend_source_removed_cb (ESourceRegistryServer *server,
+ ESource *source,
+ gpointer user_data)
{
- EEteSyncBackend *etesync_backend;
- EEteSyncConnection *connection;
- ESourceAuthenticationResult result;
+ /* Checking if it is a collection and is an EteSync collection */
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION) &&
+ e_source_has_extension (source, E_SOURCE_EXTENSION_ETESYNC_ACCOUNT)) {
- g_return_val_if_fail (E_IS_ETESYNC_BACKEND (backend), E_SOURCE_AUTHENTICATION_ERROR);
+ EEteSyncConnection *connection;
+ ENamedParameters *credentials;
+ const gchar *collection_uid;
- etesync_backend = E_ETESYNC_BACKEND (backend);
+ collection_uid = e_source_get_uid (source);
+ connection = e_etesync_connection_new (source);
- g_rec_mutex_lock (&etesync_backend->priv->etesync_lock);
+ /* Get credentials and set connection object, then use the connection object to logout */
+ if (e_etesync_service_lookup_credentials_sync (collection_uid, &credentials, NULL, NULL)
+ && e_etesync_connection_set_connection_from_sources (connection, credentials)) {
+
+ etebase_account_logout (e_etesync_connection_get_etebase_account (connection));
+ }
- if (!etesync_backend->priv->connection)
- etesync_backend_setup_connection (etesync_backend);
+ g_object_unref (connection);
+ e_named_parameters_free (credentials);
+ }
+}
- if (etesync_backend->priv->connection) {
- gboolean needs_setting;
+static void
+etesync_backend_dispose (GObject *object)
+{
+ ESourceRegistryServer *server;
- connection = etesync_backend->priv->connection;
- /* Get data from credentials if not there already */
- needs_setting = e_etesync_connection_needs_setting (connection, credentials, &result);
+ server = e_collection_backend_ref_server (E_COLLECTION_BACKEND (object));
- if (needs_setting)
- result = etesync_backend_set_credentials_sync (etesync_backend, credentials);
+ /* Only disconnect when backend_count is zero */
+ G_LOCK (backend_count);
+ if (server && !--backend_count) {
+ g_signal_handler_disconnect (
+ server, source_removed_handler_id);
- if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
- /* Getting the journals here, and updating the Sources */
- if (etesync_backend_sync_folders (etesync_backend, cancellable, error))
- e_collection_backend_authenticate_children (E_COLLECTION_BACKEND (backend),
credentials);
- else
- result = E_SOURCE_AUTHENTICATION_ERROR;
- }
- } else {
- result = E_SOURCE_AUTHENTICATION_ERROR;
+ backend_count = 0;
}
+ G_UNLOCK (backend_count);
- g_rec_mutex_unlock (&etesync_backend->priv->etesync_lock);
+ g_object_unref (server);
- return result;
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_etesync_backend_parent_class)->dispose (object);
}
static void
@@ -643,13 +809,18 @@ static void
etesync_backend_constructed (GObject *object)
{
EBackend *backend;
+ EEteSyncBackend *etesync_backend;
+ ESourceRegistryServer *server;
ESource *source;
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_etesync_backend_parent_class)->constructed (object);
backend = E_BACKEND (object);
+ etesync_backend = E_ETESYNC_BACKEND (object);
+ server = e_collection_backend_ref_server (E_COLLECTION_BACKEND (backend));
source = e_backend_get_source (backend);
+ etesync_backend->priv->connection = e_etesync_connection_new (source);
e_server_side_source_set_remote_creatable (
E_SERVER_SIDE_SOURCE (source), TRUE);
@@ -660,6 +831,16 @@ etesync_backend_constructed (GObject *object)
collection_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION);
e_source_collection_set_allow_sources_rename (collection_extension, TRUE);
}
+
+ G_LOCK (backend_count);
+ if (!backend_count++) {
+ source_removed_handler_id = g_signal_connect (
+ server, "source-removed",
+ G_CALLBACK (etesync_backend_source_removed_cb), NULL);
+ }
+ G_UNLOCK (backend_count);
+
+ g_object_unref (server);
}
static void
@@ -670,6 +851,7 @@ e_etesync_backend_class_init (EEteSyncBackendClass *class)
ECollectionBackendClass *collection_backend_class;
object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = etesync_backend_dispose;
object_class->finalize = etesync_backend_finalize;
object_class->constructed = etesync_backend_constructed;
@@ -688,4 +870,5 @@ e_etesync_backend_init (EEteSyncBackend *backend)
{
backend->priv = e_etesync_backend_get_instance_private (backend);
g_rec_mutex_init (&backend->priv->etesync_lock);
+
}
diff --git a/src/registry/module-etesync-backend.c b/src/registry/module-etesync-backend.c
index 4e0292e..68518a0 100644
--- a/src/registry/module-etesync-backend.c
+++ b/src/registry/module-etesync-backend.c
@@ -12,6 +12,7 @@
#include "e-etesync-backend.h"
#include "e-etesync-backend-factory.h"
#include "common/e-source-etesync.h"
+#include "common/e-source-etesync-account.h"
/* Module Entry Points */
void e_module_load (GTypeModule *type_module);
@@ -26,6 +27,7 @@ e_module_load (GTypeModule *type_module)
e_etesync_backend_factory_type_register (type_module);
e_source_etesync_type_register (type_module);
+ e_source_etesync_account_type_register (type_module);
}
G_MODULE_EXPORT void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]