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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/fiona7.js +1 -282
  3. data/app/assets/javascripts/fiona7_ui.js +335 -0
  4. data/app/assets/stylesheets/fiona7.css.scss +4 -36
  5. data/app/assets/stylesheets/fiona7_ui.css.scss +39 -0
  6. data/app/controllers/fiona7/blobs_controller.rb +13 -23
  7. data/app/controllers/fiona7/release_controller.rb +1 -0
  8. data/app/controllers/fiona7/sessions_controller.rb +3 -5
  9. data/app/helpers/fiona7_override_helper.rb +6 -2
  10. data/app/models/fiona7/edited_obj.rb +6 -1
  11. data/app/models/fiona7/released_obj.rb +11 -3
  12. data/app/models/fiona7/write_obj.rb +18 -3
  13. data/app/models/fiona7_login_page.rb +3 -0
  14. data/app/views/scrivito/ui/index.html.erb +16 -0
  15. data/config/routes.rb +2 -0
  16. data/infopark_fiona7.gemspec +6 -4
  17. data/lib/fiona7/builder/batch_widget_writer.rb +7 -3
  18. data/lib/fiona7/builder/obj_builder.rb +130 -42
  19. data/lib/fiona7/builder/obj_class_builder.rb +3 -59
  20. data/lib/fiona7/builder/obj_class_updater.rb +7 -44
  21. data/lib/fiona7/builder/obj_updater.rb +25 -7
  22. data/lib/fiona7/builder/widget_builder.rb +24 -0
  23. data/lib/fiona7/builder/widget_building.rb +2 -7
  24. data/lib/fiona7/builder/widget_updater.rb +21 -0
  25. data/lib/fiona7/controllers/content_service/obj_controller.rb +16 -25
  26. data/lib/fiona7/controllers/rest_api/blob_controller.rb +41 -2
  27. data/lib/fiona7/controllers/rest_api/obj_controller.rb +19 -7
  28. data/lib/fiona7/controllers/rest_api/workspace_controller.rb +1 -1
  29. data/lib/fiona7/engine.rb +58 -7
  30. data/lib/fiona7/fiona_connector_patches/basic_obj.rb +46 -0
  31. data/lib/fiona7/initializer.rb +15 -11
  32. data/lib/fiona7/json/obj_decorator.rb +53 -31
  33. data/lib/fiona7/json/reverse_obj_decorator.rb +36 -0
  34. data/lib/fiona7/json/widget_decorator.rb +3 -1
  35. data/lib/fiona7/link_converter/fiona_to_scrivito.rb +45 -13
  36. data/lib/fiona7/link_converter/scrivito_to_fiona.rb +1 -1
  37. data/lib/fiona7/middleware/server_detection_middleware.rb +27 -0
  38. data/lib/fiona7/middleware/table_switching_middleware.rb +33 -0
  39. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +5 -11
  40. data/lib/fiona7/mode_switch/composite.rb +2 -4
  41. data/lib/fiona7/naive_search_engine.rb +66 -16
  42. data/lib/fiona7/routers/rest_api.rb +50 -45
  43. data/lib/fiona7/routing_monkey_patch.rb +5 -3
  44. data/lib/fiona7/scrivito_patches/attribute_content.rb +9 -10
  45. data/lib/fiona7/scrivito_patches/attribute_serializer.rb +15 -0
  46. data/lib/fiona7/scrivito_patches/basic_obj.rb +25 -19
  47. data/lib/fiona7/scrivito_patches/basic_widget.rb +4 -0
  48. data/lib/fiona7/scrivito_patches/binary.rb +452 -33
  49. data/lib/fiona7/scrivito_patches/client_config.rb +0 -19
  50. data/lib/fiona7/scrivito_patches/cms_backend.rb +48 -0
  51. data/lib/fiona7/scrivito_patches/cms_field_tag.rb +19 -0
  52. data/lib/fiona7/scrivito_patches/cms_rest_api.rb +20 -3
  53. data/lib/fiona7/scrivito_patches/cms_routing.rb +20 -34
  54. data/lib/fiona7/scrivito_patches/controller_actions.rb +0 -8
  55. data/lib/fiona7/scrivito_patches/migrator.rb +4 -0
  56. data/lib/fiona7/scrivito_patches/objs_controller.rb +18 -0
  57. data/lib/fiona7/scrivito_patches/type_computer.rb +12 -12
  58. data/lib/fiona7/scrivito_patches/webservice_controller.rb +21 -0
  59. data/lib/fiona7/scrivito_patches/workspace.rb +8 -5
  60. data/lib/fiona7/shadow_classes.rb +74 -0
  61. data/lib/fiona7/table_switcher.rb +39 -0
  62. data/lib/fiona7/type_loader.rb +63 -0
  63. data/lib/fiona7/type_register.rb +170 -89
  64. data/lib/fiona7/type_synchronizer.rb +68 -0
  65. data/lib/fiona7/version.rb +1 -1
  66. data/lib/fiona7/version_helper.rb +35 -54
  67. data/lib/fiona7/widget_resolver.rb +1 -1
  68. data/lib/tasks/fiona7_tasks.rake +0 -8
  69. metadata +57 -18
  70. data/lib/fiona7/controllers/rest_api/obj_class_controller.rb +0 -39
  71. data/lib/fiona7/json/obj_class_decorator.rb +0 -45
  72. data/lib/fiona7/mode_switch/constants.rb +0 -86
  73. 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/cms_routes.rb"),
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 = build_path(conditions.delete(:path_info), requirements, SEPARATORS, anchor)
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
- # This is new. It returns the obj class name for given subclass of BasicObj or nil
7
- def obj_class_name
8
- self.name.split('::').last if self != Obj && self != ::Obj
9
- end
10
-
11
- # Patch to work-around Scrivito::... classes in legacy mode
12
- def with_default_obj_class(attributes)
13
- return attributes if attributes[:_obj_class] || attributes["_obj_class"]
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.file_extension
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
- assert_has_obj_class('.where')
66
- Workspace.current.objs.where(:_obj_class, :equals, obj_class_name)
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
- assert_has_obj_class('.all')
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 assert_has_obj_class(method_name)
85
- unless Workspace.current.obj_classes[obj_class_name].present?
86
- raise ScrivitoError, "#{name} has no corresponding ObjClass."
87
- + " Please use Obj.#{method_name} instead."
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
@@ -10,5 +10,9 @@ module Scrivito
10
10
  super
11
11
  end
12
12
  end
13
+
14
+ def self.widget_class
15
+ self
16
+ end
13
17
  end
14
18
  end
@@ -1,55 +1,474 @@
1
1
  require 'scrivito/binary'
2
2
 
3
- module Scrivito
4
- # This class had been reworked to support uploads directly
5
- # into CMS and not into S3
6
- class Binary
7
- # new implementation
8
- def content_type
9
- if shadow_obj
10
- shadow_obj.mime_type
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
- def content_length
15
- if shadow_obj
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
- def filename
23
- if shadow_obj
24
- shadow_obj.name + '.' + shadow_obj.file_extension
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
- # New API call. Allows to read the extension of the stored file.
29
- def file_extension
30
- if shadow_obj
31
- shadow_obj.file_extension
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
- # New API call. Allows to access the contents of the blob.
36
- def content
37
- if shadow_obj
38
- shadow_obj.body
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
- def url
43
- ActiveSupport::Deprecation.warn("This method should never be called. Use scrivito_path or scrvito_url whenever possible")
44
- if shadow_obj
45
- Rails.application.routes.url_helpers.fiona7_blob_path(id: @id, name: self.filename)
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
- private
50
- def shadow_obj
51
- @shadow_obj ||= Fiona7::InternalReleasedObj.find(@id.to_i) if @id.to_i != 0
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
+