contentful 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/contentful.png)](http://badge.fury.io/rb/contentful) [![Build Status](https://travis-ci.org/contentful/contentful.rb.png)](https://travis-ci.org/contentful/contentful.rb) [![Coverage Status](https://coveralls.io/repos/contentful/contentful.rb/badge.png?branch=master)](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
|