* lib: cleanup mu_msg_get_body_(html|text) (WIP)

This commit is contained in:
djcb 2012-08-09 09:38:22 +03:00
parent c3391b3929
commit 86bf7b7165
6 changed files with 141 additions and 83 deletions

View File

@ -659,21 +659,35 @@ get_references (MuMsgFile *self)
return g_slist_reverse (msgids);
}
/* see: http://does-not-exist.org/mail-archives/mutt-dev/msg08249.html */
static GSList*
get_tags (MuMsgFile *self)
{
GSList *lst;
GSList *lst1, *lst2, *last;
char *hdr;
/* X-Label are space-separated */
hdr = mu_msg_file_get_header (self, "X-Label");
if (!hdr)
return NULL;
if (hdr) {
lst1 = mu_str_to_list (hdr, ' ', TRUE);
g_free (hdr);
}
lst = mu_str_to_list (hdr, ',', TRUE);
g_free (hdr);
/* X-Keywords are ','-separated */
hdr = mu_msg_file_get_header (self, "X-Keywords");
if (hdr) {
lst2 = mu_str_to_list (hdr, ',', TRUE);
g_free (hdr);
}
return lst;
if (!lst1)
return lst2;
/* append lst2, if any */
last = g_slist_last (lst1);
last->next = lst2;
return last;
}
@ -722,18 +736,15 @@ mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
switch (mfid) {
case MU_MSG_FIELD_ID_EMBEDDED_TEXT: *do_free = TRUE;
return NULL; /* FIXME */
case MU_MSG_FIELD_ID_BCC:
case MU_MSG_FIELD_ID_CC:
case MU_MSG_FIELD_ID_TO: *do_free = TRUE;
return get_recipient (self, recipient_type(mfid));
case MU_MSG_FIELD_ID_BODY_TEXT: *do_free = TRUE;
return get_concatenated_text (self, TRUE); /* FIXME: decrypt ? */
case MU_MSG_FIELD_ID_BODY_HTML: *do_free = TRUE;
return get_body (self, TRUE, TRUE); /* FIXME: decrypt ? */
/* case MU_MSG_FIELD_ID_BODY_TEXT: *do_free = TRUE; */
/* return get_concatenated_text (self, TRUE); /\* FIXME: decrypt ? *\/ */
/* case MU_MSG_FIELD_ID_BODY_HTML: *do_free = TRUE; */
/* return get_body (self, TRUE, TRUE); /\* FIXME: decrypt ? *\/ */
case MU_MSG_FIELD_ID_FROM:
return (char*)maybe_cleanup
@ -752,6 +763,14 @@ mu_msg_file_get_str_field (MuMsgFile *self, MuMsgFieldId mfid,
case MU_MSG_FIELD_ID_MAILDIR: return self->_maildir;
case MU_MSG_FIELD_ID_BODY_TEXT:
case MU_MSG_FIELD_ID_BODY_HTML:
case MU_MSG_FIELD_ID_EMBEDDED_TEXT:
g_warning ("not available here: %s",
mu_msg_field_name (mfid));
g_return_val_if_reached (NULL);
return NULL;
default: g_return_val_if_reached (NULL);
}
}

View File

@ -34,8 +34,9 @@
#include "mu-msg-crypto.h"
#endif /*BUILD_CRYPTO*/
static gboolean handle_children (MuMsg *msg, GMimeObject *mobj, MuMsgOptions opts,
unsigned index, MuMsgPartForeachFunc func,
static gboolean handle_children (MuMsg *msg, GMimeObject *mobj,
MuMsgOptions opts, unsigned index,
MuMsgPartForeachFunc func,
gpointer user_data);
struct _DoData {
@ -386,26 +387,6 @@ handle_encrypted_part (MuMsg *msg,
return TRUE;
}
/* check if the current part might be a body part, and, if so, update
* the msgpart struct */
static void
check_if_body_part (MuMsg *msg, GMimeObject *mobj, MuMsgPart *msgpart)
{
/* is it an attachment? if so, this one is not the body */
if (msgpart->part_type & MU_MSG_PART_TYPE_ATTACHMENT)
return;
/* is it a text part? */
if (g_ascii_strcasecmp (msgpart->type, "text") != 0)
return;
/* we consider it a body part if it's an inline text/plain or
* text/html */
if ((g_ascii_strcasecmp (msgpart->subtype, "plain") == 0) ||
(g_ascii_strcasecmp (msgpart->subtype, "html") == 0))
msgpart->part_type |= MU_MSG_PART_TYPE_BODY;
}
/* call 'func' with information about this MIME-part */
static gboolean
@ -418,17 +399,21 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
memset (&msgpart, 0, sizeof(MuMsgPart));
ct = g_mime_object_get_content_type ((GMimeObject*)part);
if (GMIME_IS_CONTENT_TYPE(ct)) {
msgpart.type = g_mime_content_type_get_media_type (ct);
msgpart.subtype = g_mime_content_type_get_media_subtype (ct);
}
msgpart.size = get_part_size (part);
msgpart.part_type = MU_MSG_PART_TYPE_LEAF;
msgpart.part_type |= get_disposition ((GMimeObject*)part);
check_if_body_part (msg, (GMimeObject*)part, &msgpart);
ct = g_mime_object_get_content_type ((GMimeObject*)part);
if (GMIME_IS_CONTENT_TYPE(ct)) {
msgpart.type = g_mime_content_type_get_media_type (ct);
msgpart.subtype = g_mime_content_type_get_media_subtype (ct);
/* store as in the part_type as well, for quick
* checking */
if (g_mime_content_type_is_type (ct, "text", "plain"))
msgpart.part_type |= MU_MSG_PART_TYPE_TEXT_PLAIN;
else if (g_mime_content_type_is_type (ct, "text", "html"))
msgpart.part_type |= MU_MSG_PART_TYPE_TEXT_HTML;
}
msgpart.data = (gpointer)part;
msgpart.index = index;
@ -703,8 +688,8 @@ mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partid,
partid);
if (!mu_util_create_dir_maybe (dirname, 0700, FALSE)) {
mu_util_g_set_error (err, MU_ERROR_FILE, "failed to create dir %s",
dirname);
mu_util_g_set_error (err, MU_ERROR_FILE,
"failed to create dir %s", dirname);
g_free (dirname);
return NULL;
}
@ -840,8 +825,6 @@ mu_msg_part_looks_like_attachment (MuMsgPart *part, gboolean include_inline)
{
g_return_val_if_fail (part, FALSE);
if (part->part_type & MU_MSG_PART_TYPE_BODY)
return FALSE;
if (!include_inline && (part->part_type & MU_MSG_PART_TYPE_INLINE))
return FALSE;

View File

@ -30,8 +30,6 @@ G_BEGIN_DECLS
enum _MuMsgPartType {
MU_MSG_PART_TYPE_NONE = 0,
/* look like the message body (heuristic) ? */
MU_MSG_PART_TYPE_BODY = 1 << 0,
/* MIME part without children */
MU_MSG_PART_TYPE_LEAF = 1 << 1,
/* an RFC822 message part? */
@ -45,7 +43,11 @@ enum _MuMsgPartType {
/* an encrypted part? */
MU_MSG_PART_TYPE_ENCRYPTED = 1 << 6,
/* a decrypted part? */
MU_MSG_PART_TYPE_DECRYPTED = 1 << 7
MU_MSG_PART_TYPE_DECRYPTED = 1 << 7,
/* a text/plain part? */
MU_MSG_PART_TYPE_TEXT_PLAIN = 1 << 8,
/* a text/html part? */
MU_MSG_PART_TYPE_TEXT_HTML = 1 << 9
};
typedef enum _MuMsgPartType MuMsgPartType;

View File

@ -279,7 +279,6 @@ get_part_type_string (MuMsgPartType ptype)
GString *gstr;
unsigned u;
MuMsgPartType ptypes[] = {
MU_MSG_PART_TYPE_BODY,
MU_MSG_PART_TYPE_LEAF,
MU_MSG_PART_TYPE_MESSAGE,
MU_MSG_PART_TYPE_INLINE,
@ -294,7 +293,6 @@ get_part_type_string (MuMsgPartType ptype)
const char* name;
switch (ptype & ptypes[u]) {
case MU_MSG_PART_TYPE_NONE : continue;
case MU_MSG_PART_TYPE_BODY :name = "body"; break;
case MU_MSG_PART_TYPE_LEAF :name = "leaf"; break;
case MU_MSG_PART_TYPE_MESSAGE :name = "message"; break;
case MU_MSG_PART_TYPE_INLINE :name = "inline"; break;
@ -400,9 +398,9 @@ append_message_file_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
append_sexp_attr (gstr, "in-reply-to",
mu_msg_get_header (msg, "In-Reply-To"));
append_sexp_attr (gstr, "body-txt",
mu_msg_get_body_text(msg));
mu_msg_get_body_text(msg, opts));
append_sexp_attr (gstr, "body-html",
mu_msg_get_body_html(msg));
mu_msg_get_body_html(msg, opts));
}

View File

@ -335,23 +335,19 @@ mu_msg_get_header (MuMsg *self, const char *header)
time_t
mu_msg_get_timestamp (MuMsg *self)
{
const char *path;
struct stat statbuf;
g_return_val_if_fail (self, 0);
if (self->_file)
return self->_file->_timestamp;
else {
const char *path;
struct stat statbuf;
path = mu_msg_get_path (self);
if (!path)
return 0;
path = mu_msg_get_path (self);
if (!path || stat (path, &statbuf) < 0)
return 0;
if (stat (path, &statbuf) < 0)
return 0;
return statbuf.st_mtime;
}
return statbuf.st_mtime;
}
@ -424,7 +420,6 @@ mu_msg_get_date (MuMsg *self)
}
MuFlags
mu_msg_get_flags (MuMsg *self)
{
@ -448,19 +443,70 @@ mu_msg_get_prio (MuMsg *self)
}
const char*
mu_msg_get_body_html (MuMsg *self)
struct _BodyData {
GString *gstr;
gboolean want_html;
};
typedef struct _BodyData BodyData;
static void
accumulate_body (MuMsg *msg, MuMsgPart *mpart, BodyData *bdata)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_BODY_HTML);
char *txt;
gboolean err;
/* if it looks like an attachment, skip it */
if (mpart->part_type & MU_MSG_PART_TYPE_ATTACHMENT)
return;
txt = NULL;
if (!bdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_PLAIN))
txt = mu_msg_mime_part_to_string (
(GMimePart*)mpart->data, &err);
else if (bdata->want_html &&
(mpart->part_type & MU_MSG_PART_TYPE_TEXT_HTML))
txt = mu_msg_mime_part_to_string (
(GMimePart*)mpart->data, &err);
if (!err && txt)
bdata->gstr = g_string_append (bdata->gstr, txt);
g_free (txt);
}
static char*
get_body (MuMsg *self, MuMsgOptions opts, gboolean want_html)
{
BodyData bdata;
bdata.want_html = want_html;
bdata.gstr = g_string_sized_new (4096);
mu_msg_part_foreach (self, opts,
(MuMsgPartForeachFunc)accumulate_body,
&bdata);
return g_string_free (bdata.gstr, FALSE);
}
const char*
mu_msg_get_body_text (MuMsg *self)
mu_msg_get_body_html (MuMsg *self, MuMsgOptions opts)
{
g_return_val_if_fail (self, NULL);
return get_str_field (self, MU_MSG_FIELD_ID_BODY_TEXT);
return free_later_str (self, get_body (self, opts, TRUE));
}
const char*
mu_msg_get_body_text (MuMsg *self, MuMsgOptions opts)
{
g_return_val_if_fail (self, NULL);
return free_later_str (self, get_body (self, opts, FALSE));
}
@ -750,8 +796,7 @@ mu_msg_is_readable (MuMsg *self)
{
g_return_val_if_fail (self, FALSE);
return (access (get_str_field (self, MU_MSG_FIELD_ID_PATH), R_OK)
== 0) ? TRUE : FALSE;
return access (mu_msg_get_path (self), R_OK) == 0 ? TRUE : FALSE;
}
@ -771,16 +816,19 @@ get_target_mdir (MuMsg *msg, const char *target_maildir, GError **err)
/* maildir is the maildir stored in the message, e.g. '/foo' */
maildir = mu_msg_get_maildir(msg);
if (!maildir) {
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_GMIME,
"message without maildir");
mu_util_g_set_error (err, MU_ERROR_GMIME,
"message without maildir");
return NULL;
}
/* the 'rootmaildir' is the filesystem path from root to
* maildir, ie. /home/user/Maildir/foo */
rootmaildir = mu_maildir_get_maildir_from_path (mu_msg_get_path(msg));
if (!rootmaildir)
if (!rootmaildir) {
mu_util_g_set_error (err, MU_ERROR_GMIME,
"cannot determinex maildir");
return NULL;
}
/* we do a sanity check: verify that that maildir is a suffix of
* rootmaildir;*/
@ -825,6 +873,8 @@ mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
g_return_val_if_fail (self, FALSE);
g_return_val_if_fail (maildir, FALSE); /* i.e. "/inbox" */
/* targetmdir is the full path to maildir, i.e.,
* /home/foo/Maildir/inbox */
targetmdir = get_target_mdir (self, maildir, err);
if (!targetmdir)
return FALSE;
@ -832,18 +882,22 @@ mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
newfullpath = mu_maildir_move_message (mu_msg_get_path (self),
targetmdir, flags,
ignore_dups, err);
g_free (targetmdir);
/* update the message path and the flags; they may have
* changed */
if (!newfullpath)
if (!newfullpath) {
g_free (targetmdir);
return FALSE;
}
/* clear the old backends */
mu_msg_doc_destroy (self->_doc);
self->_doc = NULL;
mu_msg_file_destroy (self->_file);
/* and create a new one */
self->_file = mu_msg_file_new (newfullpath, targetmdir, err);
self->_file = mu_msg_file_new (newfullpath, maildir, err);
g_free (targetmdir);
return self->_file ? TRUE : FALSE;
}

View File

@ -157,23 +157,25 @@ void mu_msg_cache_values (MuMsg *self);
* get the plain text body of this message
*
* @param msg a valid MuMsg* instance
* @param opts options for getting the body
*
* @return the plain text body or NULL in case of error or if there is no
* such body. the returned string should *not* be modified or freed.
* The returned data is in UTF8 or NULL.
*/
const char* mu_msg_get_body_text (MuMsg *msg);
const char* mu_msg_get_body_text (MuMsg *msg, MuMsgOptions opts);
/**
* get the html body of this message
*
* @param msg a valid MuMsg* instance
* @param opts options for getting the body
*
* @return the html body or NULL in case of error or if there is no
* such body. the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_body_html (MuMsg *msg);
const char* mu_msg_get_body_html (MuMsg *msgMu, MuMsgOptions opts);
/**
* get the sender (From:) of this message