rmail 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6b4a29f4260f329ca644299cc81203d2db1f7785
4
+ data.tar.gz: caa1c6f095e88be1d91c9c694b0a0debde71edb8
5
+ SHA512:
6
+ metadata.gz: 432fb864d8aad5282d9e987870fa0996cf2e6d2f4e96c7a5cf865bc048900dcb0d77439c55c00e77694caaa64943ad486dcdf7fba97b6c2406e20f05de5b9360
7
+ data.tar.gz: 79f14439893e809897523cfa6cf7b39519b72ad67b0a885041d49ca3b4e7bc6d7f87b7bac84c72835d948cf956f01b590dbb6a0ba4f21ca15ae3ca570dc81cd3
@@ -1,3 +1,17 @@
1
+ = Changes in RubyMail 1.1.0 (released 2015-02-10)
2
+
3
+ - This version contains fixes for running on Ruby 2.0+ that were contributed by
4
+ Josef Stribny, plus 7 patches that have accumulated in the Debian package of
5
+ rmail over the years by Adeodato Simó, Per Andersson, and Antonio Terceiro.
6
+ There are also a few fixes by the original author Matt Armstrong that never
7
+ made it into a release.
8
+ - This version is mostly compatible with 1.0.0, but since it wasn't explicitly
9
+ tested on older RUby releases we bumping the minor version as a warning to
10
+ users.
11
+ - Rakefile was updated to actually run on modern Ruby versions
12
+ - The tests were fixed for Ruby 2.0+ compatibility
13
+ - The version number was moved to lib/rmail/version.rb
14
+
1
15
  = Changes in RubyMail 1.0.0 (released 2008-01-05)
2
16
 
3
17
  - This version differs *only* in the changes required for Ruby 1.9
data/Rakefile CHANGED
@@ -4,12 +4,8 @@
4
4
  # This is a Ruby file, used by the "rake" make-like program.
5
5
  #
6
6
 
7
- begin
8
- # First, we use a few ruby things...
9
- require 'rubygems'
10
- require 'rake/gempackagetask'
11
- end
12
- require 'rake/rdoctask'
7
+ require 'rubygems/package_task'
8
+ require 'rdoc/task'
13
9
  require 'rake/testtask'
14
10
  require 'shellwords'
15
11
 
@@ -23,7 +19,7 @@ task :default => :test
23
19
  # Test tasks
24
20
  #
25
21
  Rake::TestTask.new do |t|
26
- t.libs << 'test'
22
+ t.libs << '.'
27
23
  t.pattern = 'test/test*.rb'
28
24
  t.verbose = true
29
25
  end
@@ -38,7 +34,7 @@ def can_release_package
38
34
  reasons = []
39
35
 
40
36
  unless news_is_current
41
- reasons << 'the NEWS file is not current'
37
+ reasons << 'the ChangeLog file is not current'
42
38
  end
43
39
 
44
40
  unless defined?(Gem)
@@ -67,11 +63,11 @@ def can_release_package
67
63
  can_release_package
68
64
  end
69
65
 
70
- # Is the NEWS file current?
66
+ # Is ChangeLog current?
71
67
  def news_is_current
72
68
  today = Time.now.strftime('%Y-%m-%d')
73
69
  version = Regexp.new(Regexp.quote(PKG_VERSION))
74
- if IO.readlines('NEWS').first =~
70
+ if IO.readlines('ChangeLog').first =~
75
71
  /= Changes in RubyMail #{PKG_VERSION} \(released #{today}\)$/
76
72
  true
77
73
  else
@@ -83,34 +79,25 @@ end
83
79
  #
84
80
  # These PKG_ variables are used by Rake's package rule.
85
81
  #
86
- PKG_VERSION = begin
87
- version= IO.readlines('version').first.chomp
88
- if version =~ /^\d+\.\d+\.\d+$/
89
- version.untaint
90
- else
91
- fail "package version is bogus"
92
- end
93
- version
94
- end
82
+ require './lib/rmail/version.rb'
83
+ PKG_VERSION = RMail::VERSION
95
84
 
96
85
  PKG_FILES = FileList.new('test/**/*',
97
86
  'guide/**/*',
98
87
  'lib/**/*',
99
- 'install.rb',
100
- 'NEWS',
88
+ 'ChangeLog',
101
89
  'NOTES',
102
90
  'README',
103
91
  'THANKS',
104
92
  'TODO',
105
- 'Rakefile',
106
- 'version')
93
+ 'Rakefile')
107
94
 
108
95
  #
109
96
  # Teach Rake how to build the RDoc documentation for this package.
110
97
  #
111
98
  rdoc = Rake::RDocTask.new do |rdoc|
112
99
  rdoc.main = 'README'
113
- rdoc.rdoc_files.include("README", "NEWS", "THANKS",
100
+ rdoc.rdoc_files.include("README", "ChangeLog", "THANKS",
114
101
  "TODO", "guide/*.txt", "lib/**/*.rb")
115
102
  rdoc.rdoc_files.exclude(/\bSCCS\b/,
116
103
  "lib/rubymail/parser/*")
@@ -136,51 +123,49 @@ end
136
123
  #
137
124
  # Create a Gem::Specification right in the Rakefile, using some of the
138
125
  # variables we have set up above.
139
- #
140
- if defined?(Gem)
141
- spec = Gem::Specification.new do |s|
142
- s.name = 'rmail'
143
- s.version = PKG_VERSION + if can_release_package
144
- ''
145
- else
146
- '.666'
147
- end
148
- s.summary = 'A MIME mail parsing and generation library.'
149
- s.description = <<-EOF
150
- RMail is a lightweight mail library containing various utility classes and
151
- modules that allow ruby scripts to parse, modify, and generate MIME mail
152
- messages.
153
- EOF
154
-
155
- s.files = PKG_FILES.to_a
156
-
157
- s.required_ruby_version = Gem::Version::Requirement.new(">= 1.8.1")
158
-
159
- s.has_rdoc = true
160
- s.extra_rdoc_files = rdoc.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
161
- s.rdoc_options.concat([ '--title', rdoc.title, '--main', rdoc.main,
162
- rdoc.options ].flatten)
163
-
164
- s.test_files = FileList['test/tc_*.rb'].to_a
165
-
166
- s.author = "Matt Armstrong"
167
- s.email = "matt@rfc20.org"
168
- s.homepage = "http://www.rfc20.org/rubymail"
169
-
170
- s.rubyforge_project = "rubymail"
171
- end
126
+ spec = Gem::Specification.new do |s|
127
+ s.name = 'rmail'
128
+ s.version = PKG_VERSION + if can_release_package
129
+ ''
130
+ else
131
+ '.666'
132
+ end
133
+ s.summary = 'A MIME mail parsing and generation library.'
134
+ s.description = <<-EOF
135
+ RMail is a lightweight mail library containing various utility classes and
136
+ modules that allow ruby scripts to parse, modify, and generate MIME mail
137
+ messages.
138
+ EOF
139
+
140
+ s.files = PKG_FILES.to_a
141
+
142
+ s.required_ruby_version = Gem::Version::Requirement.new(">= 1.8.1")
143
+
144
+ s.has_rdoc = true
145
+ s.extra_rdoc_files = rdoc.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
146
+ s.rdoc_options.concat([ '--title', rdoc.title, '--main', rdoc.main,
147
+ rdoc.options ].flatten)
148
+
149
+ s.test_files = FileList['test/tc_*.rb'].to_a
150
+
151
+ s.author = ["Matt Armstrong", "Antonio Terceiro"]
152
+ s.email = "terceiro@softwarelivre.org"
153
+ s.homepage = "https://github.com/terceiro/rmail"
154
+ end
172
155
 
173
- #
174
- # Use our Gem::Specification to make some package tasks.
175
- #
176
- Rake::GemPackageTask.new(spec) do |pkg|
177
- pkg.need_zip = true
178
- pkg.need_tar = true
179
- end
156
+ #
157
+ # Use our Gem::Specification to make some package tasks.
158
+ #
159
+ Gem::PackageTask.new(spec) do |pkg|
160
+ pkg.need_zip = true
161
+ pkg.need_tar = true
180
162
  end
181
163
 
182
- desc "Install RubyMail using the standard install.rb script"
183
- task :install do
184
- ruby "install.rb"
164
+ desc 'Makes a release'
165
+ task :release => [:test, :package] do
166
+ sh 'git', 'tag', '-s', "v#{PKG_VERSION}"
167
+ sh 'git', 'push'
168
+ sh 'git', 'push', '--tags'
169
+ sh 'gem' 'push', 'pkg/#{rmail}-#{PKG_VERSION}.gem'
185
170
  end
186
171
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (C) 2001, 2002, 2003 Matt Armstrong. All rights
2
+ # Copyright (C) 2001, 2002, 2003, 2008 Matt Armstrong. All rights
3
3
  # reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without
@@ -50,7 +50,6 @@ module RMail
50
50
  # is parsed for mail addresses and if one is found, it is used to
51
51
  # initialize this object.
52
52
  def initialize(string = nil)
53
-
54
53
  @local = @domain = @comments = @display_name = nil
55
54
 
56
55
  if string.kind_of?(String)
@@ -421,7 +420,6 @@ module RMail
421
420
  # local-part ':' -> it is a display-name of a group
422
421
  # display-name '<' -> it is a mailbox display name
423
422
  # display-name ':' -> it is a group display name
424
- #
425
423
 
426
424
  # set lookahead to '@' '<' or ':' (or another value for
427
425
  # invalid input)
@@ -472,6 +470,20 @@ module RMail
472
470
  @addresses.last.local = get_text
473
471
  expect(SYM_AT_SIGN)
474
472
  domain
473
+
474
+ if @sym == SYM_LESS_THAN
475
+ # Workaround for invalid input. Treat 'foo@bar <foo@bar>' as if it
476
+ # were '"foo@bar" <foo@bar>'. The domain parser will eat
477
+ # 'bar' but stop at '<'. At this point, we've been
478
+ # parsing the display name as if it were an address, so we
479
+ # throw the address into display_name and parse an
480
+ # angle_addr.
481
+ @addresses.last.display_name =
482
+ format("%s@%s", @addresses.last.local, @addresses.last.domain)
483
+ @addresses.last.local = nil
484
+ @addresses.last.domain = nil
485
+ angle_addr
486
+ end
475
487
  end
476
488
  end
477
489
 
@@ -691,7 +703,7 @@ module RMail
691
703
  @sym = SYM_DOMAIN_LITERAL
692
704
  @lexeme = $1.gsub(/(^|[^\\])[\r\n\t ]+/, '\1').gsub(/\\(.)/, '\1')
693
705
  break
694
- when /\A[\200-\377\w!$%&\'*+\/=?^_\`{\}|~#-]+/m
706
+ when /\A[\200-\377\w!$%&\'*+\/=?^_\`{\}|~#-]+/nm
695
707
  # This is just like SYM_ATOM, but includes all characters
696
708
  # with high bits. This is so we can allow such tokens in
697
709
  # the display name portion of an address even though it
@@ -73,7 +73,7 @@ module RMail
73
73
 
74
74
  class Field # :nodoc:
75
75
  # fixme, document methadology for this (RFC2822)
76
- EXTRACT_FIELD_NAME_RE = /\A([^\x00-\x1f\x7f-\xff :]+):\s*/o
76
+ EXTRACT_FIELD_NAME_RE = /\A([^\x00-\x1f\x7f-\xff :]+):\s*/no
77
77
 
78
78
  class << self
79
79
  def parse(field)
@@ -630,7 +630,7 @@ module RMail
630
630
  # Set the boundary parameter of this message's Content-Type:
631
631
  # field.
632
632
  def set_boundary(boundary)
633
- params = params_quoted('content-type')
633
+ params = params('content-type')
634
634
  params ||= {}
635
635
  params['boundary'] = boundary
636
636
  content_type = content_type()
@@ -213,15 +213,17 @@ module RMail
213
213
  # headers. The body part starts directly after this
214
214
  # newline.
215
215
  rest = data[1..-1]
216
+ elsif data[0] == ?\r && data[1] == ?\n
217
+ rest = data[2..-1]
216
218
  else
217
- header, rest = data.split(/\n\n/, 2)
219
+ header, rest = data.split(/\r?\n\r?\n/, 2)
218
220
  end
219
221
  break if rest
220
222
  end
221
223
  input.pushback(rest)
222
224
  if header
223
225
  mime = false
224
- fields = header.split(/\n(?!\s)/)
226
+ fields = header.split(/\r?\n(?!\s)/)
225
227
  if fields.first =~ /^From /
226
228
  @handler.mbox_from(fields.first)
227
229
  fields.shift
@@ -0,0 +1,3 @@
1
+ module RMail
2
+ VERSION = '1.1.0'
3
+ end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #--
3
- # Copyright (C) 2001, 2002, 2003, 2007 Matt Armstrong. All rights reserved.
3
+ # Copyright (C) 2001, 2002, 2003, 2007, 2008 Matt Armstrong. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without
6
6
  # modification, are permitted provided that the following conditions are met:
@@ -419,7 +419,7 @@ class TestRMailAddress < TestBase
419
419
  :format => '"Jason @ Tibbitts" <tibbs@uh.edu>' } ] ]
420
420
 
421
421
  # Majordomo II parses all of these with an error. We have deleted
422
- # some of the tests since when they are actually legal.
422
+ # some of the tests when they are actually legal.
423
423
  validate_case ['tibbs@uh.edu Jason Tibbitts', [] ]
424
424
  validate_case ['@uh.edu', [] ] # Can't start with @
425
425
  validate_case ['J <tibbs>', [] ] # Not FQDN
@@ -644,7 +644,6 @@ class TestRMailAddress < TestBase
644
644
  end
645
645
 
646
646
  def test_rfc_822
647
-
648
647
  validate_case\
649
648
  ['":sysmail"@ Some-Group. Some-Org, Muhammed.(I am the greatest) Ali @(the)Vegas.WBA',
650
649
  [ { :name => nil,
@@ -664,7 +663,6 @@ class TestRMailAddress < TestBase
664
663
  end
665
664
 
666
665
  def test_misc_addresses()
667
-
668
666
  # Make sure that parsing empty stuff works
669
667
  assert_equal([], RMail::Address.parse(nil))
670
668
  assert_equal([], RMail::Address.parse(""))
@@ -794,17 +792,31 @@ class TestRMailAddress < TestBase
794
792
  } ] ]
795
793
  end
796
794
 
795
+ def test_bug_23043
796
+ # http://rubyforge.org/tracker/?func=detail&atid=1754&aid=23043&group_id=446
797
+ validate_case\
798
+ ['=?iso-8859-1?Q?acme@example.com?= <acme@example.com>',
799
+ [ { :name => '=?iso-8859-1?Q?acme@example.com?=',
800
+ :display_name => '=?iso-8859-1?Q?acme@example.com?=',
801
+ :address => 'acme@example.com',
802
+ :comments => nil,
803
+ :domain => 'example.com',
804
+ :local => 'acme',
805
+ :format => '"=?iso-8859-1?Q?acme@example.com?=" <acme@example.com>',
806
+ } ] ]
807
+ end
808
+
797
809
  def test_invalid_addresses()
798
810
  # The display name isn't encoded -- bad, but we parse it.
799
811
  validate_case\
800
- ["\322\315\322 \312\353\363\341 <bar@foo.invalid>",
801
- [ { :name => "\322\315\322 \312\353\363\341",
802
- :display_name => "\322\315\322 \312\353\363\341",
812
+ ["\322\315\322 \312\353\363\341 <bar@foo.invalid>".force_encoding('ASCII-8BIT'),
813
+ [ { :name => "\322\315\322 \312\353\363\341".force_encoding("ASCII-8BIT"),
814
+ :display_name => "\322\315\322 \312\353\363\341".force_encoding("ASCII-8BIT"),
803
815
  :address => 'bar@foo.invalid',
804
816
  :comments => nil,
805
817
  :domain => 'foo.invalid',
806
818
  :local => 'bar',
807
- :format => "\"\322\315\322 \312\353\363\341\" <bar@foo.invalid>",
819
+ :format => "\"\322\315\322 \312\353\363\341\" <bar@foo.invalid>".force_encoding("ASCII-8BIT"),
808
820
  } ] ]
809
821
  end
810
822
 
@@ -39,7 +39,7 @@ rescue LoadError
39
39
  end
40
40
 
41
41
  class TestBase < Test::Unit::TestCase
42
- include Config
42
+ include RbConfig
43
43
 
44
44
  attr_reader :scratch_dir
45
45
 
@@ -209,7 +209,12 @@ class TestRMailHeader < TestBase
209
209
  # Test the params argument
210
210
  h = RMail::Header.new
211
211
  h.add("name", "value", nil, 'param1' => 'value1', 'param2' => '+value2')
212
- assert_equal('value; param1=value1; param2="+value2"', h['name'])
212
+ # Param order can not be guaranteed since they are given as dict to the
213
+ # function.
214
+ #assert_equal('value; param1=value1; param2="+value2"', h['name'])
215
+ header_check = (h['name'] == 'value; param1=value1; param2="+value2"' or
216
+ h['name'] == 'value; param2="+value2"; param1=value1')
217
+ assert(header_check)
213
218
 
214
219
  h = RMail::Header.new
215
220
  h.add_raw("MIME-Version: 1.0")
@@ -141,7 +141,7 @@ Second body line
141
141
  def test_decode
142
142
  message = RMail::Message.new
143
143
 
144
- all_bytes = ''
144
+ all_bytes = ''.force_encoding('ASCII-8BIT')
145
145
  0.upto(255) do |i|
146
146
  all_bytes << i
147
147
  end
metadata CHANGED
@@ -1,38 +1,56 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rmail
3
- version: !ruby/object:Gem::Version
4
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Matt Armstrong
8
+ - Antonio Terceiro
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2008-01-05 00:00:00 -08:00
13
- default_executable:
12
+ date: 2015-02-11 00:00:00.000000000 Z
14
13
  dependencies: []
15
-
16
- description: RMail is a lightweight mail library containing various utility classes and modules that allow ruby scripts to parse, modify, and generate MIME mail messages.
17
- email: matt@rfc20.org
14
+ description: |2
15
+ RMail is a lightweight mail library containing various utility classes and
16
+ modules that allow ruby scripts to parse, modify, and generate MIME mail
17
+ messages.
18
+ email: terceiro@softwarelivre.org
18
19
  executables: []
19
-
20
20
  extensions: []
21
-
22
- extra_rdoc_files:
21
+ extra_rdoc_files:
23
22
  - README
24
- - NEWS
23
+ - ChangeLog
25
24
  - THANKS
26
25
  - TODO
27
26
  - guide/Intro.txt
28
27
  - guide/MIME.txt
29
28
  - guide/TableOfContents.txt
30
- files:
29
+ files:
30
+ - ChangeLog
31
+ - NOTES
32
+ - README
33
+ - Rakefile
34
+ - THANKS
35
+ - TODO
36
+ - guide/Intro.txt
37
+ - guide/MIME.txt
38
+ - guide/TableOfContents.txt
39
+ - lib/rmail.rb
40
+ - lib/rmail/address.rb
41
+ - lib/rmail/header.rb
42
+ - lib/rmail/mailbox.rb
43
+ - lib/rmail/mailbox/mboxreader.rb
44
+ - lib/rmail/message.rb
45
+ - lib/rmail/parser.rb
46
+ - lib/rmail/parser/multipart.rb
47
+ - lib/rmail/parser/pushbackreader.rb
48
+ - lib/rmail/serialize.rb
49
+ - lib/rmail/utils.rb
50
+ - lib/rmail/version.rb
31
51
  - test/addrgrammar.txt
32
- - test/data
33
52
  - test/data/mbox.odd
34
53
  - test/data/mbox.simple
35
- - test/data/multipart
36
54
  - test/data/multipart/data.1
37
55
  - test/data/multipart/data.10
38
56
  - test/data/multipart/data.11
@@ -50,7 +68,14 @@ files:
50
68
  - test/data/multipart/data.7
51
69
  - test/data/multipart/data.8
52
70
  - test/data/multipart/data.9
53
- - test/data/parser
71
+ - test/data/parser.badmime1
72
+ - test/data/parser.badmime2
73
+ - test/data/parser.nested-multipart
74
+ - test/data/parser.nested-simple
75
+ - test/data/parser.nested-simple2
76
+ - test/data/parser.nested-simple3
77
+ - test/data/parser.rfc822
78
+ - test/data/parser.simple-mime
54
79
  - test/data/parser/multipart.1
55
80
  - test/data/parser/multipart.10
56
81
  - test/data/parser/multipart.11
@@ -67,15 +92,6 @@ files:
67
92
  - test/data/parser/multipart.7
68
93
  - test/data/parser/multipart.8
69
94
  - test/data/parser/multipart.9
70
- - test/data/parser.badmime1
71
- - test/data/parser.badmime2
72
- - test/data/parser.nested-multipart
73
- - test/data/parser.nested-simple
74
- - test/data/parser.nested-simple2
75
- - test/data/parser.nested-simple3
76
- - test/data/parser.rfc822
77
- - test/data/parser.simple-mime
78
- - test/data/transparency
79
95
  - test/data/transparency/absolute.1
80
96
  - test/data/transparency/absolute.2
81
97
  - test/data/transparency/absolute.3
@@ -101,61 +117,33 @@ files:
101
117
  - test/testserialize.rb
102
118
  - test/testtestbase.rb
103
119
  - test/testtranspparency.rb
104
- - guide/Intro.txt
105
- - guide/MIME.txt
106
- - guide/TableOfContents.txt
107
- - lib/rmail
108
- - lib/rmail/address.rb
109
- - lib/rmail/header.rb
110
- - lib/rmail/mailbox
111
- - lib/rmail/mailbox/mboxreader.rb
112
- - lib/rmail/mailbox.rb
113
- - lib/rmail/message.rb
114
- - lib/rmail/parser
115
- - lib/rmail/parser/multipart.rb
116
- - lib/rmail/parser/pushbackreader.rb
117
- - lib/rmail/parser.rb
118
- - lib/rmail/serialize.rb
119
- - lib/rmail/utils.rb
120
- - lib/rmail.rb
121
- - install.rb
122
- - NEWS
123
- - NOTES
124
- - README
125
- - THANKS
126
- - TODO
127
- - Rakefile
128
- - version
129
- has_rdoc: true
130
- homepage: http://www.rfc20.org/rubymail
120
+ homepage: https://github.com/terceiro/rmail
121
+ licenses: []
122
+ metadata: {}
131
123
  post_install_message:
132
- rdoc_options:
133
- - --title
134
- - RubyMail Documentation (version 1.0.0)
135
- - --main
124
+ rdoc_options:
125
+ - "--title"
126
+ - RubyMail Documentation (version 1.1.0)
127
+ - "--main"
136
128
  - README
137
- - --exclude
129
+ - "--exclude"
138
130
  - SCCS
139
- require_paths:
131
+ require_paths:
140
132
  - lib
141
- required_ruby_version: !ruby/object:Gem::Requirement
142
- requirements:
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
143
135
  - - ">="
144
- - !ruby/object:Gem::Version
136
+ - !ruby/object:Gem::Version
145
137
  version: 1.8.1
146
- version:
147
- required_rubygems_version: !ruby/object:Gem::Requirement
148
- requirements:
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
149
140
  - - ">="
150
- - !ruby/object:Gem::Version
151
- version: "0"
152
- version:
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
153
143
  requirements: []
154
-
155
- rubyforge_project: rubymail
156
- rubygems_version: 1.0.1
144
+ rubyforge_project:
145
+ rubygems_version: 2.2.2
157
146
  signing_key:
158
- specification_version: 2
147
+ specification_version: 4
159
148
  summary: A MIME mail parsing and generation library.
160
149
  test_files: []
161
-