klient 0.0.1
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.
- checksums.yaml +7 -0
- data/lib/klient.rb +12 -0
- data/lib/klient/hash_methods.rb +32 -0
- data/lib/klient/klient.rb +77 -0
- data/lib/klient/resource.rb +203 -0
- data/lib/klient/resource_collection.rb +17 -0
- data/lib/klient/resource_methods.rb +82 -0
- data/lib/klient/response.rb +59 -0
- data/lib/klient/response_data.rb +31 -0
- data/lib/klient/version.rb +3 -0
- metadata +178 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 05be7e8bf426e334012023a497e378cbede55ec3b6ea3f1f7c0f912798744f3c
|
|
4
|
+
data.tar.gz: 46406b31960577c079ea06bfcd4532e5f175a5a1330d68f26ecac50f999850ba
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 06c7b1ed4383baf74ab9ccd24e471671cc2cbb2f208ce14c56d42962b7e951594210e2a3c082c9478ce275ca7d3058f612933fc6ac748e9beb88b5b60e4bcc70
|
|
7
|
+
data.tar.gz: 411da5be1600da3008f9fb0b3d7bf4804292297984bb78fa8446fd1cb38f72499608ece66c899ac83915c4565f83dfb5b1be1e28843594c6d96df661b183e487
|
data/lib/klient.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
require 'active_support/core_ext'
|
|
3
|
+
require 'addressable'
|
|
4
|
+
require 'nokogiri'
|
|
5
|
+
# require 'parsed_data'
|
|
6
|
+
|
|
7
|
+
require_relative "klient/hash_methods.rb"
|
|
8
|
+
require_relative "klient/klient.rb"
|
|
9
|
+
require_relative "klient/resource.rb"
|
|
10
|
+
require_relative "klient/response.rb"
|
|
11
|
+
require_relative "klient/response_data.rb"
|
|
12
|
+
require_relative "klient/version.rb"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Hash
|
|
2
|
+
def deep_get(key, obj, found = nil)
|
|
3
|
+
if obj.respond_to?(:key?) && obj.key?(key)
|
|
4
|
+
return obj[key]
|
|
5
|
+
elsif obj.respond_to?(:each)
|
|
6
|
+
obj.find { |*a| found = deep_get(key, a.last) }
|
|
7
|
+
return found
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def deep_set(key, obj, value, found = nil)
|
|
12
|
+
if obj.respond_to?(:key?) && obj.key?(key)
|
|
13
|
+
obj[key] = value
|
|
14
|
+
return value
|
|
15
|
+
elsif obj.respond_to?(:each)
|
|
16
|
+
obj.find { |*a| found = deep_set(key, a.last, value) }
|
|
17
|
+
return found
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def method_missing(mth, *args, &block)
|
|
22
|
+
m = mth.to_s
|
|
23
|
+
|
|
24
|
+
if keys.include?(m)
|
|
25
|
+
self[m]
|
|
26
|
+
elsif m =~ /\S+=/
|
|
27
|
+
deep_set(m.gsub(/=/, ''), self, args[0])
|
|
28
|
+
else
|
|
29
|
+
deep_get(m, self)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'rest-client'
|
|
2
|
+
require_relative "resource"
|
|
3
|
+
require_relative "resource_methods"
|
|
4
|
+
|
|
5
|
+
module Klient
|
|
6
|
+
attr_reader :base_url, :header_proc, :collection_accessor, :headers, :collection_key, :url_template, :root
|
|
7
|
+
|
|
8
|
+
module KlientClassMethods
|
|
9
|
+
attr_reader :header_proc, :resource_map
|
|
10
|
+
|
|
11
|
+
include ResourceMethods
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.included(klass)
|
|
15
|
+
klass.extend(KlientClassMethods)
|
|
16
|
+
klass.send(:attr_reader, :header_proc)
|
|
17
|
+
klass.send(:attr_reader, :resource_map)
|
|
18
|
+
klass.send(:attr_reader, :identifier_map)
|
|
19
|
+
klass.instance_variable_set(:@resource_map, {})
|
|
20
|
+
klass.instance_variable_set(:@identifier_map, {})
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(base_url)
|
|
24
|
+
@root = self
|
|
25
|
+
@header_proc = self.class.header_proc
|
|
26
|
+
@collection_accessor = self.class.instance_variable_get(:@collection_accessor)
|
|
27
|
+
@base_url = base_url
|
|
28
|
+
@headers = headers
|
|
29
|
+
@url_template = Addressable::Template.new(base_url)
|
|
30
|
+
|
|
31
|
+
rmap = {}
|
|
32
|
+
self.class::Resource.descendants
|
|
33
|
+
.select { |x| x.name.split('::').length == 2 }
|
|
34
|
+
.sort { |x, y| x.name.demodulize <=> y.name.demodulize }
|
|
35
|
+
.each do |klass|
|
|
36
|
+
next unless klass.id
|
|
37
|
+
cname = klass.name.demodulize.underscore.singularize.to_sym
|
|
38
|
+
cname_plural = klass.name.demodulize.underscore.pluralize.to_sym
|
|
39
|
+
|
|
40
|
+
if rmap.include?(cname)
|
|
41
|
+
next
|
|
42
|
+
else
|
|
43
|
+
rmap[cname_plural] = klass
|
|
44
|
+
rmap[cname] = klass
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
imap = {}
|
|
49
|
+
rmap.values.each do |klass|
|
|
50
|
+
next unless klass.id
|
|
51
|
+
imap[klass.id] = klass
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
@resource_map = rmap
|
|
55
|
+
@identifier_map = imap
|
|
56
|
+
|
|
57
|
+
self.class::Resource.descendants.each do |rklass|
|
|
58
|
+
cname = rklass.name.demodulize.underscore.to_sym
|
|
59
|
+
|
|
60
|
+
if rklass && rklass.arguments && rklass.arguments[:type]
|
|
61
|
+
rklass.resource_type = @resource_map[rklass.arguments[:type]]
|
|
62
|
+
elsif @resource_map[rklass.arguments[:type]] && @identifier_map.key(rklass)
|
|
63
|
+
rklass.resource_type = @resource_map[@identifier_map.key(rklass)]
|
|
64
|
+
elsif @resource_map.values.include?(rklass)
|
|
65
|
+
rklass.resource_type = rklass
|
|
66
|
+
elsif @resource_map[cname]
|
|
67
|
+
rklass.resource_type = @resource_map[cname]
|
|
68
|
+
elsif @identifier_map[rklass.id]
|
|
69
|
+
rklass.resource_type = rklass.id
|
|
70
|
+
else
|
|
71
|
+
rklass.resource_type = rklass
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
alias url base_url
|
|
77
|
+
end
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
require_relative "resource_methods"
|
|
2
|
+
require_relative "resource_collection"
|
|
3
|
+
require 'pry'
|
|
4
|
+
module Klient
|
|
5
|
+
class Resource
|
|
6
|
+
attr_reader :collection_accessor, :header_proc, :headers, :id, :last_response, :parent, :status, :url, :url_arguments, :url_template,:root
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
attr_reader :collection_accessor, :id, :identifier, :mapping, :url_template
|
|
10
|
+
attr_accessor :arguments, :resource_type, :type
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
extend ResourceMethods
|
|
14
|
+
|
|
15
|
+
def initialize(parent)
|
|
16
|
+
@root = parent.root
|
|
17
|
+
@header_proc = parent.header_proc
|
|
18
|
+
@regexp = /#{self.class.name.demodulize.underscore.gsub(/(_|-|\s+)/, "(_|-|\s*)")}/i
|
|
19
|
+
@id = self.class.try(:id)
|
|
20
|
+
@collection_accessor = @identifier = self.class.try(:identifier)
|
|
21
|
+
|
|
22
|
+
if @id
|
|
23
|
+
@url_arguments = {@id => @identifier}
|
|
24
|
+
else
|
|
25
|
+
@url_arguments = {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@parent = parent
|
|
29
|
+
@headers = {}
|
|
30
|
+
|
|
31
|
+
@url_template = Addressable::Template.new(
|
|
32
|
+
@parent.url + self.class.url_template.pattern
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def inspect
|
|
37
|
+
"#<#{self.class.name}:#{object_id} @url=#{self.url.inspect} @status_code=#{self.last_response.try(:status) || 'nil'}>"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
%i(delete get head).each do |mth|
|
|
41
|
+
define_method(mth) do |identifier = nil, **params|
|
|
42
|
+
|
|
43
|
+
if params.empty?
|
|
44
|
+
@headers = @header_proc.call
|
|
45
|
+
else
|
|
46
|
+
@headers = @header_proc.call.merge(params: params)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if identifier
|
|
50
|
+
out = process_response(
|
|
51
|
+
RestClient.send(
|
|
52
|
+
mth,
|
|
53
|
+
@url_template.expand(@id => identifier).to_s,
|
|
54
|
+
@headers
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
else
|
|
58
|
+
out = process_response(RestClient.send(mth, url, @headers))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if respond_to?(:last_response) && out.respond_to?(:last_response)
|
|
62
|
+
@last_response = out.last_response
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
out.instance_variable_set(:@identifier, identifier)
|
|
66
|
+
out
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
%i(post put).each do |mth|
|
|
71
|
+
define_method(mth) do |identifier = nil, doc, **params|
|
|
72
|
+
if params.empty?
|
|
73
|
+
@headers = @header_proc.call
|
|
74
|
+
else
|
|
75
|
+
@headers = @header_proc.call.merge(params: params)
|
|
76
|
+
end
|
|
77
|
+
out = process_response(
|
|
78
|
+
RestClient.send(mth, url, doc, @headers)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
if respond_to?(:last_response) && out.respond_to?(:last_response)
|
|
82
|
+
@last_response = out.last_response
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
out.instance_variable_set(:@identifier, identifier)
|
|
86
|
+
out
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def url
|
|
91
|
+
@url_template.expand(@url_arguments).to_s
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
# Assumes JSON for the moment.
|
|
96
|
+
def process_doc(doc)
|
|
97
|
+
if doc.is_a?(Hash)
|
|
98
|
+
doc.to_json
|
|
99
|
+
elsif doc.empty?
|
|
100
|
+
{}.to_json
|
|
101
|
+
else
|
|
102
|
+
doc
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def method_missing(mth, *args, &block)
|
|
107
|
+
if @parsed_body.respond_to?(mth)
|
|
108
|
+
@parsed_body.send(mth, *args, &block)
|
|
109
|
+
else
|
|
110
|
+
@last_response.send(mth, *args, &block)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# EXPERIMENTAL (USING HASH MODS)
|
|
115
|
+
def process_response(resp)
|
|
116
|
+
parsed = JSON.parse(resp.body)#.to_data
|
|
117
|
+
|
|
118
|
+
klass_type = self.class.resource_type
|
|
119
|
+
|
|
120
|
+
if klass_type == self.class
|
|
121
|
+
klass = self.class.new(parent)
|
|
122
|
+
else
|
|
123
|
+
klass = self.class.resource_type.new(@root)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if klass_type != self.class
|
|
127
|
+
if match = klass.url_template.match(resp.request.args[:url])
|
|
128
|
+
klass.url_arguments[klass.id] = match.mapping.with_indifferent_access[klass.id]
|
|
129
|
+
end
|
|
130
|
+
else
|
|
131
|
+
if match = self.url_template.match(resp.request.args[:url])
|
|
132
|
+
klass.url_arguments[klass.id] = match.mapping.with_indifferent_access[klass.id]
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if klass.url_arguments[klass.id]
|
|
137
|
+
klass.url_arguments[klass.id]= parsed[klass.id]
|
|
138
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
|
139
|
+
return klass
|
|
140
|
+
# elsif parsed.is_a?(Hash) && parsed.keys.any? { |k| k.to_sym == @root.collection_accessor }
|
|
141
|
+
# klass.url_arguments[klass.id]= parsed[klass.id]
|
|
142
|
+
# klass.instance_variable_set(:@last_response, Response.new(resp))
|
|
143
|
+
# return klass
|
|
144
|
+
elsif key = parsed.keys.find { |k| k.to_s =~ @regexp }
|
|
145
|
+
if parsed[key].is_a?(Array)
|
|
146
|
+
arr = parsed[key].map! do |res|
|
|
147
|
+
tmp = klass_type.new(@root)
|
|
148
|
+
# TODO: Ugly. Revisit after recursive lookup.
|
|
149
|
+
tmp.url_arguments[klass.id]= res.send(klass.id) || res.send(klass.collection_accessor).try(klass.id)
|
|
150
|
+
|
|
151
|
+
processed = Response.new(resp, res)
|
|
152
|
+
tmp.instance_variable_set(:@last_response, processed)
|
|
153
|
+
|
|
154
|
+
tmp.instance_variable_set(:@parsed_body, processed.parsed_body)
|
|
155
|
+
tmp.instance_variable_set(:@status, processed.status)
|
|
156
|
+
tmp
|
|
157
|
+
end
|
|
158
|
+
return Klient::ResourceCollection.new(arr)
|
|
159
|
+
else
|
|
160
|
+
klass.url_arguments[klass.id]= parsed.send(klass.id) if klass.id
|
|
161
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
|
162
|
+
return klass
|
|
163
|
+
end
|
|
164
|
+
elsif self.class.type == :resource
|
|
165
|
+
klass.url_arguments[klass.id]= parsed.send(klass.id) if klass.id
|
|
166
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
|
167
|
+
return klass
|
|
168
|
+
elsif klass.url_arguments[klass.id]
|
|
169
|
+
klass.url_arguments[klass.id]= parsed.send(klass.id)
|
|
170
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
|
171
|
+
return klass
|
|
172
|
+
else
|
|
173
|
+
if parsed.is_a?(Array)
|
|
174
|
+
arr = parsed
|
|
175
|
+
elsif parsed.keys.length == 1 && parsed[parsed.keys.first].is_a?(Array)
|
|
176
|
+
arr = parsed[parsed.keys.first]
|
|
177
|
+
else
|
|
178
|
+
parsed.keys.each do |k|
|
|
179
|
+
if parsed[k].is_a?(Array) && parsed[k].first && parsed[k].first.send(klass.id.to_sym)
|
|
180
|
+
arr = parsed[k]
|
|
181
|
+
break
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
arr.map! do |res|
|
|
187
|
+
tmp = klass_type.new(@root)
|
|
188
|
+
# TODO: Ugly. Revisit after recursive lookup.
|
|
189
|
+
tmp.url_arguments[klass.id]= res.send(klass.id) || res.send(klass.collection_accessor).try(klass.id)
|
|
190
|
+
|
|
191
|
+
processed = Response.new(resp, res)
|
|
192
|
+
tmp.instance_variable_set(:@last_response, processed)
|
|
193
|
+
|
|
194
|
+
tmp.instance_variable_set(:@parsed_body, processed.parsed_body)
|
|
195
|
+
tmp.instance_variable_set(:@status, processed.status)
|
|
196
|
+
tmp
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
return Klient::ResourceCollection.new(arr)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Klient
|
|
2
|
+
class ResourceCollection
|
|
3
|
+
attr_reader :members, :last_response
|
|
4
|
+
|
|
5
|
+
def initialize(arr)
|
|
6
|
+
@members = arr
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def method_missing(mth, *args, &block)
|
|
10
|
+
@members.send(mth, *args, &block)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def respond_to?(mth, *args, &block)
|
|
14
|
+
super || @members.respond_to?(mth)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module ResourceMethods
|
|
2
|
+
def default_collection_accessor(sym)
|
|
3
|
+
@collection_accessor = sym
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def headers(&block)
|
|
7
|
+
@header_proc = block
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def collection(name, template = nil, **hash_args, &block)
|
|
11
|
+
klass_name = name.to_s.camelcase
|
|
12
|
+
|
|
13
|
+
klass = Class.new(Klient::Resource) do
|
|
14
|
+
@arguments = hash_args
|
|
15
|
+
@type = :collection
|
|
16
|
+
|
|
17
|
+
# Obtain the collection's resource identifier. Don't allow hash arg AND block
|
|
18
|
+
# param for same thing -- it has to be either one or the other.
|
|
19
|
+
if block_given? && block.arity > 0 && hash_args[:identifier]
|
|
20
|
+
raise ArgumentError, "Collection identifier for :#{name} can be specified as a " \
|
|
21
|
+
"hash argument OR a block parameter (You can't use both simultaneously.)"
|
|
22
|
+
elsif block_given? && block.arity > 0
|
|
23
|
+
@id = block.parameters[0][1]
|
|
24
|
+
elsif hash_args[:identifier]
|
|
25
|
+
@id = hash_args[:identifier]
|
|
26
|
+
else
|
|
27
|
+
# raise ArgumentError, "#{name} collection definition does not specify a resource identifier."
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Don't allow templates with variables.
|
|
31
|
+
if template && template =~ /[\{\}]/
|
|
32
|
+
raise ArgumentError, "URL template variables not supported."
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Build a URL template if the template arg was provided.
|
|
36
|
+
if template && id
|
|
37
|
+
@url_template = Addressable::Template.new(template.to_s + "{/#{id}}")
|
|
38
|
+
elsif id
|
|
39
|
+
@identifier = nil
|
|
40
|
+
@url_template = Addressable::Template.new("/#{name}{/#{id}}")
|
|
41
|
+
else
|
|
42
|
+
@identifier = nil
|
|
43
|
+
@url_template = Addressable::Template.new("/#{name}")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class_eval(&block) if block
|
|
47
|
+
end
|
|
48
|
+
const_set(klass_name, klass)
|
|
49
|
+
|
|
50
|
+
define_method(name) do
|
|
51
|
+
klass.new(self)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def resource(name, template = nil, **hash_args, &block)
|
|
56
|
+
klass_name = name.to_s.camelcase
|
|
57
|
+
|
|
58
|
+
klass = Class.new(Klient::Resource) do
|
|
59
|
+
@arguments = hash_args
|
|
60
|
+
@type = :resource
|
|
61
|
+
|
|
62
|
+
# TODO: Avoid identifier conflicts between hash and URL template.
|
|
63
|
+
if template
|
|
64
|
+
@url_template = Addressable::Template.new(template)
|
|
65
|
+
else
|
|
66
|
+
@identifier = nil
|
|
67
|
+
@url_template = Addressable::Template.new("/#{name}")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class_eval(&block) if block
|
|
71
|
+
end
|
|
72
|
+
const_set(klass_name, klass)
|
|
73
|
+
|
|
74
|
+
define_method(name) do
|
|
75
|
+
klass.new(self)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def resources(*resource_names)
|
|
80
|
+
resource_names.each { |rname| resource rname }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
module Klient
|
|
3
|
+
class Response
|
|
4
|
+
attr_reader :original_response, :parsed_body, :parsed_headers, :status
|
|
5
|
+
|
|
6
|
+
def body
|
|
7
|
+
@original_response.body
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def ok?
|
|
11
|
+
(200..299).include?(status_code)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def status_code
|
|
15
|
+
@original_response.code
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def headers
|
|
19
|
+
@parsed_headers
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize(original_response, data = nil)
|
|
23
|
+
@status = original_response.code
|
|
24
|
+
|
|
25
|
+
# If data arg is provided then it's a collection resource and the original
|
|
26
|
+
# response is for the entire collection. We don't want that -- this is an
|
|
27
|
+
# individual resource FOR the collection -- so the data arg is used in place
|
|
28
|
+
# of the parsed body for the collection response.
|
|
29
|
+
if data
|
|
30
|
+
@original_response = nil
|
|
31
|
+
@parsed_body = data
|
|
32
|
+
@parsed_headers = nil
|
|
33
|
+
else
|
|
34
|
+
@original_response = original_response
|
|
35
|
+
@body = @original_response.body
|
|
36
|
+
@parsed_headers = @original_response.headers
|
|
37
|
+
|
|
38
|
+
if @original_response.body.blank?
|
|
39
|
+
@parsed_body = {}
|
|
40
|
+
else
|
|
41
|
+
@parsed_body = JSON.parse(@original_response.body)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# TODO: This is dangerously wrong. It's just a shortcut to get something working.
|
|
47
|
+
def method_missing(mth, *args, &block)
|
|
48
|
+
if mth.to_s =~ /http_(\d+)\?/
|
|
49
|
+
status_code == $1.to_i
|
|
50
|
+
else
|
|
51
|
+
@parsed_body.send(mth)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def respond_to_missing?(mth, *args)
|
|
56
|
+
mth.to_s =~ /http_(\d+)\?/ || @parsed_body.respond_to?(mth) || super
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Klient
|
|
2
|
+
class ResponseData
|
|
3
|
+
attr_reader :original_response, :parsed_body, :parsed_headers, :status_code
|
|
4
|
+
|
|
5
|
+
def body
|
|
6
|
+
nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def headers
|
|
10
|
+
nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(status_code, parsed_body)
|
|
14
|
+
@status_code = status_code
|
|
15
|
+
@parsed_body = parsed_body.freeze
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def ok?
|
|
19
|
+
(200..299).include?(status_code)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# TODO: Bandaid.
|
|
23
|
+
def method_missing(mth, *args, &block)
|
|
24
|
+
@parsed_body.send(mth, *args, &block)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def respond_to_missing?(mth, *args)
|
|
28
|
+
mth.to_s =~ /http_(\d+)\?/ || @parsed_body.respond_to?(mth) || super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: klient
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- John Fitisoff
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-01-16 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 4.2.5
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 4.2.5
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: addressable
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 2.5.1
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 2.5.1
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: nokogiri
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 1.7.0
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 1.7.0
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rest-client
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 2.0.0
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 2.0.0
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: coveralls
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.8.21
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 0.8.21
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: simplecov
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: 0.16.1
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: 0.16.1
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: pry
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 0.11.3
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 0.11.3
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rake
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: 12.3.1
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 12.3.1
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rspec
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: 3.7.0
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: 3.7.0
|
|
139
|
+
description: Experimental REST API client library.
|
|
140
|
+
email: jfitisoff@yahoo.com
|
|
141
|
+
executables: []
|
|
142
|
+
extensions: []
|
|
143
|
+
extra_rdoc_files: []
|
|
144
|
+
files:
|
|
145
|
+
- lib/klient.rb
|
|
146
|
+
- lib/klient/hash_methods.rb
|
|
147
|
+
- lib/klient/klient.rb
|
|
148
|
+
- lib/klient/resource.rb
|
|
149
|
+
- lib/klient/resource_collection.rb
|
|
150
|
+
- lib/klient/resource_methods.rb
|
|
151
|
+
- lib/klient/response.rb
|
|
152
|
+
- lib/klient/response_data.rb
|
|
153
|
+
- lib/klient/version.rb
|
|
154
|
+
homepage: https://github.com/jfitisoff/klient
|
|
155
|
+
licenses:
|
|
156
|
+
- MIT
|
|
157
|
+
metadata: {}
|
|
158
|
+
post_install_message:
|
|
159
|
+
rdoc_options: []
|
|
160
|
+
require_paths:
|
|
161
|
+
- lib
|
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: 2.3.0
|
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
|
+
requirements:
|
|
169
|
+
- - ">="
|
|
170
|
+
- !ruby/object:Gem::Version
|
|
171
|
+
version: '0'
|
|
172
|
+
requirements: []
|
|
173
|
+
rubyforge_project:
|
|
174
|
+
rubygems_version: 2.7.6
|
|
175
|
+
signing_key:
|
|
176
|
+
specification_version: 4
|
|
177
|
+
summary: Experimental REST API client library.
|
|
178
|
+
test_files: []
|