mailhandler 1.0.36 → 1.0.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Rakefile +2 -2
  4. data/lib/mailhandler.rb +13 -37
  5. data/lib/mailhandler/errors.rb +1 -5
  6. data/lib/mailhandler/receiver.rb +4 -22
  7. data/lib/mailhandler/receiving/base.rb +16 -45
  8. data/lib/mailhandler/receiving/filelist/base.rb +25 -49
  9. data/lib/mailhandler/receiving/filelist/filter/base.rb +10 -52
  10. data/lib/mailhandler/receiving/filelist/filter/email.rb +4 -44
  11. data/lib/mailhandler/receiving/folder.rb +16 -54
  12. data/lib/mailhandler/receiving/imap.rb +34 -78
  13. data/lib/mailhandler/receiving/mail.rb +5 -19
  14. data/lib/mailhandler/receiving/notification/console.rb +2 -18
  15. data/lib/mailhandler/receiving/notification/email.rb +5 -28
  16. data/lib/mailhandler/receiving/notification/email/content.rb +9 -20
  17. data/lib/mailhandler/receiving/notification/email/states.rb +1 -36
  18. data/lib/mailhandler/receiving/observer.rb +5 -16
  19. data/lib/mailhandler/sender.rb +2 -14
  20. data/lib/mailhandler/sending/api.rb +1 -7
  21. data/lib/mailhandler/sending/api_batch.rb +1 -13
  22. data/lib/mailhandler/sending/base.rb +1 -13
  23. data/lib/mailhandler/sending/smtp.rb +20 -22
  24. data/lib/mailhandler/version.rb +2 -2
  25. data/mailhandler.gemspec +14 -17
  26. data/readme.md +33 -8
  27. data/spec/spec_helper.rb +1 -5
  28. data/spec/unit/mailhandler/receiver_spec.rb +8 -30
  29. data/spec/unit/mailhandler/receiving/base_spec.rb +4 -14
  30. data/spec/unit/mailhandler/receiving/folder_spec.rb +61 -155
  31. data/spec/unit/mailhandler/receiving/imap_spec.rb +18 -42
  32. data/spec/unit/mailhandler/receiving/notification/console_spec.rb +6 -16
  33. data/spec/unit/mailhandler/receiving/notification/email/content_spec.rb +10 -44
  34. data/spec/unit/mailhandler/receiving/notification/email_spec.rb +9 -15
  35. data/spec/unit/mailhandler/sender_spec.rb +12 -23
  36. data/spec/unit/mailhandler/sending/sender_api_batch_spec.rb +7 -19
  37. data/spec/unit/mailhandler/sending/sender_api_spec.rb +4 -14
  38. data/spec/unit/mailhandler/sending/sender_smtp_spec.rb +24 -6
  39. data/spec/unit/mailhandler_spec.rb +33 -25
  40. metadata +2 -2
@@ -1,11 +1,8 @@
1
1
  module Mail
2
-
3
2
  class IMAP
4
-
5
3
  attr_accessor :imap_connection
6
4
 
7
- def find_emails(options={}, &block)
8
-
5
+ def find_emails(options = {}, &block)
9
6
  options = validate_options(options)
10
7
  options[:read_only] ? imap_connection.examine(options[:mailbox]) : imap_connection.select(options[:mailbox])
11
8
  uids = imap_connection.uid_search(options[:keys])
@@ -13,12 +10,11 @@ module Mail
13
10
  uids.reverse! if options[:what].to_sym == :last
14
11
  uids = uids.first(options[:count]) if options[:count].is_a?(Integer)
15
12
  uids.reverse! if (options[:what].to_sym == :last && options[:order].to_sym == :asc) ||
16
- (options[:what].to_sym != :last && options[:order].to_sym == :desc)
13
+ (options[:what].to_sym != :last && options[:order].to_sym == :desc)
17
14
 
18
15
  if block_given?
19
16
 
20
17
  uids.each do |uid|
21
-
22
18
  uid = options[:uid].to_i unless options[:uid].nil?
23
19
  fetchdata = imap_connection.uid_fetch(uid, ['RFC822'])[0]
24
20
  new_message = Mail.new(fetchdata.attr['RFC822'])
@@ -30,9 +26,8 @@ module Mail
30
26
  yield new_message
31
27
  end
32
28
 
33
- imap_connection.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete?
29
+ imap_connection.uid_store(uid, '+FLAGS', [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete?
34
30
  break unless options[:uid].nil?
35
-
36
31
  end
37
32
 
38
33
  imap_connection.expunge if options[:delete_after_find]
@@ -42,25 +37,21 @@ module Mail
42
37
  emails = []
43
38
 
44
39
  uids.each do |uid|
45
-
46
40
  uid = options[:uid].to_i unless options[:uid].nil?
47
41
  fetchdata = imap_connection.uid_fetch(uid, ['RFC822'])[0]
48
42
  emails << Mail.new(fetchdata.attr['RFC822'])
49
- imap_connection.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find]
43
+ imap_connection.uid_store(uid, '+FLAGS', [Net::IMAP::DELETED]) if options[:delete_after_find]
50
44
  break unless options[:uid].nil?
51
-
52
45
  end
53
46
 
54
47
  imap_connection.expunge if options[:delete_after_find]
55
48
  emails.size == 1 && options[:count] == 1 ? emails.first : emails
56
49
 
57
50
  end
58
-
59
51
  end
60
52
 
61
53
  # Start an IMAP session
62
- def connect(config=Mail::Configuration.instance)
63
-
54
+ def connect(_config = Mail::Configuration.instance)
64
55
  @imap_connection = Net::IMAP.new(settings[:address], settings[:port], settings[:enable_ssl], nil, false)
65
56
 
66
57
  if settings[:authentication].nil?
@@ -70,19 +61,14 @@ module Mail
70
61
  # (see also http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/net/imap_connection/rdoc/classes/Net/IMAP.html#M000718)
71
62
  imap_connection.authenticate(settings[:authentication], settings[:user_name], settings[:password])
72
63
  end
73
-
74
64
  end
75
65
 
76
66
  def disconnect
77
-
78
67
  if defined?(imap_connection) && imap_connection && !imap_connection.disconnected?
79
68
 
80
69
  imap_connection.disconnect
81
70
 
82
71
  end
83
-
84
72
  end
85
-
86
73
  end
87
-
88
74
  end
@@ -1,44 +1,28 @@
1
1
  module MailHandler
2
-
3
2
  module Receiving
4
-
5
3
  module Notification
6
-
7
4
  class Console
8
-
9
5
  def notify(search)
10
-
11
6
  output_delay Time.now - search.started_at
12
-
13
7
  end
14
8
 
15
9
  private
16
10
 
17
11
  module Seconds
18
-
19
12
  TO_SHOW = 10
20
-
21
13
  end
22
14
 
23
15
  # print to screen delay length
24
16
  def output_delay(delay)
25
-
26
17
  delay_seconds = delay.to_i
27
- output(delay_seconds) if [0,1].include? (delay_seconds % Seconds::TO_SHOW)
28
-
18
+ output(delay_seconds) if [0, 1].include? (delay_seconds % Seconds::TO_SHOW)
29
19
  end
30
20
 
31
21
  # print to screen delay length
32
22
  def output(delay)
33
-
34
- puts " email delay: #{'%03d' % delay} seconds"
35
-
23
+ puts " email delay: #{format('%03d', delay)} seconds"
36
24
  end
37
-
38
25
  end
39
-
40
26
  end
41
-
42
27
  end
43
-
44
28
  end
@@ -3,22 +3,18 @@ require_relative 'email/states'
3
3
  require_relative '../../errors'
4
4
 
5
5
  module MailHandler
6
-
7
6
  module Receiving
8
-
9
7
  module Notification
10
-
11
8
  class Email
12
-
13
- attr_reader :sender,
9
+ attr_accessor :sender,
14
10
  :from,
15
11
  :contacts,
16
12
  :min_time_to_notify,
17
- :max_time_to_notify,
18
- :current_state
13
+ :max_time_to_notify
19
14
 
20
- def initialize(sender, from, to, min_time_to_notify = 60)
15
+ attr_reader :current_state
21
16
 
17
+ def initialize(sender, from, to, min_time_to_notify = 60)
22
18
  @min_time_to_notify = min_time_to_notify
23
19
 
24
20
  @sender = sender
@@ -26,29 +22,22 @@ module MailHandler
26
22
  @contacts = to
27
23
  init_state
28
24
  set_content_handler(EmailContent.new)
29
-
30
25
  end
31
26
 
32
27
  def notify(search)
33
-
34
28
  @max_time_to_notify = search.max_duration
35
29
  init_state if Time.now - search.started_at < min_time_to_notify
36
30
  @current_state.notify(search)
37
-
38
31
  end
39
32
 
40
33
  def set_state(state)
41
-
42
34
  @current_state = state
43
-
44
35
  end
45
36
 
46
37
  def send_email(type, search)
47
-
48
38
  verify_email_type(type)
49
39
  content = @content_handler.retrieve(type, search.options, Time.now - search.started_at, from, contacts)
50
40
  sender.send_email content
51
-
52
41
  end
53
42
 
54
43
  # Allow users to specify their own content classes.
@@ -57,30 +46,18 @@ module MailHandler
57
46
  @content_handler = content_handler
58
47
  end
59
48
 
60
-
61
49
  private
62
50
 
63
51
  def init_state
64
-
65
52
  @current_state = Notification::NoDelay.new(self)
66
-
67
53
  end
68
54
 
69
- EMAIL_TYPES = [:delayed, :received]
55
+ EMAIL_TYPES = %i[delayed received].freeze
70
56
 
71
57
  def verify_email_type(type)
72
-
73
58
  raise MailHandler::TypeError, "Incorrect type: #{type}, allowed types: #{EMAIL_TYPES}." unless EMAIL_TYPES.include? type
74
-
75
59
  end
76
-
77
60
  end
78
-
79
61
  end
80
-
81
62
  end
82
-
83
63
  end
84
-
85
-
86
-
@@ -1,52 +1,41 @@
1
1
  require 'mail'
2
2
 
3
3
  module MailHandler
4
-
5
4
  module Receiving
6
-
7
5
  module Notification
8
-
9
6
  class EmailContent
10
-
11
7
  # @param [Symbol] type - notification type
12
8
  # @param [Hash] options - search options used for searching for an email
13
9
  # @param [Int] delay - delay in seconds
14
10
  # @param [String] from - email address
15
11
  # @param [String] to - email address
16
12
  def retrieve(type, options, delay, from, to)
17
-
18
13
  mail = Mail.new
19
14
  mail.from = from
20
15
  mail.to = to
21
- delay = (delay.to_f/60).round(2)
16
+ delay = (delay.to_f / 60).round(2)
22
17
 
23
18
  case type
24
19
 
25
- when :received
20
+ when :received
26
21
 
27
- mail.subject = "Received - delay was #{delay} minutes"
28
- mail.body = "Received - delay was #{delay} minutes - search by #{options}"
22
+ mail.subject = "Received - delay was #{delay} minutes"
23
+ mail.body = "Received - delay was #{delay} minutes - search by #{options}"
29
24
 
30
- when :delayed
25
+ when :delayed
31
26
 
32
- mail.subject = "Over #{delay} minutes delay"
33
- mail.body = "Over #{delay} minutes delay - search by #{options}"
27
+ mail.subject = "Over #{delay} minutes delay"
28
+ mail.body = "Over #{delay} minutes delay - search by #{options}"
34
29
 
35
- else
30
+ else
36
31
 
37
- raise StandardError, "Incorrect type: #{type}"
32
+ raise StandardError, "Incorrect type: #{type}"
38
33
 
39
34
  end
40
35
 
41
36
  mail
42
-
43
37
  end
44
-
45
-
46
38
  end
47
-
48
39
  end
49
-
50
40
  end
51
-
52
41
  end
@@ -2,68 +2,49 @@ require_relative '../email'
2
2
  require_relative '../../../errors'
3
3
 
4
4
  module MailHandler
5
-
6
5
  module Receiving
7
-
8
6
  module Notification
9
-
10
7
  class DelayState
11
-
12
8
  attr_accessor :context,
13
9
  :notified
14
10
 
15
11
  def initialize(context)
16
-
17
12
  @context = context
18
-
19
13
  end
20
14
 
21
15
  def notification_fired
22
-
23
16
  @notified = true
24
-
25
17
  end
26
18
 
27
- def notify(search)
28
-
19
+ def notify(_search)
29
20
  raise MailHandler::InterfaceError, 'notify(search) interface has to be implemented.'
30
-
31
21
  end
32
22
 
33
23
  protected
34
24
 
35
25
  def send_notification_email(type, search)
36
-
37
26
  unless notified
38
27
 
39
28
  context.send_email(type, search)
40
29
  notification_fired
41
30
 
42
31
  end
43
-
44
32
  end
45
-
46
33
  end
47
34
 
48
35
  class NoDelay < DelayState
49
-
50
36
  def notify(search)
51
-
52
37
  if Time.now - search.started_at >= context.min_time_to_notify
53
38
 
54
39
  context.set_state(Delay.new(context))
55
40
  context.notify(search)
56
41
 
57
42
  end
58
-
59
43
  end
60
-
61
44
  end
62
45
 
63
46
  class Delay < DelayState
64
-
65
47
  def notify(search)
66
-
67
48
  if search.result
68
49
 
69
50
  context.set_state(Received.new(context))
@@ -79,36 +60,20 @@ module MailHandler
79
60
  send_notification_email(:delayed, search)
80
61
 
81
62
  end
82
-
83
63
  end
84
-
85
64
  end
86
65
 
87
66
  class MaxDelay < DelayState
88
-
89
67
  def notify(search)
90
-
91
68
  send_notification_email(:delayed, search)
92
-
93
69
  end
94
-
95
70
  end
96
71
 
97
72
  class Received < DelayState
98
-
99
73
  def notify(search)
100
-
101
74
  send_notification_email(:received, search)
102
-
103
75
  end
104
-
105
76
  end
106
-
107
77
  end
108
-
109
78
  end
110
-
111
79
  end
112
-
113
-
114
-
@@ -1,37 +1,26 @@
1
1
  module MailHandler
2
-
3
2
  module Receiving
4
-
5
3
  module Observer
6
-
7
4
  def init_observer
5
+ @observers = []
6
+ end
8
7
 
9
- @observers = Array.new
10
-
8
+ def get_observers()
9
+ @observers
11
10
  end
12
11
 
13
12
  def add_observer(observer)
14
-
15
- @observers ||= Array.new
13
+ @observers ||= []
16
14
  @observers << observer
17
-
18
15
  end
19
16
 
20
17
  def delete_observer(observer)
21
-
22
18
  @observers.delete(observer) if @observers
23
-
24
19
  end
25
20
 
26
21
  def notify_observers(search)
27
-
28
22
  @observers.each { |observer| observer.notify(search) } if @observers
29
-
30
23
  end
31
-
32
24
  end
33
-
34
25
  end
35
-
36
26
  end
37
-
@@ -4,9 +4,7 @@ require_relative 'sending/api_batch'
4
4
 
5
5
  # Class for sending email, and storing details about the sending.
6
6
  module MailHandler
7
-
8
7
  class Sender
9
-
10
8
  attr_accessor :dispatcher,
11
9
  :sending
12
10
 
@@ -15,44 +13,34 @@ module MailHandler
15
13
  # @param [int] - how long sending lasted, seconds
16
14
  # @param [Object] - sending response message
17
15
  # @param [Mail] - email/emails sent
18
- Sending = Struct.new( :started_at, :finished_at, :duration, :response, :email)
16
+ Sending = Struct.new(:started_at, :finished_at, :duration, :response, :email)
19
17
 
20
18
  # @param [Sending::Oblect] dispatcher - sender type used for sending email
21
19
  def initialize(dispatcher)
22
-
23
20
  @dispatcher = dispatcher
24
21
  @sending = Sending.new
25
-
26
22
  end
27
23
 
28
24
  def send_email(email)
29
-
30
25
  init_sending_details(email)
31
26
  response = dispatcher.send(email)
32
27
  update_sending_details(response)
33
28
 
34
29
  response
35
-
36
30
  end
37
31
 
38
32
  private
39
33
 
40
34
  def init_sending_details(email)
41
-
42
35
  @sending = Sending.new
43
36
  @sending.started_at = Time.now
44
37
  @sending.email = email
45
-
46
38
  end
47
39
 
48
40
  def update_sending_details(response)
49
-
50
41
  @sending.finished_at = Time.now
51
42
  @sending.duration = @sending.finished_at - @sending.started_at
52
43
  @sending.response = response
53
-
54
44
  end
55
-
56
45
  end
57
-
58
- end
46
+ end