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