contentful-management 0.0.1.pre
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.
- data/.gitignore +24 -0
- data/.reek +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +408 -0
- data/Rakefile +37 -0
- data/bin/cma-console +8 -0
- data/contentful-management.gemspec +33 -0
- data/examples/blog.rb +82 -0
- data/examples/content_types.rb +45 -0
- data/examples/create_space.rb +35 -0
- data/lib/contentful/management.rb +12 -0
- data/lib/contentful/management/array.rb +35 -0
- data/lib/contentful/management/asset.rb +163 -0
- data/lib/contentful/management/client.rb +160 -0
- data/lib/contentful/management/content_type.rb +180 -0
- data/lib/contentful/management/dynamic_entry.rb +71 -0
- data/lib/contentful/management/entry.rb +213 -0
- data/lib/contentful/management/error.rb +62 -0
- data/lib/contentful/management/field.rb +34 -0
- data/lib/contentful/management/file.rb +15 -0
- data/lib/contentful/management/http_client.rb +22 -0
- data/lib/contentful/management/link.rb +23 -0
- data/lib/contentful/management/locale.rb +48 -0
- data/lib/contentful/management/location.rb +15 -0
- data/lib/contentful/management/request.rb +82 -0
- data/lib/contentful/management/resource.rb +166 -0
- data/lib/contentful/management/resource/array_like.rb +37 -0
- data/lib/contentful/management/resource/fields.rb +69 -0
- data/lib/contentful/management/resource/refresher.rb +21 -0
- data/lib/contentful/management/resource/system_properties.rb +56 -0
- data/lib/contentful/management/resource_builder.rb +269 -0
- data/lib/contentful/management/response.rb +72 -0
- data/lib/contentful/management/space.rb +159 -0
- data/lib/contentful/management/support.rb +24 -0
- data/lib/contentful/management/version.rb +6 -0
- data/spec/fixtures/vcr_cassettes/array_page_1.yml +1337 -0
- data/spec/fixtures/vcr_cassettes/asset/all.yml +611 -0
- data/spec/fixtures/vcr_cassettes/asset/archive.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/archive_published.yml +177 -0
- data/spec/fixtures/vcr_cassettes/asset/archived_false.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/archived_true.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/create.yml +150 -0
- data/spec/fixtures/vcr_cassettes/asset/create_with_already_used_id.yml +56 -0
- data/spec/fixtures/vcr_cassettes/asset/create_with_custom_id.yml +150 -0
- data/spec/fixtures/vcr_cassettes/asset/destroy.yml +159 -0
- data/spec/fixtures/vcr_cassettes/asset/destroy_published.yml +175 -0
- data/spec/fixtures/vcr_cassettes/asset/find.yml +108 -0
- data/spec/fixtures/vcr_cassettes/asset/find_not_found.yml +64 -0
- data/spec/fixtures/vcr_cassettes/asset/image_url.yml +133 -0
- data/spec/fixtures/vcr_cassettes/asset/locale.yml +110 -0
- data/spec/fixtures/vcr_cassettes/asset/publish.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/publish_already_published.yml +176 -0
- data/spec/fixtures/vcr_cassettes/asset/published_false.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/published_true.yml +226 -0
- data/spec/fixtures/vcr_cassettes/asset/save_update.yml +242 -0
- data/spec/fixtures/vcr_cassettes/asset/set_locale.yml +110 -0
- data/spec/fixtures/vcr_cassettes/asset/unarchive.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/unarchive_already_unarchive.yml +168 -0
- data/spec/fixtures/vcr_cassettes/asset/unarchive_already_unarchived.yml +168 -0
- data/spec/fixtures/vcr_cassettes/asset/unpublish.yml +228 -0
- data/spec/fixtures/vcr_cassettes/asset/unpublish_already_unpublished.yml +168 -0
- data/spec/fixtures/vcr_cassettes/asset/update_file.yml +207 -0
- data/spec/fixtures/vcr_cassettes/asset/update_to_specified_locale.yml +224 -0
- data/spec/fixtures/vcr_cassettes/asset/update_with_default_locale_without_file.yml +214 -0
- data/spec/fixtures/vcr_cassettes/content_type/activate.yml +246 -0
- data/spec/fixtures/vcr_cassettes/content_type/activate_with_invalid_version.yml +186 -0
- data/spec/fixtures/vcr_cassettes/content_type/activated_false.yml +246 -0
- data/spec/fixtures/vcr_cassettes/content_type/activated_true.yml +257 -0
- data/spec/fixtures/vcr_cassettes/content_type/all.yml +190 -0
- data/spec/fixtures/vcr_cassettes/content_type/create.yml +87 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_content_type_with_id.yml +87 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Array_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Boolean_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Date_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Integer_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Link_field.yml +95 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Location_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Number_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Object_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Symbol_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/create_with_Text_field.yml +94 -0
- data/spec/fixtures/vcr_cassettes/content_type/deactivate.yml +246 -0
- data/spec/fixtures/vcr_cassettes/content_type/deactivate_already_deactivated.yml +176 -0
- data/spec/fixtures/vcr_cassettes/content_type/deactivate_with_entries.yml +236 -0
- data/spec/fixtures/vcr_cassettes/content_type/deactivate_with_version_change.yml +248 -0
- data/spec/fixtures/vcr_cassettes/content_type/destroy.yml +148 -0
- data/spec/fixtures/vcr_cassettes/content_type/destroy_activated.yml +164 -0
- data/spec/fixtures/vcr_cassettes/content_type/entry/create.yml +1344 -0
- data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_camel_case_id_to_multiple_locales.yml +235 -0
- data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_entries.yml +398 -0
- data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_entries_for_multiple_locales.yml +3157 -0
- data/spec/fixtures/vcr_cassettes/content_type/entry/create_with_multiple_locales.yml +230 -0
- data/spec/fixtures/vcr_cassettes/content_type/fields/add.yml +345 -0
- data/spec/fixtures/vcr_cassettes/content_type/fields/create.yml +353 -0
- data/spec/fixtures/vcr_cassettes/content_type/fields/create_array_with_params.yml +228 -0
- data/spec/fixtures/vcr_cassettes/content_type/fields/create_with_params.yml +221 -0
- data/spec/fixtures/vcr_cassettes/content_type/fields/destroy.yml +349 -0
- data/spec/fixtures/vcr_cassettes/content_type/fields/update_field.yml +358 -0
- data/spec/fixtures/vcr_cassettes/content_type/find.yml +180 -0
- data/spec/fixtures/vcr_cassettes/content_type/find_not_found.yml +64 -0
- data/spec/fixtures/vcr_cassettes/content_type/save_new.yml +876 -0
- data/spec/fixtures/vcr_cassettes/content_type/save_updated.yml +345 -0
- data/spec/fixtures/vcr_cassettes/content_type/save_with_added_field.yml +217 -0
- data/spec/fixtures/vcr_cassettes/content_type/update.yml +175 -0
- data/spec/fixtures/vcr_cassettes/content_type/update_change_field_name.yml +222 -0
- data/spec/fixtures/vcr_cassettes/content_type/update_remove_field.yml +231 -0
- data/spec/fixtures/vcr_cassettes/content_type/update_with_fields.yml +222 -0
- data/spec/fixtures/vcr_cassettes/content_type/update_with_one_new_field.yml +251 -0
- data/spec/fixtures/vcr_cassettes/entry/all.yml +139 -0
- data/spec/fixtures/vcr_cassettes/entry/archive.yml +222 -0
- data/spec/fixtures/vcr_cassettes/entry/archive_published.yml +187 -0
- data/spec/fixtures/vcr_cassettes/entry/archived_false.yml +178 -0
- data/spec/fixtures/vcr_cassettes/entry/archived_true.yml +248 -0
- data/spec/fixtures/vcr_cassettes/entry/create.yml +245 -0
- data/spec/fixtures/vcr_cassettes/entry/create_test.yml +150 -0
- data/spec/fixtures/vcr_cassettes/entry/create_with_asset.yml +403 -0
- data/spec/fixtures/vcr_cassettes/entry/create_with_assets.yml +419 -0
- data/spec/fixtures/vcr_cassettes/entry/create_with_entries.yml +418 -0
- data/spec/fixtures/vcr_cassettes/entry/create_with_entry.yml +493 -0
- data/spec/fixtures/vcr_cassettes/entry/create_with_location.yml +259 -0
- data/spec/fixtures/vcr_cassettes/entry/create_with_symbols.yml +271 -0
- data/spec/fixtures/vcr_cassettes/entry/destory_published.yml +172 -0
- data/spec/fixtures/vcr_cassettes/entry/destroy.yml +156 -0
- data/spec/fixtures/vcr_cassettes/entry/find.yml +129 -0
- data/spec/fixtures/vcr_cassettes/entry/find_not_found.yml +64 -0
- data/spec/fixtures/vcr_cassettes/entry/publish.yml +248 -0
- data/spec/fixtures/vcr_cassettes/entry/publish_already_published.yml +186 -0
- data/spec/fixtures/vcr_cassettes/entry/published_false.yml +248 -0
- data/spec/fixtures/vcr_cassettes/entry/published_true.yml +257 -0
- data/spec/fixtures/vcr_cassettes/entry/save_update.yml +211 -0
- data/spec/fixtures/vcr_cassettes/entry/unarchive.yml +248 -0
- data/spec/fixtures/vcr_cassettes/entry/unarchive_already_unarchived.yml +178 -0
- data/spec/fixtures/vcr_cassettes/entry/unpublish.yml +248 -0
- data/spec/fixtures/vcr_cassettes/entry/unpublish_already_unpublished.yml +178 -0
- data/spec/fixtures/vcr_cassettes/entry/update.yml +626 -0
- data/spec/fixtures/vcr_cassettes/entry/update_unlocalized_field.yml +308 -0
- data/spec/fixtures/vcr_cassettes/entry/update_with_custom_locale.yml +332 -0
- data/spec/fixtures/vcr_cassettes/get_request.yml +37 -0
- data/spec/fixtures/vcr_cassettes/locale/all_for_space.yml +321 -0
- data/spec/fixtures/vcr_cassettes/locale/create_for_space.yml +95 -0
- data/spec/fixtures/vcr_cassettes/locale/find.yml +95 -0
- data/spec/fixtures/vcr_cassettes/locale/find_for_space_not_found.yml +67 -0
- data/spec/fixtures/vcr_cassettes/space/all.yml +1201 -0
- data/spec/fixtures/vcr_cassettes/space/asset/all.yml +475 -0
- data/spec/fixtures/vcr_cassettes/space/asset/assets.yml +826 -0
- data/spec/fixtures/vcr_cassettes/space/asset/create.yml +508 -0
- data/spec/fixtures/vcr_cassettes/space/asset/create_with_multiple_locales.yml +1062 -0
- data/spec/fixtures/vcr_cassettes/space/asset/find.yml +634 -0
- data/spec/fixtures/vcr_cassettes/space/content_type/all.yml +470 -0
- data/spec/fixtures/vcr_cassettes/space/content_type/content_types.yml +341 -0
- data/spec/fixtures/vcr_cassettes/space/content_type/create.yml +425 -0
- data/spec/fixtures/vcr_cassettes/space/content_type/find.yml +493 -0
- data/spec/fixtures/vcr_cassettes/space/create.yml +85 -0
- data/spec/fixtures/vcr_cassettes/space/create_when_limit_has_been_reached.yml +67 -0
- data/spec/fixtures/vcr_cassettes/space/create_with_unknown_organization.yml +65 -0
- data/spec/fixtures/vcr_cassettes/space/create_without_organization.yml +83 -0
- data/spec/fixtures/vcr_cassettes/space/destory.yml +196 -0
- data/spec/fixtures/vcr_cassettes/space/entry/all.yml +634 -0
- data/spec/fixtures/vcr_cassettes/space/entry/entries.yml +498 -0
- data/spec/fixtures/vcr_cassettes/space/entry/find.yml +624 -0
- data/spec/fixtures/vcr_cassettes/space/find.yml +270 -0
- data/spec/fixtures/vcr_cassettes/space/find_not_found.yml +67 -0
- data/spec/fixtures/vcr_cassettes/space/locale/all.yml +690 -0
- data/spec/fixtures/vcr_cassettes/space/locale/create.yml +572 -0
- data/spec/fixtures/vcr_cassettes/space/locale/create_with_the_same_code.yml +585 -0
- data/spec/fixtures/vcr_cassettes/space/locale/find.yml +572 -0
- data/spec/fixtures/vcr_cassettes/space/locale/find_not_found.yml +580 -0
- data/spec/fixtures/vcr_cassettes/space/locale/locales.yml +480 -0
- data/spec/fixtures/vcr_cassettes/space/locale/update.yml +700 -0
- data/spec/fixtures/vcr_cassettes/space/save_new_space.yml +67 -0
- data/spec/fixtures/vcr_cassettes/space/save_update_space.yml +352 -0
- data/spec/fixtures/vcr_cassettes/space/update.yml +350 -0
- data/spec/fixtures/vcr_cassettes/space/update_with_the_same_data.yml +350 -0
- data/spec/lib/contentful/management/array_spec.rb +59 -0
- data/spec/lib/contentful/management/asset_spec.rb +321 -0
- data/spec/lib/contentful/management/client_spec.rb +80 -0
- data/spec/lib/contentful/management/content_type_spec.rb +455 -0
- data/spec/lib/contentful/management/entry_spec.rb +308 -0
- data/spec/lib/contentful/management/locale_spec.rb +53 -0
- data/spec/lib/contentful/management/space_spec.rb +317 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/vcr.rb +17 -0
- metadata +554 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
module Contentful
|
|
3
|
+
module Management
|
|
4
|
+
module Resource
|
|
5
|
+
# Useful methods for array-like resources that can be included if an
|
|
6
|
+
# :items property exists
|
|
7
|
+
module ArrayLike
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
# Returns true for array-like resources
|
|
11
|
+
def array?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Delegates to items#each
|
|
16
|
+
def each_item(&block)
|
|
17
|
+
items.each(&block)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
alias each each_item
|
|
21
|
+
|
|
22
|
+
# Delegates to items#empty?
|
|
23
|
+
def empty?
|
|
24
|
+
items.empty?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Delegetes to items#size
|
|
28
|
+
def size
|
|
29
|
+
items.size
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
alias length size
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require_relative '../file'
|
|
3
|
+
|
|
4
|
+
module Contentful
|
|
5
|
+
module Management
|
|
6
|
+
module Resource
|
|
7
|
+
module Fields
|
|
8
|
+
|
|
9
|
+
def fields(wanted_locale = default_locale)
|
|
10
|
+
requested_locale = locale || wanted_locale
|
|
11
|
+
@fields[requested_locale] = {} unless @fields[requested_locale]
|
|
12
|
+
@fields[requested_locale]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(object = nil, *)
|
|
16
|
+
super
|
|
17
|
+
@fields = {}
|
|
18
|
+
extract_fields_from_object! object if object
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def inspect(info = nil)
|
|
22
|
+
if fields.empty?
|
|
23
|
+
super(info)
|
|
24
|
+
else
|
|
25
|
+
super("#{ info } @fields=#{ fields.inspect }")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.included(base)
|
|
30
|
+
base.fields_coercions.keys.each { |name|
|
|
31
|
+
accessor_name = Contentful::Management::Support.snakify(name)
|
|
32
|
+
base.send :define_method, accessor_name do
|
|
33
|
+
fields[name.to_sym]
|
|
34
|
+
end
|
|
35
|
+
base.send :define_method, "#{ accessor_name }_with_locales" do
|
|
36
|
+
fields_for_query[name.to_sym]
|
|
37
|
+
end
|
|
38
|
+
base.send :define_method, "#{ accessor_name }=" do |value|
|
|
39
|
+
fields[name.to_sym] = value
|
|
40
|
+
end
|
|
41
|
+
base.send :define_method, "#{ accessor_name }_with_locales=" do |values|
|
|
42
|
+
values.each do |locale, value|
|
|
43
|
+
@fields[locale] = {} if @fields[locale].nil?
|
|
44
|
+
@fields[locale][name.to_sym] = value
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def extract_fields_from_object!(object)
|
|
53
|
+
if nested_locale_fields? && !object['fields'].nil?
|
|
54
|
+
object['fields'].each do |field_name, nested_child_object|
|
|
55
|
+
nested_child_object.each do |object_locale, real_child_object|
|
|
56
|
+
@fields[object_locale] ||= {}
|
|
57
|
+
@fields[object_locale].merge! extract_from_object(
|
|
58
|
+
{ field_name => real_child_object }, :fields
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
@fields[locale || default_locale] = extract_from_object object['fields'], :fields
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
module Contentful
|
|
3
|
+
module Management
|
|
4
|
+
module Resource
|
|
5
|
+
# Adds the feature to have properties and system data reload for Resource.
|
|
6
|
+
module Refresher
|
|
7
|
+
|
|
8
|
+
def refresh_data(resource)
|
|
9
|
+
if resource.is_a? Error
|
|
10
|
+
resource
|
|
11
|
+
else
|
|
12
|
+
@properties = resource.instance_variable_get(:@properties)
|
|
13
|
+
@fields = resource.instance_variable_get(:@fields) if self.is_a?(Contentful::Management::Entry)
|
|
14
|
+
@sys = resource.instance_variable_get(:@sys)
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
module Contentful
|
|
3
|
+
module Management
|
|
4
|
+
module Resource
|
|
5
|
+
# Adds the feature to have system properties to a Resource.
|
|
6
|
+
module SystemProperties
|
|
7
|
+
SYS_COERCIONS = {
|
|
8
|
+
type: :string,
|
|
9
|
+
id: :string,
|
|
10
|
+
space: nil,
|
|
11
|
+
contentType: nil,
|
|
12
|
+
linkType: :string,
|
|
13
|
+
revision: :integer,
|
|
14
|
+
createdAt: :date,
|
|
15
|
+
updatedAt: :date,
|
|
16
|
+
locale: :string
|
|
17
|
+
}
|
|
18
|
+
attr_reader :sys
|
|
19
|
+
|
|
20
|
+
def initialize(object = { 'sys' => nil }, *)
|
|
21
|
+
super
|
|
22
|
+
object ||= { 'sys' => nil }
|
|
23
|
+
@sys = extract_from_object object['sys'], :sys
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def inspect(info = nil)
|
|
27
|
+
if sys.empty?
|
|
28
|
+
super(info)
|
|
29
|
+
else
|
|
30
|
+
super("#{ info } @sys=#{ sys.inspect }")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
module ClassMethods
|
|
35
|
+
def sys_coercions
|
|
36
|
+
SYS_COERCIONS
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.included(base)
|
|
41
|
+
base.extend(ClassMethods)
|
|
42
|
+
|
|
43
|
+
base.sys_coercions.keys.each { |name|
|
|
44
|
+
accessor_name = Contentful::Management::Support.snakify(name)
|
|
45
|
+
base.send :define_method, accessor_name do
|
|
46
|
+
sys[name.to_sym]
|
|
47
|
+
end
|
|
48
|
+
base.send :define_method, "#{ accessor_name }=" do |value|
|
|
49
|
+
sys[name.to_sym] = value
|
|
50
|
+
end
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require_relative 'error'
|
|
3
|
+
require_relative 'resource'
|
|
4
|
+
require_relative 'entry'
|
|
5
|
+
require_relative 'dynamic_entry'
|
|
6
|
+
require_relative 'array'
|
|
7
|
+
require_relative 'link'
|
|
8
|
+
require_relative 'space'
|
|
9
|
+
require_relative 'content_type'
|
|
10
|
+
require_relative 'asset'
|
|
11
|
+
|
|
12
|
+
module Contentful
|
|
13
|
+
module Management
|
|
14
|
+
# Transforms a Contentful::Response into a Contentful::Resource or a Contentful::Error
|
|
15
|
+
# See example/resource_mapping.rb for avanced usage
|
|
16
|
+
class ResourceBuilder
|
|
17
|
+
DEFAULT_RESOURCE_MAPPING = {
|
|
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
|
+
}
|
|
25
|
+
DEFAULT_ENTRY_MAPPING = {}
|
|
26
|
+
|
|
27
|
+
attr_reader :client, :response, :resource_mapping, :entry_mapping, :resource
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def initialize(client, response, resource_mapping = {}, entry_mapping = {})
|
|
31
|
+
@response = response
|
|
32
|
+
@client = client
|
|
33
|
+
@included_resources = {}
|
|
34
|
+
@known_resources = Hash.new { |h, k| h[k] = {} }
|
|
35
|
+
@nested_locales = true
|
|
36
|
+
@default_locale = (Contentful::Management::Client.shared_instance.configuration || Contentful::Client::DEFAULT_CONFIGURATION)[:default_locale]
|
|
37
|
+
@resource_mapping = default_resource_mapping.merge(resource_mapping)
|
|
38
|
+
@entry_mapping = default_entry_mapping.merge(entry_mapping)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Starts the parsing process.
|
|
42
|
+
# Either returns an Error, or the parsed Resource
|
|
43
|
+
def run
|
|
44
|
+
case response.status
|
|
45
|
+
when :contentful_error
|
|
46
|
+
Error[response.raw.status].new(response)
|
|
47
|
+
when :unparsable_json
|
|
48
|
+
UnparsableJson.new(response)
|
|
49
|
+
when :not_contentful
|
|
50
|
+
Error.new(response)
|
|
51
|
+
else
|
|
52
|
+
begin
|
|
53
|
+
create_all_resources!
|
|
54
|
+
rescue UnparsableResource => error
|
|
55
|
+
error
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# PARSING MECHANISM
|
|
61
|
+
# - raise error if response not valid
|
|
62
|
+
# - look for included objects and parse them to resources
|
|
63
|
+
# - parse main object to resource
|
|
64
|
+
# - replace links in included resources with known resources
|
|
65
|
+
# - replace links in main resource with known resources
|
|
66
|
+
# - return main resource
|
|
67
|
+
def create_all_resources!
|
|
68
|
+
create_included_resources! response.object['includes']
|
|
69
|
+
@resource = create_resource(response.object)
|
|
70
|
+
|
|
71
|
+
unless @included_resources.empty?
|
|
72
|
+
replace_links_in_included_resources_with_known_resources
|
|
73
|
+
replace_links_with_known_resources @resource
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
@resource
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Creates a single resource from the response object
|
|
80
|
+
def create_resource(object)
|
|
81
|
+
res_class = detect_resource_class(object)
|
|
82
|
+
@nested_locales ||= res_class.nested_locale_fields?
|
|
83
|
+
res = res_class.new(object, response.request, client, @nested_locales, @default_locale)
|
|
84
|
+
|
|
85
|
+
add_to_known_resources res
|
|
86
|
+
replace_children res, object
|
|
87
|
+
replace_child_array res.items if res.array?
|
|
88
|
+
|
|
89
|
+
res
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Checks in a custom class for an entry was defined in entry_mapping
|
|
93
|
+
def find_entry_class(object)
|
|
94
|
+
entry_mapping[content_type_id_for_entry(object)] || try_dynamic_entry(object)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Automatically converts Entry to DynamicEntry if in cache
|
|
98
|
+
def try_dynamic_entry(object)
|
|
99
|
+
get_dynamic_entry(object) || Contentful::Management::Entry
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Finds the proper DynamicEntry class for an entry
|
|
103
|
+
def get_dynamic_entry(object)
|
|
104
|
+
if content_id = content_type_id_for_entry(object)
|
|
105
|
+
client.dynamic_entry_cache[content_id.to_sym]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Returns the id of the related ContentType, if there is one
|
|
110
|
+
def content_type_id_for_entry(object)
|
|
111
|
+
object['sys'] &&
|
|
112
|
+
object['sys']['contentType'] &&
|
|
113
|
+
object['sys']['contentType']['sys'] &&
|
|
114
|
+
object['sys']['contentType']['sys']['id']
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Detects if a resource is an Contentful::Array or a SyncPage
|
|
118
|
+
def array_or_sync_page(object)
|
|
119
|
+
if object['nextPageUrl'] || object['nextSyncUrl']
|
|
120
|
+
SyncPage
|
|
121
|
+
else
|
|
122
|
+
Array
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Uses the resource mapping to find the proper Resource class to initialize
|
|
127
|
+
# for this Response object type
|
|
128
|
+
#
|
|
129
|
+
# The mapping value can be a
|
|
130
|
+
# - Class
|
|
131
|
+
# - Proc: Will be called, expected to return the proper Class
|
|
132
|
+
# - Symbol: Will be called as method of the ResourceBuilder itself
|
|
133
|
+
def detect_resource_class(object)
|
|
134
|
+
type = object['sys'] && object['sys']['type']
|
|
135
|
+
|
|
136
|
+
case res_class = resource_mapping[type]
|
|
137
|
+
when Symbol
|
|
138
|
+
public_send(res_class, object)
|
|
139
|
+
when Proc
|
|
140
|
+
res_class[object]
|
|
141
|
+
when nil
|
|
142
|
+
raise UnparsableResource.new(response)
|
|
143
|
+
else
|
|
144
|
+
res_class
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# The default mapping for #detect_resource_class
|
|
149
|
+
def default_resource_mapping
|
|
150
|
+
DEFAULT_RESOURCE_MAPPING.dup
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# The default entry mapping
|
|
154
|
+
def default_entry_mapping
|
|
155
|
+
DEFAULT_ENTRY_MAPPING.dup
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
def detect_child_objects(object)
|
|
162
|
+
if object.is_a? Hash
|
|
163
|
+
object.select { |_, v| v.is_a?(Hash) && v.key?('sys') }
|
|
164
|
+
else
|
|
165
|
+
{}
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def detect_child_arrays(object)
|
|
170
|
+
if object.is_a? Hash
|
|
171
|
+
object.select do |_, v|
|
|
172
|
+
v.is_a?(::Array) &&
|
|
173
|
+
v.first &&
|
|
174
|
+
v.first.is_a?(Hash) &&
|
|
175
|
+
v.first.key?('sys')
|
|
176
|
+
end
|
|
177
|
+
else
|
|
178
|
+
{}
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def add_to_known_resources(res)
|
|
183
|
+
@known_resources[res.type][res.id] = res if res.sys && res.id && res.type != 'Link'
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def replace_children(res, object)
|
|
187
|
+
object.each do |name, potential_objects|
|
|
188
|
+
detect_child_objects(potential_objects).each do |child_name, child_object|
|
|
189
|
+
res.public_send(name)[child_name.to_sym] = create_resource(child_object)
|
|
190
|
+
end
|
|
191
|
+
next if name == 'includes'
|
|
192
|
+
detect_child_arrays(potential_objects).each do |child_name, _child_array|
|
|
193
|
+
replace_child_array res.public_send(name)[child_name.to_sym]
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def replace_child_array(child_array)
|
|
199
|
+
child_array.map! { |resource_object| create_resource(resource_object) }
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def create_included_resources!(included_objects)
|
|
203
|
+
if included_objects
|
|
204
|
+
included_objects.each do |type, objects|
|
|
205
|
+
@included_resources[type] = Hash[
|
|
206
|
+
objects.map do |object|
|
|
207
|
+
res = create_resource(object)
|
|
208
|
+
[res.id, res]
|
|
209
|
+
end
|
|
210
|
+
]
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def replace_links_with_known_resources(res, seen_resource_ids = [])
|
|
216
|
+
seen_resource_ids << res.id
|
|
217
|
+
|
|
218
|
+
[:properties, :sys, :fields].map do |property_container_name|
|
|
219
|
+
res.public_send(property_container_name)
|
|
220
|
+
end.compact.each do |property_container|
|
|
221
|
+
replace_links_in_properties(property_container, seen_resource_ids)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
if res.array?
|
|
225
|
+
replace_links_in_array res.items, seen_resource_ids
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def replace_links_in_properties(property_container, seen_resource_ids)
|
|
230
|
+
property_container.each do |property_name, property_value|
|
|
231
|
+
if property_value.is_a? ::Array
|
|
232
|
+
replace_links_in_array property_value, seen_resource_ids
|
|
233
|
+
else
|
|
234
|
+
replace_link_or_check_recursively property_value, property_container, property_name, seen_resource_ids
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def replace_links_in_array(property_container, seen_resource_ids)
|
|
240
|
+
property_container.each.with_index do |child_property, property_index|
|
|
241
|
+
replace_link_or_check_recursively child_property, property_container, property_index, seen_resource_ids
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def replace_link_or_check_recursively(property_value, property_container, property_name, seen_resource_ids)
|
|
246
|
+
if property_value.is_a? Link
|
|
247
|
+
maybe_replace_link(property_value, property_container, property_name)
|
|
248
|
+
elsif property_value.is_a?(Resource) && property_value.sys && !seen_resource_ids.include?(property_value.id)
|
|
249
|
+
replace_links_with_known_resources(property_value, seen_resource_ids)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def maybe_replace_link(link, parent, key)
|
|
254
|
+
if @known_resources[link.link_type] &&
|
|
255
|
+
@known_resources[link.link_type].key?(link.id)
|
|
256
|
+
parent[key] = @known_resources[link.link_type][link.id]
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def replace_links_in_included_resources_with_known_resources
|
|
261
|
+
@included_resources.each do |_, for_type|
|
|
262
|
+
for_type.each do |_, res|
|
|
263
|
+
replace_links_with_known_resources(res)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|