mailmanager 1.0.18 → 1.0.19
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +8 -1
- data/Gemfile.lock +3 -3
- data/README.rdoc +2 -2
- data/lib/mailmanager/lib.rb +3 -2
- data/lib/mailmanager/list.rb +21 -5
- data/lib/mailmanager/version.rb +1 -1
- data/mailmanager.gemspec +1 -1
- data/spec/lib/mailmanager/lib_spec.rb +73 -22
- data/spec/lib/mailmanager/list_spec.rb +46 -0
- metadata +4 -4
data/Changelog
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
Current version is 1.0.
|
1
|
+
Current version is 1.0.19
|
2
|
+
|
3
|
+
changes since 1.0.18
|
4
|
+
- added optional custom_headers arg to MailManager::List#inject
|
5
|
+
- added new MailManager::List#inject_raw method to inject raw emails
|
6
|
+
- updated to new simplecov-rcov version w/ better coverage calculation
|
7
|
+
- documentation errors fixed
|
8
|
+
- cleaned up the tests and code a bit
|
2
9
|
|
3
10
|
changes since 1.0.17
|
4
11
|
- added host_name getter/setter for lists
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mailmanager (1.0.
|
4
|
+
mailmanager (1.0.19)
|
5
5
|
json (~> 1.4.6)
|
6
6
|
open4 (~> 1.0.1)
|
7
7
|
|
@@ -48,7 +48,7 @@ GEM
|
|
48
48
|
simplecov (0.3.9)
|
49
49
|
simplecov-html (>= 0.3.7)
|
50
50
|
simplecov-html (0.3.9)
|
51
|
-
simplecov-rcov (0.1.
|
51
|
+
simplecov-rcov (0.1.4)
|
52
52
|
simplecov
|
53
53
|
term-ansicolor (1.0.5)
|
54
54
|
|
@@ -63,4 +63,4 @@ DEPENDENCIES
|
|
63
63
|
rspec (~> 2.4.0)
|
64
64
|
ruby-debug19
|
65
65
|
simplecov
|
66
|
-
simplecov-rcov
|
66
|
+
simplecov-rcov (~> 0.1.4)
|
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@ for details.
|
|
6
6
|
It is licensed under the New BSD License (see the LICENSE file for details).
|
7
7
|
|
8
8
|
MailManager has been tested with Mailman 2.1.14. It has NOT been tested with any
|
9
|
-
release of Mailman 3 (in alpha as of 1/19/2011). It requires Python 2.
|
9
|
+
release of Mailman 3 (in alpha as of 1/19/2011). It requires Python 2.4 or higher.
|
10
10
|
Note that while Mailman itself requires Python, it can work with older versions. So
|
11
11
|
check your Python version before using this.
|
12
12
|
|
@@ -21,7 +21,7 @@ check your Python version before using this.
|
|
21
21
|
foo_list = mm.get_list('foo')
|
22
22
|
new_list = mm.create_list(:name => 'newlist', :admin_email => 'me@here.com', :admin_password => 'secret')
|
23
23
|
new_list.add_member('bar@baz.com')
|
24
|
-
new_list.members
|
24
|
+
new_list.members -> ['bar@baz.com']
|
25
25
|
|
26
26
|
== Hacking
|
27
27
|
|
data/lib/mailmanager/lib.rb
CHANGED
@@ -64,6 +64,7 @@ module MailManager
|
|
64
64
|
params = {:listname => list.name, :stdin => message}
|
65
65
|
params[:queue] = queue unless queue.nil?
|
66
66
|
command(cmd, params)
|
67
|
+
{'result' => 'success'}
|
67
68
|
end
|
68
69
|
|
69
70
|
def list_address(list)
|
@@ -154,7 +155,7 @@ module MailManager
|
|
154
155
|
end
|
155
156
|
|
156
157
|
def command(cmd, params = {})
|
157
|
-
mailman_cmd = "#{mailmanager.root}/bin/#{cmd.to_s} "
|
158
|
+
mailman_cmd = "#{MailManager.python} #{mailmanager.root}/bin/#{cmd.to_s} "
|
158
159
|
# delete params as we handle them explicitly
|
159
160
|
stdin = nil
|
160
161
|
stdin = params.delete(:stdin) if params.respond_to?(:has_key?) && params.has_key?(:stdin)
|
@@ -174,7 +175,7 @@ module MailManager
|
|
174
175
|
when :withlist
|
175
176
|
raise ArgumentError, "Missing :name param" if params[:name].nil?
|
176
177
|
proxy_path = File.dirname(__FILE__)
|
177
|
-
mailman_cmd = "PYTHONPATH=#{proxy_path} #{
|
178
|
+
mailman_cmd = "PYTHONPATH=#{proxy_path} #{mailman_cmd}"
|
178
179
|
mailman_cmd += "-q -r listproxy.command #{escape(params.delete(:name))} " +
|
179
180
|
"#{params.delete(:wlcmd)} "
|
180
181
|
if !params[:arg].nil? && params[:arg].length > 0
|
data/lib/mailmanager/list.rb
CHANGED
@@ -108,15 +108,31 @@ module MailManager
|
|
108
108
|
end
|
109
109
|
|
110
110
|
# Injects a message into the list.
|
111
|
-
def inject(from,
|
111
|
+
def inject(from, subj, message, custom_headers=nil)
|
112
112
|
inject_message =<<EOF
|
113
113
|
From: #{from}
|
114
114
|
To: #{address}
|
115
|
-
Subject: #{
|
116
|
-
|
117
|
-
#{message}
|
115
|
+
Subject: #{subj}
|
118
116
|
EOF
|
119
|
-
|
117
|
+
if !custom_headers.nil?
|
118
|
+
raise ArgumentError, "custom headers arg should be a hash" unless custom_headers.respond_to?(:each_pair)
|
119
|
+
headers = []
|
120
|
+
custom_headers.each_pair { |hdr, val|
|
121
|
+
headers << "#{hdr}: #{val}"
|
122
|
+
}
|
123
|
+
inject_message += headers.join("\n")
|
124
|
+
end
|
125
|
+
inject_message += "\n#{message}"
|
126
|
+
result = lib.inject(self, inject_message)
|
127
|
+
result['result'].to_sym
|
128
|
+
end
|
129
|
+
|
130
|
+
# Injects a raw message into the list. You must send a properly formatted
|
131
|
+
# email to this method. You probably want to set the To: header to the list's
|
132
|
+
# address. You can get that from MailManager::List#address
|
133
|
+
def inject_raw(message)
|
134
|
+
result = lib.inject(self, message)
|
135
|
+
result['result'].to_sym
|
120
136
|
end
|
121
137
|
|
122
138
|
# Returns the info URL for the list
|
data/lib/mailmanager/version.rb
CHANGED
data/mailmanager.gemspec
CHANGED
@@ -29,5 +29,5 @@ spec = Gem::Specification.new do |s|
|
|
29
29
|
s.add_development_dependency('ci_reporter')
|
30
30
|
s.add_development_dependency('cucumber')
|
31
31
|
s.add_development_dependency('simplecov')
|
32
|
-
s.add_development_dependency('simplecov-rcov')
|
32
|
+
s.add_development_dependency('simplecov-rcov', '~>0.1.4')
|
33
33
|
end
|
@@ -4,6 +4,7 @@ describe MailManager::Lib do
|
|
4
4
|
let(:mailmanager) { mock(MailManager) }
|
5
5
|
let(:subject) { MailManager::Lib.new }
|
6
6
|
let(:fake_root) { '/foo/bar' }
|
7
|
+
let(:python) { '/usr/bin/env python' }
|
7
8
|
let(:process) { mock(Process::Status) }
|
8
9
|
let(:list_result) { <<EOF
|
9
10
|
3 matching mailing lists found:
|
@@ -22,7 +23,7 @@ EOF
|
|
22
23
|
|
23
24
|
describe "#lists" do
|
24
25
|
it "should return all existing lists" do
|
25
|
-
subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
|
26
|
+
subject.stub(:run_command).with("#{python} #{fake_root}/bin/list_lists 2>&1", nil).
|
26
27
|
and_return([list_result, process])
|
27
28
|
subject.lists.should have(3).lists
|
28
29
|
end
|
@@ -30,7 +31,7 @@ EOF
|
|
30
31
|
|
31
32
|
describe "#create_list" do
|
32
33
|
before :each do
|
33
|
-
subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
|
34
|
+
subject.stub(:run_command).with("#{python} #{fake_root}/bin/list_lists 2>&1", nil).
|
34
35
|
and_return([list_result, process])
|
35
36
|
end
|
36
37
|
|
@@ -78,7 +79,7 @@ EOF
|
|
78
79
|
|
79
80
|
it "should create the list" do
|
80
81
|
subject.should_receive(:run_command).
|
81
|
-
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
82
|
+
with("#{python} #{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
82
83
|
and_return([new_list_return, process])
|
83
84
|
subject.stub(:list_names).and_return([],['bar'])
|
84
85
|
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
|
@@ -88,7 +89,7 @@ EOF
|
|
88
89
|
it "should not rely on the aliases setup output" do
|
89
90
|
# https://www.pivotaltracker.com/story/show/9422507
|
90
91
|
subject.should_receive(:run_command).
|
91
|
-
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
92
|
+
with("#{python} #{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
92
93
|
and_return(["", process])
|
93
94
|
subject.stub(:list_names).and_return([],['bar'])
|
94
95
|
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
|
@@ -98,7 +99,7 @@ EOF
|
|
98
99
|
it "should raise an exception if the list already exists" do
|
99
100
|
# https://www.pivotaltracker.com/story/show/9421449
|
100
101
|
subject.should_not_receive(:run_command).
|
101
|
-
with("#{fake_root}/bin/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil)
|
102
|
+
with("#{python} #{fake_root}/bin/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil)
|
102
103
|
subject.stub(:list_names).and_return(['foo'])
|
103
104
|
lambda {
|
104
105
|
subject.create_list(:name => 'foo', :admin_email => 'foo@bar.baz',
|
@@ -108,7 +109,7 @@ EOF
|
|
108
109
|
|
109
110
|
it "should raise a MailmanExecuteError if the list creation fails on the Mailman side" do
|
110
111
|
subject.should_receive(:run_command).
|
111
|
-
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
112
|
+
with("#{python} #{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
112
113
|
and_return(["", process])
|
113
114
|
subject.stub(:get_list).and_raise(MailManager::ListNotFoundError)
|
114
115
|
lambda {
|
@@ -122,7 +123,7 @@ EOF
|
|
122
123
|
describe "#delete_list" do
|
123
124
|
it "should delete the list" do
|
124
125
|
subject.should_receive(:run_command).
|
125
|
-
with("#{fake_root}/bin/rmlist \"foo\" 2>&1", nil).
|
126
|
+
with("#{python} #{fake_root}/bin/rmlist \"foo\" 2>&1", nil).
|
126
127
|
and_return(["Removing list info", process])
|
127
128
|
subject.stub(:list_names).and_return(['foo'])
|
128
129
|
subject.delete_list('foo')
|
@@ -144,19 +145,52 @@ EOF
|
|
144
145
|
let(:regular_members) { ['me@here.com', 'you@there.org'] }
|
145
146
|
let(:digest_members) { ['them@that.net'] }
|
146
147
|
|
147
|
-
|
148
|
-
|
149
|
-
|
148
|
+
describe "#inject" do
|
149
|
+
it "should tell Mailman to inject a message into the list" do
|
150
|
+
test_message = <<EOF
|
151
|
+
From: "Morgan, Wesley" <MorganW@dnc.org>
|
152
|
+
To: "labs@mailman-dev.dnc.org" <labs@mailman-dev.dnc.org>
|
153
|
+
Sender: "labs-bounces@mailman-dev.dnc.org" <labs-bounces@mailman-dev.dnc.org>
|
154
|
+
Content-Class: urn:content-classes:message
|
155
|
+
Date: Tue, 18 Jan 2011 13:26:59 -0500
|
156
|
+
Subject: [Labs] is this thing on?
|
157
|
+
Thread-Topic: is this thing on?
|
158
|
+
Thread-Index: Acu3PUssIxkW+1TESgmnlPvaBgroVQ==
|
159
|
+
Message-ID: <C3DA7B38-E1F9-4331-9025-D066DA7376F2@dnc.org>
|
160
|
+
List-Help: <mailto:labs-request@mailman-dev.dnc.org?subject=help>
|
161
|
+
List-Subscribe: <http://mailman-dev.dnc.org/mailman/listinfo/labs>,
|
162
|
+
<mailto:labs-request@mailman-dev.dnc.org?subject=subscribe>
|
163
|
+
List-Unsubscribe: <http://mailman-dev.dnc.org/mailman/options/labs>,
|
164
|
+
<mailto:labs-request@mailman-dev.dnc.org?subject=unsubscribe>
|
165
|
+
Accept-Language: en-US
|
166
|
+
Content-Language: en-US
|
167
|
+
X-Auto-Response-Suppress: All
|
168
|
+
acceptlanguage: en-US
|
169
|
+
Content-Type: text/plain; charset="us-ascii"
|
170
|
+
Content-Transfer-Encoding: quoted-printable
|
171
|
+
MIME-Version: 1.0
|
172
|
+
|
173
|
+
Cello?
|
174
|
+
_______________________________________________
|
175
|
+
Labs mailing list
|
176
|
+
Labs@mailman-dev.dnc.org
|
177
|
+
http://mailman-dev.dnc.org/mailman/listinfo/labs
|
178
|
+
|
179
|
+
EOF
|
180
|
+
test_message = "message!"
|
181
|
+
test_mailman_cmd(:inject, :inject, nil, nil, test_message)
|
182
|
+
end
|
183
|
+
end
|
150
184
|
|
151
185
|
describe "#regular_members" do
|
152
186
|
it "should ask Mailman for the regular list members" do
|
153
|
-
|
187
|
+
test_withlist_cmd(:regular_members, :getRegularMemberKeys, regular_members)
|
154
188
|
end
|
155
189
|
end
|
156
190
|
|
157
191
|
describe "#digest_members" do
|
158
192
|
it "should ask Mailman for the digest list members" do
|
159
|
-
|
193
|
+
test_withlist_cmd(:digest_members, :getDigestMemberKeys, digest_members)
|
160
194
|
end
|
161
195
|
end
|
162
196
|
|
@@ -190,14 +224,14 @@ EOF
|
|
190
224
|
|
191
225
|
describe "#moderators" do
|
192
226
|
it "should ask Mailman for the list's moderators" do
|
193
|
-
|
227
|
+
test_withlist_cmd(:moderators, :moderator, ['phb@bigcorp.com', 'nhb@smallstartup.com'])
|
194
228
|
end
|
195
229
|
end
|
196
230
|
|
197
231
|
describe "#add_moderator" do
|
198
232
|
it "should ask Mailman to add the moderator to the list" do
|
199
233
|
subject.should_receive(:moderators).with(list).and_return({'result' => 'success', 'return' => []})
|
200
|
-
|
234
|
+
test_withlist_cmd(:add_moderator, 'moderator.append', nil, 'foo@bar.com')
|
201
235
|
end
|
202
236
|
|
203
237
|
it "should raise ModeratorAlreadyExistsError if they already a moderator" do
|
@@ -211,7 +245,7 @@ EOF
|
|
211
245
|
describe "#delete_moderator" do
|
212
246
|
it "should ask Mailman to delete the moderator from the list" do
|
213
247
|
subject.should_receive(:moderators).with(list).and_return({'result' => 'success', 'return' => ['foo@bar.com']})
|
214
|
-
|
248
|
+
test_withlist_cmd(:delete_moderator, 'moderator.remove', nil, 'foo@bar.com')
|
215
249
|
end
|
216
250
|
|
217
251
|
it "should raise ModeratorNotFoundError if they are not already a moderator" do
|
@@ -261,32 +295,49 @@ EOF
|
|
261
295
|
|
262
296
|
def test_method_getter(lib_method, return_value, *args)
|
263
297
|
cc_mailman_method = camel_case("get_#{lib_method.to_s}")
|
264
|
-
|
298
|
+
test_withlist_cmd(lib_method, cc_mailman_method, return_value, *args)
|
265
299
|
end
|
266
300
|
|
267
301
|
def test_method_setter(lib_method, *args)
|
268
302
|
cc_mailman_method = camel_case(lib_method.to_s)
|
269
|
-
|
303
|
+
test_withlist_cmd(lib_method, cc_mailman_method, nil, *args)
|
270
304
|
end
|
271
305
|
|
272
306
|
def test_attr_getter(attr, return_value)
|
273
|
-
|
307
|
+
test_withlist_cmd(attr, attr, return_value)
|
274
308
|
end
|
275
309
|
|
276
310
|
def test_attr_setter(attr, *args)
|
277
|
-
|
311
|
+
test_withlist_cmd("set_#{attr}", attr, nil, *args)
|
278
312
|
end
|
279
313
|
|
280
|
-
def
|
314
|
+
def test_withlist_cmd(lib_method, mailman_method, return_value=nil, *args)
|
315
|
+
test_mailman_cmd(lib_method, :withlist, mailman_method, return_value=nil, *args)
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_mailman_cmd(lib_method, mailman_cmd, mailman_sub_cmd, return_value=nil, *args)
|
319
|
+
command = "/usr/bin/env python " +
|
320
|
+
"#{fake_root}/bin/#{mailman_cmd.to_s} "
|
321
|
+
command += "--listname=" if mailman_cmd.to_sym == :inject
|
322
|
+
if mailman_cmd.to_sym == :withlist
|
323
|
+
command = "PYTHONPATH=#{File.expand_path('lib/mailmanager')} #{command}"
|
324
|
+
command += "-q -r listproxy.command "
|
325
|
+
end
|
326
|
+
command += "\"foo\" "
|
281
327
|
if return_value.is_a?(Hash)
|
282
328
|
result = return_value
|
283
329
|
else
|
284
330
|
result = {"result" => "success"}
|
285
331
|
result["return"] = return_value unless return_value.nil?
|
286
332
|
end
|
333
|
+
cmd_arg = command
|
334
|
+
cmd_arg += "#{mailman_sub_cmd.to_s} " unless mailman_sub_cmd.nil?
|
335
|
+
cmd_arg += "#{cmd_args(*args)}" unless mailman_cmd.to_sym == :inject
|
336
|
+
cmd_arg += "2>&1"
|
337
|
+
stdin_arg = mailman_cmd.to_sym == :inject ? args[0] : nil
|
287
338
|
subject.should_receive(:run_command).
|
288
|
-
with(
|
289
|
-
|
339
|
+
with(cmd_arg, stdin_arg).and_return([JSON.generate(result),process])
|
340
|
+
# with(mailman_cmd+"#{mailman_method.to_s} #{cmd_args(*args)}2>&1", nil).
|
290
341
|
subject.send(lib_method, list, *args).should == result
|
291
342
|
end
|
292
343
|
|
@@ -114,6 +114,52 @@ describe MailManager::List do
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
+
context "when injecting a message" do
|
118
|
+
let(:from) { 'Foo Bar <foo@bar.name>' }
|
119
|
+
let(:to) { 'list@foo.org' }
|
120
|
+
let(:subj) { 'Test Subject' }
|
121
|
+
let(:message) { 'Test Message' }
|
122
|
+
let(:headers) { {'X-Custom-1' => 'foo', 'X-Custom-2' => 'bar'} }
|
123
|
+
let(:raw_message_pre) { <<EOF
|
124
|
+
From: #{from}
|
125
|
+
To: #{to}
|
126
|
+
Subject: #{subj}
|
127
|
+
EOF
|
128
|
+
}
|
129
|
+
let(:raw_message) { raw_message_pre + "\n#{message}" }
|
130
|
+
let(:msg_with_headers) {
|
131
|
+
headers_arr = []
|
132
|
+
headers.each_pair { |hdr, val|
|
133
|
+
headers_arr << "#{hdr}: #{val}"
|
134
|
+
}
|
135
|
+
raw_message_pre + headers_arr.join("\n") + "\n#{message}"
|
136
|
+
}
|
137
|
+
|
138
|
+
describe "#inject" do
|
139
|
+
it "should tell lib to inject a message into the list" do
|
140
|
+
lib.stub(:list_address).with(subject).and_return({'result' => 'success', 'return' => to})
|
141
|
+
lib.should_receive(:inject).with(subject, raw_message).
|
142
|
+
and_return({'result' => 'success'})
|
143
|
+
subject.inject(from, subj, message)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should accept custom headers" do
|
147
|
+
lib.stub(:list_address).with(subject).and_return({'result' => 'success', 'return' => to})
|
148
|
+
lib.should_receive(:inject).with(subject, msg_with_headers).
|
149
|
+
and_return({'result' => 'success'})
|
150
|
+
subject.inject(from, subj, message, headers)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#inject_raw" do
|
155
|
+
it "should tell lib to inject whatever you send it" do
|
156
|
+
lib.should_receive(:inject).with(subject, raw_message).
|
157
|
+
and_return({'result' => 'success'})
|
158
|
+
subject.inject_raw(raw_message)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
117
163
|
context "host_name accessors" do
|
118
164
|
let(:host_name) { 'groups.foo.org' }
|
119
165
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: mailmanager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.0.
|
5
|
+
version: 1.0.19
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Wes Morgan
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-02-
|
13
|
+
date: 2011-02-11 00:00:00 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -107,9 +107,9 @@ dependencies:
|
|
107
107
|
requirement: &id009 !ruby/object:Gem::Requirement
|
108
108
|
none: false
|
109
109
|
requirements:
|
110
|
-
- -
|
110
|
+
- - ~>
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
112
|
+
version: 0.1.4
|
113
113
|
type: :development
|
114
114
|
version_requirements: *id009
|
115
115
|
description: Ruby wrapper library for GNU Mailman's admin functions
|