intrinio-realtime 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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