tmail 1.2.3.1 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README +10 -0
- data/ext/tmailscanner/tmail/tmailscanner.c +39 -8
- data/lib/tmail.rb +1 -0
- data/lib/tmail/address.rb +6 -40
- data/lib/tmail/attachments.rb +41 -22
- data/lib/tmail/encode.rb +9 -0
- data/lib/tmail/header.rb +5 -3
- data/lib/tmail/interface.rb +40 -3
- data/lib/tmail/mail.rb +3 -3
- data/lib/tmail/mailbox.rb +3 -2
- data/lib/tmail/net.rb +3 -1
- data/lib/tmail/parser.rb +204 -620
- data/lib/tmail/parser.y +38 -3
- data/lib/tmail/quoting.rb +38 -1
- data/lib/tmail/utils.rb +28 -4
- data/lib/tmail/vendor/rchardet-1.3/COPYING +504 -0
- data/lib/tmail/vendor/rchardet-1.3/README +12 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet.rb +67 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/big5freq.rb +927 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/big5prober.rb +42 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/chardistribution.rb +237 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/charsetgroupprober.rb +112 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/charsetprober.rb +75 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/codingstatemachine.rb +64 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/constants.rb +42 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/escprober.rb +90 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/escsm.rb +244 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/eucjpprober.rb +88 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euckrfreq.rb +596 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euckrprober.rb +42 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euctwfreq.rb +430 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euctwprober.rb +42 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/gb2312freq.rb +474 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/gb2312prober.rb +42 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/hebrewprober.rb +289 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/jisfreq.rb +570 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/jpcntx.rb +229 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langbulgarianmodel.rb +229 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langcyrillicmodel.rb +330 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langgreekmodel.rb +227 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langhebrewmodel.rb +202 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langhungarianmodel.rb +226 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langthaimodel.rb +201 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/latin1prober.rb +147 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/mbcharsetprober.rb +89 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/mbcsgroupprober.rb +47 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/mbcssm.rb +542 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/sbcharsetprober.rb +124 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/sbcsgroupprober.rb +58 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/sjisprober.rb +88 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb +166 -0
- data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/utf8prober.rb +87 -0
- data/lib/tmail/version.rb +1 -1
- data/setup.rb +2 -2
- data/test/fixtures/apple_unquoted_content_type +44 -0
- data/test/fixtures/inline_attachment.txt +2095 -0
- data/test/fixtures/iso_8859_1_email_without_encoding_and_message_id.txt +16 -0
- data/test/fixtures/mailbox.zip +0 -0
- data/test/fixtures/marked_as_iso_8859_1_but_it_is_utf_8.txt +33 -0
- data/test/fixtures/marked_as_utf_8_but_it_is_iso_8859_1.txt +56 -0
- data/test/fixtures/raw_email_bad_time +62 -0
- data/test/fixtures/raw_email_double_at_in_header +14 -0
- data/test/fixtures/raw_email_only_attachment +17 -0
- data/test/fixtures/raw_email_string_in_date_field +17 -0
- data/test/fixtures/raw_email_trailing_dot +21 -0
- data/test/fixtures/raw_email_with_quoted_attachment_filename +60 -0
- data/test/fixtures/raw_email_with_wrong_splitted_multibyte_encoded_word_subject +15 -0
- data/test/fixtures/the_only_part_is_a_word_document.txt +425 -0
- data/test/fixtures/unquoted_filename_in_attachment +177 -0
- data/test/test_address.rb +114 -92
- data/test/test_attachments.rb +84 -1
- data/test/test_encode.rb +54 -0
- data/test/test_header.rb +60 -2
- data/test/test_mail.rb +22 -15
- data/test/test_mbox.rb +12 -3
- data/test/test_port.rb +13 -9
- data/test/test_quote.rb +9 -0
- data/tmail.gemspec +34 -0
- metadata +68 -167
- data/MANIFEST +0 -191
- data/log/BugTrackingLog.txt +0 -1231
- data/log/Changelog.txt +0 -534
- data/log/Fixme.txt +0 -6
- data/log/Testlog.txt +0 -2340
- data/log/Todo.txt +0 -30
- data/log/fixme.rdoc +0 -6
- data/meta/MANIFEST +0 -128
- data/meta/VERSION +0 -1
- data/meta/project.yaml +0 -30
- data/meta/unixname +0 -1
- data/sample/bench_base64.rb +0 -48
- data/sample/data/multipart +0 -23
- data/sample/data/normal +0 -29
- data/sample/data/sendtest +0 -5
- data/sample/data/simple +0 -14
- data/sample/data/test +0 -27
- data/sample/extract-attachements.rb +0 -33
- data/sample/from-check.rb +0 -26
- data/sample/multipart.rb +0 -26
- data/sample/parse-bench.rb +0 -68
- data/sample/parse-test.rb +0 -19
- data/sample/sendmail.rb +0 -94
- data/site/contributing/index.html +0 -183
- data/site/css/clean.css +0 -27
- data/site/css/layout.css +0 -31
- data/site/css/style.css +0 -60
- data/site/download/index.html +0 -61
- data/site/img/envelope.jpg +0 -0
- data/site/img/mailman.gif +0 -0
- data/site/img/stamp-sm.jpg +0 -0
- data/site/img/stamp.jpg +0 -0
- data/site/img/stampborder.jpg +0 -0
- data/site/img/tfire.jpg +0 -0
- data/site/img/tmail.png +0 -0
- data/site/index.html +0 -270
- data/site/js/jquery.js +0 -31
- data/site/log/Changelog.xsl +0 -33
- data/site/log/changelog.xml +0 -1677
- data/site/outdated/BUGS +0 -3
- data/site/outdated/DEPENDS +0 -1
- data/site/outdated/Incompatibilities +0 -89
- data/site/outdated/Incompatibilities.ja +0 -102
- data/site/outdated/NEWS +0 -9
- data/site/outdated/README.ja +0 -73
- data/site/outdated/doc.ja/address.html +0 -275
- data/site/outdated/doc.ja/basics.html +0 -405
- data/site/outdated/doc.ja/config.html +0 -49
- data/site/outdated/doc.ja/details.html +0 -146
- data/site/outdated/doc.ja/index.html +0 -39
- data/site/outdated/doc.ja/mail.html +0 -793
- data/site/outdated/doc.ja/mailbox.html +0 -265
- data/site/outdated/doc.ja/port.html +0 -95
- data/site/outdated/doc.ja/tmail.html +0 -58
- data/site/outdated/doc.ja/usage.html +0 -202
- data/site/outdated/rdd/address.rrd.m +0 -229
- data/site/outdated/rdd/basics.rd.m +0 -275
- data/site/outdated/rdd/config.rrd.m +0 -26
- data/site/outdated/rdd/details.rd.m +0 -117
- data/site/outdated/rdd/index.rhtml.m +0 -54
- data/site/outdated/rdd/mail.rrd.m +0 -701
- data/site/outdated/rdd/mailbox.rrd.m +0 -228
- data/site/outdated/rdd/port.rrd.m +0 -69
- data/site/outdated/rdd/tmail.rrd.m +0 -33
- data/site/outdated/rdd/usage.rd.m +0 -247
- data/site/quickstart/index.html +0 -69
- data/site/quickstart/quickstart.html +0 -52
- data/site/quickstart/usage.html +0 -193
- data/site/reference/address.html +0 -247
- data/site/reference/config.html +0 -30
- data/site/reference/index.html +0 -101
- data/site/reference/mail.html +0 -726
- data/site/reference/mailbox.html +0 -245
- data/site/reference/port.html +0 -75
- data/site/reference/tmail.html +0 -35
- data/work/script/make +0 -26
- data/work/script/rdoc +0 -39
- data/work/script/setup +0 -1616
- data/work/script/test +0 -30
data/README
CHANGED
@@ -6,6 +6,16 @@
|
|
6
6
|
Trans assitant developer
|
7
7
|
Minero Aoki original developer
|
8
8
|
|
9
|
+
== RUBY 1.9 COMPATIBILITY
|
10
|
+
|
11
|
+
Note... as of 1.2.5, TMail is not compatible with Ruby 1.9.1. We are now using rchardet
|
12
|
+
to compare encodings and there is work to do for Ruby 1.9.1 due to it's encoding
|
13
|
+
capability.
|
14
|
+
|
15
|
+
For 1.9.1 + compatibility, I suggest you look at Mail (https://github.com/mikel/mail/tree)
|
16
|
+
while this is a work in progress, it is what I am working on to replace TMail for Ruby
|
17
|
+
1.9 and beyond.
|
18
|
+
|
9
19
|
== DESCRIPTION:
|
10
20
|
|
11
21
|
TMail is a mail handling library for Ruby. It abstracts a mail message into a usable object allowing you to read, set, add and delete headers and the mail body.
|
@@ -15,9 +15,27 @@
|
|
15
15
|
# include <stdlib.h>
|
16
16
|
#endif
|
17
17
|
|
18
|
+
|
18
19
|
#include "ruby.h"
|
20
|
+
#ifndef RSTRING_PTR
|
21
|
+
#define RSTRING_PTR(obj) RSTRING(obj)->ptr
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#ifndef RSTRING_LEN
|
25
|
+
#define RSTRING_LEN(obj) RSTRING(obj)->len
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#ifdef HAVE_RUBY_VM_H
|
29
|
+
#include "ruby/re.h"
|
30
|
+
#include "ruby/encoding.h"
|
31
|
+
#else
|
19
32
|
#include "re.h"
|
33
|
+
#endif
|
20
34
|
|
35
|
+
#ifdef HAVE_RUBY_VM_H
|
36
|
+
const unsigned char *re_mbctab;
|
37
|
+
#define ismbchar(c) re_mbctab[(unsigned char)(c)]
|
38
|
+
#endif
|
21
39
|
|
22
40
|
#define TMAIL_VERSION "1.2.3"
|
23
41
|
|
@@ -72,9 +90,9 @@ mails_s_new(klass, str, ident, cmt)
|
|
72
90
|
sc = ALLOC_N(struct scanner, 1);
|
73
91
|
|
74
92
|
StringValue(str);
|
75
|
-
sc->pbeg =
|
93
|
+
sc->pbeg = RSTRING_PTR(str);
|
76
94
|
sc->p = sc->pbeg;
|
77
|
-
sc->pend = sc->p +
|
95
|
+
sc->pend = sc->p + RSTRING_LEN(str);
|
78
96
|
|
79
97
|
sc->flags = 0;
|
80
98
|
Check_Type(ident, T_SYMBOL);
|
@@ -180,6 +198,18 @@ skip_iso2022jp_string(sc)
|
|
180
198
|
}
|
181
199
|
}
|
182
200
|
|
201
|
+
#ifdef HAVE_RUBY_VM_H
|
202
|
+
static void
|
203
|
+
skip_japanese_string(sc)
|
204
|
+
struct scanner *sc;
|
205
|
+
{
|
206
|
+
while(sc->p < sc->pend) {
|
207
|
+
if (! ismbchar(*sc->p)) return;
|
208
|
+
rb_encoding *enc = rb_enc_get(sc);
|
209
|
+
sc->p += mbclen(sc->p, sc->pend, enc);
|
210
|
+
}
|
211
|
+
}
|
212
|
+
#else
|
183
213
|
static void
|
184
214
|
skip_japanese_string(sc)
|
185
215
|
struct scanner *sc;
|
@@ -189,6 +219,7 @@ skip_japanese_string(sc)
|
|
189
219
|
sc->p += mbclen(*sc->p);
|
190
220
|
}
|
191
221
|
}
|
222
|
+
#endif
|
192
223
|
|
193
224
|
|
194
225
|
#define scan_atom(sc) scan_word(sc, ATOM_SYMBOLS)
|
@@ -376,9 +407,9 @@ digit_p(str)
|
|
376
407
|
char *p;
|
377
408
|
int i;
|
378
409
|
|
379
|
-
p =
|
380
|
-
for (i = 0; i <
|
381
|
-
if (! IS_DIGIT(
|
410
|
+
p = RSTRING_PTR(str);
|
411
|
+
for (i = 0; i < RSTRING_LEN(str); i++) {
|
412
|
+
if (! IS_DIGIT(RSTRING_PTR(str)[i]))
|
382
413
|
return 0;
|
383
414
|
}
|
384
415
|
return 1;
|
@@ -396,7 +427,7 @@ atomsym(sc, str)
|
|
396
427
|
return tok_digit;
|
397
428
|
}
|
398
429
|
else if (RECV_MODE_P(sc)) {
|
399
|
-
char *p =
|
430
|
+
char *p = RSTRING_PTR(str);
|
400
431
|
if (nccmp(p, "from")) return tok_from;
|
401
432
|
else if (nccmp(p, "by")) return tok_by;
|
402
433
|
else if (nccmp(p, "via")) return tok_via;
|
@@ -417,8 +448,8 @@ debug_print(sc, sym, val)
|
|
417
448
|
s = rb_funcall(sym, rb_intern("inspect"), 0),
|
418
449
|
printf("%7ld %-10s token=<%s>\n",
|
419
450
|
(unsigned long)(sc->pend - sc->p),
|
420
|
-
|
421
|
-
|
451
|
+
RSTRING_PTR(s),
|
452
|
+
RSTRING_PTR(val));
|
422
453
|
}
|
423
454
|
|
424
455
|
#define D(expr) do {\
|
data/lib/tmail.rb
CHANGED
data/lib/tmail/address.rb
CHANGED
@@ -38,7 +38,7 @@ module TMail
|
|
38
38
|
# = Class Address
|
39
39
|
#
|
40
40
|
# Provides a complete handling library for email addresses. Can parse a string of an
|
41
|
-
# address directly or take in preformatted addresses
|
41
|
+
# address directly or take in preformatted addresses themselves. Allows you to add
|
42
42
|
# and remove phrases from the front of the address and provides a compare function for
|
43
43
|
# email addresses.
|
44
44
|
#
|
@@ -46,7 +46,7 @@ module TMail
|
|
46
46
|
#
|
47
47
|
# Just pass the email address in as a string to Address.parse:
|
48
48
|
#
|
49
|
-
# email = TMail::Address.parse('Mikel Lindsaar <mikel@lindsaar.net>)
|
49
|
+
# email = TMail::Address.parse('Mikel Lindsaar <mikel@lindsaar.net>')
|
50
50
|
# #=> #<TMail::Address mikel@lindsaar.net>
|
51
51
|
# email.address
|
52
52
|
# #=> "mikel@lindsaar.net"
|
@@ -63,7 +63,7 @@ module TMail
|
|
63
63
|
# Address.parse and catch any SyntaxError:
|
64
64
|
#
|
65
65
|
# begin
|
66
|
-
# TMail::
|
66
|
+
# TMail::Address.parse("mikel 2@@@@@ me .com")
|
67
67
|
# rescue TMail::SyntaxError
|
68
68
|
# puts("Invalid Email Address Detected")
|
69
69
|
# else
|
@@ -81,41 +81,7 @@ module TMail
|
|
81
81
|
#
|
82
82
|
# Raises a TMail::SyntaxError on invalid email format
|
83
83
|
def Address.parse( str )
|
84
|
-
Parser.parse :ADDRESS,
|
85
|
-
end
|
86
|
-
|
87
|
-
def Address.special_quote_address(str) #:nodoc:
|
88
|
-
# Takes a string which is an address and adds quotation marks to special
|
89
|
-
# edge case methods that the RACC parser can not handle.
|
90
|
-
#
|
91
|
-
# Right now just handles two edge cases:
|
92
|
-
#
|
93
|
-
# Full stop as the last character of the display name:
|
94
|
-
# Mikel L. <mikel@me.com>
|
95
|
-
# Returns:
|
96
|
-
# "Mikel L." <mikel@me.com>
|
97
|
-
#
|
98
|
-
# Unquoted @ symbol in the display name:
|
99
|
-
# mikel@me.com <mikel@me.com>
|
100
|
-
# Returns:
|
101
|
-
# "mikel@me.com" <mikel@me.com>
|
102
|
-
#
|
103
|
-
# Any other address not matching these patterns just gets returned as is.
|
104
|
-
case
|
105
|
-
# This handles the missing "" in an older version of Apple Mail.app
|
106
|
-
# around the display name when the display name contains a '@'
|
107
|
-
# like 'mikel@me.com <mikel@me.com>'
|
108
|
-
# Just quotes it to: '"mikel@me.com" <mikel@me.com>'
|
109
|
-
when str =~ /\A([^"].+@.+[^"])\s(<.*?>)\Z/
|
110
|
-
return "\"#{$1}\" #{$2}"
|
111
|
-
# This handles cases where 'Mikel A. <mikel@me.com>' which is a trailing
|
112
|
-
# full stop before the address section. Just quotes it to
|
113
|
-
# '"Mikel A. <mikel@me.com>"
|
114
|
-
when str =~ /\A(.*?\.)\s(<.*?>)\Z/
|
115
|
-
return "\"#{$1}\" #{$2}"
|
116
|
-
else
|
117
|
-
str
|
118
|
-
end
|
84
|
+
Parser.parse :ADDRESS, str
|
119
85
|
end
|
120
86
|
|
121
87
|
def address_group? #:nodoc:
|
@@ -143,7 +109,7 @@ module TMail
|
|
143
109
|
|
144
110
|
# This is to catch an unquoted "@" symbol in the local part of the
|
145
111
|
# address. Handles addresses like <"@"@me.com> and makes sure they
|
146
|
-
# stay like <"@"@me.com> (previously were
|
112
|
+
# stay like <"@"@me.com> (previously were becoming <@@me.com>)
|
147
113
|
if local && (local.join == '@' || local.join =~ /\A[^"].*?@.*?[^"]\Z/)
|
148
114
|
@local = "\"#{local.join}\""
|
149
115
|
else
|
@@ -412,7 +378,7 @@ module TMail
|
|
412
378
|
if first
|
413
379
|
first = false
|
414
380
|
else
|
415
|
-
strategy.
|
381
|
+
strategy.puts_meta ','
|
416
382
|
end
|
417
383
|
strategy.space
|
418
384
|
mbox.accept strategy
|
data/lib/tmail/attachments.rb
CHANGED
@@ -4,43 +4,62 @@
|
|
4
4
|
|
5
5
|
=end
|
6
6
|
|
7
|
+
require 'kconv'
|
7
8
|
require 'stringio'
|
8
9
|
|
9
10
|
module TMail
|
10
11
|
class Attachment < StringIO
|
11
12
|
attr_accessor :original_filename, :content_type
|
13
|
+
alias quoted_filename original_filename
|
12
14
|
end
|
13
15
|
|
14
16
|
class Mail
|
15
17
|
def has_attachments?
|
16
|
-
multipart? && parts.any? { |part| attachment?(part) }
|
18
|
+
attachment?(self) || multipart? && parts.any? { |part| attachment?(part) }
|
17
19
|
end
|
18
20
|
|
21
|
+
# Returns true if this part's content main type is text, else returns false.
|
22
|
+
# By main type is meant "text/plain" is text. "text/html" is text
|
23
|
+
def text_content_type?
|
24
|
+
self.header['content-type'] && (self.header['content-type'].main_type == 'text')
|
25
|
+
end
|
26
|
+
|
27
|
+
def inline_attachment?(part)
|
28
|
+
part['content-id'] || (part['content-disposition'] && part['content-disposition'].disposition == 'inline' && !part.text_content_type?)
|
29
|
+
end
|
30
|
+
|
19
31
|
def attachment?(part)
|
20
|
-
part.disposition_is_attachment? || part.
|
32
|
+
part.disposition_is_attachment? || (!part.content_type.nil? && !part.text_content_type?) unless part.multipart?
|
21
33
|
end
|
22
|
-
|
34
|
+
|
23
35
|
def attachments
|
24
36
|
if multipart?
|
25
|
-
parts.collect { |part|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
content = part.body # unquoted automatically by TMail#body
|
30
|
-
file_name = (part['content-location'] &&
|
31
|
-
part['content-location'].body) ||
|
32
|
-
part.sub_header("content-type", "name") ||
|
33
|
-
part.sub_header("content-disposition", "filename")
|
34
|
-
|
35
|
-
next if file_name.blank? || content.blank?
|
36
|
-
|
37
|
-
attachment = Attachment.new(content)
|
38
|
-
attachment.original_filename = file_name.strip
|
39
|
-
attachment.content_type = part.content_type
|
40
|
-
attachment
|
41
|
-
end
|
42
|
-
}.flatten.compact
|
43
|
-
end
|
37
|
+
parts.collect { |part| attachment(part) }.flatten.compact
|
38
|
+
elsif attachment?(self)
|
39
|
+
[attachment(self)]
|
40
|
+
end
|
44
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def attachment(part)
|
46
|
+
if part.multipart?
|
47
|
+
part.attachments
|
48
|
+
elsif attachment?(part)
|
49
|
+
content = part.body # unquoted automatically by TMail#body
|
50
|
+
file_name = (part['content-location'] && part['content-location'].body) ||
|
51
|
+
part.sub_header('content-type', 'name') ||
|
52
|
+
part.sub_header('content-disposition', 'filename') ||
|
53
|
+
'noname'
|
54
|
+
|
55
|
+
return if content.blank?
|
56
|
+
|
57
|
+
attachment = TMail::Attachment.new(content)
|
58
|
+
attachment.original_filename = file_name.strip unless file_name.blank?
|
59
|
+
attachment.content_type = part.content_type
|
60
|
+
attachment
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
45
64
|
end
|
46
65
|
end
|
data/lib/tmail/encode.rb
CHANGED
@@ -113,6 +113,7 @@ module TMail
|
|
113
113
|
|
114
114
|
encoded = '=\?(?:iso-2022-jp|euc-jp|shift_jis)\?[QB]\?[a-z0-9+/=]+\?='
|
115
115
|
ENCODED_WORDS = /#{encoded}(?:\s+#{encoded})*/i
|
116
|
+
SPACER = "\t"
|
116
117
|
|
117
118
|
OUTPUT_ENCODING = {
|
118
119
|
'EUC' => 'e',
|
@@ -165,6 +166,10 @@ module TMail
|
|
165
166
|
@f << str
|
166
167
|
end
|
167
168
|
|
169
|
+
def puts_meta( str )
|
170
|
+
@f << str
|
171
|
+
end
|
172
|
+
|
168
173
|
def text( str )
|
169
174
|
@f << decode(str)
|
170
175
|
end
|
@@ -301,6 +306,10 @@ module TMail
|
|
301
306
|
add_text str
|
302
307
|
end
|
303
308
|
|
309
|
+
def puts_meta( str )
|
310
|
+
add_text str + @eol + SPACER
|
311
|
+
end
|
312
|
+
|
304
313
|
def text( str )
|
305
314
|
scanadd normalize_encoding(str)
|
306
315
|
end
|
data/lib/tmail/header.rb
CHANGED
@@ -59,7 +59,7 @@ module TMail
|
|
59
59
|
#
|
60
60
|
# This is because a mailbox doesn't have the : after the From that designates the
|
61
61
|
# beginning of the envelope sender (which can be different to the from address of
|
62
|
-
# the
|
62
|
+
# the email)
|
63
63
|
#
|
64
64
|
# Other fields can be passed as normal, "Reply-To", "Received" etc.
|
65
65
|
#
|
@@ -243,6 +243,8 @@ module TMail
|
|
243
243
|
|
244
244
|
def do_parse
|
245
245
|
quote_boundary
|
246
|
+
quote_unquoted_name
|
247
|
+
quote_unquoted_bencode
|
246
248
|
obj = Parser.parse(self.class::PARSE_TYPE, @body, @comments)
|
247
249
|
set obj if obj
|
248
250
|
end
|
@@ -314,7 +316,7 @@ module TMail
|
|
314
316
|
if first
|
315
317
|
first = false
|
316
318
|
else
|
317
|
-
strategy.
|
319
|
+
strategy.puts_meta ','
|
318
320
|
strategy.space
|
319
321
|
end
|
320
322
|
a.accept strategy
|
@@ -817,7 +819,7 @@ module TMail
|
|
817
819
|
if v
|
818
820
|
strategy.meta ';'
|
819
821
|
strategy.space
|
820
|
-
strategy.kv_pair k, v
|
822
|
+
strategy.kv_pair k, unquote(v)
|
821
823
|
end
|
822
824
|
end
|
823
825
|
end
|
data/lib/tmail/interface.rb
CHANGED
@@ -42,7 +42,7 @@ module TMail
|
|
42
42
|
# Allows you to query the mail object with a string to get the contents
|
43
43
|
# of the field you want.
|
44
44
|
#
|
45
|
-
# Returns a string of the exact
|
45
|
+
# Returns a string of the exact contents of the field
|
46
46
|
#
|
47
47
|
# mail.from = "mikel <mikel@lindsaar.net>"
|
48
48
|
# mail.header_string("From") #=> "mikel <mikel@lindsaar.net>"
|
@@ -591,16 +591,43 @@ module TMail
|
|
591
591
|
end
|
592
592
|
|
593
593
|
# Destructively sets the message ID of the mail object instance to the passed in string
|
594
|
+
#
|
595
|
+
# Invalid message IDs are ignored (silently, unless configured otherwise) and result in
|
596
|
+
# a nil message ID. Left and right angle brackets are required.
|
594
597
|
#
|
598
|
+
# Be warned however, that calling mail.ready_to_send will overwrite whatever value you
|
599
|
+
# have in this field with an automatically generated unique value.
|
600
|
+
#
|
601
|
+
# If you really want to set your own message ID and know what you are doing per the
|
602
|
+
# various RFCs, you can do so with the enforced_message_id= command
|
603
|
+
#
|
595
604
|
# Example:
|
596
605
|
#
|
597
606
|
# mail = TMail::Mail.new
|
607
|
+
# mail.message_id = "<348F04F142D69C21-291E56D292BC@xxxx.net>"
|
608
|
+
# mail.message_id #=> "<348F04F142D69C21-291E56D292BC@xxxx.net>"
|
598
609
|
# mail.message_id = "this_is_my_badly_formatted_message_id"
|
599
|
-
# mail.message_id #=>
|
610
|
+
# mail.message_id #=> nil
|
600
611
|
def message_id=( str )
|
601
612
|
set_string_attr 'Message-Id', str
|
602
613
|
end
|
603
614
|
|
615
|
+
# Destructively sets the message ID of the mail object instance to the passed in string
|
616
|
+
# and also guarantees that calling #ready_to_send will not destroy what you set as the
|
617
|
+
# message_id
|
618
|
+
#
|
619
|
+
# Example:
|
620
|
+
#
|
621
|
+
# mail = TMail::Mail.new
|
622
|
+
# mail.message_id = "<348F04F142D69C21-291E56D292BC@xxxx.net>"
|
623
|
+
# mail.message_id #=> "<348F04F142D69C21-291E56D292BC@xxxx.net>"
|
624
|
+
# mail.ready_to_send
|
625
|
+
# mail.message_id #=> "<348F04F142D69C21-291E56D292BC@xxxx.net>"
|
626
|
+
def enforced_message_id=( str )
|
627
|
+
@message_id_enforced = true
|
628
|
+
self.message_id = ( str )
|
629
|
+
end
|
630
|
+
|
604
631
|
# Returns the "In-Reply-To:" field contents as an array of this mail instance if it exists
|
605
632
|
#
|
606
633
|
# If the in_reply_to field does not exist, returns nil by default or you can pass in as
|
@@ -838,7 +865,17 @@ module TMail
|
|
838
865
|
if h = @header['content-type']
|
839
866
|
h['charset'] or default
|
840
867
|
else
|
841
|
-
default
|
868
|
+
mime_version_charset || default
|
869
|
+
end
|
870
|
+
end
|
871
|
+
|
872
|
+
# some weird emails come with the charset specified in the mime-version header:
|
873
|
+
#
|
874
|
+
# #<TMail::MimeVersionHeader "1.0\n charset=\"gb2312\"">
|
875
|
+
#
|
876
|
+
def mime_version_charset
|
877
|
+
if header['mime-version'].inspect =~ /charset=('|\\")?([^\\"']+)/
|
878
|
+
$2
|
842
879
|
end
|
843
880
|
end
|
844
881
|
|
data/lib/tmail/mail.rb
CHANGED
@@ -255,7 +255,7 @@ module TMail
|
|
255
255
|
alias fetch []
|
256
256
|
|
257
257
|
# Allows you to set or delete TMail header objects at will.
|
258
|
-
#
|
258
|
+
# Examples:
|
259
259
|
# @mail = TMail::Mail.new
|
260
260
|
# @mail['to'].to_s # => 'mikel@test.com.au'
|
261
261
|
# @mail['to'] = 'mikel@elsewhere.org'
|
@@ -265,7 +265,7 @@ module TMail
|
|
265
265
|
# @mail['to'].to_s # => nil
|
266
266
|
# @mail.encoded # => "\r\n"
|
267
267
|
#
|
268
|
-
# Note: setting mail[] = nil
|
268
|
+
# Note: setting mail[] = nil actually deletes the header field in question from the object,
|
269
269
|
# it does not just set the value of the hash to nil
|
270
270
|
def []=( key, val )
|
271
271
|
dkey = key.downcase
|
@@ -547,7 +547,7 @@ module TMail
|
|
547
547
|
end
|
548
548
|
|
549
549
|
def read_multipart( src )
|
550
|
-
bound = @header['content-type'].params['boundary']
|
550
|
+
bound = @header['content-type'].params['boundary'] || ::TMail.new_boundary
|
551
551
|
is_sep = /\A--#{Regexp.quote bound}(?:--)?[ \t]*(?:\n|\r\n|\r)/
|
552
552
|
lastbound = "--#{bound}--"
|
553
553
|
|