contentful 0.1.0 → 0.1.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/.gitignore +1 -0
- data/ChangeLog.md +6 -0
- data/Gemfile +5 -0
- data/README.md +1 -0
- data/contentful.gemspec +1 -1
- data/lib/contentful/array.rb +1 -2
- data/lib/contentful/asset.rb +3 -3
- data/lib/contentful/client.rb +15 -18
- data/lib/contentful/content_type.rb +1 -1
- data/lib/contentful/dynamic_entry.rb +6 -6
- data/lib/contentful/entry.rb +1 -1
- data/lib/contentful/error.rb +3 -3
- data/lib/contentful/field.rb +1 -1
- data/lib/contentful/file.rb +1 -1
- data/lib/contentful/link.rb +2 -2
- data/lib/contentful/locale.rb +1 -1
- data/lib/contentful/location.rb +1 -1
- data/lib/contentful/resource.rb +10 -11
- data/lib/contentful/resource_builder.rb +63 -39
- data/lib/contentful/space.rb +1 -1
- data/lib/contentful/support.rb +5 -3
- data/lib/contentful/version.rb +1 -1
- data/spec/fixtures/json_responses/includes.json +111 -0
- data/spec/fixtures/json_responses/link_array.json +43 -0
- data/spec/resource_building_spec.rb +20 -0
- data/spec/spec_helper.rb +5 -1
- metadata +138 -192
- data/.README.md.swp +0 -0
- data/do_request.sh +0 -5
- data/doc/Contentful.html +0 -131
- data/doc/Contentful/AccessDenied.html +0 -158
- data/doc/Contentful/Array.html +0 -346
- data/doc/Contentful/Asset.html +0 -315
- data/doc/Contentful/BadRequest.html +0 -158
- data/doc/Contentful/Client.html +0 -1407
- data/doc/Contentful/ContentType.html +0 -183
- data/doc/Contentful/DynamicEntry.html +0 -333
- data/doc/Contentful/Entry.html +0 -198
- data/doc/Contentful/Error.html +0 -413
- data/doc/Contentful/Field.html +0 -161
- data/doc/Contentful/File.html +0 -160
- data/doc/Contentful/Link.html +0 -275
- data/doc/Contentful/Locale.html +0 -161
- data/doc/Contentful/NotFound.html +0 -158
- data/doc/Contentful/Request.html +0 -669
- data/doc/Contentful/Resource.html +0 -606
- data/doc/Contentful/Resource/AssetFields.html +0 -413
- data/doc/Contentful/Resource/AssetFields/ClassMethods.html +0 -174
- data/doc/Contentful/Resource/ClassMethods.html +0 -271
- data/doc/Contentful/Resource/Fields.html +0 -398
- data/doc/Contentful/Resource/Fields/ClassMethods.html +0 -187
- data/doc/Contentful/Resource/SystemProperties.html +0 -444
- data/doc/Contentful/Resource/SystemProperties/ClassMethods.html +0 -174
- data/doc/Contentful/ResourceBuilder.html +0 -1400
- data/doc/Contentful/Response.html +0 -546
- data/doc/Contentful/ServerError.html +0 -158
- data/doc/Contentful/Space.html +0 -183
- data/doc/Contentful/Support.html +0 -198
- data/doc/Contentful/Unauthorized.html +0 -158
- data/doc/Contentful/UnparsableJson.html +0 -158
- data/doc/Contentful/UnparsableResource.html +0 -158
- data/doc/_index.html +0 -410
- data/doc/class_list.html +0 -54
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -57
- data/doc/css/style.css +0 -338
- data/doc/file.README.html +0 -214
- data/doc/file_list.html +0 -56
- data/doc/frames.html +0 -26
- data/doc/index.html +0 -214
- data/doc/js/app.js +0 -219
- data/doc/js/full_list.js +0 -178
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -533
- data/doc/top-level-namespace.html +0 -112
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a1f5e5d0ae0f81f3be2fcef1c4cdffbd4eeb253a
|
4
|
+
data.tar.gz: 7826b5a5d1dbbdd695617a02840a2e26cd79fb22
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68d88252df1d4fb897c243d05fea8cd104c342fa8431de9b693abf7bf49d931d76f7b821ad984841d6803ddd60291eb9e2745a0b1a69d2022088079f5deea471
|
7
|
+
data.tar.gz: 0dc914a52aa703c1cade8c1bbc10f3ed7d3aec2ef8d8c7db064d47664ec2fab7c27fbda756e56ebe7d183985600355fac35f134720bb836959455dac92c79c3f
|
data/.gitignore
CHANGED
data/ChangeLog.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# contentful.rb
|
2
|
+
[](http://badge.fury.io/rb/contentful) [](https://travis-ci.org/contentful/contentful.rb) [](https://coveralls.io/r/contentful/contentful.rb?branch=master)
|
2
3
|
|
3
4
|
Ruby client for the [Contentful](https://www.contentful.com) Content Delivery API.
|
4
5
|
|
data/contentful.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^spec/})
|
18
18
|
gem.require_paths = ['lib']
|
19
19
|
|
20
|
-
gem.add_dependency 'http', '~> 0'
|
20
|
+
gem.add_dependency 'http', '~> 0', '< 0.6'
|
21
21
|
gem.add_dependency 'multi_json', '~> 1'
|
22
22
|
|
23
23
|
gem.add_development_dependency 'bundler', '~> 1.5'
|
data/lib/contentful/array.rb
CHANGED
data/lib/contentful/asset.rb
CHANGED
@@ -21,13 +21,13 @@ module Contentful
|
|
21
21
|
w: options[:w] || options[:width],
|
22
22
|
h: options[:h] || options[:height],
|
23
23
|
fm: options[:fm] || options[:format],
|
24
|
-
q: options[:q] || options[:quality]
|
25
|
-
}.reject{ |k,v| v.nil? }
|
24
|
+
q: options[:q] || options[:quality]
|
25
|
+
}.reject { |k, v| v.nil? }
|
26
26
|
|
27
27
|
if query.empty?
|
28
28
|
file.url
|
29
29
|
else
|
30
|
-
"#{file.url}?#{
|
30
|
+
"#{file.url}?#{URI.encode_www_form(query)}"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/lib/contentful/client.rb
CHANGED
@@ -17,12 +17,11 @@ module Contentful
|
|
17
17
|
authentication_mechanism: :header,
|
18
18
|
resource_builder: ResourceBuilder,
|
19
19
|
resource_mapping: {},
|
20
|
-
raw_mode: false
|
20
|
+
raw_mode: false
|
21
21
|
}
|
22
22
|
|
23
23
|
attr_reader :configuration, :dynamic_entry_cache
|
24
24
|
|
25
|
-
|
26
25
|
# Wraps the actual HTTP request
|
27
26
|
def self.get_http(url, query, headers = {})
|
28
27
|
HTTP[headers].get(url, params: query)
|
@@ -101,9 +100,9 @@ module Contentful
|
|
101
100
|
|
102
101
|
# Returns the headers used for the HTTP requests
|
103
102
|
def request_headers
|
104
|
-
headers = {
|
105
|
-
headers[
|
106
|
-
headers[
|
103
|
+
headers = { 'User-Agent' => "RubyContentfulGem/#{Contentful::VERSION}" }
|
104
|
+
headers['Authorization'] = "Bearer #{configuration[:access_token]}" if configuration[:authentication_mechanism] == :header
|
105
|
+
headers['Content-Type'] = "application/vnd.contentful.delivery.v#{configuration[:api_version].to_i}+json" if configuration[:api_version]
|
107
106
|
|
108
107
|
headers
|
109
108
|
end
|
@@ -125,7 +124,7 @@ module Contentful
|
|
125
124
|
self.class.get_http(
|
126
125
|
base_url + request.url,
|
127
126
|
request_query(request.query),
|
128
|
-
request_headers
|
127
|
+
request_headers
|
129
128
|
), request
|
130
129
|
)
|
131
130
|
|
@@ -140,12 +139,12 @@ module Contentful
|
|
140
139
|
# See README for details.
|
141
140
|
def update_dynamic_entry_cache!
|
142
141
|
@dynamic_entry_cache = Hash[
|
143
|
-
content_types(limit: 0).map
|
142
|
+
content_types(limit: 0).map do |ct|
|
144
143
|
[
|
145
144
|
ct.id.to_sym,
|
146
|
-
DynamicEntry.create(ct)
|
145
|
+
DynamicEntry.create(ct)
|
147
146
|
]
|
148
|
-
|
147
|
+
end
|
149
148
|
]
|
150
149
|
end
|
151
150
|
|
@@ -155,39 +154,37 @@ module Contentful
|
|
155
154
|
@dynamic_entry_cache[key.to_sym] = klass
|
156
155
|
end
|
157
156
|
|
158
|
-
|
159
157
|
private
|
160
158
|
|
161
159
|
def normalize_configuration!
|
162
|
-
[:space, :access_token, :api_url].each{ |s| configuration[s] = configuration[s].to_s }
|
160
|
+
[:space, :access_token, :api_url].each { |s| configuration[s] = configuration[s].to_s }
|
163
161
|
configuration[:authentication_mechanism] = configuration[:authentication_mechanism].to_sym
|
164
162
|
end
|
165
163
|
|
166
164
|
def validate_configuration!
|
167
165
|
if configuration[:space].empty?
|
168
|
-
raise ArgumentError,
|
166
|
+
raise ArgumentError, 'You will need to initialize a client with a :space'
|
169
167
|
end
|
170
168
|
|
171
169
|
if configuration[:access_token].empty?
|
172
|
-
raise ArgumentError,
|
170
|
+
raise ArgumentError, 'You will need to initialize a client with an :access_token'
|
173
171
|
end
|
174
172
|
|
175
173
|
if configuration[:api_url].empty?
|
176
|
-
raise ArgumentError,
|
174
|
+
raise ArgumentError, 'The client configuration needs to contain an :api_url'
|
177
175
|
end
|
178
176
|
|
179
177
|
unless configuration[:api_version].to_i >= 0
|
180
|
-
raise ArgumentError,
|
178
|
+
raise ArgumentError, 'The :api_version must be a positive number or nil'
|
181
179
|
end
|
182
180
|
|
183
181
|
unless [:header, :query_string].include? configuration[:authentication_mechanism]
|
184
|
-
raise ArgumentError,
|
182
|
+
raise ArgumentError, 'The authentication mechanism must be :header or :query_string'
|
185
183
|
end
|
186
184
|
|
187
185
|
unless [:auto, :manual].include? configuration[:dynamic_entries]
|
188
|
-
raise ArgumentError,
|
186
|
+
raise ArgumentError, 'The :dynamic_entries mode must be :auto or :manual'
|
189
187
|
end
|
190
188
|
end
|
191
189
|
end
|
192
190
|
end
|
193
|
-
|
@@ -12,7 +12,7 @@ module Contentful
|
|
12
12
|
'Float' => :float,
|
13
13
|
'Boolean' => :boolean,
|
14
14
|
'Date' => :date,
|
15
|
-
'Location' => Location
|
15
|
+
'Location' => Location
|
16
16
|
}
|
17
17
|
|
18
18
|
def self.create(content_type)
|
@@ -21,17 +21,17 @@ module Contentful
|
|
21
21
|
end
|
22
22
|
|
23
23
|
fields_coercions = Hash[
|
24
|
-
content_type.fields.map
|
24
|
+
content_type.fields.map do |field|
|
25
25
|
[field.id.to_sym, KNOWN_TYPES[field.type]]
|
26
|
-
|
26
|
+
end
|
27
27
|
]
|
28
28
|
|
29
29
|
Class.new DynamicEntry do
|
30
|
-
content_type.fields.each
|
30
|
+
content_type.fields.each do |f|
|
31
31
|
define_method Support.snakify(f.id).to_sym do
|
32
32
|
fields[f.id.to_sym]
|
33
33
|
end
|
34
|
-
|
34
|
+
end
|
35
35
|
|
36
36
|
define_singleton_method :fields_coercions do
|
37
37
|
fields_coercions
|
@@ -51,4 +51,4 @@ module Contentful
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
|
-
end
|
54
|
+
end
|
data/lib/contentful/entry.rb
CHANGED
data/lib/contentful/error.rb
CHANGED
@@ -11,8 +11,8 @@ module Contentful
|
|
11
11
|
|
12
12
|
# Shortcut for creating specialized error classes
|
13
13
|
# USAGE rescue Contentful::Error[404]
|
14
|
-
def self.[](
|
15
|
-
case
|
14
|
+
def self.[](error_status_code)
|
15
|
+
case error_status_code
|
16
16
|
when 404
|
17
17
|
NotFound
|
18
18
|
when 400
|
@@ -49,4 +49,4 @@ module Contentful
|
|
49
49
|
|
50
50
|
# Raised when response is not parsable as a Contentful::Resource
|
51
51
|
class UnparsableResource < Error; end
|
52
|
-
end
|
52
|
+
end
|
data/lib/contentful/field.rb
CHANGED
data/lib/contentful/file.rb
CHANGED
data/lib/contentful/link.rb
CHANGED
@@ -10,11 +10,11 @@ module Contentful
|
|
10
10
|
# Queries contentful for the Resource the Link is refering to
|
11
11
|
# Takes an optional query hash
|
12
12
|
def resolve(query = {})
|
13
|
-
id_and_query = [(id unless link_type ==
|
13
|
+
id_and_query = [(id unless link_type == 'Space')].compact + [query]
|
14
14
|
client.public_send(
|
15
15
|
Contentful::Support.snakify(link_type).to_sym,
|
16
16
|
*id_and_query
|
17
17
|
)
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
data/lib/contentful/locale.rb
CHANGED
data/lib/contentful/location.rb
CHANGED
data/lib/contentful/resource.rb
CHANGED
@@ -12,11 +12,11 @@ module Contentful
|
|
12
12
|
# by the client by default
|
13
13
|
module Resource
|
14
14
|
COERCIONS = {
|
15
|
-
string: ->(v){ v.to_s },
|
16
|
-
integer: ->(v){ v.to_i },
|
17
|
-
float: ->(v){ v.to_f },
|
18
|
-
boolean: ->(v){ !!v },
|
19
|
-
date: ->(v){ DateTime.parse(v) }
|
15
|
+
string: ->(v) { v.to_s },
|
16
|
+
integer: ->(v) { v.to_i },
|
17
|
+
float: ->(v) { v.to_f },
|
18
|
+
boolean: ->(v) { !!v },
|
19
|
+
date: ->(v) { DateTime.parse(v) }
|
20
20
|
}
|
21
21
|
|
22
22
|
attr_reader :properties, :request, :client
|
@@ -30,7 +30,7 @@ module Contentful
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def inspect(info = nil)
|
33
|
-
properties_info = properties.empty? ?
|
33
|
+
properties_info = properties.empty? ? '' : " @properties=#{properties.inspect}"
|
34
34
|
"#<#{self.class}:#{properties_info}#{info}>"
|
35
35
|
end
|
36
36
|
|
@@ -59,18 +59,17 @@ module Contentful
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
62
|
private
|
64
63
|
|
65
64
|
def extract_from_object(object, namespace, keys = nil)
|
66
65
|
if object
|
67
66
|
keys ||= object.keys
|
68
|
-
keys.each.with_object({})
|
67
|
+
keys.each.with_object({}) do |name, res|
|
69
68
|
res[name.to_sym] = coerce_value_or_array(
|
70
69
|
object.is_a?(::Array) ? object : object[name.to_s],
|
71
|
-
self.class.public_send(:"#{namespace}_coercions")[name.to_sym]
|
70
|
+
self.class.public_send(:"#{namespace}_coercions")[name.to_sym]
|
72
71
|
)
|
73
|
-
|
72
|
+
end
|
74
73
|
else
|
75
74
|
{}
|
76
75
|
end
|
@@ -78,7 +77,7 @@ module Contentful
|
|
78
77
|
|
79
78
|
def coerce_value_or_array(value, what = nil)
|
80
79
|
if value.is_a? ::Array
|
81
|
-
value.map{ |v| coerce_or_create_class(v, what) }
|
80
|
+
value.map { |v| coerce_or_create_class(v, what) }
|
82
81
|
else
|
83
82
|
coerce_or_create_class(value, what)
|
84
83
|
end
|
@@ -58,7 +58,7 @@ module Contentful
|
|
58
58
|
# - replace links in main resource with included resources
|
59
59
|
# - return main resource
|
60
60
|
def create_all_resources!
|
61
|
-
create_included_resources! response.object[
|
61
|
+
create_included_resources! response.object['includes']
|
62
62
|
res = create_resource(response.object)
|
63
63
|
|
64
64
|
unless @included_resources.empty?
|
@@ -73,7 +73,7 @@ module Contentful
|
|
73
73
|
def create_resource(object)
|
74
74
|
res = detect_resource_class(object).new(object, response.request, client)
|
75
75
|
replace_children res, object
|
76
|
-
|
76
|
+
replace_child_array res.items if res.array?
|
77
77
|
|
78
78
|
res
|
79
79
|
end
|
@@ -123,74 +123,98 @@ module Contentful
|
|
123
123
|
private
|
124
124
|
|
125
125
|
def detect_child_objects(object)
|
126
|
-
if object.is_a?
|
127
|
-
object.select{ |
|
126
|
+
if object.is_a? Hash
|
127
|
+
object.select { |_, v| v.is_a?(Hash) && v.key?('sys') }
|
128
|
+
else
|
129
|
+
{}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def detect_child_arrays(object)
|
134
|
+
if object.is_a? Hash
|
135
|
+
object.select do |_, v|
|
136
|
+
v.is_a?(::Array) &&
|
137
|
+
v.first &&
|
138
|
+
v.first.is_a?(Hash) &&
|
139
|
+
v.first.key?('sys')
|
140
|
+
end
|
128
141
|
else
|
129
142
|
{}
|
130
143
|
end
|
131
144
|
end
|
132
145
|
|
133
146
|
def replace_children(res, object)
|
134
|
-
object.each
|
135
|
-
detect_child_objects(potential_objects).each
|
147
|
+
object.each do |name, potential_objects|
|
148
|
+
detect_child_objects(potential_objects).each do |child_name, child_object|
|
136
149
|
res.public_send(name)[child_name.to_sym] = create_resource(child_object)
|
137
|
-
|
138
|
-
|
150
|
+
end
|
151
|
+
next if name == 'includes'
|
152
|
+
detect_child_arrays(potential_objects).each do |child_name, child_array|
|
153
|
+
replace_child_array res.public_send(name)[child_name.to_sym]
|
154
|
+
end
|
155
|
+
end
|
139
156
|
end
|
140
157
|
|
141
|
-
def
|
142
|
-
|
143
|
-
items.map!{ |resource_object| create_resource(resource_object) }
|
158
|
+
def replace_child_array(child_array)
|
159
|
+
child_array.map! { |resource_object| create_resource(resource_object) }
|
144
160
|
end
|
145
161
|
|
146
162
|
def create_included_resources!(included_objects)
|
147
163
|
if included_objects
|
148
|
-
included_objects.each
|
164
|
+
included_objects.each do |type, objects|
|
149
165
|
@included_resources[type] = Hash[
|
150
|
-
objects.map
|
166
|
+
objects.map do |object|
|
151
167
|
res = create_resource(object)
|
152
168
|
[res.id, res]
|
153
|
-
|
169
|
+
end
|
154
170
|
]
|
155
|
-
|
171
|
+
end
|
156
172
|
end
|
157
173
|
end
|
158
174
|
|
159
175
|
def replace_links_with_included_resources(res)
|
160
|
-
[:properties, :sys, :fields].each
|
161
|
-
if
|
162
|
-
|
163
|
-
|
164
|
-
|
176
|
+
[:properties, :sys, :fields].each do |property_container_name|
|
177
|
+
if property_container = res.public_send(property_container_name)
|
178
|
+
property_container.each do |property_name, property_value|
|
179
|
+
if property_value.is_a? ::Array
|
180
|
+
sub_property_container = property_value
|
181
|
+
sub_property_container.each.with_index do |sub_property_value, sub_property_index|
|
182
|
+
replace_link_or_check_recursively sub_property_value, sub_property_container, sub_property_index
|
183
|
+
end
|
184
|
+
else
|
185
|
+
replace_link_or_check_recursively property_value, property_container, property_name
|
186
|
+
end
|
187
|
+
end
|
165
188
|
end
|
166
|
-
|
189
|
+
end
|
167
190
|
if res.array?
|
168
|
-
res.
|
169
|
-
|
170
|
-
|
191
|
+
property_container = res.items
|
192
|
+
property_container.each.with_index do|child_property, property_index|
|
193
|
+
replace_link_or_check_recursively child_property, property_container, property_index
|
194
|
+
end
|
171
195
|
end
|
172
196
|
end
|
173
197
|
|
174
|
-
def replace_link_or_check_recursively(
|
175
|
-
if
|
176
|
-
maybe_replace_link(
|
177
|
-
elsif
|
178
|
-
replace_links_with_included_resources(
|
198
|
+
def replace_link_or_check_recursively(property_value, property_container, property_name)
|
199
|
+
if property_value.is_a? Link
|
200
|
+
maybe_replace_link(property_value, property_container, property_name)
|
201
|
+
elsif property_value.is_a?(Resource) && property_value.sys
|
202
|
+
replace_links_with_included_resources(property_value)
|
179
203
|
end
|
180
204
|
end
|
181
205
|
|
182
|
-
def
|
183
|
-
@included_resources.
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
}
|
206
|
+
def maybe_replace_link(link, parent, key)
|
207
|
+
if @included_resources[link.link_type] &&
|
208
|
+
@included_resources[link.link_type].key?(link.id)
|
209
|
+
parent[key] = @included_resources[link.link_type][link.id]
|
210
|
+
end
|
188
211
|
end
|
189
212
|
|
190
|
-
def
|
191
|
-
|
192
|
-
|
193
|
-
|
213
|
+
def replace_links_in_included_resources_with_included_resources
|
214
|
+
@included_resources.each do |_, for_type|
|
215
|
+
for_type.each do |_, res|
|
216
|
+
replace_links_with_included_resources(res)
|
217
|
+
end
|
194
218
|
end
|
195
219
|
end
|
196
220
|
end
|