sunil 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/gem-push.yml +33 -0
  3. data/.gitignore +12 -0
  4. data/.talismanrc +1 -0
  5. data/.yardopts +6 -0
  6. data/CHANGELOG.md +79 -0
  7. data/CODEOWNERS +1 -0
  8. data/CODE_OF_CONDUCT.md +73 -0
  9. data/Gemfile +3 -0
  10. data/Gemfile.lock +77 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +197 -0
  13. data/SECURITY.md +27 -0
  14. data/lib/contentstack/api.rb +191 -0
  15. data/lib/contentstack/asset.rb +69 -0
  16. data/lib/contentstack/asset_collection.rb +28 -0
  17. data/lib/contentstack/client.rb +92 -0
  18. data/lib/contentstack/content_type.rb +54 -0
  19. data/lib/contentstack/entry.rb +222 -0
  20. data/lib/contentstack/entry_collection.rb +45 -0
  21. data/lib/contentstack/error.rb +7 -0
  22. data/lib/contentstack/query.rb +654 -0
  23. data/lib/contentstack/region.rb +6 -0
  24. data/lib/contentstack/sync_result.rb +30 -0
  25. data/lib/contentstack/version.rb +3 -0
  26. data/lib/contentstack.rb +32 -0
  27. data/lib/util.rb +111 -0
  28. data/rakefile.rb +4 -0
  29. data/spec/asset_collection_spec.rb +16 -0
  30. data/spec/asset_spec.rb +48 -0
  31. data/spec/content_type_spec.rb +81 -0
  32. data/spec/contentstack_spec.rb +39 -0
  33. data/spec/entry_collection_spec.rb +42 -0
  34. data/spec/entry_spec.rb +102 -0
  35. data/spec/fixtures/asset.json +1 -0
  36. data/spec/fixtures/asset_collection.json +1 -0
  37. data/spec/fixtures/category_content_type.json +1 -0
  38. data/spec/fixtures/category_entry.json +1 -0
  39. data/spec/fixtures/category_entry_collection.json +1 -0
  40. data/spec/fixtures/category_entry_collection_without_count.json +1 -0
  41. data/spec/fixtures/content_types.json +1 -0
  42. data/spec/fixtures/product_entry.json +1 -0
  43. data/spec/fixtures/product_entry_collection.json +1 -0
  44. data/spec/fixtures/sync_init.json +2975 -0
  45. data/spec/query_spec.rb +206 -0
  46. data/spec/spec_helper.rb +181 -0
  47. data/spec/sync_spec.rb +27 -0
  48. data/sunil.gemspec +30 -0
  49. metadata +186 -0
@@ -0,0 +1,191 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'active_support'
4
+ require 'active_support/json'
5
+ require 'open-uri'
6
+ require 'util'
7
+ module Contentstack
8
+ class API
9
+ using Utility
10
+ def self.init_api(api_key, delivery_token, environment, host, branch, live_preview, proxy, retry_options)
11
+ @host = host
12
+ @api_version = '/v3'
13
+ @environment = environment
14
+ @api_key = api_key
15
+ @access_token = delivery_token
16
+ @branch = branch
17
+ @headers = {environment: @environment}
18
+ @live_preview = live_preview
19
+ @proxy_details = proxy
20
+ @timeout = retry_options["timeout"]
21
+ @retryDelay = retry_options["retryDelay"]
22
+ @retryLimit = retry_options["retryLimit"]
23
+ @errorRetry = retry_options["errorRetry"]
24
+ end
25
+
26
+ def self.live_preview_query(query= {})
27
+ @live_preview[:content_type_uid] = query[:content_type_uid] || query["content_type_uid"]
28
+ @live_preview[:live_preview] = query[:live_preview] || query["live_preview"]
29
+ @live_preview[:entry_uid] = query[:entry_uid] || query["entry_uid"]
30
+ if @live_preview[:content_type_uid].present? && @live_preview[:entry_uid].present?
31
+ path = "/content_types/#{@live_preview[:content_type_uid]}/entries/#{@live_preview[:entry_uid]}"
32
+ @live_preview_response = send_preview_request(path)
33
+ end
34
+ end
35
+
36
+ def self.fetch_content_types(uid="")
37
+ if !uid.nil? && !uid.empty?
38
+ path = "/content_types/#{uid}"
39
+ else
40
+ path = "/content_types"
41
+ end
42
+ fetch_retry(path, {})
43
+ end
44
+
45
+ def self.fetch_entries(content_type, query)
46
+ if @live_preview[:enable] && @live_preview[:content_type_uid] == content_type
47
+ path = "/content_types/#{content_type}/entries"
48
+ send_preview_request(path, query)
49
+ else
50
+ path = "/content_types/#{content_type}/entries"
51
+ fetch_retry(path, query)
52
+ end
53
+ end
54
+
55
+ def self.fetch_entry(content_type, entry_uid, query)
56
+ if @live_preview[:enable] && @live_preview[:content_type_uid] == content_type
57
+ path = "/content_types/#{content_type}/entries/#{entry_uid}"
58
+ send_preview_request(path, query)
59
+ else
60
+ path = "/content_types/#{content_type}/entries/#{entry_uid}"
61
+ fetch_retry(path, query)
62
+ end
63
+ end
64
+
65
+ def self.get_assets(asset_uid=nil)
66
+ path = "/assets"
67
+ path += "/#{asset_uid}" if !asset_uid.nil?
68
+ fetch_retry(path)
69
+ end
70
+
71
+ def self.get_sync_items(query)
72
+ path = "/stacks/sync"
73
+ fetch_retry(path, query)
74
+ end
75
+
76
+ private
77
+ def self.fetch_retry(path, query=nil, count=0)
78
+ response = send_request(path, query)
79
+ if @errorRetry.include?(response["status_code"].to_i)
80
+ if count < @retryLimit
81
+ retryDelay_in_seconds = @retryDelay / 1000 #converting retry_delay from milliseconds into seconds
82
+ sleep(retryDelay_in_seconds.to_i) #sleep method requires time in seconds as parameter
83
+ response = fetch_retry(path, query, (count + 1))
84
+ else
85
+ raise Contentstack::Error.new(response) #Retry Limit exceeded
86
+ end
87
+ else
88
+ to_render_content(response)
89
+ end
90
+ end
91
+
92
+ def self.send_request(path, q=nil)
93
+ q ||= {}
94
+
95
+ q.merge!(@headers)
96
+
97
+ query = "?" + q.to_query
98
+ # puts "Request URL:- #{@host}#{@api_version}#{path}#{query} \n\n"
99
+ params = {
100
+ "api_key" => @api_key,
101
+ "access_token"=> @access_token,
102
+ "user_agent"=> "ruby-sdk/#{Contentstack::VERSION}",
103
+ "x-user-agent" => "ruby-sdk/#{Contentstack::VERSION}",
104
+ "read_timeout" => @timeout
105
+ }
106
+ if !@branch.nil? && !@branch.empty?
107
+ params["branch"] = @branch
108
+ end
109
+
110
+ if @proxy_details.present? && @proxy_details[:url].present? && @proxy_details[:port].present? && @proxy_details[:username].empty? && @proxy_details[:password].empty?
111
+ params["proxy"] = URI.parse("http://#{@proxy_details[:url]}:#{@proxy_details[:port]}/").to_s
112
+ end
113
+
114
+ if @proxy_details.present? && @proxy_details[:url].present? && @proxy_details[:port].present? && @proxy_details[:username].present? && @proxy_details[:password].present?
115
+ proxy_uri = URI.parse("http://#{@proxy_details[:url]}:#{@proxy_details[:port]}/").to_s
116
+ params[:proxy_http_basic_authentication] = [proxy_uri, @proxy_details[:username], @proxy_details[:password]]
117
+ end
118
+
119
+ begin
120
+ ActiveSupport::JSON.decode(URI.open("#{@host}#{@api_version}#{path}#{query}", params).read)
121
+ rescue OpenURI::HTTPError => error
122
+ response = error.io
123
+ #response.status
124
+ # => ["503", "Service Unavailable"]
125
+ error_response = JSON.parse(response.string)
126
+ error_status = {"status_code" => response.status[0], "status_message" => response.status[1]}
127
+ error = error_response.merge(error_status)
128
+ raise Contentstack::Error.new(error.to_s)
129
+ end
130
+ end
131
+
132
+ def self.send_preview_request(path, q=nil)
133
+ q ||= {}
134
+
135
+ q.merge!({live_preview: (!@live_preview.key?(:live_preview) ? 'init' : @live_preview[:live_preview]),})
136
+
137
+ query = "?" + q.to_query
138
+ preview_host = @live_preview[:host]
139
+ params = {
140
+ "api_key" => @api_key,
141
+ "authorization" => @live_preview[:management_token],
142
+ "user_agent"=> "ruby-sdk/#{Contentstack::VERSION}",
143
+ "x-user-agent" => "ruby-sdk/#{Contentstack::VERSION}",
144
+ "read_timeout" => @timeout
145
+ }
146
+ if !@branch.nil? && !@branch.empty?
147
+ params["branch"] = @branch
148
+ end
149
+
150
+ if @proxy_details.present? && @proxy_details[:url].present? && @proxy_details[:port].present? && @proxy_details[:username].empty? && @proxy_details[:password].empty?
151
+ params["proxy"] = URI.parse("http://#{@proxy_details[:url]}:#{@proxy_details[:port]}/").to_s
152
+ end
153
+
154
+ if @proxy_details.present? && @proxy_details[:url].present? && @proxy_details[:port].present? && @proxy_details[:username].present? && @proxy_details[:password].present?
155
+ proxy_uri = URI.parse("http://#{@proxy_details[:url]}:#{@proxy_details[:port]}/").to_s
156
+ params[:proxy_http_basic_authentication] = [proxy_uri, @proxy_details[:username], @proxy_details[:password]]
157
+ end
158
+
159
+ begin
160
+ ActiveSupport::JSON.decode(URI.open("#{preview_host}#{@api_version}#{path}#{query}",params).read)
161
+ rescue OpenURI::HTTPError => error
162
+ response = error.io
163
+ #response.status
164
+ # => ["503", "Service Unavailable"]
165
+ error_response = JSON.parse(response.string)
166
+ error_status = {"status_code" => response.status[0], "status_message" => response.status[1]}
167
+ error = error_response.merge(error_status)
168
+ raise Contentstack::Error.new(error.to_s)
169
+ end
170
+ end
171
+
172
+ def self.to_render_content(resp)
173
+ if resp.class == Hash
174
+ if resp.key?('uid') && resp['uid'] == @live_preview[:entry_uid]
175
+ resp = resp.merge(@live_preview_response)
176
+ else
177
+ resp_keys = resp.keys
178
+ resp_keys.each {|key|
179
+ resp[key] = to_render_content(resp[key])
180
+ }
181
+ end
182
+ elsif resp.class == Array
183
+ resp.each_with_index {|value, index|
184
+ resp[index] = to_render_content(value)
185
+ }
186
+ end
187
+ resp
188
+ end
189
+
190
+ end
191
+ end
@@ -0,0 +1,69 @@
1
+ require 'util'
2
+ module Contentstack
3
+
4
+ # Asset class to fetch file details on Conentstack server.
5
+ class Asset
6
+ using Utility
7
+ attr_reader :uid, :content_type, :filename, :file_size, :tags, :url
8
+
9
+ # @!attribute [r] uid
10
+ # Contentstack Asset UID for this asset
11
+
12
+ # @!attribute [r] content_type
13
+ # Content Type for the asset. image/png, image/jpeg, application/pdf, video/mp4 etc.
14
+
15
+ # @!attribute [r] filename
16
+ # Name of the asset.
17
+
18
+ # @!attribute [r] file_size
19
+ # Size of the asset.
20
+
21
+ # @!attribute [r] tags
22
+ # Array of tags assigned to the asset.
23
+
24
+ # @!attribute [r] url
25
+ # URL to fetch/render the asset
26
+
27
+ # Create instance of an Asset. Accepts either a uid of asset (String) or a complete asset JSON
28
+ # @param [String/Hash] attrs
29
+ # Usage for String parameter
30
+ # @asset = @stack.asset("some_asset_uid")
31
+ # @asset.fetch
32
+ #
33
+ # Usage for Hash parameter
34
+ # @asset = @stack.asset({
35
+ # :uid => "some_asset_uid",
36
+ # :content_type => "file_type", # image/png, image/jpeg, application/pdf, video/mp4 etc.
37
+ # :filename => "some_file_name",
38
+ # :file_size => "some_file_size",
39
+ # :tags => ["tag1", "tag2", "tag3"],
40
+ # :url => "file_url"
41
+ # })
42
+ # @asset.fetch
43
+ def initialize(attrs)
44
+ if attrs.class == String
45
+ @uid = attrs
46
+ else
47
+ attrs = attrs.symbolize_keys
48
+ @uid = attrs[:uid]
49
+ @content_type = attrs[:content_type]
50
+ @filename = attrs[:filename]
51
+ @file_size = attrs[:file_size]
52
+ @tags = attrs[:tags]
53
+ @url = attrs[:url]
54
+ end
55
+
56
+ self
57
+ end
58
+
59
+ # Fetch a particular asset using uid.
60
+ # @asset = @stack.asset('some_asset_uid')
61
+ # @asset.fetch
62
+ # puts @asset.url
63
+ def fetch
64
+ json = API.get_assets(@uid)
65
+ # puts "json -- #{json}"
66
+ self.class.new(json["asset"])
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,28 @@
1
+ require 'contentstack/asset'
2
+ require 'util'
3
+
4
+ module Contentstack
5
+ # Asset class to fetch details of files on Conentstack server.
6
+ class AssetCollection
7
+ using Utility
8
+ attr_reader :assets
9
+
10
+ def initialize(assets_array=nil)
11
+ if assets_array.nil?
12
+ @assets = []
13
+ return self
14
+ else
15
+ @assets = assets_array.collect{|a| Asset.new(a)}
16
+ end
17
+ end
18
+
19
+ # Fetch assets uploaded to Contentstack
20
+ #
21
+ # Example:
22
+ # @assets = @stack.assets.fetch
23
+ def fetch
24
+ json = API.get_assets
25
+ self.class.new(json["assets"])
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,92 @@
1
+ require 'contentstack/api'
2
+ require 'contentstack/content_type'
3
+ require 'contentstack/asset_collection'
4
+ require 'contentstack/sync_result'
5
+ require 'util'
6
+ require 'contentstack/error'
7
+ module Contentstack
8
+ class Client
9
+ using Utility
10
+ attr_reader :region, :host
11
+ # Initialize "Contentstack" Client instance
12
+ def initialize(api_key, delivery_token, environment, options={})
13
+ raise Contentstack::Error.new("Api Key is not valid") if api_key.class != String
14
+ raise Contentstack::Error.new("Api Key Field Should not be Empty") if api_key.empty?
15
+ raise Contentstack::Error.new("Delivery Token is not valid") if delivery_token.class != String
16
+ raise Contentstack::Error.new("Delivery Token Field Should not be Empty") if delivery_token.empty?
17
+ raise Contentstack::Error.new("Envirnoment Field is not valid") if environment.class != String
18
+ raise Contentstack::Error.new("Envirnoment Field Should not be Empty") if environment.empty?
19
+ @region = options[:region].nil? ? Contentstack::Region::US : options[:region]
20
+ @host = options[:host].nil? ? get_default_region_hosts(@region) : options[:host]
21
+ @live_preview = !options.key?(:live_preview) ? {} : options[:live_preview]
22
+ @branch = options[:branch].nil? ? "" : options[:branch]
23
+ @proxy_details = options[:proxy].nil? ? "" : options[:proxy]
24
+ @timeout = options[:timeout].nil? ? 3000 : options[:timeout]
25
+ @retryDelay = options[:retryDelay].nil? ? 3000 : options[:retryDelay]
26
+ @retryLimit = options[:retryLimit].nil? ? 5 : options[:retryLimit]
27
+ @errorRetry = options[:errorRetry].nil? ? [408, 429] : options[:errorRetry]
28
+ retry_options = {
29
+ "timeout" => @timeout.to_s,
30
+ "retryDelay"=> @retryDelay,
31
+ "retryLimit"=> @retryLimit,
32
+ "errorRetry" => @errorRetry
33
+ }
34
+ raise Contentstack::Error.new("Proxy URL Should not be Empty") if @proxy_details.present? && @proxy_details[:url].empty?
35
+ raise Contentstack::Error.new("Proxy Port Should not be Empty") if @proxy_details.present? && @proxy_details[:port].empty?
36
+ API.init_api(api_key, delivery_token, environment, @host, @branch, @live_preview, @proxy_details, retry_options)
37
+ end
38
+
39
+ def content_types
40
+ ContentType.all
41
+ end
42
+
43
+ def content_type(uid)
44
+ ContentType.new({uid: uid})
45
+ end
46
+
47
+ def assets
48
+ AssetCollection.new
49
+ end
50
+
51
+ def asset(uid)
52
+ Asset.new(uid)
53
+ end
54
+
55
+ def live_preview_query(query={})
56
+ API.live_preview_query(query)
57
+ end
58
+
59
+ # Syncs your Contentstack data with your app and ensures that the data is always up-to-date by providing delta updates
60
+ #
61
+ # Stack.sync({'init': true}) // For initializing sync
62
+ #
63
+ # Stack.sync({'init': true, 'locale': 'en-us'}) //For initializing sync with entries of a specific locale
64
+ #
65
+ # Stack.sync({'init': true, 'start_date': '2018-10-22'}) //For initializing sync with entries published after a specific date
66
+ #
67
+ # Stack.sync({'init': true, 'content_type_uid': 'session'}) //For initializing sync with entries of a specific content type
68
+ #
69
+ # Stack.sync({'init': true, 'type': 'entry_published'}) // Use the type parameter to get a specific type of content.Supports 'asset_published', 'entry_published', 'asset_unpublished', 'entry_unpublished', 'asset_deleted', 'entry_deleted', 'content_type_deleted'.
70
+ #
71
+ # Stack.sync({'pagination_token': '<pagination>'}) // For fetching the next batch of entries using pagination token
72
+ #
73
+ # Stack.sync({'sync_token': '<sync>'}) // For performing subsequent sync after initial sync
74
+ #
75
+ # @param params [Hash] params is an object that supports ‘locale’, ‘start_date’, ‘content_type_uid’, and ‘type’ queries.
76
+ def sync(params)
77
+ sync_result = API.get_sync_items(params)
78
+ SyncResult.new(sync_result)
79
+ end
80
+
81
+ private
82
+ def get_default_region_hosts(region='us')
83
+ case region
84
+ when "us"
85
+ host = "https://cdn.contentstack.io"
86
+ when "eu"
87
+ host = "https://eu-cdn.contentstack.com"
88
+ end
89
+ host
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,54 @@
1
+ require 'contentstack/query'
2
+ require 'util'
3
+
4
+ module Contentstack
5
+ class ContentType
6
+ using Utility
7
+ [:title, :uid, :created_at, :updated_at, :attributes].each do |method_name|
8
+ if [:created_at, :updated_at].include?(method_name)
9
+ define_method method_name do
10
+ return Time.parse(@attributes[method_name]) if @attributes[method_name] && !@attributes[method_name].nil?
11
+ end
12
+ elsif :attributes == method_name
13
+ define_method :attributes do
14
+ {
15
+ title: self.title,
16
+ uid: self.uid,
17
+ created_at: self.created_at,
18
+ updated_at: self.updated_at,
19
+ schema: @attributes[:schema]
20
+ }
21
+ end
22
+ else
23
+ define_method method_name do
24
+ return @attributes[method_name]
25
+ end
26
+ end
27
+ end
28
+
29
+ def initialize(object)
30
+ @attributes = object.symbolize_keys
31
+ end
32
+
33
+ def query
34
+ Query.new(self.uid)
35
+ end
36
+
37
+ def entry(entry_uid)
38
+ Entry.new({uid: entry_uid}, self.uid)
39
+ end
40
+
41
+
42
+ def self.all
43
+ content_types = API.fetch_content_types["content_types"]
44
+ content_types.map do |content_type|
45
+ ContentType.new(content_type.inject({}){|clone,(k,v)| clone[k.to_sym] = v; clone})
46
+ end
47
+ end
48
+
49
+ def fetch
50
+ content_type = API.fetch_content_types(uid)["content_type"]
51
+ ContentType.new(content_type.inject({}){|clone,(k,v)| clone[k.to_sym] = v; clone})
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,222 @@
1
+ require 'active_support/core_ext'
2
+ require 'util'
3
+
4
+ module Contentstack
5
+ class Entry
6
+ using Utility
7
+ attr_reader :fields, :content_type, :uid, :owner, :query, :schema, :content_type
8
+ def initialize(attrs, content_type_uid=nil)
9
+ setup(attrs, content_type_uid)
10
+ end
11
+
12
+ # Get entries from the specified locale.
13
+ #
14
+ # @param [String] code The locale code of the entry
15
+ #
16
+ # Example
17
+ # @entry = @stack.content_type('category').entry(entry_uid)
18
+ # @entry.locale('en-us')
19
+ #
20
+ # @return [Contentstack::Entry]
21
+ def locale(code)
22
+ @query[:locale] = code
23
+ self
24
+ end
25
+
26
+ # Specifies an array of 'only' keys in BASE object that would be 'included' in the response.
27
+ #
28
+ # @param [Array] fields Array of the 'only' reference keys to be included in response.
29
+ # @param [Array] fields_with_base Can be used to denote 'only' fields of the reference class
30
+ #
31
+ # Example
32
+ # # Include only title and description field in response
33
+ # @entry = @stack.content_type('category').entry(entry_uid)
34
+ # @entry.only(['title', 'description'])
35
+ #
36
+ # # Query product and include only the title and description from category reference
37
+ # @entry = @stack.content_type('product').entry(entry_uid)
38
+ # @entry.include_reference('category')
39
+ # .only('category', ['title', 'description'])
40
+ #
41
+ # @return [Contentstack::Entry]
42
+ def only(fields, fields_with_base=nil)
43
+ q = {}
44
+ if [Array, String].include?(fields_with_base.class)
45
+ fields_with_base = [fields_with_base] if fields_with_base.class == String
46
+ q[fields.to_sym] = fields_with_base
47
+ else
48
+ fields = [fields] if fields.class == String
49
+ q = {BASE: fields}
50
+ end
51
+
52
+ @query[:only] = q
53
+ self
54
+ end
55
+
56
+ # Specifies list of field uids that would be 'excluded' from the response.
57
+ #
58
+ # @param [Array] fields Array of field uid which get 'excluded' from the response.
59
+ # @param [Array] fields_with_base Can be used to denote 'except' fields of the reference class
60
+ #
61
+ # Example
62
+ # # Exclude 'description' field in response
63
+ # @entry = @stack.content_type('category').entry(entry_uid)
64
+ # @entry.except(['description'])
65
+ #
66
+ # # Query product and exclude the 'description' from category reference
67
+ # @entry = @stack.content_type('product').entry(entry_uid)
68
+ # @entry.include_reference('category')
69
+ # .except('category', ['description'])
70
+ #
71
+ # @return [Contentstack::Entry]
72
+ def except(fields, fields_with_base=nil)
73
+ q = {}
74
+ if [Array, String].include?(fields_with_base.class)
75
+ fields_with_base = [fields_with_base] if fields_with_base.class == String
76
+ q[fields.to_sym] = fields_with_base
77
+ else
78
+ fields = [fields] if fields.class == String
79
+ q = {BASE: fields}
80
+ end
81
+
82
+ @query[:except] = q
83
+ self
84
+ end
85
+
86
+ # Add a constraint that requires a particular reference key details.
87
+ #
88
+ # @param [String/Array] reference_field_uids Pass string or array of reference fields that must be included in the response
89
+ #
90
+ # Example
91
+ #
92
+ # # Include reference of 'category'
93
+ # @entry = @stack.content_type('product').entry(entry_uid)
94
+ # @entry.include_reference('category')
95
+ #
96
+ # # Include reference of 'category' and 'reviews'
97
+ # @entry = @stack.content_type('product').entry(entry_uid)
98
+ # @entry.include_reference(['category', 'reviews'])
99
+ #
100
+ # @return [Contentstack::Entry]
101
+ def include_reference(reference_field_uids)
102
+ self.include(reference_field_uids)
103
+ end
104
+
105
+ # Include schemas of all returned objects along with objects themselves.
106
+ #
107
+ # Example
108
+ #
109
+ # @entry = @stack.content_type('product').entry(entry_uid)
110
+ # @entry.include_schema
111
+ #
112
+ # @return [Contentstack::Entry]
113
+ def include_schema(flag=true)
114
+ @query[:include_schema] = flag
115
+ self
116
+ end
117
+
118
+ # Include object owner's profile in the objects data.
119
+ #
120
+ # Example
121
+ #
122
+ # @entry = @stack.content_type('product').entry(entry_uid)
123
+ # @entry.include_owner
124
+ #
125
+ # @return [Contentstack::Entry]
126
+ def include_owner(flag=true)
127
+ @query[:include_owner] = flag
128
+ self
129
+ end
130
+
131
+ # Include object's content_type in response
132
+ #
133
+ # Example
134
+ #
135
+ # @entry = @stack.content_type('product').entry(entry_uid)
136
+ # @entry.include_content_type
137
+ #
138
+ # @return [Contentstack::Entry]
139
+ def include_content_type(flag=true)
140
+ @query[:include_content_type] = flag
141
+ self
142
+ end
143
+
144
+ # Include the fallback locale publish content, if specified locale content is not publish.
145
+ #
146
+ # Example
147
+ #
148
+ # @entry = @stack.content_type('product').entry(entry_uid)
149
+ # @entry.include_fallback
150
+ #
151
+ # @return [Contentstack::Entry]
152
+ def include_fallback(flag=true)
153
+ @query[:include_fallback] = flag
154
+ self
155
+ end
156
+
157
+ # Include the branch for publish content.
158
+ #
159
+ # Example
160
+ #
161
+ # @entry = @stack.content_type('product').entry(entry_uid)
162
+ # @entry.include_branch
163
+ #
164
+ # @return [Contentstack::Entry]
165
+ def include_branch(flag=true)
166
+ @query[:include_branch] = flag
167
+ self
168
+ end
169
+
170
+ # Include Embedded Objects (Entries and Assets) along with entry/entries details.
171
+ #
172
+ # Example
173
+ #
174
+ # @entry = @stack.content_type('product').entry(entry_uid)
175
+ # @entry.include_embedded_items
176
+ #
177
+ # @return [Contentstack::Query]
178
+ def include_embedded_items()
179
+ @query[:include_embedded_items] = ['BASE']
180
+ self
181
+ end
182
+
183
+ #
184
+ # @return [Contentstack::Query]
185
+ def include(field_uids)
186
+ field_uids = [field_uids] if field_uids.class == String
187
+ @query[:include] ||= []
188
+ @query[:include] = @query[:include] | field_uids
189
+ self
190
+ end
191
+
192
+ # Execute entry
193
+ #
194
+ # Example
195
+ #
196
+ # @entry = @stack.content_type('product').entry(entry_uid)
197
+ # @entry.fetch
198
+ #
199
+ # @return [Contentstack::EntryCollection]
200
+ def fetch
201
+ entry = API.fetch_entry(@content_type, self.fields[:uid], @query)
202
+ setup(entry["entry"])
203
+ @schema = entry["schema"].symbolize_keys if entry["schema"]
204
+ @content_type = entry["content_type"].symbolize_keys if entry["content_type"]
205
+ self
206
+ end
207
+
208
+ def get(field_uid)
209
+ raise Contentstack::Error("Please send a valid Field UID") if field_uid.class != String
210
+ @fields[field_uid.to_sym]
211
+ end
212
+
213
+ private
214
+ def setup(attrs, content_type_uid=nil)
215
+ @fields = attrs.symbolize_keys
216
+ @content_type = content_type_uid if !content_type_uid.blank?
217
+ @owner = attrs[:_owner] if attrs[:_owner]
218
+ @uid = attrs[:uid]
219
+ @query = {}
220
+ end
221
+ end
222
+ end