[gmime] Updated README.md
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] Updated README.md
- Date: Wed, 8 Mar 2017 13:36:12 +0000 (UTC)
commit a6491165d7d248e3905867deeb991818df420e1f
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Fri Mar 3 16:22:20 2017 -0500
Updated README.md
README.md | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 202 insertions(+), 4 deletions(-)
---
diff --git a/README.md b/README.md
index 9afc8ee..a886bf7 100644
--- a/README.md
+++ b/README.md
@@ -65,6 +65,208 @@ are REQUIRED:
distributions. Glib sources may be obtained from:
ftp://ftp.gtk.org/pub/glib
+## Using GMime
+
+### Parsing Messages
+
+One of the more common operations that GMime is meant for is parsing email messages from arbitrary streams.
+To do this, you will need to use a `GMimeParser`:
+
+```c
+/* load a GMimeMessage from a stream */
+GMimeMessage *message;
+GMimeStream *stream;
+GMimeParser *parser;
+
+stream = g_mime_stream_file_new (fopen ("message.eml", "r"));
+parser = g_mime_parser_new_with_stream (stream);
+
+/* Note: we can unref the stream now since the GMimeParser has a reference to it... */
+g_object_unref (stream);
+
+message = g_mime_parser_construct_message (parser);
+
+/* unref the parser since we no longer need it */
+g_object_unref (parser);
+```
+
+If you are planning to parse messages from an mbox stream, you can do something like this:
+
+```c
+GMimeMessage *message;
+GMimeStream *stream;
+GMimeParser *parser;
+gint64 offset;
+char *marker;
+
+stream = g_mime_stream_file_new (fopen ("Inbox.mbox", "r"));
+parser = g_mime_parser_new_with_stream (stream);
+
+/* tell the parser to scan mbox-style "From " markers */
+g_mime_parser_set_scan_from (parser, TRUE);
+
+/* Note: we can unref the stream now since the GMimeParser has a reference to it... */
+g_object_unref (stream);
+
+while (!g_mime_parser_eos (parser)) {
+ /* load the next message from the mbox */
+ if ((message = g_mime_parser_construct_message (parser)) != NULL)
+ g_object_unref (message);
+
+ /* get information about the mbox "From " marker... */
+ offset = g_mime_parser_get_from_offset (parser);
+ marker = g_mime_parser_get_from (parser);
+}
+```
+
+### Getting the Body of a Message
+
+A common misunderstanding about email is that there is a well-defined message body and then a list
+of attachments. This is not really the case. The reality is that MIME is a tree structure of content,
+much like a file system.
+
+Luckily, MIME does define a set of general rules for how mail clients should interpret this tree
+structure of MIME parts. The `Content-Disposition` header is meant to provide hints to the receiving
+client as to which parts are meant to be displayed as part of the message body and which are meant
+to be interpreted as attachments.
+
+The `Content-Disposition` header will generally have one of two values: `inline` or `attachment`.
+
+The meaning of these value should be fairly obvious. If the value is `attachment`, then the content
+of said MIME part is meant to be presented as a file attachment separate from the core message.
+However, if the value is `inline`, then the content of that MIME part is meant to be displayed inline
+within the mail client's rendering of the core message body. If the `Content-Disposition` header does
+not exist, then it should be treated as if the value were `inline`.
+
+Technically, every part that lacks a `Content-Disposition` header or that is marked as `inline`, then,
+is part of the core message body.
+
+There's a bit more to it than that, though.
+
+Modern MIME messages will often contain a `multipart/alternative` MIME container which will generally contain
+a `text/plain` and `text/html` version of the text that the sender wrote. The `text/html` version is
typically
+formatted much closer to what the sender saw in his or her WYSIWYG editor than the `text/plain` version.
+
+The reason for sending the message text in both formats is that not all mail clients are capable of
displaying
+HTML.
+
+The receiving client should only display one of the alternative views contained within the
`multipart/alternative`
+container. Since alternative views are listed in order of least faithful to most faithful with what the
sender
+saw in his or her WYSIWYG editor, the receiving client *should* walk over the list of alternative views
starting
+at the end and working backwards until it finds a part that it is capable of displaying.
+
+Example:
+```
+multipart/alternative
+ text/plain
+ text/html
+```
+
+As seen in the example above, the `text/html` part is listed last because it is the most faithful to
+what the sender saw in his or her WYSIWYG editor when writing the message.
+
+To make matters even more complicated, sometimes modern mail clients will use a `multipart/related`
+MIME container instead of a simple `text/html` part in order to embed images and other content
+within the HTML.
+
+Example:
+```
+multipart/alternative
+ text/plain
+ multipart/related
+ text/html
+ image/jpeg
+ video/mp4
+ image/png
+```
+
+In the example above, one of the alternative views is a `multipart/related` container which contains
+an HTML version of the message body that references the sibling video and images.
+
+Now that you have a rough idea of how a message is structured and how to interpret various MIME entities,
+the next step is learning how to traverse the MIME tree using GMime.
+
+### Traversing a MimeMessage
+
+The `MimeMessage.Body` is the top-level MIME entity of the message. Generally, it will either be a
+`TextPart` or a `Multipart`.
+
+As an example, if you wanted to rip out all of the attachments of a message, your code might look
+something like this:
+
+```c
+GMimePartIter *iter = g_mime_part_iter_new (message);
+GPtrArray *attachments = g_ptr_array_new ();
+GPtrArray *multiparts = g_ptr_array_new ();
+
+/* collect our list of attachments and their parent multiparts */
+while (g_mime_part_iter_next (iter)) {
+ GMimeObject *current = g_mime_part_iter_get_current (iter);
+ GMimeObject *parent = g_mime_part_iter_get_parent (iter);
+
+ if (GMIME_IS_MULTIPART (parent) && GMIME_IS_PART (current)) {
+ GMimePart *part = (GMimePart *) current;
+
+ if (g_mime_part_is_attachment (part)) {
+ /* keep track of each attachment's parent multipart */
+ g_ptr_array_append (multiparts, parent);
+ g_ptr_array_append (attachments, part);
+ }
+ }
+}
+
+/* now remove each attachment from its parent multipart... */
+for (int i = 0; i < attachments->len; i++) {
+ GMimeMultipart *multipart = (GMimeMultipart *) multiparts->pdata[i];
+ GMimeObject *attachment = (GMimeObject *) attachments->pdata[i];
+
+ g_mime_multipart_remove (multipart, attachment);
+}
+```
+
+### Creating a Simple Message
+
+Creating MIME messages using MimeKit is really trivial.
+
+```csharp
+GMimeMessage *message = g_mime_message_new (TRUE);
+InternetAddressMailbox *mailbox;
+InternetAddressList *list;
+GMimeDataWrapper *content;
+GMimeStream *stream;
+GMimePart *body;
+
+list = g_mime_message_get_from (message);
+mailbox = internet_address_mailbox_new ("Joey", "joey friends com");
+internet_address_list_add (list, mailbox);
+g_object_unref (mailbox);
+
+list = g_mime_message_get_to (message);
+mailbox = internet_address_mailbox_new ("Alice", "alice wonderland com");
+internet_address_list_add (list, mailbox);
+g_object_unref (mailbox);
+
+g_mime_message_set_subject (message, "How you doin?", NULL);
+
+body = g_mime_part_new_with_type ("text", "plain");
+
+stream = g_mime_stream_mem_new ();
+g_mime_stream_printf (stream, "Hey Alice,\n\n");
+g_mime_stream_printf (stream, "What are you up to this weekend? Monica is throwing one of her parties on\n");
+g_mime_stream_printf (stream, "Saturday and I was hoping you could make it.\n\n);
+g_mime_stream_printf (stream, "Will you be my +1?\n\n");
+g_mime_stream_printf (stream, "-- Joey\n");
+g_mime_stream_reset (stream);
+
+content = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_DEFAULT);
+g_object_unref (stream);
+
+g_mime_part_set_content_object (body, content);
+g_object_unref (content);
+
+g_mime_message_set_mime_part (message, body);
+g_object_unref (body);
+```
## Documentation
@@ -82,12 +284,8 @@ of GMime.
COPYING The GNU Lesser General Public License, version 2
- ChangeLog Log of changes made to the source code
-
INSTALL In-depth installation instructions
- NEWS Release notes (Overview of changes)
-
TODO Description of planned GMime development
PORTING Guide for developers porting their application
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]