mail_room 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +13 -0
- data/CODE_OF_CONDUCT.md +22 -0
- data/README.md +66 -6
- data/lib/mail_room/cli.rb +4 -0
- data/lib/mail_room/configuration.rb +8 -3
- data/lib/mail_room/delivery/letter_opener.rb +15 -5
- data/lib/mail_room/delivery/logger.rb +15 -5
- data/lib/mail_room/delivery/noop.rb +7 -0
- data/lib/mail_room/delivery/postback.rb +18 -7
- data/lib/mail_room/delivery/sidekiq.rb +66 -0
- data/lib/mail_room/mailbox.rb +30 -6
- data/lib/mail_room/mailbox_handler.rb +8 -2
- data/lib/mail_room/mailbox_watcher.rb +4 -1
- data/lib/mail_room/version.rb +1 -1
- data/mail_room.gemspec +1 -0
- data/spec/lib/mailbox_handler_spec.rb +2 -1
- data/spec/lib/mailbox_watcher_spec.rb +13 -10
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 495c36dd61e6ddd5f5a259594d414942055446ad
|
4
|
+
data.tar.gz: 9bb752935c2713d74d9ffb8c0c8b3a57d39f2a1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8271126e54103017c167bdbd42138284f863481b9dd3b47bae0e490135d04ad70b5cced5221b1fa64320e8e0e36013c9f6540e426573a0164b394bd28492f86
|
7
|
+
data.tar.gz: a5883a201543fec388de4a86f070592def4a1c22345dbc92f6c0aba149bf862c8179f4532483c256ffd706aba471f392622088d8e6fde186e9bfaf4bdac94325
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.2.
|
1
|
+
2.2.2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## mail_room 0.4.0 ##
|
2
|
+
|
3
|
+
* Sidekiq delivery method
|
4
|
+
* Option to delete messages after delivered
|
5
|
+
|
6
|
+
*Douwe Mann <@DouweM>*
|
7
|
+
|
8
|
+
* -q/--quiet do not raise errors on missing configuration
|
9
|
+
* prefetch mail messages before idling
|
10
|
+
* delivery-method-specific delivery options configuration
|
11
|
+
|
12
|
+
*Tony Pitale <@tpitale>*
|
13
|
+
|
1
14
|
## mail_room 0.3.1 ##
|
2
15
|
|
3
16
|
* Rescue from EOFError and re-setup mailroom
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include:
|
8
|
+
|
9
|
+
* The use of sexualized language or imagery
|
10
|
+
* Personal attacks
|
11
|
+
* Trolling or insulting/derogatory comments
|
12
|
+
* Public or private harassment
|
13
|
+
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
14
|
+
* Other unethical or unprofessional conduct.
|
15
|
+
|
16
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
17
|
+
|
18
|
+
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
19
|
+
|
20
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
21
|
+
|
22
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
data/README.md
CHANGED
@@ -25,6 +25,8 @@ You will also need to install `faraday` or `letter_opener` if you use the `postb
|
|
25
25
|
|
26
26
|
mail_room -c /path/to/config.yml
|
27
27
|
|
28
|
+
**Note:** To ignore missing config file or missing `mailboxes` key, use `-q` or `--quiet`
|
29
|
+
|
28
30
|
## Configuration ##
|
29
31
|
|
30
32
|
```yaml
|
@@ -34,27 +36,42 @@ You will also need to install `faraday` or `letter_opener` if you use the `postb
|
|
34
36
|
:email: "user1@gmail.com"
|
35
37
|
:password: "password"
|
36
38
|
:name: "inbox"
|
37
|
-
:
|
38
|
-
:
|
39
|
+
:search_command: 'NEW'
|
40
|
+
:delivery_options:
|
41
|
+
:delivery_url: "http://localhost:3000/inbox"
|
42
|
+
:delivery_token: "abcdefg"
|
43
|
+
|
39
44
|
-
|
40
45
|
:email: "user2@gmail.com"
|
41
46
|
:password: "password"
|
42
47
|
:name: "inbox"
|
43
48
|
:delivery_method: postback
|
44
|
-
:
|
45
|
-
|
49
|
+
:delivery_options:
|
50
|
+
:delivery_url: "http://localhost:3000/inbox"
|
51
|
+
:delivery_token: "abcdefg"
|
46
52
|
-
|
47
53
|
:email: "user3@gmail.com"
|
48
54
|
:password: "password"
|
49
55
|
:name: "inbox"
|
50
56
|
:delivery_method: logger
|
51
|
-
:
|
57
|
+
:delivery_options:
|
58
|
+
:log_path: "/var/log/user3-email.log"
|
52
59
|
-
|
53
60
|
:email: "user4@gmail.com"
|
54
61
|
:password: "password"
|
55
62
|
:name: "inbox"
|
56
63
|
:delivery_method: letter_opener
|
57
|
-
:
|
64
|
+
:delete_after_delivery: true
|
65
|
+
:delivery_options:
|
66
|
+
:location: "/tmp/user4-email"
|
67
|
+
-
|
68
|
+
:email: "user5@gmail.com"
|
69
|
+
:password: "password"
|
70
|
+
:name: "inbox"
|
71
|
+
:delivery_method: sidekiq
|
72
|
+
:delivery_options:
|
73
|
+
:redis_url: redis://localhost:6379
|
74
|
+
:worker: EmailReceiverWorker
|
58
75
|
```
|
59
76
|
|
60
77
|
## delivery_method ##
|
@@ -73,6 +90,39 @@ you may need to disable forgery protection as you would with a JSON API. In
|
|
73
90
|
our case, the postback is plaintext, but the protection will still need to be
|
74
91
|
disabled.
|
75
92
|
|
93
|
+
### sidekiq ###
|
94
|
+
|
95
|
+
Deliver the message by pushing it onto the configured Sidekiq queue to be handled by a custom worker.
|
96
|
+
|
97
|
+
Requires `redis` gem to be installed.
|
98
|
+
|
99
|
+
Configured with `:delivery_method: sidekiq`.
|
100
|
+
|
101
|
+
Delivery options:
|
102
|
+
- **redis_url**: The Redis server to connect with. Use the same Redis URL that's used to configure Sidekiq.
|
103
|
+
Required, defaults to `redis://localhost:6379`.
|
104
|
+
- **namespace**: The Redis namespace Sidekiq works under. Use the same Redis namespace that's used to configure Sidekiq.
|
105
|
+
Optional.
|
106
|
+
- **queue**: The Sidekiq queue the job is pushed onto. Make sure Sidekiq actually reads off this queue.
|
107
|
+
Required, defaults to `default`.
|
108
|
+
- **worker**: The worker class that will handle the message.
|
109
|
+
Required.
|
110
|
+
|
111
|
+
An example worker implementation looks like this:
|
112
|
+
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class EmailReceiverWorker
|
116
|
+
include Sidekiq::Worker
|
117
|
+
|
118
|
+
def perform(message)
|
119
|
+
mail = Mail::Message.new(message)
|
120
|
+
|
121
|
+
puts "New mail from #{mail.from.first}: #{mail.subject}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
76
126
|
### logger ###
|
77
127
|
|
78
128
|
Configured with `:delivery_method: logger`.
|
@@ -101,6 +151,16 @@ disabled, you can get the raw string of the email using `request.body.read`.
|
|
101
151
|
I would recommend having the `mail` gem bundled and parse the email using
|
102
152
|
`Mail.read_from_string(request.body.read)`.
|
103
153
|
|
154
|
+
## Search Command ##
|
155
|
+
|
156
|
+
This setting allows configuration of the IMAP search command sent to the server. This still defaults 'UNSEEN'. You may find that 'NEW' works better for you.
|
157
|
+
|
158
|
+
## IMAP Server Configuration ##
|
159
|
+
|
160
|
+
You can set per-mailbox configuration for the IMAP server's `host` (default: 'imap.gmail.com'), `port` (default: 993), and `ssl` (default: true).
|
161
|
+
|
162
|
+
If you're seeing the error `Please log in via your web browser: https://support.google.com/mail/accounts/answer/78754 (Failure)`, you need to configure your Gmail account to allow less secure apps to access it: https://support.google.com/accounts/answer/6010255.
|
163
|
+
|
104
164
|
## Running in Production ##
|
105
165
|
|
106
166
|
I suggest running with either upstart or init.d. Check out this wiki page for some example scripts for both: https://github.com/tpitale/mail_room/wiki/Init-Scripts-for-Running-mail_room
|
data/lib/mail_room/cli.rb
CHANGED
@@ -2,16 +2,21 @@ module MailRoom
|
|
2
2
|
# Wraps configuration for a set of individual mailboxes with global config
|
3
3
|
# @author Tony Pitale
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :mailboxes, :daemonize, :log_path, :pid_path
|
5
|
+
attr_accessor :mailboxes, :daemonize, :log_path, :pid_path, :quiet
|
6
6
|
|
7
7
|
# Initialize a new configuration of mailboxes
|
8
8
|
def initialize(options={})
|
9
9
|
self.mailboxes = []
|
10
|
+
self.quiet = options.fetch(:quiet, false)
|
10
11
|
|
11
12
|
if options.has_key?(:config_path)
|
12
|
-
|
13
|
+
begin
|
14
|
+
config_file = YAML.load_file(options[:config_path])
|
13
15
|
|
14
|
-
|
16
|
+
set_mailboxes(config_file[:mailboxes])
|
17
|
+
rescue => e
|
18
|
+
raise e unless quiet
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
@@ -7,17 +7,27 @@ module MailRoom
|
|
7
7
|
# LetterOpener Delivery method
|
8
8
|
# @author Tony Pitale
|
9
9
|
class LetterOpener
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
Options = Struct.new(:location) do
|
11
|
+
def initialize(mailbox)
|
12
|
+
location = mailbox.location || mailbox.delivery_options[:location]
|
13
|
+
|
14
|
+
super(location)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Build a new delivery, hold the delivery options
|
19
|
+
# @param [MailRoom::Delivery::LetterOpener::Options]
|
20
|
+
def initialize(delivery_options)
|
21
|
+
@delivery_options = delivery_options
|
14
22
|
end
|
15
23
|
|
16
24
|
# Trigger `LetterOpener` to deliver our message
|
17
25
|
# @param message [String] the email message as a string, RFC822 format
|
18
26
|
def deliver(message)
|
19
|
-
method = ::LetterOpener::DeliveryMethod.new(:location => @
|
27
|
+
method = ::LetterOpener::DeliveryMethod.new(:location => @delivery_options.location)
|
20
28
|
method.deliver!(Mail.read_from_string(message))
|
29
|
+
|
30
|
+
true
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
@@ -5,11 +5,19 @@ module MailRoom
|
|
5
5
|
# File/STDOUT Logger Delivery method
|
6
6
|
# @author Tony Pitale
|
7
7
|
class Logger
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
Options = Struct.new(:log_path) do
|
9
|
+
def initialize(mailbox)
|
10
|
+
log_path = mailbox.log_path || mailbox.delivery_options[:log_path]
|
11
|
+
|
12
|
+
super(log_path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Build a new delivery, hold the delivery options
|
17
|
+
# open a file or stdout for IO depending on the options
|
18
|
+
# @param [MailRoom::Delivery::Logger::Options]
|
19
|
+
def initialize(delivery_options)
|
20
|
+
io = File.open(delivery_options.log_path, 'a') if delivery_options.log_path
|
13
21
|
io ||= STDOUT
|
14
22
|
|
15
23
|
io.sync = true
|
@@ -21,6 +29,8 @@ module MailRoom
|
|
21
29
|
# @param message [String] the email message as a string, RFC822 format
|
22
30
|
def deliver(message)
|
23
31
|
@logger.info message
|
32
|
+
|
33
|
+
true
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
@@ -3,12 +3,19 @@ module MailRoom
|
|
3
3
|
# Noop Delivery method
|
4
4
|
# @author Tony Pitale
|
5
5
|
class Noop
|
6
|
+
Options = Class.new do
|
7
|
+
def initialize(*)
|
8
|
+
super()
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
6
12
|
# build a new delivery, do nothing
|
7
13
|
def initialize(*)
|
8
14
|
end
|
9
15
|
|
10
16
|
# accept the delivery, do nothing
|
11
17
|
def deliver(*)
|
18
|
+
true
|
12
19
|
end
|
13
20
|
end
|
14
21
|
end
|
@@ -5,24 +5,35 @@ module MailRoom
|
|
5
5
|
# Postback Delivery method
|
6
6
|
# @author Tony Pitale
|
7
7
|
class Postback
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
Options = Struct.new(:delivery_url, :delivery_token) do
|
9
|
+
def initialize(mailbox)
|
10
|
+
delivery_url = mailbox.delivery_url || mailbox.delivery_options[:delivery_url]
|
11
|
+
delivery_token = mailbox.delivery_token || mailbox.delivery_options[:delivery_token]
|
12
|
+
|
13
|
+
super(delivery_url, delivery_token)
|
14
|
+
end
|
12
15
|
end
|
13
16
|
|
14
|
-
#
|
17
|
+
# Build a new delivery, hold the delivery options
|
18
|
+
# @param [MailRoom::Delivery::Postback::Options]
|
19
|
+
def initialize(delivery_options)
|
20
|
+
@delivery_options = delivery_options
|
21
|
+
end
|
22
|
+
|
23
|
+
# deliver the message using Faraday to the configured delivery_options url
|
15
24
|
# @param message [String] the email message as a string, RFC822 format
|
16
25
|
def deliver(message)
|
17
26
|
connection = Faraday.new
|
18
|
-
connection.token_auth @
|
27
|
+
connection.token_auth @delivery_options.delivery_token
|
19
28
|
|
20
29
|
connection.post do |request|
|
21
|
-
request.url @
|
30
|
+
request.url @delivery_options.delivery_url
|
22
31
|
request.body = message
|
23
32
|
# request.options[:timeout] = 3
|
24
33
|
# request.headers['Content-Type'] = 'text/plain'
|
25
34
|
end
|
35
|
+
|
36
|
+
true
|
26
37
|
end
|
27
38
|
end
|
28
39
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "redis"
|
2
|
+
require "securerandom"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module MailRoom
|
6
|
+
module Delivery
|
7
|
+
# Postback Delivery method
|
8
|
+
# @author Tony Pitale
|
9
|
+
class Sidekiq
|
10
|
+
Options = Struct.new(:redis_url, :namespace, :queue, :worker) do
|
11
|
+
def initialize(mailbox)
|
12
|
+
redis_url = mailbox.delivery_options[:redis_url]
|
13
|
+
namespace = mailbox.delivery_options[:namespace]
|
14
|
+
queue = mailbox.delivery_options[:queue] || "default"
|
15
|
+
worker = mailbox.delivery_options[:worker] || "redis://localhost:6379"
|
16
|
+
|
17
|
+
super(redis_url, namespace, queue, worker)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :options
|
22
|
+
|
23
|
+
# Build a new delivery, hold the mailbox configuration
|
24
|
+
# @param [MailRoom::Mailbox]
|
25
|
+
def initialize(options)
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
# deliver the message by pushing it onto the configured Sidekiq queue
|
30
|
+
# @param message [String] the email message as a string, RFC822 format
|
31
|
+
def deliver(message)
|
32
|
+
item = item_for(message)
|
33
|
+
|
34
|
+
client.lpush("queue:#{options.queue}", JSON.generate(item))
|
35
|
+
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def client
|
42
|
+
client = Redis.new(url: options.redis_url)
|
43
|
+
|
44
|
+
namespace = options.namespace
|
45
|
+
if namespace
|
46
|
+
require 'redis/namespace'
|
47
|
+
Redis::Namespace.new(namespace, redis: client)
|
48
|
+
else
|
49
|
+
client
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def item_for(message)
|
54
|
+
{
|
55
|
+
'class' => options.worker,
|
56
|
+
'args' => [message],
|
57
|
+
|
58
|
+
'queue' => options.queue,
|
59
|
+
'jid' => SecureRandom.hex(12),
|
60
|
+
'retry' => false,
|
61
|
+
'enqueued_at' => Time.now.to_f
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/mail_room/mailbox.rb
CHANGED
@@ -1,25 +1,42 @@
|
|
1
1
|
module MailRoom
|
2
2
|
# Mailbox Configuration fields
|
3
|
-
|
3
|
+
MAILBOX_FIELDS = [
|
4
4
|
:email,
|
5
5
|
:password,
|
6
|
+
:host,
|
7
|
+
:port,
|
8
|
+
:ssl,
|
9
|
+
:search_command,
|
6
10
|
:name,
|
11
|
+
:delete_after_delivery,
|
7
12
|
:delivery_method, # :noop, :logger, :postback, :letter_opener
|
8
13
|
:log_path, # for logger
|
9
14
|
:delivery_url, # for postback
|
10
15
|
:delivery_token, # for postback
|
11
|
-
:location # for letter_opener
|
16
|
+
:location, # for letter_opener
|
17
|
+
:delivery_options
|
12
18
|
]
|
13
19
|
|
14
20
|
# Holds configuration for each of the email accounts we wish to monitor
|
15
21
|
# and deliver email to when new emails arrive over imap
|
16
|
-
Mailbox = Struct.new(*
|
22
|
+
Mailbox = Struct.new(*MAILBOX_FIELDS) do
|
23
|
+
# Default attributes for the mailbox configuration
|
24
|
+
DEFAULTS = {
|
25
|
+
:search_command => 'UNSEEN',
|
26
|
+
:delivery_method => 'postback',
|
27
|
+
:host => 'imap.gmail.com',
|
28
|
+
:port => 993,
|
29
|
+
:ssl => true,
|
30
|
+
:delete_after_delivery => false,
|
31
|
+
:delivery_options => {}
|
32
|
+
}
|
33
|
+
|
17
34
|
# Store the configuration and require the appropriate delivery method
|
18
35
|
# @param attributes [Hash] configuration options
|
19
36
|
def initialize(attributes={})
|
20
|
-
super(*attributes.values_at(*members))
|
37
|
+
super(*DEFAULTS.merge(attributes).values_at(*members))
|
21
38
|
|
22
|
-
require_relative("./delivery/#{(delivery_method
|
39
|
+
require_relative("./delivery/#{(delivery_method)}")
|
23
40
|
end
|
24
41
|
|
25
42
|
# move to a mailbox deliverer class?
|
@@ -31,6 +48,8 @@ module MailRoom
|
|
31
48
|
Delivery::Logger
|
32
49
|
when "letter_opener"
|
33
50
|
Delivery::LetterOpener
|
51
|
+
when "sidekiq"
|
52
|
+
Delivery::Sidekiq
|
34
53
|
else
|
35
54
|
Delivery::Postback
|
36
55
|
end
|
@@ -39,7 +58,12 @@ module MailRoom
|
|
39
58
|
# deliver the imap email message
|
40
59
|
# @param message [Net::IMAP::FetchData]
|
41
60
|
def deliver(message)
|
42
|
-
delivery_klass.new(
|
61
|
+
delivery_klass.new(parsed_delivery_options).deliver(message.attr['RFC822'])
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def parsed_delivery_options
|
66
|
+
delivery_klass::Options.new(self)
|
43
67
|
end
|
44
68
|
end
|
45
69
|
end
|
@@ -18,8 +18,14 @@ module MailRoom
|
|
18
18
|
# puts msg.attr['RFC822']
|
19
19
|
|
20
20
|
# loop over delivery methods and deliver each
|
21
|
-
@mailbox.deliver(msg)
|
21
|
+
delivered = @mailbox.deliver(msg)
|
22
|
+
|
23
|
+
if delivered && @mailbox.delete_after_delivery
|
24
|
+
@imap.store(msg.seqno, "+FLAGS", [Net::IMAP::DELETED])
|
25
|
+
end
|
22
26
|
end
|
27
|
+
|
28
|
+
@imap.expunge if @mailbox.delete_after_delivery
|
23
29
|
end
|
24
30
|
|
25
31
|
private
|
@@ -39,7 +45,7 @@ module MailRoom
|
|
39
45
|
# search for all new (unseen) message ids
|
40
46
|
# @return [Array<Integer>] message ids
|
41
47
|
def new_message_ids
|
42
|
-
@imap.search(
|
48
|
+
@imap.search(@mailbox.search_command)
|
43
49
|
end
|
44
50
|
|
45
51
|
# @private
|
@@ -17,7 +17,7 @@ module MailRoom
|
|
17
17
|
|
18
18
|
# build a net/imap connection to google imap
|
19
19
|
def imap
|
20
|
-
@imap ||= Net::IMAP.new(
|
20
|
+
@imap ||= Net::IMAP.new(@mailbox.host, :port => @mailbox.port, :ssl => @mailbox.ssl)
|
21
21
|
end
|
22
22
|
|
23
23
|
# build a handler to process mailbox messages
|
@@ -113,6 +113,9 @@ module MailRoom
|
|
113
113
|
|
114
114
|
@running = true
|
115
115
|
|
116
|
+
# prefetch messages before first idle
|
117
|
+
process_mailbox
|
118
|
+
|
116
119
|
self.idling_thread = Thread.start do
|
117
120
|
while(running?) do
|
118
121
|
begin
|
data/lib/mail_room/version.rb
CHANGED
data/mail_room.gemspec
CHANGED
@@ -22,12 +22,13 @@ describe MailRoom::MailboxHandler do
|
|
22
22
|
it 'returns no messages if there are no ids' do
|
23
23
|
imap.stubs(:search).returns([])
|
24
24
|
imap.stubs(:fetch)
|
25
|
+
mailbox.search_command = 'NEW'
|
25
26
|
mailbox.stubs(:deliver)
|
26
27
|
|
27
28
|
handler = MailRoom::MailboxHandler.new(mailbox, imap)
|
28
29
|
handler.process
|
29
30
|
|
30
|
-
imap.should have_received(:search).with('
|
31
|
+
imap.should have_received(:search).with('NEW')
|
31
32
|
imap.should have_received(:fetch).never
|
32
33
|
mailbox.should have_received(:deliver).never
|
33
34
|
end
|
@@ -1,32 +1,36 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe MailRoom::MailboxWatcher do
|
4
|
+
let(:mailbox) {MailRoom::Mailbox.new}
|
5
|
+
|
4
6
|
describe '#running?' do
|
5
7
|
it 'is false by default' do
|
6
|
-
watcher = MailRoom::MailboxWatcher.new(
|
8
|
+
watcher = MailRoom::MailboxWatcher.new(mailbox)
|
7
9
|
watcher.running?.should eq(false)
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
13
|
describe '#logged_in?' do
|
12
14
|
it 'is false by default' do
|
13
|
-
watcher = MailRoom::MailboxWatcher.new(
|
15
|
+
watcher = MailRoom::MailboxWatcher.new(mailbox)
|
14
16
|
watcher.logged_in?.should eq(false)
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
20
|
describe '#idling?' do
|
19
21
|
it 'is false by default' do
|
20
|
-
watcher = MailRoom::MailboxWatcher.new(
|
22
|
+
watcher = MailRoom::MailboxWatcher.new(mailbox)
|
21
23
|
watcher.idling?.should eq(false)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
27
|
describe '#imap' do
|
28
|
+
let(:mailbox) {MailRoom::Mailbox.new}
|
29
|
+
|
26
30
|
it 'builds a new Net::IMAP object' do
|
27
31
|
Net::IMAP.stubs(:new).returns('imap')
|
28
32
|
|
29
|
-
MailRoom::MailboxWatcher.new(
|
33
|
+
MailRoom::MailboxWatcher.new(mailbox).imap.should eq('imap')
|
30
34
|
|
31
35
|
Net::IMAP.should have_received(:new).with('imap.gmail.com', :port => 993, :ssl => true)
|
32
36
|
end
|
@@ -157,11 +161,13 @@ describe MailRoom::MailboxWatcher do
|
|
157
161
|
end
|
158
162
|
|
159
163
|
describe '#run' do
|
160
|
-
let(:watcher) {MailRoom::MailboxWatcher.new(
|
164
|
+
let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
|
161
165
|
|
162
166
|
before :each do
|
167
|
+
Net::IMAP.stubs(:new).returns(stub)
|
163
168
|
Thread.stubs(:start).yields.returns(stub(:abort_on_exception=))
|
164
169
|
watcher.stubs(:setup)
|
170
|
+
watcher.handler.stubs(:process)
|
165
171
|
end
|
166
172
|
|
167
173
|
it 'sets up' do
|
@@ -184,7 +190,6 @@ describe MailRoom::MailboxWatcher do
|
|
184
190
|
watcher.stubs(:running?).returns(true, false)
|
185
191
|
|
186
192
|
watcher.stubs(:idle)
|
187
|
-
watcher.stubs(:process_mailbox)
|
188
193
|
|
189
194
|
watcher.run
|
190
195
|
|
@@ -195,7 +200,6 @@ describe MailRoom::MailboxWatcher do
|
|
195
200
|
watcher.stubs(:running?).returns(true, false)
|
196
201
|
|
197
202
|
watcher.stubs(:idle)
|
198
|
-
watcher.stubs(:process_mailbox)
|
199
203
|
|
200
204
|
watcher.run
|
201
205
|
|
@@ -206,16 +210,15 @@ describe MailRoom::MailboxWatcher do
|
|
206
210
|
watcher.stubs(:running?).returns(true, false)
|
207
211
|
|
208
212
|
watcher.stubs(:idle)
|
209
|
-
watcher.stubs(:process_mailbox)
|
210
213
|
|
211
214
|
watcher.run
|
212
215
|
|
213
|
-
watcher.should have_received(:
|
216
|
+
watcher.handler.should have_received(:process).times(2)
|
214
217
|
end
|
215
218
|
end
|
216
219
|
|
217
220
|
describe '#quit' do
|
218
|
-
let(:watcher) {MailRoom::MailboxWatcher.new(
|
221
|
+
let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
|
219
222
|
|
220
223
|
it 'stops idling' do
|
221
224
|
watcher.stubs(:stop_idling)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail_room
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Pitale
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: redis
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description: mail_room will proxy email (gmail) from IMAP to a delivery method
|
126
140
|
email:
|
127
141
|
- tpitale@gmail.com
|
@@ -134,6 +148,7 @@ files:
|
|
134
148
|
- ".ruby-version"
|
135
149
|
- ".travis.yml"
|
136
150
|
- CHANGELOG.md
|
151
|
+
- CODE_OF_CONDUCT.md
|
137
152
|
- Gemfile
|
138
153
|
- LICENSE.txt
|
139
154
|
- README.md
|
@@ -147,6 +162,7 @@ files:
|
|
147
162
|
- lib/mail_room/delivery/logger.rb
|
148
163
|
- lib/mail_room/delivery/noop.rb
|
149
164
|
- lib/mail_room/delivery/postback.rb
|
165
|
+
- lib/mail_room/delivery/sidekiq.rb
|
150
166
|
- lib/mail_room/mailbox.rb
|
151
167
|
- lib/mail_room/mailbox_handler.rb
|
152
168
|
- lib/mail_room/mailbox_watcher.rb
|