Re: Partial message retrieval, the design
- From: Philip Van Hoof <spam pvanhoof be>
- To: tinymail-devel-list gnome org
- Cc: Dirk-Jan Binnema <Dirk-Jan Binnema nokia com>
- Subject: Re: Partial message retrieval, the design
- Date: Sat, 06 Jan 2007 18:33:26 +0100
New version that fixes a few things
On Sat, 2007-01-06 at 16:24 +0100, Philip Van Hoof wrote:
> This E-mail is all about throwing food to wolves
>
> Yes, it implements the core of partial message retrieval for IMAP.
>
> Not yet the jingle bells around it (there's still some work like
> detecting whether the message was previously retrieved partial whereas
> the user switched to full -- which means that it has to reretrieve the
> full message).
>
> Anyway, test this a little bit folks :)
>
> Or join!? We can start a branch for example.
>
>
> On Wed, 2007-01-03 at 18:40 +0100, Philip Van Hoof wrote:
> > Hi folks,
> >
> > This is a first design of the upcoming partial message retrieval feature
> >
> > o. http://tinymail.org/trac/tinymail/wiki/PartialMessageRetrieval
> >
> > Two new documentation pages have been added. These are about the
> > camel-lite internals. The first is going to be important when
> > implementing the camel-lite part of the partial message retrieval
> > feature (which is not really shown in the design, as that part will have
> > to blend in the existing camel infrastructure).
> >
> > o. http://tinymail.org/trac/tinymail/wiki/CamelImapMessageCache
> > o. http://tinymail.org/trac/tinymail/wiki/CamelFolderSummaryMmap
> >
> > In short will the camel-lite API, camel_folder_get_message, be changed
> > to have an extra bool "full" to its parameters. If that bool is FALSE
> > then it will only fetch the body of the E-mail from the service. Else it
> > will retrieve the entire message content (including all attachments and
> > other mime parts). Or ... at least that is the idea.
> >
> > At the tinymail part no API will be changed, only added. The API that
> > will be added is tny_folder_set/get_msg_receive_strategy. Two types will
> > also be added in libtinymail-camel (but check the wiki page for more
> > information, as decisions might change things .. whereas this E-mail
> > can't change once I press the Send button).
> >
> > Comments, thoughts and everything in between (except brick throwing at
> > my head) is very welcome. If somebody is interested in cooperating or
> > co-developing this feature, please don't hesitate to contact me or write
> > about your ideas and intentions on this mailing list.
> >
> >
> _______________________________________________
> 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 1363)
+++ libtinymail-camel/tny-camel-folder.c (working copy)
@@ -2318,7 +2318,7 @@
priv->cached_folder_type = TNY_FOLDER_TYPE_UNKNOWN;
priv->remove_strat = tny_camel_msg_remove_strategy_new ();
- priv->receive_strat = tny_camel_full_msg_receive_strategy_new ();
+ priv->receive_strat = tny_camel_partial_msg_receive_strategy_new ();
return;
}
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (revision 1366)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (working copy)
@@ -136,6 +136,7 @@
static CamelObjectClass *parent_class;
static GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att);
+static GData *parse_partial_fetch_response (CamelImapFolder *imap_folder, char *response, GData *data, gboolean last);
#ifdef G_OS_WIN32
/* The strtok() in Microsoft's C library is MT-safe (but still uses
@@ -1718,7 +1719,7 @@
static CamelMimeMessage *get_message (CamelImapFolder *imap_folder,
const char *uid,
CamelMessageContentInfo *ci,
- CamelException *ex);
+ gboolean full, CamelException *ex);
struct _part_spec_stack {
struct _part_spec_stack *parent;
@@ -1839,7 +1840,8 @@
strcpy(spec, part_spec);
g_free(part_spec);
- stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, ex);
+ /* TNY TODO: partial message retrieval exception */
+ stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, TRUE, ex);
if (stream) {
ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (body_mp), stream);
camel_object_unref (CAMEL_OBJECT (stream));
@@ -1876,7 +1878,8 @@
num = 1;
while (ci) {
sprintf (child_spec + speclen, "%d.MIME", num++);
- stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, ex);
+ /* TNY TODO: partial message retrieval exception */
+ stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, TRUE, ex);
if (stream) {
int ret;
@@ -1932,7 +1935,8 @@
return (CamelDataWrapper *) body_mp;
} else if (camel_content_type_is (ci->type, "message", "rfc822")) {
- content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, ex);
+ /* TNY TODO: partial message retrieval exception */
+ content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, TRUE, ex);
g_free (part_spec);
return content;
} else {
@@ -1956,7 +1960,7 @@
static CamelMimeMessage *
get_message (CamelImapFolder *imap_folder, const char *uid,
CamelMessageContentInfo *ci,
- CamelException *ex)
+ gboolean full, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER (imap_folder)->parent_store);
CamelDataWrapper *content;
@@ -1970,7 +1974,8 @@
section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "",
store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0");
- stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, ex);
+ /* TNY: partial message retrieval */
+ stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, full, ex);
g_free (section_text);
g_free(part_spec);
if (!stream)
@@ -2010,14 +2015,14 @@
static CamelMimeMessage *
get_message_simple (CamelImapFolder *imap_folder, const char *uid,
- CamelStream *stream, CamelException *ex)
+ CamelStream *stream, gboolean full, CamelException *ex)
{
CamelMimeMessage *msg;
int ret;
if (!stream) {
stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
- FALSE, ex);
+ FALSE, full, ex);
if (!stream)
return NULL;
}
@@ -2076,8 +2081,8 @@
/* If its cached in full, just get it as is, this is only a shortcut,
since we get stuff from the cache anyway. It affects a busted connection though. */
- if ( (stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, NULL))
- && (msg = get_message_simple(imap_folder, uid, stream, ex)))
+ if ( (stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, full, NULL))
+ && (msg = get_message_simple(imap_folder, uid, stream, full, ex)))
goto done;
/* All this mess is so we silently retry a fetch if we fail with
@@ -2094,7 +2099,7 @@
|| mi->info.size < IMAP_SMALL_BODY_SIZE
#endif
|| (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) {
- msg = get_message_simple (imap_folder, uid, NULL, ex);
+ msg = get_message_simple (imap_folder, uid, NULL, full, ex);
} else {
if (content_info_incomplete (mi->info.content)) {
/* For larger messages, fetch the structure and build a message
@@ -2160,9 +2165,9 @@
* let the mailer's "bad MIME" code handle it.
*/
if (content_info_incomplete (mi->info.content))
- msg = get_message_simple (imap_folder, uid, NULL, ex);
+ msg = get_message_simple (imap_folder, uid, NULL, full, ex);
else
- msg = get_message (imap_folder, uid, mi->info.content, ex);
+ msg = get_message (imap_folder, uid, mi->info.content, full, ex);
}
} while (msg == NULL
&& retry < 2
@@ -2184,7 +2189,8 @@
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (disco_folder);
CamelStream *stream;
- stream = camel_imap_folder_fetch_data (imap_folder, uid, "", FALSE, ex);
+ /* TNY TODO: partial message retrieval exception */
+ stream = camel_imap_folder_fetch_data (imap_folder, uid, "", FALSE, TRUE, ex);
if (stream)
camel_object_unref (CAMEL_OBJECT (stream));
}
@@ -2686,13 +2692,13 @@
CamelStream *
camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid,
const char *section_text, gboolean cache_only,
- CamelException *ex)
+ gboolean full, CamelException *ex)
{
CamelFolder *folder = CAMEL_FOLDER (imap_folder);
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapResponse *response;
CamelStream *stream;
- GData *fetch_data;
+ GData *fetch_data=NULL;
char *found_uid;
int i;
@@ -2731,36 +2737,96 @@
}
camel_exception_clear (ex);
- if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text) {
- response = camel_imap_command (store, folder, ex,
- "UID FETCH %s RFC822.PEEK",
- uid);
+
+ if (full)
+ {
+ if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text) {
+ response = camel_imap_command (store, folder, ex,
+ "UID FETCH %s RFC822.PEEK",
+ uid);
+ } else {
+ response = camel_imap_command (store, folder, ex,
+ "UID FETCH %s BODY.PEEK[%s]",
+ uid, section_text);
+ }
+ /* We won't need the connect_lock again after this. */
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+ if (!response) {
+ CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+ return NULL;
+ }
+
+ for (i = 0; i < response->untagged->len; i++) {
+ fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
+ found_uid = g_datalist_get_data (&fetch_data, "UID");
+ stream = g_datalist_get_data (&fetch_data, "BODY_PART_STREAM");
+ if (found_uid && stream && !strcmp (uid, found_uid))
+ break;
+
+ g_datalist_clear (&fetch_data);
+ stream = NULL;
+ }
+ camel_imap_response_free (store, response);
} else {
- response = camel_imap_command (store, folder, ex,
- "UID FETCH %s BODY.PEEK[%s]",
- uid, section_text);
+
+ /* Partial message retrieval feature
+
+ { HEADER boundary 1.HEADER 1 boundary }
+ */
+
+ stream = NULL;
+ response = camel_imap_command (store, folder, ex,
+ "UID FETCH %s BODY.PEEK[HEADER]", uid);
+ if (!response) {
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+ goto errorh;
+ }
+
+ for (i = 0; i < response->untagged->len; i++)
+ fetch_data = parse_partial_fetch_response (imap_folder, response->untagged->pdata[i], fetch_data, FALSE);
+ camel_imap_response_free (store, response);
+
+ response = camel_imap_command (store, folder, ex,
+ "UID FETCH %s BODY.PEEK[1.HEADER]", uid);
+ if (!response) {
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+ goto errorh;
+ }
+
+ for (i = 0; i < response->untagged->len; i++)
+ fetch_data = parse_partial_fetch_response (imap_folder, response->untagged->pdata[i], fetch_data, FALSE);
+ camel_imap_response_free (store, response);
+
+ response = camel_imap_command (store, folder, ex,
+ "UID FETCH %s BODY.PEEK[1]", uid);
+ if (!response) {
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+ goto errorh;
+ }
+
+ CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+ for (i = 0; i < response->untagged->len; i++) {
+ fetch_data = parse_partial_fetch_response (imap_folder, response->untagged->pdata[i], fetch_data, TRUE);
+ found_uid = g_datalist_get_data (&fetch_data, "UID");
+ stream = g_datalist_get_data (&fetch_data, "BODY_PART_STREAM");
+ if (found_uid && stream && !strcmp (uid, found_uid))
+ break;
+
+ g_datalist_clear (&fetch_data);
+ stream = NULL;
+ }
+ camel_imap_response_free (store, response);
+
}
- /* We won't need the connect_lock again after this. */
- CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
-
- if (!response) {
- CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
- return NULL;
- }
-
- for (i = 0; i < response->untagged->len; i++) {
- fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
- found_uid = g_datalist_get_data (&fetch_data, "UID");
- stream = g_datalist_get_data (&fetch_data, "BODY_PART_STREAM");
- if (found_uid && stream && !strcmp (uid, found_uid))
- break;
-
- g_datalist_clear (&fetch_data);
- stream = NULL;
- }
- camel_imap_response_free (store, response);
+
+errorh:
+
CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
- if (!stream) {
+
+ if (!stream)
+ {
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("Could not find message body in FETCH response."));
} else {
@@ -2771,7 +2837,229 @@
return stream;
}
+
+
static GData *
+parse_partial_fetch_response (CamelImapFolder *imap_folder, char *response, GData *data, gboolean last)
+{
+ char *start, *part_spec = NULL, *body = NULL, *uid = NULL, *idate = NULL;
+ gboolean cache_header = TRUE, header = FALSE;
+ size_t body_len = 0;
+
+ char *esequence, *ebodypartspec, *ebodypartdata;
+ char *eintdate, *euid;
+ int eflags = 0, erfc822size = 0, ebodypartlen = 0;
+
+ esequence = g_datalist_get_data (&data, "SEQUENCE");
+ eflags = GPOINTER_TO_UINT (g_datalist_get_data (&data, "FLAGS"));
+ erfc822size = GPOINTER_TO_UINT (g_datalist_get_data (&data, "RFC822.SIZE"));
+ esequence = g_datalist_get_data (&data, "SEQUENCE");
+ eintdate = g_datalist_get_data (&data, "INTERNALDATE");
+ euid = g_datalist_get_data (&data, "UID");
+ ebodypartspec = g_datalist_get_data (&data, "BODY_PART_SPEC");
+ ebodypartdata = g_datalist_get_data (&data, "BODY_PART_DATA");
+ ebodypartlen = GPOINTER_TO_INT (g_datalist_get_data (&data, "BODY_PART_LEN"));
+
+
+ if (*response != '(') {
+ long seq;
+
+ if (*response != '*' || *(response + 1) != ' ')
+ return NULL;
+ seq = strtol (response + 2, &response, 10);
+ if (seq == 0)
+ return NULL;
+ if (g_ascii_strncasecmp (response, " FETCH (", 8) != 0)
+ return NULL;
+ response += 7;
+
+ if (!esequence)
+ g_datalist_set_data (&data, "SEQUENCE", GINT_TO_POINTER (seq));
+ }
+
+ do {
+ /* Skip the initial '(' or the ' ' between elements */
+ response++;
+
+ if (!g_ascii_strncasecmp (response, "FLAGS ", 6)) {
+ guint32 flags;
+
+ response += 6;
+ /* FIXME user flags */
+ flags = imap_parse_flag_list (&response);
+
+ g_datalist_set_data (&data, "FLAGS", GUINT_TO_POINTER (flags | eflags));
+ } else if (!g_ascii_strncasecmp (response, "RFC822.SIZE ", 12)) {
+ unsigned long size;
+
+ response += 12;
+ size = strtoul (response, &response, 10);
+ g_datalist_set_data (&data, "RFC822.SIZE", GUINT_TO_POINTER (size + erfc822size));
+ } else if (!g_ascii_strncasecmp (response, "BODY[", 5) ||
+ !g_ascii_strncasecmp (response, "RFC822 ", 7)) {
+ char *p;
+ char *boundary = NULL;
+ char *nbody;
+ int nlen = 0, blen = 0;
+
+ if (*response == 'B') {
+ response += 5;
+
+ /* HEADER], HEADER.FIELDS (...)], or 0] */
+ if (!g_ascii_strncasecmp (response, "HEADER", 6)) {
+ header = TRUE;
+ if (!g_ascii_strncasecmp (response + 6, ".FIELDS", 7))
+ cache_header = FALSE;
+ } else if (!g_ascii_strncasecmp (response, "0]", 2))
+ header = TRUE;
+
+ p = strchr (response, ']');
+ if (!p || *(p + 1) != ' ')
+ break;
+
+ if (cache_header)
+ part_spec = g_strndup (response, p - response);
+ else
+ part_spec = g_strdup ("HEADER.FIELDS");
+
+ response = p + 2;
+ } else {
+ part_spec = g_strdup ("");
+ response += 7;
+
+ if (!g_ascii_strncasecmp (response, "HEADER", 6))
+ header = TRUE;
+ }
+
+ body = imap_parse_nstring ((const char **) &response, &body_len);
+ if (!response) {
+ g_free (part_spec);
+ break;
+ }
+
+ if (!body)
+ body = g_strdup ("");
+
+ boundary = g_datalist_get_data (&data, "BOUNDARY");
+
+ if (!boundary)
+ {
+ CamelContentType *ct = NULL;
+ const char *bound=NULL;
+ char *pstr = (char*)strcasestr (body, "Content-Type:");
+
+ if (pstr) {
+ pstr = strchr (pstr, ':');
+ if (pstr) { pstr++;
+ ct = camel_content_type_decode(pstr); }
+ }
+
+ if (ct) {
+ bound = camel_content_type_param(ct, "boundary");
+ if (bound) {
+ boundary = g_strdup (bound);
+ blen = strlen (bound);
+ g_datalist_set_data_full (&data, "BOUNDARY", boundary, g_free);
+ }
+ }
+ } else
+ blen = strlen (boundary);
+
+ if (!ebodypartspec) { /* Only the first is cool for below */
+ g_datalist_set_data_full (&data, "BODY_PART_SPEC", part_spec, g_free);
+ ebodypartspec = part_spec;
+ }
+
+ if (ebodypartdata)
+ {
+ if (blen > 0)
+ {
+ if (!last)
+ nbody = g_strdup_printf ("%s\n--%s\n%s", ebodypartdata, boundary, body);
+ else
+ nbody = g_strdup_printf ("%s%s\n--%s\n", ebodypartdata, body, boundary);
+
+ nlen = ebodypartlen + body_len + blen + 4;
+ g_datalist_set_data (&data, "BODY_PART_LEN", GINT_TO_POINTER (nlen));
+ } else
+ {
+ nbody = g_strdup_printf ("%s%s", ebodypartdata, body);
+ nlen = ebodypartlen + body_len;
+ g_datalist_set_data (&data, "BODY_PART_LEN", GINT_TO_POINTER (nlen));
+ }
+ g_free (body); body = nbody;
+ body_len = nlen;
+ g_datalist_set_data_full (&data, "BODY_PART_DATA", nbody, g_free);
+ } else {
+ g_datalist_set_data_full (&data, "BODY_PART_DATA", body, g_free);
+ g_datalist_set_data (&data, "BODY_PART_LEN", GINT_TO_POINTER (body_len));
+ }
+
+ } else if (!g_ascii_strncasecmp (response, "BODY ", 5) ||
+ !g_ascii_strncasecmp (response, "BODYSTRUCTURE ", 14)) {
+ response = strchr (response, ' ') + 1;
+ start = response;
+ imap_skip_list ((const char **) &response);
+ g_datalist_set_data_full (&data, "BODY", g_strndup (start, response - start), g_free);
+ } else if (!g_ascii_strncasecmp (response, "UID ", 4)) {
+ int len;
+
+ len = strcspn (response + 4, " )");
+ uid = g_strndup (response + 4, len);
+ g_datalist_set_data_full (&data, "UID", uid, g_free);
+ response += 4 + len;
+ } else if (!g_ascii_strncasecmp (response, "INTERNALDATE ", 13)) {
+ int len;
+
+ response += 13;
+ if (*response == '"')
+ {
+ response++;
+ len = strcspn (response, "\"");
+ idate = g_strndup (response, len);
+ g_datalist_set_data_full (&data, "INTERNALDATE", idate, g_free);
+ response += len + 1;
+ }
+ } else {
+ g_warning ("Unexpected FETCH response from server: (%s", response);
+ break;
+ }
+ } while (response && *response != ')');
+
+ if (!response || *response != ')') {
+ g_datalist_clear (&data);
+ return NULL;
+ }
+
+ if (last && uid && body)
+ {
+ CamelStream *stream;
+
+ if (header && !cache_header)
+ stream = camel_stream_mem_new_with_buffer (body, body_len);
+ else
+ {
+ char *pspec = ebodypartspec;
+ if (!pspec || (ebodypartspec && !strcmp (ebodypartspec, "HEADER")))
+ pspec = "";
+
+ CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
+ stream = camel_imap_message_cache_insert (imap_folder->cache, uid,
+ pspec, body, body_len, NULL);
+ CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+ if (stream == NULL)
+ stream = camel_stream_mem_new_with_buffer (body, body_len);
+ }
+
+ if (stream)
+ g_datalist_set_data_full (&data, "BODY_PART_STREAM", stream,
+ (GDestroyNotify) camel_object_unref);
+ }
+
+ return data;
+}
+
+static GData *
parse_fetch_response (CamelImapFolder *imap_folder, char *response)
{
GData *data = NULL;
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h (revision 1363)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.h (working copy)
@@ -80,7 +80,7 @@
const char *uid,
const char *section_text,
gboolean cache_only,
- CamelException *ex);
+ gboolean full, CamelException *ex);
/* Standard Camel function */
CamelType camel_imap_folder_get_type (void);
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-wrapper.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-wrapper.c (revision 1363)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-wrapper.c (working copy)
@@ -141,9 +141,10 @@
if (data_wrapper->offline) {
CamelStream *datastream;
+ /* TNY TODO: partial message retrieval exception */
datastream = camel_imap_folder_fetch_data (
imap_wrapper->folder, imap_wrapper->uid,
- imap_wrapper->part_spec, FALSE, NULL);
+ imap_wrapper->part_spec, FALSE, TRUE, NULL);
if (!datastream) {
CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
#ifdef ENETUNREACH
@@ -188,8 +189,9 @@
imap_wrapper->part = part;
/* Try the cache. */
+ /* TNY TODO: Partial message retrieval exception */
stream = camel_imap_folder_fetch_data (imap_folder, uid, part_spec,
- TRUE, NULL);
+ TRUE, TRUE, NULL);
if (stream) {
imap_wrapper_hydrate (imap_wrapper, stream);
camel_object_unref (stream);
Index: libtinymailui-gtk/tny-gtk-msg-view.c
===================================================================
--- libtinymailui-gtk/tny-gtk-msg-view.c (revision 1363)
+++ libtinymailui-gtk/tny-gtk-msg-view.c (working copy)
@@ -502,8 +502,12 @@
gboolean displayed = tny_gtk_msg_view_display_part (self, part, desc);
g_object_unref (G_OBJECT (part));
- if (alternatives && displayed)
- break;
+
+ /* TNY TODO: partial message retrieval: temporarily disabled
+ alternatives detection */
+
+ /* if (alternatives && displayed)
+ break; */
tny_iterator_next (iterator);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]