Hi all

Having not found a satisfactory solution to bug 311512 (new mail
notification) by trying to put the notification code into where mail is
received by the camel backends, I've looked into a different approach.

I was intrigued by how the mail-notification tool works, since it
effectively hangs off the same problematic folder.changed event. Looking
at its source code revealed that the author added to code to 'snoop'
through the messages, looking for ones that really were newmail (rather
than simply 'added to this folder').

So I have replicated this approach, but natively in evolution. The
attached patch affects mail-folder-cache.c only, and adds a function to
look for new messages comparing their 'received' timestamp with a global
timestamp. This enables us to check for messages that are brand new -
received since the last new mail arrived.

Can anyone comment on this patch - it should resolve nearly all the mail
notification problems. The one is doesn't resolve is to do with junk
mail - presumably I can just add a test against the messages to see if
they are junk. However - that assumes no folder_changed call happens
until after the junk-mail filtering has happened.

Currently the check has to snoop all messages in the folder. I think in
principle I can move the test into folder_changed and snoop through the
list of 'uid_added', which should be more efficient. Assuming nobody
flags any big pitfalls, I'll look into that soon.

Regards
Karl
--- mail-folder-cache.h.old	2007-03-02 13:11:50.000000000 +0000
+++ mail-folder-cache.h	2007-03-02 11:49:43.000000000 +0000
@@ -25,6 +25,9 @@
 #ifndef _MAIL_FOLDER_CACHE_H
 #define _MAIL_FOLDER_CACHE_H
 
+/* min no. seconds between newmail notifications */
+#define NOTIFY_THROTTLE 30
+
 #include <camel/camel-store.h>
 
 /* Add a store whose folders should appear in the shell
--- mail-folder-cache.c.old	2007-03-02 13:11:42.000000000 +0000
+++ mail-folder-cache.c	2007-03-02 13:14:13.000000000 +0000
@@ -103,7 +103,8 @@ struct _folder_update {
 	char *olduri;
 
 	int unread;
-	CamelStore *store;
+        CamelStore *store;
+        CamelFolder *folder;
 };
 
 struct _store_info {
@@ -127,10 +128,10 @@ static guint notify_id = 0;
 static int notify_type = -1;
 
 static time_t last_notify = 0;
+static time_t last_newmail = 0;
 static guint notify_idle_id = 0;
 static gboolean notify_idle_cb (gpointer user_data);
 
-
 /* Store to storeinfo table, active stores */
 static GHashTable *stores = NULL;
 
@@ -191,14 +192,41 @@ notify_type_changed (GConfClient *client
 	notify_type = gconf_client_get_int (client, "/apps/evolution/mail/notify/type", NULL);
 }
 
+static gboolean
+check_brand_new(CamelFolder *folder)
+{
+        GPtrArray *summary;
+        int i;
+    
+        summary = camel_folder_get_summary(folder);
+        for (i = 0; i < summary->len; i++)
+        {
+	    CamelMessageInfo *info = summary->pdata[i];
+
+//	    Check junk here using the flags?
+	    if (((camel_message_info_flags(info) & CAMEL_MESSAGE_SEEN) == 0) &&
+		 (camel_message_info_date_received(info) > last_newmail))
+	    {
+		camel_folder_free_summary(folder, summary);
+		time (&last_newmail);
+		d(printf("brand_new TRUE\n"));
+		return TRUE;
+	    }
+        }
+    
+        camel_folder_free_summary(folder, summary);
+	d(printf("brand_new FALSE\n"));
+        return FALSE;
+}
+
 static void
 real_flush_updates(void *o, void *event_data, void *data)
 {
 	struct _MailComponent *component;
 	struct _EMFolderTreeModel *model;
 	struct _folder_update *up;
-	time_t now;
-	
+        gboolean brand_new = FALSE;
+
 	component = mail_component_peek ();
 	model = mail_component_peek_tree_model (component);
 	
@@ -230,7 +258,12 @@ real_flush_updates(void *o, void *event_
 		
 		/* update unread counts */
 		em_folder_tree_model_set_unread_count (model, up->store, up->full_name, up->unread);
-		
+	    
+	        /* Check for brand new mail */
+	        if (up->new && up->unread > 0) {
+		    brand_new = check_brand_new (up->folder);
+		}
+	    
 		/* new mail notification */
 		if (notify_type == -1) {
 			/* need to track the user's new-mail-notification settings... */
@@ -244,13 +277,12 @@ real_flush_updates(void *o, void *event_
 			notify_type = gconf_client_get_int (gconf, "/apps/evolution/mail/notify/type", NULL);
 		}
 		
-		time (&now);
-		if (notify_type != 0 && up->new && notify_idle_id == 0 && (now - last_notify >= 5))
+		if (notify_type != 0 && brand_new && notify_idle_id == 0 && (last_newmail - last_notify >= NOTIFY_THROTTLE))
 			notify_idle_id = g_idle_add_full (G_PRIORITY_LOW, notify_idle_cb, NULL, NULL);
 		
 		if (up->uri) {
 			EMEvent *e = em_event_peek();
-			EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, up->new?EM_EVENT_FOLDER_NEWMAIL:0);
+			EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, brand_new?EM_EVENT_FOLDER_NEWMAIL:0);
 
 			/** @Event: folder.changed
 			 * @Title: Folder changed
@@ -380,6 +412,7 @@ update_1folder(struct _folder_info *mfi,
 	up->new = new ? 1 : 0;
 	up->store = mfi->store_info->store;
 	up->uri = g_strdup(mfi->uri);
+        up->folder = folder;
 	camel_object_ref(up->store);
 	e_dlist_addtail(&updates, (EDListNode *)up);
 	flush_updates();
_______________________________________________
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers

Reply via email to