tmail 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/CHANGES +5 -0
  2. data/NOTES +84 -0
  3. data/README +6 -1
  4. data/ext/Makefile +20 -0
  5. data/ext/{tmail/base64 → mailscanner/tmail}/MANIFEST +1 -1
  6. data/ext/mailscanner/tmail/depend +1 -0
  7. data/ext/mailscanner/tmail/extconf.rb +24 -0
  8. data/ext/{tmail/scanner_c/scanner_c.c → mailscanner/tmail/mailscanner.c} +8 -7
  9. data/lib/tmail/base64.rb +29 -52
  10. data/lib/tmail/encode.rb +37 -38
  11. data/lib/tmail/interface.rb +632 -49
  12. data/lib/tmail/main.rb +4 -0
  13. data/lib/tmail/net.rb +0 -35
  14. data/lib/tmail/quoting.rb +8 -8
  15. data/lib/tmail/scanner.rb +10 -6
  16. data/lib/tmail/scanner_r.rb +3 -5
  17. data/lib/tmail/version.rb +2 -2
  18. data/log/ChangeLog.txt +1131 -0
  19. data/log/History.txt +40 -0
  20. data/log/Todo.txt +32 -0
  21. data/meta/MANIFEST +118 -0
  22. data/meta/ROLLRC +3 -0
  23. data/meta/icli.yaml +2 -2
  24. data/meta/{tmail-1.1.1.roll → project.yaml} +3 -7
  25. data/sample/bench_base64.rb +48 -0
  26. data/{bat → script}/changelog +0 -0
  27. data/script/clobber/distclean +8 -0
  28. data/{bat → script}/clobber/package +0 -0
  29. data/script/compile +32 -0
  30. data/{bat → script}/config.yaml +2 -2
  31. data/{bat → script}/prepare +4 -2
  32. data/{bat → script}/publish +0 -0
  33. data/{bat → script}/release +0 -0
  34. data/{bat → script}/setup +0 -0
  35. data/{bat → script}/stats +0 -0
  36. data/{bat → script}/tag +0 -0
  37. data/script/test +36 -0
  38. data/test/fixtures/raw_email_reply +32 -0
  39. data/test/fixtures/raw_email_with_bad_date +48 -0
  40. data/test/test_address.rb +1 -3
  41. data/test/test_attachments.rb +1 -2
  42. data/test/test_base64.rb +3 -2
  43. data/test/test_encode.rb +1 -0
  44. data/test/test_header.rb +2 -3
  45. data/test/test_helper.rb +8 -2
  46. data/test/test_mail.rb +45 -16
  47. data/test/test_mbox.rb +1 -1
  48. data/test/test_port.rb +1 -1
  49. data/test/test_scanner.rb +1 -1
  50. data/test/test_utils.rb +1 -2
  51. metadata +82 -76
  52. data/bat/compile +0 -42
  53. data/bat/rdoc +0 -42
  54. data/bat/test +0 -25
  55. data/ext/tmail/Makefile +0 -25
  56. data/ext/tmail/base64/base64.c +0 -264
  57. data/ext/tmail/base64/depend +0 -1
  58. data/ext/tmail/base64/extconf.rb +0 -38
  59. data/ext/tmail/scanner_c/MANIFEST +0 -4
  60. data/ext/tmail/scanner_c/depend +0 -1
  61. data/ext/tmail/scanner_c/extconf.rb +0 -38
  62. data/lib/tmail/tmail.rb +0 -1
@@ -1,6 +1,6 @@
1
1
  =begin rdoc
2
2
 
3
- = Facade.rb Provides an interface to the TMail object
3
+ = interface.rb Provides an interface to the TMail object
4
4
 
5
5
  =end
6
6
  #--
@@ -29,20 +29,31 @@
29
29
  # with permission of Minero Aoki.
30
30
  #++
31
31
 
32
+ # TMail::Mail objects get accessed primarily through the methods in this file.
33
+ #
34
+ #
35
+
32
36
  require 'tmail/utils'
33
37
 
34
38
  module TMail
35
39
 
36
40
  class Mail
37
41
 
42
+ # Allows you to query the mail object with a string to get the contents
43
+ # of the field you want.
44
+ #
45
+ # Returns a string of the exact contnts of the field
46
+ #
47
+ # mail.from = "mikel <mikel@lindsaar.net>"
48
+ # mail.header_string("From") #=> "mikel <mikel@lindsaar.net>"
38
49
  def header_string( name, default = nil )
39
50
  h = @header[name.downcase] or return default
40
51
  h.to_s
41
52
  end
42
53
 
43
- ###
44
- ### attributes
45
- ###
54
+ #:stopdoc:
55
+ #--
56
+ #== Attributes
46
57
 
47
58
  include TextUtils
48
59
 
@@ -92,10 +103,15 @@ module TMail
92
103
  end
93
104
  private :addrs2specs
94
105
 
95
- #
96
- # date time
97
- #
106
+ #:startdoc:
98
107
 
108
+ #== Date and Time methods
109
+
110
+ # Returns the date of the email message as per the "date" header value or returns
111
+ # nil by default (if no date field exists).
112
+ #
113
+ # You can also pass whatever default you want into this method and it will return
114
+ # that instead of nil if there is no date already set.
99
115
  def date( default = nil )
100
116
  if h = @header['date']
101
117
  h.date
@@ -104,6 +120,15 @@ module TMail
104
120
  end
105
121
  end
106
122
 
123
+ # Destructively sets the date of the mail object with the passed Time instance,
124
+ # returns a Time instance set to the date/time of the mail
125
+ #
126
+ # Example:
127
+ #
128
+ # now = Time.now
129
+ # mail.date = now
130
+ # mail.date #=> Sat Nov 03 18:47:50 +1100 2007
131
+ # mail.date.class #=> Time
107
132
  def date=( time )
108
133
  if time
109
134
  store 'Date', time2str(time)
@@ -113,6 +138,13 @@ module TMail
113
138
  time
114
139
  end
115
140
 
141
+ # Returns the time of the mail message formatted to your taste using a
142
+ # strftime format string. If no date set returns nil by default or whatever value
143
+ # you pass as the second optional parameter.
144
+ #
145
+ # time = Time.now # (on Nov 16 2007)
146
+ # mail.date = time
147
+ # mail.strftime("%D") #=> "11/16/07"
116
148
  def strftime( fmt, default = nil )
117
149
  if t = date
118
150
  t.strftime(fmt)
@@ -121,10 +153,20 @@ module TMail
121
153
  end
122
154
  end
123
155
 
124
- #
125
- # destination
126
- #
127
-
156
+ #== Destination methods
157
+
158
+ # Return a TMail::Addresses instance for each entry in the "To:" field of the mail object header.
159
+ #
160
+ # If the "To:" field does not exist, will return nil by default or the value you
161
+ # pass as the optional parameter.
162
+ #
163
+ # Example:
164
+ #
165
+ # mail = TMail::Mail.new
166
+ # mail.to_addrs #=> nil
167
+ # mail.to_addrs([]) #=> []
168
+ # mail.to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
169
+ # mail.to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
128
170
  def to_addrs( default = nil )
129
171
  if h = @header['to']
130
172
  h.addrs
@@ -133,7 +175,19 @@ module TMail
133
175
  end
134
176
  end
135
177
 
136
- def cc_addrs( default = nil )
178
+ # Return a TMail::Addresses instance for each entry in the "Cc:" field of the mail object header.
179
+ #
180
+ # If the "Cc:" field does not exist, will return nil by default or the value you
181
+ # pass as the optional parameter.
182
+ #
183
+ # Example:
184
+ #
185
+ # mail = TMail::Mail.new
186
+ # mail.cc_addrs #=> nil
187
+ # mail.cc_addrs([]) #=> []
188
+ # mail.cc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
189
+ # mail.cc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
190
+ def cc_addrs( default = nil )
137
191
  if h = @header['cc']
138
192
  h.addrs
139
193
  else
@@ -141,6 +195,18 @@ module TMail
141
195
  end
142
196
  end
143
197
 
198
+ # Return a TMail::Addresses instance for each entry in the "Bcc:" field of the mail object header.
199
+ #
200
+ # If the "Bcc:" field does not exist, will return nil by default or the value you
201
+ # pass as the optional parameter.
202
+ #
203
+ # Example:
204
+ #
205
+ # mail = TMail::Mail.new
206
+ # mail.bcc_addrs #=> nil
207
+ # mail.bcc_addrs([]) #=> []
208
+ # mail.bcc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
209
+ # mail.bcc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
144
210
  def bcc_addrs( default = nil )
145
211
  if h = @header['bcc']
146
212
  h.addrs
@@ -149,46 +215,137 @@ module TMail
149
215
  end
150
216
  end
151
217
 
218
+ # Destructively set the to field of the "To:" header to equal the passed in string.
219
+ #
220
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
221
+ # object before assigning it to the mail message.
222
+ #
223
+ # Example:
224
+ #
225
+ # mail = TMail::Mail.new
226
+ # mail.to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
227
+ # mail.to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
152
228
  def to_addrs=( arg )
153
229
  set_addrfield 'to', arg
154
230
  end
155
231
 
232
+ # Destructively set the to field of the "Cc:" header to equal the passed in string.
233
+ #
234
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
235
+ # object before assigning it to the mail message.
236
+ #
237
+ # Example:
238
+ #
239
+ # mail = TMail::Mail.new
240
+ # mail.cc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
241
+ # mail.cc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
156
242
  def cc_addrs=( arg )
157
243
  set_addrfield 'cc', arg
158
244
  end
159
245
 
246
+ # Destructively set the to field of the "Bcc:" header to equal the passed in string.
247
+ #
248
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
249
+ # object before assigning it to the mail message.
250
+ #
251
+ # Example:
252
+ #
253
+ # mail = TMail::Mail.new
254
+ # mail.bcc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
255
+ # mail.bcc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
160
256
  def bcc_addrs=( arg )
161
257
  set_addrfield 'bcc', arg
162
258
  end
163
259
 
260
+ # Returns who the email is to as an Array of email addresses as opposed to an Array of
261
+ # TMail::Address objects which is what Mail#to_addrs returns
262
+ #
263
+ # Example:
264
+ #
265
+ # mail = TMail::Mail.new
266
+ # mail.to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
267
+ # mail.to #=> ["mikel@me.org", "mikel@you.org"]
164
268
  def to( default = nil )
165
269
  addrs2specs(to_addrs(nil)) || default
166
270
  end
167
271
 
272
+ # Returns who the email cc'd as an Array of email addresses as opposed to an Array of
273
+ # TMail::Address objects which is what Mail#to_addrs returns
274
+ #
275
+ # Example:
276
+ #
277
+ # mail = TMail::Mail.new
278
+ # mail.cc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
279
+ # mail.cc #=> ["mikel@me.org", "mikel@you.org"]
168
280
  def cc( default = nil )
169
281
  addrs2specs(cc_addrs(nil)) || default
170
282
  end
171
283
 
284
+ # Returns who the email bcc'd as an Array of email addresses as opposed to an Array of
285
+ # TMail::Address objects which is what Mail#to_addrs returns
286
+ #
287
+ # Example:
288
+ #
289
+ # mail = TMail::Mail.new
290
+ # mail.bcc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
291
+ # mail.bcc #=> ["mikel@me.org", "mikel@you.org"]
172
292
  def bcc( default = nil )
173
293
  addrs2specs(bcc_addrs(nil)) || default
174
294
  end
175
295
 
296
+ # Destructively sets the "To:" field to the passed array of strings (which should be valid
297
+ # email addresses)
298
+ #
299
+ # Example:
300
+ #
301
+ # mail = TMail::Mail.new
302
+ # mail.to = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
303
+ # mail.to #=> ["mikel@abc.org", "mikel@xyz.org"]
304
+ # mail['to'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
176
305
  def to=( *strs )
177
306
  set_string_array_attr 'To', strs
178
307
  end
179
308
 
309
+ # Destructively sets the "Cc:" field to the passed array of strings (which should be valid
310
+ # email addresses)
311
+ #
312
+ # Example:
313
+ #
314
+ # mail = TMail::Mail.new
315
+ # mail.cc = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
316
+ # mail.cc #=> ["mikel@abc.org", "mikel@xyz.org"]
317
+ # mail['cc'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
180
318
  def cc=( *strs )
181
319
  set_string_array_attr 'Cc', strs
182
320
  end
183
321
 
322
+ # Destructively sets the "Bcc:" field to the passed array of strings (which should be valid
323
+ # email addresses)
324
+ #
325
+ # Example:
326
+ #
327
+ # mail = TMail::Mail.new
328
+ # mail.bcc = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
329
+ # mail.bcc #=> ["mikel@abc.org", "mikel@xyz.org"]
330
+ # mail['bcc'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
184
331
  def bcc=( *strs )
185
332
  set_string_array_attr 'Bcc', strs
186
333
  end
187
334
 
188
- #
189
- # originator
190
- #
191
-
335
+ #== Originator methods
336
+
337
+ # Return a TMail::Addresses instance for each entry in the "From:" field of the mail object header.
338
+ #
339
+ # If the "From:" field does not exist, will return nil by default or the value you
340
+ # pass as the optional parameter.
341
+ #
342
+ # Example:
343
+ #
344
+ # mail = TMail::Mail.new
345
+ # mail.from_addrs #=> nil
346
+ # mail.from_addrs([]) #=> []
347
+ # mail.from = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
348
+ # mail.from_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
192
349
  def from_addrs( default = nil )
193
350
  if h = @header['from']
194
351
  h.addrs
@@ -197,18 +354,52 @@ module TMail
197
354
  end
198
355
  end
199
356
 
357
+ # Destructively set the to value of the "From:" header to equal the passed in string.
358
+ #
359
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
360
+ # object before assigning it to the mail message.
361
+ #
362
+ # Example:
363
+ #
364
+ # mail = TMail::Mail.new
365
+ # mail.from_addrs = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
366
+ # mail.from_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
200
367
  def from_addrs=( arg )
201
368
  set_addrfield 'from', arg
202
369
  end
203
370
 
371
+ # Returns who the email is from as an Array of email address strings instead to an Array of
372
+ # TMail::Address objects which is what Mail#from_addrs returns
373
+ #
374
+ # Example:
375
+ #
376
+ # mail = TMail::Mail.new
377
+ # mail.from = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
378
+ # mail.from #=> ["mikel@me.org", "mikel@you.org"]
204
379
  def from( default = nil )
205
380
  addrs2specs(from_addrs(nil)) || default
206
381
  end
207
382
 
383
+ # Destructively sets the "From:" field to the passed array of strings (which should be valid
384
+ # email addresses)
385
+ #
386
+ # Example:
387
+ #
388
+ # mail = TMail::Mail.new
389
+ # mail.from = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
390
+ # mail.from #=> ["mikel@abc.org", "mikel@xyz.org"]
391
+ # mail['from'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
208
392
  def from=( *strs )
209
393
  set_string_array_attr 'From', strs
210
394
  end
211
395
 
396
+ # Returns the "friendly" human readable part of the address
397
+ #
398
+ # Example:
399
+ #
400
+ # mail = TMail::Mail.new
401
+ # mail.from = "Mikel Lindsaar <mikel@abc.com>"
402
+ # mail.friendly_from #=> "Mikel Lindsaar"
212
403
  def friendly_from( default = nil )
213
404
  h = @header['from']
214
405
  a, = h.addrs
@@ -218,33 +409,92 @@ module TMail
218
409
  a.spec
219
410
  end
220
411
 
221
-
412
+ # Return a TMail::Addresses instance for each entry in the "Reply-To:" field of the mail object header.
413
+ #
414
+ # If the "Reply-To:" field does not exist, will return nil by default or the value you
415
+ # pass as the optional parameter.
416
+ #
417
+ # Example:
418
+ #
419
+ # mail = TMail::Mail.new
420
+ # mail.reply_to_addrs #=> nil
421
+ # mail.reply_to_addrs([]) #=> []
422
+ # mail.reply_to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
423
+ # mail.reply_to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
222
424
  def reply_to_addrs( default = nil )
223
425
  if h = @header['reply-to']
224
- h.addrs
426
+ h.addrs.blank? ? default : h.addrs
225
427
  else
226
428
  default
227
429
  end
228
430
  end
229
431
 
432
+ # Destructively set the to value of the "Reply-To:" header to equal the passed in argument.
433
+ #
434
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
435
+ # object before assigning it to the mail message.
436
+ #
437
+ # Example:
438
+ #
439
+ # mail = TMail::Mail.new
440
+ # mail.reply_to_addrs = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
441
+ # mail.reply_to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
230
442
  def reply_to_addrs=( arg )
231
443
  set_addrfield 'reply-to', arg
232
444
  end
233
445
 
446
+ # Returns who the email is from as an Array of email address strings instead to an Array of
447
+ # TMail::Address objects which is what Mail#reply_to_addrs returns
448
+ #
449
+ # Example:
450
+ #
451
+ # mail = TMail::Mail.new
452
+ # mail.reply_to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
453
+ # mail.reply_to #=> ["mikel@me.org", "mikel@you.org"]
234
454
  def reply_to( default = nil )
235
455
  addrs2specs(reply_to_addrs(nil)) || default
236
456
  end
237
457
 
458
+ # Destructively sets the "Reply-To:" field to the passed array of strings (which should be valid
459
+ # email addresses)
460
+ #
461
+ # Example:
462
+ #
463
+ # mail = TMail::Mail.new
464
+ # mail.reply_to = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
465
+ # mail.reply_to #=> ["mikel@abc.org", "mikel@xyz.org"]
466
+ # mail['reply_to'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
238
467
  def reply_to=( *strs )
239
468
  set_string_array_attr 'Reply-To', strs
240
469
  end
241
470
 
242
-
471
+ # Return a TMail::Addresses instance of the "Sender:" field of the mail object header.
472
+ #
473
+ # If the "Sender:" field does not exist, will return nil by default or the value you
474
+ # pass as the optional parameter.
475
+ #
476
+ # Example:
477
+ #
478
+ # mail = TMail::Mail.new
479
+ # mail.sender #=> nil
480
+ # mail.sender([]) #=> []
481
+ # mail.sender = "Mikel <mikel@me.org>"
482
+ # mail.reply_to_addrs #=> [#<TMail::Address mikel@me.org>]
243
483
  def sender_addr( default = nil )
244
484
  f = @header['sender'] or return default
245
485
  f.addr or return default
246
486
  end
247
487
 
488
+ # Destructively set the to value of the "Sender:" header to equal the passed in argument.
489
+ #
490
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
491
+ # object before assigning it to the mail message.
492
+ #
493
+ # Example:
494
+ #
495
+ # mail = TMail::Mail.new
496
+ # mail.sender_addrs = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
497
+ # mail.sender_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
248
498
  def sender_addr=( addr )
249
499
  if addr
250
500
  h = HeaderField.internal_new('sender', @config)
@@ -256,21 +506,47 @@ module TMail
256
506
  addr
257
507
  end
258
508
 
259
- def sender( default )
509
+ # Returns who the sender of this mail is as string instead to an Array of
510
+ # TMail::Address objects which is what Mail#sender_addr returns
511
+ #
512
+ # Example:
513
+ #
514
+ # mail = TMail::Mail.new
515
+ # mail.sender = "Mikel <mikel@me.org>"
516
+ # mail.sender #=> "mikel@me.org"
517
+ def sender( default = nil )
260
518
  f = @header['sender'] or return default
261
519
  a = f.addr or return default
262
520
  a.spec
263
521
  end
264
522
 
523
+ # Destructively sets the "Sender:" field to the passed string (which should be a valid
524
+ # email address)
525
+ #
526
+ # Example:
527
+ #
528
+ # mail = TMail::Mail.new
529
+ # mail.sender = "mikel@abc.com"
530
+ # mail.sender #=> "mikel@abc.org"
531
+ # mail['sender'].to_s #=> "mikel@abc.com"
265
532
  def sender=( str )
266
533
  set_string_attr 'Sender', str
267
534
  end
268
535
 
269
-
270
- #
271
- # subject
272
- #
273
-
536
+ #== Subject methods
537
+
538
+ # Returns the subject of the mail instance.
539
+ #
540
+ # If the subject field does not exist, returns nil by default or you can pass in as
541
+ # the parameter for what you want the default value to be.
542
+ #
543
+ # Example:
544
+ #
545
+ # mail = TMail::Mail.new
546
+ # mail.subject #=> nil
547
+ # mail.subject("") #=> ""
548
+ # mail.subject = "Hello"
549
+ # mail.subject #=> "Hello"
274
550
  def subject( default = nil )
275
551
  if h = @header['subject']
276
552
  h.body
@@ -280,14 +556,32 @@ module TMail
280
556
  end
281
557
  alias quoted_subject subject
282
558
 
559
+ # Destructively sets the passed string as the subject of the mail message.
560
+ #
561
+ # Example
562
+ #
563
+ # mail = TMail::Mail.new
564
+ # mail.subject #=> "This subject"
565
+ # mail.subject = "Another subject"
566
+ # mail.subject #=> "Another subject"
283
567
  def subject=( str )
284
568
  set_string_attr 'Subject', str
285
569
  end
286
570
 
287
- #
288
- # identity & threading
289
- #
290
-
571
+ #== Message Identity & Threading Methods
572
+
573
+ # Returns the message ID for this mail object instance.
574
+ #
575
+ # If the message_id field does not exist, returns nil by default or you can pass in as
576
+ # the parameter for what you want the default value to be.
577
+ #
578
+ # Example:
579
+ #
580
+ # mail = TMail::Mail.new
581
+ # mail.message_id #=> nil
582
+ # mail.message_id(TMail.new_message_id) #=> "<47404c5326d9c_2ad4fbb80161@baci.local.tmail>"
583
+ # mail.message_id = TMail.new_message_id
584
+ # mail.message_id #=> "<47404c5326d9c_2ad4fbb80161@baci.local.tmail>"
291
585
  def message_id( default = nil )
292
586
  if h = @header['message-id']
293
587
  h.id || default
@@ -296,10 +590,29 @@ module TMail
296
590
  end
297
591
  end
298
592
 
593
+ # Destructively sets the message ID of the mail object instance to the passed in string
594
+ #
595
+ # Example:
596
+ #
597
+ # mail = TMail::Mail.new
598
+ # mail.message_id = "this_is_my_badly_formatted_message_id"
599
+ # mail.message_id #=> "this_is_my_badly_formatted_message_id"
299
600
  def message_id=( str )
300
601
  set_string_attr 'Message-Id', str
301
602
  end
302
603
 
604
+ # Returns the "In-Reply-To:" field contents as an array of this mail instance if it exists
605
+ #
606
+ # If the in_reply_to field does not exist, returns nil by default or you can pass in as
607
+ # the parameter for what you want the default value to be.
608
+ #
609
+ # Example:
610
+ #
611
+ # mail = TMail::Mail.new
612
+ # mail.in_reply_to #=> nil
613
+ # mail.in_reply_to([]) #=> []
614
+ # TMail::Mail.load("../test/fixtures/raw_email_reply")
615
+ # mail.in_reply_to #=> ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
303
616
  def in_reply_to( default = nil )
304
617
  if h = @header['in-reply-to']
305
618
  h.ids
@@ -308,10 +621,33 @@ module TMail
308
621
  end
309
622
  end
310
623
 
624
+ # Destructively sets the value of the "In-Reply-To:" field of an email.
625
+ #
626
+ # Accepts an array of a single string of a message id
627
+ #
628
+ # Example:
629
+ #
630
+ # mail = TMail::Mail.new
631
+ # mail.in_reply_to = ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
632
+ # mail.in_reply_to #=> ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
311
633
  def in_reply_to=( *idstrs )
312
634
  set_string_array_attr 'In-Reply-To', idstrs
313
635
  end
314
636
 
637
+ # Returns the references of this email (prior messages relating to this message)
638
+ # as an array of message ID strings. Useful when you are trying to thread an
639
+ # email.
640
+ #
641
+ # If the references field does not exist, returns nil by default or you can pass in as
642
+ # the parameter for what you want the default value to be.
643
+ #
644
+ # Example:
645
+ #
646
+ # mail = TMail::Mail.new
647
+ # mail.references #=> nil
648
+ # mail.references([]) #=> []
649
+ # mail = TMail::Mail.load("../test/fixtures/raw_email_reply")
650
+ # mail.references #=> ["<473FF3B8.9020707@xxx.org>", "<348F04F142D69C21-291E56D292BC@xxxx.net>"]
315
651
  def references( default = nil )
316
652
  if h = @header['references']
317
653
  h.refs
@@ -320,14 +656,33 @@ module TMail
320
656
  end
321
657
  end
322
658
 
659
+ # Destructively sets the value of the "References:" field of an email.
660
+ #
661
+ # Accepts an array of strings of message IDs
662
+ #
663
+ # Example:
664
+ #
665
+ # mail = TMail::Mail.new
666
+ # mail.references = ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
667
+ # mail.references #=> ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
323
668
  def references=( *strs )
324
669
  set_string_array_attr 'References', strs
325
670
  end
326
671
 
327
- #
328
- # MIME headers
329
- #
672
+ #== MIME header methods
330
673
 
674
+ # Returns the listed MIME version of this email from the "Mime-Version:" header field
675
+ #
676
+ # If the mime_version field does not exist, returns nil by default or you can pass in as
677
+ # the parameter for what you want the default value to be.
678
+ #
679
+ # Example:
680
+ #
681
+ # mail = TMail::Mail.new
682
+ # mail.mime_version #=> nil
683
+ # mail.mime_version([]) #=> []
684
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
685
+ # mail.mime_version #=> "1.0"
331
686
  def mime_version( default = nil )
332
687
  if h = @header['mime-version']
333
688
  h.version || default
@@ -350,6 +705,18 @@ module TMail
350
705
  m
351
706
  end
352
707
 
708
+ # Returns the current "Content-Type" of the mail instance.
709
+ #
710
+ # If the content_type field does not exist, returns nil by default or you can pass in as
711
+ # the parameter for what you want the default value to be.
712
+ #
713
+ # Example:
714
+ #
715
+ # mail = TMail::Mail.new
716
+ # mail.content_type #=> nil
717
+ # mail.content_type([]) #=> []
718
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
719
+ # mail.content_type #=> "text/plain"
353
720
  def content_type( default = nil )
354
721
  if h = @header['content-type']
355
722
  h.content_type || default
@@ -358,6 +725,18 @@ module TMail
358
725
  end
359
726
  end
360
727
 
728
+ # Returns the current main type of the "Content-Type" of the mail instance.
729
+ #
730
+ # If the content_type field does not exist, returns nil by default or you can pass in as
731
+ # the parameter for what you want the default value to be.
732
+ #
733
+ # Example:
734
+ #
735
+ # mail = TMail::Mail.new
736
+ # mail.main_type #=> nil
737
+ # mail.main_type([]) #=> []
738
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
739
+ # mail.main_type #=> "text"
361
740
  def main_type( default = nil )
362
741
  if h = @header['content-type']
363
742
  h.main_type || default
@@ -366,6 +745,18 @@ module TMail
366
745
  end
367
746
  end
368
747
 
748
+ # Returns the current sub type of the "Content-Type" of the mail instance.
749
+ #
750
+ # If the content_type field does not exist, returns nil by default or you can pass in as
751
+ # the parameter for what you want the default value to be.
752
+ #
753
+ # Example:
754
+ #
755
+ # mail = TMail::Mail.new
756
+ # mail.sub_type #=> nil
757
+ # mail.sub_type([]) #=> []
758
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
759
+ # mail.sub_type #=> "plain"
369
760
  def sub_type( default = nil )
370
761
  if h = @header['content-type']
371
762
  h.sub_type || default
@@ -374,6 +765,25 @@ module TMail
374
765
  end
375
766
  end
376
767
 
768
+ # Destructively sets the "Content-Type:" header field of this mail object
769
+ #
770
+ # Allows you to set the main type, sub type as well as parameters to the field.
771
+ # The main type and sub type need to be a string.
772
+ #
773
+ # The optional params hash can be passed with keys as symbols and values as a string,
774
+ # or strings as keys and values.
775
+ #
776
+ # Example:
777
+ #
778
+ # mail = TMail::Mail.new
779
+ # mail.set_content_type("text", "plain")
780
+ # mail.to_s #=> "Content-Type: text/plain\n\n"
781
+ #
782
+ # mail.set_content_type("text", "plain", {:charset => "EUC-KR", :format => "flowed"})
783
+ # mail.to_s #=> "Content-Type: text/plain; charset=EUC-KR; format=flowed\n\n"
784
+ #
785
+ # mail.set_content_type("text", "plain", {"charset" => "EUC-KR", "format" => "flowed"})
786
+ # mail.to_s #=> "Content-Type: text/plain; charset=EUC-KR; format=flowed\n\n"
377
787
  def set_content_type( str, sub = nil, param = nil )
378
788
  if sub
379
789
  main, sub = str, sub
@@ -394,6 +804,16 @@ module TMail
394
804
 
395
805
  alias content_type= set_content_type
396
806
 
807
+ # Returns the named type parameter as a string, from the "Content-Type:" header.
808
+ #
809
+ # Example:
810
+ #
811
+ # mail = TMail::Mail.new
812
+ # mail.type_param("charset") #=> nil
813
+ # mail.type_param("charset", []) #=> []
814
+ # mail.set_content_type("text", "plain", {:charset => "EUC-KR", :format => "flowed"})
815
+ # mail.type_param("charset") #=> "EUC-KR"
816
+ # mail.type_param("format") #=> "flowed"
397
817
  def type_param( name, default = nil )
398
818
  if h = @header['content-type']
399
819
  h[name] || default
@@ -402,6 +822,18 @@ module TMail
402
822
  end
403
823
  end
404
824
 
825
+ # Returns the character set of the email. Returns nil if no encoding set or returns
826
+ # whatever default you pass as a parameter - note passing the parameter does NOT change
827
+ # the mail object in any way.
828
+ #
829
+ # Example:
830
+ #
831
+ # mail = TMail::Mail.load("path_to/utf8_email")
832
+ # mail.charset #=> "UTF-8"
833
+ #
834
+ # mail = TMail::Mail.new
835
+ # mail.charset #=> nil
836
+ # mail.charset("US-ASCII") #=> "US-ASCII"
405
837
  def charset( default = nil )
406
838
  if h = @header['content-type']
407
839
  h['charset'] or default
@@ -410,6 +842,17 @@ module TMail
410
842
  end
411
843
  end
412
844
 
845
+ # Destructively sets the character set used by this mail object to the passed string, you
846
+ # should note though that this does nothing to the mail body, just changes the header
847
+ # value, you will need to transliterate the body as well to match whatever you put
848
+ # in this header value if you are changing character sets.
849
+ #
850
+ # Example:
851
+ #
852
+ # mail = TMail::Mail.new
853
+ # mail.charset #=> nil
854
+ # mail.charset = "UTF-8"
855
+ # mail.charset #=> "UTF-8"
413
856
  def charset=( str )
414
857
  if str
415
858
  if h = @header[ 'content-type' ]
@@ -421,6 +864,18 @@ module TMail
421
864
  str
422
865
  end
423
866
 
867
+ # Returns the transfer encoding of the email. Returns nil if no encoding set or returns
868
+ # whatever default you pass as a parameter - note passing the parameter does NOT change
869
+ # the mail object in any way.
870
+ #
871
+ # Example:
872
+ #
873
+ # mail = TMail::Mail.load("path_to/base64_encoded_email")
874
+ # mail.transfer_encoding #=> "base64"
875
+ #
876
+ # mail = TMail::Mail.new
877
+ # mail.transfer_encoding #=> nil
878
+ # mail.transfer_encoding("base64") #=> "base64"
424
879
  def transfer_encoding( default = nil )
425
880
  if h = @header['content-transfer-encoding']
426
881
  h.encoding || default
@@ -429,6 +884,17 @@ module TMail
429
884
  end
430
885
  end
431
886
 
887
+ # Destructively sets the transfer encoding of the mail object to the passed string, you
888
+ # should note though that this does nothing to the mail body, just changes the header
889
+ # value, you will need to encode or decode the body as well to match whatever you put
890
+ # in this header value.
891
+ #
892
+ # Example:
893
+ #
894
+ # mail = TMail::Mail.new
895
+ # mail.transfer_encoding #=> nil
896
+ # mail.transfer_encoding = "base64"
897
+ # mail.transfer_encoding #=> "base64"
432
898
  def transfer_encoding=( str )
433
899
  set_string_attr 'Content-Transfer-Encoding', str
434
900
  end
@@ -438,6 +904,17 @@ module TMail
438
904
  alias content_transfer_encoding transfer_encoding
439
905
  alias content_transfer_encoding= transfer_encoding=
440
906
 
907
+ # Returns the content-disposition of the mail object, returns nil or the passed
908
+ # default value if given
909
+ #
910
+ # Example:
911
+ #
912
+ # mail = TMail::Mail.load("path_to/raw_mail_with_attachment")
913
+ # mail.disposition #=> "attachment"
914
+ #
915
+ # mail = TMail::Mail.load("path_to/plain_simple_email")
916
+ # mail.disposition #=> nil
917
+ # mail.disposition(false) #=> false
441
918
  def disposition( default = nil )
442
919
  if h = @header['content-disposition']
443
920
  h.disposition || default
@@ -448,6 +925,14 @@ module TMail
448
925
 
449
926
  alias content_disposition disposition
450
927
 
928
+ # Allows you to set the content-disposition of the mail object. Accepts a type
929
+ # and a hash of parameters.
930
+ #
931
+ # Example:
932
+ #
933
+ # mail.set_disposition("attachment", {:filename => "test.rb"})
934
+ # mail.disposition #=> "attachment"
935
+ # mail['content-disposition'].to_s #=> "attachment; filename=test.rb"
451
936
  def set_disposition( str, params = nil )
452
937
  if h = @header['content-disposition']
453
938
  h.disposition = str
@@ -462,7 +947,17 @@ module TMail
462
947
  alias disposition= set_disposition
463
948
  alias set_content_disposition set_disposition
464
949
  alias content_disposition= set_disposition
465
-
950
+
951
+ # Returns the value of a parameter in an existing content-disposition header
952
+ #
953
+ # Example:
954
+ #
955
+ # mail.set_disposition("attachment", {:filename => "test.rb"})
956
+ # mail['content-disposition'].to_s #=> "attachment; filename=test.rb"
957
+ # mail.disposition_param("filename") #=> "test.rb"
958
+ # mail.disposition_param("missing_param_key") #=> nil
959
+ # mail.disposition_param("missing_param_key", false) #=> false
960
+ # mail.disposition_param("missing_param_key", "Nothing to see here") #=> "Nothing to see here"
466
961
  def disposition_param( name, default = nil )
467
962
  if h = @header['content-disposition']
468
963
  h[name] || default
@@ -471,32 +966,40 @@ module TMail
471
966
  end
472
967
  end
473
968
 
474
- ###
475
- ### utils
476
- ###
477
-
478
- def create_reply
479
- mail = TMail::Mail.parse('')
480
- mail.subject = 'Re: ' + subject('').sub(/\A(?:\[[^\]]+\])?(?:\s*Re:)*\s*/i, '')
481
- mail.to_addrs = reply_addresses([])
482
- mail.in_reply_to = [message_id(nil)].compact
483
- mail.references = references([]) + [message_id(nil)].compact
484
- mail.mime_version = '1.0'
485
- mail
486
- end
487
-
488
- def base64_encode
969
+ # Destructively convert the Mail object's body into a Base64 encoded email
970
+ # returning the modified Mail object
971
+ def base64_encode!
489
972
  store 'Content-Transfer-Encoding', 'Base64'
490
973
  self.body = Base64.folding_encode(self.body)
491
974
  end
492
975
 
493
- def base64_decode
976
+ # ==Depreciation warning
977
+ # base64_encode will return the body encoded, not modify the message body in
978
+ # future versions of TMail
979
+ alias :base64_encode :base64_encode!
980
+
981
+ # Destructively convert the Mail object's body into a Base64 decoded email
982
+ # returning the modified Mail object
983
+ def base64_decode!
494
984
  if /base64/i === self.transfer_encoding('')
495
985
  store 'Content-Transfer-Encoding', '8bit'
496
986
  self.body = Base64.decode(self.body, @config.strict_base64decode?)
497
987
  end
498
988
  end
499
989
 
990
+ # ==Depreciation warning
991
+ # base64_decode will return the body decoded, not modify the message body in
992
+ # future versions of TMail
993
+ alias :base64_decode :base64_decode!
994
+
995
+ # Returns an array of each destination in the email message including to: cc: or bcc:
996
+ #
997
+ # Example:
998
+ #
999
+ # mail.to = "Mikel <mikel@lindsaar.net>"
1000
+ # mail.cc = "Trans <t@t.com>"
1001
+ # mail.bcc = "bob <bob@me.com>"
1002
+ # mail.destinations #=> ["mikel@lindsaar.net", "t@t.com", "bob@me.com"]
500
1003
  def destinations( default = nil )
501
1004
  ret = []
502
1005
  %w( to cc bcc ).each do |nm|
@@ -507,6 +1010,12 @@ module TMail
507
1010
  ret.empty? ? default : ret
508
1011
  end
509
1012
 
1013
+ # Yields a block of destination, yielding each as a string.
1014
+ # (from the destinations example)
1015
+ # mail.each_destination { |d| puts "#{d.class}: #{d}" }
1016
+ # String: mikel@lindsaar.net
1017
+ # String: t@t.com
1018
+ # String: bob@me.com
510
1019
  def each_destination( &block )
511
1020
  destinations([]).each do |i|
512
1021
  if Address === i
@@ -519,10 +1028,22 @@ module TMail
519
1028
 
520
1029
  alias each_dest each_destination
521
1030
 
1031
+ # Returns an array of reply to addresses that the Mail object has,
1032
+ # or if the Mail message has no reply-to, returns an array of the
1033
+ # Mail objects from addresses. Else returns the default which can
1034
+ # either be passed as a parameter or defaults to nil
1035
+ #
1036
+ # Example:
1037
+ # mail.from = "Mikel <mikel@lindsaar.net>"
1038
+ # mail.reply_to = nil
1039
+ # mail.reply_addresses #=> [""]
1040
+ #
522
1041
  def reply_addresses( default = nil )
523
1042
  reply_to_addrs(nil) or from_addrs(nil) or default
524
1043
  end
525
1044
 
1045
+ # Returns the "sender" field as an array -> useful to find out who to
1046
+ # send an error email to.
526
1047
  def error_reply_addresses( default = nil )
527
1048
  if s = sender(nil)
528
1049
  [s]
@@ -531,10 +1052,72 @@ module TMail
531
1052
  end
532
1053
  end
533
1054
 
1055
+ # Returns true if the Mail object is a multipart message
534
1056
  def multipart?
535
1057
  main_type('').downcase == 'multipart'
536
1058
  end
537
1059
 
1060
+ # Creates a new email in reply to self. Sets the In-Reply-To and
1061
+ # References headers for you automagically.
1062
+ #
1063
+ # Example:
1064
+ # mail = TMail::Mail.load("my_email")
1065
+ # reply_email = mail.create_reply
1066
+ # reply_email.class #=> TMail::Mail
1067
+ # reply_email.references #=> ["<d3b8cf8e49f04480850c28713a1f473e@lindsaar.net>"]
1068
+ # reply_email.in_reply_to #=> ["<d3b8cf8e49f04480850c28713a1f473e@lindsaar.net>"]
1069
+ def create_reply
1070
+ setup_reply create_empty_mail()
1071
+ end
1072
+
1073
+ # Creates a new email in reply to self. Sets the In-Reply-To and
1074
+ # References headers for you automagically.
1075
+ #
1076
+ # Example:
1077
+ # mail = TMail::Mail.load("my_email")
1078
+ # forward_email = mail.create_forward
1079
+ # forward_email.class #=> TMail::Mail
1080
+ # forward_email.content_type #=> "multipart/mixed"
1081
+ # forward_email.body #=> "Attachment: (unnamed)"
1082
+ # forward_email.encoded #=> Returns the original email as a MIME attachment
1083
+ def create_forward
1084
+ setup_forward create_empty_mail()
1085
+ end
1086
+
1087
+ #:stopdoc:
1088
+ private
1089
+
1090
+ def create_empty_mail
1091
+ self.class.new(StringPort.new(''), @config)
1092
+ end
1093
+
1094
+ def setup_reply( mail )
1095
+ if tmp = reply_addresses(nil)
1096
+ mail.to_addrs = tmp
1097
+ end
1098
+
1099
+ mid = message_id(nil)
1100
+ tmp = references(nil) || []
1101
+ tmp.push mid if mid
1102
+ mail.in_reply_to = [mid] if mid
1103
+ mail.references = tmp unless tmp.empty?
1104
+ mail.subject = 'Re: ' + subject('').sub(/\A(?:\[[^\]]+\])?(?:\s*Re:)*\s*/i, '')
1105
+ mail.mime_version = '1.0'
1106
+ mail
1107
+ end
1108
+
1109
+ def setup_forward( mail )
1110
+ m = Mail.new(StringPort.new(''))
1111
+ m.body = decoded
1112
+ m.set_content_type 'message', 'rfc822'
1113
+ m.encoding = encoding('7bit')
1114
+ mail.parts.push m
1115
+ # call encoded to reparse the message
1116
+ mail.encoded
1117
+ mail
1118
+ end
1119
+
1120
+ #:startdoc:
538
1121
  end # class Mail
539
1122
 
540
1123
  end # module TMail