evolution-data-server r8439 - trunk/calendar/backends/google



Author: ebbyw
Date: Mon Jan 28 15:14:33 2008
New Revision: 8439
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8439&view=rev

Log:
 2008-01-28 Ebby Wiselyn <ebbywiselyn gmail com>  ** Google Calendar fixes  **  


Modified:
   trunk/calendar/backends/google/e-cal-backend-google.c

Modified: trunk/calendar/backends/google/e-cal-backend-google.c
==============================================================================
--- trunk/calendar/backends/google/e-cal-backend-google.c	(original)
+++ trunk/calendar/backends/google/e-cal-backend-google.c	Mon Jan 28 15:14:33 2008
@@ -78,6 +78,7 @@
 	gchar *password;
 	gchar *uri;
 	gchar *feed;
+	gchar *local_attachments_store;	
 
 	gboolean read_only;
 	gboolean mode_changed;
@@ -198,7 +199,7 @@
 			return GNOME_Evolution_Calendar_OtherError;
 		}
 		icaltimezone_free (zone, 1);
-	}
+	}else {g_printf ("\n %s, %s", G_STRLOC, "Else case: Need a check");}
 	return GNOME_Evolution_Calendar_Success;
 }
 
@@ -299,8 +300,8 @@
 	priv = cbgo->priv;
 
 	g_mutex_lock (priv->mutex);
-
 	search_needed = FALSE;
+
 	cbsexp = e_cal_backend_sexp_new (sexp);
 
 	if (!cbsexp) {
@@ -343,6 +344,7 @@
 	status = e_cal_backend_google_get_object_list (E_CAL_BACKEND_SYNC(backend), NULL, e_data_cal_view_get_text (query), &objects);
 
 	if (status != GNOME_Evolution_Calendar_Success) {
+		g_printf ("\n FAILS %s", G_STRLOC);
 		e_data_cal_view_notify_done (query, status);
 		return;
 	}
@@ -393,7 +395,7 @@
 	cbgo = (ECalBackendGoogle *) backend;
 
 	g_return_val_if_fail(E_IS_CAL_BACKEND_GOOGLE(cbgo), GNOME_Evolution_Calendar_OtherError);
-	g_return_val_if_fail(tzobj!=NULL, GNOME_Evolution_Calendar_OtherError);
+	g_return_val_if_fail(tzobj != NULL, GNOME_Evolution_Calendar_OtherError);
 
 	priv = cbgo->priv;
 	tz_comp = icalparser_parse_string (tzobj);
@@ -454,22 +456,383 @@
 	g_mutex_unlock (priv->mutex);
 }
 
+static void
+in_offline (ECalBackendGoogle *cbgo)
+{
+	ECalBackendGooglePrivate *priv;
+
+	priv = cbgo->priv;
+	priv->read_only = TRUE;
+
+	if (priv->timeout_id) {
+		g_source_remove (priv->timeout_id);
+		priv->timeout_id = 0;
+	}
+
+	/* Remove the Connection Object */
+	if (priv->service) {
+		g_object_unref (priv->service);
+		priv->service = NULL;	
+	}
+}
+
+static void
+fetch_attachments (ECalBackendGoogle *cbgo, ECalComponent *comp) 
+{
+	GSList *attach_list = NULL, *new_attach_list = NULL;
+	GSList *l = NULL;
+	const char *uid;	
+	gchar *attach_store, *dest_file, *dest_url;
+	int fd;	
+
+	e_cal_component_get_attachment_list (comp, &attach_list);
+	e_cal_component_get_uid (comp, &uid);
+	
+	attach_store = g_strdup(e_cal_backend_google_get_local_attachments_store (cbgo));
+
+	for (l = attach_list; l; l = l->next) {	
+		char *sfname = (char *)l->data;
+		char *filename, *new_filename;
+		GMappedFile *mapped_file;
+		GError *error = NULL;
+	
+		mapped_file = g_mapped_file_new (sfname, FALSE, &error);
+		if (!mapped_file) {	
+			g_message ("DEBUG: could not map %s: %s \n", 
+			sfname, error->message);
+			g_error_free (error);
+			continue;
+		}
+	
+		filename = g_path_get_basename (sfname);
+		new_filename = g_strconcat (uid, "-", filename, NULL);
+		g_free (filename);	
+		dest_file = g_build_filename (attach_store, new_filename, NULL);
+		g_free (new_filename);
+		fd = g_open (dest_file, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
+		if (fd == -1) {
+			/* TODO handle error conditions */
+			g_message ("DEBUG: could not open %s for writing\n",
+					dest_file);
+		} else if (write (fd, g_mapped_file_get_contents (mapped_file),
+				      g_mapped_file_get_length (mapped_file)) == -1) {
+			g_message ("DEBUG: attachment write failed.\n");
+		}
+
+		g_mapped_file_free (mapped_file);
+		if (fd != -1)
+			close (fd);	
+		dest_url = g_filename_to_uri (dest_file, NULL, NULL);
+		g_free (dest_url);
+		new_attach_list = g_slist_append (new_attach_list, dest_url);	 
+	}	
+	g_free (attach_store);
+	e_cal_component_set_attachment_list (comp, new_attach_list);
+}	
+
+ECalBackendSyncStatus 
+static receive_object (ECalBackendGoogle *cbgo, EDataCal *cal, icalcomponent *icalcomp)
+{
+	ECalBackendGooglePrivate *priv;
+	EGoItem *item = NULL;
+	GDataEntry *entry = NULL;
+	ECalComponent *comp, *modif_comp;
+	GSList *comps = NULL, *l = NULL;
+	icalproperty_method method;
+	icalproperty *icalprop;
+	gboolean instances = TRUE, found;
+	icalparameter_partstat pstatus = 0;
+
+	priv = cbgo->priv;
+	icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);	
+	while (icalprop) {
+		const char *x_name;
+		x_name	= icalproperty_get_x_name (icalprop);
+		
+		/* FIXME Set the Property for Google */	
+		if (!strcmp (x_name, "X-GW-RECUR-INSTANCES-MOD-TYPE")) {
+			instances = TRUE;	
+			icalcomponent_remove_property (icalcomp, icalprop);	
+			break;
+		}
+		icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+	}
+	
+	comp = e_cal_component_new ();
+	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+	method = icalcomponent_get_method (icalcomp);	
+
+	/* Attachments */
+	if (e_cal_component_has_attachments (comp)) 
+		fetch_attachments (cbgo, comp);
+	 
+	/* Sent to Server */
+	item = e_go_item_from_cal_component (cbgo, comp);	
+	entry =	e_go_item_get_entry (item);
+
+	if (!GDATA_IS_ENTRY(entry))
+		return GNOME_Evolution_Calendar_InvalidObject;	
+
+	gdata_service_insert_entry (GDATA_SERVICE(priv->service), priv->uri, entry);
+
+	/* Update the Cache */
+
+	/* FIXME get the modified entry after insertion*/
+	modif_comp = g_object_ref (comp);
+	if (instances) {
+		const char *uid;
+		found = FALSE;	
+
+		e_cal_component_get_uid (modif_comp, &uid);
+		comps = e_cal_backend_cache_get_components_by_uid (priv->cache, uid);
+
+		if (!comps) 	
+			comps = g_slist_append (comps, g_object_ref (modif_comp));
+		else	
+			found = TRUE;
+	} else {
+		ECalComponentId *id = e_cal_component_get_id (modif_comp);
+		ECalComponent *component = NULL;
+
+		component = e_cal_backend_cache_get_component (priv->cache, id->uid, id->rid);
+
+		if (!component)
+			comps = g_slist_append (comps, g_object_ref (modif_comp));
+		else {
+			comps = g_slist_append (comps, component);
+			found = TRUE;
+		}
+
+		e_cal_component_free_id (id);	
+	}
+
+	for (l = comps; l != NULL; l = l->next) {
+		ECalComponent *component = E_CAL_COMPONENT (l->data);
+
+		if (pstatus == ICAL_PARTSTAT_DECLINED) {
+			ECalComponentId *id = e_cal_component_get_id (component);
+
+			if (e_cal_backend_cache_remove_component (priv->cache, id->uid, id->rid)) {
+
+				e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgo), id, e_cal_component_get_as_string (component), NULL);
+				e_cal_component_free_id (id);
+
+			}
+
+		} 
+		else {
+			char *comp_str = NULL;
+
+			/* change_status (component, pstatus, e_gw_connection_get_user_email (priv->cnc)); */
+			e_cal_backend_cache_put_component (priv->cache, component);
+			comp_str = e_cal_component_get_as_string (component);
+
+			if (found)
+				e_cal_backend_notify_object_modified (E_CAL_BACKEND (cbgo), comp_str, comp_str);
+			else
+				e_cal_backend_notify_object_created (E_CAL_BACKEND (cbgo), comp_str);
+
+			g_free (comp_str);
+		}
+	}
+
+	g_slist_foreach (comps, (GFunc) g_object_unref, NULL);
+	g_slist_free (comps);
+	g_object_unref (comp);
+	g_object_unref (modif_comp);
+
+	return GNOME_Evolution_Calendar_Success;
+}
+
 static ECalBackendSyncStatus
 e_cal_backend_google_receive_objects (ECalBackendSync *backend, EDataCal *cal, const char *calobj)
 {
-	/* FIXME Not implemented */
-	return GNOME_Evolution_Calendar_Success;
+	ECalBackendGoogle *cbgo;
+	ECalBackendGooglePrivate *priv;
+	icalcomponent *icalcomp, *subcomp;
+	icalcomponent_kind kind;
+	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_Success;
+		
+	cbgo = (ECalBackendGoogle *)backend;
+	priv = cbgo->priv;
+
+	if (priv->mode == CAL_MODE_LOCAL) {
+		in_offline (cbgo);
+		return GNOME_Evolution_Calendar_RepositoryOffline;
+	}
+	
+	icalcomp = icalparser_parse_string (calobj);	
+	if (!icalcomp)
+		return GNOME_Evolution_Calendar_InvalidObject;
+
+	kind = icalcomponent_isa (icalcomp);
+	if (kind == ICAL_VCALENDAR_COMPONENT) {
+		subcomp = icalcomponent_get_first_component (icalcomp, e_cal_backend_get_kind (E_CAL_BACKEND(backend)));
+		
+		while (subcomp) {
+			icalcomponent_set_method (subcomp, icalcomponent_get_method (icalcomp));
+			status = receive_object (cbgo, cal, subcomp);	
+		
+			if (status != GNOME_Evolution_Calendar_Success)	
+				break;
+			subcomp = icalcomponent_get_next_component (icalcomp, e_cal_backend_get_kind (E_CAL_BACKEND(backend)));
+		}
+	} else if (kind == e_cal_backend_get_kind (E_CAL_BACKEND(backend))) {	
+		status = receive_object (cbgo, cal, icalcomp);
+	} else 
+		status = GNOME_Evolution_Calendar_InvalidObject;	
+
+	icalcomponent_free (icalcomp);
+
+	return status;
+}
+
+static ECalBackendSyncStatus 
+send_object (ECalBackendGoogle *cbgo, EDataCal *cal, icalcomponent *icalcomp, icalproperty_method method)
+{
+	ECalComponent *comp, *found_comp = NULL;
+	ECalBackendGooglePrivate *priv;
+	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_OtherError;
+	const char *uid, *rid;
+
+	priv = cbgo->priv;
+	comp = e_cal_component_new ();
+	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));	
+	rid = e_cal_component_get_recurid_as_string (comp);	
+
+	e_cal_component_get_uid (comp, (const char **)&uid);
+	found_comp = e_cal_backend_cache_get_component (priv->cache, uid, NULL);
+
+	if (!found_comp) {
+		g_object_unref (comp);
+		return GNOME_Evolution_Calendar_InvalidObject;
+	}
+
+	status = GNOME_Evolution_Calendar_Success;	
+	/* TODO Check if connection exists */
+	switch (priv->mode) {
+		case CAL_MODE_ANY:
+		case CAL_MODE_REMOTE: 	
+			if (method == ICAL_METHOD_CANCEL) {
+				gboolean instances = FALSE;
+				if (instances) {
+					char *old_object = NULL;
+					GSList *l = NULL, *comp_list;
+					comp_list = e_cal_backend_cache_get_components_by_uid (priv->cache, uid);
+		
+					for (l = comp_list; l; l = l->next) {
+						ECalComponent *component = E_CAL_COMPONENT (l->data);
+						ECalComponentId *cid = e_cal_component_get_id (component);
+						char *object = e_cal_component_get_as_string (component);
+
+						if (e_cal_backend_cache_remove_component (priv->cache, cid->uid,
+									cid->rid))
+							e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgo), cid, object, NULL);
+
+						e_cal_component_free_id (cid);
+						g_free (object);
+						g_object_unref (component);
+					}
+						
+					g_slist_free (comp_list);	
+					g_free (old_object);
+				} else {
+					ECalComponentId *cid;
+					char * object;
+
+					cid = e_cal_component_get_id (comp);
+					icalcomp = e_cal_component_get_icalcomponent (comp);
+					object = e_cal_component_get_as_string (comp);
+
+					if (e_cal_backend_cache_remove_component (priv->cache, cid->uid,
+								cid->rid)) {
+						e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgo), cid,
+							object, NULL);
+					}
+
+					g_free (object);
+					e_cal_component_free_id (cid);
+				}	
+			}
+			break;
+		case CAL_MODE_LOCAL:
+			status = GNOME_Evolution_Calendar_RepositoryOffline;
+			break;
+		default: 
+			break;
+	}
+
+	g_object_unref (comp);
+	g_object_unref (found_comp);
+
+	return status;
 }
 
 static ECalBackendSyncStatus
 e_cal_backend_google_send_objects (ECalBackendSync *backend, EDataCal *cal, const char *calobj, GList **users, char **modified_calobj)
 {
-	/* FIXME Not Implemented */
-	return GNOME_Evolution_Calendar_Success;
+	ECalBackendGoogle *cbgo;
+	ECalBackendGooglePrivate *priv;
+	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_Success;
+	icalcomponent *icalcomp, *subcomp;
+	icalcomponent_kind kind;
+	icalproperty_method method;
+		
+	cbgo = E_CAL_BACKEND_GOOGLE(backend);
+	priv = cbgo->priv;
+	if (priv->mode == CAL_MODE_LOCAL) {
+		in_offline (cbgo);
+		return GNOME_Evolution_Calendar_RepositoryOffline;
+	}
+
+	icalcomp = icalparser_parse_string (calobj);
+	if (!icalcomp)
+		return GNOME_Evolution_Calendar_InvalidObject;
+	
+	method = icalcomponent_get_method (icalcomp);
+	kind = icalcomponent_isa (icalcomp);
+	
+	if (kind == ICAL_VCALENDAR_COMPONENT) {		
+		subcomp = icalcomponent_get_first_component (icalcomp, e_cal_backend_get_kind(E_CAL_BACKEND(backend)));
+		while (subcomp) {
+			status = send_object (cbgo, cal, subcomp, method);
+				
+			if (status != GNOME_Evolution_Calendar_Success)
+				break;
+			subcomp = icalcomponent_get_next_component (icalcomp, e_cal_backend_get_kind (E_CAL_BACKEND(backend)));
+		}
+	} else if (kind == e_cal_backend_get_kind (E_CAL_BACKEND(backend))) {
+		status = send_object (cbgo, cal, icalcomp, method);	
+	} else 
+		status = GNOME_Evolution_Calendar_InvalidObject;		
+	if (status == GNOME_Evolution_Calendar_Success) {
+		ECalComponent *comp;
+
+		comp = e_cal_component_new ();
+
+		if (e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp))) {
+			GSList *attendee_list = NULL, *tmp;
+			e_cal_component_get_attendee_list (comp, &attendee_list);
+			/* convert this into GList */
+			for (tmp = attendee_list; tmp; tmp = g_slist_next (tmp)) {
+				const char *attendee = tmp->data;
+
+				if (attendee)
+					*users = g_list_append (*users, g_strdup (attendee));
+			}
+
+			g_object_unref (comp);
+		}
+		*modified_calobj = g_strdup (calobj);
+	}
+	g_printf ("\n %s, %s \n", *modified_calobj, G_STRLOC);	
+	icalcomponent_free (icalcomp);	
+
+	return status;
 }
 
 static ECalBackendSyncStatus
-e_cal_backend_google_get_changes (ECalBackend *backend, EDataCal *cal, const char *change_id, GList **adds, GList **modifies, GList *deletes)
+e_cal_backend_google_get_changes (ECalBackendSync *backend, EDataCal *cal, const char *change_id, GList **adds, GList **modifies, GList **deletes)
 {
 	/* FIXME Not Implemented */
 	return GNOME_Evolution_Calendar_Success;
@@ -765,7 +1128,8 @@
 	ECalBackendGooglePrivate *priv;
 	ECalBackendSyncStatus status;
 	ECalSourceType source_type;
-	gchar *source = NULL;
+	gchar *source = NULL, *mangled_uri = NULL, *filename = NULL;
+	int i;
 
 	cbgo = E_CAL_BACKEND_GOOGLE(backend);
 	priv = cbgo->priv;
@@ -822,7 +1186,27 @@
 	priv->username = g_strdup(username);
 	priv->password = g_strdup(password);
 
-	/*FIXME */
+	/* Setting Up the Local Attachments Store */
+	mangled_uri = g_strdup (e_cal_backend_get_uri (E_CAL_BACKEND(cbgo)));
+
+	/* mangle the URI to not contain invalid characters */
+	for (i = 0; i < strlen (mangled_uri); i++) {
+		switch (mangled_uri[i]) {
+		case ':' :
+		case '/' :
+			mangled_uri[i] = '_';
+		}
+	}
+	
+	filename = g_build_filename (g_get_home_dir (), 
+				     ".evolution/cache", source,
+				     mangled_uri,
+			             NULL);
+
+	g_free (mangled_uri);
+	priv->local_attachments_store = g_filename_to_uri (filename, NULL, NULL);
+	g_free (filename);
+
 	status = e_cal_backend_google_utils_connect (cbgo);
 	g_mutex_unlock (priv->mutex);
 	return status;
@@ -1259,8 +1643,8 @@
 {
 	ECalBackendGooglePrivate *priv;
 
-	g_return_val_if_fail (cbgo != NULL, NULL);
-	g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), NULL);
+	g_return_val_if_fail (cbgo != NULL, 0);
+	g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), 0);
 
 	priv = cbgo->priv;
 	return priv->timeout_id;
@@ -1303,4 +1687,14 @@
 }
 
 
+gchar *
+e_cal_backend_google_get_local_attachments_store (ECalBackendGoogle *cbgo)
+{
+	ECalBackendGooglePrivate *priv;
+	
+	g_return_val_if_fail (cbgo != NULL, NULL);
+	g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), NULL);
 
+	priv = cbgo->priv;
+	return priv->local_attachments_store;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]