infopark_fiona7 0.30.0.2 → 0.70.0.1
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/assets/javascripts/fiona7.js +1 -282
- data/app/assets/javascripts/fiona7_ui.js +335 -0
- data/app/assets/stylesheets/fiona7.css.scss +4 -36
- data/app/assets/stylesheets/fiona7_ui.css.scss +39 -0
- data/app/controllers/fiona7/blobs_controller.rb +13 -23
- data/app/controllers/fiona7/release_controller.rb +1 -0
- data/app/controllers/fiona7/sessions_controller.rb +3 -5
- data/app/helpers/fiona7_override_helper.rb +6 -2
- data/app/models/fiona7/edited_obj.rb +6 -1
- data/app/models/fiona7/released_obj.rb +11 -3
- data/app/models/fiona7/write_obj.rb +18 -3
- data/app/models/fiona7_login_page.rb +3 -0
- data/app/views/scrivito/ui/index.html.erb +16 -0
- data/config/routes.rb +2 -0
- data/infopark_fiona7.gemspec +6 -4
- data/lib/fiona7/builder/batch_widget_writer.rb +7 -3
- data/lib/fiona7/builder/obj_builder.rb +130 -42
- data/lib/fiona7/builder/obj_class_builder.rb +3 -59
- data/lib/fiona7/builder/obj_class_updater.rb +7 -44
- data/lib/fiona7/builder/obj_updater.rb +25 -7
- data/lib/fiona7/builder/widget_builder.rb +24 -0
- data/lib/fiona7/builder/widget_building.rb +2 -7
- data/lib/fiona7/builder/widget_updater.rb +21 -0
- data/lib/fiona7/controllers/content_service/obj_controller.rb +16 -25
- data/lib/fiona7/controllers/rest_api/blob_controller.rb +41 -2
- data/lib/fiona7/controllers/rest_api/obj_controller.rb +19 -7
- data/lib/fiona7/controllers/rest_api/workspace_controller.rb +1 -1
- data/lib/fiona7/engine.rb +58 -7
- data/lib/fiona7/fiona_connector_patches/basic_obj.rb +46 -0
- data/lib/fiona7/initializer.rb +15 -11
- data/lib/fiona7/json/obj_decorator.rb +53 -31
- data/lib/fiona7/json/reverse_obj_decorator.rb +36 -0
- data/lib/fiona7/json/widget_decorator.rb +3 -1
- data/lib/fiona7/link_converter/fiona_to_scrivito.rb +45 -13
- data/lib/fiona7/link_converter/scrivito_to_fiona.rb +1 -1
- data/lib/fiona7/middleware/server_detection_middleware.rb +27 -0
- data/lib/fiona7/middleware/table_switching_middleware.rb +33 -0
- data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +5 -11
- data/lib/fiona7/mode_switch/composite.rb +2 -4
- data/lib/fiona7/naive_search_engine.rb +66 -16
- data/lib/fiona7/routers/rest_api.rb +50 -45
- data/lib/fiona7/routing_monkey_patch.rb +5 -3
- data/lib/fiona7/scrivito_patches/attribute_content.rb +9 -10
- data/lib/fiona7/scrivito_patches/attribute_serializer.rb +15 -0
- data/lib/fiona7/scrivito_patches/basic_obj.rb +25 -19
- data/lib/fiona7/scrivito_patches/basic_widget.rb +4 -0
- data/lib/fiona7/scrivito_patches/binary.rb +452 -33
- data/lib/fiona7/scrivito_patches/client_config.rb +0 -19
- data/lib/fiona7/scrivito_patches/cms_backend.rb +48 -0
- data/lib/fiona7/scrivito_patches/cms_field_tag.rb +19 -0
- data/lib/fiona7/scrivito_patches/cms_rest_api.rb +20 -3
- data/lib/fiona7/scrivito_patches/cms_routing.rb +20 -34
- data/lib/fiona7/scrivito_patches/controller_actions.rb +0 -8
- data/lib/fiona7/scrivito_patches/migrator.rb +4 -0
- data/lib/fiona7/scrivito_patches/objs_controller.rb +18 -0
- data/lib/fiona7/scrivito_patches/type_computer.rb +12 -12
- data/lib/fiona7/scrivito_patches/webservice_controller.rb +21 -0
- data/lib/fiona7/scrivito_patches/workspace.rb +8 -5
- data/lib/fiona7/shadow_classes.rb +74 -0
- data/lib/fiona7/table_switcher.rb +39 -0
- data/lib/fiona7/type_loader.rb +63 -0
- data/lib/fiona7/type_register.rb +170 -89
- data/lib/fiona7/type_synchronizer.rb +68 -0
- data/lib/fiona7/version.rb +1 -1
- data/lib/fiona7/version_helper.rb +35 -54
- data/lib/fiona7/widget_resolver.rb +1 -1
- data/lib/tasks/fiona7_tasks.rake +0 -8
- metadata +57 -18
- data/lib/fiona7/controllers/rest_api/obj_class_controller.rb +0 -39
- data/lib/fiona7/json/obj_class_decorator.rb +0 -45
- data/lib/fiona7/mode_switch/constants.rb +0 -86
- data/lib/fiona7/type_register_mixin.rb +0 -9
@@ -4,7 +4,7 @@ module ActionDispatch
|
|
4
4
|
def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
|
5
5
|
raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
|
6
6
|
|
7
|
-
forbidden_paths = [::File.join(Gem.loaded_specs['scrivito_sdk'].full_gem_path, "config/
|
7
|
+
forbidden_paths = [::File.join(Gem.loaded_specs['scrivito_sdk'].full_gem_path, "config/routes.rb"),
|
8
8
|
::File.join(Gem.loaded_specs['infopark_fiona_connector'].full_gem_path, "config/cms_routes.rb")]
|
9
9
|
|
10
10
|
if caller.any? {|path| forbidden_paths.any? {|fp| path.include?(fp) } }
|
@@ -12,7 +12,6 @@ module ActionDispatch
|
|
12
12
|
end
|
13
13
|
|
14
14
|
if name && named_routes[name]
|
15
|
-
|
16
15
|
raise ArgumentError, "Invalid route name, already in use: '#{name}' \n" \
|
17
16
|
"You may have defined two routes with the same name using the `:as` option, or " \
|
18
17
|
"you may be overriding a route already defined by a resource with the same naming. " \
|
@@ -20,13 +19,16 @@ module ActionDispatch
|
|
20
19
|
"http://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
|
21
20
|
end
|
22
21
|
|
23
|
-
path =
|
22
|
+
path = conditions.delete :path_info
|
23
|
+
ast = conditions.delete :parsed_path_info
|
24
|
+
path = build_path(path, ast, requirements, anchor)
|
24
25
|
conditions = build_conditions(conditions, path.names.map { |x| x.to_sym })
|
25
26
|
|
26
27
|
route = @set.add_route(app, path, conditions, defaults, name)
|
27
28
|
named_routes[name] = route if name
|
28
29
|
route
|
29
30
|
end
|
31
|
+
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
require 'scrivito/attribute_content'
|
2
|
+
require 'fiona7/type_register'
|
2
3
|
|
3
4
|
module Scrivito
|
4
5
|
module AttributeContent
|
5
6
|
module ClassMethods
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
return attributes if type_computer.special_class?(self)
|
15
|
-
attributes.merge("_obj_class" => self.obj_class_name)
|
7
|
+
# patch attribute to notify type register
|
8
|
+
alias_method :orig_attribute, :attribute
|
9
|
+
def attribute(name, type, options = {})
|
10
|
+
orig_attribute(name, type, options)
|
11
|
+
ensure
|
12
|
+
if self.name.present?
|
13
|
+
Fiona7::TypeRegister.instance.add_usr_attr(self.name, name, type, options[:values])
|
14
|
+
end
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'scrivito/attribute_serializer'
|
2
|
+
|
3
|
+
module Scrivito
|
4
|
+
class AttributeSerializer
|
5
|
+
def serialize_binary_value(attribute_value, attribute_definition)
|
6
|
+
case attribute_value
|
7
|
+
when File then attribute_value
|
8
|
+
when UploadedBinary then attribute_value.params
|
9
|
+
else
|
10
|
+
raise_validation_error(attribute_definition.name,
|
11
|
+
'an instance of File, Scrivito::UploadedBinary or nil', attribute_value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -14,6 +14,15 @@ module Scrivito
|
|
14
14
|
id.to_s
|
15
15
|
end
|
16
16
|
|
17
|
+
def outdated?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def copy_binaries(attributes)
|
22
|
+
# TODO: what to do?
|
23
|
+
attributes
|
24
|
+
end
|
25
|
+
|
17
26
|
# Originally this method checks for conflicts
|
18
27
|
# which are impossible here, hence the method is stubbed out
|
19
28
|
def publishable?
|
@@ -27,7 +36,7 @@ module Scrivito
|
|
27
36
|
# it has to be worked around.
|
28
37
|
def file_extension
|
29
38
|
if (blob = find_blob)
|
30
|
-
blob.
|
39
|
+
File.extname(blob.filename)[1..-1]
|
31
40
|
else
|
32
41
|
""
|
33
42
|
end
|
@@ -47,24 +56,14 @@ module Scrivito
|
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
50
|
-
# This method may be called like this: image_tag(obj) in a view
|
51
|
-
# which is fundamentally broken. image_tag(scrivito_path(obj))
|
52
|
-
# should be called instead.
|
53
|
-
def body_data_url
|
54
|
-
if binary? && read_attribute('blob')
|
55
|
-
raise "This method is not supported by Fiona7 and should not be called, try using Scrivito::Binary#content or scrivito_url(obj) when appropriate"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
59
|
# Originally this method refers to the global Obj via ::Obj
|
60
60
|
def self.where(field, operator, value, boost = nil)
|
61
61
|
assert_not_basic_obj('.where')
|
62
62
|
if self == Obj || self == ::Obj
|
63
63
|
Workspace.current.objs.where(field, operator, value, boost)
|
64
64
|
else
|
65
|
-
|
66
|
-
|
67
|
-
.and(field, operator, value, boost)
|
65
|
+
Workspace.current.objs.where(:_obj_class, :equals, name)
|
66
|
+
.and(field, operator, value, boost)
|
68
67
|
end
|
69
68
|
end
|
70
69
|
|
@@ -74,19 +73,26 @@ module Scrivito
|
|
74
73
|
if self == Obj || self == ::Obj
|
75
74
|
Workspace.current.objs.all
|
76
75
|
else
|
77
|
-
|
78
|
-
find_all_by_obj_class(obj_class_name)
|
76
|
+
find_all_by_obj_class(name)
|
79
77
|
end
|
80
78
|
end
|
81
79
|
|
82
80
|
class << self
|
83
81
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
def inherited(subclass,*args)
|
83
|
+
super
|
84
|
+
if subclass.name == 'Obj' && !::RailsConnector.const_defined?('Obj', false)
|
85
|
+
::RailsConnector.const_set('Obj', ::RailsConnector::AbstractObj)
|
86
|
+
end
|
87
|
+
ensure
|
88
|
+
if subclass.name.present?
|
89
|
+
type_register = Fiona7::TypeRegister.instance
|
90
|
+
subclass.attribute_definitions.each do |attribute_definition|
|
91
|
+
type_register.add_usr_attr(subclass.name, attribute_definition.name, attribute_definition.type, attribute_definition.values.presence)
|
92
|
+
end
|
88
93
|
end
|
89
94
|
end
|
95
|
+
|
90
96
|
end
|
91
97
|
end
|
92
98
|
end
|
@@ -1,55 +1,474 @@
|
|
1
1
|
require 'scrivito/binary'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
require 'mini_magick'
|
4
|
+
|
5
|
+
|
6
|
+
module Fiona7
|
7
|
+
module BinaryHandling
|
8
|
+
class ParamEncoder
|
9
|
+
def initialize
|
10
|
+
self.verifier = ActiveSupport::MessageVerifier.new(
|
11
|
+
Rails.application.secrets.secret_key_base, serializer: ::JSON)
|
11
12
|
end
|
12
|
-
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
shadow_obj.body_length
|
17
|
-
else
|
18
|
-
0
|
14
|
+
def encode(params)
|
15
|
+
self.verifier.generate(params)
|
19
16
|
end
|
20
|
-
end
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
def decode(string)
|
19
|
+
self.verifier.verify(string)
|
20
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature => e
|
21
|
+
{}
|
25
22
|
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
attr_accessor :verifier
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
class MetaBinary
|
29
|
+
class ActualBinary
|
30
|
+
def initialize(binary_id, transformation=false)
|
31
|
+
self.binary_id = binary_id.to_i
|
32
|
+
self.transformation = transformation
|
33
|
+
self.obj = self.load_obj
|
34
|
+
end
|
35
|
+
protected
|
36
|
+
attr_accessor :binary_id, :transformation, :obj
|
37
|
+
|
38
|
+
def load_obj
|
39
|
+
if Fiona7.mode == :legacy
|
40
|
+
Fiona7::WriteObj.find(self.binary_id)
|
41
|
+
else
|
42
|
+
Fiona7::InternalReleasedObj.find(self.binary_id)
|
43
|
+
end
|
44
|
+
rescue ActiveRecord::RecordNotFound
|
45
|
+
nil
|
46
|
+
end
|
32
47
|
end
|
48
|
+
|
49
|
+
class UnmodifiedBinary < ActualBinary
|
50
|
+
def valid?
|
51
|
+
self.binary_id >= 0 && self.obj.try(:binary?)
|
52
|
+
end
|
53
|
+
|
54
|
+
def present?
|
55
|
+
!self.obj.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def filename
|
59
|
+
self.obj.filename
|
60
|
+
end
|
61
|
+
|
62
|
+
def filepath
|
63
|
+
self.obj.body_data_path
|
64
|
+
end
|
65
|
+
|
66
|
+
def length
|
67
|
+
self.obj.body_length
|
68
|
+
end
|
69
|
+
|
70
|
+
def width
|
71
|
+
if self.image
|
72
|
+
self.image[:width]
|
73
|
+
else
|
74
|
+
0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def height
|
79
|
+
if self.image
|
80
|
+
self.image[:height]
|
81
|
+
else
|
82
|
+
0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def mime_type
|
87
|
+
self.obj.mime_type
|
88
|
+
end
|
89
|
+
|
90
|
+
def last_changed
|
91
|
+
self.obj.last_changed.utc
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
def image
|
96
|
+
return @image if defined?(@image)
|
97
|
+
if self.filepath
|
98
|
+
@image = MiniMagick::Image.new(self.filepath)
|
99
|
+
else
|
100
|
+
@image = nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class TransformedBinary < UnmodifiedBinary
|
106
|
+
def valid?
|
107
|
+
super && valid_transformation?
|
108
|
+
end
|
109
|
+
|
110
|
+
def filename
|
111
|
+
::File.basename(self.transformed_filepath)
|
112
|
+
end
|
113
|
+
|
114
|
+
alias_method :original_filepath, :filepath
|
115
|
+
def filepath
|
116
|
+
self.transformed_filepath
|
117
|
+
end
|
118
|
+
|
119
|
+
def legnth
|
120
|
+
::File.size(self.transformed_filepath)
|
121
|
+
end
|
122
|
+
|
123
|
+
def last_changed
|
124
|
+
::File.mtime(self.transformed_filepath).utc
|
125
|
+
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
def valid_transformation?
|
129
|
+
true &&
|
130
|
+
(self.mime_type =~ /image\//) &&
|
131
|
+
(self.width.present? || self.height.present?) &&
|
132
|
+
(!self.width.present? || (1..4096).include?(self.width.to_i)) &&
|
133
|
+
(!self.height.present? || (1..4096).include?(self.height.to_i)) &&
|
134
|
+
((1..75).include?(self.quality.to_i)) &&
|
135
|
+
(self.fit == 'clip' || self.fit == 'crop') &&
|
136
|
+
(self.width.to_i + self.height.to_i < 4096) &&
|
137
|
+
(self.fit == 'clip' || (self.width.present? && self.height.present?))
|
138
|
+
end
|
139
|
+
|
140
|
+
def transformed_filepath
|
141
|
+
return @transformed_filepath if @transformed_filepath
|
142
|
+
return nil if self.original_filepath.nil?
|
143
|
+
|
144
|
+
output_filepath = original_filepath + self.transformed_filename
|
145
|
+
|
146
|
+
if ::File.exists?(output_filepath)
|
147
|
+
Rails.logger.debug("Transformed image #{output_filepath} already generated, serving")
|
148
|
+
return @transformed_filepath = output_filepath
|
149
|
+
else
|
150
|
+
Rails.logger.debug("Transforming image")
|
151
|
+
end
|
152
|
+
|
153
|
+
image = MiniMagick::Image.open(original_filepath)
|
154
|
+
|
155
|
+
if self.fit == 'clip'
|
156
|
+
image.combine_options do |b|
|
157
|
+
b.resize "#{self.width}x#{self.height}>"
|
158
|
+
end
|
159
|
+
elsif self.fit == 'crop'
|
160
|
+
image.combine_options do |b|
|
161
|
+
b.resize "#{self.width}x#{self.height}>"
|
162
|
+
b.gravity "center"
|
163
|
+
b.extent "#{self.width}x#{self.height}>"
|
164
|
+
end
|
165
|
+
else
|
166
|
+
raise 'invalid fit'
|
167
|
+
end
|
168
|
+
|
169
|
+
image.write(output_filepath)
|
170
|
+
@transformed_filepath = output_filepath
|
171
|
+
end
|
172
|
+
|
173
|
+
def transformed_filename
|
174
|
+
ext = ::File.extname(self.original_filepath)
|
175
|
+
"#{self.fit}_#{self.width}_#{self.height}_#{self.quality}#{ext}"
|
176
|
+
end
|
177
|
+
|
178
|
+
def transformation_with_fallback
|
179
|
+
@transformation_with_fallback ||= (self.transformation || {}).with_indifferent_access
|
180
|
+
end
|
181
|
+
|
182
|
+
def width
|
183
|
+
self.transformation_with_fallback[:width].to_s
|
184
|
+
end
|
185
|
+
|
186
|
+
def height
|
187
|
+
self.transformation_with_fallback[:height].to_s
|
188
|
+
end
|
189
|
+
|
190
|
+
def quality
|
191
|
+
self.transformation_with_fallback[:quality] || '75'
|
192
|
+
end
|
193
|
+
|
194
|
+
def fit
|
195
|
+
self.transformation_with_fallback[:fit] || 'clip'
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
delegate :valid?, :present?,
|
200
|
+
:filename, :filepath,
|
201
|
+
:mime_type, :length, :last_changed,
|
202
|
+
:width, :height,
|
203
|
+
:to => :implementation
|
204
|
+
|
205
|
+
def initialize(binary_id, transformation=false)
|
206
|
+
if transformation
|
207
|
+
self.implementation = TransformedBinary.new(binary_id, transformation)
|
208
|
+
else
|
209
|
+
self.implementation = UnmodifiedBinary.new(binary_id, transformation)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
protected
|
214
|
+
attr_accessor :implementation
|
215
|
+
|
33
216
|
end
|
34
217
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
218
|
+
module DeliveryMixin
|
219
|
+
# GET
|
220
|
+
def show
|
221
|
+
binary_id = binary_id_from_params
|
222
|
+
transformation = transformation_from_params
|
223
|
+
meta_binary = MetaBinary.new(binary_id, transformation)
|
224
|
+
|
225
|
+
if !meta_binary.present?
|
226
|
+
not_found
|
227
|
+
elsif !meta_binary.valid?
|
228
|
+
bad_request
|
229
|
+
elsif stale?(:last_modified => meta_binary.last_changed) && true
|
230
|
+
filename = meta_binary.filename
|
231
|
+
filepath = meta_binary.filepath
|
232
|
+
mime_type = meta_binary.mime_type
|
233
|
+
|
234
|
+
send_file(File.expand_path(filepath), {
|
235
|
+
:type => mime_type,
|
236
|
+
:filename => filename,
|
237
|
+
:disposition => 'inline'
|
238
|
+
})
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# HEAD
|
243
|
+
def query
|
244
|
+
binary_id = binary_id_from_params
|
245
|
+
transformation = transformation_from_params
|
246
|
+
meta_binary = BinaryHandling::MetaBinary.new(binary_id, transformation)
|
247
|
+
|
248
|
+
if !meta_binary.valid?
|
249
|
+
bad_request
|
250
|
+
elsif !meta_binary.present?
|
251
|
+
not_found
|
252
|
+
else
|
253
|
+
set_header('Content-Type', meta_binary.mime_type)
|
254
|
+
set_header('Content-Length', meta_binary.length)
|
255
|
+
set_header('Cache-Control', 'no-transform,public,max-age=300,s-maxage=900')
|
256
|
+
head_ok
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
protected
|
261
|
+
def bad_request
|
262
|
+
head 400
|
263
|
+
end
|
264
|
+
|
265
|
+
def not_found
|
266
|
+
head 404
|
267
|
+
end
|
268
|
+
|
269
|
+
def head_ok
|
270
|
+
head 200
|
39
271
|
end
|
40
272
|
end
|
41
273
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
274
|
+
|
275
|
+
class EmbeddedServer
|
276
|
+
class << self
|
277
|
+
attr_accessor :enable
|
278
|
+
end
|
279
|
+
|
280
|
+
self.enable = false
|
281
|
+
|
282
|
+
HOST = 'localhost'
|
283
|
+
PORT = 7104
|
284
|
+
extend MonitorMixin
|
285
|
+
|
286
|
+
require 'webrick'
|
287
|
+
|
288
|
+
class BinaryServerlet < ::WEBrick::HTTPServlet::AbstractServlet
|
289
|
+
class RequestHandler
|
290
|
+
|
291
|
+
include Fiona7::BinaryHandling::DeliveryMixin
|
292
|
+
|
293
|
+
def initialize(request, response)
|
294
|
+
self.request = request
|
295
|
+
self.response = response
|
296
|
+
end
|
297
|
+
|
298
|
+
protected
|
299
|
+
attr_accessor :request, :response
|
300
|
+
def binary_id_from_params
|
301
|
+
# TODO: handle malformed input
|
302
|
+
match = /\/_b\/([0-9]+)(\/(.*)(\.[a-z0-9A-Z]+)?)?/.match(self.request.request_uri.to_s)
|
303
|
+
if match
|
304
|
+
match[1]
|
305
|
+
else
|
306
|
+
0
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def transformation_from_params
|
311
|
+
if self.request.query_string
|
312
|
+
ParamEncoder.new.decode(
|
313
|
+
::CGI.parse(self.request.query_string)["t"]
|
314
|
+
)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def set_header(name, value)
|
319
|
+
self.response[name] = value
|
320
|
+
end
|
321
|
+
|
322
|
+
# minimal stubs for Rails API below
|
323
|
+
|
324
|
+
def stale?(*args)
|
325
|
+
true
|
326
|
+
end
|
327
|
+
|
328
|
+
def head(status)
|
329
|
+
self.response.status = status
|
330
|
+
end
|
331
|
+
|
332
|
+
def send_file(filepath, options={})
|
333
|
+
self.response['Content-Type'] = options[:type]
|
334
|
+
self.response['Content-Length'] = ::File.size(filepath)
|
335
|
+
self.response['Content-Disposition'] = "#{options[:disposition]}; filename=\"#{options[:filename]}\""
|
336
|
+
self.response.body = File.read(filepath)
|
337
|
+
self.response.status = 200
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def do_GET(request, response)
|
342
|
+
RequestHandler.new(request, response).show
|
343
|
+
end
|
344
|
+
|
345
|
+
def do_HEAD(request, response)
|
346
|
+
RequestHandler.new(request, response).query
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def self.running_instance
|
351
|
+
if !self.enable
|
352
|
+
return HOST, PORT
|
353
|
+
end
|
354
|
+
|
355
|
+
self.synchronize do
|
356
|
+
@server_thread ||= self.wait_for_server
|
357
|
+
|
358
|
+
Kernel.at_exit do
|
359
|
+
Process.kill("INT", @server_thread)
|
360
|
+
Process.kill("KILL", @server_thread)
|
361
|
+
end
|
362
|
+
|
363
|
+
return HOST, PORT
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def self.wait_for_server
|
368
|
+
pid = Process.fork do
|
369
|
+
self.run_server
|
370
|
+
end
|
371
|
+
# wait for webrick!
|
372
|
+
sleep 1
|
373
|
+
pid
|
374
|
+
end
|
375
|
+
|
376
|
+
def self.run_server
|
377
|
+
|
378
|
+
server = ::WEBrick::HTTPServer.new({
|
379
|
+
:Port => PORT, :DocumentRoot => '/dev/null',
|
380
|
+
#Logger: WEBrick::Log.new(Logger.new(nil)), AccessLog: []
|
381
|
+
})
|
382
|
+
|
383
|
+
server.mount '/', BinaryServerlet
|
384
|
+
|
385
|
+
Signal.trap('INT') do
|
386
|
+
server.shutdown
|
387
|
+
exit!
|
388
|
+
end
|
389
|
+
|
390
|
+
server.start
|
46
391
|
end
|
47
392
|
end
|
48
393
|
|
49
|
-
|
50
|
-
|
51
|
-
|
394
|
+
class UrlGenerator
|
395
|
+
attr_reader :blob_id, :access_type, :verb, :transformation
|
396
|
+
def initialize(blob_id, access_type, verb, transformation)
|
397
|
+
self.blob_id = blob_id
|
398
|
+
self.access_type = access_type
|
399
|
+
self.verb = verb
|
400
|
+
self.transformation = transformation
|
401
|
+
end
|
402
|
+
|
403
|
+
def generate
|
404
|
+
if server_detected?
|
405
|
+
hosted_server_url
|
406
|
+
else
|
407
|
+
embedded_server_url
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
protected
|
412
|
+
attr_writer :blob_id, :access_type, :verb, :transformation
|
413
|
+
def blob
|
414
|
+
if Fiona7.mode == :legacy
|
415
|
+
@blob ||= Fiona7::WriteObj.find(blob_id.to_i)
|
416
|
+
else
|
417
|
+
@blob ||= Fiona7::InternalReleasedObj.find(blob_id.to_i)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
def filename
|
422
|
+
self.blob.filename
|
423
|
+
rescue ActiveRecord::RecordNotFound
|
424
|
+
"null.null"
|
425
|
+
end
|
426
|
+
|
427
|
+
def server_detected?
|
428
|
+
Fiona7::Middleware::ServerDetectionMiddleware.server_detected?
|
429
|
+
end
|
430
|
+
|
431
|
+
def hosted_server_url
|
432
|
+
# TODO: use middleware for storing url
|
433
|
+
host = Fiona7::Middleware::ServerDetectionMiddleware.server_name
|
434
|
+
port = Fiona7::Middleware::ServerDetectionMiddleware.server_port
|
435
|
+
|
436
|
+
generate_url(host, port)
|
437
|
+
end
|
438
|
+
|
439
|
+
def embedded_server_url
|
440
|
+
host, port = EmbeddedServer.running_instance
|
441
|
+
generate_url(host, port)
|
442
|
+
end
|
443
|
+
|
444
|
+
def generate_url(host, port=80)
|
445
|
+
options = {}
|
446
|
+
options[:host] = host
|
447
|
+
options[:port] = port
|
448
|
+
options[:path] = "/_b/#{self.blob_id}/#{self.filename}"
|
449
|
+
if self.transformation.present?
|
450
|
+
self.validate_transformation!
|
451
|
+
options[:query] = self.encode_query_string
|
452
|
+
end
|
453
|
+
URI::HTTP.build(options).to_s
|
454
|
+
end
|
455
|
+
|
456
|
+
def encode_query_string
|
457
|
+
token = ParamEncoder.new.encode(self.transformation)
|
458
|
+
return "t=#{token}"
|
459
|
+
end
|
460
|
+
|
461
|
+
def validate_transformation!
|
462
|
+
MetaBinary.new(self.blob_id, self.transformation).valid? || raise(Scrivito::TransformationDefinitionError.new("Invalid transformation", "binary.unprocessable.image.transform.invalid_config"))
|
463
|
+
end
|
52
464
|
end
|
53
465
|
end
|
54
466
|
end
|
55
467
|
|
468
|
+
module Scrivito
|
469
|
+
# This class had been reworked to support uploads directly
|
470
|
+
# into CMS and not into S3
|
471
|
+
class Binary
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|