mailman 0.4.0 → 0.5.0
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.
- data/LICENSE +1 -1
- data/README.md +24 -3
- data/USER_GUIDE.md +9 -2
- data/lib/mailman.rb +0 -3
- data/lib/mailman/application.rb +63 -30
- data/lib/mailman/configuration.rb +8 -3
- data/lib/mailman/message_processor.rb +5 -4
- data/lib/mailman/receiver.rb +2 -1
- data/lib/mailman/receiver/imap.rb +54 -0
- data/lib/mailman/route/conditions.rb +9 -1
- data/lib/mailman/version.rb +1 -1
- metadata +68 -106
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Mailman
|
1
|
+
# Mailman [](https://secure.travis-ci.org/titanous/mailman)
|
2
2
|
|
3
3
|
Mailman is an incoming mail processing microframework (with POP3 and Maildir
|
4
4
|
support), that works with Rails "out of the box".
|
@@ -12,10 +12,25 @@ support), that works with Rails "out of the box".
|
|
12
12
|
|
13
13
|
See the [User Guide](http://rubydoc.info/github/titanous/mailman/master/file/USER_GUIDE.md) for more information.
|
14
14
|
|
15
|
+
There is also a great [Getting Started Guide](http://dansowter.com/mailman-guide/) written by Dan Sowter.
|
16
|
+
|
17
|
+
|
15
18
|
## Installation
|
16
19
|
|
17
20
|
gem install mailman
|
18
21
|
|
22
|
+
## Compatibility
|
23
|
+
|
24
|
+
Tested on all Ruby versions with Travis CI.
|
25
|
+
|
26
|
+
### Dependencies
|
27
|
+
|
28
|
+
* mail >= 2.0.3
|
29
|
+
* activesupport >= 2.3.4
|
30
|
+
* listen >= 0.4.1
|
31
|
+
* maildir >= 0.5.0
|
32
|
+
* i18n >= 0.4.1
|
33
|
+
|
19
34
|
## Thanks
|
20
35
|
|
21
36
|
This project was sponsored by the [Ruby Summer of Code](http://rubysoc.org),
|
@@ -23,11 +38,17 @@ and my mentor was [Steven Soroka](http://github.com/ssoroka).
|
|
23
38
|
|
24
39
|
### Contributors
|
25
40
|
|
26
|
-
- [Tim Carey-Smith](http://github.com/halorgium)
|
27
41
|
- [Nicolas Aguttes](http://github.com/tranquiliste)
|
42
|
+
- [Nathan Broadbent](https://github.com/ndbroadbent)
|
43
|
+
- [Tim Carey-Smith](http://github.com/halorgium)
|
44
|
+
- [Francis Chong](https://github.com/siuying)
|
45
|
+
- [Cyril Mougel](http://github.com/shingara)
|
46
|
+
- [Phillip Ridlen](https://github.com/philtr)
|
28
47
|
- [Daniel Schierbeck](http://github.com/dasch)
|
48
|
+
- [Steven Soroka](http://github.com/ssoroka)
|
29
49
|
- [Ian White](http://github.com/ianwhite)
|
30
50
|
|
51
|
+
|
31
52
|
## Copyright
|
32
53
|
|
33
|
-
Copyright (c) 2010 Jonathan Rudenberg. See LICENSE for details.
|
54
|
+
Copyright (c) 2010-2012 Jonathan Rudenberg. See LICENSE for details.
|
data/USER_GUIDE.md
CHANGED
@@ -99,9 +99,9 @@ All captures from matchers are available as block arguments:
|
|
99
99
|
#### Class Routing
|
100
100
|
|
101
101
|
Messages can also be routed to methods. For instance, to route to an
|
102
|
-
|
102
|
+
Object with a `receive` instance method defined, this will work:
|
103
103
|
|
104
|
-
from '%user%@example.org',
|
104
|
+
from '%user%@example.org', Sample
|
105
105
|
|
106
106
|
Messages can also be routed to arbitrary instance methods:
|
107
107
|
|
@@ -242,3 +242,10 @@ loading will be disabled.
|
|
242
242
|
interfere with running Mailman with cron or as a daemon.
|
243
243
|
|
244
244
|
**Default**: `false`
|
245
|
+
|
246
|
+
### Graceful death
|
247
|
+
|
248
|
+
`Mailman.config.graceful_death`, if set, will catch SIGINTs
|
249
|
+
(Control-C) and allow the mail receiver to finish its current
|
250
|
+
iteration before exiting. Note that this currently only works
|
251
|
+
with POP3 receivers.
|
data/lib/mailman.rb
CHANGED
data/lib/mailman/application.rb
CHANGED
@@ -15,6 +15,8 @@ module Mailman
|
|
15
15
|
attr_reader :processor
|
16
16
|
|
17
17
|
# Creates a new router, and sets up any routes passed in the block.
|
18
|
+
# @param [Hash] options the application options
|
19
|
+
# @option options [true,false] :graceful_death catch interrupt signal and don't die until end of poll
|
18
20
|
# @param [Proc] block a block with routes
|
19
21
|
def initialize(&block)
|
20
22
|
@router = Mailman::Router.new
|
@@ -22,6 +24,10 @@ module Mailman
|
|
22
24
|
instance_eval(&block)
|
23
25
|
end
|
24
26
|
|
27
|
+
def polling?
|
28
|
+
Mailman.config.poll_interval > 0 && !@polling_interrupt
|
29
|
+
end
|
30
|
+
|
25
31
|
# Sets the block to run if no routes match a message.
|
26
32
|
def default(&block)
|
27
33
|
@router.default_block = block
|
@@ -32,52 +38,79 @@ module Mailman
|
|
32
38
|
Mailman.logger.info "Mailman v#{Mailman::VERSION} started"
|
33
39
|
|
34
40
|
rails_env = File.join(Mailman.config.rails_root, 'config', 'environment.rb')
|
35
|
-
if Mailman.config.rails_root && File.exist?(rails_env)
|
41
|
+
if Mailman.config.rails_root && File.exist?(rails_env) && !(defined?(Rails) && Rails.env)
|
36
42
|
Mailman.logger.info "Rails root found in #{Mailman.config.rails_root}, requiring environment..."
|
37
43
|
require rails_env
|
38
44
|
end
|
39
45
|
|
40
|
-
if
|
46
|
+
if Mailman.config.graceful_death
|
47
|
+
# When user presses CTRL-C, finish processing current message before exiting
|
48
|
+
Signal.trap("INT") { @polling_interrupt = true }
|
49
|
+
end
|
50
|
+
|
51
|
+
# STDIN
|
52
|
+
if !Mailman.config.ignore_stdin && $stdin.fcntl(Fcntl::F_GETFL, 0) == 0
|
41
53
|
Mailman.logger.debug "Processing message from STDIN."
|
42
54
|
@processor.process($stdin.read)
|
55
|
+
|
56
|
+
# IMAP
|
57
|
+
elsif Mailman.config.imap
|
58
|
+
options = {:processor => @processor}.merge(Mailman.config.imap)
|
59
|
+
Mailman.logger.info "IMAP receiver enabled (#{options[:username]}@#{options[:server]})."
|
60
|
+
polling_loop Receiver::IMAP.new(options)
|
61
|
+
|
62
|
+
# POP3
|
43
63
|
elsif Mailman.config.pop3
|
44
64
|
options = {:processor => @processor}.merge(Mailman.config.pop3)
|
45
65
|
Mailman.logger.info "POP3 receiver enabled (#{options[:username]}@#{options[:server]})."
|
46
|
-
|
47
|
-
polling = true
|
48
|
-
Mailman.logger.info "Polling enabled. Checking every #{Mailman.config.poll_interval} seconds."
|
49
|
-
else
|
50
|
-
polling = false
|
51
|
-
Mailman.logger.info 'Polling disabled. Checking for messages once.'
|
52
|
-
end
|
53
|
-
|
54
|
-
connection = Receiver::POP3.new(options)
|
55
|
-
loop do
|
56
|
-
Mailman.logger.debug "Checking POP3 server for messages..."
|
57
|
-
connection.connect
|
58
|
-
connection.get_messages
|
59
|
-
connection.disconnect
|
60
|
-
break if !polling
|
61
|
-
sleep Mailman.config.poll_interval
|
62
|
-
end
|
66
|
+
polling_loop Receiver::POP3.new(options)
|
63
67
|
|
68
|
+
# Maildir
|
64
69
|
elsif Mailman.config.maildir
|
70
|
+
require 'maildir'
|
71
|
+
require 'listen'
|
72
|
+
|
65
73
|
Mailman.logger.info "Maildir receiver enabled (#{Mailman.config.maildir})."
|
66
|
-
maildir = Maildir.new(Mailman.config.maildir)
|
74
|
+
@maildir = Maildir.new(Mailman.config.maildir)
|
67
75
|
|
68
|
-
|
69
|
-
Mailman.
|
70
|
-
|
71
|
-
@processor.process_maildir_message(message)
|
76
|
+
Mailman.logger.debug "Monitoring the Maildir for new messages..."
|
77
|
+
Listen.to File.join(Mailman.config.maildir, 'new') do |modified, added, removed|
|
78
|
+
process_maildir
|
72
79
|
end
|
80
|
+
end
|
81
|
+
end
|
73
82
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
83
|
+
# List all message in Maildir new directory and process it
|
84
|
+
def process_maildir
|
85
|
+
# Process messages queued in the new directory
|
86
|
+
Mailman.logger.debug "Processing new message queue..."
|
87
|
+
@maildir.list(:new).each do |message|
|
88
|
+
@processor.process_maildir_message(message)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# Run the polling loop for the email inbox connection
|
95
|
+
def polling_loop(connection)
|
96
|
+
if polling?
|
97
|
+
polling_msg = "Polling enabled. Checking every #{Mailman.config.poll_interval} seconds."
|
98
|
+
else
|
99
|
+
polling_msg = "Polling disabled. Checking for messages once."
|
100
|
+
end
|
101
|
+
Mailman.logger.info(polling_msg)
|
102
|
+
|
103
|
+
loop do
|
104
|
+
begin
|
105
|
+
connection.connect
|
106
|
+
connection.get_messages
|
107
|
+
connection.disconnect
|
108
|
+
rescue SystemCallError => e
|
109
|
+
Mailman.logger.error e.message
|
80
110
|
end
|
111
|
+
|
112
|
+
break unless polling?
|
113
|
+
sleep Mailman.config.poll_interval
|
81
114
|
end
|
82
115
|
end
|
83
116
|
|
@@ -5,7 +5,7 @@ module Mailman
|
|
5
5
|
attr_accessor :logger
|
6
6
|
|
7
7
|
# @return [Hash] the configuration hash for POP3
|
8
|
-
attr_accessor :pop3
|
8
|
+
attr_accessor :pop3, :imap
|
9
9
|
|
10
10
|
# @return [Fixnum] the poll interval for POP3 or IMAP. Setting this to 0
|
11
11
|
# disables polling
|
@@ -18,10 +18,15 @@ module Mailman
|
|
18
18
|
# rails environment loading
|
19
19
|
attr_accessor :rails_root
|
20
20
|
|
21
|
-
# @return [boolean] whether or not to ignore stdin. Setting this to true
|
21
|
+
# @return [boolean] whether or not to ignore stdin. Setting this to true
|
22
22
|
# stops Mailman from entering stdin processing mode.
|
23
23
|
attr_accessor :ignore_stdin
|
24
|
-
|
24
|
+
|
25
|
+
# @return [boolean] catch SIGINT and allow current iteration to finish
|
26
|
+
# rather than dropping dead immediately. Currently only works with POP3
|
27
|
+
# connections.
|
28
|
+
attr_accessor :graceful_death
|
29
|
+
|
25
30
|
def logger
|
26
31
|
@logger ||= Logger.new(STDOUT)
|
27
32
|
end
|
@@ -13,16 +13,17 @@ module Mailman
|
|
13
13
|
# router.
|
14
14
|
# @param [String] message the message to process
|
15
15
|
def process(message)
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
mail = Mail.new(message)
|
17
|
+
from = mail.from.nil? ? "unknown" : mail.from.first
|
18
|
+
Mailman.logger.info "Got new message from '#{from}' with subject '#{mail.subject}'."
|
19
|
+
@router.route(mail)
|
19
20
|
end
|
20
21
|
|
21
22
|
# Processes a +Maildir::Message+ instance.
|
22
23
|
def process_maildir_message(message)
|
24
|
+
process(message.data)
|
23
25
|
message.process # move message to cur
|
24
26
|
message.seen!
|
25
|
-
process(message.data)
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
data/lib/mailman/receiver.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'net/imap'
|
2
|
+
|
3
|
+
module Mailman
|
4
|
+
module Receiver
|
5
|
+
# Receives messages using IMAP, and passes them to a {MessageProcessor}.
|
6
|
+
class IMAP
|
7
|
+
|
8
|
+
# @return [Net::IMAP] the IMAP connection
|
9
|
+
attr_reader :connection
|
10
|
+
|
11
|
+
# @param [Hash] options the receiver options
|
12
|
+
# @option options [MessageProcessor] :processor the processor to pass new
|
13
|
+
# messages to
|
14
|
+
# @option options [String] :server the server to connect to
|
15
|
+
# @option options [Integer] :port the port to connect to
|
16
|
+
# @option options [String] :username the username to authenticate with
|
17
|
+
# @option options [String] :password the password to authenticate with
|
18
|
+
def initialize(options)
|
19
|
+
@processor = options[:processor]
|
20
|
+
@username = options[:username]
|
21
|
+
@password = options[:password]
|
22
|
+
@filter = options[:filter] || ['NEW']
|
23
|
+
@port = options[:port] || 143
|
24
|
+
|
25
|
+
@connection = Net::IMAP.new(options[:server], @port)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Connects to the IMAP server.
|
29
|
+
def connect
|
30
|
+
@connection.login(@username, @password)
|
31
|
+
@connection.examine("INBOX")
|
32
|
+
end
|
33
|
+
|
34
|
+
# Disconnects from the IMAP server.
|
35
|
+
def disconnect
|
36
|
+
@connection.logout
|
37
|
+
@connection.disconnected? ? true : @connection.disconnect rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Iterates through new messages, passing them to the processor, and
|
41
|
+
# deleting them.
|
42
|
+
def get_messages
|
43
|
+
@connection.search(@filter).each do |message|
|
44
|
+
body = @connection.fetch(message,"RFC822")[0].attr["RFC822"]
|
45
|
+
@processor.process(body)
|
46
|
+
@connection.store(message,"+FLAGS",[Net::IMAP::DELETED])
|
47
|
+
end
|
48
|
+
# Clears messages that have the Deleted flag set
|
49
|
+
@connection.expunge
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -37,7 +37,15 @@ module Mailman
|
|
37
37
|
# Matches against the Body of a message.
|
38
38
|
class BodyCondition < Condition
|
39
39
|
def match(message)
|
40
|
-
|
40
|
+
if message.multipart?
|
41
|
+
message.parts.each do |part|
|
42
|
+
if result = @matcher.match(part.decoded)
|
43
|
+
return result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
else
|
47
|
+
@matcher.match(message.body.decoded)
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
|
data/lib/mailman/version.rb
CHANGED
metadata
CHANGED
@@ -1,123 +1,94 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: mailman
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 4
|
8
|
-
- 0
|
9
|
-
version: 0.4.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Jonathan Rudenberg
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-04-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: mail
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70284016144160 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 2
|
30
|
-
- 0
|
31
|
-
- 3
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
32
21
|
version: 2.0.3
|
33
22
|
type: :runtime
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: activesupport
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: *70284016144160
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
requirement: &70284016143180 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
segments:
|
44
|
-
- 2
|
45
|
-
- 3
|
46
|
-
- 4
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
47
32
|
version: 2.3.4
|
48
33
|
type: :runtime
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: fssm
|
52
34
|
prerelease: false
|
53
|
-
|
35
|
+
version_requirements: *70284016143180
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: listen
|
38
|
+
requirement: &70284016140380 !ruby/object:Gem::Requirement
|
54
39
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
- 0
|
60
|
-
- 1
|
61
|
-
- 4
|
62
|
-
version: 0.1.4
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.4.1
|
63
44
|
type: :runtime
|
64
|
-
version_requirements: *id003
|
65
|
-
- !ruby/object:Gem::Dependency
|
66
|
-
name: maildir
|
67
45
|
prerelease: false
|
68
|
-
|
46
|
+
version_requirements: *70284016140380
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: maildir
|
49
|
+
requirement: &70284017139220 !ruby/object:Gem::Requirement
|
69
50
|
none: false
|
70
|
-
requirements:
|
71
|
-
- -
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
- 5
|
76
|
-
- 0
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
77
54
|
version: 0.5.0
|
78
55
|
type: :runtime
|
79
|
-
version_requirements: *id004
|
80
|
-
- !ruby/object:Gem::Dependency
|
81
|
-
name: i18n
|
82
56
|
prerelease: false
|
83
|
-
|
57
|
+
version_requirements: *70284017139220
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: i18n
|
60
|
+
requirement: &70284017138760 !ruby/object:Gem::Requirement
|
84
61
|
none: false
|
85
|
-
requirements:
|
86
|
-
- -
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
segments:
|
89
|
-
- 0
|
90
|
-
- 4
|
91
|
-
- 1
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
92
65
|
version: 0.4.1
|
93
66
|
type: :runtime
|
94
|
-
version_requirements: *id005
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: rspec
|
97
67
|
prerelease: false
|
98
|
-
|
68
|
+
version_requirements: *70284017138760
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: &70284017138300 !ruby/object:Gem::Requirement
|
99
72
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
- 0
|
105
|
-
version: "0"
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.6.0
|
106
77
|
type: :development
|
107
|
-
|
108
|
-
|
109
|
-
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70284017138300
|
80
|
+
description: Mailman makes it easy to process incoming emails with a simple routing
|
81
|
+
DSL
|
82
|
+
email:
|
110
83
|
- jonathan@titanous.com
|
111
84
|
executables: []
|
112
|
-
|
113
85
|
extensions: []
|
114
|
-
|
115
86
|
extra_rdoc_files: []
|
116
|
-
|
117
|
-
files:
|
87
|
+
files:
|
118
88
|
- lib/mailman/application.rb
|
119
89
|
- lib/mailman/configuration.rb
|
120
90
|
- lib/mailman/message_processor.rb
|
91
|
+
- lib/mailman/receiver/imap.rb
|
121
92
|
- lib/mailman/receiver/pop3.rb
|
122
93
|
- lib/mailman/receiver.rb
|
123
94
|
- lib/mailman/route/condition.rb
|
@@ -133,37 +104,28 @@ files:
|
|
133
104
|
- LICENSE
|
134
105
|
- README.md
|
135
106
|
- USER_GUIDE.md
|
136
|
-
has_rdoc: true
|
137
107
|
homepage: http://mailmanrb.com
|
138
108
|
licenses: []
|
139
|
-
|
140
109
|
post_install_message:
|
141
110
|
rdoc_options: []
|
142
|
-
|
143
|
-
require_paths:
|
111
|
+
require_paths:
|
144
112
|
- lib
|
145
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
114
|
none: false
|
147
|
-
requirements:
|
148
|
-
- -
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
|
151
|
-
|
152
|
-
version: "0"
|
153
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
120
|
none: false
|
155
|
-
requirements:
|
156
|
-
- -
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
|
159
|
-
- 0
|
160
|
-
version: "0"
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
161
125
|
requirements: []
|
162
|
-
|
163
126
|
rubyforge_project: mailman
|
164
|
-
rubygems_version: 1.
|
127
|
+
rubygems_version: 1.8.11
|
165
128
|
signing_key:
|
166
129
|
specification_version: 3
|
167
130
|
summary: A incoming email processing microframework
|
168
131
|
test_files: []
|
169
|
-
|