diff options
-rw-r--r-- | sync/ChangeLog | 12 | ||||
-rw-r--r-- | sync/src/Makefile.am | 1 | ||||
-rw-r--r-- | sync/src/sync_collection.c | 18 | ||||
-rw-r--r-- | sync/src/sync_collection.h | 2 | ||||
-rw-r--r-- | sync/src/sync_gcal_item.c | 85 | ||||
-rw-r--r-- | sync/src/sync_gcal_item.h | 12 | ||||
-rw-r--r-- | sync/src/sync_group.c | 45 | ||||
-rw-r--r-- | sync/src/sync_group.h | 2 | ||||
-rw-r--r-- | sync/src/sync_main.c | 122 | ||||
-rw-r--r-- | sync/src/sync_main.h | 3 |
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, |