From faac871501ee1935cdbaf044e2f8ac4dc00eadc2 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 2 Jul 2001 15:03:49 +0000 Subject: new method to get an application-initialized filter driver. * camel-session.c (camel_session_get_filter_driver): new method to get an application-initialized filter driver. * camel-filter-driver.c (camel_filter_driver_new): Remove the get_folder function and data args from here... (camel_filter_driver_set_folder_func): ...and add this function to set/change them. * providers/imap/camel-imap-folder.c (camel_imap_folder_new): If this folder is INBOX and we're filtering INBOX, set a flag on the folder for later. (imap_update_summary): Add another argument (GPtrArray *recents), and if it's non-NULL, add the uids of any \Recent new messages to it. (camel_imap_folder_changed): If doing filtering in this folder, create a recents array and pass it to imap_update_summary. Then get a filter driver and use it to filter the recent messages. * providers/imap/camel-imap-summary.h: * providers/imap/camel-imap-utils.c (imap_parse_flag_list): Add support for the \Recent flag. * providers/imap/camel-imap-provider.c (imap_conf_entries): enable the "filter" option. * camel-types.h: add CamelFilterDriver typedef here svn path=/trunk/; revision=10681 --- camel/ChangeLog | 29 +++++++++++++++++++++++++ camel/camel-filter-driver.c | 35 ++++++++++-------------------- camel/camel-filter-driver.h | 4 ++-- camel/camel-session.c | 17 +++++++++++++++ camel/camel-session.h | 23 +++++++++++++------- camel/camel-types.h | 1 + camel/providers/imap/camel-imap-folder.c | 34 ++++++++++++++++++++++++++--- camel/providers/imap/camel-imap-folder.h | 2 +- camel/providers/imap/camel-imap-provider.c | 2 +- camel/providers/imap/camel-imap-summary.h | 2 ++ camel/providers/imap/camel-imap-utils.c | 2 ++ 11 files changed, 113 insertions(+), 38 deletions(-) (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index 68cb2d7640..78104382fd 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,32 @@ +2001-07-02 Dan Winship + + * camel-session.c (camel_session_get_filter_driver): new method to + get an application-initialized filter driver. + + * camel-filter-driver.c (camel_filter_driver_new): Remove the + get_folder function and data args from here... + (camel_filter_driver_set_folder_func): ...and add this function to + set/change them. + + * providers/imap/camel-imap-folder.c (camel_imap_folder_new): If + this folder is INBOX and we're filtering INBOX, set a flag on the + folder for later. + (imap_update_summary): Add another argument (GPtrArray *recents), + and if it's non-NULL, add the uids of any \Recent new messages to + it. + (camel_imap_folder_changed): If doing filtering in this folder, + create a recents array and pass it to imap_update_summary. Then + get a filter driver and use it to filter the recent messages. + + * providers/imap/camel-imap-summary.h: + * providers/imap/camel-imap-utils.c (imap_parse_flag_list): Add + support for the \Recent flag. + + * providers/imap/camel-imap-provider.c (imap_conf_entries): enable + the "filter" option. + + * camel-types.h: add CamelFilterDriver typedef here + 2001-07-02 Not Zed * camel-lock-client.c (camel_lock_helper_init): properly return diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index cc3b63f440..71c1091b07 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -228,27 +228,22 @@ camel_filter_driver_finalise (CamelObject *obj) /** * camel_filter_driver_new: - * @system: path to system rules - * @user: path to user rules - * @get_folder: function to call to fetch folders * - * Create a new CamelFilterDriver object. - * - * Return value: A new CamelFilterDriver widget. + * Return value: A new CamelFilterDriver object **/ CamelFilterDriver * -camel_filter_driver_new (CamelFilterGetFolderFunc get_folder, void *data) +camel_filter_driver_new (void) { - CamelFilterDriver *new; - struct _CamelFilterDriverPrivate *p; - - new = CAMEL_FILTER_DRIVER (camel_object_new(camel_filter_driver_get_type ())); - p = _PRIVATE (new); - + return CAMEL_FILTER_DRIVER (camel_object_new(camel_filter_driver_get_type ())); +} + +void +camel_filter_driver_set_folder_func (CamelFilterDriver *d, CamelFilterGetFolderFunc get_folder, void *data) +{ + struct _CamelFilterDriverPrivate *p = _PRIVATE (d); + p->get_folder = get_folder; p->data = data; - - return new; } void @@ -368,7 +363,6 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv if (argv[i]->type == ESEXP_RES_STRING) { /* open folders we intent to copy to */ char *folder = argv[i]->value.string; - char *service_url; CamelFolder *outbox; outbox = open_folder (driver, folder); @@ -386,10 +380,8 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv } else camel_folder_append_message (outbox, p->message, p->info, p->ex); - service_url = camel_service_get_url (CAMEL_SERVICE (camel_folder_get_parent_store (outbox))); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Copy to folder %s", - service_url); - g_free (service_url); + folder); } } @@ -408,7 +400,6 @@ do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv if (argv[i]->type == ESEXP_RES_STRING) { /* open folders we intent to move to */ char *folder = argv[i]->value.string; - char *service_url; CamelFolder *outbox; outbox = open_folder (driver, folder); @@ -428,10 +419,8 @@ do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv } else camel_folder_append_message (outbox, p->message, p->info, p->ex); - service_url = camel_service_get_url (CAMEL_SERVICE (camel_folder_get_parent_store (outbox))); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Move to folder %s", - service_url); - g_free (service_url); + folder); } } diff --git a/camel/camel-filter-driver.h b/camel/camel-filter-driver.h index fc72fa1485..7f4f3f7f15 100644 --- a/camel/camel-filter-driver.h +++ b/camel/camel-filter-driver.h @@ -33,7 +33,6 @@ #define CAMEL_FILTER_DRIVER_CLASS(klass) CAMEL__CHECK_CLASS_CAST (klass, camel_filter_driver_get_type (), CamelFilterDriverClass) #define CAMEL_IS_FILTER_DRIVER(obj) CAMEL_CHECK_TYPE (obj, camel_filter_driver_get_type ()) -typedef struct _CamelFilterDriver CamelFilterDriver; typedef struct _CamelFilterDriverClass CamelFilterDriverClass; struct _CamelFilterDriver { @@ -61,9 +60,10 @@ typedef CamelFolder * (*CamelFilterGetFolderFunc) (CamelFilterDriver *, const ch typedef void (CamelFilterStatusFunc)(CamelFilterDriver *driver, enum camel_filter_status_t status, int pc, const char *desc, void *data); guint camel_filter_driver_get_type (void); -CamelFilterDriver *camel_filter_driver_new (CamelFilterGetFolderFunc fetcher, void *data); +CamelFilterDriver *camel_filter_driver_new (void); /* modifiers */ +void camel_filter_driver_set_folder_func (CamelFilterDriver *d, CamelFilterGetFolderFunc fetcher, void *data); void camel_filter_driver_set_logfile (CamelFilterDriver *d, FILE *logfile); void camel_filter_driver_set_status_func (CamelFilterDriver *d, CamelFilterStatusFunc *func, void *data); diff --git a/camel/camel-session.c b/camel/camel-session.c index 7dc3c268f3..e21d6b7ef2 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -665,3 +665,20 @@ camel_session_set_online (CamelSession *session, gboolean online) { session->online = online; } + + +/** + * camel_session_get_filter_driver: + * @session: the session + * @type: the type of filter (eg, "incoming") + * @ex: a CamelException + * + * Return value: a filter driver, loaded with applicable rules + **/ +CamelFilterDriver * +camel_session_get_filter_driver (CamelSession *session, + const char *type, + CamelException *ex) +{ + return CS_CLASS (session)->get_filter_driver (session, type, ex); +} diff --git a/camel/camel-session.h b/camel/camel-session.h index fa0705c693..54eea0b1e6 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -101,6 +101,9 @@ typedef struct { gboolean (*remove_timeout) (CamelSession *session, guint handle); + CamelFilterDriver * (*get_filter_driver) (CamelSession *session, + const char *type, + CamelException *ex); } CamelSessionClass; @@ -136,38 +139,42 @@ CamelService * camel_session_get_service_connected (CamelSession *session, #define camel_session_get_transport(session, url_string, ex) \ ((CamelTransport *) camel_session_get_service_connected (session, url_string, CAMEL_PROVIDER_TRANSPORT, ex)) -char * camel_session_get_storage_path (CamelSession *session, +char * camel_session_get_storage_path (CamelSession *session, CamelService *service, CamelException *ex); -char * camel_session_get_password (CamelSession *session, +char * camel_session_get_password (CamelSession *session, const char *prompt, gboolean secret, CamelService *service, const char *item, CamelException *ex); -void camel_session_forget_password (CamelSession *session, +void camel_session_forget_password (CamelSession *session, CamelService *service, const char *item, CamelException *ex); -gboolean camel_session_alert_user (CamelSession *session, +gboolean camel_session_alert_user (CamelSession *session, CamelSessionAlertType type, const char *prompt, gboolean cancel); -guint camel_session_register_timeout (CamelSession *session, +guint camel_session_register_timeout (CamelSession *session, guint32 interval, CamelTimeoutCallback callback, gpointer user_data); -gboolean camel_session_remove_timeout (CamelSession *session, +gboolean camel_session_remove_timeout (CamelSession *session, guint handle); -gboolean camel_session_is_online (CamelSession *session); -void camel_session_set_online (CamelSession *session, +gboolean camel_session_is_online (CamelSession *session); +void camel_session_set_online (CamelSession *session, gboolean online); +CamelFilterDriver *camel_session_get_filter_driver (CamelSession *session, + const char *type, + CamelException *ex); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/camel-types.h b/camel/camel-types.h index f2928bb9f8..8480d9f024 100644 --- a/camel/camel-types.h +++ b/camel/camel-types.h @@ -34,6 +34,7 @@ typedef struct _CamelDiscoFolder CamelDiscoFolder; typedef struct _CamelDiscoStore CamelDiscoStore; typedef struct _CamelDataWrapper CamelDataWrapper; typedef struct _CamelException CamelException; +typedef struct _CamelFilterDriver CamelFilterDriver; typedef struct _CamelFolder CamelFolder; typedef struct _CamelFolderSearch CamelFolderSearch; typedef struct _CamelFolderSummary CamelFolderSummary; diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index beb9ec2740..c04c6cbb4c 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -50,6 +50,7 @@ #include "camel-data-wrapper.h" #include "camel-disco-diary.h" #include "camel-exception.h" +#include "camel-filter-driver.h" #include "camel-mime-filter-crlf.h" #include "camel-mime-filter-from.h" #include "camel-mime-message.h" @@ -219,6 +220,10 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name, return NULL; } + if ((imap_store->parameters & IMAP_PARAM_FILTER_INBOX) && + !g_strcasecmp (folder_name, "INBOX")) + imap_folder->do_filtering = TRUE; + return folder; } @@ -1515,6 +1520,7 @@ imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, static void imap_update_summary (CamelFolder *folder, CamelFolderChangeInfo *changes, + GPtrArray *recents, CamelException *ex) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); @@ -1623,12 +1629,14 @@ imap_update_summary (CamelFolder *folder, } camel_folder_summary_add (folder->summary, mi); camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi)); + if (recents && (mi->flags & CAMEL_IMAP_MESSAGE_RECENT)) + g_ptr_array_add (recents, (char *)camel_message_info_uid (mi)); } g_ptr_array_free (messages, TRUE); /* Did more mail arrive while we were doing this? */ if (exists && exists > camel_folder_summary_count (folder->summary)) - imap_update_summary (folder, changes, ex); + imap_update_summary (folder, changes, recents, ex); } /* Called with the store's command_lock locked */ @@ -1639,6 +1647,7 @@ camel_imap_folder_changed (CamelFolder *folder, int exists, CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); CamelFolderChangeInfo *changes; CamelMessageInfo *info; + GPtrArray *recents = NULL; int len; CAMEL_IMAP_STORE_ASSERT_LOCKED (folder->parent_store, command_lock); @@ -1660,8 +1669,11 @@ camel_imap_folder_changed (CamelFolder *folder, int exists, } len = camel_folder_summary_count (folder->summary); - if (exists > len) - imap_update_summary (folder, changes, ex); + if (exists > len) { + if (imap_folder->do_filtering) + recents = g_ptr_array_new (); + imap_update_summary (folder, changes, recents, ex); + } if (camel_folder_change_info_changed (changes)) { camel_object_trigger_event (CAMEL_OBJECT (folder), @@ -1669,6 +1681,22 @@ camel_imap_folder_changed (CamelFolder *folder, int exists, } camel_folder_change_info_free (changes); + if (recents) { + if (!camel_exception_is_set (ex) && recents->len) { + CamelFilterDriver *driver; + + driver = camel_session_get_filter_driver ( + CAMEL_SERVICE (folder->parent_store)->session, + "incoming", ex); + if (driver) { + camel_filter_driver_filter_folder ( + driver, folder, recents, FALSE, ex); + camel_object_unref (CAMEL_OBJECT (driver)); + } + } + g_ptr_array_free (recents, TRUE); + } + camel_folder_summary_save (folder->summary); } diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h index 295cfd041e..db507d52d5 100644 --- a/camel/providers/imap/camel-imap-folder.h +++ b/camel/providers/imap/camel-imap-folder.h @@ -48,7 +48,7 @@ struct _CamelImapFolder { struct _CamelImapFolderPrivate *priv; - gboolean need_rescan, need_refresh; + gboolean need_rescan, need_refresh, do_filtering; CamelFolderSearch *search; CamelImapMessageCache *cache; }; diff --git a/camel/providers/imap/camel-imap-provider.c b/camel/providers/imap/camel-imap-provider.c index c4b86c3bfc..35163cdf8d 100644 --- a/camel/providers/imap/camel-imap-provider.c +++ b/camel/providers/imap/camel-imap-provider.c @@ -53,7 +53,7 @@ CamelProviderConfEntry imap_conf_entries[] = { { CAMEL_PROVIDER_CONF_ENTRY, "namespace", "override_namespace", N_("Namespace") }, { CAMEL_PROVIDER_CONF_SECTION_END }, - { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", "UNIMPLEMENTED", + { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL, N_("Apply filters to new messages in INBOX on this server"), "0" }, { CAMEL_PROVIDER_CONF_END } }; diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h index 1b96008b1f..bd9e39cc5b 100644 --- a/camel/providers/imap/camel-imap-summary.h +++ b/camel/providers/imap/camel-imap-summary.h @@ -38,6 +38,8 @@ CAMEL_MESSAGE_FLAGGED | \ CAMEL_MESSAGE_SEEN) +#define CAMEL_IMAP_MESSAGE_RECENT (1 << 8) + typedef struct _CamelImapSummaryClass CamelImapSummaryClass; typedef struct _CamelImapMessageContentInfo { diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index 1da6bbcf20..f2909fb6a4 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -176,6 +176,8 @@ imap_parse_flag_list (char **flag_list_p) flags |= CAMEL_MESSAGE_FLAGGED; else if (!g_strncasecmp (flag_list, "\\Seen", len)) flags |= CAMEL_MESSAGE_SEEN; + else if (!g_strncasecmp (flag_list, "\\Recent", len)) + flags |= CAMEL_IMAP_MESSAGE_RECENT; flag_list += len; if (*flag_list == ' ') -- cgit v1.2.3