contentful 1.2.2 → 2.0.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 +4 -4
- data/CHANGELOG.md +21 -0
- data/LICENSE.txt +1 -0
- data/README.md +8 -0
- data/contentful.gemspec +2 -1
- data/examples/custom_classes.rb +23 -26
- data/examples/raise_errors.rb +2 -2
- data/lib/contentful.rb +0 -1
- data/lib/contentful/array.rb +27 -19
- data/lib/contentful/array_like.rb +51 -0
- data/lib/contentful/asset.rb +43 -11
- data/lib/contentful/base_resource.rb +87 -0
- data/lib/contentful/client.rb +43 -34
- data/lib/contentful/coercions.rb +116 -0
- data/lib/contentful/content_type.rb +23 -8
- data/lib/contentful/content_type_cache.rb +26 -0
- data/lib/contentful/deleted_asset.rb +2 -5
- data/lib/contentful/deleted_entry.rb +2 -5
- data/lib/contentful/entry.rb +55 -33
- data/lib/contentful/error.rb +1 -1
- data/lib/contentful/field.rb +37 -9
- data/lib/contentful/fields_resource.rb +115 -0
- data/lib/contentful/file.rb +7 -8
- data/lib/contentful/link.rb +3 -6
- data/lib/contentful/locale.rb +6 -6
- data/lib/contentful/location.rb +7 -5
- data/lib/contentful/resource_builder.rb +72 -226
- data/lib/contentful/space.rb +16 -6
- data/lib/contentful/support.rb +41 -3
- data/lib/contentful/sync_page.rb +17 -10
- data/lib/contentful/version.rb +1 -1
- data/spec/array_spec.rb +4 -8
- data/spec/client_class_spec.rb +12 -23
- data/spec/client_configuration_spec.rb +13 -23
- data/spec/content_type_spec.rb +0 -5
- data/spec/entry_spec.rb +130 -125
- data/spec/error_requests_spec.rb +1 -1
- data/spec/field_spec.rb +0 -5
- data/spec/file_spec.rb +0 -5
- data/spec/fixtures/vcr_cassettes/entry.yml +54 -64
- data/spec/fixtures/vcr_cassettes/entry/include_resolution.yml +101 -0
- data/spec/fixtures/vcr_cassettes/entry/marshall.yml +227 -251
- data/spec/fixtures/vcr_cassettes/entry/raw.yml +88 -124
- data/spec/fixtures/vcr_cassettes/entry_locales.yml +56 -74
- data/spec/fixtures/vcr_cassettes/human.yml +63 -40
- data/spec/fixtures/vcr_cassettes/location.yml +99 -211
- data/spec/fixtures/vcr_cassettes/multi_locale_array_reference.yml +12 -16
- data/spec/fixtures/vcr_cassettes/not_found.yml +26 -21
- data/spec/fixtures/vcr_cassettes/nyancat.yml +53 -63
- data/spec/fixtures/vcr_cassettes/ratelimit.yml +1 -1
- data/spec/fixtures/vcr_cassettes/reloaded_entry.yml +54 -64
- data/spec/fixtures/vcr_cassettes/unauthorized.yml +1 -1
- data/spec/fixtures/vcr_cassettes/unavailable.yml +27 -15
- data/spec/link_spec.rb +3 -2
- data/spec/locale_spec.rb +0 -5
- data/spec/location_spec.rb +1 -6
- data/spec/request_spec.rb +3 -2
- data/spec/resource_building_spec.rb +10 -7
- data/spec/response_spec.rb +1 -1
- data/spec/space_spec.rb +0 -5
- data/spec/spec_helper.rb +3 -0
- data/spec/support/json_responses.rb +3 -3
- data/spec/sync_page_spec.rb +1 -6
- data/spec/sync_spec.rb +11 -7
- metadata +69 -20
- data/examples/dynamic_entries.rb +0 -124
- data/examples/resource_mapping.rb +0 -32
- data/lib/contentful/constants.rb +0 -504
- data/lib/contentful/dynamic_entry.rb +0 -57
- data/lib/contentful/resource.rb +0 -239
- data/lib/contentful/resource/array_like.rb +0 -39
- data/lib/contentful/resource/asset_fields.rb +0 -58
- data/lib/contentful/resource/custom_resource.rb +0 -29
- data/lib/contentful/resource/fields.rb +0 -73
- data/lib/contentful/resource/system_properties.rb +0 -55
- data/spec/coercions_spec.rb +0 -23
- data/spec/dynamic_entry_spec.rb +0 -75
- data/spec/resource_spec.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3336395c12c33716d03ef5ccd4ca5662d0c9f0e4
|
4
|
+
data.tar.gz: ff41b0e879b3ab72bc0962abeac4dae2fb49496a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39692cf6bc73f11ea37ede62a11fc70f9ca5ccc7346cfe415d88dc53c320a30443669b7585df78ef13b657697a7f91fe126f01e26cdbab280ab03ebd5bcbdc5b
|
7
|
+
data.tar.gz: a6d462ef93caf18c9179b36403911f255685bcacd3ff7a06c9f91eca40c5c8e1346474068f20766baa726513d9a63a0c5fee101f0037b6444230062bda5bf65a
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 2.0.0
|
6
|
+
|
7
|
+
**ATTENTION**: Breaking Changes introduces in order to simplify code and improve the ability to add new features.
|
8
|
+
|
9
|
+
## Changed
|
10
|
+
|
11
|
+
* The removal of the Client and Request objects from the Resource objects, means that for example: Link#resolve and Array#next_page now require the client as a parameter.
|
12
|
+
* Client#entry now uses /entries?sys.id=ENTRY_ID instead of /entries/ENTRY_ID to properly resolve includes.
|
13
|
+
* Refactor locale handling code
|
14
|
+
* Refactor ResourceBuilder
|
15
|
+
* Update all specs to RSpec 3
|
16
|
+
* Removed DynamicEntry and Resource
|
17
|
+
* Moved ContentTypeCache outside of the client into it's own class
|
18
|
+
* Added new base BaseResource and FieldsResource classes to handle common resource attributes and fields related attributes respectively
|
19
|
+
* Coercions are now part of ContentType, each Field knows which coercion should be applied depending on Field#type
|
20
|
+
* Resource #inspect now provides a clearer and better output, without all the noise that was previously there
|
21
|
+
* CustomResource was removed, now subclasses of Entry should be used instead.
|
22
|
+
* `max_include_resolution_depth` option added to the client, defaults to 20.
|
23
|
+
* Updated LICENSE
|
24
|
+
* Updated examples
|
25
|
+
|
5
26
|
## 1.2.2
|
6
27
|
### Fixed
|
7
28
|
* Fixed Symbol/Text field serialization when value is `null` [#117](https://github.com/contentful/contentful.rb/issues/117)
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
3
|
Copyright (c) 2014 Contentful GmbH - Jan Lelis
|
4
|
+
Copyright (c) 2016 Contentful GmbH - David Litvak
|
4
5
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -5,6 +5,8 @@ Ruby client for the [Contentful](https://www.contentful.com) Content Delivery AP
|
|
5
5
|
|
6
6
|
[Contentful](https://www.contentful.com) is a content management platform for web applications, mobile apps and connected devices. It allows you to create, edit & manage content in the cloud and publish it anywhere via powerful API. Contentful offers tools for managing editorial teams and enabling cooperation between organizations.
|
7
7
|
|
8
|
+
**IMPORTANT**: We're collecting feedback before releasing version 2.0.0 of the SDK, if you're interested in helping, please drop by this issue and help us improving: https://github.com/contentful/contentful.rb/issues/120
|
9
|
+
|
8
10
|
## Setup
|
9
11
|
|
10
12
|
Add to your Gemfile and bundle:
|
@@ -248,6 +250,12 @@ Maximum time to wait for next available request (in seconds). Default value is 6
|
|
248
250
|
can have up to 60 minutes of blocked requests. It is set to a default of 60 seconds in order to avoid blocking processes for too long, as rate limit retry behaviour
|
249
251
|
is blocking per execution thread.
|
250
252
|
|
253
|
+
### :max_include_resolution_depth
|
254
|
+
|
255
|
+
Maximum amount of levels to resolve includes for SDK entities (this is independent of API-level includes - it represents the maximum depth the include resolution
|
256
|
+
tree is allowed to resolved before falling back to `Link` objects). This include resolution strategy is in place in order to avoid having infinite circular recursion
|
257
|
+
on resources with circular dependencies. Defaults to 20. _Note_: If you're using something like `Rails::cache` it's advisable to considerably lower this value
|
258
|
+
(around 5 has proven to be a good compromise - but keep it higher or equal than your maximum API-level include parameter if you need the entire tree resolution).
|
251
259
|
|
252
260
|
### Proxy example
|
253
261
|
|
data/contentful.gemspec
CHANGED
@@ -35,9 +35,10 @@ Gem::Specification.new do |gem|
|
|
35
35
|
gem.add_development_dependency 'guard-rubocop'
|
36
36
|
gem.add_development_dependency 'guard-yard'
|
37
37
|
gem.add_development_dependency 'rubocop', '~> 0.41.0'
|
38
|
-
gem.add_development_dependency 'rspec', '~>
|
38
|
+
gem.add_development_dependency 'rspec', '~> 3'
|
39
39
|
gem.add_development_dependency 'rr'
|
40
40
|
gem.add_development_dependency 'vcr'
|
41
|
+
gem.add_development_dependency 'simplecov'
|
41
42
|
gem.add_development_dependency 'webmock', '~> 1', '>= 1.17.3'
|
42
43
|
gem.add_development_dependency 'tins', '~> 1.6.0'
|
43
44
|
end
|
data/examples/custom_classes.rb
CHANGED
@@ -1,42 +1,39 @@
|
|
1
|
-
# Contentful resource classes are just plain Ruby classes that include the
|
2
|
-
# Contentful::Resource module.
|
3
|
-
#
|
4
|
-
# You can then define properties of the class. This will create a getter method
|
5
|
-
# with this name. You can optionally pass a type identifier (Symbol or Class).
|
6
|
-
#
|
7
|
-
# Classes will be instantiated for the properties,
|
8
|
-
# Symbols will be looked up in Contentful::Resource::COERCIONS
|
9
|
-
|
10
1
|
require 'contentful'
|
11
2
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
# You can define your own custom classes that inherit from Contentful::Entry.
|
4
|
+
# This allows you to define custom behaviour, for example, in this case, we want
|
5
|
+
# the :country field to act as a Contentful::Locale
|
6
|
+
class MyResource < Contentful::Entry
|
7
|
+
def country(locale = nil)
|
8
|
+
@country ||= Contentful::Locale.new(fields(locale)[:country])
|
9
|
+
end
|
18
10
|
end
|
19
11
|
|
20
|
-
res = MyResource.new(
|
12
|
+
res = MyResource.new('fields' => {
|
21
13
|
'some' => 'value',
|
22
14
|
'age' => '25',
|
23
15
|
'country' => { 'code' => 'de', 'name' => 'Deutschland' },
|
24
16
|
'unknown_property' => 'ignored'
|
25
|
-
)
|
17
|
+
})
|
26
18
|
|
27
19
|
p res.some # => "value"
|
28
20
|
p res.age # => 25
|
29
21
|
p res.country # #<Contentful::Locale: ...
|
30
22
|
p res.unknown_property # NoMethodError
|
31
23
|
|
32
|
-
#
|
33
|
-
#
|
24
|
+
# To then have it mapped automatically from the client,
|
25
|
+
# upon client instantiation, you set the :entry_mapping for your ContentType.
|
34
26
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
27
|
+
client = Contentful::Client.new(
|
28
|
+
space: 'your_space_id',
|
29
|
+
access_token: 'your_access_token',
|
30
|
+
entry_mapping: {
|
31
|
+
'myResource' => MyResource
|
32
|
+
}
|
33
|
+
)
|
41
34
|
|
42
|
-
#
|
35
|
+
# We request the entries, entries of the 'myResource` content type,
|
36
|
+
# will return MyResource class objects, while others will remain Contentful::Entry.
|
37
|
+
client.entries.each { |e| puts e }
|
38
|
+
# => <Contentful::Entry[other_content_type] id='foobar'>
|
39
|
+
# => <MyResource[myResource] id='baz'>
|
data/examples/raise_errors.rb
CHANGED
@@ -6,7 +6,7 @@ client = Contentful::Client.new(
|
|
6
6
|
)
|
7
7
|
|
8
8
|
begin
|
9
|
-
p client.
|
9
|
+
p client.asset 'not found'
|
10
10
|
rescue => error
|
11
11
|
p error
|
12
12
|
end
|
@@ -17,4 +17,4 @@ client2 = Contentful::Client.new(
|
|
17
17
|
raise_errors: false,
|
18
18
|
)
|
19
19
|
|
20
|
-
p client2.
|
20
|
+
p client2.asset 'not found'
|
data/lib/contentful.rb
CHANGED
data/lib/contentful/array.rb
CHANGED
@@ -1,35 +1,43 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
1
|
+
require_relative 'base_resource'
|
2
|
+
require_relative 'array_like'
|
3
3
|
|
4
4
|
module Contentful
|
5
5
|
# Resource Class for Arrays (e.g. search results)
|
6
6
|
# @see _ https://www.contentful.com/developers/documentation/content-delivery-api/#arrays
|
7
7
|
# @note It also provides an #each method and includes Ruby's Enumerable module (gives you methods like #min, #first, etc)
|
8
|
-
class Array
|
8
|
+
class Array < BaseResource
|
9
9
|
# @private
|
10
10
|
DEFAULT_LIMIT = 100
|
11
11
|
|
12
|
-
include Contentful::
|
13
|
-
include Contentful::Resource::SystemProperties
|
14
|
-
include Contentful::Resource::ArrayLike
|
12
|
+
include Contentful::ArrayLike
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
attr_reader :total, :limit, :skip, :items, :endpoint
|
15
|
+
|
16
|
+
def initialize(item = nil,
|
17
|
+
default_locale = Contentful::Client::DEFAULT_CONFIGURATION[:default_locale],
|
18
|
+
endpoint = '', *)
|
19
|
+
super(item, { default_locale: default_locale })
|
20
|
+
|
21
|
+
@endpoint = endpoint
|
22
|
+
@total = item.fetch('total', nil)
|
23
|
+
@limit = item.fetch('limit', nil)
|
24
|
+
@skip = item.fetch('skip', nil)
|
25
|
+
@items = item.fetch('items', [])
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def inspect
|
30
|
+
"<#{repr_name} total=#{total} skip=#{skip} limit=#{limit}>"
|
31
|
+
end
|
20
32
|
|
21
33
|
# Simplifies pagination
|
22
34
|
#
|
23
35
|
# @return [Contentful::Array, false]
|
24
|
-
def next_page
|
25
|
-
if
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
new_request.get
|
30
|
-
else
|
31
|
-
false
|
32
|
-
end
|
36
|
+
def next_page(client = nil)
|
37
|
+
return false if client.nil?
|
38
|
+
|
39
|
+
new_skip = (skip || 0) + (limit || DEFAULT_LIMIT)
|
40
|
+
client.send(endpoint.delete('/'), limit: limit, skip: new_skip)
|
33
41
|
end
|
34
42
|
end
|
35
43
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Contentful
|
2
|
+
# Useful methods for array-like resources that can be included if an
|
3
|
+
# :items property exists
|
4
|
+
module ArrayLike
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# Returns true for array-like resources
|
8
|
+
#
|
9
|
+
# @return [true]
|
10
|
+
def array?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
# Delegates to items#each
|
15
|
+
#
|
16
|
+
# @yield [Contentful::Entry, Contentful::Asset]
|
17
|
+
def each_item(&block)
|
18
|
+
items.each(&block)
|
19
|
+
end
|
20
|
+
alias each each_item
|
21
|
+
|
22
|
+
# Delegates to items#empty?
|
23
|
+
#
|
24
|
+
# @return [Boolean]
|
25
|
+
def empty?
|
26
|
+
items.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Delegetes to items#size
|
30
|
+
#
|
31
|
+
# @return [Number]
|
32
|
+
def size
|
33
|
+
items.size
|
34
|
+
end
|
35
|
+
alias length size
|
36
|
+
|
37
|
+
# Delegates to items#[]
|
38
|
+
#
|
39
|
+
# @return [Contentful::Entry, Contentful::Asset]
|
40
|
+
def [](index)
|
41
|
+
items[index]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Delegates to items#last
|
45
|
+
#
|
46
|
+
# @return [Contentful::Entry, Contentful::Asset]
|
47
|
+
def last
|
48
|
+
items.last
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/contentful/asset.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
1
|
+
require_relative 'fields_resource'
|
2
|
+
require_relative 'file'
|
3
3
|
|
4
4
|
module Contentful
|
5
5
|
# Resource class for Asset.
|
6
6
|
# https://www.contentful.com/developers/documentation/content-delivery-api/#assets
|
7
|
-
class Asset
|
8
|
-
include Contentful::Resource
|
9
|
-
include Contentful::Resource::SystemProperties
|
10
|
-
include Contentful::Resource::AssetFields
|
11
|
-
|
7
|
+
class Asset < FieldsResource
|
12
8
|
# @private
|
13
9
|
def marshal_dump
|
14
10
|
raw
|
@@ -16,10 +12,20 @@ module Contentful
|
|
16
12
|
|
17
13
|
# @private
|
18
14
|
def marshal_load(raw_object)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
super(raw_object)
|
16
|
+
create_files!
|
17
|
+
define_asset_methods!
|
18
|
+
end
|
19
|
+
|
20
|
+
# @private
|
21
|
+
def inspect
|
22
|
+
"<#{repr_name} id='#{sys[:id]}' url='#{url}'>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(*)
|
26
|
+
super
|
27
|
+
create_files!
|
28
|
+
define_asset_methods!
|
23
29
|
end
|
24
30
|
|
25
31
|
# Generates a URL for the Contentful Image API
|
@@ -54,5 +60,31 @@ module Contentful
|
|
54
60
|
end
|
55
61
|
|
56
62
|
alias url image_url
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def create_files!
|
67
|
+
file_json = fields[:file]
|
68
|
+
return if file_json.nil?
|
69
|
+
|
70
|
+
is_localized = file_json.keys.none? { |f| %w(fileName contentType details url).include? f }
|
71
|
+
if is_localized
|
72
|
+
locales.each do |locale|
|
73
|
+
fields(locale)[:file] = ::Contentful::File.new(file_json[locale.to_s] || {})
|
74
|
+
end
|
75
|
+
else
|
76
|
+
fields[:file] = ::Contentful::File.new(file_json)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def define_asset_methods!
|
81
|
+
define_singleton_method :description do
|
82
|
+
fields.fetch(:description, nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
define_singleton_method :file do |wanted_locale = nil|
|
86
|
+
fields(wanted_locale)[:file]
|
87
|
+
end
|
88
|
+
end
|
57
89
|
end
|
58
90
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require_relative 'support'
|
2
|
+
|
3
|
+
module Contentful
|
4
|
+
# Base definition of a Contentful Resource containing Sys properties
|
5
|
+
class BaseResource
|
6
|
+
attr_reader :raw, :default_locale, :sys
|
7
|
+
|
8
|
+
def initialize(item, configuration = {}, _localized = false, _includes = [], depth = 0)
|
9
|
+
@raw = item
|
10
|
+
@default_locale = configuration[:default_locale]
|
11
|
+
@depth = depth
|
12
|
+
@sys = hydrate_sys
|
13
|
+
@configuration = configuration
|
14
|
+
|
15
|
+
define_sys_methods!
|
16
|
+
end
|
17
|
+
|
18
|
+
# @private
|
19
|
+
def inspect
|
20
|
+
"<#{repr_name} id='#{sys[:id]}'>"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Definition of equality
|
24
|
+
def ==(other)
|
25
|
+
self.class == other.class && sys[:id] == other.sys[:id]
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def marshal_dump
|
30
|
+
raw
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def marshal_load(raw_object)
|
35
|
+
@raw = raw_object
|
36
|
+
@sys = hydrate_sys
|
37
|
+
@depth = 0
|
38
|
+
define_sys_methods!
|
39
|
+
end
|
40
|
+
|
41
|
+
# Issues the request that was made to fetch this response again.
|
42
|
+
# Only works for Entry, Asset, ContentType and Space
|
43
|
+
def reload(client = nil)
|
44
|
+
return client.send(Support.snakify(self.class.name.split('::').last), id) unless client.nil?
|
45
|
+
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def define_sys_methods!
|
52
|
+
@sys.each do |k, v|
|
53
|
+
define_singleton_method k do
|
54
|
+
v
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def hydrate_sys
|
60
|
+
result = {}
|
61
|
+
raw.fetch('sys', {}).each do |k, v|
|
62
|
+
if %w(space contentType).include?(k)
|
63
|
+
v = build_link(v)
|
64
|
+
elsif %w(createdAt updatedAt deletedAt).include?(k)
|
65
|
+
v = DateTime.parse(v)
|
66
|
+
end
|
67
|
+
result[Support.snakify(k).to_sym] = v
|
68
|
+
end
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def repr_name
|
75
|
+
self.class
|
76
|
+
end
|
77
|
+
|
78
|
+
def internal_resource_locale
|
79
|
+
sys.fetch(:locale, nil) || default_locale
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_link(item)
|
83
|
+
require_relative 'link'
|
84
|
+
::Contentful::Link.new(item)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|