Permalink
Browse files

Documentation for Body and Header parts of the mail, and updated to

provide an 'end' hook for attachments
  • Loading branch information...
1 parent 8b2195e commit 44909ffeabc8dd05107087df7989ff745e8dfbbb @baudehlo committed Apr 29, 2011
Showing with 122 additions and 15 deletions.
  1. +22 −0 docs/Body.md
  2. +41 −0 docs/Header.md
  3. +35 −9 docs/Transaction.md
  4. +6 −5 mailbody.js
  5. +3 −1 transaction.js
  6. +15 −0 utils.js
View
@@ -0,0 +1,22 @@
+Body Object
+===========
+
+The Body object gives you access to the textual body parts of an email.
+
+API
+---
+
+* body.bodytext
+
+A String containing the body text. Note that HTML parts will have tags in-tact.
+
+* body.header
+
+The header of this MIME part. See the `Header Object` for details of the API.
+
+* body.children
+
+Any child MIME parts. For example a multipart/alternative mail will have a
+main body part with just the MIME preamble in (which is usually either empty,
+or reads something like "This is a multipart MIME message"), and two
+children, one text/plain and one text/html.
View
@@ -0,0 +1,41 @@
+Header Object
+=============
+
+The Header object gives programmatic access to email headers. It is primarily
+used from `transaction.header` but also each MIME part of the `Body` will
+also have its own header object.
+
+API
+---
+
+* header.get(key)
+
+Returns the header with the name `key`. If there are multiple headers with
+the given name (as is usually the case with "Received" for example) they will
+be concatenated together with "\n".
+
+* header.get_all(key)
+
+Returns the headers with the name `key` as an array. Multi-valued headers
+will have multiple entries in the array.
+
+* header.get_decoded(key)
+
+Works like `get(key)`, only it gives you headers decoded from any MIME encoding
+they may have used.
+
+* header.remove(key)
+
+Removes all headers with the given name.
+
+* header.add(key, value)
+
+Adds a header with the given name and value.
+
+* header.lines()
+
+Returns the entire header as a list of lines.
+
+* header.toString()
+
+Returns the entire header as a string.
View
@@ -8,29 +8,55 @@ API
* transaction.mail\_from
-The value of the MAIL FROM command
+The value of the MAIL FROM command as an `Address` object.
* transaction.rcpt\_to
-An Array of values of recipients from the RCPT TO command
+An Array of `Address` objects of recipients from the RCPT TO command.
* transaction.data\_lines
-An Array of the lines of the email after DATA
+An Array of the lines of the email after DATA.
* transaction.data\_bytes
-The number of bytes in the email after DATA
-
-* transaction.add_header(key, value)
-
-Adds a header to the email
+The number of bytes in the email after DATA.
* transaction.add_data(line)
-Adds a line of data to the email
+Adds a line of data to the email. Note this is RAW email - it isn't useful
+for adding banners to the email.
* transaction.notes
A safe place to store transaction specific values.
+* transaction.add_header(key, value)
+
+Adds a header to the email.
+
+* transaction.header
+
+The header of the email. See `Header Object`.
+
+* transaction.parse_body
+
+Set to 1 to enable parsing of the mail body. Make sure you set this in
+hook_data or before.
+
+* transaction.body
+
+The body of the email if you set `parse_body` above. See `Body Object`.
+
+* transaction.attachment_hooks(start, data, end)
+
+Sets event emitter hooks for attachments if you set `parse_body` above.
+
+The `start` event will receive `(content_type, filename)` as parameters.
+
+The `data` event will receive a `Buffer` object containing some of the
+attachment data.
+
+The `end` event will be called with no parameters when an attachment ends.
+
+Both the `data` and `end` params are optional.
View
@@ -25,12 +25,14 @@ Body.prototype.parse_child = function (line) {
if (line.substr(0, (this.boundary.length + 2)) === ('--' + this.boundary)) {
if (line.substr(this.boundary.length + 2, 2) === '--') {
// end
+ this.emit('attachment_end');
return;
}
else {
var bod = new Body(new Header(), this.options);
this.listeners('attachment_start').forEach(function (cb) { bod.on('attachment_start', cb) });
- this.listeners('attachment_data').forEach( function (cb) { bod.on('attachment_data', cb) });
+ this.listeners('attachment_data' ).forEach(function (cb) { bod.on('attachment_data', cb) });
+ this.listeners('attachment_end' ).forEach(function (cb) { bod.on('attachment_end', cb) });
this.children.push(bod);
bod.state = 'headers';
return;
@@ -114,9 +116,6 @@ Body.prototype.parse_multipart_preamble = function (line) {
this.bodytext += this.decode_function(line);
}
-Body.prototype.parse_multipart = function (line) {
-}
-
Body.prototype.parse_attachment = function (line) {
if (this.boundary) {
if (line.substr(0, (this.boundary.length + 2)) === ('--' + this.boundary)) {
@@ -157,7 +156,9 @@ Body.prototype.decode_qp = function (line) {
return String.fromCharCode(parseInt(code, 16));
});
// TODO - figure out encoding and apply it
- return line;
+ var encoding = 'utf8';
+
+ return new Buffer(line, encoding);
}
Body.prototype.decode_bin_base64 = function (line) {
View
@@ -55,10 +55,12 @@ Transaction.prototype.add_header = function(key, value) {
this.data_lines = this.header.lines().concat(this.data_lines.slice(this.header_pos));
};
-Transaction.prototype.attachment_hooks = function (start, data) {
+Transaction.prototype.attachment_hooks = function (start, data, end) {
this.parse_body = 1;
this.body = this.body || new body.Body(this.header);
this.body.on('attachment_start', start);
if (data)
this.body.on('attachment_data', data);
+ if (end)
+ this.body.on('attachment_end', end);
};
View
@@ -35,6 +35,21 @@ exports.sort_keys = function (obj) {
return Object.keys(obj).sort();
};
+exports.uniq = function (arr) {
+ var out = [];
+ var o = 0;
+ for (var i=0,l=arr.length; i < l; i++) {
+ if (out.length === 0) {
+ out.push(arr[i]);
+ }
+ else if (out[o] != arr[i]) {
+ out.push(arr[i]);
+ o++;
+ }
+ }
+ return out;
+}
+
exports.ISODate = function (d) {
function pad(n) {return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'

0 comments on commit 44909ff

Please sign in to comment.