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.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/ChangeLog.md +6 -0
  4. data/Gemfile +5 -0
  5. data/README.md +1 -0
  6. data/contentful.gemspec +1 -1
  7. data/lib/contentful/array.rb +1 -2
  8. data/lib/contentful/asset.rb +3 -3
  9. data/lib/contentful/client.rb +15 -18
  10. data/lib/contentful/content_type.rb +1 -1
  11. data/lib/contentful/dynamic_entry.rb +6 -6
  12. data/lib/contentful/entry.rb +1 -1
  13. data/lib/contentful/error.rb +3 -3
  14. data/lib/contentful/field.rb +1 -1
  15. data/lib/contentful/file.rb +1 -1
  16. data/lib/contentful/link.rb +2 -2
  17. data/lib/contentful/locale.rb +1 -1
  18. data/lib/contentful/location.rb +1 -1
  19. data/lib/contentful/resource.rb +10 -11
  20. data/lib/contentful/resource_builder.rb +63 -39
  21. data/lib/contentful/space.rb +1 -1
  22. data/lib/contentful/support.rb +5 -3
  23. data/lib/contentful/version.rb +1 -1
  24. data/spec/fixtures/json_responses/includes.json +111 -0
  25. data/spec/fixtures/json_responses/link_array.json +43 -0
  26. data/spec/resource_building_spec.rb +20 -0
  27. data/spec/spec_helper.rb +5 -1
  28. metadata +138 -192
  29. data/.README.md.swp +0 -0
  30. data/do_request.sh +0 -5
  31. data/doc/Contentful.html +0 -131
  32. data/doc/Contentful/AccessDenied.html +0 -158
  33. data/doc/Contentful/Array.html +0 -346
  34. data/doc/Contentful/Asset.html +0 -315
  35. data/doc/Contentful/BadRequest.html +0 -158
  36. data/doc/Contentful/Client.html +0 -1407
  37. data/doc/Contentful/ContentType.html +0 -183
  38. data/doc/Contentful/DynamicEntry.html +0 -333
  39. data/doc/Contentful/Entry.html +0 -198
  40. data/doc/Contentful/Error.html +0 -413
  41. data/doc/Contentful/Field.html +0 -161
  42. data/doc/Contentful/File.html +0 -160
  43. data/doc/Contentful/Link.html +0 -275
  44. data/doc/Contentful/Locale.html +0 -161
  45. data/doc/Contentful/NotFound.html +0 -158
  46. data/doc/Contentful/Request.html +0 -669
  47. data/doc/Contentful/Resource.html +0 -606
  48. data/doc/Contentful/Resource/AssetFields.html +0 -413
  49. data/doc/Contentful/Resource/AssetFields/ClassMethods.html +0 -174
  50. data/doc/Contentful/Resource/ClassMethods.html +0 -271
  51. data/doc/Contentful/Resource/Fields.html +0 -398
  52. data/doc/Contentful/Resource/Fields/ClassMethods.html +0 -187
  53. data/doc/Contentful/Resource/SystemProperties.html +0 -444
  54. data/doc/Contentful/Resource/SystemProperties/ClassMethods.html +0 -174
  55. data/doc/Contentful/ResourceBuilder.html +0 -1400
  56. data/doc/Contentful/Response.html +0 -546
  57. data/doc/Contentful/ServerError.html +0 -158
  58. data/doc/Contentful/Space.html +0 -183
  59. data/doc/Contentful/Support.html +0 -198
  60. data/doc/Contentful/Unauthorized.html +0 -158
  61. data/doc/Contentful/UnparsableJson.html +0 -158
  62. data/doc/Contentful/UnparsableResource.html +0 -158
  63. data/doc/_index.html +0 -410
  64. data/doc/class_list.html +0 -54
  65. data/doc/css/common.css +0 -1
  66. data/doc/css/full_list.css +0 -57
  67. data/doc/css/style.css +0 -338
  68. data/doc/file.README.html +0 -214
  69. data/doc/file_list.html +0 -56
  70. data/doc/frames.html +0 -26
  71. data/doc/index.html +0 -214
  72. data/doc/js/app.js +0 -219
  73. data/doc/js/full_list.js +0 -178
  74. data/doc/js/jquery.js +0 -4
  75. data/doc/method_list.html +0 -533
  76. 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
@@ -1,2 +1,3 @@
1
1
  pkg
2
+ coverage
2
3
  Gemfile.lock
data/ChangeLog.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 0.1.1
2
+
3
+ * Fix a bug that prevented fields with multiple resources to be parsed correctly
4
+ * Restrict HTTP gem dependency to < 0.6
5
+
6
+
1
7
  ### 0.1.0
2
8
 
3
9
  * Initial release.
data/Gemfile CHANGED
@@ -1,3 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+
6
+ group :documentation do
7
+ gem 'coveralls', :require => false
8
+ end
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'
@@ -42,6 +42,5 @@ module Contentful
42
42
  def empty?
43
43
  items.empty?
44
44
  end
45
-
46
45
  end
47
- end
46
+ end
@@ -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}?#{ URI.encode_www_form(query) }"
30
+ "#{file.url}?#{URI.encode_www_form(query)}"
31
31
  end
32
32
  end
33
33
  end
@@ -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 = { "User-Agent" => "RubyContentfulGem/#{Contentful::VERSION}" }
105
- headers["Authorization"] = "Bearer #{configuration[:access_token]}" if configuration[:authentication_mechanism] == :header
106
- headers["Content-Type"] = "application/vnd.contentful.delivery.v#{configuration[:api_version].to_i}+json" if configuration[:api_version]
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{ |ct|
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, "You will need to initialize a client with a :space"
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, "You will need to initialize a client with an :access_token"
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, "The client configuration needs to contain an :api_url"
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, "The :api_version must be a positive number or nil"
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, "The authentication mechanism must be :header or :query_string"
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, "The :dynamic_entries mode must be :auto or :manual"
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
-
@@ -13,4 +13,4 @@ module Contentful
13
13
  property :fields, Field
14
14
  property :displayField, :string
15
15
  end
16
- end
16
+ end
@@ -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{ |field|
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{ |f|
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
@@ -9,4 +9,4 @@ module Contentful
9
9
  include Contentful::Resource::SystemProperties
10
10
  include Contentful::Resource::Fields
11
11
  end
12
- end
12
+ end
@@ -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.[](no)
15
- case no
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
@@ -13,4 +13,4 @@ module Contentful
13
13
  property :required, :boolean
14
14
  property :localized, :boolean
15
15
  end
16
- end
16
+ end
@@ -10,4 +10,4 @@ module Contentful
10
10
  property :details
11
11
  property :url, :string
12
12
  end
13
- end
13
+ end
@@ -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 == "Space")].compact + [query]
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
@@ -9,4 +9,4 @@ module Contentful
9
9
  property :code, :string
10
10
  property :name, :string
11
11
  end
12
- end
12
+ end
@@ -9,4 +9,4 @@ module Contentful
9
9
  property :lat, :float
10
10
  property :lon, :float
11
11
  end
12
- end
12
+ end
@@ -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? ? "" : " @properties=#{properties.inspect}"
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({}){ |name, res|
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["includes"]
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
- replace_children_array(res, :items) if res.array?
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?(Hash)
127
- object.select{ |k,v| v.is_a?(Hash) && v.has_key?("sys") }
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{ |name, potential_objects|
135
- detect_child_objects(potential_objects).each{ |child_name, child_object|
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 replace_children_array(res, array_field)
142
- items = res.public_send(array_field)
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{ |type, objects|
164
+ included_objects.each do |type, objects|
149
165
  @included_resources[type] = Hash[
150
- objects.map{ |object|
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{ |_what|
161
- if what = res.public_send(_what)
162
- what.each{ |name, child_res|
163
- replace_link_or_check_recursively child_res, what, name, res
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.each.with_index{ |child_res, index|
169
- replace_link_or_check_recursively child_res, res.items, index, child_res
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(res, what, name, resource_to_replace)
175
- if res.is_a? Link
176
- maybe_replace_link(res, what, name)
177
- elsif res.is_a?(Resource) && res.sys
178
- replace_links_with_included_resources(resource_to_replace)
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 replace_links_in_included_resources_with_included_resources
183
- @included_resources.each{ |_, for_type|
184
- for_type.each{ |_, res|
185
- replace_links_with_included_resources(res)
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 maybe_replace_link(resource, parent, index)
191
- if @included_resources[resource.link_type] &&
192
- @included_resources[resource.link_type].has_key?(resource.id)
193
- parent[index] = @included_resources[resource.link_type][resource.id]
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