contentful-management 0.0.1.pre → 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.
Files changed (36) hide show
  1. data/CHANGELOG.md +8 -0
  2. data/LICENSE.txt +17 -18
  3. data/README.md +10 -19
  4. data/examples/blog.rb +2 -0
  5. data/examples/create_space.rb +1 -1
  6. data/lib/contentful/management.rb +0 -8
  7. data/lib/contentful/management/asset.rb +41 -38
  8. data/lib/contentful/management/client.rb +8 -1
  9. data/lib/contentful/management/content_type.rb +44 -6
  10. data/lib/contentful/management/entry.rb +61 -29
  11. data/lib/contentful/management/field.rb +1 -1
  12. data/lib/contentful/management/file.rb +1 -0
  13. data/lib/contentful/management/link.rb +1 -1
  14. data/lib/contentful/management/locale.rb +24 -8
  15. data/lib/contentful/management/location.rb +1 -1
  16. data/lib/contentful/management/resource/asset_fields.rb +17 -0
  17. data/lib/contentful/management/resource/entry_fields.rb +13 -0
  18. data/lib/contentful/management/resource/fields.rb +1 -0
  19. data/lib/contentful/management/resource_builder.rb +0 -1
  20. data/lib/contentful/management/space.rb +38 -10
  21. data/lib/contentful/management/support.rb +3 -1
  22. data/lib/contentful/management/version.rb +1 -1
  23. data/spec/fixtures/vcr_cassettes/asset/publish_after_create.yml +268 -0
  24. data/spec/fixtures/vcr_cassettes/content_type/entry/all.yml +777 -0
  25. data/spec/fixtures/vcr_cassettes/entry/content_type_entires.yml +156 -0
  26. data/spec/fixtures/vcr_cassettes/entry/create_with_custom_id.yml +287 -0
  27. data/spec/fixtures/vcr_cassettes/space/{asset/assets.yml → entry/content_type_entires.yml} +369 -367
  28. data/spec/lib/contentful/management/asset_spec.rb +32 -23
  29. data/spec/lib/contentful/management/content_type_spec.rb +31 -6
  30. data/spec/lib/contentful/management/entry_spec.rb +21 -3
  31. data/spec/lib/contentful/management/space_spec.rb +26 -37
  32. metadata +22 -17
  33. data/spec/fixtures/vcr_cassettes/asset/image_url.yml +0 -133
  34. data/spec/fixtures/vcr_cassettes/space/content_type/content_types.yml +0 -341
  35. data/spec/fixtures/vcr_cassettes/space/entry/entries.yml +0 -498
  36. data/spec/fixtures/vcr_cassettes/space/locale/locales.yml +0 -480
@@ -1,29 +1,37 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  require_relative 'resource'
3
+ require_relative 'resource/entry_fields'
3
4
  require_relative 'resource/fields'
4
5
 
5
6
  module Contentful
6
7
  module Management
8
+ # Resource class for Entry.
9
+ # https://www.contentful.com/developers/documentation/content-management-api/#resources-entries
7
10
  class Entry
8
11
 
9
- def self.fields_coercions
10
- {}
11
- end
12
-
13
12
  include Contentful::Management::Resource
14
13
  include Contentful::Management::Resource::SystemProperties
15
14
  include Contentful::Management::Resource::Refresher
15
+ extend Contentful::Management::Resource::EntryFields
16
16
  include Contentful::Management::Resource::Fields
17
17
 
18
18
  attr_accessor :content_type
19
19
 
20
- def self.all(space_id)
21
- request = Request.new("/#{ space_id }/entries")
20
+ # Gets a collection of entries.
21
+ # Takes an id of space and hash of parameters with optional content_type_id.
22
+ # Returns a Contentful::Management::Array of Contentful::Management::Entry.
23
+ def self.all(space_id, parameters = {})
24
+ path = "/#{ space_id }/entries"
25
+ path += "?content_type=#{parameters[:content_type_id]}" if parameters[:content_type_id]
26
+ request = Request.new(path)
22
27
  response = request.get
23
28
  result = ResourceBuilder.new(Contentful::Management::Client.shared_instance, response, {}, {})
24
29
  result.run
25
30
  end
26
31
 
32
+ # Gets a specific entry.
33
+ # Takes an id of space and entry.
34
+ # Returns a Contentful::Management::Entry.
27
35
  def self.find(space_id, entry_id)
28
36
  request = Request.new("/#{ space_id }/entries/#{ entry_id }")
29
37
  response = request.get
@@ -31,40 +39,51 @@ module Contentful
31
39
  result.run
32
40
  end
33
41
 
42
+ # Creates an entry.
43
+ # Takes a content type object and hash with attributes of content type.
44
+ # Returns a Contentful::Management::Entry.
34
45
  def self.create(content_type, attributes)
46
+ custom_id = attributes[:id] || ''
35
47
  fields_for_create = if attributes[:fields] #create from initialized dynamic entry via save
36
- tmp_entry = self.new
48
+ tmp_entry = new
37
49
  tmp_entry.instance_variable_set(:@fields, attributes.delete(:fields) || {})
38
50
  Contentful::Management::Support.deep_hash_merge(tmp_entry.fields_for_query, tmp_entry.fields_from_attributes(attributes))
39
51
  else
40
52
  fields_with_locale content_type, attributes
41
53
  end
42
54
 
43
- request = Request.new("/#{ content_type.sys[:space].id }/entries/#{ attributes[:id] || ''}", { fields: fields_for_create }, nil, content_type_id: content_type.id)
55
+ request = Request.new("/#{ content_type.sys[:space].id }/entries/#{ custom_id }", {fields: fields_for_create}, nil, content_type_id: content_type.id)
44
56
 
45
- response = attributes[:id].nil? ? request.post : request.put
57
+ response = custom_id.empty? ? request.post : request.put
46
58
  result = ResourceBuilder.new(Contentful::Management::Client.shared_instance, response, {}, {})
47
59
  result.run
48
60
  end
49
61
 
62
+ # Updates an entry.
63
+ # Takes an optional hash with attributes of content type.
64
+ # Returns a Contentful::Management::Entry.
50
65
  def update(attributes)
51
66
  fields_for_update = Contentful::Management::Support.deep_hash_merge(fields_for_query, fields_from_attributes(attributes))
52
67
 
53
- request = Request.new("/#{ space.id }/entries/#{ id }", { fields: fields_for_update }, id = nil, version: sys[:version])
68
+ request = Request.new("/#{ space.id }/entries/#{ self.id }", { fields: fields_for_update }, id = nil, version: sys[:version])
54
69
  response = request.put
55
70
  result = ResourceBuilder.new(Contentful::Management::Client.shared_instance, response, {}, {}).run
56
71
  refresh_data(result)
57
72
  end
58
73
 
74
+ # If an entry is a new object gets created in the Contentful, otherwise the existing entry gets updated.
75
+ # See README for details.
59
76
  def save
60
77
  if id.nil?
61
- new_instance = Contentful::Management::Entry.create(content_type, { fields: instance_variable_get(:@fields) })
78
+ new_instance = Contentful::Management::Entry.create(content_type, {fields: instance_variable_get(:@fields)})
62
79
  refresh_data(new_instance)
63
80
  else
64
81
  update({})
65
82
  end
66
83
  end
67
84
 
85
+ # Publishes an entry.
86
+ # Returns a Contentful::Management::Entry.
68
87
  def publish
69
88
  request = Request.new("/#{ space.id }/entries/#{ id }/published", {}, id = nil, version: sys[:version])
70
89
  response = request.put
@@ -72,6 +91,8 @@ module Contentful
72
91
  refresh_data(result)
73
92
  end
74
93
 
94
+ # Unpublishes an entry.
95
+ # Returns a Contentful::Management::Entry.
75
96
  def unpublish
76
97
  request = Request.new("/#{ space.id }/entries/#{ id }/published", {}, id = nil, version: sys[:version])
77
98
  response = request.delete
@@ -79,6 +100,8 @@ module Contentful
79
100
  refresh_data(result)
80
101
  end
81
102
 
103
+ # Archives an entry.
104
+ # Returns a Contentful::Management::Entry.
82
105
  def archive
83
106
  request = Request.new("/#{ space.id }/entries/#{ id }/archived", {}, id = nil, version: sys[:version])
84
107
  response = request.put
@@ -86,6 +109,8 @@ module Contentful
86
109
  refresh_data(result)
87
110
  end
88
111
 
112
+ # Unarchives an entry.
113
+ # Returns a Contentful::Management::Entry.
89
114
  def unarchive
90
115
  request = Request.new("/#{ space.id }/entries/#{ id }/archived", {}, id = nil, version: sys[:version])
91
116
  response = request.delete
@@ -93,6 +118,8 @@ module Contentful
93
118
  refresh_data(result)
94
119
  end
95
120
 
121
+ # Destroys an entry.
122
+ # Returns true if succeed.
96
123
  def destroy
97
124
  request = Request.new("/#{ space.id }/entries/#{ id }")
98
125
  response = request.delete
@@ -104,18 +131,25 @@ module Contentful
104
131
  end
105
132
  end
106
133
 
134
+ # Checks if an entry is published.
135
+ # Returns true if published.
107
136
  def published?
108
137
  !sys[:publishedAt].nil?
109
138
  end
110
139
 
140
+ # Checks if an entry is archived.
141
+ # Returns true if published.
111
142
  def archived?
112
143
  !sys[:archivedAt].nil?
113
144
  end
114
145
 
146
+ # Returns the currently supported local.
115
147
  def locale
116
148
  sys[:locale] || default_locale
117
149
  end
118
150
 
151
+ # Parser for assets attributes from query.
152
+ # Returns a hash of existing fields.
119
153
  def fields_for_query
120
154
  raw_fields = self.instance_variable_get(:@fields)
121
155
  fields_names = raw_fields.first[1].keys
@@ -129,7 +163,7 @@ module Contentful
129
163
 
130
164
  def fields_from_attributes(attributes)
131
165
  attributes.each do |id, value|
132
- attributes[id] = { locale => parse_update_attribute(value) }
166
+ attributes[id] = {locale => parse_update_attribute(value)}
133
167
  end
134
168
  end
135
169
 
@@ -138,24 +172,24 @@ module Contentful
138
172
  def self.parse_attribute_with_field(attribute, field)
139
173
  case field.type
140
174
  when ContentType::LINK then
141
- { sys: { type: field.type, linkType: field.link_type, id: attribute.id }}
175
+ { sys: { type: field.type, linkType: field.link_type, id: attribute.id } } if attribute
142
176
  when ContentType::ARRAY then
143
177
  parse_fields_array(attribute)
144
178
  when ContentType::LOCATION then
145
- { lat: attribute.properties[:lat], lon: attribute.properties[:lon]}
179
+ { lat: attribute.properties[:lat], lon: attribute.properties[:lon] }
146
180
  else
147
181
  attribute
148
182
  end
149
183
  end
150
184
 
151
- #TODO refactor
185
+ # TODO refactor
152
186
  def parse_update_attribute(attribute)
153
187
  if attribute.is_a? Asset
154
- { sys: { type: 'Link', linkType: 'Asset', id: attribute.id } }
188
+ {sys: {type: 'Link', linkType: 'Asset', id: attribute.id}}
155
189
  elsif attribute.is_a? Entry
156
- { sys: { type: 'Link', linkType: 'Entry', id: attribute.id } }
190
+ {sys: {type: 'Link', linkType: 'Entry', id: attribute.id}}
157
191
  elsif attribute.is_a? Location
158
- { lat: attribute.properties[:lat], lon: attribute.properties[:lon] }
192
+ {lat: attribute.properties[:lat], lon: attribute.properties[:lon]}
159
193
  elsif attribute.is_a? ::Array
160
194
  parse_update_fields_array(attribute)
161
195
  else
@@ -163,20 +197,19 @@ module Contentful
163
197
  end
164
198
  end
165
199
 
166
- #TODO refactor
167
200
  def parse_update_fields_array(attributes)
168
201
  type = attributes.first.class.to_s
169
- unless type == 'String'
170
- attributes.each_with_object([]) do |attr, arr|
202
+ if type == 'String'
203
+ attributes
204
+ else
205
+ attributes.each_with_object([]) do |attr, arr|
171
206
  arr << case type
172
207
  when /Entry/ then
173
- { sys: { type: 'Link', linkType: 'Entry', id: attr.id } }
208
+ {sys: {type: 'Link', linkType: 'Entry', id: attr.id}}
174
209
  when /Asset/ then
175
- { sys: { type: 'Link', linkType: 'Asset', id: attr.id } }
210
+ {sys: {type: 'Link', linkType: 'Asset', id: attr.id}}
176
211
  end
177
212
  end
178
- else
179
- attributes
180
213
  end
181
214
  end
182
215
 
@@ -186,9 +219,9 @@ module Contentful
186
219
  attributes.each_with_object([]) do |attr, arr|
187
220
  arr << case type.to_s
188
221
  when /Entry/ then
189
- { sys: { type: 'Link', linkType: 'Entry', id: attr.id } }
222
+ {sys: {type: 'Link', linkType: 'Entry', id: attr.id}}
190
223
  when /Asset/ then
191
- { sys: { type: 'Link', linkType: 'Asset', id: attr.id } }
224
+ {sys: {type: 'Link', linkType: 'Asset', id: attr.id}}
192
225
  end
193
226
  end
194
227
  else
@@ -204,10 +237,9 @@ module Contentful
204
237
 
205
238
  attributes.each do |id, value|
206
239
  field = fields.select { |f| f.id.to_sym == id.to_sym }.first
207
- attributes[id] = { locale => parse_attribute_with_field(value, field) }
240
+ attributes[id] = {locale => parse_attribute_with_field(value, field)}
208
241
  end
209
242
  end
210
-
211
243
  end
212
244
  end
213
245
  end
@@ -3,6 +3,7 @@ require_relative 'resource'
3
3
 
4
4
  module Contentful
5
5
  module Management
6
+ # A ContentType's field schema
6
7
  class Field
7
8
  include Contentful::Management::Resource
8
9
 
@@ -28,7 +29,6 @@ module Contentful
28
29
  end
29
30
  end
30
31
  end
31
-
32
32
  end
33
33
  end
34
34
  end
@@ -3,6 +3,7 @@ require_relative 'resource'
3
3
 
4
4
  module Contentful
5
5
  module Management
6
+ # An Asset's file schema
6
7
  class File
7
8
  include Contentful::Management::Resource
8
9
 
@@ -9,7 +9,7 @@ module Contentful
9
9
  include Contentful::Management::Resource
10
10
  include Contentful::Management::Resource::SystemProperties
11
11
 
12
- # Queries contentful for the Resource the Link is refering to
12
+ # Queries contentful for the Resource the Link is referring to
13
13
  # Takes an optional query hash
14
14
  def resolve(query = {})
15
15
  id_and_query = [(id unless link_type == 'Space')].compact + [query]
@@ -2,9 +2,8 @@
2
2
  require_relative 'resource'
3
3
 
4
4
  module Contentful
5
-
6
5
  module Management
7
-
6
+ # Resource class for Locale.
8
7
  class Locale
9
8
  include Contentful::Management::Resource
10
9
  include Contentful::Management::Resource::SystemProperties
@@ -16,6 +15,9 @@ module Contentful
16
15
  property :contentDeliveryApi, :boolean
17
16
  property :publish, :boolean
18
17
 
18
+ # Gets a collection of locales.
19
+ # Takes an id of a space.
20
+ # Returns a Contentful::Management::Array of Contentful::Management::Locale.
19
21
  def self.all(space_id = nil)
20
22
  request = Request.new("/#{ space_id }/locales")
21
23
  response = request.get
@@ -23,20 +25,34 @@ module Contentful
23
25
  result.run
24
26
  end
25
27
 
26
- def self.create(space_id, attributes)
27
- request = Request.new("/#{ space_id }/locales", { 'name' => attributes.fetch(:name), 'code' => attributes.fetch(:code) })
28
- response = request.post
28
+ # Gets a specific locale.
29
+ # Takes an id of a space and locale id.
30
+ # Returns a Contentful::Management::Locale.
31
+ def self.find(space_id, locale_id)
32
+ request = Request.new("/#{ space_id }/locales/#{ locale_id }")
33
+ response = request.get
29
34
  result = ResourceBuilder.new(self, response, { 'Locale' => Locale }, {})
30
35
  result.run
31
36
  end
32
37
 
33
- def self.find(space_id, locale_id)
34
- request = Request.new("/#{ space_id }/locales/#{ locale_id }")
35
- response = request.get
38
+ # Creates a locale.
39
+ # Takes a space id and hash with attributes:
40
+ # :name
41
+ # :code
42
+ # :contentManagementApi
43
+ # :contentDeliveryApi
44
+ # :publish
45
+ # Returns a Contentful::Management::Locale.
46
+ def self.create(space_id, attributes)
47
+ request = Request.new("/#{ space_id }/locales", { 'name' => attributes.fetch(:name), 'code' => attributes.fetch(:code) })
48
+ response = request.post
36
49
  result = ResourceBuilder.new(self, response, { 'Locale' => Locale }, {})
37
50
  result.run
38
51
  end
39
52
 
53
+ # Updates a locale.
54
+ # Takes a hash with attributes.
55
+ # Returns a Contentful::Management::Locale.
40
56
  def update(attributes)
41
57
  request = Request.new("/#{ space.id }/locales/#{ id }", { 'name' => attributes.fetch(:name) }, id = nil, version: sys[:version])
42
58
  response = request.put
@@ -4,7 +4,7 @@ require_relative 'resource'
4
4
  module Contentful
5
5
  module Management
6
6
  # Location Field Type
7
- # You can directly query for them: https://www.contentful.com/developers/documentation/content-delivery-api/#search-filter-geo
7
+ # You can directly query for them: https://www.contentful.com/developers/documentation/content-management-api/#search-filter-geo
8
8
  class Location
9
9
  include Contentful::Management::Resource
10
10
 
@@ -0,0 +1,17 @@
1
+ module Contentful
2
+ module Management
3
+ module Resource
4
+ module AssetFields
5
+
6
+ def fields_coercions
7
+ {
8
+ title: :hash,
9
+ description: :hash,
10
+ file: Contentful::Management::File
11
+ }
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Contentful
2
+ module Management
3
+ module Resource
4
+ module EntryFields
5
+
6
+ def fields_coercions
7
+ {}
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -26,6 +26,7 @@ module Contentful
26
26
  end
27
27
  end
28
28
 
29
+ # Create accessors for content type, asset, entry objects.
29
30
  def self.included(base)
30
31
  base.fields_coercions.keys.each { |name|
31
32
  accessor_name = Contentful::Management::Support.snakify(name)
@@ -26,7 +26,6 @@ module Contentful
26
26
 
27
27
  attr_reader :client, :response, :resource_mapping, :entry_mapping, :resource
28
28
 
29
-
30
29
  def initialize(client, response, resource_mapping = {}, entry_mapping = {})
31
30
  @response = response
32
31
  @client = client
@@ -7,6 +7,8 @@ require_relative 'entry'
7
7
 
8
8
  module Contentful
9
9
  module Management
10
+ # Resource class for Space.
11
+ # https://www.contentful.com/developers/documentation/content-management-api/#resources-spaces
10
12
  class Space
11
13
  include Contentful::Management::Resource
12
14
  include Contentful::Management::Resource::SystemProperties
@@ -16,6 +18,8 @@ module Contentful
16
18
  property :organization, :string
17
19
  property :locales, Locale
18
20
 
21
+ # Gets a collection of spaces.
22
+ # Returns a Contentful::Management::Array of Contentful::Management::Space.
19
23
  def self.all
20
24
  request = Request.new('')
21
25
  response = request.get
@@ -25,29 +29,40 @@ module Contentful
25
29
  spaces
26
30
  end
27
31
 
32
+ # Gets a specific space.
33
+ # Takes an id of space.
34
+ # Returns a Contentful::Management::Space.
28
35
  def self.find(space_id)
29
36
  request = Request.new("/#{ space_id }")
30
37
  response = request.get
31
38
  result = ResourceBuilder.new(self, response, {}, {})
32
39
  space = result.run
33
- Contentful::Management::Client.shared_instance.update_dynamic_entry_cache_for_space!(space) if space.is_a?Space
40
+ Contentful::Management::Client.shared_instance.update_dynamic_entry_cache_for_space!(space) if space.is_a? Space
34
41
  space
35
42
  end
36
43
 
44
+ # Create a space.
45
+ # Takes a hash of attributes with optional organization id if client has more than one organization.
46
+ # Returns a Contentful::Management::Space.
37
47
  def self.create(attributes)
38
- request = Request.new('', { 'name' => attributes.fetch(:name) }, id = nil, organization_id: attributes[:organization_id])
48
+ request = Request.new('', {'name' => attributes.fetch(:name)}, id = nil, organization_id: attributes[:organization_id])
39
49
  response = request.post
40
50
  result = ResourceBuilder.new(self, response, {}, {})
41
51
  result.run
42
52
  end
43
53
 
54
+ # Updates a space.
55
+ # Takes a hash of attributes with optional organization id if client has more than one organization.
56
+ # Returns a Contentful::Management::Space.
44
57
  def update(attributes)
45
- request = Request.new("/#{ id }", { 'name' => attributes.fetch(:name) }, id = nil,{ version: sys[:version], organization_id: attributes[:organization_id]})
58
+ request = Request.new("/#{ id }", { 'name' => attributes.fetch(:name) }, id = nil, version: sys[:version], organization_id: attributes[:organization_id])
46
59
  response = request.put
47
60
  result = ResourceBuilder.new(self, response, {}, {})
48
61
  refresh_data(result.run)
49
62
  end
50
63
 
64
+ # If a space is new, an object gets created in the Contentful, otherwise the existing space gets updated.
65
+ # See README for details.
51
66
  def save
52
67
  if id.nil?
53
68
  new_instance = self.class.create(name: name, organization_id: organization)
@@ -57,6 +72,8 @@ module Contentful
57
72
  end
58
73
  end
59
74
 
75
+ # Destroys a space.
76
+ # Returns true if succeed.
60
77
  def destroy
61
78
  request = Request.new("/#{ id }")
62
79
  response = request.delete
@@ -67,8 +84,11 @@ module Contentful
67
84
  end
68
85
  end
69
86
 
87
+ # Allows manipulation of content types in context of the current space
88
+ # Allows listing all content types of space, creating new and finding one by id.
89
+ # See README for details.
70
90
  def content_types
71
- content_types = ContentType.all(id)
91
+ content_types = nil
72
92
 
73
93
  content_types.instance_exec(self) do |space|
74
94
 
@@ -94,8 +114,11 @@ module Contentful
94
114
  content_types
95
115
  end
96
116
 
117
+ # Allows manipulation of locales in context of the current space
118
+ # Allows listing all locales of space, creating new and finding one by id.
119
+ # See README for details.
97
120
  def locales
98
- locales = Locale.all(id)
121
+ locales = nil
99
122
 
100
123
  locales.instance_exec(self) do |space|
101
124
  define_singleton_method(:all) do
@@ -114,8 +137,11 @@ module Contentful
114
137
  locales
115
138
  end
116
139
 
140
+ # Allows manipulation of assets in context of the current space
141
+ # Allows listing all assets of space, creating new and finding one by id.
142
+ # See README for details.
117
143
  def assets
118
- assets = Asset.all(id)
144
+ assets = nil
119
145
 
120
146
  assets.instance_exec(self) do |space|
121
147
  define_singleton_method(:all) do
@@ -139,12 +165,15 @@ module Contentful
139
165
  assets
140
166
  end
141
167
 
168
+ # Allows manipulation of entries in context of the current space
169
+ # Allows listing all entries of space and finding one by id.
170
+ # See README for details.
142
171
  def entries
143
- entries = Entry.all(id)
172
+ entries = nil
144
173
 
145
174
  entries.instance_exec(self) do |space|
146
- define_singleton_method(:all) do
147
- Entry.all(space.id)
175
+ define_singleton_method(:all) do |attributes = {}|
176
+ Entry.all(space.id, attributes)
148
177
  end
149
178
 
150
179
  define_singleton_method(:find) do |entry_id|
@@ -153,7 +182,6 @@ module Contentful
153
182
  end
154
183
  entries
155
184
  end
156
-
157
185
  end
158
186
  end
159
187
  end