gurgitate-mail 1.10.0 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,30 +1,56 @@
1
- #!/opt/bin/ruby -w
2
-
3
- #------------------------------------------------------------------------
4
- # Handles a complete mail message
5
- #------------------------------------------------------------------------
1
+ # Contains the class Gurgitate::Mailmessage, used to handle the parsing
2
+ # of existing messages and the creation of new messages.
6
3
 
7
4
  require 'gurgitate/headers'
5
+ require 'gurgitate/message'
8
6
 
9
7
  module Gurgitate
10
8
 
11
- # A complete mail message.
12
- class Mailmessage
9
+ # A complete mail message. This is the base class for
10
+ # gurgitate-mail itself: if you want to use gurgitate-mail to create
11
+ # new messages, this is what you want to use.
12
+ class Mailmessage < Message
13
13
 
14
14
  Fromregex=/([^ ]+@[^ ]+) \(.*\)|[^<][<](.*@.*)[>]|([^ ]+@[^ ]+)/;
15
15
 
16
- # The headers of the message
17
- attr_reader :headers
18
- # The body of the message
19
- attr_accessor :body
20
-
21
16
  # The envelope sender and recipient, if anyone thought to
22
17
  # mention them to us.
23
18
  attr_accessor :sender
24
19
  attr_accessor :recipient
25
20
 
26
- # Creates a new mail message with headers built from the options hash,
27
- # and the body of the message in a string.
21
+ # Creates a new mail message from the options hash, and the body of the
22
+ # message in a string.
23
+ #
24
+ # This can actually be invoked in several ways:
25
+ #
26
+ # Gurgitate::Mailmessage.create "This is the message body",
27
+ # :from => "from_address@example.com",
28
+ # :to => "to_address@example.com",
29
+ # :subject => "This is the message subject"
30
+ #
31
+ # This results in an email message that, when rendered via to_s, will
32
+ # look like this:
33
+ #
34
+ # From: from_address@example.com
35
+ # To: to_address@example.com
36
+ # Subject: This is the message subject
37
+ #
38
+ # This is the message body
39
+ #
40
+ # If you prefer to do things entirely by options hashes, as some do,
41
+ # you can substitute a :body key for the first argument:
42
+ #
43
+ # Gurgitate::Mailmessage.create(
44
+ # :body => "This is the message body",
45
+ # :from => "from_address@example.com",
46
+ # :to => "to_address@example.com",
47
+ # :subject => "This is the message subject"
48
+ # )
49
+ #
50
+ # There are two other special options you can use: :sender and
51
+ # :recipient. These are used to specify the sender and recipient of
52
+ # email messages, when the message is sent via SMTP.
53
+ #
28
54
  def self.create(*args)
29
55
  options = body = nil
30
56
 
@@ -51,7 +77,7 @@ module Gurgitate
51
77
  end
52
78
  end
53
79
 
54
- @headers = Headers.new(options)
80
+ @headers = MailHeaders.new(options)
55
81
  end
56
82
 
57
83
  message
@@ -64,30 +90,33 @@ module Gurgitate
64
90
 
65
91
  if text
66
92
  (@headertext,@body)=text.split(/\n\n/,2)
67
- @headers=Headers.new(@headertext);
93
+ @headers=MailHeaders.new(@headertext);
68
94
  Fromregex.match(@headers["From"][0].contents);
69
95
  @from=$+
70
96
  else
71
- @headers = Headers.new
72
- @body = ""
97
+ super(text)
73
98
  end
74
99
  end
75
100
 
76
- # Returns the header +name+
77
- def header(name)
78
- @headers[name].each { |h| h.contents }.join(", ")
79
- end
80
-
81
101
  # custom accessors
82
102
 
83
103
  # Returns the message's sender
84
104
  def from; @sender || @headers.from; end
85
105
 
86
106
  # Returns all the candidates for a recipient
87
- def to; @recipient || @headers["To", "Cc"][0].contents; end
88
-
89
- # Returns the formatted mail message
90
- def to_s; @headers.to_s + "\n\n" + ( @body || ""); end
107
+ def to
108
+ if @recipient
109
+ then @recipient
110
+ elsif @headers["To"]
111
+ then @headers["To"][0].contents
112
+ elsif @headers["Cc"]
113
+ then @headers["Cc"][0].contents
114
+ elsif @headers["X-Original-To"]
115
+ then @headers["X-Original-To"][0].contents
116
+ else
117
+ ""
118
+ end
119
+ end
91
120
 
92
121
  # Returns the mail message formatted for mbox
93
122
  def to_mbox; @headers.to_mbox + "\n\n" + @body; end
@@ -0,0 +1,113 @@
1
+ #!/opt/bin/ruby -w
2
+
3
+ #------------------------------------------------------------------------
4
+ # Handles a complete mail message
5
+ #------------------------------------------------------------------------
6
+
7
+ require 'gurgitate/mail_headers'
8
+
9
+ module Gurgitate
10
+
11
+ # A complete mail message.
12
+ class Message
13
+
14
+ # The headers of the message
15
+ attr_reader :headers
16
+ # The body of the message
17
+ attr_accessor :body
18
+
19
+ # Creates a new message from the options hash, and the body of the
20
+ # message in a string.
21
+ #
22
+ # This can actually be invoked in several ways:
23
+ #
24
+ # Gurgitate::Mailmessage.create "This is the message body",
25
+ # :from => "from_address@example.com",
26
+ # :to => "to_address@example.com",
27
+ # :subject => "This is the message subject"
28
+ #
29
+ # This results in an email message that, when rendered via to_s, will
30
+ # look like this:
31
+ #
32
+ # From: from_address@example.com
33
+ # To: to_address@example.com
34
+ # Subject: This is the message subject
35
+ #
36
+ # This is the message body
37
+ #
38
+ # If you prefer to do things entirely by options hashes, as some do,
39
+ # you can substitute a :body key for the first argument:
40
+ #
41
+ # Gurgitate::Mailmessage.create(
42
+ # :body => "This is the message body",
43
+ # :from => "from_address@example.com",
44
+ # :to => "to_address@example.com",
45
+ # :subject => "This is the message subject"
46
+ # )
47
+ #
48
+ # There are two other special options you can use: :sender and
49
+ # :recipient. These are used to specify the sender and recipient of
50
+ # email messages, when the message is sent via SMTP.
51
+ #
52
+ def self.create(*args)
53
+ options = body = nil
54
+
55
+ if String === args[0]
56
+ options = args[1]
57
+ body = args[0]
58
+ elsif Hash === args[0]
59
+ options = args[0]
60
+ else
61
+ options = {}
62
+ end
63
+
64
+ message = self.new
65
+
66
+ message.instance_eval do
67
+ if body
68
+ @body=body
69
+ end
70
+
71
+ @headers = Headers.new(options)
72
+ end
73
+
74
+ message
75
+ end
76
+
77
+ # Creates a new Gurgitate message from a pre-existing message.
78
+ # This is what is used when gurgitate-mail is used as a mail filter.
79
+ #
80
+ # ARGUMENTS::
81
+ # +text+ :: An RFC822-formatted message.
82
+ # +recipient+ :: The recipient of the email message, from the MTA
83
+ # +sender+ :: The sender of the email message, also from the MTA
84
+ #
85
+ # All of its arguments can be nil: if called with no arguments,
86
+ # it simply returns an empty email message, which can be populated
87
+ # after the fact.
88
+ def initialize(text=nil)
89
+ if text
90
+ (@headertext,@body)=text.split(/\n\n/,2)
91
+ @headers=Headers.new(@headertext);
92
+ else
93
+ @headers = Headers.new
94
+ @body = ""
95
+ end
96
+ end
97
+
98
+ # Returns the header +name+, which is, note, a HeaderBag of all
99
+ # headers by that name, not just a single header.
100
+ #
101
+ # If you want the text of the header, then you have to coerce it to a
102
+ # string:
103
+ #
104
+ # header("name").to_s
105
+ #
106
+ def header(name)
107
+ @headers[name].each { |h| h.contents }.join(", ")
108
+ end
109
+
110
+ # Returns the formatted mail message
111
+ def to_s; @headers.to_s + "\n\n" + ( @body || ""); end
112
+ end
113
+ end
@@ -1,11 +1,17 @@
1
+ builddir = File.dirname(File.dirname(__FILE__))
2
+
3
+ unless $:[0] == builddir
4
+ $:.unshift builddir
5
+ end
6
+
1
7
  require 'test/unit'
2
8
  require 'test/unit/ui/console/testrunner'
3
9
  require 'stringio'
4
10
  require 'fileutils'
5
11
  require 'pathname'
6
12
  require 'irb'
7
- $:.unshift File.dirname(__FILE__) + "/.."
8
13
  require "gurgitate-mail"
14
+ require "etc"
9
15
 
10
16
  class GurgitateTest < Test::Unit::TestCase
11
17
  def setup
data/test/runtests.rb CHANGED
@@ -1,14 +1,23 @@
1
- #!/opt/bin/ruby -w
2
-
3
- #------------------------------------------------------------------------
4
- # Unit tests for gurgitate-mail
5
- #------------------------------------------------------------------------
6
-
7
1
  require 'test/unit'
8
- require 'test/unit/ui/console/testrunner'
2
+ tester = nil
3
+ begin
4
+ require 'test/unit/ui/console/testrunner'
5
+ tester = Test::Unit::UI::Console::TestRunner
6
+ rescue LoadError # ruby 1.9
7
+ require 'test/unit'
8
+ tester = Test::Unit
9
+ end
9
10
  require 'stringio'
10
11
  require 'pathname'
11
12
 
13
+ builddir = File.dirname(File.dirname(__FILE__))
14
+
15
+ unless $:[0] == builddir
16
+ $:.unshift builddir
17
+ end
18
+
19
+ require "test/gurgitate-test"
20
+
12
21
  def runtests(testcases)
13
22
  testcases.each do |testcase|
14
23
  Test::Unit::UI::Console::TestRunner.run testcase
@@ -1,3 +1,9 @@
1
+ builddir = File.dirname(File.dirname(__FILE__))
2
+
3
+ unless $:[0] == builddir
4
+ $:.unshift builddir
5
+ end
6
+
1
7
  require "test/gurgitate-test"
2
8
  require "etc"
3
9
 
data/test/test_deliver.rb CHANGED
@@ -1,3 +1,9 @@
1
+ builddir = File.dirname(File.dirname(__FILE__))
2
+
3
+ unless $:[0] == builddir
4
+ $:.unshift builddir
5
+ end
6
+
1
7
  require 'test/unit'
2
8
  require 'test/unit/ui/console/testrunner'
3
9
  require 'stringio'
@@ -1,3 +1,9 @@
1
+ builddir = File.dirname(File.dirname(__FILE__))
2
+
3
+ unless $:[0] == builddir
4
+ $:.unshift builddir
5
+ end
6
+
1
7
  require 'test/unit'
2
8
  require 'test/unit/ui/console/testrunner'
3
9
  require 'stringio'
@@ -0,0 +1,43 @@
1
+ builddir = File.join(File.dirname(__FILE__),"..")
2
+
3
+ unless $:[0] == builddir
4
+ $:.unshift builddir
5
+ end
6
+
7
+ require "test/gurgitate-test"
8
+ require "test/test_rules"
9
+ require "etc"
10
+
11
+ class TC_Execute_rules < TC_Rules
12
+ def setup
13
+ super
14
+ @invalidrules = File.join(@testdir, "rules_invalid.rb")
15
+ File.open @invalidrules, "w" do |f|
16
+ f.puts "invalid syntax"
17
+ end
18
+ @exceptionrules = File.join(@testdir, "rules_exception.rb")
19
+ File.open @exceptionrules, "w" do |f|
20
+ f.puts "raise RuntimeError, 'testing'"
21
+ end
22
+ end
23
+
24
+ def teardown
25
+ File.unlink @invalidrules if File.exists? @invalidrules
26
+ end
27
+
28
+ def test_process_default
29
+ @gurgitate.add_rules :default
30
+ assert_nothing_raised do
31
+ @gurgitate.process
32
+ end
33
+ end
34
+
35
+ def test_process_rules_not_found
36
+ @gurgitate.add_rules @rulesfile
37
+ File.unlink @rulesfile
38
+ assert_nothing_raised do
39
+ @gurgitate.process
40
+ end
41
+ assert File.exists?(@spoolfile)
42
+ end
43
+ end
@@ -1,3 +1,9 @@
1
+ builddir = File.dirname(File.dirname(__FILE__))
2
+
3
+ unless $:[0] == builddir
4
+ $:.unshift builddir
5
+ end
6
+
1
7
  require 'test/unit'
2
8
  require 'test/unit/ui/console/testrunner'
3
9
  require 'stringio'
@@ -8,6 +14,40 @@ require "test/gurgitate-test"
8
14
  require "gurgitate-mail"
9
15
 
10
16
  class TC_Gurgitate_delivery < GurgitateTest
17
+ def ensure_empty_maildir(dir)
18
+ assert File.exists?(dir)
19
+ assert File.stat(dir).directory?
20
+ assert File.exists?(File.join(dir, "new"))
21
+
22
+ assert_equal 0, Dir[File.join(dir, "new", "*")].length
23
+ assert_equal 0, Dir[File.join(dir, "cur", "*")].length
24
+ end
25
+
26
+ def ensure_maildir_with_n_messages(dir, n)
27
+ assert File.exists?(dir)
28
+ assert File.stat(dir).directory?
29
+ assert File.exists?(File.join(dir, "new"))
30
+ assert File.stat(File.join(dir, "new")).directory?
31
+ assert_equal 0, Dir[File.join(dir, "cur", "*")].length
32
+ assert_equal n, Dir[File.join(dir, "new", "*")].length
33
+ end
34
+
35
+ def ensure_empty_mhdir(dir)
36
+ assert File.exists?(dir)
37
+ assert File.stat(dir).directory?
38
+
39
+ assert_equal 0, Dir[File.join(dir, "*")].length
40
+ end
41
+
42
+ def ensure_mhdir_with_messages(dir, *messages)
43
+ assert File.exists?(dir)
44
+ assert File.stat(dir).directory?
45
+ messages.each do |message|
46
+ assert File.exists?(File.join(dir, message.to_s))
47
+ assert File.stat(File.join(dir,message.to_s)).file?
48
+ end
49
+ end
50
+
11
51
  #************************************************************************
12
52
  # tests
13
53
  #************************************************************************
@@ -78,12 +118,7 @@ class TC_Gurgitate_delivery < GurgitateTest
78
118
  def test_save_guess_maildir
79
119
  maildirmake File.join(@folders,"test")
80
120
 
81
- assert File.exists?(File.join(@folders, "test"))
82
- assert File.stat(File.join(@folders, "test")).directory?
83
- assert File.exists?(File.join(@folders, "test", "new"))
84
-
85
- assert_equal 0, Dir[File.join(@folders, "test", "new", "*")].length
86
- assert_equal 0, Dir[File.join(@folders, "test", "cur", "*")].length
121
+ ensure_empty_maildir File.join(@folders, "test")
87
122
 
88
123
  assert_nothing_raised do
89
124
  @gurgitate.process do
@@ -92,21 +127,13 @@ class TC_Gurgitate_delivery < GurgitateTest
92
127
  end
93
128
  end
94
129
 
95
- assert File.exists?(File.join(@folders, "test"))
96
- assert File.stat(File.join(@folders, "test")).directory?
97
- assert File.exists?(File.join(@folders, "test", "new"))
98
- assert File.stat(File.join(@folders, "test","new")).directory?
99
- assert_equal 0, Dir[File.join(@folders, "test", "cur", "*")].length
100
- assert_equal 1, Dir[File.join(@folders, "test", "new", "*")].length
130
+ ensure_maildir_with_n_messages(File.join(@folders, "test"), 1)
101
131
  end
102
132
 
103
133
  def test_save_guess_mh
104
134
  mhdirmake File.join(@folders,"test")
105
135
 
106
- assert File.exists?(File.join(@folders, "test"))
107
- assert File.stat(File.join(@folders, "test")).directory?
108
-
109
- assert_equal 0, Dir[File.join(@folders, "test", "*")].length
136
+ ensure_empty_mhdir File.join(@folders, "test")
110
137
 
111
138
  assert_nothing_raised do
112
139
  @gurgitate.process do
@@ -115,10 +142,7 @@ class TC_Gurgitate_delivery < GurgitateTest
115
142
  end
116
143
  end
117
144
 
118
- assert File.exists?(File.join(@folders, "test"))
119
- assert File.stat(File.join(@folders, "test")).directory?
120
- assert File.exists?(File.join(@folders, "test", "1"))
121
- assert File.stat(File.join(@folders, "test","1")).file?
145
+ ensure_mhdir_with_messages(File.join(@folders,"test"),1)
122
146
  assert File.exists?(File.join(@folders, "test", ".mh_sequences"))
123
147
  assert File.stat(File.join(@folders, "test", ".mh_sequences")).file?
124
148
  assert_equal "unseen: 1\n",
@@ -128,12 +152,7 @@ class TC_Gurgitate_delivery < GurgitateTest
128
152
  def test_save_maildir_collision
129
153
  maildirmake File.join(@folders,"test")
130
154
 
131
- assert File.exists?(File.join(@folders, "test"))
132
- assert File.stat(File.join(@folders, "test")).directory?
133
- assert File.exists?(File.join(@folders, "test", "new"))
134
-
135
- assert_equal 0, Dir[File.join(@folders, "test", "new", "*")].length
136
- assert_equal 0, Dir[File.join(@folders, "test", "cur", "*")].length
155
+ ensure_empty_maildir(File.join(@folders, "test"))
137
156
 
138
157
  assert_nothing_raised do
139
158
  @gurgitate.process do
@@ -143,20 +162,13 @@ class TC_Gurgitate_delivery < GurgitateTest
143
162
  end
144
163
  end
145
164
 
146
- assert File.exists?(File.join(@folders, "test"))
147
- assert File.stat(File.join(@folders, "test")).directory?
148
- assert File.exists?(File.join(@folders, "test", "new"))
149
- assert File.stat(File.join(@folders, "test","new")).directory?
150
- assert_equal 0, Dir[File.join(@folders, "test", "cur", "*")].length
151
- assert_equal 2, Dir[File.join(@folders, "test", "new", "*")].length
165
+ ensure_maildir_with_n_messages(File.join(@folders,"test"),2)
152
166
  end
153
167
 
154
168
  def test_save_mh_collision
155
169
  mhdirmake File.join(@folders,"test")
156
170
 
157
- assert File.exists?(File.join(@folders, "test"))
158
- assert File.stat(File.join(@folders, "test")).directory?
159
- assert_equal 0, Dir[File.join(@folders, "test", "*")].length
171
+ ensure_empty_mhdir File.join(@folders,"test")
160
172
 
161
173
  assert_nothing_raised do
162
174
  @gurgitate.process do
@@ -166,12 +178,8 @@ class TC_Gurgitate_delivery < GurgitateTest
166
178
  end
167
179
  end
168
180
 
169
- assert File.exists?(File.join(@folders, "test"))
170
- assert File.stat(File.join(@folders, "test")).directory?
171
- assert File.exists?(File.join(@folders, "test", "1"))
172
- assert File.stat(File.join(@folders, "test","1")).file?
173
- assert File.exists?(File.join(@folders, "test", "2"))
174
- assert File.stat(File.join(@folders, "test","2")).file?
181
+ ensure_mhdir_with_messages(File.join(@folders, "test"), 1, 2)
182
+
175
183
  assert File.exists?(File.join(@folders, "test", ".mh_sequences"))
176
184
  assert File.stat(File.join(@folders, "test", ".mh_sequences")).file?
177
185
  assert_equal "unseen: 1-2\n",
@@ -190,12 +198,7 @@ class TC_Gurgitate_delivery < GurgitateTest
190
198
  end
191
199
  end
192
200
 
193
- assert File.exists?(File.join(@spoolfile, ".test"))
194
- assert File.stat(File.join(@spoolfile, ".test")).directory?
195
- assert File.exists?(File.join(@spoolfile, ".test", "new"))
196
- assert File.stat(File.join(@spoolfile, ".test","new")).directory?
197
- assert_equal 0, Dir[File.join(@spoolfile, ".test", "cur", "*")].length
198
- assert_equal 1, Dir[File.join(@spoolfile, ".test", "new", "*")].length
201
+ ensure_maildir_with_n_messages(File.join(@spoolfile,".test"),1)
199
202
  end
200
203
 
201
204
  def test_save_create_mh
@@ -210,12 +213,9 @@ class TC_Gurgitate_delivery < GurgitateTest
210
213
  end
211
214
  end
212
215
 
213
- assert File.exists?(File.join(@spoolfile, "test"))
214
- assert File.stat(File.join(@spoolfile, "test")).directory?
216
+ ensure_mhdir_with_messages(File.join(@spoolfile,"test"),1)
215
217
  assert File.exists?(File.join(@spoolfile, "test", ".mh_sequences"))
216
218
  assert File.stat(File.join(@spoolfile, "test",".mh_sequences")).file?
217
- assert File.exists?(File.join(@spoolfile, "test", "1"))
218
- assert File.stat(File.join(@spoolfile, "test", "1")).file?
219
219
  end
220
220
 
221
221
  def test_save_bad_filename
@@ -266,12 +266,7 @@ class TC_Gurgitate_delivery < GurgitateTest
266
266
  end
267
267
  end
268
268
 
269
- assert File.exists?(File.join(@folders, "test"))
270
- assert File.stat(File.join(@folders, "test")).directory?
271
- assert File.exists?(File.join(@folders, "test", "new"))
272
- assert File.stat(File.join(@folders, "test","new")).directory?
273
- assert_equal 0, Dir[File.join(@folders, "test", "cur", "*")].length
274
- assert_equal 1, Dir[File.join(@folders, "test", "new", "*")].length
269
+ ensure_maildir_with_n_messages(File.join(@folders, "test"), 1)
275
270
  end
276
271
 
277
272
  def test_message_parsed_correctly