tmail 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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