stockboy 0.5.4 → 0.5.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -1
- data/lib/stockboy/configurator.rb +2 -1
- data/lib/stockboy/providers/imap.rb +60 -50
- data/lib/stockboy/providers/imap/search_options.rb +121 -0
- data/lib/stockboy/translations.rb +2 -14
- data/lib/stockboy/version.rb +1 -1
- data/spec/stockboy/providers/imap/search_options_spec.rb +56 -0
- data/spec/stockboy/providers/imap_spec.rb +60 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f79e82814670601621d41e2bd236f209c0623d26
|
4
|
+
data.tar.gz: eb46c2caf2ff5932afbc8eaf41a32064f52c6504
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 041d9ca85788641bb8ee2e834c0488901f7d68207b1af5fb6e10e494d94b1e6d8b507cf06044403d6a2c06b81055dbf96853567ad9c4dcc057bfdcf8856f2aaf
|
7
|
+
data.tar.gz: 01ffad83c3db76ea4e97845c970dac4013a557b36044a118a83f577564ebaf13f52ae56dbdd220b1bbc21df82edf91adb7d620f9e011f95b7b6b724b63e72fb9
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -147,7 +147,8 @@ module Stockboy
|
|
147
147
|
# defined within the context of each job template.
|
148
148
|
#
|
149
149
|
# @param [Symbol] key Name of the trigger
|
150
|
-
# @
|
150
|
+
# @yieldparam [Stockboy::Job]
|
151
|
+
# @yieldparam [Array] Arguments passed to the action when called
|
151
152
|
#
|
152
153
|
# @example
|
153
154
|
# trigger :cleanup do |job, *args|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'stockboy/provider'
|
2
|
+
require 'stockboy/providers/imap/search_options'
|
2
3
|
require 'net/imap'
|
3
4
|
require 'mail'
|
4
5
|
|
@@ -20,9 +21,6 @@ module Stockboy::Providers
|
|
20
21
|
#
|
21
22
|
class IMAP < Stockboy::Provider
|
22
23
|
|
23
|
-
# Corresponds to %v mode in +DateTime#strftime+
|
24
|
-
VMS_DATE = /\A\d{2}-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{2}\z/i
|
25
|
-
|
26
24
|
# @!group Options
|
27
25
|
|
28
26
|
# Host name or IP address for IMAP server connection
|
@@ -128,17 +126,6 @@ module Stockboy::Providers
|
|
128
126
|
|
129
127
|
# @!endgroup
|
130
128
|
|
131
|
-
# Library for connection, defaults to +Net::IMAP+
|
132
|
-
#
|
133
|
-
# @!attribute [rw] imap_client
|
134
|
-
#
|
135
|
-
def self.imap_client
|
136
|
-
@imap_client ||= Net::IMAP
|
137
|
-
end
|
138
|
-
class << self
|
139
|
-
attr_writer :imap_client
|
140
|
-
end
|
141
|
-
|
142
129
|
# Initialize a new IMAP reader
|
143
130
|
#
|
144
131
|
def initialize(opts={}, &block)
|
@@ -158,23 +145,36 @@ module Stockboy::Providers
|
|
158
145
|
DSL.new(self).instance_eval(&block) if block_given?
|
159
146
|
end
|
160
147
|
|
148
|
+
# Direct access to the configured +Net::IMAP+ connection
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# provider.client do |imap|
|
152
|
+
# imap.search("FLAGGED")
|
153
|
+
# end
|
154
|
+
#
|
161
155
|
def client
|
162
156
|
raise(ArgumentError, "no block given") unless block_given?
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
157
|
+
first_connection = @open_client.nil?
|
158
|
+
if first_connection
|
159
|
+
@open_client = ::Net::IMAP.new(host)
|
160
|
+
@open_client.login(username, password)
|
161
|
+
@open_client.examine(mailbox)
|
168
162
|
end
|
169
163
|
yield @open_client
|
170
|
-
@open_client.disconnect
|
171
|
-
@open_client = nil
|
172
164
|
rescue ::Net::IMAP::Error => e
|
173
165
|
errors.add :response, "IMAP connection error"
|
174
|
-
|
175
|
-
|
166
|
+
ensure
|
167
|
+
if first_connection
|
168
|
+
@open_client.disconnect
|
169
|
+
@open_client = nil
|
170
|
+
end
|
176
171
|
end
|
177
172
|
|
173
|
+
# Purge the email from the mailbox corresponding to the [#matching_file]
|
174
|
+
#
|
175
|
+
# This can only be called after selecting the matching file to confirm the
|
176
|
+
# selected item, or after fetching the data
|
177
|
+
#
|
178
178
|
def delete_data
|
179
179
|
raise Stockboy::OutOfSequence, "must confirm #matching_message or calling #data" unless picked_matching_message?
|
180
180
|
|
@@ -185,12 +185,16 @@ module Stockboy::Providers
|
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
|
+
# IMAP message id for the email that contains the selected data to process
|
189
|
+
#
|
188
190
|
def matching_message
|
189
191
|
return @matching_message if @matching_message
|
190
|
-
|
191
|
-
@matching_message = pick_from(
|
192
|
+
message_ids = search(default_search_options)
|
193
|
+
@matching_message = pick_from(message_ids) unless message_ids.empty?
|
192
194
|
end
|
193
195
|
|
196
|
+
# Clear received data and allow for selecting a new item from the server
|
197
|
+
#
|
194
198
|
def clear
|
195
199
|
super
|
196
200
|
@matching_message = nil
|
@@ -198,8 +202,39 @@ module Stockboy::Providers
|
|
198
202
|
@data_size = nil
|
199
203
|
end
|
200
204
|
|
205
|
+
# Search the selected mailbox for matching messages
|
206
|
+
#
|
207
|
+
# By default, the configured options are used,
|
208
|
+
# @param [Hash, Array, String] options
|
209
|
+
# Override default configured search options
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# provider.search(subject: "Daily Report", before: Date.today)
|
213
|
+
# provider.search(["SUBJECT", "Daily Report", "BEFORE", "21-DEC-12"])
|
214
|
+
# provider.search("FLAGGED BEFORE 21-DEC-12")
|
215
|
+
#
|
216
|
+
def search(options=nil)
|
217
|
+
client { |imap| imap.sort(['DATE'], search_keys(options), 'UTF-8') }
|
218
|
+
end
|
219
|
+
|
220
|
+
# Normalize a hash of search options into an array of IMAP search keys
|
221
|
+
#
|
222
|
+
# @param [Hash] options If none are given, the configured options are used
|
223
|
+
# @return [Array]
|
224
|
+
#
|
225
|
+
def search_keys(options=nil)
|
226
|
+
case options
|
227
|
+
when Array, String then options
|
228
|
+
else SearchOptions.new(options || default_search_options).to_imap
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
201
232
|
private
|
202
233
|
|
234
|
+
def default_search_options
|
235
|
+
{subject: subject, from: from, since: since}
|
236
|
+
end
|
237
|
+
|
203
238
|
def fetch_data
|
204
239
|
client do |imap|
|
205
240
|
return false unless matching_message
|
@@ -222,10 +257,6 @@ module Stockboy::Providers
|
|
222
257
|
errors.empty?
|
223
258
|
end
|
224
259
|
|
225
|
-
def fetch_imap_message_keys
|
226
|
-
client { |imap| imap.sort(['DATE'], search_keys, 'UTF-8') }
|
227
|
-
end
|
228
|
-
|
229
260
|
def picked_matching_message?
|
230
261
|
!!@matching_message
|
231
262
|
end
|
@@ -241,27 +272,6 @@ module Stockboy::Providers
|
|
241
272
|
end
|
242
273
|
end
|
243
274
|
|
244
|
-
def search_keys
|
245
|
-
keys = []
|
246
|
-
keys.concat ['SUBJECT', subject] if subject
|
247
|
-
keys.concat ['FROM', from] if from
|
248
|
-
keys.concat ['SINCE', date_format(since)] if since
|
249
|
-
keys.concat search if search
|
250
|
-
keys
|
251
|
-
end
|
252
|
-
|
253
|
-
def date_format(value)
|
254
|
-
case value
|
255
|
-
when Date, Time, DateTime
|
256
|
-
value.strftime('%v')
|
257
|
-
when Numeric
|
258
|
-
Time.at(value).strftime('%v')
|
259
|
-
when String
|
260
|
-
return value if value =~ VMS_DATE
|
261
|
-
Date.parse(value).strftime('%v')
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
275
|
# If activesupport is loaded, it mucks with DateTime#to_time to return
|
266
276
|
# self when it has a utc_offset. Handle both to always return a Time.utc.
|
267
277
|
#
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'stockboy/providers/imap'
|
2
|
+
|
3
|
+
module Stockboy::Providers
|
4
|
+
|
5
|
+
# Helper for building standard IMAP options passed to [::Net::IMAP#search]
|
6
|
+
#
|
7
|
+
class IMAP::SearchOptions
|
8
|
+
|
9
|
+
# Corresponds to %v mode in +DateTime#strftime+
|
10
|
+
VMS_DATE = /\A\d{2}-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{2}\z/i
|
11
|
+
|
12
|
+
OPTION_FORMATS = {
|
13
|
+
'BEFORE' => :date_format,
|
14
|
+
'ON' => :date_format,
|
15
|
+
'SINCE' => :date_format,
|
16
|
+
'SENTBEFORE' => :date_format,
|
17
|
+
'SENTON' => :date_format,
|
18
|
+
'SENTSINCE' => :date_format,
|
19
|
+
'FLAGGED' => :boolean_format,
|
20
|
+
'UNFLAGGED' => :boolean_format,
|
21
|
+
'SEEN' => :boolean_format,
|
22
|
+
'UNSEEN' => :boolean_format,
|
23
|
+
'ANSWERED' => :boolean_format,
|
24
|
+
'UNANSWERED' => :boolean_format,
|
25
|
+
'DELETED' => :boolean_format,
|
26
|
+
'UNDELETED' => :boolean_format,
|
27
|
+
'DRAFT' => :boolean_format,
|
28
|
+
'UNDRAFT' => :boolean_format,
|
29
|
+
'NEW' => :boolean_format,
|
30
|
+
'RECENT' => :boolean_format,
|
31
|
+
'OLD' => :boolean_format
|
32
|
+
}
|
33
|
+
|
34
|
+
# Read options from a hash
|
35
|
+
#
|
36
|
+
# @param [Hash] options
|
37
|
+
#
|
38
|
+
def initialize(options={})
|
39
|
+
@options = options.each_with_object(Hash.new) do |(k,v), h|
|
40
|
+
h[imap_key(k)] = v
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return a hash with merged and normalized key strings
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# opt = Stockboy::Providers::IMAP::SearchOptions.new(since: Date.new(2012, 12, 21))
|
48
|
+
# opt.to_hash #=> {"SINCE" => #<Date 2012, 12, 21>}
|
49
|
+
#
|
50
|
+
def to_hash
|
51
|
+
@options
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return an array of IMAP search keys
|
55
|
+
#
|
56
|
+
# @example
|
57
|
+
# opt = Stockboy::Providers::IMAP::SearchOptions.new(since: Date.new(2012, 12, 21))
|
58
|
+
# opt.to_imap #=> ["SINCE", "21-DEC-12"]
|
59
|
+
#
|
60
|
+
def to_imap
|
61
|
+
@options.reduce([]) do |a, pair|
|
62
|
+
a.concat imap_pair(pair)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Convert a rubyish key to IMAP string key format
|
67
|
+
#
|
68
|
+
# @param [String, Symbol] key
|
69
|
+
# @return [String]
|
70
|
+
#
|
71
|
+
def imap_key(key)
|
72
|
+
key.to_s.upcase.gsub(/[^A-Z]/,'').freeze
|
73
|
+
end
|
74
|
+
|
75
|
+
# Format a key-value pair for IMAP, according to the correct type
|
76
|
+
#
|
77
|
+
# @param [Array] pair
|
78
|
+
# @return [Array] pair
|
79
|
+
#
|
80
|
+
def imap_pair(pair)
|
81
|
+
if format = OPTION_FORMATS[pair[0]]
|
82
|
+
send(format, pair)
|
83
|
+
else
|
84
|
+
pair
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Format a key-value pair for IMAP date keys (e.g. SINCE, ON, BEFORE)
|
89
|
+
#
|
90
|
+
# @param [Array] pair
|
91
|
+
# @return [Array] pair
|
92
|
+
#
|
93
|
+
def date_format(pair)
|
94
|
+
pair[1] = case value = pair[1]
|
95
|
+
when Date, Time, DateTime
|
96
|
+
value.strftime('%v')
|
97
|
+
when Numeric
|
98
|
+
Time.at(value).strftime('%v')
|
99
|
+
when String
|
100
|
+
value =~ VMS_DATE ? value : Date.parse(value).strftime('%v')
|
101
|
+
end
|
102
|
+
pair
|
103
|
+
end
|
104
|
+
|
105
|
+
# Format a key-value pair for setting true/false on IMAP keys (e.g. DELETED)
|
106
|
+
#
|
107
|
+
# @param [Array] pair
|
108
|
+
# @return [Array] pair
|
109
|
+
#
|
110
|
+
def boolean_format(pair)
|
111
|
+
return [] unless pair[1] == true || pair[1] == false
|
112
|
+
|
113
|
+
if pair[1]
|
114
|
+
[pair[0]]
|
115
|
+
else
|
116
|
+
['NOT', pair[0]]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'stockboy/exceptions'
|
2
|
+
require 'stockboy/registry'
|
2
3
|
require 'stockboy/translator'
|
3
4
|
|
4
5
|
module Stockboy
|
@@ -7,8 +8,7 @@ module Stockboy
|
|
7
8
|
# job template DSL.
|
8
9
|
#
|
9
10
|
module Translations
|
10
|
-
|
11
|
-
@registry ||= {}
|
11
|
+
extend Stockboy::Registry
|
12
12
|
|
13
13
|
# Register a translator under a convenient symbolic name
|
14
14
|
#
|
@@ -54,17 +54,5 @@ module Stockboy
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
# Look up a translation and return it by symbolic name
|
58
|
-
#
|
59
|
-
# @param [Symbol] func_name
|
60
|
-
# @return [Translator]
|
61
|
-
#
|
62
|
-
def self.find(func_name)
|
63
|
-
@registry[func_name]
|
64
|
-
end
|
65
|
-
class << self
|
66
|
-
alias_method :[], :find
|
67
|
-
end
|
68
|
-
|
69
57
|
end
|
70
58
|
end
|
data/lib/stockboy/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stockboy/providers/imap/search_options'
|
3
|
+
|
4
|
+
module Stockboy::Providers
|
5
|
+
describe IMAP::SearchOptions do
|
6
|
+
|
7
|
+
describe "to_hash" do
|
8
|
+
it "converts keys to uppercase" do
|
9
|
+
options(subject: "Improbability")
|
10
|
+
.to_hash.should == {"SUBJECT" => "Improbability"}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
describe "to_imap" do
|
16
|
+
|
17
|
+
it "converts to a flat array of options" do
|
18
|
+
options(subject: "Improbability", from: "me@example.com")
|
19
|
+
.to_imap.should == ["SUBJECT", "Improbability", "FROM", "me@example.com"]
|
20
|
+
end
|
21
|
+
|
22
|
+
DATE_OPTIONS = { before: "BEFORE",
|
23
|
+
on: "ON",
|
24
|
+
since: "SINCE",
|
25
|
+
sent_before: "SENTBEFORE",
|
26
|
+
sent_on: "SENTON",
|
27
|
+
sent_since: "SENTSINCE" }
|
28
|
+
|
29
|
+
DATE_OPTIONS.each do |date_option_symbol, date_option_imap|
|
30
|
+
it "converts #{date_option_imap.inspect} to IMAP date option" do
|
31
|
+
options(date_option_symbol => Time.new(2012, 12, 12))
|
32
|
+
.to_imap.should == [date_option_imap, "12-DEC-2012"]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
BOOLEAN_OPTIONS = { seen: "SEEN",
|
37
|
+
unseen: "UNSEEN",
|
38
|
+
flagged: "FLAGGED",
|
39
|
+
unflagged: "UNFLAGGED" }
|
40
|
+
|
41
|
+
BOOLEAN_OPTIONS.each do |bool_option_symbol, bool_option_imap|
|
42
|
+
it "converts #{bool_option_imap.inspect} to IMAP single value option" do
|
43
|
+
options(bool_option_symbol => true).to_imap.should == [bool_option_imap]
|
44
|
+
options(bool_option_symbol => false).to_imap.should == ["NOT", bool_option_imap]
|
45
|
+
options(bool_option_symbol => nil).to_imap.should == []
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def options(*args)
|
52
|
+
described_class.new(*args)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -76,7 +76,7 @@ module Stockboy
|
|
76
76
|
|
77
77
|
it "should call delete on the matching message" do
|
78
78
|
allow(provider).to receive(:client).and_yield(imap)
|
79
|
-
allow(provider).to receive(:
|
79
|
+
allow(provider).to receive(:search) { [5] }
|
80
80
|
|
81
81
|
provider.matching_message
|
82
82
|
|
@@ -87,5 +87,64 @@ module Stockboy
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
describe "#client" do
|
91
|
+
|
92
|
+
before do
|
93
|
+
provider.host, provider.username, provider.password = "hhh", "uuu", "ppp"
|
94
|
+
provider.mailbox = "UNBOX"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "reuses open connections in nested contexts" do
|
98
|
+
net_imap = expect_connection("hhh", "uuu", "ppp", "UNBOX")
|
99
|
+
|
100
|
+
provider.client do |connection|
|
101
|
+
expect(connection).to be net_imap
|
102
|
+
provider.client do |i|
|
103
|
+
expect(connection).to be net_imap
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "closes connections when catching exceptions" do
|
109
|
+
net_imap = expect_connection("hhh", "uuu", "ppp", "UNBOX")
|
110
|
+
provider.client { |i| raise Net::IMAP::Error }
|
111
|
+
provider.errors[:response].should include "IMAP connection error"
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#search_keys" do
|
117
|
+
it "uses configured options by default" do
|
118
|
+
provider.since = Date.new(2012, 12, 21)
|
119
|
+
provider.subject = "Earth"
|
120
|
+
provider.from = "me@example.com"
|
121
|
+
|
122
|
+
provider.search_keys.should == [
|
123
|
+
"SUBJECT", "Earth",
|
124
|
+
"FROM", "me@example.com",
|
125
|
+
"SINCE", "21-Dec-2012"
|
126
|
+
]
|
127
|
+
end
|
128
|
+
|
129
|
+
it "replaces defaults with given options" do
|
130
|
+
provider.since = Date.new(2012, 12, 21)
|
131
|
+
provider.subject = "Earth"
|
132
|
+
provider.search_keys(subject: "Improbability").should == ["SUBJECT", "Improbability"]
|
133
|
+
end
|
134
|
+
|
135
|
+
it "returns the same array given" do
|
136
|
+
provider.search_keys(["SINCE", "21-DEC-12"]).should == ["SINCE", "21-DEC-12"]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def expect_connection(host, user, pass, mailbox)
|
141
|
+
net_imap = double("IMAP")
|
142
|
+
expect(Net::IMAP).to receive(:new).with(host) { net_imap }
|
143
|
+
expect(net_imap).to receive(:login).with(user, pass)
|
144
|
+
expect(net_imap).to receive(:examine).with(mailbox)
|
145
|
+
expect(net_imap).to receive(:disconnect)
|
146
|
+
net_imap
|
147
|
+
end
|
148
|
+
|
90
149
|
end
|
91
150
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stockboy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Vit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/stockboy/providers/ftp.rb
|
147
147
|
- lib/stockboy/providers/http.rb
|
148
148
|
- lib/stockboy/providers/imap.rb
|
149
|
+
- lib/stockboy/providers/imap/search_options.rb
|
149
150
|
- lib/stockboy/providers/soap.rb
|
150
151
|
- lib/stockboy/railtie.rb
|
151
152
|
- lib/stockboy/reader.rb
|
@@ -201,6 +202,7 @@ files:
|
|
201
202
|
- spec/stockboy/providers/file_spec.rb
|
202
203
|
- spec/stockboy/providers/ftp_spec.rb
|
203
204
|
- spec/stockboy/providers/http_spec.rb
|
205
|
+
- spec/stockboy/providers/imap/search_options_spec.rb
|
204
206
|
- spec/stockboy/providers/imap_spec.rb
|
205
207
|
- spec/stockboy/providers/soap_spec.rb
|
206
208
|
- spec/stockboy/providers_spec.rb
|
@@ -247,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
249
|
version: '0'
|
248
250
|
requirements: []
|
249
251
|
rubyforge_project: stockboy
|
250
|
-
rubygems_version: 2.0.
|
252
|
+
rubygems_version: 2.0.14
|
251
253
|
signing_key:
|
252
254
|
specification_version: 4
|
253
255
|
summary: Multi-source data normalization library
|
@@ -279,6 +281,7 @@ test_files:
|
|
279
281
|
- spec/stockboy/providers/file_spec.rb
|
280
282
|
- spec/stockboy/providers/ftp_spec.rb
|
281
283
|
- spec/stockboy/providers/http_spec.rb
|
284
|
+
- spec/stockboy/providers/imap/search_options_spec.rb
|
282
285
|
- spec/stockboy/providers/imap_spec.rb
|
283
286
|
- spec/stockboy/providers/soap_spec.rb
|
284
287
|
- spec/stockboy/providers_spec.rb
|