mime 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/README.rdoc +192 -140
  2. data/lib/mime/composite_media.rb +230 -0
  3. data/lib/mime/content_formats/text_flowed.rb +6 -6
  4. data/lib/mime/discrete_media.rb +73 -0
  5. data/lib/mime/discrete_media_factory.rb +19 -13
  6. data/lib/mime/header.rb +48 -0
  7. data/lib/mime/headers/internet.rb +124 -27
  8. data/lib/mime/headers/mime.rb +38 -27
  9. data/lib/mime/mail.rb +51 -0
  10. data/lib/mime/media.rb +30 -0
  11. data/lib/mime/parser.rb +1 -1
  12. data/lib/mime.rb +27 -9
  13. data/test/scaffold/application.msg +2 -5
  14. data/test/scaffold/audio.msg +2 -5
  15. data/test/scaffold/image.msg +0 -0
  16. data/test/scaffold/multipart_alternative.msg +7 -7
  17. data/test/scaffold/multipart_alternative_related.msg +0 -0
  18. data/test/scaffold/multipart_form_data_file_and_text.msg +0 -0
  19. data/test/scaffold/multipart_form_data_mixed.msg +0 -0
  20. data/test/scaffold/multipart_form_data_text.msg +12 -12
  21. data/test/scaffold/multipart_mixed_inline_and_attachment.msg +0 -0
  22. data/test/scaffold/multipart_mixed_inline_and_attachment2.msg +0 -0
  23. data/test/scaffold/multipart_related.msg +0 -0
  24. data/test/scaffold/rfc822_composite.msg +0 -0
  25. data/test/scaffold/{plain_text_email.msg → rfc822_discrete.msg} +5 -5
  26. data/test/scaffold/text.msg +2 -5
  27. data/test/scaffold/video.msg +2 -5
  28. data/test/test_mime.rb +323 -150
  29. data/test/test_text_flowed.rb +1 -1
  30. metadata +13 -12
  31. data/lib/mime/composite_media_type.rb +0 -169
  32. data/lib/mime/discrete_media_type.rb +0 -78
  33. data/lib/mime/header_container.rb +0 -32
  34. data/lib/mime/media_type.rb +0 -51
  35. data/lib/mime/message.rb +0 -61
@@ -8,19 +8,19 @@ module MIME
8
8
 
9
9
  attr_reader(
10
10
  :mime_version,
11
- :content_description,
12
- :content_disposition,
13
- :content_id,
14
- :content_transfer_encoding,
15
- :content_type
11
+ :description,
12
+ :disposition,
13
+ :id,
14
+ :transfer_encoding,
15
+ :type
16
16
  )
17
17
 
18
18
  #
19
19
  # Describes the content, which can be useful for non-MIME clients.
20
20
  #
21
- def content_description= description
22
- @content_description = description
23
- headers.add('Content-Description', description)
21
+ def description= description
22
+ @description = description
23
+ headers.set('Content-Description', description)
24
24
  end
25
25
 
26
26
  #
@@ -30,18 +30,18 @@ module MIME
30
30
  #
31
31
  # RFC 2183 Communicating Presentation Information in Internet Messages.
32
32
  #
33
- def content_disposition= disposition
34
- @content_disposition = disposition
35
- headers.add('Content-Disposition', disposition)
33
+ def disposition= disposition
34
+ @disposition = disposition
35
+ headers.set('Content-Disposition', disposition)
36
36
  end
37
37
 
38
38
  #
39
39
  # Globally unique ID that identifies a top-level message or message
40
40
  # entity. Content IDs can be used for referencing or caching purposes.
41
41
  #
42
- def content_id= id
43
- @content_id = id
44
- headers.add('Content-ID', "<#{id}>")
42
+ def id= id
43
+ @id = id
44
+ headers.set('Content-ID', "<#{id}>")
45
45
  end
46
46
 
47
47
  #
@@ -54,9 +54,9 @@ module MIME
54
54
  # * quoted-printable
55
55
  # * base64
56
56
  #
57
- def content_transfer_encoding= encoding
58
- @content_transfer_encoding = encoding
59
- headers.add('Content-Transfer-Encoding', encoding)
57
+ def transfer_encoding= encoding
58
+ @transfer_encoding = encoding
59
+ headers.set('Content-Transfer-Encoding', encoding)
60
60
  end
61
61
 
62
62
  #
@@ -64,7 +64,7 @@ module MIME
64
64
  #
65
65
  def mime_version= version
66
66
  @mime_version = version
67
- headers.add('MIME-Version', version)
67
+ headers.set('MIME-Version', version)
68
68
  end
69
69
 
70
70
  protected
@@ -80,9 +80,9 @@ module MIME
80
80
  # * text/plain
81
81
  # * video/mpeg
82
82
  #
83
- def content_type= type
84
- @content_type = type
85
- headers.add('Content-Type', type)
83
+ def type= type
84
+ @type = type
85
+ headers.set('Content-Type', type)
86
86
  end
87
87
 
88
88
  #
@@ -97,20 +97,31 @@ module MIME
97
97
  #
98
98
  # The values for the *-date keys may use Time::rfc2822.
99
99
  #
100
- def set_content_disposition type, params = {}
101
- disposition = type
102
-
100
+ def set_disposition type, params = {}
103
101
  if params['filename']
104
102
  params['filename'] = File.basename(params['filename'])
105
103
  elsif self.respond_to?(:path)
106
104
  params['filename'] = File.basename(self.path)
107
105
  end
106
+ self.disposition = append_field_params(type, params)
107
+ end
108
+
109
+
110
+ private
108
111
 
112
+ #
113
+ # Append parameters to header field body.
114
+ # Used for Content-Type and Content-Disposition headers.
115
+ #
116
+ def append_field_params body, params = {}
109
117
  params.each do |name, value|
110
- disposition << %Q[; #{name}="#{value}"] if value
118
+ next unless value
119
+ unless value =~ Internet::DOT_ATOM
120
+ value = '"' + value.gsub('"','\"') + '"'
121
+ end
122
+ body << "; #{name}=#{value}"
111
123
  end
112
-
113
- self.content_disposition = disposition
124
+ body
114
125
  end
115
126
 
116
127
  end
data/lib/mime/mail.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'time'
2
+ require 'mime/headers/internet'
3
+
4
+ module MIME
5
+
6
+ #
7
+ # Construct RFC 2822 Internet messages.
8
+ #
9
+ class Mail
10
+
11
+ include Headers::Internet
12
+
13
+ attr_reader :headers, :body
14
+
15
+ #
16
+ # Initialize a Mail object with body set to +content+.
17
+ #
18
+ def initialize content = nil
19
+ @headers = Header.new
20
+ self.body = content
21
+ self.date = Time.now
22
+ end
23
+
24
+ #
25
+ # Format the Mail object as an Internet message.
26
+ #
27
+ def to_s
28
+ self.message_id ||= ID.generate_gid(domain)
29
+ body.mime_version ||= "1.0 (Ruby MIME v#{VERSION})"
30
+
31
+ #--
32
+ # In an RFC 2822 message, the header and body sections must be separated
33
+ # by two line breaks (i.e., 2*CRLF). One line break is deliberately
34
+ # omitted here to allowing the body supplier to append headers to the
35
+ # top-level message header section.
36
+ #++
37
+ "#{headers}\r\n#{body}"
38
+ end
39
+
40
+ def body= content
41
+ @body = content.is_a?(Media) ? content : Text.new(content.to_s)
42
+ end
43
+
44
+ private
45
+
46
+ def domain
47
+ headers.get('from').match(/@([[:alnum:].-]+)/)[1] rescue nil
48
+ end
49
+
50
+ end
51
+ end
data/lib/mime/media.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'mime/headers/mime'
2
+
3
+ module MIME
4
+
5
+ #
6
+ # Abstract top-level media class.
7
+ #
8
+ class Media
9
+
10
+ include Headers::MIME
11
+
12
+ attr_reader :headers, :body
13
+
14
+ def initialize content, content_type, content_params = {}
15
+ AbstractClassError.no_instantiation(self, Media)
16
+ @headers = Header.new
17
+ @body = content
18
+ self.id = ID.generate_gid
19
+ self.type = append_field_params(content_type, content_params)
20
+ end
21
+
22
+ #
23
+ # Format the Media object as a MIME message.
24
+ #
25
+ def to_s
26
+ "#{headers}\r\n\r\n#{body}"
27
+ end
28
+
29
+ end
30
+ end
data/lib/mime/parser.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module MIME
2
2
 
3
3
  #
4
- # Parse MIME messages, constructing MediaType objects for each MIME entity.
4
+ # Parse MIME messages, constructing Media objects for each MIME entity.
5
5
  #
6
6
  # TODO Implement
7
7
  #
data/lib/mime.rb CHANGED
@@ -18,20 +18,38 @@
18
18
  #
19
19
  module MIME
20
20
 
21
- VERSION = '0.3.0'
21
+ VERSION = '0.4.0'
22
22
 
23
- module ContentFormats
24
- MAX_SMTP_LINE = 997
23
+ # Defined in RFC: https://tools.ietf.org/html/rfc5322#section-2.1.1
24
+ MAX_LINE_LENGTH = 998
25
+
26
+ module ID
27
+ #
28
+ # Generate local ID.
29
+ #
30
+ def self.generate_id
31
+ timestamp = (Time.now.to_f * 1E7).to_i
32
+ rand(1E9).to_s(36) +
33
+ object_id.to_s(36) +
34
+ timestamp.to_s(36)
35
+ end
36
+
37
+ #
38
+ # Generate global ID for "Message-ID" or "Content-ID" header.
39
+ #
40
+ def self.generate_gid domain = nil
41
+ generate_id + "@" + (domain || "#{generate_id}.local")
42
+ end
25
43
  end
26
44
 
27
45
  end
28
46
 
29
47
  require 'mime/content_types'
48
+ require 'mime/content_formats/text_flowed'
30
49
  require 'mime/error'
31
- require 'mime/header_container'
32
- require 'mime/media_type'
33
- require 'mime/discrete_media_type'
34
- require 'mime/composite_media_type'
35
- require 'mime/message'
50
+ require 'mime/header'
51
+ require 'mime/media'
52
+ require 'mime/composite_media'
53
+ require 'mime/discrete_media'
36
54
  require 'mime/discrete_media_factory'
37
- require 'mime/content_formats/text_flowed'
55
+ require 'mime/mail'
@@ -1,8 +1,5 @@
1
- Date: Wed, 29 Oct 2008 22:02:00 -0700
2
- Message-ID: <350015069@1033007998>
3
- MIME-Version: 1.0 (Ruby MIME v0.2.0)
4
- Content-ID: <10330079680.971971651113797>
1
+ Content-ID: <10330079680@971971651113797>
5
2
  Content-Type: application/octet-stream
6
3
  Content-Transfer-Encoding: binary
7
4
 
8
- 0110000101110101011001000110100101101111
5
+ 0110000101110101011001000110100101101111
@@ -1,8 +1,5 @@
1
- Date: Wed, 29 Oct 2008 22:06:46 -0700
2
- Message-ID: <738362674@978907908>
3
- MIME-Version: 1.0 (Ruby MIME v0.2.0)
4
- Content-ID: <9789078880.11546613041526>
1
+ Content-ID: <9789078880@11546613041526>
5
2
  Content-Type: audio/midi
6
3
  Content-Transfer-Encoding: binary
7
4
 
8
- 0110000101110101011001000110100101101111
5
+ 0110000101110101011001000110100101101111
Binary file
@@ -1,15 +1,15 @@
1
- Content-ID: <154873488180000.3045551269054866>
2
- Content-Type: multipart/alternative; boundary=Boundary_154873488180000.5284747660488839
1
+ Content-ID: <154873488180000@3045551269054866>
2
+ Content-Type: multipart/alternative; boundary=Boundary_154873488180000
3
3
 
4
- --Boundary_154873488180000.5284747660488839
5
- Content-ID: <154873488189000.6392244491224042>
4
+ --Boundary_154873488180000
5
+ Content-ID: <154873488189000@6392244491224042>
6
6
  Content-Type: text/enhanced; charset=us-ascii
7
7
 
8
8
  *Header*
9
9
  message
10
- --Boundary_154873488180000.5284747660488839
11
- Content-ID: <154873488185800.3424043482513621>
10
+ --Boundary_154873488180000
11
+ Content-ID: <154873488185800@3424043482513621>
12
12
  Content-Type: text/html; charset=iso-8859-1
13
13
 
14
14
  <html><body><h1>Header</h1><p>message</p></body></html>
15
- --Boundary_154873488180000.5284747660488839--
15
+ --Boundary_154873488180000--
@@ -1,10 +1,10 @@
1
- Content-ID: <88135231713600.7894413004791365>
2
- Content-Type: multipart/form-data; boundary=Boundary_88135231713600.3996846921776409
1
+ Content-ID: <88135231713600@7894413004791365>
2
+ Content-Type: multipart/form-data; boundary=Boundary_88135231713600
3
3
 
4
- --Boundary_88135231713600.3996846921776409
5
- Content-ID: <88135231717000.5720607746781624>
4
+ --Boundary_88135231713600
5
+ Content-ID: <88135231717000@5720607746781624>
6
6
  Content-Type: text/xml
7
- Content-Disposition: form-data; name="xml"
7
+ Content-Disposition: form-data; name=xml
8
8
 
9
9
  <media_types abstract="true">
10
10
  <discrete_media_types abstract="true">
@@ -24,10 +24,10 @@ Content-Disposition: form-data; name="xml"
24
24
  </composite>
25
25
  </media_types>
26
26
 
27
- --Boundary_88135231713600.3996846921776409
28
- Content-ID: <88135231721400.4415016053712104>
27
+ --Boundary_88135231713600
28
+ Content-ID: <88135231721400@4415016053712104>
29
29
  Content-Type: text/html
30
- Content-Disposition: form-data; name="htm"
30
+ Content-Disposition: form-data; name=htm
31
31
 
32
32
  <html>
33
33
  <body>
@@ -36,10 +36,10 @@ Content-Disposition: form-data; name="htm"
36
36
  </body>
37
37
  </html>
38
38
 
39
- --Boundary_88135231713600.3996846921776409
40
- Content-ID: <88135231725400.11623307734175536>
39
+ --Boundary_88135231713600
40
+ Content-ID: <88135231725400@11623307734175536>
41
41
  Content-Type: text/plain
42
- Content-Disposition: form-data; name="txt"
42
+ Content-Disposition: form-data; name=txt
43
43
 
44
44
  text body
45
- --Boundary_88135231713600.3996846921776409--
45
+ --Boundary_88135231713600--
Binary file
Binary file
@@ -1,11 +1,11 @@
1
1
  Date: Tue, 17 Dec 2013 04:54:56 -0700
2
- Message-ID: <776432154@10297424291820>
3
- MIME-Version: 1.0 (Ruby MIME v0.0.0)
4
2
  To: John <john@example.com>, paul@example.com, Mary <mary@example.com>
5
- Cc: boss@example.com <Head Honcho>
3
+ Cc: Head Honcho <boss@example.com>
6
4
  From: jane@example.com
7
5
  Subject: This is an important email
8
- Content-ID: <102975158103800.7998663631497803>
6
+ Message-ID: <776432154@10297424291820>
7
+ Content-ID: <102975158103800@7998663631497803>
9
8
  Content-Type: text/plain
9
+ MIME-Version: 1.0 (Ruby MIME v0.0.0)
10
10
 
11
- Hello, world!
11
+ Hello, world!
@@ -1,7 +1,4 @@
1
- Date: Wed, 29 Oct 2008 14:55:34 -0700
2
- Message-ID: <357114433@1021851988>
3
- MIME-Version: 1.0 (Ruby MIME v0.1.0)
4
- Content-ID: <10218519780.0838656876757202>
1
+ Content-ID: <10218519780@0838656876757202>
5
2
  Content-Type: text/plain
6
3
 
7
- a plain text message
4
+ a plain text message
@@ -1,8 +1,5 @@
1
- Date: Wed, 29 Oct 2008 21:56:48 -0700
2
- Message-ID: <740518531@1061166128>
3
- MIME-Version: 1.0 (Ruby MIME v0.1.0)
4
- Content-ID: <10611659780.38729886896997>
1
+ Content-ID: <10611659780@38729886896997>
5
2
  Content-Type: video/mpeg
6
3
  Content-Transfer-Encoding: binary
7
4
 
8
- 0110000101110101011001000110100101101111
5
+ 0110000101110101011001000110100101101111