mailhandler 1.0.36 → 1.0.37

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.
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