Re: [evolution-patches] Exchange connector patch for attachments
- From: Sarfraaz Ahmed <asarfraaz novell com>
- To: evo-patches <evolution-patches lists ximian com>
- Subject: Re: [evolution-patches] Exchange connector patch for attachments
- Date: Fri, 11 Mar 2005 19:49:32 +0530
Found some bugs in the previous (exchange) patch which i have fixed in this new one. Please review.
On Fri, 2005-03-11 at 12:34 +0530, Sarfraaz Ahmed wrote:
Hi,
This patch includes changes to e-d-s and connector. I have attached separate patches for both.
Thanks
-- Sarfraaz
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/ChangeLog,v
retrieving revision 1.432.2.1
diff -u -p -u -r1.432.2.1 ChangeLog
--- ChangeLog 8 Mar 2005 02:48:31 -0000 1.432.2.1
+++ ChangeLog 11 Mar 2005 07:00:36 -0000
@@ -1,3 +1,8 @@
+2005-03-11 Sarfraaz Ahmed <asarfraaz novell com>
+
+ * libecal/e-cal.c : Set the local_attachment_store for exchange
+ * libecal/e-cal-component.c : Dont unref the attach
+
2005-03-06 Rodrigo Moya <rodrigo novell com>
Fixes #72454
Index: libecal/e-cal.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal.c,v
retrieving revision 1.94
diff -u -p -u -r1.94 e-cal.c
--- libecal/e-cal.c 9 Feb 2005 00:29:26 -0000 1.94
+++ libecal/e-cal.c 11 Mar 2005 07:00:36 -0000
@@ -1349,6 +1349,10 @@ set_local_attachment_store (ECal *ecal)
g_strconcat ("file://", g_get_home_dir (), "/", ".evolution/cache/calendar",
"/", mangled_uri, NULL);
}
+ if (g_str_has_prefix (priv->uri, "exchange://")) {
+ priv->local_attachment_store = g_strdup_printf ("file://%s/.evolution/exchange/%s",
+ g_get_home_dir (), mangled_uri);
+ }
}
/**
Index: libecal/e-cal-component.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal-component.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 e-cal-component.c
--- libecal/e-cal-component.c 2 Feb 2005 18:44:32 -0000 1.13
+++ libecal/e-cal-component.c 11 Mar 2005 07:00:36 -0000
@@ -1489,7 +1489,6 @@ set_attachment_list (icalcomponent *ical
icalcomponent_remove_property (icalcomp, attachment->prop);
icalproperty_free (attachment->prop);
- icalattach_unref (attachment->attach);
g_free (attachment);
}
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-exchange/ChangeLog,v
retrieving revision 1.293
diff -u -p -u -r1.293 ChangeLog
--- ChangeLog 10 Mar 2005 17:52:13 -0000 1.293
+++ ChangeLog 11 Mar 2005 14:22:25 -0000
@@ -1,3 +1,26 @@
+2005-03-11 Sarfraaz Ahmed <asarfraaz novell com>
+
+ * calendar/e-cal-backend-exchange-calendar.c (add_ical) : Make sure we
+ check for attachments in subcomponents of a vcalendar as well.
+ (get_attachment) : Moved to e-cal-backend-exchange.c
+ (build_msg) : Moved to e-cal-backend-exchange.c
+ (create_object) : Minor leak fixed.
+ (modify_object_with_href) : Dont loose the attachments while modifying.
+ * calendar/e-cal-backend-exchange-tasks.c (put_body): Handle attachments
+ (get_changed_tasks) : Check for attachments and fetch them from server.
+ (create_task_object) : Check for attachments and send them to server.
+ (modify_task_object) : Similar
+ * calendar/e-cal-backend-exchange.c (load_cache) : Create the local
+ attachment store for the GUI to store exchange attachments
+ (save_attach_file) : Make a local copy of the attachment in the backend
+ (get_attachment) : Extract the attachment from the server object.(Moved
+ from calendar.c)
+ (get_attach_file_contents) : Store the attachment in a file.
+ (build_msg) : Build the mime part to send to the server (Moved from
+ calendar.c)
+ * calendar/e-cal-backend-exchange.h : Export the attachment utility
+ functions.
+
2005-03-07 Jeffrey Stedfast <fejj novell com>
Fixes bug #72889, #72943 and probably others.
Index: calendar/e-cal-backend-exchange.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/calendar/e-cal-backend-exchange.c,v
retrieving revision 1.30
diff -u -p -u -r1.30 e-cal-backend-exchange.c
--- calendar/e-cal-backend-exchange.c 8 Mar 2005 10:29:42 -0000 1.30
+++ calendar/e-cal-backend-exchange.c 11 Mar 2005 14:22:25 -0000
@@ -21,10 +21,21 @@
#include <config.h>
#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+
#include <string.h>
#include <unistd.h>
#include <e-util/e-time-utils.h>
+#include <libgnomevfs/gnome-vfs-mime-utils.h>
+
+#include <camel/camel-mime-message.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-file-utils.h>
+
#include "e-cal-backend-exchange.h"
#include "e2k-cal-utils.h"
#include "e2k-uri.h"
@@ -44,6 +55,7 @@ struct ECalBackendExchangePrivate {
GHashTable *objects, *cache_unseen;
char *object_cache_file;
char *lastmod;
+ char *local_attachment_store;
guint save_timeout_id;
/* Timezones */
@@ -127,11 +139,33 @@ load_cache (ECalBackendExchange *cbex, E
struct icaltimetype comp_last_mod, folder_last_mod;
icalcomponent_kind kind;
icalproperty *prop;
- char *lastmod;
+ char *lastmod, *mangled_uri, *storage_dir, *end;
+ const char *uristr;
+ int i;
+ struct stat buf;
cbex->priv->object_cache_file =
e_folder_exchange_get_storage_file (cbex->folder, "cache.ics");
+ /* Fixme : Try avoiding to do this everytime we come here */
+ uristr = e_cal_backend_get_uri (E_CAL_BACKEND (cbex));
+ mangled_uri = g_strdup (uristr);
+ for (i = 0; i < strlen (mangled_uri); i++) {
+ switch (mangled_uri[i]) {
+ case ':' :
+ case '/' :
+ mangled_uri[i] = '_';
+ }
+ }
+ cbex->priv->local_attachment_store = g_strdup_printf ("%s/.evolution/exchange/%s", g_get_home_dir (), mangled_uri);
+ end = strrchr (cbex->priv->object_cache_file, '/');
+ storage_dir = g_strndup (cbex->priv->object_cache_file, end - cbex->priv->object_cache_file);
+ if (lstat(cbex->priv->local_attachment_store , &buf) < 0) {
+ symlink (storage_dir, cbex->priv->local_attachment_store);
+ }
+ g_free (storage_dir);
+ g_free (mangled_uri);
+
vcalcomp = e_cal_util_parse_ics_file (cbex->priv->object_cache_file);
if (!vcalcomp)
return;
@@ -263,6 +297,7 @@ open_calendar (ECalBackendSync *backend,
d(printf("ecbe_open_calendar(%p, %p, %sonly if exists, user=%s, pass=%s)\n", backend, cal, only_if_exists?"":"not ", username?username:"(null)", password?password:"(null)"));
uristr = e_cal_backend_get_uri (E_CAL_BACKEND (backend));
+
if (cbex->priv->mode == CAL_MODE_LOCAL) {
ESource *source;
const char *display_contents = NULL;
@@ -1244,6 +1279,229 @@ e_cal_backend_exchange_compute_changes_f
e_xmlhash_remove (cbedata->ehash, key);
g_object_unref (comp);
}
+}
+
+/* Attachments */
+static char *
+save_attach_file (const char *dest_file, char *file_contents, int len)
+{
+ char *dest_url = NULL;
+ int fd;
+
+ d(printf ("dest_file is :%s\n", dest_file));
+
+ /* Write it to our local exchange store in .evolution */
+ fd = open (dest_file, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0) {
+ d(printf ("open of destination file for attachments failed\n"));
+ goto end;
+ }
+
+ if (camel_write (fd, file_contents, len) < 0) {
+ d(printf ("camel write to attach file failed\n"));
+ goto end;
+ }
+ /* FIXME : Add a ATTACH:CID:someidentifier here */
+ dest_url = g_strdup_printf ("file://%s", dest_file);
+
+end :
+ close (fd);
+ return dest_url;
+}
+
+GSList *
+get_attachment (ECalBackendExchange *cbex, const char *uid,
+ const char *body, int len)
+{
+ CamelStream *stream;
+ CamelMimeMessage *msg;
+ CamelDataWrapper *msg_content, *content = NULL;
+ CamelMultipart *multipart;
+ CamelMimePart *part;
+ const char *filename = NULL;
+ char *attach_file_url, *attach_file;
+ int i;
+ GSList *list = NULL;
+ unsigned char *attach_data;
+
+ stream = camel_stream_mem_new_with_buffer (body, len);
+ msg = camel_mime_message_new ();
+ camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
+ camel_object_unref (stream);
+
+ msg_content = camel_medium_get_content_object (CAMEL_MEDIUM (msg));
+ if (msg_content && CAMEL_IS_MULTIPART (msg_content)) {
+ multipart = (CamelMultipart *)msg_content;
+
+ for (i = 0; i < (int)camel_multipart_get_number (multipart); i++) {
+ part = camel_multipart_get_part (multipart, i);
+ filename = camel_mime_part_get_filename (part);
+ if (filename) {
+ CamelStreamMem *stream_mem;
+
+ content = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+
+ stream = camel_stream_mem_new ();
+ stream_mem = (CamelStreamMem *)stream;
+
+ camel_data_wrapper_decode_to_stream (content, stream);
+ attach_data = g_memdup (stream_mem->buffer->data, stream_mem->buffer->len);
+ attach_file = g_strdup_printf ("%s/%s-%s", cbex->priv->local_attachment_store, uid, filename);
+ // Attach
+ attach_file_url = save_attach_file (attach_file, attach_data, stream_mem->buffer->len);
+ g_free (attach_file);
+ d(printf ("attach file name : %s\n", attach_file_url));
+ list = g_slist_append (list, g_strdup (attach_file_url));
+
+ camel_object_unref (stream);
+ }
+ } /* Loop through each multipart */
+ }
+
+ camel_object_unref (msg);
+ return list;
+}
+
+static char *
+get_attach_file_contents (const char *filename)
+{
+ int fd, len = 0;
+ struct stat sb;
+ char *file_contents = NULL;
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0) {
+ d(printf ("Could not open the attachment file : %s\n", filename));
+ goto end;
+ }
+ if (fstat (fd, &sb) < 0) {
+ d(printf ("fstat of attachment file failed\n"));
+ goto end;
+ }
+ len = sb.st_size;
+
+ if (len > 0) {
+ file_contents = g_malloc0 (len + 1);
+
+ if (camel_read (fd, file_contents, len) < 0) {
+ d(printf ("reading from the attachment file failed\n"));
+ g_free (file_contents);
+ file_contents = NULL;
+ goto end;
+ }
+ file_contents [len] = '\0';
+ }
+
+end :
+ close (fd);
+ return file_contents;
+}
+
+char *
+build_msg ( ECalBackendExchange *cbex, ECalComponent *comp, const char *subject, char **boundary)
+{
+ CamelMimeMessage *msg;
+ CamelStreamMem *content;
+ CamelMimePart *mime_part;
+ CamelDataWrapper *dw, *wrapper;
+ CamelMultipart *multipart;
+ CamelInternetAddress *from;
+ CamelStream *stream;
+ CamelContentType *type;
+ const char *uid;
+ char *buffer = NULL, *cid;
+ char *from_name, *from_email;
+ GSList *attach_list = NULL, *l, *new_attach_list = NULL;
+ char *fname, *file_contents = NULL, *filename, *dest_url, *mime_filename, *attach_file;
+ int len = 0;
+
+ e_cal_backend_exchange_get_from (E_CAL_BACKEND_SYNC (cbex), comp, &from_name, &from_email);
+
+ msg = camel_mime_message_new ();
+
+ multipart = camel_multipart_new ();
+
+ /* Headers */
+ camel_mime_message_set_subject (msg, subject);
+
+ from = camel_internet_address_new ();
+ camel_internet_address_add (from, from_name, from_email);
+ camel_mime_message_set_from (msg, from);
+ camel_object_unref (from);
+
+ e_cal_component_get_uid (comp, &uid);
+ e_cal_component_get_attachment_list (comp, &attach_list);
+ for (l = attach_list; l ; l = l->next){
+ if (!strncmp ((char *)l->data, "file://", 7)) {
+ fname = (char *)(l->data) + strlen ("file://");
+ filename = g_strrstr (fname, "/") + 1;
+ mime_filename = filename + strlen(uid) + 1;
+ attach_file = g_strdup (fname);
+ } else {
+ fname = (char *)(l->data);
+ filename = g_strrstr (fname, "/") + 1;
+ mime_filename = filename;
+ attach_file = g_strdup_printf ("%s/%s-%s", cbex->priv->local_attachment_store, uid, filename);
+ }
+
+ file_contents = get_attach_file_contents (fname);
+ if (!file_contents)
+ continue;
+
+ len = strlen (file_contents);
+ dest_url = save_attach_file (attach_file, file_contents, len);
+ g_free (attach_file);
+ if (!dest_url)
+ continue;
+ new_attach_list = g_slist_append (new_attach_list, dest_url);
+
+ /* Content */
+ stream = camel_stream_mem_new_with_buffer (file_contents, len);
+ wrapper = camel_data_wrapper_new ();
+ camel_data_wrapper_construct_from_stream (wrapper, stream);
+ camel_object_unref (stream);
+
+ char *mime_type = gnome_vfs_get_mime_type (dest_url + strlen ("file://"));
+ type = camel_content_type_decode (mime_type);
+ camel_data_wrapper_set_mime_type_field (wrapper, type);
+ camel_content_type_unref (type);
+
+ mime_part = camel_mime_part_new ();
+
+ camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper);
+ camel_mime_part_set_filename (mime_part, mime_filename);
+ camel_mime_part_set_encoding (mime_part, CAMEL_TRANSFER_ENCODING_BASE64);
+ cid = camel_header_msgid_generate ();
+ camel_mime_part_set_content_id (mime_part, cid);
+ camel_mime_part_set_description (mime_part, mime_filename);
+ camel_mime_part_set_disposition (mime_part, "attachment");
+ camel_multipart_set_boundary (multipart, NULL);
+ *boundary = g_strdup (camel_multipart_get_boundary (multipart));
+ camel_multipart_add_part (multipart, mime_part);
+ camel_object_unref (mime_part);
+ g_free (cid);
+
+ }
+ if (!new_attach_list) {
+ camel_object_unref (multipart);
+ camel_object_unref (msg);
+ return NULL;
+ }
+ e_cal_component_set_attachment_list (comp, new_attach_list);
+
+ camel_medium_set_content_object (CAMEL_MEDIUM (msg), CAMEL_DATA_WRAPPER (multipart));
+ camel_object_unref (multipart);
+
+ content = (CamelStreamMem *)camel_stream_mem_new();
+ dw = camel_medium_get_content_object (CAMEL_MEDIUM (msg));
+ camel_data_wrapper_decode_to_stream(dw, (CamelStream *)content);
+ buffer = g_memdup (content->buffer->data, content->buffer->len);
+ buffer[content->buffer->len] = '\0';
+ d(printf ("|| Buffer: \n%s\n", buffer));
+ camel_object_unref (content);
+ camel_object_unref (msg);
+
+ return buffer;
}
static ECalBackendSyncStatus
Index: calendar/e-cal-backend-exchange.h
===================================================================
RCS file: /cvs/gnome/evolution-exchange/calendar/e-cal-backend-exchange.h,v
retrieving revision 1.9
diff -u -p -u -r1.9 e-cal-backend-exchange.h
--- calendar/e-cal-backend-exchange.h 18 Jan 2005 11:56:08 -0000 1.9
+++ calendar/e-cal-backend-exchange.h 11 Mar 2005 14:22:25 -0000
@@ -92,6 +92,8 @@ void e_cal_backend_exchange_get_from (EC
char **from_name, char **from_addr);
char * e_cal_backend_exchange_get_from_string (ECalBackendSync *backend, ECalComponent *comp);
gboolean e_cal_backend_exchange_is_online (ECalBackendExchange *cbex);
+GSList * get_attachment (ECalBackendExchange *cbex, const char *uid, const char *body, int len);
+char * build_msg ( ECalBackendExchange *cbex, ECalComponent *comp, const char *subject, char **boundary);
G_END_DECLS
Index: calendar/e-cal-backend-exchange-calendar.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/calendar/e-cal-backend-exchange-calendar.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 e-cal-backend-exchange-calendar.c
--- calendar/e-cal-backend-exchange-calendar.c 10 Mar 2005 10:02:58 -0000 1.38
+++ calendar/e-cal-backend-exchange-calendar.c 11 Mar 2005 14:22:25 -0000
@@ -25,11 +25,6 @@
#include <sys/stat.h>
#include <sys/fcntl.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-multipart.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-file-utils.h>
-
#include "e-cal-backend-exchange-calendar.h"
#include "e2k-cal-utils.h"
@@ -56,12 +51,10 @@ enum {
#define PARENT_TYPE E_TYPE_CAL_BACKEND_EXCHANGE
static ECalBackendExchange *parent_class = NULL;
-#define d(x) (x)
+#define d(x)
static ECalBackendSyncStatus modify_object_with_href (ECalBackendSync *backend, EDataCal *cal, const char *calobj, CalObjModType mod, char **old_object, const char *href);
-static GSList * get_attachment (ECalBackendExchange *cbex, const char *uid, const char *body, int len);
-
gboolean check_for_send_options (icalcomponent *icalcomp, E2kProperties *props);
static void
@@ -191,7 +184,6 @@ add_ical (ECalBackendExchange *cbex, con
if (uid)
attachment_list = get_attachment (cbex, uid, body, len);
-
start = g_strstr_len (body, len, "\nBEGIN:VCALENDAR");
if (!start)
return FALSE;
@@ -218,7 +210,6 @@ add_ical (ECalBackendExchange *cbex, con
ecomp = e_cal_component_new ();
e_cal_component_set_icalcomponent (ecomp, icalcomponent_new_clone (icalcomp));
e_cal_component_set_attachment_list (ecomp, attachment_list);
- icalcomponent_free (icalcomp);
icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (ecomp));
g_object_unref (ecomp);
}
@@ -235,14 +226,17 @@ add_ical (ECalBackendExchange *cbex, con
subcomp = icalcomponent_get_first_component (
icalcomp, ICAL_VEVENT_COMPONENT);
while (subcomp) {
- new_comp = icalcomponent_new_clone (subcomp);
+ if (uid && !strcmp (uid, icalcomponent_get_uid (subcomp)) && attachment_list) {
+ ecomp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (ecomp, icalcomponent_new_clone (subcomp));
+ e_cal_component_set_attachment_list (ecomp, attachment_list);
+ new_comp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (ecomp));
+ g_object_unref (ecomp);
+ } else {
+ new_comp = icalcomponent_new_clone (subcomp);
+ }
+
if (new_comp) {
- /*
- if (attach_len) {
- iattach = icalattach_new_from_data (attach_data, g_free, NULL);
- attachment_list = g_slist_append (attachment_list, iattach);
- e_cal_component_set_attachment_list (new_comp, attachment_list);
- } */
add_vevent (cbex, href, lastmod, new_comp);
icalcomponent_free (new_comp);
}
@@ -254,77 +248,6 @@ add_ical (ECalBackendExchange *cbex, con
return TRUE;
}
-static GSList *
-get_attachment (ECalBackendExchange *cbex, const char *uid,
- const char *body, int len)
-{
- CamelStream *stream;
- CamelMimeMessage *msg;
- CamelDataWrapper *content;
- CamelMultipart *multipart;
- CamelMimePart *part;
- const char *filename = NULL;
- char *attach_filename, *attach_file, *attach_file_url;
- int fd;
- int i;
- GSList *list = NULL;
- unsigned char *attach_data;
-
- stream = camel_stream_mem_new_with_buffer (body, len);
- msg = camel_mime_message_new ();
- camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
- camel_object_unref (stream);
-
- content = camel_medium_get_content_object (CAMEL_MEDIUM (msg));
- if (CAMEL_IS_MULTIPART (content)) {
- multipart = (CamelMultipart *)content;
- content = NULL;
-
- for (i = 0; i < (int)camel_multipart_get_number (multipart); i++) {
- part = camel_multipart_get_part (multipart, i);
- filename = camel_mime_part_get_filename (part);
- if (filename) {
- content = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- break;
- }
- }
- }
-
- if (content) {
- CamelStreamMem *stream_mem;
-
- stream = camel_stream_mem_new ();
- stream_mem = (CamelStreamMem *)stream;
-
- camel_data_wrapper_decode_to_stream (content, stream);
- attach_data = g_memdup (stream_mem->buffer->data, stream_mem->buffer->len);
-
- // Attach
- attach_filename = g_strdup_printf ("%s-%s", uid, filename);
- attach_file = e_folder_exchange_get_storage_file (cbex->folder, attach_filename);
- g_free (attach_filename);
-
- fd = open (attach_file, O_RDWR|O_CREAT|O_TRUNC, 0600);
- if (fd < 0) {
- d(printf ("could not open file for creating attachment file locally\n"));
- } else {
- if (camel_write (fd, attach_data, stream_mem->buffer->len) < 0)
- d(printf ("camel write to attach file failed\n"));
- }
- attach_file_url = g_strdup_printf ("file://%s", attach_file);
- list = g_slist_append (list, g_strdup (attach_file_url));
-
- close (fd);
- g_free (attach_file_url);
- g_free (attach_file);
-
- camel_object_unref (stream);
- }
-
- camel_object_unref (msg);
- return list;
-}
-
static const char *event_properties[] = {
E2K_PR_CALENDAR_UID,
E2K_PR_DAV_LAST_MODIFIED,
@@ -336,7 +259,6 @@ static const int n_event_properties = G_
static const char *new_event_properties[] = {
PR_INTERNET_CONTENT,
- E2K_PR_HTTPMAIL_HAS_ATTACHMENT,
PR_READ_RECEIPT_REQUESTED,
PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED
};
@@ -592,120 +514,6 @@ add_timezone_cb (icalparameter *param, v
icalcomponent_add_component (cbdata->vcal_comp, vtzcomp);
}
-static char *
-build_msg ( ECalBackendExchange *cbex, ECalComponent *comp, const char *subject, const char **boundary)
-{
- CamelMimeMessage *msg;
- CamelStreamMem *content;
- CamelMimePart *mime_part;
- CamelDataWrapper *dw, *wrapper;
- CamelMultipart *multipart;
- CamelInternetAddress *from;
- CamelStream *stream;
- CamelContentType *type;
- char *buffer = NULL, *cid;
- char *from_name, *from_email;
- GSList *attach_list = NULL, *l, *new_attach_list = NULL;
- char *fname, *filename = NULL, *file_contents = NULL, *dest_url, *dest_file;
- int fd, len = 0;
- struct stat sb;
-
- e_cal_backend_exchange_get_from (E_CAL_BACKEND_SYNC (cbex), comp, &from_name, &from_email);
-
- e_cal_component_get_attachment_list (comp, &attach_list);
- for (l = attach_list; l ; l = l->next){
- fname = (char *)l->data;
-
- filename = g_strrstr (fname, "/") + 1;
-
- fd = open (fname, O_RDONLY);
- if (fd < 0) {
- d(printf ("Could not open the attachment file\n"));
- continue;
- }
- if (fstat (fd, &sb) < 0) {
- d(printf ("fstat of attachment file failed\n"));
- }
- len = sb.st_size;
-
- file_contents = g_malloc0 (len + 1);
-
- if (len > 0 && camel_read (fd, file_contents, len) < 0) {
- d(printf ("reading from the attachment file failed\n"));
- close (fd);
- }
- file_contents [len] = '\0';
- close (fd);
-
- /* Write it to our local exchange store in .evolution */
- dest_file = e_folder_exchange_get_storage_file (cbex->folder, filename);
- fd = open (dest_file, O_RDWR | O_CREAT | O_TRUNC, 0600);
- if (fd < 0) {
- d(printf ("open of destination file for attachments failed\n"));
- }
-
- if (camel_write (fd, file_contents, len) < 0)
- d(printf ("camel write to attach file failed\n"));
- /* FIXME : Add a ATTACH:CID:someidentifier here */
- dest_url = g_strconcat ("file:///", dest_file, NULL);
- new_attach_list = g_slist_append (new_attach_list, dest_url);
- g_free (dest_file);
- }
- e_cal_component_set_attachment_list (comp, new_attach_list);
-
-
- if (len) {
- msg = camel_mime_message_new ();
-
- multipart = camel_multipart_new ();
-
- /* Headers */
- camel_mime_message_set_subject (msg, subject);
-
- from = camel_internet_address_new ();
- camel_internet_address_add (from, from_name, from_email);
- camel_mime_message_set_from (msg, from);
- camel_object_unref (from);
-
- /* Content */
- stream = camel_stream_mem_new_with_buffer (file_contents, len);
- wrapper = camel_data_wrapper_new ();
- camel_data_wrapper_construct_from_stream (wrapper, stream);
- camel_object_unref (stream);
-
- type = camel_content_type_new ("text", "plain");
- camel_content_type_set_param (type, "name", "\"test-attach.txt\"");
- camel_data_wrapper_set_mime_type_field (wrapper, type);
- camel_content_type_unref (type);
-
- //mime_part = CAMEL_MIME_PART (msg);
- mime_part = camel_mime_part_new ();
-
- camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper);
- camel_mime_part_set_filename (mime_part, filename);
- camel_mime_part_set_encoding (mime_part, CAMEL_TRANSFER_ENCODING_BASE64);
- cid = camel_header_msgid_generate ();
- camel_mime_part_set_content_id (mime_part, cid);
- camel_mime_part_set_description (mime_part, filename);
- camel_mime_part_set_disposition (mime_part, "attachment");
- camel_multipart_set_boundary (multipart, NULL);
- *boundary = camel_multipart_get_boundary (multipart);
- camel_multipart_add_part (multipart, mime_part);
- camel_object_unref (mime_part);
- camel_medium_set_content_object (CAMEL_MEDIUM (msg), CAMEL_DATA_WRAPPER (multipart));
- camel_object_unref (multipart);
-
- content = (CamelStreamMem *)camel_stream_mem_new();
- dw = camel_medium_get_content_object (CAMEL_MEDIUM (msg));
- camel_data_wrapper_decode_to_stream(dw, (CamelStream *)content);
- buffer = g_memdup (content->buffer->data, content->buffer->len);
- d(printf ("|| Buffer: \n%s\n", buffer));
- g_free (cid);
- }
-
- return buffer;
-}
-
gboolean
check_for_send_options (icalcomponent *icalcomp, E2kProperties *props)
{
@@ -759,7 +567,7 @@ create_object (ECalBackendSync *backend,
const char *summary;
char *attach_body = NULL;
char *attach_body_crlf = NULL;
- const char *boundary;
+ char *boundary = NULL;
E2kHTTPStatus http_status;
E2kProperties *props = e2k_properties_new ();
E2kContext *e2kctx;
@@ -930,6 +738,7 @@ create_object (ECalBackendSync *backend,
"\r\n%s\r\n%s", summary, date, boundary,
from ? from : "Evolution", boundary,
body_crlf, attach_body_crlf);
+ g_free (boundary);
} else {
msg = g_strdup_printf ("Subject: %s\r\n"
@@ -1106,6 +915,9 @@ modify_object_with_href (ECalBackendSync
const char *comp_uid;
char *updated_ecomp_str, *real_comp_str;
char *body, *body_crlf, *msg;
+ char *attach_body = NULL;
+ char *attach_body_crlf = NULL;
+ char *boundary = NULL;
struct icaltimetype last_modified;
icalcomponent_kind kind;
ECalComponentDateTime dt;
@@ -1147,6 +959,11 @@ modify_object_with_href (ECalBackendSync
return GNOME_Evolution_Calendar_ObjectNotFound;
}
+ /* Fetch summary */
+ summary = icalcomponent_get_summary (icalcomp);
+ if (!summary)
+ summary = "";
+
updated_ecomp = e_cal_component_new ();
e_cal_component_set_icalcomponent (updated_ecomp, icalcomp);
@@ -1154,7 +971,13 @@ modify_object_with_href (ECalBackendSync
last_modified = icaltime_from_timet (time (NULL), 0);
e_cal_component_set_last_modified (updated_ecomp, &last_modified);
-
+
+ if (e_cal_component_has_attachments (updated_ecomp)) {
+ d(printf ("This comp has attachments !!\n"));
+ attach_body = build_msg (E_CAL_BACKEND_EXCHANGE (cbexc), updated_ecomp, summary, &boundary);
+ attach_body_crlf = e_cal_backend_exchange_lf_to_crlf (attach_body);
+ }
+
updated_ecomp_str = e_cal_component_get_as_string (updated_ecomp);
updated_icalcomp = icalparser_parse_string (updated_ecomp_str);
g_free (updated_ecomp_str);
@@ -1278,24 +1101,44 @@ modify_object_with_href (ECalBackendSync
date = e_cal_backend_exchange_make_timestamp_rfc822 (time (NULL));
from = e_cal_backend_exchange_get_from_string (backend, updated_ecomp);
- summary = icalcomponent_get_summary (real_icalcomp);
- if (!summary)
- summary = "";
+ if (attach_body) {
+ msg = g_strdup_printf ("Subject: %s\r\n"
+ "Date: %s\r\n"
+ "MIME-Version: 1.0\r\n"
+ "Content-Type: multipart/mixed;\r\n"
+ "\tboundary=\"%s\";\r\n"
+ "X-MS_Has-Attach: yes\r\n"
+ "From: %s\r\n"
+ "\r\n--%s\r\n"
+ "content-class: urn:content-classes:appointment\r\n"
+ "Content-Type: text/calendar;\r\n"
+ "\tmethod=REQUEST;\r\n"
+ "\tcharset=\"utf-8\"\r\n"
+ "Content-Transfer-Encoding: 8bit\r\n"
+ "Importance: normal\r\n"
+ "Priority: normal\r\n"
+ "\r\n%s\r\n%s", summary, date, boundary,
+ from ? from : "Evolution", boundary,
+ body_crlf, attach_body_crlf);
+ g_free (boundary);
+
+ } else {
- msg = g_strdup_printf ("Subject: %s\r\n"
- "Date: %s\r\n"
- "MIME-Version: 1.0\r\n"
- "Content-Type: text/calendar;\r\n"
- "\tmethod=REQUEST;\r\n"
- "\tcharset=\"utf-8\"\r\n"
- "Content-Transfer-Encoding: 8bit\r\n"
- "content-class: urn:content-classes:appointment\r\n"
- "Importance: normal\r\n"
- "Priority: normal\r\n"
- "From: %s\r\n"
- "\r\n%s", summary, date,
- from ? from : "Evolution",
- body_crlf);
+ msg = g_strdup_printf ("Subject: %s\r\n"
+ "Date: %s\r\n"
+ "MIME-Version: 1.0\r\n"
+ "Content-Type: text/calendar;\r\n"
+ "\tmethod=REQUEST;\r\n"
+ "\tcharset=\"utf-8\"\r\n"
+ "Content-Transfer-Encoding: 8bit\r\n"
+ "content-class: urn:content-classes:appointment\r\n"
+ "Importance: normal\r\n"
+ "Priority: normal\r\n"
+ "From: %s\r\n"
+ "\r\n%s", summary, date,
+ from ? from : "Evolution",
+ body_crlf);
+ }
g_free (date);
g_free (from);
Index: calendar/e-cal-backend-exchange-tasks.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/calendar/e-cal-backend-exchange-tasks.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 e-cal-backend-exchange-tasks.c
--- calendar/e-cal-backend-exchange-tasks.c 10 Mar 2005 09:34:50 -0000 1.14
+++ calendar/e-cal-backend-exchange-tasks.c 11 Mar 2005 14:22:26 -0000
@@ -431,6 +431,7 @@ get_summary (ECalComponent *comp)
static int
put_body (ECalComponent *comp, E2kContext *ctx, E2kOperation *op,
const char *uri, const char *from_name, const char *from_addr,
+ const char *attach_body, const char *boundary,
char **repl_uid)
{
@@ -457,7 +458,41 @@ put_body (ECalComponent *comp, E2kContex
/* PUT the component on the server */
desc_crlf = e2k_lf_to_crlf ((const char *) desc->str);
date = e2k_make_timestamp_rfc822 (time (NULL));
- body = g_strdup_printf ("content-class: urn:content-classes:task\r\n"
+
+ if (attach_body) {
+ body = g_strdup_printf ("content-class: urn:content-classes:task\r\n"
+ "Subject: %s\r\n"
+ "Date: %s\r\n"
+ "Message-ID: <%s>\r\n"
+ "MIME-Version: 1.0\r\n"
+ "Content-Type: multipart/mixed;\r\n"
+ "\tboundary=\"%s\";\r\n"
+ "X-MS_Has-Attach: yes\r\n"
+ "From: \"%s\" <%s>\r\n"
+ "\r\n--%s\r\n"
+ "content-class: urn:content-classes:task\r\n"
+ "Content-Type: text/plain;\r\n"
+ "\tcharset=\"utf-8\"\r\n"
+ "Content-Transfer-Encoding: 8bit\r\n"
+ "Thread-Topic: %s\r\n"
+ "Priority: %s\r\n"
+ "Importance: %s\r\n"
+ "\r\n%s\r\n%s",
+ get_summary (comp),
+ date,
+ get_uid (comp),
+ boundary,
+ from_name ? from_name : "Evolution",
+ from_addr ? from_addr : "",
+ boundary,
+ get_summary (comp),
+ get_priority (comp),
+ get_priority (comp),
+ desc_crlf,
+ attach_body);
+
+ } else {
+ body = g_strdup_printf ("content-class: urn:content-classes:task\r\n"
"Subject: %s\r\n"
"Date: %s\r\n"
"Message-ID: <%s>\r\n"
@@ -479,6 +514,7 @@ put_body (ECalComponent *comp, E2kContex
from_name ? from_name : "Evolution",
from_addr ? from_addr : "",
desc_crlf);
+ }
status = e2k_context_put (ctx, NULL, uri, "message/rfc822",
body, strlen (body), NULL);
@@ -501,6 +537,7 @@ static const char *task_props[] = {
E2K_PR_HTTPMAIL_SUBJECT,
E2K_PR_HTTPMAIL_TEXT_DESCRIPTION,
E2K_PR_HTTPMAIL_DATE,
+ E2K_PR_HTTPMAIL_HAS_ATTACHMENT,
E2K_PR_CALENDAR_LAST_MODIFIED,
E2K_PR_HTTPMAIL_FROM_EMAIL,
E2K_PR_HTTPMAIL_FROM_NAME,
@@ -519,17 +556,20 @@ static const int n_task_props = sizeof (
static guint
get_changed_tasks (ECalBackendExchange *cbex, const char *since)
{
+ ECalBackendExchangeComponent *ecalbexcomp;
E2kRestriction *rn;
E2kResultIter *iter;
GPtrArray *hrefs, *array;
- GHashTable *modtimes;
+ GHashTable *modtimes, *attachments;
+ GSList *attachment_list = NULL;
E2kResult *result;
- const char *modtime, *str;
- char *uid;
+ E2kContext *ctx;
+ const char *modtime, *str, *prop;
+ char *uid, *body;
char *tzid;
int status, i, priority, percent;
float f_percent;
- ECalComponent *ecal;
+ ECalComponent *ecal, *ecomp;
struct icaltimetype itt;
const icaltimezone *itzone;
ECalComponentDateTime ecdatetime;
@@ -564,6 +604,8 @@ get_changed_tasks (ECalBackendExchange *
hrefs = g_ptr_array_new ();
modtimes = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
+ attachments = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
while ((result = e2k_result_iter_next (iter))) {
uid = e2k_properties_get_prop (result->props,
@@ -753,7 +795,13 @@ get_changed_tasks (ECalBackendExchange *
E2K_PR_CALENDAR_URL))) {
e_cal_component_set_url (ecal, str);
}
-
+
+ /* Set Attachments */
+ if ((str = e2k_properties_get_prop (result->props,
+ E2K_PR_HTTPMAIL_HAS_ATTACHMENT))) {
+ g_hash_table_insert (attachments, g_strdup (result->href),
+ g_strdup (uid));
+ }
e_cal_component_commit_sequence (ecal);
icalcomp = e_cal_component_get_icalcomponent (ecal);
if (icalcomp)
@@ -765,6 +813,7 @@ get_changed_tasks (ECalBackendExchange *
if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
g_ptr_array_free (hrefs, TRUE);
g_hash_table_destroy (modtimes);
+ g_hash_table_destroy (attachments);
return status;
}
@@ -774,15 +823,86 @@ get_changed_tasks (ECalBackendExchange *
if (!hrefs->len) {
g_ptr_array_free (hrefs, TRUE);
g_hash_table_destroy (modtimes);
+ g_hash_table_destroy (attachments);
+ return SOUP_STATUS_OK;
+ }
+
+ prop = PR_INTERNET_CONTENT;
+ iter = e_folder_exchange_bpropfind_start (cbex->folder, NULL,
+ (const char **)hrefs->pdata,
+ hrefs->len, &prop, 1);
+ for (i = 0; i < hrefs->len; i++)
+ g_free (hrefs->pdata[i]);
+ g_ptr_array_set_size (hrefs, 0);
+
+ while ((result = e2k_result_iter_next (iter))) {
+ GByteArray *ical_data;
+ ical_data = e2k_properties_get_prop (result->props, PR_INTERNET_CONTENT);
+ if (!ical_data) {
+ g_ptr_array_add (hrefs, g_strdup (result->href));
+ continue;
+ }
+
+ uid = g_hash_table_lookup (attachments, result->href);
+ /* Fetch component from cache and update it */
+ ecalbexcomp = get_exchange_comp (cbex, uid);
+ attachment_list = get_attachment (cbex, uid, ical_data->data, ical_data->len);
+ if (attachment_list) {
+ ecomp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (ecomp, icalcomponent_new_clone (ecalbexcomp->icomp));
+ e_cal_component_set_attachment_list (ecomp, attachment_list);
+ icalcomponent_free (ecalbexcomp->icomp);
+ ecalbexcomp->icomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (ecomp));
+ g_object_unref (ecomp);
+ }
+ }
+ status = e2k_result_iter_free (iter);
+
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
+ g_ptr_array_free (hrefs, TRUE);
+ g_hash_table_destroy (attachments);
+ return status;
+ }
+
+ if (!hrefs->len) {
+ g_ptr_array_free (hrefs, TRUE);
+ g_hash_table_destroy (attachments);
return SOUP_STATUS_OK;
}
+
+ ctx = exchange_account_get_context (cbex->account);
+ if (!ctx) {
+ /* This either means we lost connection or we are in offline mode */
+ return SOUP_STATUS_CANT_CONNECT;
+ }
+
+ for (i = 0; i < hrefs->len; i++) {
+ int length;
- /* FIXME */
+ status = e2k_context_get (ctx, NULL, hrefs->pdata[i],
+ NULL, &body, &length);
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status))
+ continue;
+ uid = g_hash_table_lookup (attachments, hrefs->pdata[i]);
+ /* Fetch component from cache and update it */
+ ecalbexcomp = get_exchange_comp (cbex, uid);
+ attachment_list = get_attachment (cbex, uid, body, length);
+ if (attachment_list) {
+ ecomp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (ecomp, icalcomponent_new_clone (ecalbexcomp->icomp));
+ e_cal_component_set_attachment_list (ecomp, attachment_list);
+ icalcomponent_free (ecalbexcomp->icomp);
+ ecalbexcomp->icomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (ecomp));
+ g_object_unref (ecomp);
+ }
+ g_free (body);
+ }
for (i = 0; i < hrefs->len; i++)
g_free (hrefs->pdata[i]);
g_ptr_array_free (hrefs, TRUE);
g_hash_table_destroy (modtimes);
+ g_hash_table_destroy (attachments);
return status;
}
@@ -849,6 +969,9 @@ create_task_object (ECalBackendSync *bac
icalcomponent_kind kind;
struct icaltimetype current;
char *from_name, *from_addr;
+ char *boundary = NULL;
+ char *attach_body = NULL;
+ char *attach_body_crlf = NULL;
const char *summary;
char * modtime;
char *location;
@@ -882,6 +1005,10 @@ create_task_object (ECalBackendSync *bac
icalcomponent_add_property (icalcomp, icalproperty_new_lastmodified (current));
modtime = e2k_timestamp_from_icaltime (current);
+
+ summary = icalcomponent_get_summary (icalcomp);
+ if (!summary)
+ summary = "";
/* Get the uid */
temp_comp_uid = icalcomponent_get_uid (icalcomp);
@@ -903,6 +1030,13 @@ create_task_object (ECalBackendSync *bac
get_from (backend, comp, &from_name, &from_addr);
+ /* Check for attachments */
+ if (e_cal_component_has_attachments (comp)) {
+ d(printf ("This task has attachments\n"));
+ attach_body = build_msg (ecalbex, comp, summary, &boundary);
+ attach_body_crlf = e_cal_backend_exchange_lf_to_crlf (attach_body);
+ }
+
props = e2k_properties_new ();
/* FIXME Check for props and its members */
@@ -939,9 +1073,6 @@ create_task_object (ECalBackendSync *bac
}
real_icalcomp = icalparser_parse_string (*calobj);
- summary = e2k_properties_get_prop (props, E2K_PR_HTTPMAIL_THREAD_TOPIC);
- if (!summary)
- summary = g_strdup ("");
e2kctx = exchange_account_get_context (ecalbex->account);
status = e_folder_exchange_proppatch_new (ecalbex->folder, NULL,
@@ -949,7 +1080,8 @@ create_task_object (ECalBackendSync *bac
props, &location, NULL );
if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
- status = put_body(comp, e2kctx, NULL, location, from_name, from_addr, NULL);
+ status = put_body(comp, e2kctx, NULL, location, from_name, from_addr,
+ attach_body_crlf, boundary, NULL);
if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
e_cal_backend_exchange_add_object (ecalbex, location, modtime, real_icalcomp);
}
@@ -975,6 +1107,9 @@ modify_task_object (ECalBackendSync *bac
const char* comp_uid, *summary;
char *from_name, *from_addr;
char *comp_str;
+ char *attach_body = NULL;
+ char *attach_body_crlf = NULL;
+ char *boundary = NULL;
struct icaltimetype current;
ECalBackendSyncStatus status;
E2kContext *e2kctx;
@@ -1021,6 +1156,9 @@ modify_task_object (ECalBackendSync *bac
*old_object = e_cal_component_get_as_string (cache_comp);
g_free (cache_comp);
+ summary = icalcomponent_get_summary (icalcomp);
+ if (!summary)
+ summary = "";
/* Create the cal component */
new_comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (new_comp, icalcomp);
@@ -1029,6 +1167,12 @@ modify_task_object (ECalBackendSync *bac
current = icaltime_from_timet (time (NULL), 0);
e_cal_component_set_last_modified (new_comp, ¤t);
+ /* Set Attachments */
+ if (e_cal_component_has_attachments (new_comp)) {
+ d(printf ("This task has attachments for modifications\n"));
+ attach_body = build_msg (ecalbex, new_comp, summary, &boundary);
+ attach_body_crlf = e_cal_backend_exchange_lf_to_crlf (attach_body);
+ }
comp_str = e_cal_component_get_as_string (new_comp);
icalcomp = icalparser_parse_string (comp_str);
g_free (comp_str);
@@ -1040,7 +1184,6 @@ modify_task_object (ECalBackendSync *bac
props = e2k_properties_new ();
update_props (new_comp, &props);
- summary = e2k_properties_get_prop (props, E2K_PR_HTTPMAIL_THREAD_TOPIC);
e_cal_component_commit_sequence (new_comp);
e2kctx = exchange_account_get_context (ecalbex->account);
@@ -1048,7 +1191,8 @@ modify_task_object (ECalBackendSync *bac
comp_str = e_cal_component_get_as_string (new_comp);
icalcomp = icalparser_parse_string (comp_str);
if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)){
- status = put_body(new_comp, e2kctx, NULL, ecalbexcomp->href, from_name, from_addr, NULL);
+ status = put_body(new_comp, e2kctx, NULL, ecalbexcomp->href, from_name, from_addr,
+ attach_body_crlf, boundary, NULL);
if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
e_cal_backend_exchange_modify_object (ecalbex, icalcomp, mod);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]