contentful-management 0.0.1.pre → 0.0.1

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