scrivito_sdk 0.65.2 → 0.66.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.
- checksums.yaml +4 -4
- data/app/controllers/scrivito/binary_redirect_controller.rb +19 -0
- data/app/controllers/scrivito/objs_controller.rb +6 -2
- data/app/controllers/scrivito/webservice_controller.rb +1 -1
- data/app/controllers/scrivito/workspaces_controller.rb +1 -7
- data/app/helpers/scrivito_helper.rb +115 -64
- data/app/views/scrivito/objs/is_outdated.json.jbuilder +1 -0
- data/app/views/scrivito/ui/index.html.erb +1 -0
- data/config/ca-bundle.crt +1 -1
- data/config/precedence_routes.rb +6 -4
- data/config/routes.rb +1 -1
- data/lib/assets/images/scrivito/source_too_large.png +0 -0
- data/lib/assets/images/scrivito/source_type_invalid.png +0 -0
- data/lib/assets/javascripts/scrivito_ui.js +2975 -357
- data/lib/assets/stylesheets/scrivito_sdk.css +1 -3
- data/lib/assets/stylesheets/scrivito_ui.css +1 -3
- data/lib/generators/scrivito/install/templates/scrivito/migrate/install_scrivito_migration.rb +0 -2
- data/lib/generators/scrivito/migration/templates/migration.erb +6 -8
- data/lib/scrivito/attribute_content.rb +16 -52
- data/lib/scrivito/attribute_deserializer.rb +3 -5
- data/lib/scrivito/attribute_serializer.rb +42 -45
- data/lib/scrivito/backend/content_state_node.rb +71 -19
- data/lib/scrivito/backend/index.rb +20 -0
- data/lib/scrivito/backend/obj_data_cache.rb +157 -31
- data/lib/scrivito/backend/obj_data_from_rest.rb +1 -0
- data/lib/scrivito/backend/obj_load.rb +10 -6
- data/lib/scrivito/backend/obj_query.rb +2 -1
- data/lib/scrivito/backend/parent_path_index.rb +5 -1
- data/lib/scrivito/backend/path_index.rb +5 -1
- data/lib/scrivito/backend/permalink_index.rb +18 -10
- data/lib/scrivito/basic_obj.rb +62 -42
- data/lib/scrivito/basic_widget.rb +5 -5
- data/lib/scrivito/binary.rb +154 -13
- data/lib/scrivito/binary_param_verifier.rb +31 -0
- data/lib/scrivito/binary_rewrite.rb +35 -0
- data/lib/scrivito/cache_middleware.rb +5 -0
- data/lib/scrivito/child_list_tag.rb +3 -3
- data/lib/scrivito/cms_backend.rb +89 -57
- data/lib/scrivito/cms_data_cache.rb +21 -4
- data/lib/scrivito/cms_dispatch_controller.rb +13 -0
- data/lib/scrivito/cms_field_tag.rb +16 -3
- data/lib/scrivito/cms_rest_api.rb +2 -2
- data/lib/scrivito/cms_routing.rb +41 -18
- data/lib/scrivito/configuration.rb +22 -0
- data/lib/scrivito/content_state.rb +1 -9
- data/lib/scrivito/content_state_caching.rb +0 -20
- data/lib/scrivito/controller_actions.rb +3 -2
- data/lib/scrivito/controller_runtime.rb +16 -8
- data/lib/scrivito/dialog_size_helper.rb +11 -0
- data/lib/scrivito/diff.rb +0 -2
- data/lib/scrivito/editing_context.rb +24 -13
- data/lib/scrivito/editing_context_middleware.rb +6 -1
- data/lib/scrivito/errors.rb +18 -0
- data/lib/scrivito/image_tag.rb +55 -0
- data/lib/scrivito/link.rb +12 -0
- data/lib/scrivito/membership_collection.rb +3 -2
- data/lib/scrivito/migrations/cms_backend.rb +6 -13
- data/lib/scrivito/migrations/migrator.rb +2 -23
- data/lib/scrivito/migrations/workspace_lock.rb +23 -11
- data/lib/scrivito/named_link.rb +1 -1
- data/lib/scrivito/obj_collection.rb +1 -1
- data/lib/scrivito/obj_data_from_service.rb +0 -7
- data/lib/scrivito/obj_search_enumerator.rb +2 -2
- data/lib/scrivito/parent_path.rb +9 -0
- data/lib/scrivito/routing_helper.rb +2 -2
- data/lib/scrivito/user.rb +2 -2
- data/lib/scrivito/user_definition.rb +2 -2
- data/lib/scrivito/widget_garbage_collection.rb +2 -2
- data/lib/scrivito/widget_tag.rb +6 -3
- data/lib/scrivito/workspace.rb +60 -41
- data/lib/scrivito/workspace_data.rb +40 -4
- data/lib/scrivito/workspace_data_from_service.rb +0 -10
- data/lib/scrivito_sdk.rb +0 -16
- metadata +12 -12
- data/lib/scrivito/attribute.rb +0 -152
- data/lib/scrivito/attribute_collection.rb +0 -66
- data/lib/scrivito/attribute_definition_migrator.rb +0 -188
- data/lib/scrivito/cms_rest_api/legacy_attribute_serializer.rb +0 -105
- data/lib/scrivito/image_tag_helper.rb +0 -46
- data/lib/scrivito/obj_class.rb +0 -258
- data/lib/scrivito/obj_class_collection.rb +0 -71
- data/lib/scrivito/obj_class_data.rb +0 -37
- data/lib/tasks/migrate_attribute_definitions.rake +0 -6
@@ -21,13 +21,13 @@ class BasicWidget
|
|
21
21
|
# to ensure that only a special type of widget can be added to a specific
|
22
22
|
# container. An example for this is a +TabGroupWidget+ that should
|
23
23
|
# contain widgets of the +TabWidget+ type only, and, vice versa, a +TabWidget+
|
24
|
-
# should only be contained in a +TabGroupWidget+. A value of +
|
24
|
+
# should only be contained in a +TabGroupWidget+. A value of +NilClass+ means that
|
25
25
|
# no additional restrictions are applied.
|
26
26
|
#
|
27
27
|
# This method only further restricts the list of valid classes defined
|
28
28
|
# by means of {AttributeContent#valid_widget_classes_for}.
|
29
29
|
#
|
30
|
-
# @return [Array<
|
30
|
+
# @return [NilClass, Array<Class>]
|
31
31
|
#
|
32
32
|
# @example
|
33
33
|
# class TabGroupWidget < Widget
|
@@ -46,8 +46,9 @@ class BasicWidget
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def self.valid_inside_container?(container_class)
|
49
|
-
valid_container_classes.
|
50
|
-
|
49
|
+
computed_classes = assert_classes(valid_container_classes, '.valid_container_classes')
|
50
|
+
|
51
|
+
computed_classes.nil? || computed_classes.include?(container_class)
|
51
52
|
end
|
52
53
|
|
53
54
|
attr_accessor :container, :container_attribute_name
|
@@ -202,7 +203,6 @@ class BasicWidget
|
|
202
203
|
# Please use {Scrivito::BasicObj#revert Obj#revert} to restore them.
|
203
204
|
#
|
204
205
|
# @raise [ScrivitoError] If the current workspace is +published+.
|
205
|
-
# @raise [ScrivitoError] If the current workspace is the +rtc+ workspace.
|
206
206
|
# @raise [ScrivitoError] If the +Widget+ is +new+.
|
207
207
|
# @raise [ScrivitoError] If the +Widget+ is +deleted+.
|
208
208
|
#
|
data/lib/scrivito/binary.rb
CHANGED
@@ -4,11 +4,13 @@ module Scrivito
|
|
4
4
|
# The Binary class represents the data stored in a binary attribute of an Obj
|
5
5
|
# or Widget
|
6
6
|
class Binary
|
7
|
-
attr_reader :id
|
7
|
+
attr_reader :id, :transformation_definition
|
8
8
|
|
9
|
-
def initialize(id,
|
9
|
+
def initialize(id, is_public, transformation_definition = nil, original = nil)
|
10
10
|
@id = id
|
11
|
-
@
|
11
|
+
@is_public = !!is_public
|
12
|
+
@transformation_definition = transformation_definition
|
13
|
+
@original = original
|
12
14
|
end
|
13
15
|
|
14
16
|
# @api public
|
@@ -17,21 +19,35 @@ class Binary
|
|
17
19
|
# been published yet.
|
18
20
|
# @return [Boolean]
|
19
21
|
def private?
|
20
|
-
|
22
|
+
!@is_public
|
23
|
+
end
|
24
|
+
|
25
|
+
def public?
|
26
|
+
@is_public
|
21
27
|
end
|
22
28
|
|
23
29
|
# @api public
|
24
|
-
# The URL
|
25
|
-
#
|
26
|
-
# expiration time in order to protect them.
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
30
|
+
# The URL for accessing the binary data and downloading it using an HTTP GET request.
|
31
|
+
#
|
32
|
+
# @note URLs for private content have an expiration time in order to protect them.
|
33
|
+
# Therefore, the URL should be accessed immediately after it has been returned
|
34
|
+
# (i.e. within a couple of minutes). Accessing it after expiration causes an error.
|
35
|
+
#
|
36
|
+
# The URLs should not be used for long-term storage since they are no longer
|
37
|
+
# accessible hours or days after they have been generated.
|
38
|
+
# @return [String] the URL at which this content is available.
|
31
39
|
def url
|
32
40
|
find_url('get')
|
33
41
|
end
|
34
42
|
|
43
|
+
def url_from_cache
|
44
|
+
blob_data = CmsBackend.instance
|
45
|
+
.find_blob_data_from_cache(id, access_type, 'get', transformation_definition)
|
46
|
+
if blob_data
|
47
|
+
blob_data['url']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
35
51
|
# @api public
|
36
52
|
# the filename of this binary data, for example "my_image.jpg"
|
37
53
|
# @return [String] the filename of binary
|
@@ -53,6 +69,121 @@ class Binary
|
|
53
69
|
headers[:content_length].to_i
|
54
70
|
end
|
55
71
|
|
72
|
+
#
|
73
|
+
# Returns a transformed {Scrivito::Binary}.
|
74
|
+
#
|
75
|
+
# @api beta
|
76
|
+
#
|
77
|
+
# Calling this method will not change the binary, but instead return a copy of it,
|
78
|
+
# transformed using the +definition+.
|
79
|
+
#
|
80
|
+
# If the original binary has already been transformed, then the returned binary will be a
|
81
|
+
# combination of the transformations. Thus the transformations can be chained (see examples).
|
82
|
+
#
|
83
|
+
# The transformed data is calculated "lazily", so calling {Scrivito::Binary#transform} will not
|
84
|
+
# trigger any calculation. The calculation will be triggered only if data is accessed, for example
|
85
|
+
# via {Scrivito::Binary#url}.
|
86
|
+
#
|
87
|
+
# @param [Hash] definition transformation definition
|
88
|
+
#
|
89
|
+
# @option definition [Fixnum,String] :width The width in pixels of the output image. Must be a
|
90
|
+
# positive integer.
|
91
|
+
#
|
92
|
+
# If only this dimension is specified, the other dimension will be calculated automatically to
|
93
|
+
# preserve the aspect ratio of the input image.
|
94
|
+
#
|
95
|
+
# If the +fit+ parameter is set to +:clip+, then the actual output one of width and height may
|
96
|
+
# be equal to or less than the dimensions you specify to prevent distortion.
|
97
|
+
#
|
98
|
+
# If neither +width+ nor +height+ is given, the width and height of the input image
|
99
|
+
# will be used.
|
100
|
+
#
|
101
|
+
# The maximum output image size width + height = 4096 pixels. The given width and height may be
|
102
|
+
# adjusted to accomodate this limit. The output image will never be larger than the source
|
103
|
+
# image, i.e. the given width and height may be adjusted to keep the output image from exceeding
|
104
|
+
# the dimensions of the input image.
|
105
|
+
#
|
106
|
+
# When the given width and height are adjusted, the aspect ratio is preserved.
|
107
|
+
#
|
108
|
+
# @option definition [Fixnum,String] :height The height in pixels of the output image. Must be a
|
109
|
+
# positive integer.
|
110
|
+
#
|
111
|
+
# If only this dimension is specified, the other dimension will be calculated automatically to
|
112
|
+
# preserve the aspect ratio of the input image.
|
113
|
+
#
|
114
|
+
# If the +fit+ parameter is set to +:clip+, then the actual output one of width and height may
|
115
|
+
# be equal to or less than the dimensions you specify to prevent distortion.
|
116
|
+
#
|
117
|
+
# If neither +width+ nor +height+ is given, the width and height of the input image
|
118
|
+
# will be used.
|
119
|
+
#
|
120
|
+
# The maximum output image size width + height = 4096 pixels. The given width and height may be
|
121
|
+
# adjusted to accomodate this limit. The output image will never be larger than the source
|
122
|
+
# image, i.e. the given width and height may be adjusted to keep the output image from exceeding
|
123
|
+
# the dimensions of the input image.
|
124
|
+
#
|
125
|
+
# When the given width and height are adjusted, the aspect ratio is preserved.
|
126
|
+
#
|
127
|
+
# @option definition [Symbol,String] :fit Controls how the tranformed image is fitted to the
|
128
|
+
# given width and heigth. Valid values are +:clip+ and +:crop+. The default value is +:clip+.
|
129
|
+
#
|
130
|
+
# If set to +:clip+ it resizes the image to fit within the width and height boundaries without
|
131
|
+
# cropping or distorting the image. The resulting image is assured to match one of the
|
132
|
+
# constraining dimensions, while the other dimension is altered to maintain the same aspect
|
133
|
+
# ratio of the input image.
|
134
|
+
#
|
135
|
+
# If set to +:crop+ it resizes the image to fill the given width and height and preserves the
|
136
|
+
# aspect ration by cropping any excess image data. The resulting image will match both the given
|
137
|
+
# width and height without distorting the image. The crop is done centered, i.e. the center of
|
138
|
+
# the image is preserved.
|
139
|
+
#
|
140
|
+
# @option definition [Fixnum,String] :quality Controls the output quality of lossy file formats.
|
141
|
+
# Applies when the format is +"jpg"+. Valid values are in the range from +0+ to +100+.
|
142
|
+
# The default value is +75+.
|
143
|
+
#
|
144
|
+
# @return [Scrivito::Binary] transformed binary
|
145
|
+
#
|
146
|
+
# @example Crop image to fit into 50 x 50 pixel square
|
147
|
+
# @obj.blob.transform(width: 50, height: 50, fit: :crop)
|
148
|
+
#
|
149
|
+
# @example Convert image to a low quality JPEG
|
150
|
+
# @obj.blob.transform(quality: 25)
|
151
|
+
#
|
152
|
+
# @example Combine the both transformations
|
153
|
+
# @obj.blob.transform(width: 50, height: 50, fit: :crop).transform(quality: 25)
|
154
|
+
#
|
155
|
+
def transform(definition)
|
156
|
+
self.class.new(id, public?, (transformation_definition || {}).merge(definition), original)
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# Returns whether a binary is transformed.
|
161
|
+
# @api beta
|
162
|
+
#
|
163
|
+
def transformed?
|
164
|
+
!!transformation_definition
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Returns the transformation original of a binary.
|
169
|
+
#
|
170
|
+
# @api beta
|
171
|
+
#
|
172
|
+
# If a binary is a result of a transformation, then its original binary is returned.
|
173
|
+
# Otherwise +self+.
|
174
|
+
#
|
175
|
+
# @return [Scrivito::Binary] original binary
|
176
|
+
#
|
177
|
+
# @example
|
178
|
+
# @obj.blob.id # => "abc123"
|
179
|
+
# @obj.blob.original.id # => "abc123"
|
180
|
+
# @obj.blob.transform(width: 50).original.id # => "abc123"
|
181
|
+
# @obj.blob.transform(width: 50).transform(height: 50).original.id # => "abc123"
|
182
|
+
#
|
183
|
+
def original
|
184
|
+
@original || self
|
185
|
+
end
|
186
|
+
|
56
187
|
private
|
57
188
|
|
58
189
|
def public_content?
|
@@ -64,11 +195,21 @@ class Binary
|
|
64
195
|
end
|
65
196
|
|
66
197
|
def find_url(verb)
|
67
|
-
CmsBackend.instance.find_blob_data(
|
198
|
+
CmsBackend.instance.find_blob_data(id, access_type, verb, transformation_definition)['url']
|
199
|
+
rescue ClientError => e
|
200
|
+
case e.backend_code
|
201
|
+
when 'binary.unprocessable.image.transform.source_too_large',
|
202
|
+
'binary.unprocessable.image.transform.source_type_invalid'
|
203
|
+
raise TransformationSourceError.new(e.message, e.backend_code)
|
204
|
+
when 'binary.unprocessable.image.transform.invalid_config'
|
205
|
+
raise TransformationDefinitionError.new(e.message, e.backend_code)
|
206
|
+
else
|
207
|
+
raise e
|
208
|
+
end
|
68
209
|
end
|
69
210
|
|
70
211
|
def access_type
|
71
|
-
|
212
|
+
public? ? 'public_access' : 'private_access'
|
72
213
|
end
|
73
214
|
end
|
74
215
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
module BinaryParamVerifier
|
4
|
+
InvalidSignature = Class.new(StandardError)
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def verify(params)
|
8
|
+
params = message_verifier.verify(params)
|
9
|
+
expires = DateAttribute.parse(params['expires'])
|
10
|
+
raise InvalidSignature if expires && expires < Time.zone.now
|
11
|
+
Binary.new(params['binary_id'], expires.nil?, params['transformation_definition'])
|
12
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
13
|
+
raise InvalidSignature
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate(binary)
|
17
|
+
params = {binary_id: binary.id, transformation_definition: binary.transformation_definition}
|
18
|
+
params[:expires] = DateAttribute.serialize(Time.zone.now + 1.hour) if binary.private?
|
19
|
+
message_verifier.generate(params)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def message_verifier
|
25
|
+
ActiveSupport::MessageVerifier.new(
|
26
|
+
Rails.application.secrets.secret_key_base, serializer: JSON)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Scrivito
|
2
|
+
#
|
3
|
+
# This module lets you change the URL of a binary CMS object for the purpose of
|
4
|
+
# fetching the binary data from a different location (e.g. via a proxy or from a mirror).
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
#
|
9
|
+
module BinaryRewrite
|
10
|
+
def self.call(request, url)
|
11
|
+
change_url_callback = request.env["SCRIVITO_BINARY_URL_CALLBACK"]
|
12
|
+
url = change_url_callback.call(url) if change_url_callback
|
13
|
+
url
|
14
|
+
end
|
15
|
+
#
|
16
|
+
# You can, for example, have the URLs of images, etc., point to your desired
|
17
|
+
# domain instead of to the CDN Scrivito uses.
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
#
|
21
|
+
# @param request [ActionDispatch::Request]
|
22
|
+
# @param block [Proc] block change default CDN url of current binary obj
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# Scrivito::BinaryRewrite.enable_for(request) do |binary_url|
|
26
|
+
# binary_url.sub(
|
27
|
+
# "https://scrivito-public-cdn.s3-eu-west-1.amazonaws.com/",
|
28
|
+
# "https://my.reverse.proxy.com/")
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
def self.enable_for(request, &block)
|
32
|
+
request.env["SCRIVITO_BINARY_URL_CALLBACK"] = block
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -7,6 +7,7 @@ class CacheMiddleware
|
|
7
7
|
|
8
8
|
def call(env)
|
9
9
|
clear_caches
|
10
|
+
clear_runtime
|
10
11
|
|
11
12
|
@app.call(env)
|
12
13
|
end
|
@@ -14,6 +15,10 @@ class CacheMiddleware
|
|
14
15
|
|
15
16
|
private
|
16
17
|
|
18
|
+
def clear_runtime
|
19
|
+
Scrivito::LogSubscriber.reset_runtime
|
20
|
+
end
|
21
|
+
|
17
22
|
def clear_caches
|
18
23
|
Workspace.cache.clear
|
19
24
|
CmsBackend.instance.clear_cache
|
@@ -65,9 +65,9 @@ class ChildListTag < Struct.new(:tag_name, :obj, :field_name, :view)
|
|
65
65
|
# @return [String] The rendered html tag
|
66
66
|
#
|
67
67
|
# @example Render a <div> tag containing the text "random content" and assigns the tag a css class called +very_important+.
|
68
|
-
#
|
69
|
-
# random content
|
70
|
-
#
|
68
|
+
# list.tag(:div, class: "very_important") do
|
69
|
+
# "random content"
|
70
|
+
# end
|
71
71
|
#
|
72
72
|
def tag(tag_name, html_options = {}, &block)
|
73
73
|
raise '"list.tag" can only be called once per iteration!' if @rendered
|
data/lib/scrivito/cms_backend.rb
CHANGED
@@ -90,30 +90,36 @@ module Scrivito
|
|
90
90
|
|
91
91
|
def find_workspace_data_by_id(id)
|
92
92
|
if die_content_service
|
93
|
-
|
93
|
+
begin
|
94
|
+
cached_workspace_state = CmsDataCache.read_workspace_state(id)
|
94
95
|
|
95
|
-
|
96
|
+
cached_csid = cached_workspace_state.try(:first)
|
97
|
+
cached_workspace_data_tag = cached_workspace_state.try(:second)
|
96
98
|
|
97
|
-
|
98
|
-
if objs.present?
|
99
|
-
if objs != "*"
|
100
|
-
last_state = Backend::ContentStateNode.find(from_csid)
|
99
|
+
changes = CmsRestApi.get("/workspaces/#{id}/changes", from: cached_csid)
|
101
100
|
|
102
|
-
|
103
|
-
current_state = last_state.create_successor(successor_state, objs)
|
104
|
-
end
|
101
|
+
update_obj_cache(id, cached_csid, changes)
|
105
102
|
|
106
|
-
|
107
|
-
|
108
|
-
current_csid = changes["workspace"]["content_state_id"]
|
109
|
-
CmsDataCache.write_workspace_csid(id, current_csid)
|
110
|
-
end
|
103
|
+
workspace_data, workspace_data_tag = update_workspace_cache(
|
104
|
+
id, cached_workspace_data_tag, changes["workspace"])
|
111
105
|
|
112
|
-
|
113
|
-
|
114
|
-
|
106
|
+
current_csid = changes["current"]
|
107
|
+
current_workspace_state = [current_csid, workspace_data_tag]
|
108
|
+
|
109
|
+
if current_workspace_state != cached_workspace_state
|
110
|
+
CmsDataCache.write_workspace_state(id, current_workspace_state)
|
111
|
+
end
|
115
112
|
|
116
|
-
|
113
|
+
return WorkspaceData.new(workspace_data.merge(
|
114
|
+
"content_state_id" => current_csid))
|
115
|
+
|
116
|
+
rescue Scrivito::ClientError => client_error
|
117
|
+
if client_error.http_code == 404
|
118
|
+
return nil
|
119
|
+
else
|
120
|
+
raise
|
121
|
+
end
|
122
|
+
end
|
117
123
|
end
|
118
124
|
|
119
125
|
workspace_data_from_cache = WorkspaceDataFromService.find_from_cache(id)
|
@@ -168,17 +174,22 @@ module Scrivito
|
|
168
174
|
end
|
169
175
|
end
|
170
176
|
|
171
|
-
def find_blob_data(id, access, verb)
|
172
|
-
|
173
|
-
if blob_data = fetch_blob_data_from_cache(id, access, verb)
|
177
|
+
def find_blob_data(id, access, verb, transformation_definition)
|
178
|
+
if blob_data = find_blob_data_from_cache(id, access, verb, transformation_definition)
|
174
179
|
blob_data
|
175
180
|
else
|
176
|
-
|
177
|
-
|
181
|
+
id = normalize_blob_id(id)
|
182
|
+
blob_datas = request_blob_datas_from_backend(id, transformation_definition)
|
183
|
+
store_blob_datas_in_cache(id, transformation_definition, blob_datas)
|
178
184
|
blob_datas[access][verb]
|
179
185
|
end
|
180
186
|
end
|
181
187
|
|
188
|
+
def find_blob_data_from_cache(id, access, verb, transformation_definition)
|
189
|
+
cache_key = blob_data_cache_key(normalize_blob_id(id), access, verb, transformation_definition)
|
190
|
+
CmsDataCache.cache.read(cache_key)
|
191
|
+
end
|
192
|
+
|
182
193
|
def find_blob_metadata(id, url)
|
183
194
|
if blob_metadata = fetch_blob_metadata_from_cache(id)
|
184
195
|
blob_metadata
|
@@ -190,14 +201,24 @@ module Scrivito
|
|
190
201
|
end
|
191
202
|
|
192
203
|
def search_objs(workspace, params)
|
204
|
+
cache_index = 'search'
|
205
|
+
cache_key = params.to_param
|
206
|
+
|
193
207
|
if die_content_service
|
194
|
-
|
195
|
-
|
208
|
+
cache = Backend::ObjDataCache.view_for_revision(workspace.revision)
|
209
|
+
|
210
|
+
if hit = cache.read_index(cache_index, cache_key)
|
211
|
+
return hit
|
212
|
+
end
|
213
|
+
|
214
|
+
result = request_search_result_from_backend(workspace, params)
|
215
|
+
|
216
|
+
cache.write_index(cache_index, cache_key, result)
|
217
|
+
|
218
|
+
return result
|
196
219
|
end
|
197
220
|
|
198
221
|
content_state = workspace.revision.content_state
|
199
|
-
cache_index = 'search'
|
200
|
-
cache_key = params.to_param
|
201
222
|
|
202
223
|
if result = fetch_search_result_from_cache(content_state, cache_index, cache_key)
|
203
224
|
result
|
@@ -208,34 +229,39 @@ module Scrivito
|
|
208
229
|
end
|
209
230
|
end
|
210
231
|
|
211
|
-
|
212
|
-
find_all_obj_class_data(revision).find { |obj_class_data| obj_class_data.name == name }
|
213
|
-
end
|
232
|
+
private
|
214
233
|
|
215
|
-
def
|
216
|
-
|
217
|
-
|
218
|
-
obj_classes_data
|
234
|
+
def update_workspace_cache(id, cached_data_tag, changed_workspace)
|
235
|
+
if changed_workspace
|
236
|
+
workspace_data = changed_workspace
|
219
237
|
else
|
220
|
-
|
221
|
-
|
238
|
+
cached_workspace_data = CmsDataCache.read_data_from_tag(cached_data_tag)
|
239
|
+
|
240
|
+
if cached_workspace_data
|
241
|
+
workspace_data = cached_workspace_data
|
242
|
+
workspace_data_tag = cached_data_tag
|
243
|
+
else
|
244
|
+
workspace_data = CmsRestApi.get("/workspaces/#{id}")
|
222
245
|
end
|
223
246
|
end
|
224
|
-
end
|
225
247
|
|
226
|
-
|
248
|
+
workspace_data_tag ||= CmsDataCache.write_data_to_tag(workspace_data)
|
227
249
|
|
228
|
-
|
229
|
-
ContentStateCaching.find_obj_classes_data(content_state) if caching?
|
250
|
+
[workspace_data, workspace_data_tag]
|
230
251
|
end
|
231
252
|
|
232
|
-
def
|
233
|
-
|
234
|
-
|
235
|
-
|
253
|
+
def update_obj_cache(workspace_id, cached_csid, changes)
|
254
|
+
objs = changes["objs"]
|
255
|
+
if objs.present? && objs != "*"
|
256
|
+
last_state = Backend::ContentStateNode.find(cached_csid)
|
257
|
+
changes_index = Backend::ObjDataCache.changes_index_from(objs)
|
258
|
+
successor = last_state.create_successor(changes["to"], changes_index)
|
236
259
|
|
237
|
-
|
238
|
-
|
260
|
+
cache = Backend::ObjDataCache.view_for_workspace(workspace_id, successor)
|
261
|
+
changes_index.each do |id, tag|
|
262
|
+
cache.write_obj_tag(id, tag)
|
263
|
+
end
|
264
|
+
end
|
239
265
|
end
|
240
266
|
|
241
267
|
def fetch_search_result_from_cache(content_state, cache_index, cache_key)
|
@@ -250,27 +276,33 @@ module Scrivito
|
|
250
276
|
content_state.save_obj_data(cache_index, cache_key, result) if caching?
|
251
277
|
end
|
252
278
|
|
253
|
-
def
|
254
|
-
CmsDataCache.cache.read(blob_data_cache_key(id, access, verb))
|
255
|
-
end
|
256
|
-
|
257
|
-
def request_blob_datas_from_backend(id)
|
279
|
+
def request_blob_datas_from_backend(id, transformation_definition)
|
258
280
|
@query_counter += 1
|
259
|
-
|
281
|
+
if transformation_definition
|
282
|
+
CmsRestApi.get("blobs/#{id}/transform", transformation: transformation_definition)
|
283
|
+
else
|
284
|
+
CmsRestApi.get("blobs/#{id}")
|
285
|
+
end
|
260
286
|
end
|
261
287
|
|
262
|
-
def store_blob_datas_in_cache(id, blob_datas)
|
288
|
+
def store_blob_datas_in_cache(id, transformation_definition, blob_datas)
|
263
289
|
%w[public_access private_access].each do |access|
|
264
290
|
%w[get head].each do |verb|
|
265
291
|
blob_data = blob_datas[access][verb]
|
266
|
-
|
267
|
-
|
292
|
+
cache_key = blob_data_cache_key(id, access, verb, transformation_definition)
|
293
|
+
CmsDataCache.cache.write(cache_key, blob_data, blob_data['maxage'])
|
268
294
|
end
|
269
295
|
end
|
270
296
|
end
|
271
297
|
|
272
|
-
def blob_data_cache_key(id, access, verb)
|
273
|
-
"blob_data/#{id}/#{access}/#{verb}"
|
298
|
+
def blob_data_cache_key(id, access, verb, transformation_definition)
|
299
|
+
cache_key = "blob_data/#{id}/#{access}/#{verb}"
|
300
|
+
cache_key << "/#{transformation_definition.to_query}" if transformation_definition
|
301
|
+
cache_key
|
302
|
+
end
|
303
|
+
|
304
|
+
def normalize_blob_id(id)
|
305
|
+
Addressable::URI.normalize_component(id, Addressable::URI::CharacterClasses::UNRESERVED)
|
274
306
|
end
|
275
307
|
|
276
308
|
def fetch_blob_metadata_from_cache(id)
|