contentful 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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