daemon-kit 0.1.7 → 0.1.7.4

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 (80) hide show
  1. data/Configuration.txt +58 -0
  2. data/History.txt +24 -0
  3. data/Manifest.txt +50 -2
  4. data/PostInstall.txt +1 -1
  5. data/README.rdoc +7 -9
  6. data/Rakefile +2 -4
  7. data/TODO.txt +6 -5
  8. data/app_generators/daemon_kit/daemon_kit_generator.rb +5 -0
  9. data/app_generators/daemon_kit/templates/Rakefile +3 -1
  10. data/app_generators/daemon_kit/templates/bin/daemon.erb +1 -1
  11. data/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
  12. data/app_generators/daemon_kit/templates/config/boot.rb +2 -2
  13. data/app_generators/daemon_kit/templates/script/console +3 -0
  14. data/app_generators/daemon_kit/templates/script/destroy +14 -0
  15. data/app_generators/daemon_kit/templates/script/generate +14 -0
  16. data/daemon_generators/amqp/templates/config/amqp.yml +5 -5
  17. data/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +4 -23
  18. data/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
  19. data/daemon_generators/deploy_capistrano/templates/config/deploy.rb +3 -1
  20. data/lib/daemon_kit.rb +33 -5
  21. data/lib/daemon_kit/amqp.rb +2 -1
  22. data/lib/daemon_kit/application.rb +136 -11
  23. data/lib/daemon_kit/arguments.rb +151 -0
  24. data/lib/daemon_kit/commands/console.rb +38 -0
  25. data/lib/daemon_kit/config.rb +1 -0
  26. data/lib/daemon_kit/console_daemon.rb +2 -0
  27. data/lib/daemon_kit/core_ext.rb +1 -0
  28. data/lib/daemon_kit/core_ext/string.rb +22 -0
  29. data/lib/daemon_kit/deployment/capistrano.rb +6 -9
  30. data/lib/daemon_kit/error_handlers/mail.rb +52 -15
  31. data/lib/daemon_kit/initializer.rb +95 -41
  32. data/lib/daemon_kit/pid_file.rb +61 -0
  33. data/lib/daemon_kit/tasks/environment.rake +5 -4
  34. data/lib/daemon_kit/tasks/framework.rake +15 -1
  35. data/lib/daemon_kit/tasks/god.rake +62 -0
  36. data/lib/daemon_kit/tasks/log.rake +8 -0
  37. data/lib/daemon_kit/tasks/monit.rake +29 -0
  38. data/spec/argument_spec.rb +51 -0
  39. data/spec/config_spec.rb +77 -0
  40. data/spec/daemon_kit_spec.rb +2 -2
  41. data/spec/error_handlers_spec.rb +23 -0
  42. data/spec/fixtures/env.yml +15 -0
  43. data/spec/fixtures/noenv.yml +4 -0
  44. data/spec/initializer_spec.rb +4 -3
  45. data/spec/spec_helper.rb +8 -11
  46. data/templates/god/god.erb +69 -0
  47. data/templates/monit/monit.erb +14 -0
  48. data/test/test_daemon-kit_generator.rb +6 -1
  49. data/test/test_deploy_capistrano_generator.rb +1 -2
  50. data/vendor/tmail-1.2.3/tmail.rb +5 -0
  51. data/vendor/tmail-1.2.3/tmail/address.rb +426 -0
  52. data/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
  53. data/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
  54. data/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
  55. data/vendor/tmail-1.2.3/tmail/config.rb +67 -0
  56. data/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
  57. data/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
  58. data/vendor/tmail-1.2.3/tmail/header.rb +960 -0
  59. data/vendor/tmail-1.2.3/tmail/index.rb +9 -0
  60. data/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
  61. data/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
  62. data/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
  63. data/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
  64. data/vendor/tmail-1.2.3/tmail/main.rb +6 -0
  65. data/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
  66. data/vendor/tmail-1.2.3/tmail/net.rb +248 -0
  67. data/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
  68. data/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
  69. data/vendor/tmail-1.2.3/tmail/port.rb +379 -0
  70. data/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
  71. data/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
  72. data/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
  73. data/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
  74. data/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
  75. data/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
  76. data/vendor/tmail-1.2.3/tmail/version.rb +39 -0
  77. data/vendor/tmail.rb +13 -0
  78. metadata +57 -18
  79. data/daemon_generators/deploy_capistrano/USAGE +0 -5
  80. data/lib/daemon_kit/patches/force_kill_wait.rb +0 -120
@@ -0,0 +1,960 @@
1
+ #--
2
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
24
+ # with permission of Minero Aoki.
25
+ #++
26
+
27
+ require 'tmail/encode'
28
+ require 'tmail/address'
29
+ require 'tmail/parser'
30
+ require 'tmail/config'
31
+ require 'tmail/utils'
32
+
33
+ #:startdoc:
34
+ module TMail
35
+
36
+ # Provides methods to handle and manipulate headers in the email
37
+ class HeaderField
38
+
39
+ include TextUtils
40
+
41
+ class << self
42
+
43
+ alias newobj new
44
+
45
+ def new( name, body, conf = DEFAULT_CONFIG )
46
+ klass = FNAME_TO_CLASS[name.downcase] || UnstructuredHeader
47
+ klass.newobj body, conf
48
+ end
49
+
50
+ # Returns a HeaderField object matching the header you specify in the "name" param.
51
+ # Requires an initialized TMail::Port to be passed in.
52
+ #
53
+ # The method searches the header of the Port you pass into it to find a match on
54
+ # the header line you pass. Once a match is found, it will unwrap the matching line
55
+ # as needed to return an initialized HeaderField object.
56
+ #
57
+ # If you want to get the Envelope sender of the email object, pass in "EnvelopeSender",
58
+ # if you want the From address of the email itself, pass in 'From'.
59
+ #
60
+ # This is because a mailbox doesn't have the : after the From that designates the
61
+ # beginning of the envelope sender (which can be different to the from address of
62
+ # the email)
63
+ #
64
+ # Other fields can be passed as normal, "Reply-To", "Received" etc.
65
+ #
66
+ # Note: Change of behaviour in 1.2.1 => returns nil if it does not find the specified
67
+ # header field, otherwise returns an instantiated object of the correct header class
68
+ #
69
+ # For example:
70
+ # port = TMail::FilePort.new("/test/fixtures/raw_email_simple")
71
+ # h = TMail::HeaderField.new_from_port(port, "From")
72
+ # h.addrs.to_s #=> "Mikel Lindsaar <mikel@nowhere.com>"
73
+ # h = TMail::HeaderField.new_from_port(port, "EvelopeSender")
74
+ # h.addrs.to_s #=> "mike@anotherplace.com.au"
75
+ # h = TMail::HeaderField.new_from_port(port, "SomeWeirdHeaderField")
76
+ # h #=> nil
77
+ def new_from_port( port, name, conf = DEFAULT_CONFIG )
78
+ if name == "EnvelopeSender"
79
+ name = "From"
80
+ re = Regexp.new('\A(From) ', 'i')
81
+ else
82
+ re = Regexp.new('\A(' + Regexp.quote(name) + '):', 'i')
83
+ end
84
+ str = nil
85
+ port.ropen {|f|
86
+ f.each do |line|
87
+ if m = re.match(line) then str = m.post_match.strip
88
+ elsif str and /\A[\t ]/ === line then str << ' ' << line.strip
89
+ elsif /\A-*\s*\z/ === line then break
90
+ elsif str then break
91
+ end
92
+ end
93
+ }
94
+ new(name, str, Config.to_config(conf)) if str
95
+ end
96
+
97
+ def internal_new( name, conf )
98
+ FNAME_TO_CLASS[name].newobj('', conf, true)
99
+ end
100
+
101
+ end # class << self
102
+
103
+ def initialize( body, conf, intern = false )
104
+ @body = body
105
+ @config = conf
106
+
107
+ @illegal = false
108
+ @parsed = false
109
+
110
+ if intern
111
+ @parsed = true
112
+ parse_init
113
+ end
114
+ end
115
+
116
+ def inspect
117
+ "#<#{self.class} #{@body.inspect}>"
118
+ end
119
+
120
+ def illegal?
121
+ @illegal
122
+ end
123
+
124
+ def empty?
125
+ ensure_parsed
126
+ return true if @illegal
127
+ isempty?
128
+ end
129
+
130
+ private
131
+
132
+ def ensure_parsed
133
+ return if @parsed
134
+ @parsed = true
135
+ parse
136
+ end
137
+
138
+ # defabstract parse
139
+ # end
140
+
141
+ def clear_parse_status
142
+ @parsed = false
143
+ @illegal = false
144
+ end
145
+
146
+ public
147
+
148
+ def body
149
+ ensure_parsed
150
+ v = Decoder.new(s = '')
151
+ do_accept v
152
+ v.terminate
153
+ s
154
+ end
155
+
156
+ def body=( str )
157
+ @body = str
158
+ clear_parse_status
159
+ end
160
+
161
+ include StrategyInterface
162
+
163
+ def accept( strategy )
164
+ ensure_parsed
165
+ do_accept strategy
166
+ strategy.terminate
167
+ end
168
+
169
+ # abstract do_accept
170
+
171
+ end
172
+
173
+
174
+ class UnstructuredHeader < HeaderField
175
+
176
+ def body
177
+ ensure_parsed
178
+ @body
179
+ end
180
+
181
+ def body=( arg )
182
+ ensure_parsed
183
+ @body = arg
184
+ end
185
+
186
+ private
187
+
188
+ def parse_init
189
+ end
190
+
191
+ def parse
192
+ @body = Decoder.decode(@body.gsub(/\n|\r\n|\r/, ''))
193
+ end
194
+
195
+ def isempty?
196
+ not @body
197
+ end
198
+
199
+ def do_accept( strategy )
200
+ strategy.text @body
201
+ end
202
+
203
+ end
204
+
205
+
206
+ class StructuredHeader < HeaderField
207
+
208
+ def comments
209
+ ensure_parsed
210
+ if @comments[0]
211
+ [Decoder.decode(@comments[0])]
212
+ else
213
+ @comments
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ def parse
220
+ save = nil
221
+
222
+ begin
223
+ parse_init
224
+ do_parse
225
+ rescue SyntaxError
226
+ if not save and mime_encoded? @body
227
+ save = @body
228
+ @body = Decoder.decode(save)
229
+ retry
230
+ elsif save
231
+ @body = save
232
+ end
233
+
234
+ @illegal = true
235
+ raise if @config.strict_parse?
236
+ end
237
+ end
238
+
239
+ def parse_init
240
+ @comments = []
241
+ init
242
+ end
243
+
244
+ def do_parse
245
+ quote_boundary
246
+ obj = Parser.parse(self.class::PARSE_TYPE, @body, @comments)
247
+ set obj if obj
248
+ end
249
+
250
+ end
251
+
252
+
253
+ class DateTimeHeader < StructuredHeader
254
+
255
+ PARSE_TYPE = :DATETIME
256
+
257
+ def date
258
+ ensure_parsed
259
+ @date
260
+ end
261
+
262
+ def date=( arg )
263
+ ensure_parsed
264
+ @date = arg
265
+ end
266
+
267
+ private
268
+
269
+ def init
270
+ @date = nil
271
+ end
272
+
273
+ def set( t )
274
+ @date = t
275
+ end
276
+
277
+ def isempty?
278
+ not @date
279
+ end
280
+
281
+ def do_accept( strategy )
282
+ strategy.meta time2str(@date)
283
+ end
284
+
285
+ end
286
+
287
+
288
+ class AddressHeader < StructuredHeader
289
+
290
+ PARSE_TYPE = :MADDRESS
291
+
292
+ def addrs
293
+ ensure_parsed
294
+ @addrs
295
+ end
296
+
297
+ private
298
+
299
+ def init
300
+ @addrs = []
301
+ end
302
+
303
+ def set( a )
304
+ @addrs = a
305
+ end
306
+
307
+ def isempty?
308
+ @addrs.empty?
309
+ end
310
+
311
+ def do_accept( strategy )
312
+ first = true
313
+ @addrs.each do |a|
314
+ if first
315
+ first = false
316
+ else
317
+ strategy.meta ','
318
+ strategy.space
319
+ end
320
+ a.accept strategy
321
+ end
322
+
323
+ @comments.each do |c|
324
+ strategy.space
325
+ strategy.meta '('
326
+ strategy.text c
327
+ strategy.meta ')'
328
+ end
329
+ end
330
+
331
+ end
332
+
333
+
334
+ class ReturnPathHeader < AddressHeader
335
+
336
+ PARSE_TYPE = :RETPATH
337
+
338
+ def addr
339
+ addrs()[0]
340
+ end
341
+
342
+ def spec
343
+ a = addr() or return nil
344
+ a.spec
345
+ end
346
+
347
+ def routes
348
+ a = addr() or return nil
349
+ a.routes
350
+ end
351
+
352
+ private
353
+
354
+ def do_accept( strategy )
355
+ a = addr()
356
+
357
+ strategy.meta '<'
358
+ unless a.routes.empty?
359
+ strategy.meta a.routes.map {|i| '@' + i }.join(',')
360
+ strategy.meta ':'
361
+ end
362
+ spec = a.spec
363
+ strategy.meta spec if spec
364
+ strategy.meta '>'
365
+ end
366
+
367
+ end
368
+
369
+
370
+ class SingleAddressHeader < AddressHeader
371
+
372
+ def addr
373
+ addrs()[0]
374
+ end
375
+
376
+ private
377
+
378
+ def do_accept( strategy )
379
+ a = addr()
380
+ a.accept strategy
381
+ @comments.each do |c|
382
+ strategy.space
383
+ strategy.meta '('
384
+ strategy.text c
385
+ strategy.meta ')'
386
+ end
387
+ end
388
+
389
+ end
390
+
391
+
392
+ class MessageIdHeader < StructuredHeader
393
+
394
+ def id
395
+ ensure_parsed
396
+ @id
397
+ end
398
+
399
+ def id=( arg )
400
+ ensure_parsed
401
+ @id = arg
402
+ end
403
+
404
+ private
405
+
406
+ def init
407
+ @id = nil
408
+ end
409
+
410
+ def isempty?
411
+ not @id
412
+ end
413
+
414
+ def do_parse
415
+ @id = @body.slice(MESSAGE_ID) or
416
+ raise SyntaxError, "wrong Message-ID format: #{@body}"
417
+ end
418
+
419
+ def do_accept( strategy )
420
+ strategy.meta @id
421
+ end
422
+
423
+ end
424
+
425
+
426
+ class ReferencesHeader < StructuredHeader
427
+
428
+ def refs
429
+ ensure_parsed
430
+ @refs
431
+ end
432
+
433
+ def each_id
434
+ self.refs.each do |i|
435
+ yield i if MESSAGE_ID === i
436
+ end
437
+ end
438
+
439
+ def ids
440
+ ensure_parsed
441
+ @ids
442
+ end
443
+
444
+ def each_phrase
445
+ self.refs.each do |i|
446
+ yield i unless MESSAGE_ID === i
447
+ end
448
+ end
449
+
450
+ def phrases
451
+ ret = []
452
+ each_phrase {|i| ret.push i }
453
+ ret
454
+ end
455
+
456
+ private
457
+
458
+ def init
459
+ @refs = []
460
+ @ids = []
461
+ end
462
+
463
+ def isempty?
464
+ @ids.empty?
465
+ end
466
+
467
+ def do_parse
468
+ str = @body
469
+ while m = MESSAGE_ID.match(str)
470
+ pre = m.pre_match.strip
471
+ @refs.push pre unless pre.empty?
472
+ @refs.push s = m[0]
473
+ @ids.push s
474
+ str = m.post_match
475
+ end
476
+ str = str.strip
477
+ @refs.push str unless str.empty?
478
+ end
479
+
480
+ def do_accept( strategy )
481
+ first = true
482
+ @ids.each do |i|
483
+ if first
484
+ first = false
485
+ else
486
+ strategy.space
487
+ end
488
+ strategy.meta i
489
+ end
490
+ end
491
+
492
+ end
493
+
494
+
495
+ class ReceivedHeader < StructuredHeader
496
+
497
+ PARSE_TYPE = :RECEIVED
498
+
499
+ def from
500
+ ensure_parsed
501
+ @from
502
+ end
503
+
504
+ def from=( arg )
505
+ ensure_parsed
506
+ @from = arg
507
+ end
508
+
509
+ def by
510
+ ensure_parsed
511
+ @by
512
+ end
513
+
514
+ def by=( arg )
515
+ ensure_parsed
516
+ @by = arg
517
+ end
518
+
519
+ def via
520
+ ensure_parsed
521
+ @via
522
+ end
523
+
524
+ def via=( arg )
525
+ ensure_parsed
526
+ @via = arg
527
+ end
528
+
529
+ def with
530
+ ensure_parsed
531
+ @with
532
+ end
533
+
534
+ def id
535
+ ensure_parsed
536
+ @id
537
+ end
538
+
539
+ def id=( arg )
540
+ ensure_parsed
541
+ @id = arg
542
+ end
543
+
544
+ def _for
545
+ ensure_parsed
546
+ @_for
547
+ end
548
+
549
+ def _for=( arg )
550
+ ensure_parsed
551
+ @_for = arg
552
+ end
553
+
554
+ def date
555
+ ensure_parsed
556
+ @date
557
+ end
558
+
559
+ def date=( arg )
560
+ ensure_parsed
561
+ @date = arg
562
+ end
563
+
564
+ private
565
+
566
+ def init
567
+ @from = @by = @via = @with = @id = @_for = nil
568
+ @with = []
569
+ @date = nil
570
+ end
571
+
572
+ def set( args )
573
+ @from, @by, @via, @with, @id, @_for, @date = *args
574
+ end
575
+
576
+ def isempty?
577
+ @with.empty? and not (@from or @by or @via or @id or @_for or @date)
578
+ end
579
+
580
+ def do_accept( strategy )
581
+ list = []
582
+ list.push 'from ' + @from if @from
583
+ list.push 'by ' + @by if @by
584
+ list.push 'via ' + @via if @via
585
+ @with.each do |i|
586
+ list.push 'with ' + i
587
+ end
588
+ list.push 'id ' + @id if @id
589
+ list.push 'for <' + @_for + '>' if @_for
590
+
591
+ first = true
592
+ list.each do |i|
593
+ strategy.space unless first
594
+ strategy.meta i
595
+ first = false
596
+ end
597
+ if @date
598
+ strategy.meta ';'
599
+ strategy.space
600
+ strategy.meta time2str(@date)
601
+ end
602
+ end
603
+
604
+ end
605
+
606
+
607
+ class KeywordsHeader < StructuredHeader
608
+
609
+ PARSE_TYPE = :KEYWORDS
610
+
611
+ def keys
612
+ ensure_parsed
613
+ @keys
614
+ end
615
+
616
+ private
617
+
618
+ def init
619
+ @keys = []
620
+ end
621
+
622
+ def set( a )
623
+ @keys = a
624
+ end
625
+
626
+ def isempty?
627
+ @keys.empty?
628
+ end
629
+
630
+ def do_accept( strategy )
631
+ first = true
632
+ @keys.each do |i|
633
+ if first
634
+ first = false
635
+ else
636
+ strategy.meta ','
637
+ end
638
+ strategy.meta i
639
+ end
640
+ end
641
+
642
+ end
643
+
644
+
645
+ class EncryptedHeader < StructuredHeader
646
+
647
+ PARSE_TYPE = :ENCRYPTED
648
+
649
+ def encrypter
650
+ ensure_parsed
651
+ @encrypter
652
+ end
653
+
654
+ def encrypter=( arg )
655
+ ensure_parsed
656
+ @encrypter = arg
657
+ end
658
+
659
+ def keyword
660
+ ensure_parsed
661
+ @keyword
662
+ end
663
+
664
+ def keyword=( arg )
665
+ ensure_parsed
666
+ @keyword = arg
667
+ end
668
+
669
+ private
670
+
671
+ def init
672
+ @encrypter = nil
673
+ @keyword = nil
674
+ end
675
+
676
+ def set( args )
677
+ @encrypter, @keyword = args
678
+ end
679
+
680
+ def isempty?
681
+ not (@encrypter or @keyword)
682
+ end
683
+
684
+ def do_accept( strategy )
685
+ if @key
686
+ strategy.meta @encrypter + ','
687
+ strategy.space
688
+ strategy.meta @keyword
689
+ else
690
+ strategy.meta @encrypter
691
+ end
692
+ end
693
+
694
+ end
695
+
696
+
697
+ class MimeVersionHeader < StructuredHeader
698
+
699
+ PARSE_TYPE = :MIMEVERSION
700
+
701
+ def major
702
+ ensure_parsed
703
+ @major
704
+ end
705
+
706
+ def major=( arg )
707
+ ensure_parsed
708
+ @major = arg
709
+ end
710
+
711
+ def minor
712
+ ensure_parsed
713
+ @minor
714
+ end
715
+
716
+ def minor=( arg )
717
+ ensure_parsed
718
+ @minor = arg
719
+ end
720
+
721
+ def version
722
+ sprintf('%d.%d', major, minor)
723
+ end
724
+
725
+ private
726
+
727
+ def init
728
+ @major = nil
729
+ @minor = nil
730
+ end
731
+
732
+ def set( args )
733
+ @major, @minor = *args
734
+ end
735
+
736
+ def isempty?
737
+ not (@major or @minor)
738
+ end
739
+
740
+ def do_accept( strategy )
741
+ strategy.meta sprintf('%d.%d', @major, @minor)
742
+ end
743
+
744
+ end
745
+
746
+
747
+ class ContentTypeHeader < StructuredHeader
748
+
749
+ PARSE_TYPE = :CTYPE
750
+
751
+ def main_type
752
+ ensure_parsed
753
+ @main
754
+ end
755
+
756
+ def main_type=( arg )
757
+ ensure_parsed
758
+ @main = arg.downcase
759
+ end
760
+
761
+ def sub_type
762
+ ensure_parsed
763
+ @sub
764
+ end
765
+
766
+ def sub_type=( arg )
767
+ ensure_parsed
768
+ @sub = arg.downcase
769
+ end
770
+
771
+ def content_type
772
+ ensure_parsed
773
+ @sub ? sprintf('%s/%s', @main, @sub) : @main
774
+ end
775
+
776
+ def params
777
+ ensure_parsed
778
+ unless @params.blank?
779
+ @params.each do |k, v|
780
+ @params[k] = unquote(v)
781
+ end
782
+ end
783
+ @params
784
+ end
785
+
786
+ def []( key )
787
+ ensure_parsed
788
+ @params and unquote(@params[key])
789
+ end
790
+
791
+ def []=( key, val )
792
+ ensure_parsed
793
+ (@params ||= {})[key] = val
794
+ end
795
+
796
+ private
797
+
798
+ def init
799
+ @main = @sub = @params = nil
800
+ end
801
+
802
+ def set( args )
803
+ @main, @sub, @params = *args
804
+ end
805
+
806
+ def isempty?
807
+ not (@main or @sub)
808
+ end
809
+
810
+ def do_accept( strategy )
811
+ if @sub
812
+ strategy.meta sprintf('%s/%s', @main, @sub)
813
+ else
814
+ strategy.meta @main
815
+ end
816
+ @params.each do |k,v|
817
+ if v
818
+ strategy.meta ';'
819
+ strategy.space
820
+ strategy.kv_pair k, v
821
+ end
822
+ end
823
+ end
824
+
825
+ end
826
+
827
+
828
+ class ContentTransferEncodingHeader < StructuredHeader
829
+
830
+ PARSE_TYPE = :CENCODING
831
+
832
+ def encoding
833
+ ensure_parsed
834
+ @encoding
835
+ end
836
+
837
+ def encoding=( arg )
838
+ ensure_parsed
839
+ @encoding = arg
840
+ end
841
+
842
+ private
843
+
844
+ def init
845
+ @encoding = nil
846
+ end
847
+
848
+ def set( s )
849
+ @encoding = s
850
+ end
851
+
852
+ def isempty?
853
+ not @encoding
854
+ end
855
+
856
+ def do_accept( strategy )
857
+ strategy.meta @encoding.capitalize
858
+ end
859
+
860
+ end
861
+
862
+
863
+ class ContentDispositionHeader < StructuredHeader
864
+
865
+ PARSE_TYPE = :CDISPOSITION
866
+
867
+ def disposition
868
+ ensure_parsed
869
+ @disposition
870
+ end
871
+
872
+ def disposition=( str )
873
+ ensure_parsed
874
+ @disposition = str.downcase
875
+ end
876
+
877
+ def params
878
+ ensure_parsed
879
+ unless @params.blank?
880
+ @params.each do |k, v|
881
+ @params[k] = unquote(v)
882
+ end
883
+ end
884
+ @params
885
+ end
886
+
887
+ def []( key )
888
+ ensure_parsed
889
+ @params and unquote(@params[key])
890
+ end
891
+
892
+ def []=( key, val )
893
+ ensure_parsed
894
+ (@params ||= {})[key] = val
895
+ end
896
+
897
+ private
898
+
899
+ def init
900
+ @disposition = @params = nil
901
+ end
902
+
903
+ def set( args )
904
+ @disposition, @params = *args
905
+ end
906
+
907
+ def isempty?
908
+ not @disposition and (not @params or @params.empty?)
909
+ end
910
+
911
+ def do_accept( strategy )
912
+ strategy.meta @disposition
913
+ @params.each do |k,v|
914
+ strategy.meta ';'
915
+ strategy.space
916
+ strategy.kv_pair k, unquote(v)
917
+ end
918
+ end
919
+
920
+ end
921
+
922
+
923
+ class HeaderField # redefine
924
+
925
+ FNAME_TO_CLASS = {
926
+ 'date' => DateTimeHeader,
927
+ 'resent-date' => DateTimeHeader,
928
+ 'to' => AddressHeader,
929
+ 'cc' => AddressHeader,
930
+ 'bcc' => AddressHeader,
931
+ 'from' => AddressHeader,
932
+ 'reply-to' => AddressHeader,
933
+ 'resent-to' => AddressHeader,
934
+ 'resent-cc' => AddressHeader,
935
+ 'resent-bcc' => AddressHeader,
936
+ 'resent-from' => AddressHeader,
937
+ 'resent-reply-to' => AddressHeader,
938
+ 'sender' => SingleAddressHeader,
939
+ 'resent-sender' => SingleAddressHeader,
940
+ 'return-path' => ReturnPathHeader,
941
+ 'message-id' => MessageIdHeader,
942
+ 'resent-message-id' => MessageIdHeader,
943
+ 'in-reply-to' => ReferencesHeader,
944
+ 'received' => ReceivedHeader,
945
+ 'references' => ReferencesHeader,
946
+ 'keywords' => KeywordsHeader,
947
+ 'encrypted' => EncryptedHeader,
948
+ 'mime-version' => MimeVersionHeader,
949
+ 'content-type' => ContentTypeHeader,
950
+ 'content-transfer-encoding' => ContentTransferEncodingHeader,
951
+ 'content-disposition' => ContentDispositionHeader,
952
+ 'content-id' => MessageIdHeader,
953
+ 'subject' => UnstructuredHeader,
954
+ 'comments' => UnstructuredHeader,
955
+ 'content-description' => UnstructuredHeader
956
+ }
957
+
958
+ end
959
+
960
+ end # module TMail