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
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
+ #