infopark_fiona7 1.1.0.0.10 → 1.2.0.0.0

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/fiona7_ui.js +96 -50
  3. data/app/assets/javascripts/scrivito_patches/models/blob.js +21 -0
  4. data/app/assets/javascripts/scrivito_patches/models/obj.js +1 -1
  5. data/app/controllers/fiona7/release_controller.rb +6 -2
  6. data/app/controllers/fiona7/sessions_controller.rb +3 -0
  7. data/app/controllers/fiona7/workflow_controller.rb +46 -0
  8. data/app/helpers/fiona7_login_helper.rb +16 -0
  9. data/app/helpers/fiona7_override_helper.rb +1 -1
  10. data/config/delayed_routes.rb +1 -0
  11. data/config/precedence_routes.rb +92 -0
  12. data/infopark_fiona7.gemspec +2 -2
  13. data/lib/fiona7/blob_id_generator.rb +13 -0
  14. data/lib/fiona7/builder/indirect_blob_builder.rb +71 -0
  15. data/lib/fiona7/builder/lazy_blob_copier.rb +207 -0
  16. data/lib/fiona7/builder/obj_builder.rb +29 -50
  17. data/lib/fiona7/builder/obj_class_builder.rb +20 -0
  18. data/lib/fiona7/controllers/rest_api/blob_controller.rb +19 -0
  19. data/lib/fiona7/controllers/rest_api/obj_controller.rb +8 -4
  20. data/lib/fiona7/controllers/rest_api/workspace_controller.rb +2 -1
  21. data/lib/fiona7/engine.rb +56 -2
  22. data/lib/fiona7/json/obj_decorator.rb +4 -1
  23. data/lib/fiona7/link_converter/fiona_to_scrivito.rb +3 -1
  24. data/lib/fiona7/link_converter/scrivito_to_fiona.rb +12 -1
  25. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +1 -71
  26. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk_slave.rb +1 -71
  27. data/lib/fiona7/recursive_object_finder.rb +32 -8
  28. data/lib/fiona7/routers/rest_api.rb +6 -7
  29. data/lib/fiona7/scrivito_patches/attribute_content.rb +1 -1
  30. data/lib/fiona7/scrivito_patches/attribute_serializer.rb +22 -1
  31. data/lib/fiona7/scrivito_patches/basic_obj.rb +27 -5
  32. data/lib/fiona7/scrivito_patches/cms_backend.rb +3 -22
  33. data/lib/fiona7/scrivito_patches/cms_rest_api.rb +2 -1
  34. data/lib/fiona7/scrivito_patches/cms_routing.rb +2 -2
  35. data/lib/fiona7/scrivito_patches/model_library.rb +3 -3
  36. data/lib/fiona7/scrivito_patches/page_config.rb +21 -1
  37. data/lib/fiona7/scrivito_patches/preset_routes.rb +15 -2
  38. data/lib/fiona7/scrivito_patches/routing_extensions.rb +33 -20
  39. data/lib/fiona7/scrivito_patches/workspace.rb +3 -1
  40. data/lib/fiona7/super_object_finder.rb +63 -0
  41. data/lib/fiona7/type_register.rb +35 -9
  42. data/lib/fiona7/verity_search_engine.rb +1 -1
  43. data/lib/fiona7/version.rb +1 -1
  44. metadata +13 -7
  45. data/config/routes.rb +0 -13
@@ -1,3 +1,5 @@
1
+ require 'fiona7/builder/lazy_blob_copier'
2
+
1
3
  module Fiona7
2
4
  module Controllers
3
5
  module RestAPI
@@ -29,6 +31,7 @@ module Fiona7
29
31
  }
30
32
  }
31
33
  end
34
+
32
35
  def metadata(blob_id)
33
36
  meta_binary = BinaryHandling::MetaBinary.new(blob_id)
34
37
  content_type = meta_binary.mime_type
@@ -50,6 +53,22 @@ module Fiona7
50
53
  }
51
54
  }
52
55
  end
56
+
57
+ def copy(blob_id, params)
58
+ input = params.symbolize_keys
59
+ blob_id = blob_id.to_i
60
+ destination_obj_id = input[:destination_obj_id]
61
+ filename = input[:filename]
62
+ content_type = input[:content_type]
63
+ destination_obj = Fiona7::WriteObj.find(destination_obj_id)
64
+
65
+ Fiona7::Builder::LazyBlobCopier.new({
66
+ destination_obj: destination_obj,
67
+ source_blob_id: blob_id,
68
+ filename: filename,
69
+ content_type: content_type
70
+ }).call.stringify_keys
71
+ end
53
72
  end
54
73
  end
55
74
  end
@@ -34,6 +34,8 @@ module Fiona7
34
34
 
35
35
  klass = EditedObj
36
36
  decorated = Fiona7::JSON::ReverseObjDecorator.new(klass, obj)
37
+
38
+ ::Fiona7.run_callbacks(:create_obj, obj.id)
37
39
 
38
40
  return ::JSON.parse(::ActiveSupport::JSON.encode(decorated))
39
41
  end
@@ -121,13 +123,13 @@ module Fiona7
121
123
 
122
124
  query = (params[:query] || []).dup
123
125
 
124
- puts "SEARCH: #{query}"
126
+ Rails.logger.debug "Executing search for: #{query.inspect}"
125
127
  if use_naive_search_engine?(query)
126
- puts "NAIVE"
128
+ Rails.logger.debug "Using DB-native lookup for search"
127
129
  search = NaiveSearchEngine.new(klass, query, offset, size, sort, order)
128
130
  else
129
- puts "VERITY"
130
- search = VeritySearchEngine.new(klass, query, offset, size, sort, order)
131
+ Rails.logger.debug "Using configured search engine: #{::Fiona7.search_engine.name}"
132
+ search = ::Fiona7.search_engine.new(klass, query, offset, size, sort, order)
131
133
  end
132
134
  result = search.results.map {|o_id| {id: o_id} }
133
135
  total = search.total
@@ -168,6 +170,8 @@ module Fiona7
168
170
  obj = Builder::ObjUpdater.new(values[:obj].dup.with_indifferent_access).build
169
171
  klass = EditedObj
170
172
  decorated = Fiona7::JSON::ReverseObjDecorator.new(klass, obj)
173
+
174
+ ::Fiona7.run_callbacks(:update_obj, obj.id)
171
175
  return ::JSON.parse(::ActiveSupport::JSON.encode(decorated))
172
176
  end
173
177
 
@@ -34,10 +34,11 @@ module Fiona7
34
34
 
35
35
  def publish(id)
36
36
  raise "Unexpected workspace_id: #{id}" unless id.to_s == "rtc"
37
- WriteObj.where(is_edited: 1).each do |obj|
37
+ WriteObj.where(is_edited: 1).order('path DESC').each do |obj|
38
38
  begin
39
39
  obj.take
40
40
  obj.release!
41
+ ::Fiona7.run_callbacks(:release_obj, obj.id) unless obj.path =~ /\/_widgets\//
41
42
  rescue => e
42
43
  raise "Release impossible of: #{obj.path} because: #{e.message}"
43
44
  end
data/lib/fiona7/engine.rb CHANGED
@@ -55,16 +55,48 @@ require 'fiona7/scrivito_user'
55
55
 
56
56
  require 'fiona7/type_synchronizer'
57
57
 
58
+
59
+ require 'fiona7/naive_search_engine'
60
+ require 'fiona7/verity_search_engine'
61
+
58
62
  module Fiona7
59
63
  mattr_accessor :mode
60
64
  mattr_accessor :login
61
65
  mattr_accessor :root
62
66
 
63
- class Config < Struct.new("Config", :mode, :instance, :host, :port, :username, :secret, :root_mode)
67
+ mattr_accessor :callbacks
68
+ self.callbacks = {
69
+ :create_obj => [],
70
+ :update_obj => [],
71
+ :release_obj => []
72
+ }
73
+
74
+ mattr_accessor :search_engine
75
+ self.search_engine = Fiona7::VeritySearchEngine
76
+
77
+ def self.run_callbacks(callback, *params)
78
+ (self.callbacks[callback] || []).each do |callback_proc|
79
+ begin
80
+ callback_proc.call(*params)
81
+ rescue => e
82
+ Rails.logger.error("An error occured when running a callback: #{callback} with #{params.inspect}")
83
+ Rails.logger.error("#{e.class}: #{e.message}")
84
+ Rails.logger.error(e.backtrace[0,30].join("\n"))
85
+ end
86
+ end
87
+ end
88
+
89
+ def self.workflows_enabled?
90
+ true
91
+ end
92
+
93
+ class Config < Struct.new("Config", :mode, :instance, :host, :port, :username, :secret, :root_mode, :dont_yell_at_me_for_abusing_attributes)
64
94
  end
65
95
 
96
+ mattr_accessor :config
97
+
66
98
  def self.configure(&block)
67
- Config.new.tap do |config|
99
+ self.config = Config.new.tap do |config|
68
100
  yield config
69
101
 
70
102
  Reactor::Configuration.xml_access = {
@@ -116,6 +148,11 @@ module Fiona7
116
148
  initializer.initialize_system
117
149
  end
118
150
 
151
+ initializer "fiona7.add_cms_routing_paths", :after => "scrivito.add_cms_routing_paths" do |app|
152
+ precedence_route = File.expand_path("precedence_routes.rb", paths['config'].to_a.first)
153
+ app.routes_reloader.paths.unshift(precedence_route)
154
+ end
155
+
119
156
  initializer "fiona7.mode_switch" do |app|
120
157
  mode = nil
121
158
 
@@ -154,6 +191,16 @@ module Fiona7
154
191
  ActionController::Base.__send__(:define_method, :rsession_auth) do
155
192
  if !Fiona7.login
156
193
  rsession.user_name = Fiona7.root unless rsession.user_name == Fiona7.root
194
+ else
195
+ # This is interessting! We check for an existing rsession
196
+ # and if we don't find any, we destroy rsession. Why?
197
+ # Calling rsession.destroy first constructs the session
198
+ # for the current user (root most likely), which is not
199
+ # really a thing that we want - being root by default
200
+ # should only happen in the root mode
201
+ if !session[:rsession]
202
+ rsession.destroy
203
+ end
157
204
  end
158
205
  end
159
206
  end
@@ -170,8 +217,15 @@ module Fiona7
170
217
  RailsConnector::Meta::EagerLoader.instance.obj_classes.each do |_, obj_class|
171
218
  type_register.read_mangled(obj_class.name)
172
219
  end
220
+ end
221
+
173
222
 
223
+ # Installs delayed, low-priority scrivito routes (primarily: permalink route)
224
+ initializer "fiona7.add_cms_routing_paths", :after => :add_routing_paths do |app|
225
+ cms_route = File.expand_path("delayed_routes.rb", paths['config'].to_a.first)
226
+ app.routes_reloader.paths.push(cms_route)
174
227
  end
228
+
175
229
  # This ensures that reactor is loaded in the app
176
230
  config.after_initialize { Fiona7::WriteObj }
177
231
 
@@ -9,6 +9,7 @@ require 'fiona7/assert'
9
9
  require 'fiona7/link_converter/fiona_to_scrivito'
10
10
  require 'fiona7/json/widget_decorator'
11
11
  require 'fiona7/widget_resolver'
12
+ require 'fiona7/blob_id_generator'
12
13
 
13
14
  module Fiona7
14
15
  module JSON
@@ -90,7 +91,7 @@ module Fiona7
90
91
  if !Fiona7.mode == :legacy || !@obj.binary?
91
92
  deserialize_binary(@obj.attr_values[real_attribute_name].try(:first))
92
93
  else
93
- {id: "%032d" % @obj.id.to_s}
94
+ {id: Fiona7::BlobIdGenerator.new(@obj.id, @obj.last_changed).call}
94
95
  end
95
96
  when :enum, :multienum, :text, :string
96
97
  if real_attribute_name == "suppress_export"
@@ -98,6 +99,8 @@ module Fiona7
98
99
  else
99
100
  @obj[real_attribute_name]
100
101
  end
102
+ when :number
103
+ @obj[real_attribute_name].to_f
101
104
  when :stringlist
102
105
  if Fiona7.mode == :legacy && real_attribute_name == "channels"
103
106
  @obj["channels"] || []
@@ -45,7 +45,9 @@ module Fiona7
45
45
  base += "##{link['fragment']}" if link['fragment'].present?
46
46
  base
47
47
  else
48
- link["url"]
48
+ # This cleans-up pseudo-external links.
49
+ # Such links have a external: scheme.
50
+ link["url"].to_s.sub(/^external:/, '')
49
51
  end
50
52
  end
51
53
 
@@ -20,10 +20,21 @@ module Fiona7
20
20
  end
21
21
  link_expressions.each do |expr|
22
22
  @value.gsub!(expr) do |string|
23
+ attr = $1
23
24
  target = $2
24
25
  objid = objid_from_target(target)
25
26
  if objid
26
- "#{$1}=\"#{obj_path(objid)}\""
27
+ # This is a normal objid link
28
+ "#{attr}=\"#{obj_path(objid)}\""
29
+ elsif target =~ /^#/
30
+ # This is a link with anchor only if such link
31
+ # is placed within a widget it would become
32
+ # invalid (because it would produce a self-link
33
+ # in the widget)
34
+ #
35
+ # This works around this problem by producing
36
+ # an external link instead.
37
+ "#{attr}=\"external:#{target}\""
27
38
  else
28
39
  string
29
40
  end
@@ -1,72 +1,2 @@
1
- Rails.application.routes.draw do
2
- mount Scrivito::SdkEngine, at: '/', as: :scrivito_engine
3
- end
4
-
5
- Scrivito::SdkEngine.routes.draw do
6
- get 'scrivito', to: 'scrivito/ui#index'
7
- get 'scrivito/*application_path', to: 'scrivito/ui#index', format: false
8
-
9
- scope '__scrivito', module: 'scrivito' do
10
- get ':id', to: 'cms_dispatch#index', as: :base_id, constraints: {id: /\h{4,}/}
11
-
12
- resources :objs, controller: 'objs', only: [:show, :create, :update, :destroy],
13
- defaults: {format: :json} do
14
- collection do
15
- get :page_class_selection
16
- get :search
17
- end
18
-
19
- member do
20
- get :widget
21
- get :widget_class_selection
22
- get :widget_modification
23
- get :conflicting_workspaces
24
- get :is_outdated
25
- get :binary_no_cache
26
-
27
- post :copy
28
- post :duplicate
29
-
30
- put :revert
31
- put :restore
32
- put :mark_resolved
33
- put :destroy_widget
34
- put :revert_widget
35
- put :restore_widget
36
- put :transfer_modifications
37
- end
38
- end
39
-
40
- resources :tasks, controller: 'tasks', only: [:show], defaults: {format: :json}
41
-
42
- get 'blobs/upload_permission' => 'blobs#upload_permission', defaults: {format: :json}
43
- put 'blobs/activate_upload' => 'blobs#activate_upload', defaults: {format: :json}
44
-
45
- resources :workspaces,
46
- controller: 'workspaces',
47
- only: [:index, :show, :create, :destroy],
48
- defaults: {format: :json} do
49
- member do
50
- put :rename
51
- put :memberships
52
- put :rebase
53
- put :publish
54
- get :check
55
- end
56
- end
57
-
58
- get 'users/suggest' => 'users#suggest', defaults: {format: :json}
59
- get 'suggest_completion' => 'completion#suggest', defaults: {format: :json}
60
-
61
- get 'render_widget/:id/show_widget/:widget_id' => 'cms_dispatch#show_widget'
62
- get 'render_widget/:id/widget_details/:widget_id' => 'cms_dispatch#widget_details'
63
-
64
- get 'page_details/:id' => 'cms_dispatch#page_details'
65
- get 'resource_details/:resource_id', to: 'ui#index'
66
-
67
- get 'to_binary' => 'binary_redirect#to_binary', as: :binary
68
- end
69
- end
70
-
71
- Scrivito::PresetRoutes.install_into(Rails.application.routes)
1
+ Scrivito::PresetRoutes.install_into(Rails.application.routes, true)
72
2
 
@@ -1,72 +1,2 @@
1
- Rails.application.routes.draw do
2
- mount Scrivito::SdkEngine, at: '/', as: :scrivito_engine
3
- end
4
-
5
- Scrivito::SdkEngine.routes.draw do
6
- get 'scrivito', to: 'scrivito/ui#index'
7
- get 'scrivito/*application_path', to: 'scrivito/ui#index', format: false
8
-
9
- scope '__scrivito', module: 'scrivito' do
10
- get ':id', to: 'cms_dispatch#index', as: :base_id, constraints: {id: /\h{4,}/}
11
-
12
- resources :objs, controller: 'objs', only: [:show, :create, :update, :destroy],
13
- defaults: {format: :json} do
14
- collection do
15
- get :page_class_selection
16
- get :search
17
- end
18
-
19
- member do
20
- get :widget
21
- get :widget_class_selection
22
- get :widget_modification
23
- get :conflicting_workspaces
24
- get :is_outdated
25
- get :binary_no_cache
26
-
27
- post :copy
28
- post :duplicate
29
-
30
- put :revert
31
- put :restore
32
- put :mark_resolved
33
- put :destroy_widget
34
- put :revert_widget
35
- put :restore_widget
36
- put :transfer_modifications
37
- end
38
- end
39
-
40
- resources :tasks, controller: 'tasks', only: [:show], defaults: {format: :json}
41
-
42
- get 'blobs/upload_permission' => 'blobs#upload_permission', defaults: {format: :json}
43
- put 'blobs/activate_upload' => 'blobs#activate_upload', defaults: {format: :json}
44
-
45
- resources :workspaces,
46
- controller: 'workspaces',
47
- only: [:index, :show, :create, :destroy],
48
- defaults: {format: :json} do
49
- member do
50
- put :rename
51
- put :memberships
52
- put :rebase
53
- put :publish
54
- get :check
55
- end
56
- end
57
-
58
- get 'users/suggest' => 'users#suggest', defaults: {format: :json}
59
- get 'suggest_completion' => 'completion#suggest', defaults: {format: :json}
60
-
61
- get 'render_widget/:id/show_widget/:widget_id' => 'cms_dispatch#show_widget'
62
- get 'render_widget/:id/widget_details/:widget_id' => 'cms_dispatch#widget_details'
63
-
64
- get 'page_details/:id' => 'cms_dispatch#page_details'
65
- get 'resource_details/:resource_id', to: 'ui#index'
66
-
67
- get 'to_binary' => 'binary_redirect#to_binary', as: :binary
68
- end
69
- end
70
-
71
- Scrivito::PresetRoutes.install_slave_into(Rails.application.routes)
1
+ Scrivito::PresetRoutes.install_slave_into(Rails.application.routes, true)
72
2
 
@@ -73,10 +73,22 @@ module Fiona7
73
73
 
74
74
  def find_images(obj)
75
75
  find_selected(obj) do |link, attribute|
76
- if link.internal?
77
- destination_object = link.destination_object
78
- if destination_object && destination_object.image?
79
- true
76
+ if Fiona7.mode == :legacy
77
+ if link.internal?
78
+ destination_object = link.destination_object
79
+ if destination_object && destination_object.image?
80
+ true
81
+ end
82
+ end
83
+ else
84
+ if link.internal?
85
+ destination_object = link.destination_object
86
+ # now we check whether destination_object links X_Image
87
+ attribute = Fiona7::AttributeNameMangler.new(:blob, destination_object.obj_class).mangle
88
+ blob_link = (destination_object[attribute] || []).first
89
+ if blob_link && blob_link.internal? && blob_link.destination_object.try(:obj_class) == 'X_Image'
90
+ true
91
+ end
80
92
  end
81
93
  end
82
94
  end
@@ -84,10 +96,22 @@ module Fiona7
84
96
 
85
97
  def find_downloads(obj)
86
98
  find_selected(obj) do |link, attribute|
87
- if link.internal?
88
- destination_object = link.destination_object
89
- if destination_object && destination_object.generic?
90
- true
99
+ if Fiona7.mode == :legacy
100
+ if link.internal?
101
+ destination_object = link.destination_object
102
+ if destination_object && destination_object.generic?
103
+ true
104
+ end
105
+ end
106
+ else
107
+ if link.internal?
108
+ destination_object = link.destination_object
109
+ # now we check whether destination_object links X_Generic
110
+ attribute = Fiona7::AttributeNameMangler.new(:blob, destination_object.obj_class).mangle
111
+ blob_link = (destination_object[attribute] || []).first
112
+ if blob_link && blob_link.internal? && blob_link.destination_object.try(:obj_class) == 'X_Generic'
113
+ true
114
+ end
91
115
  end
92
116
  end
93
117
  end
@@ -29,7 +29,7 @@ class Scrivito::CmsRestApi
29
29
  resource_path = '/' + resource_path
30
30
  end
31
31
 
32
- $stdout.puts "DEBUG GET: #{resource_path}"
32
+ #Rails.logger.debug "F7 REST GET: #{resource_path}"
33
33
  case resource_path
34
34
  when /\A\/?revisions\/[a-zA-Z0-9_-]+\/objs\/mget\Z/
35
35
  _, _, revision_id, _, _ = *resource_path.split("/")
@@ -68,7 +68,6 @@ class Scrivito::CmsRestApi
68
68
  _, _, blob_id = *resource_path.split("/")
69
69
  Fiona7::Controllers::RestAPI::BlobController.new.metadata(blob_id)
70
70
  else
71
- $stdout.puts "GET: #{resource_path}"
72
71
  original_get(resource_path, payload, options||{})
73
72
  end
74
73
  end
@@ -93,7 +92,6 @@ class Scrivito::CmsRestApi
93
92
  _, _, workspace_id, _, obj_id = *resource_path.split("/")
94
93
  Fiona7::Controllers::RestAPI::ObjController.new.destroy(workspace_id, obj_id)
95
94
  else
96
- #$stdout.puts "DELETE: #{resource_path}"
97
95
  original_delete(resource_path, payload, options||{})
98
96
  end
99
97
  end
@@ -106,7 +104,7 @@ class Scrivito::CmsRestApi
106
104
  resource_path = '/' + resource_path
107
105
  end
108
106
 
109
- #$stdout.puts "DEBUG POST: #{resource_path}"
107
+ #Rails.logger.debug "F7 REST POST: #{resource_path}"
110
108
  case resource_path
111
109
  when /\A\/?workspaces\Z/
112
110
  Fiona7::Controllers::RestAPI::WorkspaceController.new.create(payload)
@@ -114,7 +112,6 @@ class Scrivito::CmsRestApi
114
112
  _, _, workspace_id = *resource_path.split("/")
115
113
  Fiona7::Controllers::RestAPI::ObjController.new.create(workspace_id, payload)
116
114
  else
117
- #$stdout.puts "POST: #{resource_path}"
118
115
  original_post(resource_path, payload, options||{})
119
116
  end
120
117
  end
@@ -127,7 +124,7 @@ class Scrivito::CmsRestApi
127
124
  resource_path = '/' + resource_path
128
125
  end
129
126
 
130
- #$stdout.puts "DEBUG PUT: #{resource_path}"
127
+ #Rails.logger.debug "F7 PUT: #{resource_path}"
131
128
  case resource_path
132
129
  when /\A\/?workspaces\/[a-zA-Z0-9]+\/objs\/[a-zA-Z0-9]+\Z/
133
130
  _, _, workspace_id, _, obj_id = *resource_path.split("/")
@@ -143,8 +140,10 @@ class Scrivito::CmsRestApi
143
140
  when /\A\/?workspaces\/[a-zA-Z0-9]+/
144
141
  _, _, workspace_id = *resource_path.split("/")
145
142
  Fiona7::Controllers::RestAPI::WorkspaceController.new.update(workspace_id)
143
+ when /\A\/?blobs\/[a-zA-Z0-9]+\/copy/
144
+ _, _, blob_id, _ = * resource_path.split("/")
145
+ Fiona7::Controllers::RestAPI::BlobController.new.copy(blob_id, payload)
146
146
  else
147
- #$stdout.puts "PUT: #{resource_path}"
148
147
  original_put(resource_path, payload, options||{})
149
148
  end
150
149
  end