intrinio-realtime 2.0.0 → 2.1.0

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/intrinio-realtime.rb +77 -21
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6c6b1e8ef7761659187a4f70cfd2d63b22a6bfb
4
- data.tar.gz: 1ce5ed2d02a98101de4f36e6ba8b7a0db0bc1868
3
+ metadata.gz: a230dd8a59f925f023ddde64d91f7d6c33e40ecb
4
+ data.tar.gz: d6fe3f0b65ececa7e939d036d9bdf7322b396737
5
5
  SHA512:
6
- metadata.gz: 6555c857b6e00546c9d9fa6d237a74fda2cb410803dd2ff6c8fcf648be9da1cbb60cb2d6fb4eb49bb987541b16363c3b2cd28073ccf8873e7e177f28e725f0ab
7
- data.tar.gz: a2392977884efb471d1db6fd42f1093fddfe4f0b68e02e63194aab3b560e286ae464a15ffffaa2ee3cc710b248844822e8e6a8db7cb76aa1441d373fae269413
6
+ metadata.gz: 194bf4c83eda268fcd8df8e522588e326027aeb23e9f769bf608bedcf4538414bd8e9849b669d9e94f84f18731c484fb146c2d678f802f2caccb2df92bdc9147
7
+ data.tar.gz: e5170c7f944938e482f8a205c3694cd137faa277a07834b199df81a41ab760ab60e40b5859cde468adbc46458f760e6937f9a073f9933a585e9940a0d5791b39
@@ -7,10 +7,11 @@ require 'websocket-client-simple'
7
7
  module Intrinio
8
8
  module Realtime
9
9
  HEARTBEAT_TIME = 3
10
- SELF_HEAL_BACKOFFS = [0,100,500,1000,2000,5000]
11
- IEX = "iex"
12
- QUODD = "quodd"
13
- PROVIDERS = [IEX, QUODD]
10
+ SELF_HEAL_BACKOFFS = [0, 100, 500, 1000, 2000, 5000].freeze
11
+ IEX = "iex".freeze
12
+ QUODD = "quodd".freeze
13
+ CRYPTOQUOTE = "cryptoquote".freeze
14
+ PROVIDERS = [IEX, QUODD, CRYPTOQUOTE].freeze
14
15
 
15
16
  def self.connect(options, &b)
16
17
  EM.run do
@@ -21,16 +22,22 @@ module Intrinio
21
22
  end
22
23
 
23
24
  class Client
25
+
24
26
  def initialize(options)
25
27
  raise "Options parameter is required" if options.nil? || !options.is_a?(Hash)
26
-
27
- @username = options[:username]
28
- @password = options[:password]
29
- raise "Username and password are required" if @username.nil? || @username.empty? || @password.nil? || @password.empty?
30
-
28
+
29
+ @api_key = options[:api_key]
30
+ raise "API Key was formatted invalidly." if @api_key && !valid_api_key?(@api_key)
31
+
32
+ unless @api_key
33
+ @username = options[:username]
34
+ @password = options[:password]
35
+ raise "API Key or Username and password are required" if @username.nil? || @username.empty? || @password.nil? || @password.empty?
36
+ end
37
+
31
38
  @provider = options[:provider]
32
39
  raise "Provider must be 'quodd' or 'iex'" unless PROVIDERS.include?(@provider)
33
-
40
+
34
41
  @channels = []
35
42
  @channels = parse_channels(options[:channels]) if options[:channels]
36
43
  bad_channels = @channels.select{|x| !x.is_a?(String)}
@@ -44,7 +51,7 @@ module Intrinio
44
51
  @logger = Logger.new($stdout)
45
52
  @logger.level = Logger::INFO
46
53
  end
47
-
54
+
48
55
  @quotes = EventMachine::Channel.new
49
56
  @ready = false
50
57
  @joined_channels = []
@@ -53,7 +60,7 @@ module Intrinio
53
60
  @selfheal_backoffs = Array.new(SELF_HEAL_BACKOFFS)
54
61
  @ws = nil
55
62
  end
56
-
63
+
57
64
  def provider
58
65
  @provider
59
66
  end
@@ -124,32 +131,55 @@ module Intrinio
124
131
 
125
132
  def refresh_token
126
133
  @token = nil
127
-
128
- response = HTTP.basic_auth(:user => @username, :pass => @password).get(auth_url)
134
+
135
+ if @api_key
136
+ response = HTTP.get(auth_url)
137
+ else
138
+ response = HTTP.basic_auth(:user => @username, :pass => @password).get(auth_url)
139
+ end
140
+
129
141
  return fatal("Unable to authorize") if response.status == 401
130
142
  return fatal("Could not get auth token") if response.status != 200
131
-
143
+
132
144
  @token = response.body
133
145
  debug "Token refreshed"
134
146
  end
135
147
 
136
148
  def auth_url
149
+ url = ""
150
+
137
151
  case @provider
138
- when IEX then "https://realtime.intrinio.com/auth"
139
- when QUODD then "https://api.intrinio.com/token?type=QUODD"
152
+ when IEX then url = "https://realtime.intrinio.com/auth"
153
+ when QUODD then url = "https://api.intrinio.com/token?type=QUODD"
154
+ when CRYPTOQUOTE then url = "https://crypto.intrinio.com/auth"
140
155
  end
156
+
157
+ url = api_auth_url(url) if @api_key
158
+
159
+ url
141
160
  end
142
-
161
+
162
+ def api_auth_url(url)
163
+ if @api_key.include? "?"
164
+ url = "#{url}&"
165
+ else
166
+ url = "#{url}?"
167
+ end
168
+
169
+ "#{url}api_key=#{@api_key}"
170
+ end
171
+
143
172
  def socket_url
144
173
  case @provider
145
174
  when IEX then URI.escape("wss://realtime.intrinio.com/socket/websocket?vsn=1.0.0&token=#{@token}")
146
175
  when QUODD then URI.escape("wss://www5.quodd.com/websocket/webStreamer/intrinio/#{@token}")
176
+ when CRYPTOQUOTE then URI.escape("wss://crypto.intrinio.com/socket/websocket?vsn=1.0.0&token=#{@token}")
147
177
  end
148
178
  end
149
-
179
+
150
180
  def refresh_websocket
151
181
  me = self
152
-
182
+
153
183
  @ws.close() unless @ws.nil?
154
184
  @ready = false
155
185
  @joined_channels = []
@@ -160,7 +190,7 @@ module Intrinio
160
190
  ws.on :open do
161
191
  me.send :info, "Connection established"
162
192
  me.send :ready, true
163
- if me.send(:provider) == IEX
193
+ if me.send(:provider) == IEX || me.send(:provider) == CRYPTOQUOTE
164
194
  me.send :refresh_channels
165
195
  end
166
196
  me.send :start_heartbeat
@@ -185,6 +215,10 @@ module Intrinio
185
215
  elsif json["event"] == "quote" || json["event"] == "trade"
186
216
  json["data"]
187
217
  end
218
+ when CRYPTOQUOTE
219
+ if json["event"] == "book_update" || json["event"] == "ticker" || json["event"] == "trade"
220
+ json["payload"]
221
+ end
188
222
  end
189
223
 
190
224
  if quote && quote.is_a?(Hash)
@@ -245,6 +279,7 @@ module Intrinio
245
279
  case @provider
246
280
  when IEX then {topic: 'phoenix', event: 'heartbeat', payload: {}, ref: nil}.to_json
247
281
  when QUODD then {event: 'heartbeat', data: {action: 'heartbeat', ticker: (Time.now.to_f * 1000).to_i}}.to_json
282
+ when CRYPTOQUOTE then {topic: 'phoenix', event: 'heartbeat', payload: {}, ref: nil}.to_json
248
283
  end
249
284
  end
250
285
 
@@ -341,6 +376,13 @@ module Intrinio
341
376
  action: "subscribe"
342
377
  }
343
378
  }
379
+ when CRYPTOQUOTE
380
+ {
381
+ topic: channel,
382
+ event: "phx_join",
383
+ payload: {},
384
+ ref: nil
385
+ }
344
386
  end
345
387
  end
346
388
 
@@ -361,8 +403,22 @@ module Intrinio
361
403
  action: "unsubscribe"
362
404
  }
363
405
  }
406
+ when CRYPTOQUOTE
407
+ {
408
+ topic: channel,
409
+ event: "phx_leave",
410
+ payload: {},
411
+ ref: nil
412
+ }
364
413
  end
365
414
  end
415
+
416
+ def valid_api_key?(api_key)
417
+ return false unless api_key.is_a?(String)
418
+ return false if api_key.empty?
419
+ true
420
+ end
421
+
366
422
  end
367
423
  end
368
424
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intrinio-realtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Intrinio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-18 00:00:00.000000000 Z
11
+ date: 2018-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
80
  version: '0'
81
81
  requirements: []
82
82
  rubyforge_project:
83
- rubygems_version: 2.5.1
83
+ rubygems_version: 2.5.2.2
84
84
  signing_key:
85
85
  specification_version: 4
86
86
  summary: Intrinio provides real-time stock prices from the IEX stock exchange, via