Class: Pandoru::Transport::APITransport

Inherits:
Object
  • Object
show all
Defined in:
lib/pandoru/transport.rb

Overview

Pandora API Transport with retries

Constant Summary collapse

API_VERSION =
"5"
REQUIRE_RESET =
%w[auth.partnerLogin].freeze
NO_ENCRYPT =
%w[auth.partnerLogin].freeze
REQUIRE_TLS =
%w[
  auth.partnerLogin
  auth.userLogin
  station.getPlaylist
  user.createUser
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cryptor = nil, api_host: DEFAULT_API_HOST, proxy: nil) ⇒ APITransport

Returns a new instance of APITransport.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/pandoru/transport.rb', line 154

def initialize(cryptor = nil, api_host: DEFAULT_API_HOST, proxy: nil)
  @cryptor = cryptor
  api_host ||= DEFAULT_API_HOST
  
  # Parse host and path
  if api_host.include?('/services/json')
    # Extract host from full URL
    if api_host.include?('://')
      # Protocol://host format
      uri_parts = api_host.split('/')
      @api_host = uri_parts[2]
    else
      # host/path format
      @api_host = api_host.split('/')[0]
    end
    @api_path = '/services/json/'
  else
    @api_host = api_host
    @api_path = '/services/json/'
  end
  
  # Set port and TLS based on URL
  if api_host.include?('https:') || api_host.include?(':443') || api_host == 'tuner.pandora.com'
    @api_port = 443
    @api_tls = true
  else
    @api_port = 80  
    @api_tls = false
  end
  
  # Strip protocol from host for compatibility
  @api_host = @api_host.gsub(%r{^https?://}, '')
  # Remove path if it got included
  @api_host = @api_host.split('/')[0]
  
  # Extract port from hostname if present
  if @api_host.include?(':')
    host_parts = @api_host.split(':')
    @api_host = host_parts[0]
    @api_port = host_parts[1].to_i
    @api_tls = (@api_port == 443)
  end
  
  @encryption_padding = "\x00" * 16
  @connection = build_connection(proxy)
  reset
  @start_time = Time.now.to_f  # Set after reset so it doesn't get cleared
end

Instance Attribute Details

#api_hostObject (readonly)

Returns the value of attribute api_host.



150
151
152
# File 'lib/pandoru/transport.rb', line 150

def api_host
  @api_host
end

#cryptorObject (readonly)

Returns the value of attribute cryptor.



150
151
152
# File 'lib/pandoru/transport.rb', line 150

def cryptor
  @cryptor
end

#partner_auth_tokenObject

Returns the value of attribute partner_auth_token.



151
152
153
# File 'lib/pandoru/transport.rb', line 151

def partner_auth_token
  @partner_auth_token
end

#partner_idObject

Returns the value of attribute partner_id.



151
152
153
# File 'lib/pandoru/transport.rb', line 151

def partner_id
  @partner_id
end

#server_sync_timeObject

Returns the value of attribute server_sync_time.



151
152
153
# File 'lib/pandoru/transport.rb', line 151

def server_sync_time
  @server_sync_time
end

#start_timeObject

Returns the value of attribute start_time.



151
152
153
# File 'lib/pandoru/transport.rb', line 151

def start_time
  @start_time
end

#user_auth_tokenObject

Returns the value of attribute user_auth_token.



151
152
153
# File 'lib/pandoru/transport.rb', line 151

def user_auth_token
  @user_auth_token
end

#user_idObject

Returns the value of attribute user_id.



151
152
153
# File 'lib/pandoru/transport.rb', line 151

def user_id
  @user_id
end

Instance Method Details

#auth_tokenObject



223
224
225
# File 'lib/pandoru/transport.rb', line 223

def auth_token
  @auth_token || @user_auth_token || @partner_auth_token
end

#call(method, **data) ⇒ Object



232
233
234
235
236
237
238
239
240
241
# File 'lib/pandoru/transport.rb', line 232

def call(method, **data)
  start_request(method)

  params = build_params(method)
  url = build_url(method, params)
  request_info = build_data(method, data)

  result = make_http_request(url, request_info[:data], params, request_info[:encrypted])
  parse_response(result)
end

#resetObject



203
204
205
206
207
208
209
210
# File 'lib/pandoru/transport.rb', line 203

def reset
  @partner_auth_token = nil
  @user_auth_token = nil
  @partner_id = nil
  @user_id = nil
  @start_time = nil
  @server_sync_time = nil
end

#set_partner(data) ⇒ Object



212
213
214
215
216
# File 'lib/pandoru/transport.rb', line 212

def set_partner(data)
  self.sync_time = data["syncTime"]
  @partner_auth_token = data["partnerAuthToken"]
  @partner_id = data["partnerId"]
end

#set_user(data) ⇒ Object



218
219
220
221
# File 'lib/pandoru/transport.rb', line 218

def set_user(data)
  @user_id = data["userId"]
  @user_auth_token = data["userAuthToken"]
end

#sync_timeObject



227
228
229
230
# File 'lib/pandoru/transport.rb', line 227

def sync_time
  return nil unless @server_sync_time
  (@server_sync_time + (Time.now.to_f - @start_time)).to_i
end

#test_connectivityObject



243
244
245
246
247
248
249
250
251
252
# File 'lib/pandoru/transport.rb', line 243

def test_connectivity
  return false unless @connection
  
  begin
    test_url = "#{@api_tls ? 'https' : 'http'}://#{@api_host}:#{@api_tls ? 443 : 80}"
    test_url(test_url)
  rescue StandardError
    false
  end
end

#test_url(url) ⇒ Object



254
255
256
257
258
259
# File 'lib/pandoru/transport.rb', line 254

def test_url(url)
  response = @connection.head(url)
  response.status == 200
rescue
  false
end