From 623a8d83ce693c5250d85e81c674f899234ce70d Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Wed, 9 Jan 2002 21:34:07 +0000 Subject: If the mbox file is a symlink, follow the symlink and get the One True 2002-01-09 Jeffrey Stedfast * providers/local/camel-mbox-folder.c (camel_mbox_folder_new): If the mbox file is a symlink, follow the symlink and get the One True Path so that we can rewrite the mbox later without worrying about clobbering the symlink. 2002-01-08 Jeffrey Stedfast * camel-filter-search.c (TODO): There are a few sexp callbacks that could be modified to use fms->info rather than using a message object (like date and possibly mlist stuff) but *only* if the date exists on the CamelMessageInfo object (since it may be blank except for message flags). (camel_filter_search_get_message): New internal convenience function to make sure that the FilterMessageSearch has loaded the message (and to load the message if this isn't the case). (check_header): Call camel_filter_search_get_message(). (header_exists): Same. (header_regex): Here too. (header_full_regex): And here. (body_contains): Again here. (body_regex): Here too. (get_sent_date): Here also. (get_received_date): Same. (get_source): Here if we need to. (camel_filter_search_match): Now takes a callback function/data pair for on-demand message loading so that we don't necessarily have to load the message if the defined filter rules don't require it. * camel-filter-driver.c (camel_filter_driver_filter_folder): Don't bother fetching the message here, let camel_filter_driver_filter_message() worry about this. (get_message_cb): New utility callback to fetch a message. (camel_filter_driver_filter_message): Only fetch the message if we absolutely need it to get a CamelMessageInfo. Instead of passing a message object to camel_filter_search_match(), pass get_message_cb and some user_data so that the matching code can fetch the message on demand. svn path=/trunk/; revision=15276 --- camel/camel-filter-driver.c | 107 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 24 deletions(-) (limited to 'camel/camel-filter-driver.c') diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index 9a05b91b2c..c9720b621f 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -791,7 +791,7 @@ camel_filter_driver_flush (CamelFilterDriver *driver, CamelException *ex) data.driver = driver; data.ex = ex; - g_hash_table_foreach_remove (p->only_once, run_only_once, &data); + g_hash_table_foreach_remove (p->only_once, (GHRFunc) run_only_once, &data); } /** @@ -917,14 +917,13 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folde GPtrArray *uids, gboolean remove, CamelException *ex) { struct _CamelFilterDriverPrivate *p = _PRIVATE (driver); - int i; - int freeuids = FALSE; - CamelMimeMessage *message; + gboolean freeuids = FALSE; CamelMessageInfo *info; char *source_url, *service_url; const char *folder_name; int status = 0; int need_sep = 0; + int i; service_url = camel_service_get_url (CAMEL_SERVICE (camel_folder_get_parent_store (folder))); folder_name = camel_folder_get_full_name (folder); @@ -934,9 +933,8 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folde if (service_url && *service_url && !need_sep) { need_sep = (service_url[strlen (service_url)-1] != '/'); } - source_url = g_strdup_printf ("%s%s%s", - service_url, - need_sep ? "/" : "", + + source_url = g_strdup_printf ("%s%s%s", service_url, need_sep ? "/" : "", folder_name); g_free (service_url); @@ -951,20 +949,12 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folde report_status (driver, CAMEL_FILTER_STATUS_START, pc, _("Getting message %d of %d"), i+1, uids->len); - message = camel_folder_get_message (folder, uids->pdata[i], ex); - if (!message || camel_exception_is_set (ex)) { - report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed at message %d of %d"), - i+1, uids->len); - status = -1; - break; - } - if (camel_folder_has_summary_capability (folder)) info = camel_folder_get_message_info (folder, uids->pdata[i]); else info = NULL; - status = camel_filter_driver_filter_message (driver, message, info, uids->pdata[i], + status = camel_filter_driver_filter_message (driver, NULL, info, uids->pdata[i], folder, source_url, source_url, ex); if (camel_folder_has_summary_capability (folder)) @@ -983,8 +973,6 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folde if (cache) camel_uid_cache_save_uid (cache, uids->pdata[i]); - - camel_object_unref (CAMEL_OBJECT (message)); } if (freeuids) @@ -1004,10 +992,44 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver, CamelFolder *folde } +struct _get_message { + struct _CamelFilterDriverPrivate *p; + const char *source_url; +}; + + +static CamelMimeMessage * +get_message_cb (void *data, CamelException *ex) +{ + struct _get_message *msgdata = data; + struct _CamelFilterDriverPrivate *p = msgdata->p; + const char *source_url = msgdata->source_url; + CamelMimeMessage *message; + + if (p->message) { + message = p->message; + camel_object_ref (CAMEL_OBJECT (message)); + } else { + const char *uid; + + if (p->uid) + uid = p->uid; + else + uid = camel_message_info_uid (p->info); + + message = camel_folder_get_message (p->source, uid, ex); + } + + if (source_url && camel_mime_message_get_source (message) == NULL) + camel_mime_message_set_source (message, source_url); + + return message; +} + /** * camel_filter_driver_filter_message: * @driver: CamelFilterDriver - * @message: message to filter + * @message: message to filter or NULL * @info: message info or NULL * @uid: message uid or NULL * @source: source folder or NULL @@ -1039,14 +1061,34 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage ESExpResult *r; int result; + /* FIXME: make me into a g_return_if_fail/g_assert or whatever... */ + if (message == NULL && (source == NULL || uid == NULL)) { + g_warning ("there is no way to fetch the message using the information provided..."); + return -1; + } + if (info == NULL) { - struct _header_raw *h = CAMEL_MIME_PART (message)->headers; + struct _header_raw *h; + + if (message) { + camel_object_ref (CAMEL_OBJECT (message)); + } else { + message = camel_folder_get_message (source, uid, ex); + if (!message) + return -1; + } + h = CAMEL_MIME_PART (message)->headers; info = camel_message_info_new_from_header (h); freeinfo = TRUE; } else { if (info->flags & CAMEL_MESSAGE_DELETED) return 0; + + uid = camel_message_info_uid (info); + + if (message) + camel_object_ref (CAMEL_OBJECT (message)); } p->ex = ex; @@ -1058,15 +1100,20 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage p->uid = uid; p->source = source; - if (original_source_url && camel_mime_message_get_source (message) == NULL) + if (message && original_source_url && camel_mime_message_get_source (message) == NULL) camel_mime_message_set_source (message, original_source_url); - node = (struct _filter_rule *)p->rules.head; + node = (struct _filter_rule *) p->rules.head; result = CAMEL_SEARCH_NOMATCH; while (node->next && !p->terminated) { + struct _get_message data; + d(fprintf (stderr, "applying rule %s\naction %s\n", node->match, node->action)); - result = camel_filter_search_match (p->message, p->info, + data.p = p; + data.source_url = original_source_url; + + result = camel_filter_search_match (get_message_cb, &data, p->info, original_source_url ? original_source_url : source_url, node->match, p->ex); @@ -1119,19 +1166,31 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage camel_folder_copy_messages_to (p->source, uids, p->defaultfolder, p->ex); g_ptr_array_free (uids, TRUE); } else { + if (p->message == NULL) { + p->message = camel_folder_get_message (source, uid, ex); + if (!p->message) + goto error; + } + camel_folder_append_message (p->defaultfolder, p->message, p->info, p->ex); } } + if (p->message) + camel_object_unref (CAMEL_OBJECT (p->message)); + if (freeinfo) camel_message_info_free (info); return 0; -error: + error: if (filtered) camel_filter_driver_log (driver, FILTER_LOG_END, NULL); + if (p->message) + camel_object_unref (CAMEL_OBJECT (p->message)); + if (freeinfo) camel_message_info_free (info); -- cgit v1.2.3