aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/conduits/todo/todo-conduit.c
diff options
context:
space:
mode:
authorJP Rosevear <jpr@helixcode.com>2000-09-20 06:48:47 +0800
committerJP Rosevear <jpr@src.gnome.org>2000-09-20 06:48:47 +0800
commit58b5fd92fc9f5419beabe82d38622aba064cc56e (patch)
treea8219b9cc9b1311466f9854b0fa673045250edb1 /calendar/conduits/todo/todo-conduit.c
parent6820bb50e53b479997ae5a9616186301c333fad8 (diff)
downloadgsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.tar
gsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.tar.gz
gsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.tar.bz2
gsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.tar.lz
gsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.tar.xz
gsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.tar.zst
gsoc2013-evolution-58b5fd92fc9f5419beabe82d38622aba064cc56e.zip
Add some other cases where a slow sync is in order (pre_sync): Pre load
2000-09-19 JP Rosevear <jpr@helixcode.com> * conduits/todo/todo-conduit.c (check_for_slow_setting): Add some other cases where a slow sync is in order (pre_sync): Pre load the uids, the map and the add/mod/del lists (match_record): Use the map hash to match records (iterate): Iterate using the pre-loaded uid list (iterate_specific): Iterate using the add/mod/del lists (purge): Delete all entries in the del list (set_status): Set status by adding to an appropriate list (set_pilot_id): Set pilot_id by updating map hash * conduits/todo/todo-conduit.h: Add lists for added, modified and deleted objects * conduits/todo/todo-conduit.c (map_name): Get the pilot_id->uid map file name (map_sax_start_element): SAX handler to extract a pilot_id->uid mapping (map_sax_parse): Parse the given file and build a pilot_id->uid hash (map_write_foreach): Write out individual mapping elements (map_write): Write out the pilot_id->uid mapping (start_calendar_server_cb): Rename from gnome_calendar_load_cb * conduits/todo/todo-conduit-config.h: Rename pilotID to pilot_id * conduits/todo/e-todo.conduit.in: A little renaming * conduits/todo/Makefile.am: Fix build slightly * pcs/cal.c (build_change_seq): Build a corba sequence out of a list of CalObjChanges (Cal_get_objects_in_range): Implement new corba function * pcs/cal-backend.c (cal_backend_init): Intiliaze to NULL (cal_backend_load): Track the uri so we can write the log file to the same place (cal_backend_log_name): Figure out the log filename/path based on the calendar uri (cal_backend_set_node_timet): Set an xml node property value from a time_t (cal_backend_log_entry): Adds a log entry to list waiting to be written out (cal_backend_log_sync): Syncs the log entries to disk (cal_backend_log_sax_start_element): SAX callback for reading in log entries (cal_backend_log_sax_end_element): ditto (cal_backend_log_sax_parse): Main SAX parser call to parse the log file looking for particular log entries and creating a CalObjChange hash with the last change for each object (cal_backend_get_log_entries): Returns a hash of objects of a given type changed since the given time (cal_backend_update_object): Add appropriate log entries (cal_backend_remove_object): ditto (cal_backend_get_changed_uids): Implement new idl interface call (cal_backend_foreach_changed): Convert CalObjChange hash into a list * pcs/cal-backend-imc.[hc]: Remove crufty files * pcs/cal-backend-file.c (cal_backend_file_get_type_by_uid): New function that returns the CalObjType for a uid. * cal-client/cal-client.h: Update prototypes. * cal-client/cal-client.c (build_change_list): Build a list of CalObjChange items from a corba sequence. (cal_client_get_changed_uids): New accessor method for the similarly named addition to the idl file. * cal-util/cal-util.h: Update prototypes and add CalObjChangeType enum. * cal-util/cal-util.c (cal_obj_change_list_free): New utility method to free a list of CalObjChange objects. * idl/evolution-calendar.idl: Add get_changed_uids method and associated types. svn path=/trunk/; revision=5512
Diffstat (limited to 'calendar/conduits/todo/todo-conduit.c')
-rw-r--r--calendar/conduits/todo/todo-conduit.c964
1 files changed, 470 insertions, 494 deletions
diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c
index f1f0e11e28..6b9659f70f 100644
--- a/calendar/conduits/todo/todo-conduit.c
+++ b/calendar/conduits/todo/todo-conduit.c
@@ -48,7 +48,6 @@
GnomePilotConduit * conduit_get_gpilot_conduit (guint32);
void conduit_destroy_gpilot_conduit (GnomePilotConduit*);
-void local_record_from_compobject (EToDoLocalRecord *local, CalComponent *comp);
#define CONDUIT_VERSION "0.8.11"
#ifdef G_LOG_DOMAIN
@@ -60,15 +59,13 @@ void local_record_from_compobject (EToDoLocalRecord *local, CalComponent *comp);
/* #undef DEBUG_CALCONDUIT */
#ifdef DEBUG_CALCONDUIT
-#define show_exception(e) g_warning ("Exception: %s\n", CORBA_exception_id (e))
-#define LOG(e...) g_log(G_LOG_DOMAIN,G_LOG_LEVEL_MESSAGE, e)
+#define LOG(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
#else
-#define show_exception(e)
#define LOG(e...)
#endif
-#define WARN(e...) g_log(G_LOG_DOMAIN,G_LOG_LEVEL_WARNING, e)
-#define INFO(e...) g_log(G_LOG_DOMAIN,G_LOG_LEVEL_MESSAGE, e)
+#define WARN(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, e)
+#define INFO(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
/* debug spew DELETE ME */
static char *print_local (EToDoLocalRecord *local)
@@ -120,19 +117,16 @@ static char *print_remote (PilotRecord *remote)
return buff;
}
-/* Given a GCalConduitContxt*, allocates the structure */
+/* Context Routines */
static void
-e_todo_context_new (EToDoConduitContext **ctxt, guint32 pilotId)
+e_todo_context_new (EToDoConduitContext **ctxt, guint32 pilot_id)
{
*ctxt = g_new0 (EToDoConduitContext,1);
g_assert (ctxt!=NULL);
- todoconduit_load_configuration (&(*ctxt)->cfg, pilotId);
+ todoconduit_load_configuration (&(*ctxt)->cfg, pilot_id);
}
-
-/* Destroys any data allocated by gcalconduit_new_context
- and deallocates its data. */
static void
e_todo_context_destroy (EToDoConduitContext **ctxt)
{
@@ -149,15 +143,135 @@ e_todo_context_destroy (EToDoConduitContext **ctxt)
*ctxt = NULL;
}
+/* Map routines */
+static char *
+map_name (EToDoConduitContext *ctxt)
+{
+ char *filename;
+
+ filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id);
+
+ return filename;
+}
+
+static void
+map_sax_start_element (void *data, const xmlChar *name,
+ const xmlChar **attrs)
+{
+ EToDoConduitContext *ctxt = (EToDoConduitContext *)data;
+
+ if (!strcmp (name, "map")) {
+ char *uid = NULL;
+ guint32 *pid = g_new (guint32, 1);
+
+ *pid = 0;
+
+ while (*attrs != NULL) {
+ const xmlChar **val = attrs;
+
+ val++;
+ if (!strcmp (*attrs, "uid"))
+ uid = g_strdup (*val);
+
+ if (!strcmp (*attrs, "pilotid"))
+ *pid = strtoul (*val, NULL, 0);
+
+ attrs = ++val;
+ }
+
+ if (uid && *pid != 0)
+ g_hash_table_insert (ctxt->map, pid, uid);
+ else
+ g_free (pid);
+ }
+}
+
+static int
+map_sax_parse (xmlSAXHandler *handler, EToDoConduitContext *ctxt, const char *filename)
+{
+ int ret = 0;
+ xmlParserCtxtPtr xc;
+
+ if (!g_file_exists (filename))
+ return 0;
+
+ xc = xmlCreateFileParserCtxt (filename);
+ if (xc == NULL)
+ return -1;
+
+ xc->sax = handler;
+ xc->userData = (void *)ctxt;
+
+ xmlParseDocument (xc);
+
+ if (xc->wellFormed)
+ ret = 0;
+ else
+ ret = -1;
+
+ if (handler != NULL)
+ xc->sax = NULL;
+ xmlFreeParserCtxt(xc);
+
+ return ret;
+}
static void
-gnome_calendar_load_cb (GtkWidget *cal_client,
- CalClientLoadStatus status,
- EToDoConduitContext *ctxt)
+map_write_foreach (gpointer key, gpointer value, gpointer data)
+{
+ xmlNodePtr root = data;
+ xmlNodePtr mnode;
+ unsigned long *pid = key;
+ const char *uid = value;
+ char *pidstr;
+
+ mnode = xmlNewChild (root, NULL, "map", NULL);
+ xmlSetProp (mnode, "uid", uid);
+ pidstr = g_strdup_printf ("%lu", *pid);
+ xmlSetProp (mnode, "pilot_id", pidstr);
+ g_free (pidstr);
+}
+
+static int
+map_write (EToDoConduitContext *ctxt, char *filename)
+{
+ xmlDocPtr doc;
+ int ret;
+
+ if (ctxt->map == NULL)
+ return 0;
+
+ doc = xmlNewDoc ("1.0");
+ if (doc == NULL) {
+ WARN ("Pilot map file could not be created\n");
+ return -1;
+ }
+ doc->root = xmlNewDocNode(doc, NULL, "PilotMap", NULL);
+
+ g_hash_table_foreach (ctxt->map, map_write_foreach, doc->root);
+
+ /* Write the file */
+ xmlSetDocCompressMode (doc, 0);
+ ret = xmlSaveFile (filename, doc);
+ if (ret < 0) {
+ g_warning ("Pilot map file '%s' could not be saved\n", filename);
+ return -1;
+ }
+
+ xmlFreeDoc (doc);
+
+ return 0;
+}
+
+/* Calendar Server routines */
+static void
+start_calendar_server_cb (GtkWidget *cal_client,
+ CalClientLoadStatus status,
+ EToDoConduitContext *ctxt)
{
CalClient *client = CAL_CLIENT (cal_client);
- LOG (" todo-conduit entering gnome_calendar_load_cb, tried=%d\n",
+ LOG (" entering start_calendar_server_load_cb, tried=%d\n",
ctxt->calendar_load_tried);
if (status == CAL_CLIENT_LOAD_SUCCESS) {
@@ -172,21 +286,15 @@ gnome_calendar_load_cb (GtkWidget *cal_client,
}
cal_client_create_calendar (client, ctxt->calendar_file);
- ctxt->calendar_load_tried = 1;
+ ctxt->calendar_load_tried = TRUE;
}
}
-
-
-
-
static int
-start_calendar_server (GnomePilotConduitStandardAbs *conduit,
- EToDoConduitContext *ctxt)
+start_calendar_server (EToDoConduitContext *ctxt)
{
- g_return_val_if_fail(conduit!=NULL,-2);
- g_return_val_if_fail(ctxt!=NULL,-2);
+ g_return_val_if_fail (ctxt != NULL, -2);
ctxt->client = cal_client_new ();
@@ -195,7 +303,7 @@ start_calendar_server (GnomePilotConduitStandardAbs *conduit,
"evolution/local/Calendar/calendar.ics");
gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_loaded",
- gnome_calendar_load_cb, ctxt);
+ start_calendar_server_cb, ctxt);
LOG (" calling cal_client_load_calendar\n");
cal_client_load_calendar (ctxt->client, ctxt->calendar_file);
@@ -210,59 +318,9 @@ start_calendar_server (GnomePilotConduitStandardAbs *conduit,
return -1;
}
-
-static GSList *
-get_calendar_objects(GnomePilotConduitStandardAbs *conduit,
- gboolean *status,
- EToDoConduitContext *ctxt)
-{
- GList *uids;
- GSList *result = NULL;
-
- g_return_val_if_fail (conduit != NULL, NULL);
- g_return_val_if_fail (ctxt != NULL, NULL);
-
- uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO);
-
- LOG ("got %d todo entries from cal server\n", g_list_length (uids));
-
- if (status != NULL)
- (*status) = TRUE;
-
- if (! uids)
- INFO ("No entries found");
- else {
- GList *c;
- for (c=uids; c; c=c->next)
- result = g_slist_prepend (result, (gchar *) c->data);
- /* FIX ME free uids */
- }
-
- return result;
-}
-
-
-static void
-local_record_from_comp_uid (EToDoLocalRecord *local,
- char *uid,
- EToDoConduitContext *ctxt)
-{
- CalComponent *comp;
- CalClientGetStatus status;
-
- g_assert(local!=NULL);
-
- status = cal_client_get_object (ctxt->client, uid, &comp);
-
- if (status == CAL_CLIENT_GET_SUCCESS)
- local_record_from_compobject (local, comp);
- else
- INFO ("Object did not exist");
-}
-
-
-
-static const char *gnome_pilot_status_to_string (gint status)
+/* Utility routines */
+static const char *
+status_to_string (gint status)
{
switch(status) {
case GnomePilotRecordPending: return "GnomePilotRecordPending";
@@ -275,14 +333,37 @@ static const char *gnome_pilot_status_to_string (gint status)
return "Unknown";
}
+static PilotRecord *
+local_record_to_pilot_record (EToDoLocalRecord *local,
+ EToDoConduitContext *ctxt)
+{
+ PilotRecord *p = NULL;
+
+ g_return_val_if_fail (local != NULL, NULL);
+ g_assert (local->comp != NULL);
+ g_assert (local->todo != NULL );
+
+ LOG ("local_record_to_remote_record\n");
+
+ p = g_new0 (PilotRecord, 1);
+ p->ID = local->local.ID;
+ p->attr = local->local.attr;
+ p->archived = local->local.archived;
+ p->secret = local->local.secret;
+
+ /* Generate pilot record structure */
+ p->record = g_new0 (char,0xffff);
+ p->length = pack_ToDo (local->todo, p->record, 0xffff);
+
+ return p;
+}
/*
* converts a CalComponent object to a EToDoLocalRecord
*/
-void
-local_record_from_compobject(EToDoLocalRecord *local,
- CalComponent *comp)
+static void
+local_record_from_comp (EToDoLocalRecord *local, CalComponent *comp)
{
int *priority;
struct icaltimetype *completed;
@@ -295,7 +376,7 @@ local_record_from_compobject(EToDoLocalRecord *local,
unsigned long *pilot_id;
unsigned long *pilot_status;
- LOG ("local_record_from_compobject\n");
+ LOG ("local_record_from_comp\n");
g_return_if_fail (local != NULL);
g_return_if_fail (comp != NULL);
@@ -364,68 +445,23 @@ local_record_from_compobject(EToDoLocalRecord *local,
local->local.archived = 0;
}
-
-/*
- * Given a PilotRecord, find the matching record in
- * the calendar repository. If no match, return NULL
- */
-static EToDoLocalRecord *
-find_record_in_repository(GnomePilotConduitStandardAbs *conduit,
- PilotRecord *remote,
- EToDoConduitContext *ctxt)
+static void
+local_record_from_uid (EToDoLocalRecord *local,
+ char *uid,
+ EToDoConduitContext *ctxt)
{
- char *uid = NULL;
- EToDoLocalRecord *loc;
- CalClientGetStatus status;
CalComponent *comp;
-
- g_return_val_if_fail(conduit!=NULL,NULL);
- g_return_val_if_fail(remote!=NULL,NULL);
-
- LOG ("find_record_in_repository: remote=%s... ",
- print_remote (remote));
+ CalClientGetStatus status;
- LOG ("requesting %ld", remote->ID);
+ g_assert(local!=NULL);
- status = cal_client_get_uid_by_pilot_id (ctxt->client, remote->ID, &uid);
+ status = cal_client_get_object (ctxt->client, uid, &comp);
if (status == CAL_CLIENT_GET_SUCCESS) {
- status = cal_client_get_object (ctxt->client, uid, &comp);
- if (status == CAL_CLIENT_GET_SUCCESS) {
- LOG ("found %s\n", cal_component_get_as_string (comp));
- loc = g_new0(EToDoLocalRecord,1);
- /* memory allocated in new_from_string is freed in free_match */
- local_record_from_compobject (loc, comp);
- return loc;
- }
- LOG ("Pilot ID found, but comp for uid %s was not\n", uid);
- }
-
- INFO ("Object did not exist");
- return NULL;
-}
-
-
-/*
- * updates an given CalComponent in the repository
- */
-static void
-update_calendar_entry_in_repository(GnomePilotConduitStandardAbs *conduit,
- CalComponent *comp,
- EToDoConduitContext *ctxt)
-{
- gboolean success;
-
- g_return_if_fail (conduit != NULL);
- g_return_if_fail (comp != NULL);
-
- LOG (" update_calendar_entry_in_repository "
- "saving to desktop\n%s", cal_component_get_as_string (comp));
-
- success = cal_client_update_object (ctxt->client, comp);
-
- if (!success)
- WARN (_("Error while communicating with calendar server"));
+ local_record_from_comp (local, comp);
+ } else {
+ INFO ("Object did not exist");
+ }
}
@@ -505,90 +541,34 @@ comp_from_remote_record (GnomePilotConduitStandardAbs *conduit,
return comp;
}
-
-/* Code blatantly stolen from
- * calendar-pilot-sync.c:
- *
- * (C) 1999 International GNOME Support
- *
- * Author:
- * Miguel de Icaza (miguel@gnome-support.com)
- *
- * store a copy of a pilot record in the desktop database
- *
- */
-static gint
-update_record (GnomePilotConduitStandardAbs *conduit,
- PilotRecord *remote,
- EToDoConduitContext *ctxt)
+static void
+update_comp (GnomePilotConduitStandardAbs *conduit, CalComponent *comp,
+ EToDoConduitContext *ctxt)
{
- CalComponent *comp;
- CalClientGetStatus status;
- struct ToDo todo;
- unsigned long pilot_status = GnomePilotRecordNothing;
- char *uid;
-
- g_return_val_if_fail (remote!=NULL,-1);
-
- memset (&todo, 0, sizeof (struct ToDo));
- unpack_ToDo (&todo, remote->record, remote->length);
-
- LOG (" cal_client_get_uid_by_pilot_id... ");
-
- status = cal_client_get_uid_by_pilot_id (ctxt->client,
- remote->ID, &uid);
- if (status == CAL_CLIENT_GET_SUCCESS) {
- LOG (" succeeded with '%s'\n", uid);
- LOG (" cal_client_get_object... ");
- status = cal_client_get_object (ctxt->client, uid, &comp);
- }
-
- if (status != CAL_CLIENT_GET_SUCCESS) {
- comp = comp_from_remote_record (conduit, remote, NULL);
- } else {
- CalComponent *new_comp;
-
- LOG ("succeeded %s\n", cal_component_get_as_string (comp));
-
- new_comp = comp_from_remote_record (conduit, remote, comp);
- gtk_object_unref (GTK_OBJECT (comp));
- comp = new_comp;
- }
+ gboolean success;
- /* update record on server */
- {
- const char *uid;
- unsigned long *pilot_id;
+ g_return_if_fail (conduit != NULL);
+ g_return_if_fail (comp != NULL);
- cal_component_get_uid (comp, &uid);
- cal_component_get_pilot_id (comp, &pilot_id);
-
- update_calendar_entry_in_repository (conduit, comp, ctxt);
- cal_client_update_pilot_id (ctxt->client, (char *) uid,
- *pilot_id, pilot_status);
- }
+ LOG ("update_comp: saving to desktop\n%s\n",
+ cal_component_get_as_string (comp));
- /*
- * Shutdown
- */
- gtk_object_unref (GTK_OBJECT (comp));
- free_ToDo(&todo);
+ success = cal_client_update_object (ctxt->client, comp);
- return 0;
+ if (!success)
+ WARN (_("Error while communicating with calendar server"));
}
static void
check_for_slow_setting (GnomePilotConduit *c, EToDoConduitContext *ctxt)
{
- GList *uids;
- unsigned long int entry_number;
-
- uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO);
-
- entry_number = g_list_length (uids);
+ int count, map_count;
- /* If the local base is empty, do a slow sync */
- if (entry_number == 0) {
+ count = g_list_length (ctxt->uids);
+ map_count = g_hash_table_size (ctxt->map);
+
+ /* If there are no objects or objects but no log */
+ if ((count == 0) || (count > 0 && map_count == 0)) {
GnomePilotConduitStandard *conduit;
LOG (" doing slow sync\n");
conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
@@ -598,24 +578,21 @@ check_for_slow_setting (GnomePilotConduit *c, EToDoConduitContext *ctxt)
}
}
+/* Pilot syncing callbacks */
static gint
-pre_sync (GnomePilotConduit *c,
+pre_sync (GnomePilotConduit *conduit,
GnomePilotDBInfo *dbi,
EToDoConduitContext *ctxt)
{
- int l;
+ GnomePilotConduitStandardAbs *abs_conduit;
+ int len, ret;
unsigned char *buf;
- GnomePilotConduitStandardAbs *conduit;
+ char *filename;
+ xmlSAXHandler handler;
+ GList *changes, *l;
gint num_records;
- /*
- g_log_set_always_fatal (G_LOG_LEVEL_ERROR |
- G_LOG_LEVEL_CRITICAL |
- G_LOG_LEVEL_WARNING);
- */
-
-
- conduit = GNOME_PILOT_CONDUIT_STANDARD_ABS(c);
+ abs_conduit = GNOME_PILOT_CONDUIT_STANDARD_ABS (conduit);
LOG ("---------------------------------------------------------\n");
LOG ("pre_sync: ToDo Conduit v.%s", CONDUIT_VERSION);
@@ -623,102 +600,174 @@ pre_sync (GnomePilotConduit *c,
ctxt->client = NULL;
- if (start_calendar_server (GNOME_PILOT_CONDUIT_STANDARD_ABS(c), ctxt) != 0) {
- WARN(_("Could not start gnomecal server"));
- gnome_pilot_conduit_error(GNOME_PILOT_CONDUIT(c),
- _("Could not start gnomecal server"));
+ if (start_calendar_server (ctxt) != 0) {
+ WARN(_("Could not start wombat server"));
+ gnome_pilot_conduit_error (conduit, _("Could not start wombat"));
return -1;
}
-
+ /* Get the local database */
+ ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO);
+
+ /* Load the uid <--> pilot id mapping */
+ ctxt->map = g_hash_table_new (g_int_hash, g_int_equal);
+ memset (&handler, 0, sizeof (xmlSAXHandler));
+ handler.startElement = map_sax_start_element;
+
+ filename = map_name (ctxt);
+ ret = map_sax_parse (&handler, ctxt, filename);
+ if (ret < 0)
+ return ret;
+
+ g_free (filename);
+
+ /* Find the added, modified and deleted items */
+ changes = cal_client_get_changed_uids (ctxt->client, CALOBJ_TYPE_TODO, 0);
+ for (l = changes; l != NULL; l = l->next) {
+ CalObjChange *coc = l->data;
+
+ switch (coc->type) {
+ case CALOBJ_UPDATED:
+ if (g_hash_table_lookup (ctxt->map, coc->uid))
+ ctxt->modified = g_list_prepend (ctxt->modified, coc);
+ else
+ ctxt->added = g_list_prepend (ctxt->added, coc);
+ break;
+ case CALOBJ_REMOVED:
+ ctxt->deleted = g_list_prepend (ctxt->deleted, coc);
+ break;
+ }
+ }
+ g_list_free (changes);
+
+ /* Set the count information */
num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO);
- gnome_pilot_conduit_standard_abs_set_num_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records);
+ gnome_pilot_conduit_standard_abs_set_num_local_records(abs_conduit, num_records);
+ num_records = g_list_length (ctxt->added);
+ gnome_pilot_conduit_standard_abs_set_num_new_local_records (abs_conduit, num_records);
+ num_records = g_list_length (ctxt->modified);
+ gnome_pilot_conduit_standard_abs_set_num_updated_local_records (abs_conduit, num_records);
+ num_records = g_list_length (ctxt->deleted);
+ gnome_pilot_conduit_standard_abs_set_num_deleted_local_records(abs_conduit, num_records);
- /* FIX ME How are we going to fill in these fields? */
- num_records = 0;
- gnome_pilot_conduit_standard_abs_set_num_updated_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records);
- gnome_pilot_conduit_standard_abs_set_num_new_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records);
- gnome_pilot_conduit_standard_abs_set_num_deleted_local_records(GNOME_PILOT_CONDUIT_STANDARD_ABS(c), num_records);
+ gtk_object_set_data (GTK_OBJECT (conduit), "dbinfo", dbi);
- gtk_object_set_data (GTK_OBJECT(c), "dbinfo", dbi);
-
buf = (unsigned char*)g_malloc (0xffff);
- l = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
+ len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
(unsigned char *)buf, 0xffff);
- if (l < 0) {
- WARN(_("Could not read pilot's ToDo application block"));
- WARN("dlp_ReadAppBlock(...) = %d",l);
- gnome_pilot_conduit_error(GNOME_PILOT_CONDUIT(c),
- _("Could not read pilot's ToDo application block"));
+ if (len < 0) {
+ WARN (_("Could not read pilot's ToDo application block"));
+ WARN ("dlp_ReadAppBlock(...) = %d", len);
+ gnome_pilot_conduit_error (conduit,
+ _("Could not read pilot's ToDo application block"));
return -1;
}
- unpack_ToDoAppInfo (&(ctxt->ai), buf, l);
+ unpack_ToDoAppInfo (&(ctxt->ai), buf, len);
g_free (buf);
- check_for_slow_setting (c, ctxt);
+ check_for_slow_setting (conduit, ctxt);
return 0;
}
-/**
- * Find (if possible) the local record which matches
- * the given PilotRecord.
- * if successfull, return non-zero and set *local to
- * a non-null value (the located local record),
- * otherwise return 0 and set *local = NULL;
- */
+static gint
+update_record (GnomePilotConduitStandardAbs *conduit,
+ PilotRecord *remote,
+ EToDoConduitContext *ctxt)
+{
+ CalComponent *comp;
+ CalClientGetStatus status;
+ struct ToDo todo;
+ const char *uid;
+
+ LOG ("update_record\n");
+
+ g_return_val_if_fail (remote != NULL, -1);
+
+ memset (&todo, 0, sizeof (struct ToDo));
+ unpack_ToDo (&todo, remote->record, remote->length);
+
+ uid = g_hash_table_lookup (ctxt->map, &remote->ID);
+
+ if (uid)
+ status = cal_client_get_object (ctxt->client, uid, &comp);
+ else
+ status = CAL_CLIENT_LOAD_ERROR;
+
+ if (status != CAL_CLIENT_GET_SUCCESS) {
+ comp = comp_from_remote_record (conduit, remote, NULL);
+ } else {
+ CalComponent *new_comp;
+
+ LOG ("succeeded %s\n", cal_component_get_as_string (comp));
+
+ new_comp = comp_from_remote_record (conduit, remote, comp);
+ gtk_object_unref (GTK_OBJECT (comp));
+ comp = new_comp;
+ }
+
+ update_comp (conduit, comp, ctxt);
+
+ if (!uid) {
+ guint32 *pid = g_new (guint32, 1);
+
+ *pid = remote->ID;
+ cal_component_get_uid (comp, &uid);
+ g_hash_table_insert (ctxt->map, pid, g_strdup (uid));
+ }
+
+ gtk_object_unref (GTK_OBJECT (comp));
+ free_ToDo(&todo);
+
+ return 0;
+}
static gint
-match_record (GnomePilotConduitStandardAbs *conduit,
- EToDoLocalRecord **local,
- PilotRecord *remote,
- EToDoConduitContext *ctxt)
+match_record (GnomePilotConduitStandardAbs *conduit,
+ EToDoLocalRecord **local,
+ PilotRecord *remote,
+ EToDoConduitContext *ctxt)
{
+ char *uid;
+
LOG ("match_record: looking for local copy of %s\n",
- print_remote (remote));
-
+ print_remote (remote));
+
g_return_val_if_fail (local != NULL, -1);
g_return_val_if_fail (remote != NULL, -1);
- *local = find_record_in_repository (conduit, remote, ctxt);
+ uid = g_hash_table_lookup (ctxt->map, &remote->ID);
+
+ if (!uid)
+ return -1;
+ *local = g_new0 (EToDoLocalRecord, 1);
+ local_record_from_uid (*local, uid, ctxt);
+
if (*local == NULL)
- LOG (" match_record: not found.\n");
- else
- LOG (" match_record: found, %s\n",
- print_local (*local));
-
- if (*local == NULL)
return -1;
-
+
return 0;
}
-/**
- * Free the data allocated by a previous match_record call.
- * If successfull, return non-zero and ser *local=NULL, otherwise
- * return 0.
- */
static gint
-free_match (GnomePilotConduitStandardAbs *conduit,
- EToDoLocalRecord **local,
- EToDoConduitContext *ctxt)
+free_match (GnomePilotConduitStandardAbs *conduit,
+ EToDoLocalRecord **local,
+ EToDoConduitContext *ctxt)
{
LOG ("free_match: %s\n", print_local (*local));
g_return_val_if_fail (local != NULL, -1);
g_return_val_if_fail (*local != NULL, -1);
+ gtk_object_unref (GTK_OBJECT ((*local)->comp));
g_free (*local);
*local = NULL;
return 0;
}
-/*
- Move to archive and set status to Nothing
- */
static gint
archive_local (GnomePilotConduitStandardAbs *conduit,
EToDoLocalRecord *local,
@@ -731,9 +780,6 @@ archive_local (GnomePilotConduitStandardAbs *conduit,
return -1;
}
-/*
- Store in archive and set status to Nothing
- */
static gint
archive_remote (GnomePilotConduitStandardAbs *conduit,
EToDoLocalRecord *local,
@@ -741,30 +787,29 @@ archive_remote (GnomePilotConduitStandardAbs *conduit,
EToDoConduitContext *ctxt)
{
LOG ("archive_remote: doing nothing with %s\n",
- print_local (local));
-
-/* g_return_val_if_fail(remote!=NULL,-1); */
-/* g_return_val_if_fail(local!=NULL,-1); */
-
+ print_local (local));
+
+ g_return_val_if_fail (remote != NULL, -1);
+ g_return_val_if_fail (local != NULL, -1);
+
return -1;
}
-/*
- Store and set status to Nothing
- */
static gint
store_remote (GnomePilotConduitStandardAbs *conduit,
PilotRecord *remote,
EToDoConduitContext *ctxt)
{
+ int ret;
+
g_return_val_if_fail (remote != NULL, -1);
LOG ("store_remote: copying pilot record %s to desktop\n",
print_remote (remote));
- remote->attr = GnomePilotRecordNothing;
+ ret = update_record (conduit, remote, ctxt);
- return update_record (conduit, remote, ctxt);
+ return ret;
}
static gint
@@ -784,59 +829,48 @@ iterate (GnomePilotConduitStandardAbs *conduit,
EToDoLocalRecord **local,
EToDoConduitContext *ctxt)
{
- static GSList *events,*iterator;
- static int hest;
+ static GList *uids, *iterator;
+ static int count;
g_return_val_if_fail (local != NULL, -1);
if (*local == NULL) {
LOG ("beginning iteration");
- events = get_calendar_objects (conduit, NULL, ctxt);
- hest = 0;
+ uids = ctxt->uids;
+ count = 0;
- if (events != NULL) {
- LOG ("iterating over %d records", g_slist_length (events));
+ if (uids != NULL) {
+ LOG ("iterating over %d records", g_list_length (uids));
+
*local = g_new0 (EToDoLocalRecord, 1);
+ local_record_from_uid (*local, uids->data, ctxt);
- local_record_from_comp_uid (*local,
- (gchar*)events->data,
- ctxt);
- iterator = events;
+ iterator = uids;
} else {
LOG ("no events");
(*local) = NULL;
+ return -1;
}
} else {
- LOG ("continuing iteration\n");
- hest++;
- if (g_slist_next (iterator) == NULL) {
- GSList *l;
+ count++;
+ if (g_list_next (iterator)) {
+ iterator = g_list_next (iterator);
- LOG ("ending");
- /** free stuff allocated for iteration */
- g_free((*local));
-
- LOG ("iterated over %d records", hest);
- for (l=events; l; l = l->next)
- g_free (l->data);
+ *local = g_new0 (EToDoLocalRecord, 1);
+ local_record_from_uid (*local, iterator->data, ctxt);
+ } else {
+ LOG ("iteration ending");
- g_slist_free (events);
+ /* Tell the pilot the iteration is over */
+ *local = NULL;
- /* ends iteration */
- (*local) = NULL;
return 0;
- } else {
- iterator = g_slist_next (iterator);
- local_record_from_comp_uid(*local,
- (gchar*)(iterator->data),
- ctxt);
}
}
return 1;
}
-
static gint
iterate_specific (GnomePilotConduitStandardAbs *conduit,
EToDoLocalRecord **local,
@@ -844,44 +878,88 @@ iterate_specific (GnomePilotConduitStandardAbs *conduit,
gint archived,
EToDoConduitContext *ctxt)
{
- (*local) = NULL; /* ??? */
+ static GList *changes, *iterator;
+ static int count;
- /* debugging */
- {
- const char *tmp = gnome_pilot_status_to_string (flag);
- LOG ("\niterate_specific: (flag = %s)... ", tmp);
- }
+ g_return_val_if_fail (local != NULL, 0);
- g_return_val_if_fail (local != NULL, -1);
+ /* FIX ME Hack - gnome-pilot does not recognize iterate_specific err values */
+ if (*local == NULL) {
+ LOG ("beginning iteration for %s\n", status_to_string (flag));
- /* iterate until a record meets the criteria */
- while (gnome_pilot_conduit_standard_abs_iterate (conduit,
- (LocalRecord**)local)) {
- if ((*local) == NULL)
+ switch (flag) {
+ case GnomePilotRecordNew:
+ changes = ctxt->added;
break;
- if (archived && ((*local)->local.archived == archived))
+ case GnomePilotRecordModified:
+ changes = ctxt->modified;
break;
- if (((*local)->local.attr == flag))
+ case GnomePilotRecordDeleted:
+ changes = ctxt->deleted;
break;
- }
+ }
+
+ count = 0;
+
+ if (changes != NULL) {
+ CalObjChange *coc = changes->data;
+
+ LOG ("iterating over %d records", g_list_length (changes));
+
+ *local = g_new0 (EToDoLocalRecord, 1);
+ local_record_from_uid (*local, coc->uid, ctxt);
- if ((*local))
- LOG (" found %s\n", print_local (*local));
- else
- LOG (" no more found.\n");
+ iterator = changes;
+ } else {
+ LOG ("no events");
+ (*local) = NULL;
+ return 0;
+ }
+ } else {
+ count++;
+ if (g_list_next (iterator)) {
+ CalObjChange *coc;
+
+ iterator = g_list_next (iterator);
+ coc = iterator->data;
+
+ *local = g_new0 (EToDoLocalRecord, 1);
+ local_record_from_uid (*local, coc->uid, ctxt);
+ } else {
+ LOG ("iteration ending");
- return (*local) == NULL ? 0 : 1;
+ /* Tell the pilot the iteration is over */
+ (*local) = NULL;
+
+ return 0;
+ }
+ }
+
+ return 1;
}
static gint
purge (GnomePilotConduitStandardAbs *conduit,
EToDoConduitContext *ctxt)
{
- LOG ("purge: doing nothing\n");
+ GList *l;
+ char *filename;
+ int ret = 0;
+
+ LOG ("purge\n");
+
+ /* FIX ME report an error */
+ for (l = ctxt->deleted; l != NULL; l = l->next) {
+ CalObjChange *coc = l->data;
+
+ cal_client_remove_object (ctxt->client, coc->uid);
+ }
- /* HEST, gem posterne her */
+ filename = map_name (ctxt);
+ ret = map_write (ctxt, filename);
+ g_free (filename);
- return -1;
+ return ret;
}
@@ -891,37 +969,28 @@ set_status (GnomePilotConduitStandardAbs *conduit,
gint status,
EToDoConduitContext *ctxt)
{
- gboolean success;
-
- LOG ("set_status: %s status is now '%s' for %s\n",
- print_local (local),
- gnome_pilot_status_to_string (status),
- cal_component_get_as_string (local->comp));
+ CalObjChange *coc;
g_return_val_if_fail (local != NULL, -1);
g_assert (local->comp != NULL);
-
- local->local.attr = status;
- if (status == GnomePilotRecordDeleted) {
- const char *uid;
- cal_component_get_uid (local->comp, &uid);
- success = cal_client_remove_object (ctxt->client, uid);
- } else {
- const char *uid;
- unsigned long *pilot_id;
- cal_component_get_uid (local->comp, &uid);
- cal_component_get_pilot_id (local->comp, &pilot_id);
+ LOG ("set_status: %s status is now '%s' for %s\n",
+ print_local (local),
+ status_to_string (status),
+ cal_component_get_as_string (local->comp));
- success = cal_client_update_object (ctxt->client, local->comp);
- cal_client_update_pilot_id (ctxt->client, (char *) uid,
- *pilot_id, status);
+ /* FIX ME New and modified? */
+ switch (status) {
+ case GnomePilotRecordNew:
+ break;
+ case GnomePilotRecordModified:
+ break;
+ case GnomePilotRecordDeleted:
+ coc = g_new0 (CalObjChange, 1);
+ ctxt->deleted = g_list_prepend (ctxt->deleted, coc);
+ break;
}
- if (!success) {
- WARN (_("Error while communicating with calendar server"));
- }
-
return 0;
}
@@ -938,10 +1007,12 @@ set_archived (GnomePilotConduitStandardAbs *conduit,
g_assert(local->comp!=NULL);
local->local.archived = archived;
- update_calendar_entry_in_repository(conduit,local->comp,ctxt);
+ update_comp (conduit, local->comp, ctxt);
+
/* FIXME: This should move the entry into a speciel
calendar file, eg. Archive, or (by config option), simply
delete it */
+
return 0;
}
@@ -952,24 +1023,11 @@ set_pilot_id (GnomePilotConduitStandardAbs *conduit,
EToDoConduitContext *ctxt)
{
const char *uid;
- unsigned long *pilot_status;
-
- LOG ("set_pilot_id: %s pilot ID is now '%d'\n",
- print_local (local), ID);
-
- g_return_val_if_fail(local!=NULL,-1);
- g_assert(local->comp!=NULL);
-
- local->local.ID = ID;
- cal_component_set_pilot_id (local->comp, (unsigned long *)&ID);
-
+ guint32 *pid = g_new (guint32, 1);
+
cal_component_get_uid (local->comp, &uid);
- cal_component_get_pilot_status (local->comp, &pilot_status);
-
- cal_client_update_pilot_id (ctxt->client,
- (char *) uid,
- local->local.ID,
- *pilot_status);
+ *pid = ID;
+ g_hash_table_insert (ctxt->map, pid, g_strdup (uid));
return 0;
}
@@ -980,80 +1038,13 @@ transmit (GnomePilotConduitStandardAbs *conduit,
PilotRecord **remote,
EToDoConduitContext *ctxt)
{
- PilotRecord *p;
- int *priority;
- struct icaltimetype *completed;
- CalComponentText summary;
- GSList *d_list = NULL;
- CalComponentText *description;
- CalComponentDateTime due;
- time_t due_time;
- CalComponentClassification classif;
-
LOG ("transmit: encoding local %s\n", print_local (local));
- g_return_val_if_fail (local != NULL,-1);
- g_return_val_if_fail (remote != NULL,-1);
- g_assert (local->comp != NULL);
-
- p = g_new0 (PilotRecord,1);
-
- p->ID = local->local.ID;
- p->attr = local->local.attr;
- p->archived = local->local.archived;
- p->secret = local->local.secret;
-
- local->todo = g_new0 (struct ToDo,1);
-
- /* STOP: don't replace these with g_strdup, since free_ToDo
- uses free to deallocate */
- cal_component_get_summary (local->comp, &summary);
- if (summary.value)
- local->todo->description = strdup ((char *) summary.value);
-
- cal_component_get_description_list (local->comp, &d_list);
- if (d_list) {
- description = (CalComponentText *) d_list->data;
- if (description && description->value)
- local->todo->note = strdup (description->value);
- else
- local->todo->note = NULL;
- } else {
- local->todo->note = NULL;
- }
-
- cal_component_get_due (local->comp, &due);
- if (due.value) {
- due_time = icaltime_as_timet (*due.value);
-
- local->todo->due = *localtime (&due_time);
- local->todo->indefinite = 0;
- } else {
- local->todo->indefinite = 1;
- }
-
- cal_component_get_completed (local->comp, &completed);
- if (completed) {
- local->todo->complete = 1;
- cal_component_free_icaltimetype (completed);
- }
-
- cal_component_get_priority (local->comp, &priority);
- if (priority) {
- local->todo->priority = *priority;
- cal_component_free_priority (priority);
- }
-
- cal_component_get_classification (local->comp, &classif);
- if (classif == CAL_COMPONENT_CLASS_PRIVATE)
- p->attr = p->attr & dlpRecAttrSecret;
-
- /* Generate pilot record structure */
- p->record = g_new0 (char,0xffff);
- p->length = pack_ToDo (local->todo, p->record, 0xffff);
-
- *remote = p;
+ *remote = local_record_to_pilot_record (local, ctxt);
+ if (!*remote)
+ return -1;
+
return 0;
}
@@ -1063,14 +1054,12 @@ free_transmit (GnomePilotConduitStandardAbs *conduit,
PilotRecord **remote,
EToDoConduitContext *ctxt)
{
- LOG ("free_transmit: freeing %s\n",
- print_local (local));
+ LOG ("free_transmit: freeing %s\n", print_local (local));
g_return_val_if_fail (local != NULL, -1);
g_return_val_if_fail (remote != NULL, -1);
- /* free_ToDo(local->todo); */ /* FIX ME is this needed? */
- g_free ((*remote)->record);
+ g_free (*remote);
*remote = NULL;
return 0;
@@ -1084,9 +1073,8 @@ compare (GnomePilotConduitStandardAbs *conduit,
EToDoConduitContext *ctxt)
{
/* used by the quick compare */
- PilotRecord *remoteOfLocal;
- int err;
- int retval;
+ PilotRecord *local_pilot;
+ int retval = 0;
LOG ("compare: local=%s remote=%s...\n",
print_local (local), print_remote (remote));
@@ -1094,31 +1082,21 @@ compare (GnomePilotConduitStandardAbs *conduit,
g_return_val_if_fail (local!=NULL,-1);
g_return_val_if_fail (remote!=NULL,-1);
- err = transmit(conduit,local,&remoteOfLocal,ctxt);
- if (err != 0) return err;
+ local_pilot = local_record_to_pilot_record (local, ctxt);
+ if (!local_pilot)
+ return -1;
- retval = 0;
- if (remote->length == remoteOfLocal->length) {
- if (memcmp (remoteOfLocal->record,
- remote->record, remote->length)!=0) {
- LOG (" compare failed on contents\n");
- retval = 1;
- }
- } else {
- LOG(" compare failed on length\n");
+ if (remote->length != local_pilot->length
+ || memcmp (local_pilot->record, remote->record, remote->length))
retval = 1;
- }
-
- if (retval == 0) {
+ if (retval == 0)
LOG (" match.\n");
- } else {
- /* debug spew */
- LOG (" local:%s\n", print_remote (remoteOfLocal));
- LOG (" remote:%s\n", print_remote (remote));
- }
-
- free_transmit(conduit,local,&remoteOfLocal,ctxt);
+ else
+ LOG (" did not match");
+
+ g_free (local_pilot);
+
return retval;
}
@@ -1134,6 +1112,8 @@ compare_backup (GnomePilotConduitStandardAbs *conduit,
g_return_val_if_fail(local!=NULL,-1);
g_return_val_if_fail(remote!=NULL,-1);
+ /* FIX ME - What the hell? */
+
return -1;
}
@@ -1142,25 +1122,21 @@ static gint
delete_all (GnomePilotConduitStandardAbs *conduit,
EToDoConduitContext *ctxt)
{
- GSList *events,*it;
- gboolean error;
+ GList *uids, *it;
gboolean success;
- events = get_calendar_objects(conduit,&error,ctxt);
-
LOG ("delete_all: deleting all objects from desktop\n");
- if (error == FALSE) return -1;
- for (it=events; it; it = g_slist_next (it)) {
+ uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO);
+
+ for (it = uids; it != NULL; it = g_list_next (it)) {
success = cal_client_remove_object (ctxt->client, it->data);
if (!success)
INFO ("Object did not exist");
-
- g_free (it->data);
}
+ cal_obj_uid_list_free (uids);
- g_slist_free (events);
return 0;
}
@@ -1176,7 +1152,7 @@ accept_all_cookies (CORBA_unsigned_long request_id,
GnomePilotConduit *
-conduit_get_gpilot_conduit (guint32 pilotId)
+conduit_get_gpilot_conduit (guint32 pilot_id)
{
GtkObject *retval;
EToDoConduitContext *ctxt;
@@ -1202,9 +1178,9 @@ conduit_get_gpilot_conduit (guint32 pilotId)
g_assert (retval != NULL);
gnome_pilot_conduit_construct (GNOME_PILOT_CONDUIT (retval),
- "ToDoConduit");
+ "e_todo_conduit");
- e_todo_context_new (&ctxt, pilotId);
+ e_todo_context_new (&ctxt, pilot_id);
gtk_object_set_data (GTK_OBJECT (retval), "todoconduit_context", ctxt);
gtk_signal_connect (retval, "match_record", (GtkSignalFunc) match_record, ctxt);