infopark_fiona7 0.30.0.2 → 0.70.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+