scrivito_sdk 1.0.0 → 1.1.0.rc1

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.
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