scrivito_sdk 1.0.0 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/README.md +1 -1
  4. data/app/controllers/scrivito/legacy_redirect_controller.rb +11 -0
  5. data/app/controllers/scrivito/objs_controller.rb +15 -5
  6. data/app/controllers/scrivito/webservice_controller.rb +4 -3
  7. data/app/controllers/scrivito/workspaces_controller.rb +24 -29
  8. data/app/helpers/scrivito_helper.rb +82 -37
  9. data/app/views/scrivito/objs/binary_no_cache.json.jbuilder +1 -0
  10. data/app/views/scrivito/objs/search.json.jbuilder +5 -5
  11. data/app/views/scrivito/webservice/error.json.jbuilder +2 -2
  12. data/config/ca-bundle.crt +1 -1
  13. data/config/precedence_routes.rb +51 -48
  14. data/config/routes.rb +1 -14
  15. data/lib/assets/javascripts/scrivito_ui.js +2447 -266
  16. data/lib/assets/stylesheets/scrivito.css +1 -1
  17. data/lib/assets/stylesheets/scrivito_ui.css +1 -1
  18. data/lib/generators/scrivito/install/install_generator.rb +12 -0
  19. data/lib/generators/scrivito/install/templates/config/initializers/scrivito.rb +3 -0
  20. data/lib/scrivito/attribute_definition.rb +13 -1
  21. data/lib/scrivito/attribute_deserializer.rb +4 -4
  22. data/lib/scrivito/attribute_value_renderer.rb +79 -0
  23. data/lib/scrivito/backend/obj_data_cache.rb +15 -15
  24. data/lib/scrivito/backend/obj_data_from_rest.rb +1 -21
  25. data/lib/scrivito/backend/obj_query.rb +2 -2
  26. data/lib/scrivito/basic_obj.rb +17 -6
  27. data/lib/scrivito/binary.rb +13 -5
  28. data/lib/scrivito/cache/chainable.rb +10 -5
  29. data/lib/scrivito/cache/file_store.rb +4 -0
  30. data/lib/scrivito/cache/ram_store.rb +4 -0
  31. data/lib/scrivito/child_list_tag.rb +16 -14
  32. data/lib/scrivito/client_error.rb +10 -0
  33. data/lib/scrivito/cms_backend.rb +66 -291
  34. data/lib/scrivito/cms_data_cache.rb +7 -9
  35. data/lib/scrivito/cms_dispatch_controller.rb +1 -10
  36. data/lib/scrivito/cms_field_tag.rb +2 -1
  37. data/lib/scrivito/cms_rest_api.rb +2 -0
  38. data/lib/scrivito/cms_routing.rb +26 -22
  39. data/lib/scrivito/configuration.rb +38 -0
  40. data/lib/scrivito/connection_manager.rb +69 -0
  41. data/lib/scrivito/controller_actions.rb +2 -2
  42. data/lib/scrivito/controller_helper.rb +2 -2
  43. data/lib/scrivito/date_attribute.rb +4 -1
  44. data/lib/scrivito/deprecation.rb +5 -4
  45. data/lib/scrivito/editing_context.rb +2 -2
  46. data/lib/scrivito/errors.rb +17 -0
  47. data/lib/scrivito/image_tag.rb +2 -2
  48. data/lib/scrivito/link_parser.rb +10 -5
  49. data/lib/scrivito/meta_data_collection.rb +11 -0
  50. data/lib/scrivito/obj_collection.rb +1 -1
  51. data/lib/scrivito/obj_facet_value.rb +19 -7
  52. data/lib/scrivito/obj_params_parser.rb +43 -14
  53. data/lib/scrivito/obj_search_builder.rb +1 -2
  54. data/lib/scrivito/obj_search_enumerator/batch.rb +22 -0
  55. data/lib/scrivito/obj_search_enumerator/batch_iterator.rb +36 -0
  56. data/lib/scrivito/obj_search_enumerator/query_executor.rb +35 -0
  57. data/lib/scrivito/obj_search_enumerator.rb +218 -93
  58. data/lib/scrivito/obj_update_params_parser.rb +1 -0
  59. data/lib/scrivito/preset_routes.rb +25 -0
  60. data/lib/scrivito/revision.rb +13 -11
  61. data/lib/scrivito/route.rb +62 -0
  62. data/lib/scrivito/routing_extensions.rb +92 -0
  63. data/lib/scrivito/sdk_engine.rb +4 -0
  64. data/lib/scrivito/task.rb +77 -0
  65. data/lib/scrivito/type_computer.rb +3 -3
  66. data/lib/scrivito/ui_config.rb +4 -0
  67. data/lib/scrivito/user.rb +24 -18
  68. data/lib/scrivito/workspace/publish_checker.rb +2 -3
  69. data/lib/scrivito/workspace.rb +38 -6
  70. data/lib/scrivito/workspace_data.rb +0 -14
  71. metadata +14 -10
  72. data/lib/scrivito/content_service.rb +0 -121
  73. data/lib/scrivito/content_state.rb +0 -109
  74. data/lib/scrivito/content_state_caching.rb +0 -47
  75. data/lib/scrivito/content_state_visitor.rb +0 -19
  76. data/lib/scrivito/obj_data_from_service.rb +0 -63
  77. data/lib/scrivito/workspace_data_from_service.rb +0 -43
@@ -0,0 +1,92 @@
1
+ module Scrivito
2
+
3
+ # @api public
4
+ module RoutingExtensions
5
+
6
+ # @api public
7
+ #
8
+ #+scrivito_route+ defines routes for Scrivito pages. The default routes are:
9
+ #
10
+ # scrivito_route '(/)(*slug-):id', using: 'slug_id', via: :all
11
+ # scrivito_route '/', using: 'homepage', via: :all
12
+ # scrivito_route '/*permalink', using: 'permalink', format: false, via: :all
13
+ #
14
+ # The first parameter of +scrivito_route+ should look familiar - it is just a regular
15
+ # Rails route pattern. You can make full use of the Rails route patterns when specifying
16
+ # Scrivito routes.
17
+ #
18
+ # In addition to directing incoming traffic to the code that handles it, Scrivito
19
+ # routes have another distinct functionality: They determine which URL or path is generated
20
+ # for a given CMS object. The +using:+ option needs to be provided to tell Scrivito which
21
+ # route should be used for which type of CMS objects. For example, <code>using:
22
+ # "permalink"</code> instructs Scrivito to use the route for CMS objects to which a
23
+ # +_permalink+ has been assigned. The Scrivito routes expect the route pattern to contain
24
+ # route parameters for dynamically inserting the values for individual CMS objects. If,
25
+ # for example, the permalink of an object is +about+ and the route pattern is
26
+ # +my_page/*permalink+, Scrivito generates the url +http://www.example.com/my_page/about+.
27
+ # Valid +:using+ values and their required route parameters are:
28
+ #
29
+ # [+slug_id+] Route pattern for a normal CMS object. Expected route parameters are +slug+
30
+ # and +id+.
31
+ # [+homepage+] Route pattern for a homepage CMS object. No route parameters needed.
32
+ # [+permalink+] Route pattern for CMS objects that have a +_permalink+ assigned to them. The
33
+ # required route parameter is +permalink+.
34
+ #
35
+ # @example Route that starts with the object ID
36
+ # scrivito_route '(/):id(/*slug)', using: 'slug_id', via: [:get, :post]
37
+ #
38
+ # @example Scoped permalink with disabled format
39
+ # scrivito_route '/pl/*permalink', using: 'permalink', format: false
40
+ #
41
+ # @param path [String] a Rails route pattern
42
+ # @param using [String] The name of the route. Valid values are +slug_id+, +homepage+, and
43
+ # +permalink+.
44
+ # @param format [Boolean] Use +format+ +true+ or +false+ to enforce or disable the format.
45
+ # @param via [Symbol] Use to specify for which HTTP verbs the route should match. +:get+ is
46
+ # the default. Use +:all+ to allow every verb.
47
+ #
48
+ # @note To use +scrivito_route+ {Scrivito::Configuration.inject_preset_routes} needs to be
49
+ # disabled.
50
+ def scrivito_route(path, using:, format: nil, via: :get)
51
+ assert_scrivito_route_enabled
52
+ # @set is a ActionDispatch::Routing::RouteSet
53
+ # see: http://git.io/v4UYF and http://git.io/v4UOI
54
+ route_set = @set
55
+
56
+ route_name = using.to_sym
57
+
58
+ route = Route.register(route_set, route_name)
59
+
60
+ options = {
61
+ to: 'scrivito/cms_dispatch#index',
62
+ via: via,
63
+ format: format,
64
+ as: route.helper_name,
65
+ }
66
+
67
+ options[:constraints] = {id: /[a-z0-9]{16}/} if route_name == :slug_id
68
+
69
+ begin
70
+ match(path, options)
71
+ rescue ArgumentError => error
72
+ if error.message.include?(route.helper_name)
73
+ raise ScrivitoError,
74
+ %(You have already defined a Scrivito route with the name "#{route_name}".)
75
+ else
76
+ raise error
77
+ end
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def assert_scrivito_route_enabled
84
+ unless Scrivito::Configuration.scrivito_route_enabled?
85
+ raise ScrivitoError, 'The preset routes are still enabled. Please disable them by ' \
86
+ 'setting the configuration "inject_preset_routes" to false before using scrivito_route'
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -39,6 +39,10 @@ module ::Scrivito
39
39
  end
40
40
  end
41
41
 
42
+ initializer "scrivito.routing_extensions" do
43
+ ActionDispatch::Routing::Mapper.__send__(:include, Scrivito::RoutingExtensions)
44
+ end
45
+
42
46
  initializer 'scrivito.add_sdk_assets' do |app|
43
47
  # Specify which file should be precompiled for packaging
44
48
  app.config.assets.precompile += %w[
@@ -0,0 +1,77 @@
1
+ module Scrivito
2
+ class Task
3
+ def self.find(id)
4
+ new(id: id)
5
+ end
6
+
7
+ attr_reader :id
8
+
9
+ def initialize(params = nil)
10
+ return update(params) if params
11
+
12
+ response = yield
13
+ if params = extract_params(response)
14
+ update(params)
15
+ else
16
+ update(status: 'success', result: response)
17
+ end
18
+ rescue ClientError => e
19
+ update(status: 'error', message: e.message, code: e.backend_code)
20
+ end
21
+
22
+ def open?
23
+ @status == 'open'
24
+ end
25
+
26
+ def success?
27
+ @status == 'success'
28
+ end
29
+
30
+ def error?
31
+ @status == 'error'
32
+ end
33
+
34
+ def result
35
+ case
36
+ when success? then @result
37
+ when error? then raise ClientError.new(@message, 400, @code)
38
+ else
39
+ poll
40
+ result
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def extract_params(response)
47
+ if response.is_a?(Hash) && response.keys == ['task'] && response['task'].is_a?(Hash)
48
+ response['task']
49
+ end
50
+ end
51
+
52
+ def reload
53
+ task_data = CmsRestApi.task_unaware_request(:get, "tasks/#{@id}")
54
+ update(task_data)
55
+ end
56
+
57
+ def update(task_data)
58
+ task_data = task_data.with_indifferent_access
59
+
60
+ @id = task_data[:id] if task_data[:id]
61
+ @status = task_data[:status] if task_data[:status]
62
+ @result = task_data[:result] if task_data[:result]
63
+ @message = task_data[:message] if task_data[:message]
64
+ @code = task_data[:code] if task_data[:code]
65
+
66
+ reload unless @status
67
+ end
68
+
69
+ def poll
70
+ loop do
71
+ sleep 2
72
+ reload
73
+ break unless open?
74
+ end
75
+ end
76
+ end
77
+ end
@@ -9,11 +9,11 @@ class TypeComputer
9
9
  load_class(obj_class) || @fallback_class
10
10
  end
11
11
 
12
- def compute_type_without_fallback(obj_class)
13
- if obj_class = load_class(obj_class)
12
+ def compute_type_without_fallback(obj_class_name)
13
+ if obj_class = load_class(obj_class_name)
14
14
  obj_class
15
15
  else
16
- raise ObjClassNotFound
16
+ raise ObjClassNotFound, obj_class_name
17
17
  end
18
18
  end
19
19
 
@@ -57,6 +57,10 @@ class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extens
57
57
  def user_permissions_config
58
58
  {
59
59
  create_workspace: editor.can?(:create, :workspace),
60
+ rename_workspace: editor.can?(:write, selected_workspace),
61
+ invite_to_workspace: editor.can?(:invite_to, selected_workspace),
62
+ rebase_workspace: editor.can?(:write, selected_workspace),
63
+ delete_workspace: editor.can?(:delete, selected_workspace),
60
64
  publish_workspace: editor.can?(:publish, selected_workspace),
61
65
  }
62
66
  end
data/lib/scrivito/user.rb CHANGED
@@ -8,12 +8,24 @@ module Scrivito
8
8
  # @api public
9
9
  #
10
10
  VERBS = [
11
+ # Lets the user create new working copies.
11
12
  :create,
13
+
14
+ # Makes the content of the working copy visible to the user.
15
+ :read,
16
+
17
+ # Lets the user modify the content of the working copy.
18
+ # Also lets the user rename the working copy.
19
+ :write,
20
+
21
+ # Permits the user to delete the working copy.
12
22
  :delete,
23
+
24
+ # Permits the user to invite other users to collaborate on the working copy.
13
25
  :invite_to,
26
+
27
+ # Permits the user to publish the working copy.
14
28
  :publish,
15
- :read,
16
- :write,
17
29
  ].freeze
18
30
 
19
31
  class << self
@@ -105,6 +117,7 @@ module Scrivito
105
117
  end
106
118
 
107
119
  def assert_valid_id(id)
120
+ raise ScrivitoError.new('User id must be a string') unless id.to_s == id
108
121
  raise ScrivitoError.new('User id can not be blank') if id.blank?
109
122
  raise ScrivitoError.new('User id is too long (max length 64)') if id.length > 64
110
123
  end
@@ -130,10 +143,15 @@ module Scrivito
130
143
 
131
144
  def can?(verb, workspace)
132
145
  assert_valid_verb(verb)
133
- can_always?(verb, :workspace) ||
134
- verb == :create && can_create? ||
135
- verb == :read && can_read?(workspace) ||
136
- can_as_owner?(verb, workspace)
146
+
147
+ return true if can_always?(verb, :workspace)
148
+ return false if can_never?(verb, :workspace)
149
+
150
+ case verb
151
+ when :create then true
152
+ when :read then workspace.published? || owner_of?(workspace)
153
+ when :write, :delete, :invite_to, :publish then owner_of?(workspace)
154
+ end
137
155
  end
138
156
 
139
157
  def can_always?(verb, subject)
@@ -207,18 +225,6 @@ module Scrivito
207
225
 
208
226
  private
209
227
 
210
- def can_create?
211
- !can_never?(:create, :workspace)
212
- end
213
-
214
- def can_read?(workspace)
215
- workspace.published? || can_as_owner?(:read, workspace)
216
- end
217
-
218
- def can_as_owner?(verb, workspace)
219
- workspace.is_a?(Workspace) && owner_of?(workspace) && !can_never?(verb, :workspace)
220
- end
221
-
222
228
  def calculate_description
223
229
  description_proc ? description_proc.call : id
224
230
  end
@@ -11,8 +11,7 @@ module Scrivito
11
11
 
12
12
  return false unless responses.all? do |response|
13
13
  raise_invalid_certificates_error if response[:content_state_id].nil?
14
-
15
- response[:content_state_id] == workspace.content_state.content_state_id
14
+ response[:content_state_id] == workspace.content_state_id
16
15
  end
17
16
 
18
17
  assert_passing_result(responses)
@@ -51,7 +50,7 @@ module Scrivito
51
50
 
52
51
  pass_sub_hash = {
53
52
  workspace_id: workspace.id,
54
- content_state_id: workspace.content_state.content_state_id,
53
+ content_state_id: workspace.content_state_id,
55
54
  from: offset,
56
55
  until: until_element,
57
56
  }
@@ -136,9 +136,13 @@ class Workspace
136
136
  # @param [Hash] attributes
137
137
  # @return [Scrivito::Workspace]
138
138
  def self.create(attributes)
139
- workspace_json = CmsRestApi.post("/workspaces", workspace: attributes)
139
+ find(create_async(attributes).result['id'])
140
+ end
140
141
 
141
- self.find(workspace_json["id"])
142
+ def self.create_async(attributes)
143
+ Task.new do
144
+ CmsRestApi.task_unaware_request(:post, 'workspaces', workspace: attributes)
145
+ end
142
146
  end
143
147
 
144
148
  # Reloads the current workspace to reflect the changes that were made to it concurrently
@@ -148,6 +152,23 @@ class Workspace
148
152
  current.reload
149
153
  end
150
154
 
155
+ # @api public
156
+ #
157
+ # This method provides a string that can be used as part of a cache key. It changes
158
+ # whenever any content ({Scrivito::BasicObj Obj} or {Scrivito::BasicWidget Widget})
159
+ # changes. Due to this, caches using the +cache_key+ are invalidated whenever
160
+ # a CMS object in the working copy has been changed.
161
+ #
162
+ # Scrivito provides the {ScrivitoHelper#scrivito_cache scrivito_cache} method which
163
+ # integrates the +cache_key+ with Rails' fragment caching. You might want to check whether
164
+ # +scrivito_cache+ satisfies your needs before implementing your own solution.
165
+ #
166
+ # @return [String] A string that changes whenever the content of the working copy
167
+ # changes.
168
+ def cache_key
169
+ @cache_key ||= Digest::SHA1.hexdigest("#{id}|#{content_state_id}")
170
+ end
171
+
151
172
  def self.cache
152
173
  @cache ||= {}
153
174
  end
@@ -206,21 +227,31 @@ class Workspace
206
227
  # Publish the changes that were made to this workspace.
207
228
  # @api public
208
229
  def publish
209
- CmsRestApi.put("#{backend_url}/publish", {})
210
-
230
+ publish_async.result
211
231
  Workspace.published.reload
212
-
213
232
  reset_workspace_if_current
214
233
  end
215
234
 
235
+ def publish_async
236
+ Task.new do
237
+ task_unaware_api_request(:put, '/publish')
238
+ end
239
+ end
240
+
216
241
  # Rebases the current workspace from the published content in order to integrate the changes
217
242
  # that were published in the meantime.
218
243
  # @api public
219
244
  def rebase
220
- CmsRestApi.put("#{backend_url}/rebase", {})
245
+ rebase_async.result
221
246
  reload
222
247
  end
223
248
 
249
+ def rebase_async
250
+ Task.new do
251
+ task_unaware_api_request(:put, '/rebase')
252
+ end
253
+ end
254
+
224
255
  # Returns the id of the workspace.
225
256
  # @api public
226
257
  # @return [String]
@@ -341,6 +372,7 @@ class Workspace
341
372
  @base_revision = nil
342
373
  @memberships = nil
343
374
  @revision = nil
375
+ @cache_key = nil
344
376
  end
345
377
 
346
378
  def fetch_workspace_data
@@ -36,20 +36,6 @@ module Scrivito
36
36
  assert_no_obj_classes
37
37
  end
38
38
 
39
- def store_in_cache
40
- CmsDataCache.write_workspace_data(id, to_hash)
41
- end
42
-
43
- def content_state
44
- @content_state ||= ContentState.find_or_create(content_state_id) if content_state_id
45
- end
46
-
47
- def base_content_state
48
- if base_content_state_id
49
- @base_content_state ||= ContentState.find_or_create(base_content_state_id)
50
- end
51
- end
52
-
53
39
  private
54
40
 
55
41
  def assert_no_obj_classes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrivito_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Infopark AG
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-07 00:00:00.000000000 Z
11
+ date: 2016-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -162,6 +162,7 @@ files:
162
162
  - app/controllers/scrivito/blobs_controller.rb
163
163
  - app/controllers/scrivito/completion_controller.rb
164
164
  - app/controllers/scrivito/default_cms_controller.rb
165
+ - app/controllers/scrivito/legacy_redirect_controller.rb
165
166
  - app/controllers/scrivito/objs_controller.rb
166
167
  - app/controllers/scrivito/tasks_controller.rb
167
168
  - app/controllers/scrivito/ui_controller.rb
@@ -178,6 +179,7 @@ files:
178
179
  - app/views/scrivito/completion/suggest.json.jbuilder
179
180
  - app/views/scrivito/content_widget/show.html.erb
180
181
  - app/views/scrivito/fallback_thumbnail.html.erb
182
+ - app/views/scrivito/objs/binary_no_cache.json.jbuilder
181
183
  - app/views/scrivito/objs/destroy.json.jbuilder
182
184
  - app/views/scrivito/objs/is_outdated.json.jbuilder
183
185
  - app/views/scrivito/objs/obj.json.jbuilder
@@ -266,6 +268,7 @@ files:
266
268
  - lib/scrivito/attribute_definition_collection.rb
267
269
  - lib/scrivito/attribute_deserializer.rb
268
270
  - lib/scrivito/attribute_serializer.rb
271
+ - lib/scrivito/attribute_value_renderer.rb
269
272
  - lib/scrivito/backend/content_state_node.rb
270
273
  - lib/scrivito/backend/index.rb
271
274
  - lib/scrivito/backend/obj_data_cache.rb
@@ -308,10 +311,6 @@ files:
308
311
  - lib/scrivito/configuration.rb
309
312
  - lib/scrivito/connection_manager.rb
310
313
  - lib/scrivito/content_conversion.rb
311
- - lib/scrivito/content_service.rb
312
- - lib/scrivito/content_state.rb
313
- - lib/scrivito/content_state_caching.rb
314
- - lib/scrivito/content_state_visitor.rb
315
314
  - lib/scrivito/controller_actions.rb
316
315
  - lib/scrivito/controller_helper.rb
317
316
  - lib/scrivito/controller_runtime.rb
@@ -350,21 +349,27 @@ files:
350
349
  - lib/scrivito/obj_create_params_parser.rb
351
350
  - lib/scrivito/obj_data.rb
352
351
  - lib/scrivito/obj_data_from_hash.rb
353
- - lib/scrivito/obj_data_from_service.rb
354
352
  - lib/scrivito/obj_facet_value.rb
355
353
  - lib/scrivito/obj_params_parser.rb
356
354
  - lib/scrivito/obj_search_builder.rb
357
355
  - lib/scrivito/obj_search_enumerator.rb
356
+ - lib/scrivito/obj_search_enumerator/batch.rb
357
+ - lib/scrivito/obj_search_enumerator/batch_iterator.rb
358
+ - lib/scrivito/obj_search_enumerator/query_executor.rb
358
359
  - lib/scrivito/obj_update_params_parser.rb
359
360
  - lib/scrivito/page_config.rb
360
361
  - lib/scrivito/parent_path.rb
362
+ - lib/scrivito/preset_routes.rb
361
363
  - lib/scrivito/rate_limit_exceeded.rb
362
364
  - lib/scrivito/request_homepage.rb
363
365
  - lib/scrivito/restriction_set.rb
364
366
  - lib/scrivito/revision.rb
367
+ - lib/scrivito/route.rb
368
+ - lib/scrivito/routing_extensions.rb
365
369
  - lib/scrivito/sdk_engine.rb
366
370
  - lib/scrivito/string_tagging.rb
367
371
  - lib/scrivito/tag_renderer.rb
372
+ - lib/scrivito/task.rb
368
373
  - lib/scrivito/test_request.rb
369
374
  - lib/scrivito/text_link.rb
370
375
  - lib/scrivito/text_link_conversion.rb
@@ -380,7 +385,6 @@ files:
380
385
  - lib/scrivito/workspace.rb
381
386
  - lib/scrivito/workspace/publish_checker.rb
382
387
  - lib/scrivito/workspace_data.rb
383
- - lib/scrivito/workspace_data_from_service.rb
384
388
  - lib/scrivito/workspace_selection_middleware.rb
385
389
  - lib/scrivito_sdk.rb
386
390
  - lib/tasks/cache.rake
@@ -401,9 +405,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
401
405
  version: 2.1.0
402
406
  required_rubygems_version: !ruby/object:Gem::Requirement
403
407
  requirements:
404
- - - ">="
408
+ - - ">"
405
409
  - !ruby/object:Gem::Version
406
- version: '0'
410
+ version: 1.3.1
407
411
  requirements: []
408
412
  rubyforge_project:
409
413
  rubygems_version: 2.4.5
@@ -1,121 +0,0 @@
1
- require 'timeout'
2
- require 'net/http'
3
-
4
- module Scrivito
5
- class ContentService
6
- class RateLimitExceeded < StandardError
7
- def initialize(retry_after)
8
- @retry_after = retry_after
9
- end
10
-
11
- attr_reader :retry_after
12
- end
13
-
14
- class MaxSleepTimeReached < StandardError
15
- end
16
-
17
- class Delay
18
- def initialize
19
- @sleep_count = 0
20
- @total_sleep_time = 0
21
- end
22
-
23
- def next_sleep_time(min_sleep = 0)
24
- sleep_time = [2 ** @sleep_count * 0.5, min_sleep.to_f].max
25
- @total_sleep_time += sleep_time
26
- raise MaxSleepTimeReached if @total_sleep_time > 40
27
- @sleep_count += 1
28
- sleep_time
29
- end
30
- end
31
-
32
- class << self
33
- @next_request_not_before = nil
34
-
35
- def query(path, payload, options={})
36
- timeout = options.fetch(:timeout, ConnectionManager::DEFAULT_TIMEOUT)
37
- retry_until_timeout_on_rate_limit_exceeded do
38
- request = build_request(path, payload)
39
- if @next_request_not_before && @next_request_not_before > (now = Time.now)
40
- sleep @next_request_not_before - now
41
- end
42
-
43
- response = nil
44
- retry_once_on_network_error do
45
- response = connection_manager.request(request, timeout)
46
- end
47
- handle_response(response)
48
- end
49
- end
50
-
51
- # for tests only
52
- def forget_retry_after
53
- @next_request_not_before = nil
54
- end
55
-
56
- def connection_manager
57
- ConnectionManager.instance
58
- end
59
-
60
- private
61
-
62
- def retry_once_on_network_error
63
- retried = false
64
- begin
65
- yield
66
- rescue NetworkError => e
67
- raise e if retried
68
- retried = true
69
- retry
70
- end
71
- end
72
-
73
- def retry_until_timeout_on_rate_limit_exceeded
74
- delay = Delay.new
75
- begin
76
- yield
77
- rescue RateLimitExceeded => e
78
- begin
79
- sleep delay.next_sleep_time(e.retry_after)
80
- rescue MaxSleepTimeReached
81
- raise ::Scrivito::RateLimitExceeded.new('rate limit exceeded', 429)
82
- end
83
- retry
84
- end
85
- end
86
-
87
- def build_request(path, payload)
88
- url = "#{Configuration.endpoint_uri.path}/#{path}".squeeze('/')
89
- request = Net::HTTP::Post.new(url, request_headers)
90
- request.basic_auth('api_token', Configuration.api_key)
91
- request.body = MultiJson.dump(payload)
92
- request
93
- end
94
-
95
- def handle_response(response)
96
- case code = response.code
97
- when /^2/
98
- retry_after = response['Retry-After']
99
- @next_request_not_before = retry_after ? Time.now + retry_after.to_f : nil
100
- MultiJson.load(response.body)
101
- when '429' then raise RateLimitExceeded.new(response['Retry-After'])
102
- when '403' then raise AccessDenied.new(response.body)
103
- when '401', '404'
104
- raise NetworkError.new(
105
- 'There was a problem communicating with the Scrivito backend. '\
106
- 'Check your configuration, i.e. "tenant" and "api_key".', code)
107
- else
108
- raise NetworkError.new("Server responded with status code #{code}", code)
109
- end
110
- end
111
-
112
- def request_headers
113
- {
114
- 'Accept' => 'application/json',
115
- 'Content-Type' => 'application/json',
116
- }
117
- end
118
- end
119
-
120
- end
121
- end