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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e3e402f4b95ef68f6d3e14782e9df18f45a7ff0
4
- data.tar.gz: 6285982ac47bfafa48410c2a1c98f6d21c3f0510
3
+ metadata.gz: 8f4daed68e55b824dbcad5321f41fd3aa4374769
4
+ data.tar.gz: 12934cc4aa8d94d6647c2049291f40910b939a7b
5
5
  SHA512:
6
- metadata.gz: e132dcab6529c17c696390bac5c052d92ea91d8d718715d575a28342da1f85b57d6bdd370b737c5494ae82c0e64f9cc279287d825b11c0fbfee24e2d44554524
7
- data.tar.gz: 3daf78e47d35f23add73b1484667f1b5f9b54385013924ae3ce2ee56778bca044856a4b256665dfb342efc83ab0e41558307eb64e97ee6ec1199e519ad6ed4c0
6
+ metadata.gz: 5f3f94f0de2600cc2d99d8cfeeb43f3b33ec74e5917a0a045b103f0f2c63ccb52ecdcc1bd0a77300ea13de5f8820d834c679edfc6e955a01754d2dcf72a95f09
7
+ data.tar.gz: 23355aac8afd26e73c3f04b34a75dd65d823e78cdf8f95cce040df3482a5cf1f14c18d276726b42df23d86eb626a44b58bd26c716cc42fd65b3de2c9fb0caf33
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  # A sample Gemfile
2
2
  source 'https://rubygems.org'
3
3
 
4
- gem 'rspec'
5
4
  gem 'mail'
6
5
  gem 'postmark'
7
- gem 'pry'
6
+ gem 'pry'
7
+ gem 'rspec'
data/Rakefile CHANGED
@@ -1,3 +1,3 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
- RSpec::Core::RakeTask.new(:default)
3
+ RSpec::Core::RakeTask.new(:default)
@@ -8,31 +8,26 @@ require_relative 'mailhandler/errors'
8
8
  # Main MailHandler class, for creating sender and receiver objects.
9
9
  # Sender objects for sending emails, receiver objects for searching and receiving emails.
10
10
  module MailHandler
11
-
12
- extend self
11
+ module_function
13
12
 
14
13
  # sending accessor
15
14
  # @return [Object] - sender for sending emails
16
15
  def sender(type = :postmark_api)
17
-
18
16
  handler = Handler.new
19
17
  handler.init_sender(type)
20
18
  yield(handler.sender.dispatcher) if block_given?
21
19
 
22
20
  handler.sender
23
-
24
21
  end
25
22
 
26
23
  # receiving accessor
27
24
  # @return [Object] - receiver for searching emails
28
25
  def receiver(type = :folder, notifications = [])
29
-
30
26
  handler = Handler.new
31
27
  handler.init_receiver(type, notifications)
32
28
  yield(handler.receiver.checker) if block_given?
33
29
 
34
30
  handler.receiver
35
-
36
31
  end
37
32
 
38
33
  # Holder for receiving and sending handlers
@@ -40,92 +35,73 @@ module MailHandler
40
35
  # @param [Receiving::Class] receiver
41
36
  # @param [Sending::Class] sender
42
37
  def handler(receiver, sender)
43
-
44
38
  handler = Handler.new
45
39
  handler.handler(receiver, sender)
46
-
47
40
  end
48
41
 
49
42
  # main handler class for creating sender, receiver handlers
50
43
  class Handler
51
-
52
44
  attr_accessor :sender,
53
45
  :receiver
54
46
 
55
47
  def init_sender(type = :postmark_api)
56
-
57
48
  verify_type(type, SENDER_TYPES)
58
49
  @sender = MailHandler::Sender.new(SENDER_TYPES[type].new)
59
-
60
50
  end
61
51
 
62
-
63
52
  def init_receiver(type = :folder, notifications = [])
64
-
65
53
  verify_type(type, CHECKER_TYPES)
66
54
  @receiver = MailHandler::Receiver.new(CHECKER_TYPES[type].new)
67
55
  add_receiving_notifications(@receiver, notifications)
68
56
  @receiver
69
-
70
57
  end
71
58
 
72
59
  def handler(sender, receiver)
73
-
74
60
  handler = new
75
61
  handler.sender = sender
76
62
  handler.receiver = receiver
77
63
  handler
78
-
79
64
  end
80
65
 
81
66
  private
82
67
 
83
- # Add notifications, in case email receiving is delayed.
68
+ # Add notifications, in case email receiving is delayed.
84
69
  # When email is delayed, email notification can be sent or console status update.
85
70
  #
86
71
  # @param [Receiving::Object] receiver
87
72
  # @param [Array<Receiving::Notification::Class>] notifications
88
73
  def add_receiving_notifications(receiver, notifications)
89
-
90
74
  if (notifications - NOTIFICATION_TYPES.keys).empty?
91
75
 
92
76
  notifications.each { |n| receiver.add_observer(NOTIFICATION_TYPES[n].new) }
93
77
 
94
78
  end
95
-
96
79
  end
97
80
 
98
81
  def verify_type(type, types)
99
-
100
- raise MailHandler::TypeError, "Unknown type - #{type}, possible options: #{types.keys}." unless types.keys.include? type
101
-
82
+ raise MailHandler::TypeError, "Unknown type - #{type}, possible options: #{types.keys}." unless types.key?(type)
102
83
  end
103
84
 
104
85
  CHECKER_TYPES = {
105
86
 
106
- :folder => Receiving::FolderChecker,
107
- :imap => Receiving::IMAPChecker
87
+ folder: Receiving::FolderChecker,
88
+ imap: Receiving::IMAPChecker
108
89
 
109
- }
90
+ }.freeze
110
91
 
111
92
  SENDER_TYPES = {
112
93
 
113
- :postmark_api => Sending::PostmarkAPISender,
114
- :postmark_batch_api => Sending::PostmarkBatchAPISender,
115
- :smtp => Sending::SMTPSender
94
+ postmark_api: Sending::PostmarkAPISender,
95
+ postmark_batch_api: Sending::PostmarkBatchAPISender,
96
+ smtp: Sending::SMTPSender
116
97
 
117
- }
98
+ }.freeze
118
99
 
119
100
  NOTIFICATION_TYPES = {
120
101
 
121
- :console => Receiving::Notification::Console,
122
- :email => Receiving::Notification::Email
123
-
124
- }
102
+ console: Receiving::Notification::Console,
103
+ email: Receiving::Notification::Email
125
104
 
105
+ }.freeze
126
106
  end
127
-
128
107
  end
129
-
130
-
131
-
@@ -1,16 +1,12 @@
1
1
  module MailHandler
2
-
3
2
  class Error < StandardError
4
-
5
3
  def initialize(message = nil)
6
4
  super(message)
7
5
  end
8
-
9
6
  end
10
7
 
11
8
  class UnknownError < Error; end
12
9
  class TypeError < Error; end
13
10
  class FileError < Error; end
14
11
  class InterfaceError < Error; end
15
-
16
- end
12
+ end
@@ -4,9 +4,7 @@ require_relative 'receiving/observer'
4
4
  require_relative 'receiving/mail.rb'
5
5
 
6
6
  module MailHandler
7
-
8
7
  class Receiver
9
-
10
8
  include Receiving::Observer
11
9
 
12
10
  attr_accessor :checker,
@@ -15,10 +13,8 @@ module MailHandler
15
13
  :search_frequency
16
14
 
17
15
  module DEFAULTS
18
-
19
16
  MAX_SEARCH_DURATION = 240 # maximum time for search to last in [seconds]
20
17
  SEARCH_FREQUENCY = 0.5 # how frequently to check for email in inbox [seconds]
21
-
22
18
  end
23
19
 
24
20
  # @param [Hash] - search options
@@ -31,18 +27,15 @@ module MailHandler
31
27
  # @param [boolean] - result of search
32
28
  # @param [Mail] - first email found
33
29
  # @param [Array] - all emails found
34
- Search = Struct.new( :options, :started_at, :finished_at, :duration, :max_duration, :result, :email, :emails)
30
+ Search = Struct.new(:options, :started_at, :finished_at, :duration, :max_duration, :result, :email, :emails)
35
31
 
36
32
  def initialize(checker)
37
-
38
33
  @checker = checker
39
34
  @max_search_duration = DEFAULTS::MAX_SEARCH_DURATION
40
35
  @search_frequency = DEFAULTS::SEARCH_FREQUENCY
41
-
42
36
  end
43
37
 
44
38
  def find_email(options)
45
-
46
39
  init_search_details(options)
47
40
  checker.start
48
41
 
@@ -58,40 +51,29 @@ module MailHandler
58
51
 
59
52
  notify_observers(search)
60
53
  checker.search_result
61
-
62
- ensure
63
-
64
- checker.stop
65
-
54
+ ensure
55
+ checker.stop
66
56
  end
67
57
 
68
58
  private
69
59
 
70
60
  def init_search_details(options)
71
-
72
61
  @search = Search.new
73
62
  @search.options = options
74
63
  @search.started_at = Time.now
75
64
  @search.max_duration = @max_search_duration
76
-
77
65
  end
78
66
 
79
67
  def update_search_details
80
-
81
68
  search.finished_at = Time.now
82
69
  search.duration = search.finished_at - search.started_at
83
70
  search.result = checker.search_result
84
71
  search.emails = checker.found_emails
85
72
  search.email = search.emails.first
86
-
87
73
  end
88
74
 
89
75
  def search_time_expired?
90
-
91
76
  (Time.now - search.started_at) > @max_search_duration
92
-
93
77
  end
94
-
95
78
  end
96
-
97
- end
79
+ end
@@ -1,83 +1,64 @@
1
1
  require_relative '../errors'
2
2
 
3
3
  module MailHandler
4
-
5
4
  module Receiving
6
-
7
5
  #
8
6
  # Email receiving checker main class.
9
7
  # @see MailHandler::Receiving::FolderChecker for example for one of implemented checkers.
10
8
  #
11
9
  class Checker
12
-
13
10
  attr_accessor :search_options,
14
11
  :found_emails,
15
12
  :available_search_options
16
13
 
17
14
  def initialize
18
-
19
15
  @available_search_options = AVAILABLE_SEARCH_OPTIONS
20
16
  set_base_search_options
21
17
  reset_found_emails
22
-
23
18
  end
24
19
 
25
- def start
26
-
27
- end
20
+ def start; end
28
21
 
29
- def stop
30
-
31
- end
32
-
33
- def find(options)
22
+ def stop; end
34
23
 
24
+ def find(_options)
35
25
  raise MailHandler::InterfaceError, 'Find interface not implemented.'
36
-
37
26
  end
38
27
 
39
28
  def search_result
40
-
41
29
  !found_emails.empty?
42
-
43
30
  end
44
31
 
45
32
  def reset_found_emails
46
-
47
33
  @found_emails = []
48
-
49
34
  end
50
35
 
51
36
  private
52
37
 
53
- AVAILABLE_SEARCH_OPTIONS = [
38
+ AVAILABLE_SEARCH_OPTIONS = %i[
54
39
 
55
- :by_subject,
56
- :by_content,
57
- :since,
58
- :before,
59
- :by_recipient,
60
- :count,
61
- :archive,
62
- :fast_check
63
-
64
- ]
40
+ by_subject
41
+ by_content
42
+ since
43
+ before
44
+ by_recipient
45
+ count
46
+ archive
47
+ fast_check
48
+ ].freeze
65
49
 
66
50
  protected
67
51
 
68
52
  def verify_and_set_search_options(options)
69
-
70
53
  validate_used_options(options)
71
54
  validate_option_values(options)
72
55
 
73
56
  set_base_search_options
74
57
  add_additional_search_options(options)
75
58
  reset_found_emails
76
-
77
59
  end
78
60
 
79
61
  def validate_option_values(options)
80
-
81
62
  if options[:since]
82
63
 
83
64
  raise MailHandler::Error, "Incorrect option options[:since]=#{options[:since]}." unless options[:since].is_a? Time
@@ -87,13 +68,13 @@ module MailHandler
87
68
  unless options[:count].nil?
88
69
 
89
70
  count = options[:count]
90
- raise MailHandler::Error, "Incorrect option options[:count]=#{options[:count]}." if count < 0 or count > 2000
71
+ raise MailHandler::Error, "Incorrect option options[:count]=#{options[:count]}." if (count < 0) || (count > 2000)
91
72
 
92
73
  end
93
74
 
94
75
  if options[:archive]
95
76
 
96
- raise MailHandler::Error, "Incorrect option options[:archive]=#{options[:archive]}." unless options[:archive] == true or options[:archive] == false
77
+ raise MailHandler::Error, "Incorrect option options[:archive]=#{options[:archive]}." unless (options[:archive] == true) || (options[:archive] == false)
97
78
 
98
79
  end
99
80
 
@@ -102,32 +83,22 @@ module MailHandler
102
83
  raise MailHandler::Error, "Incorrect option options[:by_recipient]=#{options[:by_recipient]}." unless options[:by_recipient].is_a?(Hash)
103
84
 
104
85
  end
105
-
106
86
  end
107
87
 
108
88
  def validate_used_options(options)
109
-
110
89
  unless (options.keys - available_search_options).empty?
111
90
  raise MailHandler::Error, "#{(options.keys - available_search_options)} - Incorrect search option values, options are #{available_search_options}."
112
91
  end
113
-
114
92
  end
115
93
 
116
94
  def set_base_search_options
117
-
118
95
  # Default number of email results to return, and whether to archive emails.
119
- @search_options = {:count => 50, :archive => false}
120
-
96
+ @search_options = { count: 50, archive: false }
121
97
  end
122
98
 
123
99
  def add_additional_search_options(options)
124
-
125
100
  @search_options = @search_options.merge options
126
-
127
101
  end
128
-
129
102
  end
130
-
131
103
  end
132
-
133
104
  end
@@ -4,25 +4,17 @@ require 'fileutils'
4
4
  # Patterns to be used can be checked here: http://ruby-doc.org/core-1.9.3/Dir.html
5
5
 
6
6
  module MailHandler
7
-
8
7
  module Receiving
9
-
10
8
  module FileHandling
11
-
12
9
  # if file exists, execute file operation, otherwise return default return value when it doesn't
13
- def access_file(file, default_return = false, &block)
14
-
15
- if File.exists? file
10
+ def access_file(file, default_return = false)
11
+ if File.exist? file
16
12
 
17
13
  begin
18
-
19
- block.call
20
-
21
- rescue => e
22
-
23
- raise e if File.exists? file
14
+ yield
15
+ rescue StandardError => e
16
+ raise e if File.exist? file
24
17
  default_return
25
-
26
18
  end
27
19
 
28
20
  else
@@ -30,69 +22,53 @@ module MailHandler
30
22
  default_return
31
23
 
32
24
  end
33
-
34
25
  end
35
-
36
26
  end
37
27
 
38
28
  class FileList
39
-
40
29
  include FileHandling
41
30
 
42
31
  def get(pattern)
43
-
44
32
  Dir.glob(pattern)
45
-
46
33
  end
47
34
 
48
35
  def sort(files)
49
-
50
36
  swapped = true
51
37
  j = 0
52
38
 
53
- while swapped do
39
+ while swapped
54
40
 
55
41
  swapped = false
56
- j+=1
42
+ j += 1
57
43
 
58
44
  (files.size - j).times do |i|
59
-
60
45
  file1 = access_file(files[i], false) { File.new(files[i]).ctime }
61
- file2 = access_file(files[i+1], false) { File.new(files[i+1]).ctime }
62
-
63
- if file1 && file2 && file1 < file2
64
- tmp = files[i]
65
- files[i] = files[i + 1]
66
- files[i + 1] = tmp
67
- swapped = true
68
-
69
- end
46
+ file2 = access_file(files[i + 1], false) { File.new(files[i + 1]).ctime }
70
47
 
48
+ next unless file1 && file2 && file1 < file2
49
+ tmp = files[i]
50
+ files[i] = files[i + 1]
51
+ files[i + 1] = tmp
52
+ swapped = true
71
53
  end
72
54
 
73
55
  end
74
56
 
75
57
  files
76
-
77
58
  end
78
-
79
59
  end
80
-
81
60
  end
82
-
83
61
  end
84
62
 
85
- =begin
86
-
87
- TEST EXAMPLE
88
-
89
- FileList.get('*.*')
90
- FileList::Filter::ByEmailSubject.new(files,'subject').get
91
- FileList::Filter::ByEmailContent.new(files,'content').get
92
- FileList::Filter::ByEmailDate.new(files, date).get
93
- FileList::Filter::ByEmailRecipient.new(files, recipient).get
94
-
95
- f = FileList::Filter::ByEmailSubject.new(FileList.get("*.*"), "binding")
96
- puts f.get
97
-
98
- =end
63
+ #
64
+ # TEST EXAMPLE
65
+ #
66
+ # FileList.get('*.*')
67
+ # FileList::Filter::ByEmailSubject.new(files,'subject').get
68
+ # FileList::Filter::ByEmailContent.new(files,'content').get
69
+ # FileList::Filter::ByEmailDate.new(files, date).get
70
+ # FileList::Filter::ByEmailRecipient.new(files, recipient).get
71
+ #
72
+ # f = FileList::Filter::ByEmailSubject.new(FileList.get("*.*"), "binding")
73
+ # puts f.get
74
+ #