summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sync/ChangeLog12
-rw-r--r--sync/src/Makefile.am1
-rw-r--r--sync/src/sync_collection.c18
-rw-r--r--sync/src/sync_collection.h2
-rw-r--r--sync/src/sync_gcal_item.c85
-rw-r--r--sync/src/sync_gcal_item.h12
-rw-r--r--sync/src/sync_group.c45
-rw-r--r--sync/src/sync_group.h2
-rw-r--r--sync/src/sync_main.c122
-rw-r--r--sync/src/sync_main.h3
10 files changed, 232 insertions, 70 deletions
diff --git a/sync/ChangeLog b/sync/ChangeLog
index a2f53c4..19d8838 100644
--- a/sync/ChangeLog
+++ b/sync/ChangeLog
@@ -1,3 +1,15 @@
+2006-12-19 Chris Lord,,, <chris@openedhand.com>
+
+ * src/sync_gcal_item.[ch], src/Makefile.am:
+ Add a Google Calendar sync item
+
+ * src/sync_group.[ch], src/sync_collection.[ch]:
+ Add extra debugging, add a failure condition for *_start functions
+
+ * src/sync_main.[ch]:
+ Fix some crashers, add a Google Calendar target, change SyncML
+ target to use the file plug-in instead of evolution
+
2006-08-19 Chris Lord,,, <chris@openedhand.com>
* src/sync_group.c: (sync_append_error),
diff --git a/sync/src/Makefile.am b/sync/src/Makefile.am
index 765d2b0..1f328f8 100644
--- a/sync/src/Makefile.am
+++ b/sync/src/Makefile.am
@@ -7,6 +7,7 @@ sync_SOURCES = sync_main.c sync.h sync_group.c sync_group.h sync_item.c \
sync_item.h sync_evo2_item.c sync_evo2_item.h sync_file_item.c \
sync_file_item.h sync_syncml_item.c sync_syncml_item.h \
sync_syncml_server_item.c sync_syncml_server_item.h \
+ sync_gcal_item.c sync_gcal_item.h \
sync_collection.c sync_collection.h
sync_LDADD = $(SYNC_LIBS)
diff --git a/sync/src/sync_collection.c b/sync/src/sync_collection.c
index 88b2d05..913d580 100644
--- a/sync/src/sync_collection.c
+++ b/sync/src/sync_collection.c
@@ -35,6 +35,8 @@ struct _SyncCollectionPrivate
gdouble progress;
gint num_groups;
gint num_finished;
+
+ gboolean abort_failed;
};
static void
@@ -134,8 +136,11 @@ static void
sync_collection_abort_func (gpointer data, gpointer user_data)
{
SyncCollectionGroup *col_group = data;
+ SyncCollection *collection = user_data;
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
- sync_group_abort (col_group->group);
+ if (!sync_group_abort (col_group->group))
+ priv->abort_failed = TRUE;
}
static void
@@ -211,6 +216,9 @@ sync_collection_finished (SyncCollection *collection)
if (priv->num_finished == priv->num_groups) {
GList *c;
gchar *error = NULL;
+
+ g_debug ("All groups in collection finished syncing");
+
for (c = priv->groups; c; c = c->next) {
gchar *new_error;
SyncCollectionGroup *col_group = c->data;
@@ -245,6 +253,7 @@ sync_collection_finished (SyncCollection *collection)
static void
sync_collection_finished_cb (SyncGroup *group, SyncCollection *collection)
{
+ g_debug ("Group in collection finished syncing");
sync_collection_finished (collection);
}
@@ -342,13 +351,16 @@ sync_collection_start (SyncCollection *collection)
return success;
}
-void
+gboolean
sync_collection_abort (SyncCollection *collection)
{
SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ priv->abort_failed = FALSE;
g_list_foreach (priv->groups,
sync_collection_abort_func, collection);
+
+ return !priv->abort_failed;
}
void
@@ -364,6 +376,7 @@ sync_collection_remove_group (SyncCollection *collection,
sync_collection_group_free (collection, (SyncCollectionGroup *)
col_group->data);
priv->groups = g_list_delete_link (priv->groups, col_group);
+ priv->num_groups --;
}
}
@@ -378,6 +391,7 @@ sync_collection_remove_all (SyncCollection *collection)
sync_collection_group_free (collection, col_group);
priv->groups = g_list_delete_link (priv->groups, priv->groups);
}
+ priv->num_groups = 0;
}
gboolean
diff --git a/sync/src/sync_collection.h b/sync/src/sync_collection.h
index 8550baf..f750e9b 100644
--- a/sync/src/sync_collection.h
+++ b/sync/src/sync_collection.h
@@ -55,7 +55,7 @@ GList * sync_collection_get_groups (SyncCollection *collection);
gboolean sync_collection_start (SyncCollection *collection);
void sync_collection_resolve_conflict(SyncCollection *collection,
SyncGroupConflictRes res);
-void sync_collection_abort (SyncCollection *collection);
+gboolean sync_collection_abort (SyncCollection *collection);
void sync_collection_remove_group (SyncCollection *collection,
SyncGroup *group);
void sync_collection_remove_all (SyncCollection *collection);
diff --git a/sync/src/sync_gcal_item.c b/sync/src/sync_gcal_item.c
new file mode 100644
index 0000000..45362cc
--- /dev/null
+++ b/sync/src/sync_gcal_item.c
@@ -0,0 +1,85 @@
+
+#include <opensync/opensync.h>
+#include <glib.h>
+#include <string.h>
+#include "sync_item.h"
+#include "sync_group.h"
+#include "sync_gcal_item.h"
+
+#define GCAL_PLUGIN "google-calendar"
+#define GCAL_CONFIG \
+ "<config>" \
+ "<url>http://www.google.com/calendar/feeds/%s@gmail.com/private/full</url>" \
+ "<username>%s@gmail.com</username>" \
+ "<password>%s</password>" \
+ "</config>"
+
+typedef struct {
+ gchar *user;
+ gchar *pass;
+} SyncGCalItemData;
+
+static OSyncMember *
+sync_gcal_item_get_member (SyncItem *item, SyncGroup *group)
+{
+ OSyncMember *member;
+ OSyncError *error = NULL;
+ OSyncConfigurationTypes type = NO_CONFIGURATION;
+
+ member = osync_member_new (sync_group_get_osync_group (group));
+ if (!osync_member_instance_plugin (member, GCAL_PLUGIN, &error)) {
+ g_warning ("Error instancing google calendar plug-in: %s",
+ osync_error_print (&error));
+ osync_error_free (&error);
+ return NULL;
+ }
+ if (!osync_member_need_config (member, &type, &error)) {
+ g_warning ("Error reading plug-in config requirements: %s",
+ osync_error_print (&error));
+ osync_error_free (&error);
+ return NULL;
+ }
+ if (type == NO_CONFIGURATION) {
+ g_warning ("Google Calendar sync plug-in reports no need for "
+ "configuration");
+ } else {
+ SyncGCalItemData *data;
+ gchar *gcal_config;
+
+ data = (SyncGCalItemData *)sync_item_get_data (item);
+ gcal_config = g_strdup_printf (GCAL_CONFIG, data->user,
+ data->user, data->pass);
+ osync_member_set_config (
+ member, gcal_config, strlen (gcal_config));
+ g_free (gcal_config);
+ }
+
+ return member;
+}
+
+static void
+sync_gcal_free_data (SyncGCalItemData *data)
+{
+ g_free (data->user);
+ g_free (data->pass);
+ g_free (data);
+}
+
+SyncItem *
+sync_gcal_item_new (const gchar *name, const gchar *user, const gchar *pass)
+{
+ SyncItem *item;
+ SyncGCalItemData *data;
+
+ item = sync_item_new (name, NULL, sync_gcal_item_get_member);
+
+ data = g_new0 (SyncGCalItemData, 1);
+ data->user = user ? g_strdup (user) : g_strdup ("username");
+ data->pass = pass ? g_strdup (pass) : g_strdup ("password");
+
+ sync_item_set_data (item, data);
+ sync_item_set_data_free_func (
+ item, (SyncItemDataFreeFunc)sync_gcal_free_data);
+
+ return item;
+}
diff --git a/sync/src/sync_gcal_item.h b/sync/src/sync_gcal_item.h
new file mode 100644
index 0000000..a243265
--- /dev/null
+++ b/sync/src/sync_gcal_item.h
@@ -0,0 +1,12 @@
+
+#ifndef SYNC_GCAL_ITEM_H
+#define SYNC_GCAL_ITEM_H
+
+#include <glib.h>
+#include "sync_item.h"
+
+SyncItem * sync_gcal_item_new (const gchar *name,
+ const gchar *user,
+ const gchar *pass);
+
+#endif
diff --git a/sync/src/sync_group.c b/sync/src/sync_group.c
index db34e13..adf9d49 100644
--- a/sync/src/sync_group.c
+++ b/sync/src/sync_group.c
@@ -397,6 +397,10 @@ sync_group_get_osync_group (SyncGroup *group)
static gboolean
sync_group_started_idle (SyncGroup *group)
{
+ gchar *name = sync_group_get_name (group);
+ g_debug ("Group '%s' emitting started signal", name);
+ g_free (name);
+
g_signal_emit (group, signals[STARTED], 0);
return FALSE;
@@ -407,6 +411,10 @@ sync_group_progress_idle (SyncGroup *group)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
+ gchar *name = sync_group_get_name (group);
+ g_debug ("Group '%s' emitting progress signal", name);
+ g_free (name);
+
g_mutex_lock (priv->mutex);
g_signal_emit (group, signals[PROGRESS], 0, priv->changes /
(gdouble)priv->max_changes);
@@ -419,6 +427,10 @@ sync_group_progress_idle (SyncGroup *group)
static gboolean
sync_group_conflict_idle (SyncGroup *group)
{
+ gchar *name = sync_group_get_name (group);
+ g_debug ("Group '%s' emitting conflict signal", name);
+ g_free (name);
+
g_signal_emit (group, signals[CONFLICT], 0);
return FALSE;
@@ -429,14 +441,20 @@ sync_group_free_engine (SyncGroup *group)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
- osengine_finalize (priv->engine);
- osengine_free (priv->engine);
- priv->engine = NULL;
+ if (priv->engine) {
+ osengine_finalize (priv->engine);
+ osengine_free (priv->engine);
+ priv->engine = NULL;
+ }
}
static gboolean
sync_group_finished_idle (SyncGroup *group)
{
+ gchar *name = sync_group_get_name (group);
+ g_debug ("Group '%s' emitting finished signal", name);
+ g_free (name);
+
sync_group_free_engine (group);
g_signal_emit (group, signals[FINISHED], 0);
@@ -448,9 +466,13 @@ sync_group_failed_idle (SyncGroup *group)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
+ gchar *name = sync_group_get_name (group);
+ g_debug ("Group '%s' emitting failed signal", name);
+ g_free (name);
+
sync_group_free_engine (group);
g_signal_emit (group, signals[FAILED], 0, priv->error ?
- priv->error : "");
+ priv->error : "Unknown error");
g_free (priv->error);
priv->error = NULL;
@@ -619,10 +641,12 @@ sync_enginestatus_cb (OSyncEngine *engine, OSyncEngineUpdate *status,
break;
#endif
case ENG_SYNC_SUCCESSFULL:
+ g_debug ("Sync successful");
g_idle_add ((GSourceFunc)
sync_group_finished_idle, group);
break;
case ENG_ERROR:
+ g_debug ("Error");
g_idle_add ((GSourceFunc)
sync_group_failed_idle, group);
break;
@@ -761,6 +785,8 @@ sync_group_sync (SyncGroup *group, gboolean wait)
g_debug ("Sync started");
} else {
+ g_debug ("Auto-sync waiting...");
+
if (!osengine_wait_sync_end (priv->engine, &error)) {
g_warning ("osengine_wait_sync_end unsuccessful: %s",
osync_error_print (&error));
@@ -841,12 +867,17 @@ sync_group_resolve_conflict (SyncGroup *group, SyncGroupConflictRes res)
priv->mapping = NULL;
}
-void
+gboolean
sync_group_abort (SyncGroup *group)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
- if (priv->engine) osengine_abort (priv->engine);
- else g_warning ("%s called, but no sync in progress", G_STRFUNC);
+ if (priv->engine) {
+ osengine_abort (priv->engine);
+ return TRUE;
+ } else {
+ g_warning ("%s called, but no sync in progress", G_STRFUNC);
+ return FALSE;
+ }
}
void sync_group_remove_item (SyncGroup *group,
diff --git a/sync/src/sync_group.h b/sync/src/sync_group.h
index 08318fb..d73a531 100644
--- a/sync/src/sync_group.h
+++ b/sync/src/sync_group.h
@@ -75,7 +75,7 @@ gboolean sync_group_start (SyncGroup *group);
gboolean sync_group_autostart (SyncGroup *group);
void sync_group_resolve_conflict (SyncGroup *group,
SyncGroupConflictRes res);
-void sync_group_abort (SyncGroup *group);
+gboolean sync_group_abort (SyncGroup *group);
void sync_group_remove_item (SyncGroup *group,
SyncItem *item);
gboolean sync_group_delete (SyncGroup *group);
diff --git a/sync/src/sync_main.c b/sync/src/sync_main.c
index 7881145..3e21d69 100644
--- a/sync/src/sync_main.c
+++ b/sync/src/sync_main.c
@@ -17,52 +17,7 @@
#include "sync_file_item.h"
#include "sync_syncml_item.h"
#include "sync_syncml_server_item.h"
-#if 0
-static gboolean
-sync_clean_backup (SyncData *data)
-{
- OSyncGroup *group;
- GDir *backup_dir;
- OSyncError *error = NULL;
- GError *gerror = NULL;
- const gchar *filename;
-
- group = osync_env_find_group (data->osync, BACKUP_GROUP);
-
- /* Delete group */
- if ((group) && (!osync_group_delete(group, &error))) {
- g_warning ("Unable to delete backup group: %s\n",
- osync_error_print(&error));
- osync_error_free(&error);
- return FALSE;
- }
-
- /* Remove backup files */
- if (!g_file_test (BACKUP_PATH, G_FILE_TEST_EXISTS)) return TRUE;
- if (!g_file_test (BACKUP_PATH, G_FILE_TEST_IS_DIR)) return FALSE;
- if (!(backup_dir = g_dir_open (BACKUP_PATH, 0, &gerror))) {
- g_warning ("Error opening backup directory: %s",
- gerror->message);
- g_error_free (gerror);
- return FALSE;
- }
- while ((filename = g_dir_read_name (backup_dir))) {
- if (g_remove (filename) != 0) {
- g_warning ("Error removing file: %s", filename);
- break;
- }
- }
- g_dir_close (backup_dir);
-
- /* Remove backup directory */
- if (g_rmdir (BACKUP_PATH) != 0) {
- g_warning ("Error removing backup directory");
- return FALSE;
- }
-
- return TRUE;
-}
-#endif
+#include "sync_gcal_item.h"
static gboolean
sync_animate (SyncData *data)
@@ -118,10 +73,30 @@ sync_server_finished_cb (SyncGroup *group)
}
static void
-sync_server_failed_cb (SyncGroup *group, const gchar *error)
+sync_server_failed_cb (SyncGroup *group, const gchar *error, SyncData *data)
{
+ GtkWidget *dialog, *window;
+
g_warning ("Server sync failed");
- sync_group_autostart (group);
+
+ window = glade_xml_get_widget (data->xml, "main_window");
+ dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
+ "There was an error starting the synchronisation server:\n"
+ "\"%s\"\nWould you like to restart the server?", error);
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog), "_Disable server",
+ GTK_RESPONSE_CANCEL, "_Restart server", GTK_RESPONSE_OK, NULL);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+ sync_group_autostart (group);
+ } else {
+ gchar *new_title = g_strconcat (gtk_window_get_title (
+ GTK_WINDOW (window)), " - Server disabled", NULL);
+ gtk_window_set_title (GTK_WINDOW (window), new_title);
+ g_free (new_title);
+ }
+
+ gtk_widget_destroy (dialog);
}
static void
@@ -211,7 +186,7 @@ sync_item_activated_cb (GtkIconView *iconview, GtkTreePath *arg1,
g_free (path);
/* Contacts SyncML item */
- item = sync_syncml_item_new ("Server",
+/* item = sync_syncml_item_new ("Server",
"http://localhost:8080",
CONTACTS, "", "", "card");
group = sync_group_new_with_items (
@@ -219,10 +194,10 @@ sync_item_activated_cb (GtkIconView *iconview, GtkTreePath *arg1,
sync_collection_add_group (data->collection,
group);
g_object_unref (group);
- g_object_unref (item);
+ g_object_unref (item);*/
/* Events SyncML item */
-/* item = sync_syncml_item_new ("Server",
+ item = sync_syncml_item_new ("Server",
"http://localhost:8080",
EVENTS, "", "", "cal");
group = sync_group_new_with_items (
@@ -230,7 +205,7 @@ sync_item_activated_cb (GtkIconView *iconview, GtkTreePath *arg1,
sync_collection_add_group (data->collection,
group);
g_object_unref (group);
- g_object_unref (item);*.
+ g_object_unref (item);
/* Todo SyncML item */
/* item = sync_syncml_item_new ("Server",
@@ -259,6 +234,23 @@ sync_item_activated_cb (GtkIconView *iconview, GtkTreePath *arg1,
g_object_unref (group);
g_object_unref (item);
break;
+ case TYPE_GCAL:
+ path = g_strdup_printf (TEMP_PATH,
+ g_getenv ("HOME"));
+ item = sync_file_item_new ("Test", path);
+ g_free (path);
+
+ item2 = sync_gcal_item_new ("GCal",
+ "user", "password");
+
+ group = sync_group_new_with_items (
+ item2, item);
+ sync_collection_add_group (data->collection,
+ group);
+ g_object_unref (group);
+ g_object_unref (item);
+ g_object_unref (item2);
+ break;
default:
return;
}
@@ -316,7 +308,12 @@ sync_abort_cb (GtkWidget *source, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (data->xml, "cancel_button");
gtk_widget_set_sensitive (widget, FALSE);
- sync_collection_abort (data->collection);
+ widget = glade_xml_get_widget (data->xml, "sync_progressbar");
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget),
+ "Aborting...");
+ if (!sync_collection_abort (data->collection)) {
+ sync_failed_cb (data->collection, "Unknown error", data);
+ }
}
void
@@ -394,6 +391,7 @@ main (int argc, char **argv)
gint width = 0, height = 0;
SyncData data;
SyncItem *server_item;
+ gchar *testpath;
gtk_init (&argc, &argv);
glade_init ();
@@ -433,7 +431,11 @@ main (int argc, char **argv)
/* Create local sync-item and sync collection */
data.collection = sync_collection_new ();
- data.local_item = sync_evo2_item_new ("Local", NULL, NULL, NULL);
+ /* Test with a local file store, evo2 plug-in is broken? */
+/* data.local_item = sync_evo2_item_new ("Local", NULL, NULL, NULL);*/
+ testpath = g_strdup_printf (TEMP_PATH2, g_getenv ("HOME"));
+ data.local_item = sync_file_item_new ("Test2", testpath);
+ g_free (testpath);
/* Create and start server */
server_item = sync_syncml_server_item_new ("Server", "", "",
@@ -443,11 +445,11 @@ main (int argc, char **argv)
g_object_unref (server_item);
/* TODO: Conflicts? */
g_signal_connect (G_OBJECT (data.server_group), "started",
- G_CALLBACK (sync_server_started_cb), NULL);
+ G_CALLBACK (sync_server_started_cb), &data);
g_signal_connect (G_OBJECT (data.server_group), "finished",
- G_CALLBACK (sync_server_finished_cb), NULL);
+ G_CALLBACK (sync_server_finished_cb), &data);
g_signal_connect (G_OBJECT (data.server_group), "failed",
- G_CALLBACK (sync_server_failed_cb), NULL);
+ G_CALLBACK (sync_server_failed_cb), &data);
sync_group_autostart (data.server_group);
/* Insert some items for testing (TODO: look at loading groups later) */
@@ -455,8 +457,11 @@ main (int argc, char **argv)
G_MAXINT, COL_NAME, "SyncML Test", COL_TYPE, TYPE_SYNCML,
COL_PIXBUF, data.network_icon, -1);
gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
- G_MAXINT, COL_NAME, "File Test", COL_TYPE, TYPE_FILE,
+ G_MAXINT, COL_NAME, "Evo2 Test", COL_TYPE, TYPE_FILE,
COL_PIXBUF, data.backup_icon, -1);
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
+ G_MAXINT, COL_NAME, "GCal Test", COL_TYPE, TYPE_GCAL,
+ COL_PIXBUF, data.network_icon, -1);
/* Insert preset items */
/* gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
@@ -477,7 +482,6 @@ main (int argc, char **argv)
gtk_icon_view_select_path (GTK_ICON_VIEW (widget), path);
gtk_tree_path_free (path);
-
/* Connect signals */
glade_xml_signal_autoconnect_full (data.xml, dates_autoconnect, &data);
diff --git a/sync/src/sync_main.h b/sync/src/sync_main.h
index 7542029..4d3adac 100644
--- a/sync/src/sync_main.h
+++ b/sync/src/sync_main.h
@@ -12,6 +12,8 @@
#define XML_FILE PKGDATADIR G_DIR_SEPARATOR_S "sync.glade"
#define TEMP_PATH "%s" G_DIR_SEPARATOR_S ".gnome2" G_DIR_SEPARATOR_S \
"sync" G_DIR_SEPARATOR_S "backup"
+#define TEMP_PATH2 "%s" G_DIR_SEPARATOR_S ".gnome2" G_DIR_SEPARATOR_S \
+ "sync" G_DIR_SEPARATOR_S "backup2"
#define ANIM_FREQ 100
#define SWITCH_FREQ 10
@@ -20,6 +22,7 @@ typedef enum {
TYPE_FILE,
TYPE_EVO2,
TYPE_SYNCML,
+ TYPE_GCAL,
TYPE_ADD_NEW,
TYPE_BACKUP,
TYPE_RESTORE,