contentful-management 0.2.1 → 0.3.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +37 -8
- data/Gemfile +0 -1
- data/README.md +130 -0
- data/Rakefile +0 -1
- data/contentful-management.gemspec +0 -1
- data/examples/blog.rb +1 -1
- data/lib/contentful/management.rb +0 -1
- data/lib/contentful/management/array.rb +0 -1
- data/lib/contentful/management/asset.rb +65 -26
- data/lib/contentful/management/client.rb +19 -9
- data/lib/contentful/management/content_type.rb +43 -28
- data/lib/contentful/management/dynamic_entry.rb +15 -15
- data/lib/contentful/management/entry.rb +73 -40
- data/lib/contentful/management/error.rb +6 -1
- data/lib/contentful/management/field.rb +63 -8
- data/lib/contentful/management/file.rb +0 -1
- data/lib/contentful/management/http_client.rb +0 -1
- data/lib/contentful/management/link.rb +0 -1
- data/lib/contentful/management/locale.rb +11 -3
- data/lib/contentful/management/location.rb +0 -1
- data/lib/contentful/management/request.rb +5 -7
- data/lib/contentful/management/resource.rb +3 -3
- data/lib/contentful/management/resource/array_like.rb +0 -1
- data/lib/contentful/management/resource/fields.rb +1 -2
- data/lib/contentful/management/resource/refresher.rb +3 -3
- data/lib/contentful/management/resource/system_properties.rb +0 -1
- data/lib/contentful/management/resource_builder.rb +16 -27
- data/lib/contentful/management/response.rb +36 -32
- data/lib/contentful/management/space.rb +16 -6
- data/lib/contentful/management/space_webhook_methods_factory.rb +0 -4
- data/lib/contentful/management/support.rb +0 -1
- data/lib/contentful/management/validation.rb +34 -0
- data/lib/contentful/management/version.rb +1 -2
- data/lib/contentful/management/webhook.rb +17 -10
- data/spec/fixtures/vcr_cassettes/content_type/validation/in.yml +588 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/in_add.yml +620 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/in_update.yml +668 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/link_content_type.yml +749 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/link_field.yml +770 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/link_mimetype_group.yml +766 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/multiple_add.yml +854 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/present.yml +808 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/range.yml +683 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/range_update.yml +697 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/regexp.yml +720 -0
- data/spec/fixtures/vcr_cassettes/content_type/validation/size.yml +791 -0
- data/spec/fixtures/vcr_cassettes/entry/service_unavailable.yml +52 -0
- data/spec/fixtures/vcr_cassettes/space/webhook/create.yml +439 -0
- data/spec/lib/contentful/management/asset_spec.rb +16 -16
- data/spec/lib/contentful/management/client_spec.rb +0 -1
- data/spec/lib/contentful/management/content_type_spec.rb +143 -1
- data/spec/lib/contentful/management/entry_spec.rb +10 -4
- data/spec/lib/contentful/management/locale_spec.rb +0 -1
- data/spec/lib/contentful/management/space_spec.rb +9 -1
- data/spec/lib/contentful/management/webhook_spec.rb +0 -1
- data/spec/spec_helper.rb +0 -1
- data/spec/support/vcr.rb +0 -1
- metadata +63 -62
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
module Contentful
|
3
2
|
module Management
|
4
3
|
# All errors raised by the contentful gem are either instances of Contentful::Error
|
@@ -25,6 +24,8 @@ module Contentful
|
|
25
24
|
Unauthorized
|
26
25
|
when 500
|
27
26
|
ServerError
|
27
|
+
when 503
|
28
|
+
ServiceUnavailable
|
28
29
|
else
|
29
30
|
Error
|
30
31
|
end
|
@@ -51,6 +52,10 @@ module Contentful
|
|
51
52
|
class ServerError < Error
|
52
53
|
end
|
53
54
|
|
55
|
+
# 503
|
56
|
+
class ServiceUnavailable < Error
|
57
|
+
end
|
58
|
+
|
54
59
|
# Raised when response is no valid json
|
55
60
|
class UnparsableJson < Error
|
56
61
|
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
require_relative 'resource'
|
3
|
-
|
2
|
+
require_relative 'validation'
|
4
3
|
module Contentful
|
5
4
|
module Management
|
6
5
|
# A ContentType's field schema
|
@@ -14,21 +13,77 @@ module Contentful
|
|
14
13
|
property :items, Field
|
15
14
|
property :required, :boolean
|
16
15
|
property :localized, :boolean
|
16
|
+
property :validations, Validation
|
17
17
|
|
18
|
+
# Takes a field object of content type
|
19
|
+
# Merges existing properties, items and validations of field with new one
|
18
20
|
def deep_merge!(field)
|
19
|
-
|
20
|
-
|
21
|
+
merge_properties(field.properties)
|
22
|
+
merge_items(field.items)
|
23
|
+
merge_validations(field.validations)
|
21
24
|
end
|
22
25
|
|
26
|
+
# Extract values of field to hash
|
23
27
|
def properties_to_hash
|
24
28
|
properties.each_with_object({}) do |(key, value), results|
|
25
|
-
|
26
|
-
|
29
|
+
results[key] = parse_value(key, value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return parsed value of field object
|
34
|
+
def parse_value(key, value)
|
35
|
+
case key
|
36
|
+
when :items
|
37
|
+
value.properties_to_hash if type == 'Array' && type.is_a?(Field)
|
38
|
+
when :validations
|
39
|
+
validations_to_hash(value) if value.is_a?(::Array)
|
27
40
|
else
|
28
|
-
|
29
|
-
|
41
|
+
value if self.class.value_exists?(value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.value_exists?(value)
|
46
|
+
value.respond_to?(:empty?) && !value.empty? || !value.respond_to?(:empty?) && value
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Update properties of field object
|
52
|
+
def merge_properties(new_properties)
|
53
|
+
properties.merge!(new_properties.select { |name, _type| name != :items && name != :validations })
|
54
|
+
end
|
55
|
+
|
56
|
+
# Update items of field object
|
57
|
+
def merge_items(new_items)
|
58
|
+
items.properties.merge!(new_items.properties) if items.respond_to?(:properties) && new_items.respond_to?(:properties)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Takes an array with new validations
|
62
|
+
# Returns merged existing and new validations
|
63
|
+
def merge_validations(new_validations)
|
64
|
+
if new_validations
|
65
|
+
validations_by_type = validations_by_type(validations)
|
66
|
+
new_validations_by_type = validations_by_type(new_validations)
|
67
|
+
validations_by_type.delete_if { |type, _v| new_validations_by_type[type] }
|
68
|
+
self.validations = validations_by_type.values + new_validations_by_type.values
|
30
69
|
end
|
31
70
|
end
|
71
|
+
|
72
|
+
def validations_by_type(validations)
|
73
|
+
validations.is_a?(::Array) ? index_by_type(validations) : {}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Build hash with validations
|
77
|
+
def index_by_type(validations)
|
78
|
+
validations.each_with_object({}) { |validation, results| results[validation.type] = validation }
|
79
|
+
end
|
80
|
+
|
81
|
+
def validations_to_hash(validations)
|
82
|
+
validations.each_with_object([]) do |validation, results|
|
83
|
+
results << validation.properties_to_hash
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
32
87
|
end
|
33
88
|
end
|
34
89
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
require_relative 'resource'
|
3
2
|
|
4
3
|
module Contentful
|
@@ -44,7 +43,11 @@ module Contentful
|
|
44
43
|
# :publish
|
45
44
|
# Returns a Contentful::Management::Locale.
|
46
45
|
def self.create(space_id, attributes)
|
47
|
-
request = Request.new(
|
46
|
+
request = Request.new(
|
47
|
+
"/#{ space_id }/locales",
|
48
|
+
'name' => attributes.fetch(:name),
|
49
|
+
'code' => attributes.fetch(:code)
|
50
|
+
)
|
48
51
|
response = request.post
|
49
52
|
result = ResourceBuilder.new(response, {'Locale' => Locale}, {})
|
50
53
|
result.run
|
@@ -54,7 +57,12 @@ module Contentful
|
|
54
57
|
# Takes a hash with attributes.
|
55
58
|
# Returns a Contentful::Management::Locale.
|
56
59
|
def update(attributes)
|
57
|
-
request = Request.new(
|
60
|
+
request = Request.new(
|
61
|
+
"/#{ space.id }/locales/#{ id }",
|
62
|
+
{'name' => attributes.fetch(:name)},
|
63
|
+
id = nil,
|
64
|
+
version: sys[:version]
|
65
|
+
)
|
58
66
|
response = request.put
|
59
67
|
result = ResourceBuilder.new(response, {'Locale' => Locale}, {})
|
60
68
|
refresh_data(result.run)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
module Contentful
|
3
2
|
module Management
|
4
3
|
# This object represents a request that is to be made. It gets initialized by the client
|
@@ -11,9 +10,9 @@ module Contentful
|
|
11
10
|
@header = header
|
12
11
|
@initial_id = id
|
13
12
|
@client = Contentful::Management::Client.shared_instance
|
14
|
-
@client.version = header[:version]
|
15
|
-
@client.organization_id = header[:organization_id]
|
16
|
-
@client.content_type_id = header[:content_type_id]
|
13
|
+
@client.version = header[:version]
|
14
|
+
@client.organization_id = header[:organization_id]
|
15
|
+
@client.content_type_id = header[:content_type_id]
|
17
16
|
@client.zero_length = query.empty?
|
18
17
|
@endpoint = endpoint
|
19
18
|
@absolute = true if @endpoint.start_with?('http')
|
@@ -71,9 +70,8 @@ module Contentful
|
|
71
70
|
Hash[
|
72
71
|
query.map do |key, value|
|
73
72
|
[
|
74
|
-
|
75
|
-
|
76
|
-
# value.is_a?(::Array) ? value.join(',') : value
|
73
|
+
key.to_sym,
|
74
|
+
value
|
77
75
|
]
|
78
76
|
end
|
79
77
|
]
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
require_relative 'resource/system_properties'
|
3
2
|
require_relative 'resource/refresher'
|
4
3
|
require 'date'
|
@@ -22,7 +21,7 @@ module Contentful
|
|
22
21
|
date: ->(value) { !value.nil? ? DateTime.parse(value) : nil }
|
23
22
|
}
|
24
23
|
|
25
|
-
attr_reader :properties, :request, :client, :default_locale
|
24
|
+
attr_reader :properties, :request, :client, :default_locale, :raw_object
|
26
25
|
|
27
26
|
def initialize(object = nil, request = nil, client = nil, nested_locale_fields = false, default_locale = Contentful::Management::Client::DEFAULT_CONFIGURATION[:default_locale])
|
28
27
|
self.class.update_coercions!
|
@@ -32,6 +31,7 @@ module Contentful
|
|
32
31
|
@properties = extract_from_object object, :property, self.class.property_coercions.keys
|
33
32
|
@request = request
|
34
33
|
@client = client
|
34
|
+
@raw_object = object
|
35
35
|
end
|
36
36
|
|
37
37
|
def inspect(info = nil)
|
@@ -82,7 +82,7 @@ module Contentful
|
|
82
82
|
|
83
83
|
def coerce_value_or_array(value, what = nil)
|
84
84
|
if value.is_a? ::Array
|
85
|
-
value.map { |
|
85
|
+
value.map { |row| coerce_or_create_class(row, what) }
|
86
86
|
else
|
87
87
|
coerce_or_create_class(value, what)
|
88
88
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
require_relative '../file'
|
3
2
|
|
4
3
|
module Contentful
|
@@ -40,7 +39,7 @@ module Contentful
|
|
40
39
|
end
|
41
40
|
base.send :define_method, "#{ accessor_name }_with_locales=" do |values|
|
42
41
|
values.each do |locale, value|
|
43
|
-
@fields[locale] = {}
|
42
|
+
@fields[locale] = {} unless @fields[locale]
|
44
43
|
@fields[locale][name.to_sym] = value
|
45
44
|
end
|
46
45
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
module Contentful
|
3
2
|
module Management
|
4
3
|
module Resource
|
@@ -7,8 +6,9 @@ module Contentful
|
|
7
6
|
# Reload an object
|
8
7
|
# Updates the current version of the object to the version on the system
|
9
8
|
def reload
|
10
|
-
|
11
|
-
|
9
|
+
self_class = self.class
|
10
|
+
resource = self.is_a?(Space) ? self_class.find(id) : self_class.find(space.id, id)
|
11
|
+
refresh_data(resource) if resource.is_a? self_class
|
12
12
|
end
|
13
13
|
|
14
14
|
def refresh_data(resource)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
require_relative 'error'
|
3
2
|
require_relative 'resource'
|
4
3
|
require_relative 'entry'
|
@@ -16,13 +15,13 @@ module Contentful
|
|
16
15
|
# See example/resource_mapping.rb for avanced usage
|
17
16
|
class ResourceBuilder
|
18
17
|
DEFAULT_RESOURCE_MAPPING = {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
'Space' => Contentful::Management::Space,
|
19
|
+
'ContentType' => Contentful::Management::ContentType,
|
20
|
+
'Entry' => :find_entry_class,
|
21
|
+
'Asset' => Contentful::Management::Asset,
|
22
|
+
'Array' => :array_or_sync_page,
|
23
|
+
'Link' => Contentful::Management::Link,
|
24
|
+
'WebhookDefinition' => Contentful::Management::Webhook
|
26
25
|
}
|
27
26
|
DEFAULT_ENTRY_MAPPING = {}
|
28
27
|
|
@@ -32,7 +31,7 @@ module Contentful
|
|
32
31
|
@response = response
|
33
32
|
@client = Contentful::Management::Client.shared_instance
|
34
33
|
@included_resources = {}
|
35
|
-
@known_resources = Hash.new { |
|
34
|
+
@known_resources = Hash.new { |hash, key| hash[key] = {} }
|
36
35
|
@nested_locales = true
|
37
36
|
@default_locale = (client.configuration || Contentful::Client::DEFAULT_CONFIGURATION)[:default_locale]
|
38
37
|
@resource_mapping = default_resource_mapping.merge(resource_mapping)
|
@@ -42,19 +41,10 @@ module Contentful
|
|
42
41
|
# Starts the parsing process.
|
43
42
|
# Either returns an Error, or the parsed Resource
|
44
43
|
def run
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
UnparsableJson.new(response)
|
50
|
-
when :not_contentful
|
51
|
-
Error.new(response)
|
52
|
-
else
|
53
|
-
begin
|
54
|
-
create_all_resources!
|
55
|
-
rescue UnparsableResource => error
|
56
|
-
error
|
57
|
-
end
|
44
|
+
if response.status == :ok
|
45
|
+
create_all_resources!
|
46
|
+
else
|
47
|
+
response.object
|
58
48
|
end
|
59
49
|
end
|
60
50
|
|
@@ -75,6 +65,8 @@ module Contentful
|
|
75
65
|
end
|
76
66
|
|
77
67
|
@resource
|
68
|
+
rescue UnparsableResource => error
|
69
|
+
error
|
78
70
|
end
|
79
71
|
|
80
72
|
# Creates a single resource from the response object
|
@@ -109,10 +101,7 @@ module Contentful
|
|
109
101
|
|
110
102
|
# Returns the id of the related ContentType, if there is one
|
111
103
|
def content_type_id_for_entry(object)
|
112
|
-
object['sys']
|
113
|
-
object['sys']['contentType'] &&
|
114
|
-
object['sys']['contentType']['sys'] &&
|
115
|
-
object['sys']['contentType']['sys']['id']
|
104
|
+
object['sys']['contentType']['sys']['id']
|
116
105
|
end
|
117
106
|
|
118
107
|
# Detects if a resource is an Contentful::Array or a SyncPage
|
@@ -159,7 +148,7 @@ module Contentful
|
|
159
148
|
|
160
149
|
def detect_child_objects(object)
|
161
150
|
if object.is_a? Hash
|
162
|
-
object.select { |
|
151
|
+
object.select { |_key, value| value.is_a?(Hash) && value.key?('sys') }
|
163
152
|
else
|
164
153
|
{}
|
165
154
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
require_relative 'error'
|
3
2
|
require 'multi_json'
|
4
3
|
|
@@ -29,60 +28,65 @@ module Contentful
|
|
29
28
|
@request = request
|
30
29
|
@status = :ok
|
31
30
|
|
32
|
-
if
|
33
|
-
|
34
|
-
@error_message = 'Service Unavailable, contenful.com API seems to be down'
|
31
|
+
if valid_http_response?
|
32
|
+
parse_json!
|
35
33
|
elsif no_content_response?
|
36
34
|
@status = :no_content
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
elsif no_resource_or_bad_request?
|
36
|
+
parse_contentful_error
|
37
|
+
else
|
38
|
+
parse_http_error
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
42
|
private
|
44
43
|
|
45
|
-
def
|
46
|
-
|
44
|
+
def error_object?
|
45
|
+
object['sys']['type'] == 'Error'
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_contentful_error
|
49
|
+
@object = load_json
|
50
|
+
@error_message = object['message'] if error_object?
|
51
|
+
parse_http_error
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid_http_response?
|
55
|
+
[200, 201].include?(raw.status)
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_http_error
|
59
|
+
@status = :error
|
60
|
+
@object = Error[raw.status].new(self)
|
61
|
+
end
|
62
|
+
|
63
|
+
def no_resource_or_bad_request?
|
64
|
+
[400, 404].include?(raw.status)
|
47
65
|
end
|
48
66
|
|
49
67
|
def no_content_response?
|
50
|
-
|
68
|
+
raw.to_s == '' && raw.status == 204
|
51
69
|
end
|
52
70
|
|
53
71
|
def parse_json!
|
54
|
-
|
55
|
-
@object = MultiJson.load(body)
|
56
|
-
true
|
72
|
+
@object = load_json
|
57
73
|
rescue MultiJson::LoadError => error
|
58
|
-
@status = :unparsable_json
|
59
74
|
@error_message = error.message
|
60
|
-
|
61
|
-
false
|
75
|
+
UnparsableJson.new(self)
|
62
76
|
end
|
63
77
|
|
64
|
-
def
|
65
|
-
|
66
|
-
if @object['sys']['type'] == 'Error'
|
67
|
-
@status = :contentful_error
|
68
|
-
@error_message = object['message']
|
69
|
-
true
|
70
|
-
else
|
71
|
-
false
|
72
|
-
end
|
73
|
-
else
|
74
|
-
@status = :not_contentful
|
75
|
-
@error_message = 'No contentful system properties found in object'
|
76
|
-
end
|
78
|
+
def load_json
|
79
|
+
MultiJson.load(unzip_response(raw))
|
77
80
|
end
|
78
81
|
|
79
82
|
def unzip_response(response)
|
80
|
-
|
81
|
-
|
83
|
+
parsed_response = response.to_s
|
84
|
+
if response.headers['Content-Encoding'].eql?('gzip')
|
85
|
+
sio = StringIO.new(parsed_response)
|
82
86
|
gz = Zlib::GzipReader.new(sio)
|
83
87
|
gz.read
|
84
88
|
else
|
85
|
-
|
89
|
+
parsed_response
|
86
90
|
end
|
87
91
|
end
|
88
92
|
end
|