Class: Ubiquity::MediaSilo::API::V3::HTTPClient

Inherits:
Object
  • Object
show all
Defined in:
lib/ubiquity/mediasilo/api/v3/http_client.rb

Defined Under Namespace

Classes: CaseSensitiveHeaderKey, RateLimitException

Constant Summary collapse

DEFAULT_HTTP_HOST_ADDRESS =

DEFAULT_HTTP_HOST_ADDRESS = ‘api.mediasilo.com’

'p-api-new.mediasilo.com'
DEFAULT_HTTP_HOST_PORT =
443

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = { }) ⇒ HTTPClient

Returns a new instance of HTTPClient.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 38

def initialize(args = { })
  args = args.dup
  initialize_logger(args)
  initialize_http(args)

  @hostname = args[:hostname] || ''
  @username = args[:username] || ''
  @password = args[:password] || ''
  @api_key  = args[:api_key]
  @base_uri = args[:base_uri] || "http#{http.use_ssl? ? 's' : ''}://#{http.address}:#{http.port}/v3/"

  @user_agent_default = "#{@hostname}:#{@username} Ubiquity Ruby SDK Version #{Ubiquity::MediaSilo::API::V3::VERSION}"

  authorization_header_name = CaseSensitiveHeaderKey.new('Authorization')
  authorization_header_value = 'Basic ' + ["#{username}:#{password}"].pack('m').delete("\r\n")

  host_context_header_name = CaseSensitiveHeaderKey.new('MediaSiloHostContext')
  host_context_header_value = hostname.downcase

  @default_request_headers = {
    'user-agent' => @user_agent_default,
    'Content-Type' => 'application/json; charset=utf-8',
    'Accept' => 'application/json',
    host_context_header_name => host_context_header_value,
    authorization_header_name => authorization_header_value,
  }

  if @api_key
    api_key_header_name = CaseSensitiveHeaderKey.new('MediaSiloApiKey')
    default_request_headers[api_key_header_name] = @api_key
  end

  @log_request_body = args.fetch(:log_request_body, true)
  @log_response_body = args.fetch(:log_response_body, true)
  @log_pretty_print_body = args.fetch(:log_pretty_print_body, true)

  @delay_between_rate_limit_retries = 300
  @cancelled = false
  @parse_response = args.fetch(:parse_response, true)
end

Instance Attribute Details

#base_uriObject

Returns the value of attribute base_uri.



25
26
27
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 25

def base_uri
  @base_uri
end

#default_request_headersObject

Returns the value of attribute default_request_headers.



28
29
30
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 28

def default_request_headers
  @default_request_headers
end

#hostnameObject

Returns the value of attribute hostname.



26
27
28
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 26

def hostname
  @hostname
end

#httpObject

Returns the value of attribute http.



25
26
27
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 25

def http
  @http
end

#http_host_addressObject

Returns the value of attribute http_host_address.



25
26
27
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 25

def http_host_address
  @http_host_address
end

#http_host_portObject

Returns the value of attribute http_host_port.



25
26
27
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 25

def http_host_port
  @http_host_port
end

#log_pretty_print_bodyObject

Returns the value of attribute log_pretty_print_body.



30
31
32
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 30

def log_pretty_print_body
  @log_pretty_print_body
end

#log_request_bodyObject

Returns the value of attribute log_request_body.



30
31
32
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 30

def log_request_body
  @log_request_body
end

#log_response_bodyObject

Returns the value of attribute log_response_body.



30
31
32
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 30

def log_response_body
  @log_response_body
end

#loggerObject

Returns the value of attribute logger.



25
26
27
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 25

def logger
  @logger
end

#passwordObject

Returns the value of attribute password.



26
27
28
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 26

def password
  @password
end

#requestObject

Returns the value of attribute request.



32
33
34
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 32

def request
  @request
end

#responseObject

Returns the value of attribute response.



32
33
34
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 32

def response
  @response
end

#usernameObject

Returns the value of attribute username.



26
27
28
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 26

def username
  @username
end

Instance Method Details

#build_uri(path = '', query = nil) ⇒ Object



162
163
164
165
166
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 162

def build_uri(path = '', query = nil)
  _query = query.is_a?(Hash) ? query.map { |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v)}" }.join('&') : query
  _path = "#{path}#{_query and _query.respond_to?(:empty?) and !_query.empty? ? "?#{_query}" : ''}"
  URI.parse(File.join(base_uri, _path))
end

#call_method(method_name = :get, args = { }, options = { }) ⇒ Object

Parameters:

  • method_name (Symbol) (defaults to: :get)

    (:get)

  • args (Hash) (defaults to: { })
  • options (Hash) (defaults to: { })

Options Hash (args):

  • :headers (Hash) — default: {}
  • :path (String) — default: ''
  • :query (Hash) — default: {}
  • :body (Any) — default: nil

Options Hash (options):

  • :default_request_headers (Hash) — default: @default_request_headers


186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 186

def call_method(method_name = :get, args = { }, options = { })
  headers = args[:headers] || options[:headers] || { }
  path = args[:path] || ''
  query = args[:query] || { }
  body = args[:body]

  # Allow the default request headers to be overridden
  _default_request_headers = options.fetch(:default_request_headers, default_request_headers)
  _default_request_headers ||= { }
  _headers = _default_request_headers.merge(headers)

  @uri = build_uri(path, query)
  klass_name = request_method_name_to_class_name(method_name)
  klass = Net::HTTP.const_get(klass_name)

  request = klass.new(@uri.request_uri, _headers)

  if request.request_body_permitted?
    _body = (body and !body.is_a?(String)) ? JSON.generate(body) : body
    logger.debug { "Processing Body: '#{_body}'" }
    request.body = _body if _body
  end

  send_request(request)
end

#delete(path, options = { }) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 212

def delete(path, options = { })
  query = options.fetch(:query, { })
  @uri = build_uri(path, query)


  request = Net::HTTP::Delete.new(@uri.request_uri, default_request_headers)
  body = options[:body]
  if body
    body = JSON.generate(body) unless body.is_a?(String)
    request.body = body
  end

  send_request(request)
end

#format_body_for_log_output(obj) ⇒ String

Formats a HTTPRequest or HTTPResponse body for log output.

Parameters:

  • obj (HTTPRequest|HTTPResponse)

Returns:

  • (String)


104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 104

def format_body_for_log_output(obj)
  if obj.content_type == 'application/json'
    if @log_pretty_print_body
      _body = obj.body
      output = "\n" << JSON.pretty_generate(JSON.parse(_body)) rescue _body
      return output
    else
      return obj.body
    end
  else
    return obj.body.inspect
  end
end

#get(path, query = nil, options = { }) ⇒ Object



227
228
229
230
231
232
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 227

def get(path, query = nil, options = { })
  query ||= options.fetch(:query, { })
  @uri = build_uri(path, query)
  request = Net::HTTP::Get.new(@uri.request_uri, default_request_headers)
  send_request(request)
end

#initialize_http(args = { }) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 89

def initialize_http(args = { })
  @http_host_address = args[:http_host_address] ||= DEFAULT_HTTP_HOST_ADDRESS
  @http_host_port = args[:http_host_port] ||= DEFAULT_HTTP_HOST_PORT
  @http = Net::HTTP.new(http_host_address, http_host_port)
  http.use_ssl = true

  # TODO Add SSL Patch
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  http
end

#initialize_logger(args = { }) ⇒ Object



79
80
81
82
83
84
85
86
87
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 79

def initialize_logger(args = { })
  @logger = args[:logger] ||= Logger.new(args[:log_to] || STDOUT)
  log_level = args[:log_level]
  if log_level
    @logger.level = log_level
    args[:logger] = @logger
  end
  @logger
end

#post(path, body, options = { }) ⇒ Object



244
245
246
247
248
249
250
251
252
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 244

def post(path, body, options = { })
  query = options.fetch(:query, { })
  @uri = build_uri(path, query)
  body = JSON.generate(body) unless body.is_a?(String)

  request = Net::HTTP::Post.new(@uri.request_uri, default_request_headers)
  request.body = body
  send_request(request)
end

#put(path, body, options = { }) ⇒ Object



234
235
236
237
238
239
240
241
242
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 234

def put(path, body, options = { })
  query = options.fetch(:query, { })
  @uri = build_uri(path, query)
  body = JSON.generate(body) unless body.is_a?(String)

  request = Net::HTTP::Put.new(@uri.request_uri, default_request_headers)
  request.body = body
  send_request(request)
end

#request_method_name_to_class_name(method_name) ⇒ Object



169
170
171
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 169

def request_method_name_to_class_name(method_name)
  method_name.to_s.capitalize
end

#response_parsedObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 146

def response_parsed
  @response_parsed ||= begin
    response_content_type = response.content_type
    logger.debug { "Parsing Response: #{response_content_type}" }

    case response_content_type
      when 'application/json'
        JSON.parse(response.body) rescue response
      # when 'text/html'
      # when 'text/plain'
      else
        response.body
    end
  end
end

#send_request(request) ⇒ Object

Parameters:

  • request (Net::HTTPRequest)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 119

def send_request(request)
  @response_parsed = nil
  @request = request

  begin
    logger.debug { %(REQUEST: #{request.method} http#{http.use_ssl? ? 's' : ''}://#{http.address}:#{http.port}#{request.path} HEADERS: #{request.to_hash.inspect} #{log_request_body and request.request_body_permitted? ? "BODY: #{format_body_for_log_output(request)}" : ''}) }

    @response = http.request(request)
    logger.debug { %(RESPONSE: #{response.inspect} HEADERS: #{response.to_hash.inspect} #{log_response_body and response.respond_to?(:body) ? "BODY: #{format_body_for_log_output(response)}" : ''}) }
    raise RateLimitException, "#{response.to_hash.inspect}" if response.code == '420'
  rescue RateLimitException => e
    logger.warn { "Rate Limited. Will retry in #{@delay_between_rate_limit_retries} seconds." }
    sleep_break @delay_between_rate_limit_retries
    retry unless @cancelled
  end

  @parse_response ? response_parsed : response.body
end

#sleep_break(seconds) ⇒ Object



138
139
140
141
142
143
144
# File 'lib/ubiquity/mediasilo/api/v3/http_client.rb', line 138

def sleep_break(seconds)
  while (seconds > 0)
    sleep(1)
    seconds -= 1
    break if @cancelled
  end
end