summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@gnome.org>2010-10-30 10:49:47 -0400
committerJeffrey Stedfast <fejj@gnome.org>2010-10-30 10:49:47 -0400
commit33d36d93b0d232701d1094d6c073a563fc458d6e (patch)
tree7d21d4765261c2012d29dd6d2eacac88a8df124d
parent719cd0f325b63a28eb7e95eebe54577d249f00ea (diff)
downloadgmime-33d36d93b0d232701d1094d6c073a563fc458d6e.tar.gz
Added g_mime_message_get_body()
2010-10-30 Jeffrey Stedfast <fejj@novell.com> * gmime/gmime-message.c (g_mime_message_get_body): New function * to try and guess which part (or multipart/alternative) represents the message body.
-rw-r--r--ChangeLog6
-rw-r--r--TODO6
-rw-r--r--gmime/gmime-message.c97
-rw-r--r--gmime/gmime-message.h2
4 files changed, 109 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 28bf20b9..576bfeac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-30 Jeffrey Stedfast <fejj@novell.com>
+
+ * gmime/gmime-message.c (g_mime_message_guess_body): New function
+ to try and guess which part (or multipart/alternative) represents
+ the message body.
+
2010-09-25 Jeffrey Stedfast <fejj@novell.com>
* gmime/charset-map.c: According to rfc1557, it is suggested that
diff --git a/TODO b/TODO
index 4f8cd374..a3a4e39a 100644
--- a/TODO
+++ b/TODO
@@ -26,7 +26,7 @@ GMime 2.6 Planning:
- Consider GCancellable and GError for GMimeStreams and
GMimeParser... GError being far more important than
GCancellable. GCancellable could be nice to have for network
- streams, though...
+ streams, though... [ POSTPONED ]
- Add a GIO-backed GMimeStream and bump glib dep to 2.16 [ DONE ]
@@ -36,7 +36,7 @@ GMime 2.6 Planning:
This might be a better name for the enum to reflect what it's
actually meant for. Maybe also move it from gmime-filter-best.h to
- gmime-encodings.h? [ DONE ]
+ gmime-encodings.h?
- How about a g_mime_part_get_best_charset()? This one could be
awkward since it depends on the content being text and also encoded
@@ -46,6 +46,8 @@ GMime 2.6 Planning:
or else make sure that GMime.metadata 'fixes' the method name to be
GetEncoding so that it will appear as a C# property getter.
+- Re-add a g_mime_message_get_body()?
+
Other:
======
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 638b93e5..00518730 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -29,6 +29,8 @@
#include "gmime-message.h"
#include "gmime-multipart.h"
+#include "gmime-multipart-signed.h"
+#include "gmime-multipart-encrypted.h"
#include "gmime-part.h"
#include "gmime-utils.h"
#include "gmime-stream-mem.h"
@@ -1502,3 +1504,98 @@ g_mime_message_foreach (GMimeMessage *message, GMimeObjectForeachFunc callback,
if (GMIME_IS_MULTIPART (message->mime_part))
g_mime_multipart_foreach ((GMimeMultipart *) message->mime_part, callback, user_data);
}
+
+static gboolean
+part_is_textual (GMimeObject *mime_part)
+{
+ GMimeContentType *type;
+
+ type = g_mime_object_get_content_type (mime_part);
+
+ return g_mime_content_type_is_type (type, "text", "*");
+}
+
+static GMimeObject *
+multipart_guess_body (GMimeMultipart *multipart)
+{
+ GMimeContentType *type;
+ GMimeObject *mime_part;
+ int count, i;
+
+ if (GMIME_IS_MULTIPART_ENCRYPTED (multipart)) {
+ /* check if this part has already been decrypted... */
+ if (!(mime_part = ((GMimeMultipartEncrypted *) multipart)->decrypted)) {
+ /* nothing more we can do */
+ return (GMimeObject *) multipart;
+ }
+
+ if (GMIME_IS_MULTIPART (mime_part))
+ return multipart_guess_body ((GMimeMultipart *) mime_part);
+ else if (GMIME_IS_PART (mime_part) && part_is_textual (mime_part))
+ return mime_part;
+ else
+ return NULL;
+ }
+
+ type = g_mime_object_get_content_type ((GMimeObject *) multipart);
+ if (g_mime_content_type_is_type (type, "multipart", "alternative")) {
+ /* very likely that this is the body - leave it up to
+ * our caller to decide which format of the body it
+ * wants to use. */
+ return (GMimeObject *) multipart;
+ }
+
+ count = g_mime_multipart_get_count (multipart);
+
+ if (!GMIME_IS_MULTIPART_SIGNED (mime_part)) {
+ /* if the body is in here, it has to be the first part */
+ count = 1;
+ }
+
+ for (i = 0; i < count; i++) {
+ mime_part = g_mime_multipart_get_part (multipart, i);
+
+ if (GMIME_IS_MULTIPART (mime_part)) {
+ if ((mime_part = multipart_guess_body ((GMimeMultipart *) mime_part)))
+ return mime_part;
+ } else if (GMIME_IS_PART (mime_part)) {
+ if (part_is_textual (mime_part))
+ return mime_part;
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ * g_mime_message_get_body:
+ * @message: MIME Message
+ *
+ * Attempts to identify the MIME part containing the body of the
+ * message.
+ *
+ * Returns: a #GMimeObject containing the textual content that appears
+ * to be the main body of the message.
+ *
+ * Note: This function is NOT guarenteed to always work as it
+ * makes some assumptions that are not necessarily true. It is
+ * recommended that you traverse the MIME structure yourself.
+ **/
+GMimeObject *
+g_mime_message_guess_body (GMimeMessage *message)
+{
+ GMimeObject *mime_part;
+
+ g_return_val_if_fail (GMIME_IS_MESSAGE (message), NULL);
+
+ if (!(mime_part = message->mime_part))
+ return NULL;
+
+ if (GMIME_IS_MULTIPART (mime_part))
+ return multipart_guess_body ((GMimeMultipart *) mime_part);
+ else if (GMIME_IS_PART (mime_part) && part_is_textual (mime_part))
+ return mime_part;
+
+ return NULL;
+}
diff --git a/gmime/gmime-message.h b/gmime/gmime-message.h
index e2bad724..46682096 100644
--- a/gmime/gmime-message.h
+++ b/gmime/gmime-message.h
@@ -126,6 +126,8 @@ void g_mime_message_set_mime_part (GMimeMessage *message, GMimeObject *mime_part
void g_mime_message_foreach (GMimeMessage *message, GMimeObjectForeachFunc callback,
gpointer user_data);
+GMimeObject *g_mime_message_get_body (GMimeMessage *message);
+
G_END_DECLS
#endif /* __GMIME_MESSAGE_H__ */