Class: TwelvedataRuby::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/twelvedata_ruby/response.rb

Constant Summary collapse

CSV_COL_SEP =
";"
HTTP_STATUSES =
{http_error: (400..600), success: (200..299)}.freeze
CONTENT_TYPE_HANDLERS =
{
  json: {parser: :json_parser, dumper: :json_dumper},
  csv: {parser: :csv_parser, dumper: :csv_dumper},
  plain: {parser: :plain_parser, dumper: :to_s}
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(http_response:, request:, headers: nil, body: nil) ⇒ Response

Returns a new instance of Response.



39
40
41
42
43
# File 'lib/twelvedata_ruby/response.rb', line 39

def initialize(http_response:, request:, headers: nil, body: nil)
  self.http_response = http_response
  self.headers = headers || http_response.headers
  self.body = body || http_response.body
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body.



37
38
39
# File 'lib/twelvedata_ruby/response.rb', line 37

def body
  @body
end

#headersObject

Returns the value of attribute headers.



37
38
39
# File 'lib/twelvedata_ruby/response.rb', line 37

def headers
  @headers
end

#http_responseObject

Returns the value of attribute http_response.



37
38
39
# File 'lib/twelvedata_ruby/response.rb', line 37

def http_response
  @http_response
end

#requestObject

Returns the value of attribute request.



37
38
39
# File 'lib/twelvedata_ruby/response.rb', line 37

def request
  @request
end

Class Method Details

.http_status_codesObject



32
33
34
# File 'lib/twelvedata_ruby/response.rb', line 32

def http_status_codes
  @http_status_codes ||= HTTP_STATUSES.values.map(&:to_a).flatten
end

.resolve(http_response, request) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/twelvedata_ruby/response.rb', line 15

def resolve(http_response, request)
  if http_status_codes.member?(http_response.status)
    new(http_response: http_response, request: request)
  else
    resolve_error(http_response, request)
  end
end

.resolve_error(http_response, request) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/twelvedata_ruby/response.rb', line 23

def resolve_error(http_response, request)
  error_attribs = if http_response.respond_to?(:error) && http_response.error
                    {message: http_response.error.message, code: http_response.error.class.name}
                  else
                    {message: http_response.body.to_s, code: http_response.status}
                  end
  TwelvedataRuby::ResponseError.new(json: (error_attribs || {}), request: request)
end

Instance Method Details

#attachment_filenameObject



45
46
47
48
49
# File 'lib/twelvedata_ruby/response.rb', line 45

def attachment_filename
  return nil unless headers["content-disposition"]

  @attachment_filename ||= headers["content-disposition"].split("filename=").last.delete("\"")
end

#body_parserObject



51
52
53
# File 'lib/twelvedata_ruby/response.rb', line 51

def body_parser
  CONTENT_TYPE_HANDLERS[content_type][:parser]
end

#content_typeObject



55
56
57
# File 'lib/twelvedata_ruby/response.rb', line 55

def content_type
  @content_type ||= headers["content-type"].match(%r{^.+/([a-z]+).*$})&.send(:[], 1)&.to_sym
end

#csv_dumperObject



68
69
70
# File 'lib/twelvedata_ruby/response.rb', line 68

def csv_dumper
  parsed_body.is_a?(CSV::Table) ? parsed_body.to_csv : nil
end

#csv_parserObject



59
60
61
62
63
64
65
66
# File 'lib/twelvedata_ruby/response.rb', line 59

def csv_parser
  chunk_parsed = nil
  opts = {col_sep: CSV_COL_SEP}
  body.each do |chk|
    chunk_parsed = chunk_parsed&.send(:push, CSV.parse(chk, **opts)) || CSV.parse(chk, **opts.merge(headers: true))
  end
  chunk_parsed
end

#dumped_parsed_bodyObject



72
73
74
75
# File 'lib/twelvedata_ruby/response.rb', line 72

def dumped_parsed_body
  @dumped_parsed_body ||=
    parsed_body.respond_to?(parsed_body_dumper) ? parsed_body.send(parsed_body_dumper) : send(parsed_body_dumper)
end

#errorObject



77
78
79
80
81
82
# File 'lib/twelvedata_ruby/response.rb', line 77

def error
  klass_name = ResponseError.error_code_klass(status_code, success_http_status? ? :api : :http)
  return unless klass_name
  TwelvedataRuby.const_get(klass_name)
    .new(json: parsed_body, request: request, code: status_code, message: parsed_body)
end

#http_status_codeObject



84
85
86
# File 'lib/twelvedata_ruby/response.rb', line 84

def http_status_code
  http_response&.status
end

#json_dumperObject



88
89
90
# File 'lib/twelvedata_ruby/response.rb', line 88

def json_dumper
  parsed_body.is_a?(Hash) ? JSON.dump(parsed_body) : nil
end

#json_parserObject



92
93
94
# File 'lib/twelvedata_ruby/response.rb', line 92

def json_parser
  JSON.parse(body, symbolize_names: true)
end

#parsed_bodyObject



96
97
98
# File 'lib/twelvedata_ruby/response.rb', line 96

def parsed_body
  @parsed_body ||= send(body_parser)
end

#parsed_body_dumperObject



100
101
102
# File 'lib/twelvedata_ruby/response.rb', line 100

def parsed_body_dumper
  CONTENT_TYPE_HANDLERS[content_type][:dumper]
end

#plain_parserObject



104
105
106
# File 'lib/twelvedata_ruby/response.rb', line 104

def plain_parser
  body.to_s
end

#status_codeObject



108
109
110
# File 'lib/twelvedata_ruby/response.rb', line 108

def status_code
  @status_code ||= parsed_body.is_a?(Hash) ? parsed_body[:code] : http_status_code
end

#success_http_status?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/twelvedata_ruby/response.rb', line 112

def success_http_status?
  @success_http_status ||= HTTP_STATUSES[:success].member?(http_status_code) || false
end

#to_disk_file(file_fullpath = attachment_filename) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/twelvedata_ruby/response.rb', line 116

def to_disk_file(file_fullpath=attachment_filename)
  return nil unless file_fullpath

  begin
    file = File.open(file_fullpath, "w")
    file.puts dumped_parsed_body
    file
  ensure
    file&.close
  end
end