Re: New design idea: when new messages arrive



And now the real diff

On Mon, 2007-01-22 at 02:35 +0100, Philip Van Hoof wrote:
> Applying this diff on what is current in SVN will already append the
> newest messages to your view.
> 
> The messages wont be readable, and while the operation of checking for
> new messages happens, if you would for example do another operation on
> the IMAP server like getting a message, you'd crash the application.
> 
> So I need to make it in itself cancel-able (over writable by a real
> command from the user, as that one has a higher priority of course).
> 
> I also need to check locking in depth of the IMAP provider before any of
> this is in some sort of usable state (it isn't).
> 
> The problem is of course that I want to reuse the one connection .. that
> I don't want to create a new connection. This of course means playing
> nice with the foreground operations (that is, restoring the state if
> this background operation changes any state, like the selected folder,
> and making sure that the background operation doesn't run in case any
> foreground operation is already running).
> 
> ps. There's indeed a lot of work on this feature. Or at least until it
> will be a usable and more specifically stable state.
> 
> But using this patch people can try and see what direction I'm heading.
> 
> Not that I'm very certain whether this feature is actually doable ...
> 
> 
> On Tue, 2007-01-16 at 22:37 +0100, Philip Van Hoof wrote:
> > When new messages arrive, tinymail will soon add them to the models that
> > are registered as observer of the folder.
> > 
> > http://tinymail.org/trac/tinymail/wiki/WhenNewMessagesArrive
> > 
> > 
> _______________________________________________
> tinymail-devel-list mailing list
> tinymail-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/tinymail-devel-list
-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog



Index: libtinymail-camel/tny-camel-folder.c
===================================================================
--- libtinymail-camel/tny-camel-folder.c	(revision 1445)
+++ libtinymail-camel/tny-camel-folder.c	(working copy)
@@ -2213,12 +2213,44 @@
 tny_camel_folder_poke_status_callback (gpointer data)
 {
 	TnyFolder *self = data;
+	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
+
 	TnyFolderChange *change = tny_folder_change_new (self);
+	GPtrArray *items = NULL;
+	CamelStore *store = priv->store;
+	gint unseen = -1, msgs = -1;
 
 #ifdef IM_TESTING
 	add_dummy_test_header (self, change);
 #endif
 
+	items = camel_store_get_recent_messages (store, priv->folder_name, 
+			&unseen, &msgs);
+
+	if (unseen != 0)
+		priv->unread_length = unseen;
+	if (msgs != 0)
+		priv->cached_length = msgs;
+
+	if (items)
+	{
+		int i;
+
+		printf ("Have %d items (%d,%d)\n",
+			items->len, unseen, msgs);
+
+		for (i=0; i< items->len; i++)
+		{
+			CamelMessageInfo *info = g_ptr_array_index (items, i);
+			TnyHeader *hdr_addded = tny_camel_header_new ();
+			_tny_camel_header_set_as_memory (TNY_CAMEL_HEADER (hdr_addded), info);
+			tny_folder_change_add_added_header (change, hdr_addded);
+			g_object_unref (G_OBJECT (hdr_addded));
+		}
+		g_ptr_array_free (items, TRUE);
+
+	}
+
 	notify_observers_about (self, change);
 
 	g_object_unref (G_OBJECT (change));
Index: libtinymail-camel/camel-lite/camel/camel-store.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-store.c	(revision 1445)
+++ libtinymail-camel/camel-lite/camel/camel-store.c	(working copy)
@@ -178,6 +178,20 @@
 	return camel_store_type;
 }
 
+
+GPtrArray* 
+camel_store_get_recent_messages (CamelStore *store, const char *folder_name, 
+			int *unseen, int *messages)
+{
+	GPtrArray *ret;
+
+	CAMEL_STORE_LOCK(store, folder_lock);
+	ret = CS_CLASS (store)->get_recent_messages (store, folder_name, unseen, messages);
+	CAMEL_STORE_UNLOCK(store, folder_lock);
+
+	return ret;
+}
+
 static GPtrArray* 
 get_recent_messages (CamelStore *store, const char *folder_name, int *unseen, int *messages)
 {
@@ -1121,6 +1135,8 @@
 	return ret;
 }
 
+
+
 static void
 subscribe_folder(CamelStore *store, const char *folder_name, CamelException *ex)
 {
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(revision 1445)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(working copy)
@@ -1795,11 +1795,12 @@
 	struct imap_status_item *items, *item, *tail;
 	CamelImapResponse *response;
 	char *status, *name, *p;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
 
 	if (!(imap_store->capabilities & IMAP_CAPABILITY_STATUS))
 		return NULL;
 
-	response = camel_imap_command (imap_store, NULL, NULL,
+	response = camel_imap_command (imap_store, NULL, &ex,
 				       "STATUS %F (%s)",
 				       folder_name,
 				       type);
@@ -2036,13 +2037,34 @@
 	struct imap_status_item *items, *item;
 	guint ounseen, omessages, ouidnext;
 	GPtrArray *retval = NULL;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+	CamelImapResponse *response;
+	CamelException tex = CAMEL_EXCEPTION_INITIALISER;
 
+	if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (imap_store), &ex))
+		return NULL;
+
 /*
       Example:    C: A042 STATUS blurdybloop (UIDNEXT MESSAGES)
                   S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
                   S: A042 OK STATUS completed
 */
 
+	camel_operation_uncancel (NULL);
+
+
+	/* On for example courier, the selected's STATUS is cached (kill that cache) */
+	if (withthem)
+	{
+	    response = camel_imap_command (imap_store, NULL, &tex,
+			    "SELECT"/*, folder_name*/);
+
+printf ("SELECT %s\n", folder_name);
+
+	    if (response)
+		    camel_imap_response_free (imap_store, response);
+	}
+
 	item = items = get_folder_status (imap_store, folder_name, "MESSAGES UNSEEN UIDNEXT");
 	while (item != NULL) {
 		if (!g_ascii_strcasecmp (item->name, "MESSAGES"))
@@ -2054,6 +2076,7 @@
 		item = item->next;
 	}
 	imap_status_item_free (items);
+printf ("%d %d %d\n", *messages, *unseen, uidnext);
 
 	if (withthem)
 	{
@@ -2061,18 +2084,10 @@
 
 		if (ouidnext != uidnext)
 		{
-			CamelImapResponse *response;
 			CamelImapResponseType type;
-			CamelException tex = CAMEL_EXCEPTION_INITIALISER;
 			char *resp; 
 
-			if (!camel_imap_store_connected (imap_store, &tex))
-				goto done;
-			response = camel_imap_command (imap_store, NULL, &tex,
-					"SELECT %F", folder_name);
-			if (!response)
-				goto done;
-			camel_imap_response_free (imap_store, response);
+			camel_exception_clear (&tex);
 
 			if (!camel_imap_command_start (imap_store, NULL, &tex,
 				"UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[HEADER])", ouidnext-1))
@@ -2095,8 +2110,6 @@
 			   }
 			}
 
-			camel_imap_response_free (imap_store, response);
-
 			/* Restore the original folder selection */
 			if (imap_store->current_folder != NULL && imap_store->current_folder->full_name != NULL)
 			{
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(revision 1445)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(working copy)
@@ -2252,7 +2252,7 @@
 	return TRUE;
 }
 
-static time_t
+time_t
 decode_internaldate (const unsigned char *in)
 {
 	const unsigned char *inptr = in;
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h	(revision 1445)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h	(working copy)
@@ -83,6 +83,8 @@
 					   gboolean cache_only,
 					   CamelFolderReceiveType type, gint param, CamelException *ex);
 
+time_t decode_internaldate (const unsigned char *in);
+
 /* Standard Camel function */
 CamelType camel_imap_folder_get_type (void);
 
Index: libtinymail-camel/camel-lite/camel/camel-folder-summary.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-folder-summary.c	(revision 1445)
+++ libtinymail-camel/camel-lite/camel/camel-folder-summary.c	(working copy)
@@ -1152,19 +1152,27 @@
 camel_folder_summary_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg)
 {
 	CamelMessageInfo *info;
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+	struct _CamelFolderSummaryPrivate *p;
 	CamelIndexName *name = NULL;
 
-	info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_message(s, msg);
+	if (s != NULL)
+	{
+		info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_message(s, msg);
 
-	/* assign a unique uid, this is slightly 'wrong' as we do not really
-	 * know if we are going to store this in the summary, but we need it set for indexing */
-	if (p->index)
-		summary_assign_uid(s, info);
+		p = _PRIVATE(s);
 
-	CAMEL_SUMMARY_LOCK(s, filter_lock);
+		/* assign a unique uid, this is slightly 'wrong' as we do not really
+		 * know if we are going to store this in the summary, but we need it set for indexing */
+		if (p->index)
+			summary_assign_uid(s, info);
+	} else
+		info = message_info_new_from_message(s, msg);
 
-	if (p->index) {
+
+	if (s!=NULL)
+		CAMEL_SUMMARY_LOCK(s, filter_lock);
+
+	if (s != NULL && p->index) {
 		if (p->filter_index == NULL)
 			p->filter_index = camel_mime_filter_index_new_index(p->index);
 		camel_index_delete_name(p->index, camel_message_info_uid(info));
@@ -1181,13 +1189,15 @@
 
 	((CamelMessageInfoBase *)info)->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg);
 
-	if (name) {
+	if (s != NULL && name) 
+	{
 		camel_index_write_name(p->index, name);
 		camel_object_unref((CamelObject *)name);
 		camel_mime_filter_index_set_name(p->filter_index, NULL);
 	}
 
-	CAMEL_SUMMARY_UNLOCK(s, filter_lock);
+	if (s!=NULL)
+		CAMEL_SUMMARY_UNLOCK(s, filter_lock);
 
 	return info;
 }
@@ -1206,7 +1216,12 @@
 	CamelMessageContentInfo *pw, *pn;
 
 	pw = ci->childs;
-	((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_free(s, ci);
+
+	if (s != NULL)
+		((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_free(s, ci);
+	else
+		content_info_free (NULL, ci);
+
 	while (pw) {
 		pn = pw->next;
 		camel_folder_summary_content_info_free(s, pw);
@@ -1741,7 +1756,10 @@
 {
 	CamelMessageInfo *mi;
 
-	mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
+	if (s != NULL)
+		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
+	else
+		mi = message_info_new_from_header(s, ((CamelMimePart *)msg)->headers);
 
 	return mi;
 }
@@ -1751,7 +1769,10 @@
 {
 	CamelMessageContentInfo *ci;
 
-	ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers);
+	if (s != NULL)
+		ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers);
+	else
+		ci = content_info_new_from_header(NULL, mp->headers);
 
 	return ci;
 }
@@ -1805,7 +1826,9 @@
 CamelMessageContentInfo *
 camel_folder_summary_content_info_new(CamelFolderSummary *s)
 {
-	return g_slice_alloc0(s->content_info_size);
+	if (s != NULL)
+		return g_slice_alloc0(s->content_info_size);
+	return g_slice_new0 (CamelMessageContentInfo);
 }
 
 static CamelMessageInfo *
@@ -2360,7 +2383,10 @@
 		token_free (ci->encoding);
 	}
 
-	g_slice_free1(s->content_info_size, ci);
+	if (s != NULL)
+		g_slice_free1(s->content_info_size, ci);
+	else
+		g_slice_free (CamelMessageContentInfo, ci);
 }
 
 static char *
@@ -2536,13 +2562,18 @@
 {
 	CamelDataWrapper *containee;
 	int parts, i;
-	struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+	struct _CamelFolderSummaryPrivate *p;
 	CamelMessageContentInfo *info = NULL, *child;
 	CamelContentType *ct;
 
-	if (s->build_content)
+	if (s != NULL && s->build_content)
 		info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_message(s, object);
-	
+	else
+		info = content_info_new_from_message(NULL, object);
+
+	if (s != NULL)
+		p = _PRIVATE(s);
+
 	containee = camel_medium_get_content_object(CAMEL_MEDIUM(object));
 
 	if (containee == NULL)
@@ -2587,7 +2618,7 @@
 			child->parent = info;
 			my_list_append((struct _node **)&info->childs, (struct _node *)child);
 		}
-	} else if (p->filter_stream
+	} else if (s != NULL && p->filter_stream
 		   && camel_content_type_is(ct, "text", "*")) {
 		int html_id = -1, idx_id = -1;
 
@@ -3090,7 +3121,11 @@
 		}
 		GLOBAL_INFO_UNLOCK(info);
 
+		if (((CamelMessageInfoBase *)mi)->content)
+			camel_folder_summary_content_info_free(NULL, ((CamelMessageInfoBase *)mi)->content);
+
 		message_info_free(NULL, mi);
+
 	}
 }
 
Index: libtinymail-camel/tny-camel-account.c
===================================================================
--- libtinymail-camel/tny-camel-account.c	(revision 1445)
+++ libtinymail-camel/tny-camel-account.c	(working copy)
@@ -213,10 +213,13 @@
 		tny_camel_account_stop_camel_operation_priv (priv);
 	}
 
+	camel_operation_uncancel (NULL);
+
 	while (priv->inuse_spin); 
 
 	priv->inuse_spin = TRUE;
 
+
 	priv->cancel = camel_operation_new (func, user_data);
 	
 	camel_operation_ref (priv->cancel);


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