scrivito_sdk 1.1.1 → 1.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/scrivito/blobs_controller.rb +7 -0
- data/app/controllers/scrivito/objs_controller.rb +0 -6
- data/app/controllers/scrivito/ui_controller.rb +2 -0
- data/app/views/scrivito/blobs/{activate_upload.json.jbuilder → blob.json.jbuilder} +0 -0
- data/config/ca-bundle.crt +1 -1
- data/config/precedence_routes.rb +1 -1
- data/lib/assets/javascripts/scrivito_ui.js +20072 -19687
- data/lib/assets/stylesheets/scrivito.css +1 -1
- data/lib/assets/stylesheets/scrivito_ui.css +1 -1
- data/lib/generators/scrivito/install/install_generator.rb +2 -8
- data/lib/generators/scrivito/install/templates/app/views/download/details.html.erb +11 -0
- data/lib/generators/scrivito/install/templates/app/views/headline_widget/thumbnail.html.erb +1 -1
- data/lib/generators/scrivito/install/templates/app/views/image/details.html.erb +17 -0
- data/lib/generators/scrivito/install/templates/app/views/image_widget/thumbnail.html.erb +1 -1
- data/lib/generators/scrivito/install/templates/app/views/page/details.html.erb +4 -2
- data/lib/generators/scrivito/install/templates/app/views/page/thumbnail.html.erb +1 -3
- data/lib/generators/scrivito/install/templates/app/views/text_widget/thumbnail.html.erb +2 -2
- data/lib/generators/scrivito/page/page_generator.rb +8 -0
- data/lib/generators/scrivito/page/templates/details.html.erb +4 -2
- data/lib/generators/scrivito/page/templates/thumbnail.html.erb +1 -3
- data/lib/generators/scrivito/widget/templates/details.html.erb +4 -2
- data/lib/generators/scrivito/widget/templates/show.html.erb +1 -2
- data/lib/generators/scrivito/widget/templates/thumbnail.html.erb +1 -3
- data/lib/generators/scrivito/widget/widget_generator.rb +0 -4
- data/lib/scrivito/attribute_content.rb +44 -15
- data/lib/scrivito/attribute_definition.rb +59 -3
- data/lib/scrivito/basic_obj.rb +11 -18
- data/lib/scrivito/basic_widget.rb +42 -0
- data/lib/scrivito/binary.rb +5 -5
- data/lib/scrivito/cache_middleware.rb +13 -17
- data/lib/scrivito/class_collection.rb +1 -1
- data/lib/scrivito/client_attribute_serializer.rb +5 -1
- data/lib/scrivito/cms_backend.rb +43 -60
- data/lib/scrivito/cms_data_cache.rb +18 -14
- data/lib/scrivito/cms_field_tag.rb +2 -2
- data/lib/scrivito/cms_rest_api.rb +9 -8
- data/lib/scrivito/cms_routing.rb +1 -1
- data/lib/scrivito/configuration.rb +15 -4
- data/lib/scrivito/connection_manager.rb +29 -23
- data/lib/scrivito/model_library.rb +43 -11
- data/lib/scrivito/obj_collection.rb +1 -1
- data/lib/scrivito/obj_params_parser.rb +1 -19
- data/lib/scrivito/obj_search_enumerator/query_executor.rb +1 -1
- data/lib/scrivito/obj_search_enumerator.rb +1 -1
- data/lib/scrivito/ui_config.rb +13 -2
- data/lib/scrivito/widget_collection.rb +1 -1
- data/lib/scrivito/workspace.rb +25 -26
- data/lib/scrivito_sdk.rb +67 -40
- metadata +21 -8
- data/lib/generators/scrivito/install/templates/app/views/download/embed.html.erb +0 -1
- data/lib/generators/scrivito/install/templates/app/views/image/embed.html.erb +0 -1
- data/lib/scrivito/widget_garbage_collection.rb +0 -97
data/lib/scrivito/cms_backend.rb
CHANGED
@@ -1,45 +1,8 @@
|
|
1
1
|
module Scrivito
|
2
|
-
|
2
|
+
module CmsBackend
|
3
3
|
VALID_INDEX_NAMES = %w[id path ppath permalink].freeze
|
4
4
|
|
5
|
-
|
6
|
-
def instance
|
7
|
-
@instance ||= new
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@query_counter = 0
|
13
|
-
@caching = true
|
14
|
-
end
|
15
|
-
|
16
|
-
def begin_caching
|
17
|
-
@caching = true
|
18
|
-
end
|
19
|
-
|
20
|
-
def end_caching
|
21
|
-
CmsDataCache.clear_request_cache
|
22
|
-
@caching = false
|
23
|
-
end
|
24
|
-
|
25
|
-
def clear_cache
|
26
|
-
CmsDataCache.clear_request_cache
|
27
|
-
end
|
28
|
-
|
29
|
-
def caching?
|
30
|
-
!!@caching
|
31
|
-
end
|
32
|
-
|
33
|
-
def query_counter
|
34
|
-
@query_counter
|
35
|
-
end
|
36
|
-
|
37
|
-
# For test purpose only.
|
38
|
-
def reset_query_counter!
|
39
|
-
@query_counter = 0
|
40
|
-
end
|
41
|
-
|
42
|
-
def find_workspace_data_from_cache(id)
|
5
|
+
def self.find_workspace_data_from_cache(id)
|
43
6
|
cached_workspace_state = CmsDataCache.read_workspace_state(id)
|
44
7
|
cached_data_tag = cached_workspace_state.try(:second)
|
45
8
|
cached_content_state_id = cached_workspace_state.try(:first)
|
@@ -51,7 +14,7 @@ module Scrivito
|
|
51
14
|
end
|
52
15
|
end
|
53
16
|
|
54
|
-
def find_workspace_data_by_id(id, timeout=nil)
|
17
|
+
def self.find_workspace_data_by_id(id, timeout=nil)
|
55
18
|
options = timeout ? {timeout: timeout} : {}
|
56
19
|
|
57
20
|
cached_workspace_state = CmsDataCache.read_workspace_state(id)
|
@@ -82,7 +45,7 @@ module Scrivito
|
|
82
45
|
end
|
83
46
|
end
|
84
47
|
|
85
|
-
def find_obj_data_by(revision, index, keys)
|
48
|
+
def self.find_obj_data_by(revision, index, keys)
|
86
49
|
index = index.to_s
|
87
50
|
|
88
51
|
if index == "id"
|
@@ -94,7 +57,7 @@ module Scrivito
|
|
94
57
|
end
|
95
58
|
end
|
96
59
|
|
97
|
-
def find_blob_data(id, access, verb, options = {})
|
60
|
+
def self.find_blob_data(id, access, verb, options = {})
|
98
61
|
if blob_data = find_blob_data_from_cache(id, access, verb, options)
|
99
62
|
blob_data
|
100
63
|
else
|
@@ -105,12 +68,12 @@ module Scrivito
|
|
105
68
|
end
|
106
69
|
end
|
107
70
|
|
108
|
-
def find_blob_data_from_cache(id, access, verb, options)
|
71
|
+
def self.find_blob_data_from_cache(id, access, verb, options)
|
109
72
|
cache_key = blob_data_cache_key(normalize_blob_id(id), access, verb, options)
|
110
73
|
CmsDataCache.cache.read(cache_key)
|
111
74
|
end
|
112
75
|
|
113
|
-
def find_binary_meta_data(blob_id)
|
76
|
+
def self.find_binary_meta_data(blob_id)
|
114
77
|
blob_id = normalize_blob_id(blob_id)
|
115
78
|
cache_key = "binary_meta_data/#{blob_id}"
|
116
79
|
if meta_data = CmsDataCache.cache.read(cache_key)
|
@@ -122,7 +85,7 @@ module Scrivito
|
|
122
85
|
end
|
123
86
|
end
|
124
87
|
|
125
|
-
def search_objs(workspace, params)
|
88
|
+
def self.search_objs(workspace, params)
|
126
89
|
cache_index = 'search'
|
127
90
|
cache_key = params.to_param
|
128
91
|
cache = Backend::ObjDataCache.view_for_revision(workspace.revision)
|
@@ -137,23 +100,32 @@ module Scrivito
|
|
137
100
|
result
|
138
101
|
end
|
139
102
|
|
140
|
-
def create_obj(workspace_id, attributes)
|
103
|
+
def self.create_obj(workspace_id, attributes)
|
141
104
|
write_obj(:post, "/workspaces/#{workspace_id}/objs", attributes)
|
142
105
|
end
|
143
106
|
|
144
|
-
def update_obj(workspace_id, obj_id, attributes)
|
107
|
+
def self.update_obj(workspace_id, obj_id, attributes)
|
145
108
|
write_obj(:put, "/workspaces/#{workspace_id}/objs/#{obj_id}", attributes)
|
146
109
|
end
|
147
110
|
|
148
|
-
|
111
|
+
# For test purpose only.
|
112
|
+
def self.query_counter
|
113
|
+
@query_counter
|
114
|
+
end
|
115
|
+
|
116
|
+
# For test purpose only.
|
117
|
+
def self.reset_query_counter!
|
118
|
+
@query_counter = 0
|
119
|
+
end
|
149
120
|
|
150
|
-
def write_obj(verb, path, attributes)
|
121
|
+
def self.write_obj(verb, path, attributes)
|
151
122
|
Backend::ObjDataFromRest.new(CmsRestApi.task_unaware_request(verb, path, attributes))
|
152
123
|
end
|
124
|
+
private_class_method :write_obj
|
153
125
|
|
154
|
-
def update_workspace_cache(id, cached_data_tag,
|
155
|
-
if
|
156
|
-
workspace_data =
|
126
|
+
def self.update_workspace_cache(id, cached_data_tag, workspace, options)
|
127
|
+
if workspace
|
128
|
+
workspace_data = workspace
|
157
129
|
else
|
158
130
|
if cached_workspace_data = fetch_cached_data_by_tag(cached_data_tag)
|
159
131
|
workspace_data = cached_workspace_data
|
@@ -167,16 +139,19 @@ module Scrivito
|
|
167
139
|
|
168
140
|
[workspace_data, workspace_data_tag]
|
169
141
|
end
|
142
|
+
private_class_method :update_workspace_cache
|
170
143
|
|
171
|
-
def fetch_cached_data_by_tag(data_tag)
|
144
|
+
def self.fetch_cached_data_by_tag(data_tag)
|
172
145
|
data_tag && CmsDataCache.read_data_from_tag(data_tag)
|
173
146
|
end
|
147
|
+
private_class_method :fetch_cached_data_by_tag
|
174
148
|
|
175
|
-
def build_workspace_data(raw_data, content_state_id)
|
149
|
+
def self.build_workspace_data(raw_data, content_state_id)
|
176
150
|
WorkspaceData.new(raw_data.merge('content_state_id' => content_state_id))
|
177
151
|
end
|
152
|
+
private_class_method :build_workspace_data
|
178
153
|
|
179
|
-
def update_obj_cache(workspace_id, cached_csid, changes)
|
154
|
+
def self.update_obj_cache(workspace_id, cached_csid, changes)
|
180
155
|
objs = changes["objs"]
|
181
156
|
if objs.present? && objs != "*"
|
182
157
|
last_state = Backend::ContentStateNode.find(cached_csid)
|
@@ -189,14 +164,18 @@ module Scrivito
|
|
189
164
|
end
|
190
165
|
end
|
191
166
|
end
|
167
|
+
private_class_method :update_obj_cache
|
192
168
|
|
193
|
-
def request_search_result_from_backend(workspace, params)
|
169
|
+
def self.request_search_result_from_backend(workspace, params)
|
194
170
|
params = params.merge(consistent_with: workspace.content_state_id)
|
195
171
|
CmsRestApi.get("workspaces/#{workspace.id}/objs/search", params)
|
196
172
|
end
|
173
|
+
private_class_method :request_search_result_from_backend
|
197
174
|
|
198
|
-
def request_blob_datas_from_backend(id, options)
|
175
|
+
def self.request_blob_datas_from_backend(id, options)
|
176
|
+
@query_counter ||= 0
|
199
177
|
@query_counter += 1
|
178
|
+
|
200
179
|
case
|
201
180
|
when transformation_definition = options[:transformation_definition]
|
202
181
|
CmsRestApi.get("blobs/#{id}/transform", transformation: transformation_definition)
|
@@ -206,8 +185,9 @@ module Scrivito
|
|
206
185
|
CmsRestApi.get("blobs/#{id}")
|
207
186
|
end
|
208
187
|
end
|
188
|
+
private_class_method :request_blob_datas_from_backend
|
209
189
|
|
210
|
-
def store_blob_datas_in_cache(id, options, blob_datas)
|
190
|
+
def self.store_blob_datas_in_cache(id, options, blob_datas)
|
211
191
|
%w[public_access private_access].each do |access|
|
212
192
|
%w[get head].each do |verb|
|
213
193
|
if access_blob_data = blob_datas[access]
|
@@ -219,8 +199,9 @@ module Scrivito
|
|
219
199
|
end
|
220
200
|
end
|
221
201
|
end
|
202
|
+
private_class_method :store_blob_datas_in_cache
|
222
203
|
|
223
|
-
def blob_data_cache_key(id, access, verb, options)
|
204
|
+
def self.blob_data_cache_key(id, access, verb, options)
|
224
205
|
cache_key = "blob_data/#{id}/#{access}/#{verb}"
|
225
206
|
|
226
207
|
if transformation_definition = options[:transformation_definition]
|
@@ -233,9 +214,11 @@ module Scrivito
|
|
233
214
|
|
234
215
|
cache_key
|
235
216
|
end
|
217
|
+
private_class_method :blob_data_cache_key
|
236
218
|
|
237
|
-
def normalize_blob_id(id)
|
219
|
+
def self.normalize_blob_id(id)
|
238
220
|
CmsRestApi.normalize_path_component(id)
|
239
221
|
end
|
222
|
+
private_class_method :normalize_blob_id
|
240
223
|
end
|
241
224
|
end
|
@@ -5,29 +5,29 @@ module CmsDataCache
|
|
5
5
|
VERSION = 'v3'.freeze
|
6
6
|
|
7
7
|
class << self
|
8
|
-
attr_reader :second_level_cache
|
9
|
-
attr_writer :cache_path
|
10
|
-
|
11
8
|
def cache
|
12
|
-
|
9
|
+
Thread.current[:scrivito_cms_data_cache_chain] ||=
|
10
|
+
Cache::RamStore.new(next_store: first_level_cache, cache_prefix: VERSION)
|
13
11
|
end
|
14
12
|
|
15
13
|
def cache_path=(path)
|
16
14
|
clear_cache_chain
|
17
|
-
|
15
|
+
Thread.current[:scrivito_cms_data_cache_path] = path
|
18
16
|
end
|
19
17
|
|
20
18
|
def first_level_cache
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def clear_request_cache
|
25
|
-
cache.clear
|
19
|
+
cache_path = Thread.current[:scrivito_cms_data_cache_path]
|
20
|
+
Thread.current[:scrivito_cms_data_first_level_cache] ||=
|
21
|
+
Cache::FileStore.new(path: cache_path, next_store: second_level_cache)
|
26
22
|
end
|
27
23
|
|
28
24
|
def second_level_cache=(cache_store)
|
29
25
|
clear_cache_chain
|
30
|
-
|
26
|
+
Thread.current[:scrivito_cms_data_second_level_cache] = cache_store
|
27
|
+
end
|
28
|
+
|
29
|
+
def second_level_cache
|
30
|
+
Thread.current[:scrivito_cms_data_second_level_cache]
|
31
31
|
end
|
32
32
|
|
33
33
|
SCHEMA = {
|
@@ -77,12 +77,16 @@ module CmsDataCache
|
|
77
77
|
read_tag_data(tag)
|
78
78
|
end
|
79
79
|
|
80
|
+
def clear_request_cache
|
81
|
+
cache.clear
|
82
|
+
end
|
83
|
+
|
80
84
|
private
|
81
85
|
|
82
86
|
def clear_cache_chain
|
83
|
-
|
84
|
-
|
85
|
-
|
87
|
+
Thread.current[:scrivito_cms_data_cache_chain] = nil
|
88
|
+
Thread.current[:scrivito_cms_data_first_level_cache] = nil
|
89
|
+
Thread.current[:scrivito_cms_data_second_level_cache] = nil
|
86
90
|
end
|
87
91
|
end
|
88
92
|
end
|
@@ -46,7 +46,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_option
|
|
46
46
|
'field-obj-class' => obj_or_widget.obj_class,
|
47
47
|
'field-type' => field_type,
|
48
48
|
'private-editor' => editing_options[:editor],
|
49
|
-
'private-field-allowed-values' =>
|
49
|
+
'private-field-allowed-values' => valid_values,
|
50
50
|
'private-field-workspace-id' => current_workspace_id,
|
51
51
|
}
|
52
52
|
|
@@ -158,7 +158,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_option
|
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
|
-
def
|
161
|
+
def valid_values
|
162
162
|
MultiJson.encode(obj_or_widget.attribute_definitions[field_name].try(:values) || [])
|
163
163
|
end
|
164
164
|
|
@@ -70,8 +70,8 @@ module Scrivito
|
|
70
70
|
|
71
71
|
def self.upload_future_binary(future_binary, obj_id)
|
72
72
|
if future_binary.id_to_copy
|
73
|
-
|
74
|
-
|
73
|
+
copy_binary(normalize_path_component(future_binary.id_to_copy),
|
74
|
+
future_binary.to_h.merge(destination_obj_id: obj_id))
|
75
75
|
else
|
76
76
|
permission = get('blobs/upload_permission')
|
77
77
|
upload = upload_file(future_binary.file_to_upload, future_binary.content_type, permission)
|
@@ -83,6 +83,10 @@ module Scrivito
|
|
83
83
|
put('blobs/activate_upload', params)
|
84
84
|
end
|
85
85
|
|
86
|
+
def self.copy_binary(id, params)
|
87
|
+
put("blobs/#{id}/copy", params)
|
88
|
+
end
|
89
|
+
|
86
90
|
def self.normalize_path_component(component)
|
87
91
|
Addressable::URI.normalize_component(component,
|
88
92
|
Addressable::URI::CharacterClasses::UNRESERVED)
|
@@ -135,7 +139,7 @@ module Scrivito
|
|
135
139
|
response = retry_once_on_network_error(method, timer) do
|
136
140
|
CmsRestApi::RateLimit.retry_on_rate_limit(timer) do
|
137
141
|
request_timeout = [timer.remaining_time, MAX_REQUEST_TIME].min
|
138
|
-
|
142
|
+
ConnectionManager.request(request, timeout: request_timeout)
|
139
143
|
end
|
140
144
|
end
|
141
145
|
|
@@ -189,7 +193,8 @@ module Scrivito
|
|
189
193
|
upload_io = UploadIO.new(open_file, content_type, File.basename(file))
|
190
194
|
params = upload_permission['fields'].merge('file' => upload_io)
|
191
195
|
request = Net::HTTP::Post::Multipart.new(uri.path, params)
|
192
|
-
response = ConnectionManager.request(
|
196
|
+
response = ConnectionManager.request(request, uri: uri)
|
197
|
+
|
193
198
|
if response.code.starts_with?('2')
|
194
199
|
upload_permission['blob']
|
195
200
|
else
|
@@ -231,10 +236,6 @@ module Scrivito
|
|
231
236
|
"/#{Configuration.endpoint_uri.path}/#{path}".squeeze('/')
|
232
237
|
end
|
233
238
|
|
234
|
-
def connection_manager
|
235
|
-
ConnectionManager.instance
|
236
|
-
end
|
237
|
-
|
238
239
|
def build_timer(options={})
|
239
240
|
CmsRestApi::RequestTimer.new(options.fetch(:timeout, DEFAULT_TIMEOUT))
|
240
241
|
end
|
data/lib/scrivito/cms_routing.rb
CHANGED
@@ -77,7 +77,7 @@ class CmsRouting < Struct.new(:request, :context, :scrivito_engine, :image_optio
|
|
77
77
|
|
78
78
|
def path_or_url_for_objs(obj, path_or_url, options)
|
79
79
|
permalink = obj.permalink
|
80
|
-
if permalink && route_defined?(:permalink)
|
80
|
+
if permalink && route_defined?(:permalink) && permalink.split('/').first != 'scrivito'
|
81
81
|
use_route(:permalink, path_or_url, options.merge(:permalink => permalink))
|
82
82
|
elsif homepage?(obj) && route_defined?(:homepage)
|
83
83
|
use_route(:homepage, path_or_url, options)
|
@@ -297,11 +297,22 @@ Please use the new scrivito_route api to replicate the legacy routes:
|
|
297
297
|
|
298
298
|
attr_reader :default_image_transformation
|
299
299
|
|
300
|
-
# Configure a callback to be invoked when the Scrivito SDK delivers the homepage.
|
301
|
-
# The given callback will receive the rack env
|
302
|
-
# and must return an {BasicObj Obj} to be used as the homepage.
|
303
|
-
# If no callback is configured, {BasicObj.root Obj.root} will be used as the default.
|
304
300
|
# @api public
|
301
|
+
#
|
302
|
+
# A callback that can be provided for determining the CMS object to be used when visiting
|
303
|
+
# the homepage. See {Scrivito::RoutingExtensions#scrivito_route scrivito_route} for
|
304
|
+
# details on how to define routes. The callback is called once per request and receives
|
305
|
+
# the rack environment as its only parameter. By default, the CMS object at the root
|
306
|
+
# path (+/+) is used as the homepage.
|
307
|
+
#
|
308
|
+
# @yield Rack environment of the current request
|
309
|
+
#
|
310
|
+
# @example
|
311
|
+
# Scrivito.configure do |config|
|
312
|
+
# config.choose_homepage do |env|
|
313
|
+
# Obj.root # Replace with code to set the homepage
|
314
|
+
# end
|
315
|
+
# end
|
305
316
|
def choose_homepage(&block)
|
306
317
|
self.choose_homepage_callback = block
|
307
318
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'connection_pool'
|
2
|
+
|
1
3
|
module Scrivito
|
2
4
|
class ConnectionManager
|
3
5
|
DEFAULT_TIMEOUT = 10.freeze
|
@@ -5,22 +7,15 @@ module Scrivito
|
|
5
7
|
attr_reader :uri
|
6
8
|
|
7
9
|
class << self
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# For test purpose only.
|
13
|
-
def reset_instance!
|
14
|
-
@instance = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
def request(uri, request, timeout = nil)
|
18
|
-
instance_for(uri).request(request, timeout)
|
10
|
+
def request(request, timeout: nil, uri: nil)
|
11
|
+
connection_pool_for(uri || Configuration.endpoint_uri).with do |connection|
|
12
|
+
connection.request(request, timeout)
|
13
|
+
end
|
19
14
|
end
|
20
15
|
|
21
16
|
# For test purpose only.
|
22
17
|
def clear_cache!
|
23
|
-
@
|
18
|
+
@connection_pools = nil
|
24
19
|
@cert_store = nil
|
25
20
|
end
|
26
21
|
|
@@ -33,15 +28,17 @@ module Scrivito
|
|
33
28
|
|
34
29
|
private
|
35
30
|
|
36
|
-
def
|
31
|
+
def connection_pool_for(uri)
|
37
32
|
endpoint_url = "#{uri.scheme}://#{uri.host}:#{uri.port}"
|
38
|
-
|
39
|
-
|
33
|
+
connection_pools.fetch(endpoint_url) do
|
34
|
+
connection_pools[endpoint_url] = ConnectionPool.new(size: 100, timeout: 0) do
|
35
|
+
new(URI.parse(endpoint_url))
|
36
|
+
end
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
43
|
-
def
|
44
|
-
@
|
40
|
+
def connection_pools
|
41
|
+
@connection_pools ||= {}
|
45
42
|
end
|
46
43
|
end
|
47
44
|
|
@@ -53,12 +50,16 @@ module Scrivito
|
|
53
50
|
request['User-Agent'] = user_agent
|
54
51
|
ensure_started(timeout)
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
# This should never happen!
|
54
|
+
raise InternalError, 'Connection is already in use!' if @in_use
|
55
|
+
|
56
|
+
@in_use = true
|
57
|
+
connection.request(request)
|
58
|
+
rescue => e
|
59
|
+
ensure_finished
|
60
|
+
raise NetworkError.from_socket_error(e)
|
61
|
+
ensure
|
62
|
+
@in_use = false
|
62
63
|
end
|
63
64
|
|
64
65
|
# for testing purposes
|
@@ -66,6 +67,11 @@ module Scrivito
|
|
66
67
|
@connect_count || 0
|
67
68
|
end
|
68
69
|
|
70
|
+
# For test purpose only.
|
71
|
+
def in_use?
|
72
|
+
!!@in_use
|
73
|
+
end
|
74
|
+
|
69
75
|
private
|
70
76
|
|
71
77
|
attr_accessor :connection
|
@@ -4,10 +4,13 @@ module Scrivito
|
|
4
4
|
# @api public
|
5
5
|
#
|
6
6
|
class ModelLibrary
|
7
|
-
attr_reader :custom_pages, :custom_widgets, :custom_paths
|
7
|
+
attr_reader :custom_pages, :custom_widgets, :custom_objs, :custom_paths
|
8
8
|
|
9
9
|
def initialize
|
10
|
-
@custom_pages
|
10
|
+
@custom_pages = []
|
11
|
+
@custom_widgets = []
|
12
|
+
@custom_objs = []
|
13
|
+
@custom_paths = []
|
11
14
|
end
|
12
15
|
|
13
16
|
#
|
@@ -17,13 +20,14 @@ class ModelLibrary
|
|
17
20
|
# @see Scrivito.models
|
18
21
|
#
|
19
22
|
def clear_cache
|
20
|
-
@pages
|
23
|
+
@pages = nil
|
21
24
|
@widgets = nil
|
22
|
-
@
|
25
|
+
@objs = nil
|
26
|
+
@paths = nil
|
23
27
|
end
|
24
28
|
|
25
29
|
#
|
26
|
-
# Configures which models Scrivito assumes as pages and
|
30
|
+
# Configures which models Scrivito assumes as pages, widgets and objs.
|
27
31
|
#
|
28
32
|
# @api public
|
29
33
|
# @see Scrivito.models
|
@@ -54,6 +58,25 @@ class ModelLibrary
|
|
54
58
|
@widgets ||= load_models('widget', Scrivito::BasicWidget)
|
55
59
|
end
|
56
60
|
|
61
|
+
#
|
62
|
+
# Lists available CMS object models.
|
63
|
+
#
|
64
|
+
# @api public
|
65
|
+
# @see Scrivito.models
|
66
|
+
# @return [Scrivito::ClassCollection] available CMS object classes
|
67
|
+
#
|
68
|
+
def objs
|
69
|
+
@objs ||= load_obj_models
|
70
|
+
end
|
71
|
+
|
72
|
+
def load_obj_models
|
73
|
+
base_class = Scrivito::BasicObj
|
74
|
+
model_classes = load_models_from_paths('obj', base_class) +
|
75
|
+
load_custom_models('obj', base_class) +
|
76
|
+
load_custom_models('page', base_class)
|
77
|
+
ClassCollection.new(model_classes)
|
78
|
+
end
|
79
|
+
|
57
80
|
#
|
58
81
|
# Lists available paths to scan for models.
|
59
82
|
#
|
@@ -69,7 +92,7 @@ class ModelLibrary
|
|
69
92
|
|
70
93
|
def load_models(type, base_class)
|
71
94
|
model_classes = load_models_from_paths(type, base_class) + load_custom_models(type, base_class)
|
72
|
-
ClassCollection.new(model_classes
|
95
|
+
ClassCollection.new(model_classes)
|
73
96
|
end
|
74
97
|
|
75
98
|
def load_models_from_paths(type, base_class)
|
@@ -78,20 +101,25 @@ class ModelLibrary
|
|
78
101
|
|
79
102
|
def load_models_from_path(type, path, base_class)
|
80
103
|
candidates_from_path(type, path).map do |file_path|
|
81
|
-
load_model(file_path.gsub(path, '').gsub('.rb', '').
|
104
|
+
load_model(file_path.gsub(path, '').gsub('.rb', '').camelize, base_class)
|
82
105
|
end
|
83
106
|
end
|
84
107
|
|
85
108
|
def candidates_from_path(type, path)
|
86
|
-
|
87
|
-
|
88
|
-
|
109
|
+
Dir["#{path}/**/*.rb"].select do |file_path|
|
110
|
+
case type
|
111
|
+
when 'page' then file_path.ends_with?('page.rb')
|
112
|
+
when 'widget' then file_path.ends_with?('_widget.rb')
|
113
|
+
else true
|
114
|
+
end
|
115
|
+
end
|
89
116
|
end
|
90
117
|
|
91
118
|
def load_model(class_name, base_class)
|
92
119
|
model_class = class_name.constantize
|
93
120
|
model_class if model_class.ancestors.include?(base_class)
|
94
|
-
rescue
|
121
|
+
rescue LoadError
|
122
|
+
# Ignore files with invalid models, e.g. empty files.
|
95
123
|
end
|
96
124
|
|
97
125
|
def load_custom_models(type, base_class)
|
@@ -107,6 +135,10 @@ class ModelLibrary
|
|
107
135
|
end
|
108
136
|
|
109
137
|
class DSL < Struct.new(:model_library)
|
138
|
+
def obj(*names)
|
139
|
+
model_library.custom_objs.push(*names)
|
140
|
+
end
|
141
|
+
|
110
142
|
def page(*names)
|
111
143
|
model_library.custom_pages.push(*names)
|
112
144
|
end
|
@@ -137,7 +137,7 @@ module Scrivito
|
|
137
137
|
# Accepts the name of an "obj_by" view, a list of keys.
|
138
138
|
# Returns a list of lists of Objs: a list of Objs for each given key.
|
139
139
|
def find_by_including_deleted(view, keys)
|
140
|
-
result = CmsBackend.
|
140
|
+
result = CmsBackend.find_obj_data_by(
|
141
141
|
workspace.revision,
|
142
142
|
view,
|
143
143
|
keys)
|
@@ -54,25 +54,7 @@ module Scrivito
|
|
54
54
|
|
55
55
|
def parse_binary_params(params)
|
56
56
|
return unless params
|
57
|
-
|
58
|
-
if params[:copy]
|
59
|
-
parse_copy_binary_params(params[:copy])
|
60
|
-
else
|
61
|
-
UploadedBinary.new(params)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def parse_copy_binary_params(params)
|
66
|
-
obj = Obj.find(params[:obj_id])
|
67
|
-
|
68
|
-
if widget_id = params[:widget_id]
|
69
|
-
widget = obj.widgets[widget_id]
|
70
|
-
raise_widget_not_found_error(widget_id) unless widget
|
71
|
-
end
|
72
|
-
|
73
|
-
if binary = (widget || obj)[params[:attribute_name]]
|
74
|
-
binary.copy(params.slice(:filename, :content_type).compact)
|
75
|
-
end
|
57
|
+
UploadedBinary.new(params)
|
76
58
|
end
|
77
59
|
|
78
60
|
def raise_widget_not_found_error(widget_id)
|
@@ -7,7 +7,7 @@ class ObjSearchEnumerator
|
|
7
7
|
|
8
8
|
def call(query, continuation=nil, fetched_ids=[])
|
9
9
|
query['continuation'] = continuation if continuation
|
10
|
-
response = CmsBackend.
|
10
|
+
response = CmsBackend.search_objs(workspace, query)
|
11
11
|
|
12
12
|
ObjSearchEnumerator::Batch.new(
|
13
13
|
build_objs(response),
|
@@ -349,7 +349,7 @@ module Scrivito
|
|
349
349
|
}
|
350
350
|
end
|
351
351
|
|
352
|
-
@size ||= CmsBackend.
|
352
|
+
@size ||= CmsBackend.search_objs(workspace, size_query)['total'].to_i
|
353
353
|
end
|
354
354
|
|
355
355
|
# Loads a single batch of search results from the backend.
|
data/lib/scrivito/ui_config.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
module Scrivito
|
2
2
|
|
3
|
-
class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extension_tags
|
3
|
+
class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extension_tags,
|
4
|
+
:obj_models, :widget_models)
|
4
5
|
def initialize(**named_params)
|
5
6
|
named_params.each { |key, value| self[key] = value }
|
6
7
|
end
|
7
8
|
|
8
9
|
def to_json
|
9
10
|
{
|
11
|
+
app_extension_tags: app_extension_tags,
|
10
12
|
editing_context: editing_context_config,
|
11
13
|
i18n: i18n_config,
|
12
14
|
is_development_mode: Rails.env.development?,
|
13
15
|
resource_dialog: resource_dialog_config,
|
14
16
|
user: user_config,
|
15
17
|
user_permissions: user_permissions_config,
|
16
|
-
|
18
|
+
obj_class: obj_class_config,
|
19
|
+
widget_class: widget_class_config,
|
17
20
|
}.to_json
|
18
21
|
end
|
19
22
|
|
@@ -46,6 +49,14 @@ class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extens
|
|
46
49
|
{locale: Scrivito::Configuration.ui_locale || I18n.locale}
|
47
50
|
end
|
48
51
|
|
52
|
+
def obj_class_config
|
53
|
+
obj_models.map(&:as_json)
|
54
|
+
end
|
55
|
+
|
56
|
+
def widget_class_config
|
57
|
+
widget_models.map(&:as_json)
|
58
|
+
end
|
59
|
+
|
49
60
|
def resource_dialog_config
|
50
61
|
return {} unless resource
|
51
62
|
{
|