infopark_fiona7 0.71.1.12 → 1.1.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/fiona7_ui.js +67 -0
  3. data/app/assets/stylesheets/fiona7_ui.css.scss +29 -0
  4. data/app/controllers/fiona7/release_controller.rb +37 -75
  5. data/app/controllers/scrivito/cms_dispatch_controller.rb +2 -12
  6. data/app/controllers/scrivito/objs_controller.rb +41 -13
  7. data/app/controllers/scrivito/webservice_controller.rb +4 -3
  8. data/app/views/fiona7/release/preview.html.erb +73 -0
  9. data/config/routes.rb +3 -1
  10. data/infopark_fiona7.gemspec +1 -1
  11. data/lib/fiona7/assert.rb +4 -0
  12. data/lib/fiona7/attribute_name_mangler.rb +19 -0
  13. data/lib/fiona7/attribute_names_from_cms.rb +17 -0
  14. data/lib/fiona7/attribute_names_from_queries.rb +17 -0
  15. data/lib/fiona7/builder/obj_builder.rb +3 -2
  16. data/lib/fiona7/builder/obj_updater.rb +2 -2
  17. data/lib/fiona7/builder/widget_builder.rb +1 -1
  18. data/lib/fiona7/builder/widget_updater.rb +2 -2
  19. data/lib/fiona7/complex_object.rb +24 -0
  20. data/lib/fiona7/controllers/rest_api/obj_controller.rb +96 -24
  21. data/lib/fiona7/controllers/rest_api/workspace_controller.rb +23 -2
  22. data/lib/fiona7/engine.rb +11 -23
  23. data/lib/fiona7/facet_builder.rb +136 -0
  24. data/lib/fiona7/json/reverse_obj_decorator.rb +2 -0
  25. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +68 -10
  26. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk_slave.rb +66 -14
  27. data/lib/fiona7/mode_switch/views.rb +2 -2
  28. data/lib/fiona7/naive_search_engine.rb +40 -5
  29. data/lib/fiona7/obj_class_name_demangler.rb +11 -0
  30. data/lib/fiona7/obj_class_name_mangler.rb +11 -0
  31. data/lib/fiona7/obj_classes_from_cms.rb +14 -0
  32. data/lib/fiona7/obj_classes_from_queries.rb +11 -0
  33. data/lib/fiona7/recursive_object_finder.rb +149 -0
  34. data/lib/fiona7/routers/rest_api.rb +14 -1
  35. data/lib/fiona7/routing_monkey_patch.rb +5 -2
  36. data/lib/fiona7/scrivito_patches/attribute_serializer.rb +1 -1
  37. data/lib/fiona7/scrivito_patches/basic_obj.rb +4 -9
  38. data/lib/fiona7/scrivito_patches/basic_widget.rb +0 -9
  39. data/lib/fiona7/scrivito_patches/cms_backend.rb +11 -16
  40. data/lib/fiona7/scrivito_patches/cms_rest_api.rb +1 -1
  41. data/lib/fiona7/scrivito_patches/cms_routing.rb +50 -33
  42. data/lib/fiona7/scrivito_patches/link_parser.rb +6 -13
  43. data/lib/fiona7/scrivito_patches/log_subscriber.rb +18 -0
  44. data/lib/fiona7/scrivito_patches/preset_routes.rb +47 -0
  45. data/lib/fiona7/scrivito_patches/routing_extensions.rb +48 -0
  46. data/lib/fiona7/search_engine.rb +4 -0
  47. data/lib/fiona7/type_loader.rb +5 -4
  48. data/lib/fiona7/type_register.rb +13 -27
  49. data/lib/fiona7/type_synchronizer.rb +8 -6
  50. data/lib/fiona7/verity_search_engine.rb +77 -30
  51. data/lib/fiona7/version.rb +1 -1
  52. metadata +18 -13
  53. data/app/models/rails_connector/abstract_obj.rb +0 -24
  54. data/lib/fiona7/controllers/content_service/obj_controller.rb +0 -121
  55. data/lib/fiona7/controllers/content_service/workspace_controller.rb +0 -19
  56. data/lib/fiona7/recursive_link_resolver.rb +0 -93
  57. data/lib/fiona7/routers/content_service.rb +0 -19
  58. data/lib/fiona7/scrivito_patches/client_config.rb +0 -0
  59. data/lib/fiona7/scrivito_patches/controller_actions.rb +0 -6
  60. data/lib/fiona7/scrivito_patches/obj_class.rb +0 -16
  61. data/lib/fiona7/scrivito_patches/obj_data_from_rest.rb +0 -30
@@ -0,0 +1,136 @@
1
+ require "fiona7/verity_search_engine"
2
+
3
+ module Fiona7
4
+ class FacetBuilder
5
+ def initialize(facet_params, query, klass)
6
+ @query = query
7
+ @klass = klass
8
+
9
+ @attribute = facet_params[:attribute]
10
+
11
+ @limit = [facet_params[:limit] || 20, 100].min # default = 20, limit <= 100
12
+ @fake_limit = 100
13
+ @include_objs = facet_params[:include_objs] || false
14
+
15
+ @known_values = Set.new
16
+ @facets = []
17
+ @next_facets = []
18
+ end
19
+
20
+ def build
21
+ @facets << fetch_more_facets until limit_reached or !more_facets_available
22
+
23
+ # adjust totals
24
+ for index in 0.upto(@facets.length-2)
25
+ next_facet_total = @facets[index+1].first[:total] rescue 0
26
+ @facets[index].each do |facet|
27
+ facet[:total] -= next_facet_total
28
+ end
29
+ end
30
+
31
+ # flatten
32
+ @facets.flatten!
33
+
34
+ # sort
35
+ @facets.sort_by! {|f| f[:total] }.reverse!
36
+
37
+ # delete superfluous elements
38
+ @facets.slice!(@limit, @facets.length)
39
+
40
+ # add included objs
41
+ if @include_objs
42
+ @facets.each do |facet|
43
+ include_objs_query = @query.dup
44
+ include_objs_query << {field: @attribute, operator: :__in__, value: facet[:value]}
45
+ search = VeritySearchEngine.new(@klass, include_objs_query, 0, @include_objs, @attribute, :desc)
46
+ facet[:results] = search.results.map {|o_id| {id: o_id.to_s}}
47
+ # this gives a true total!
48
+ facet[:total] = search.total
49
+ end
50
+ end
51
+
52
+ @facets
53
+ end
54
+
55
+ protected
56
+ def limit_reached
57
+ (@fake_limit -= 1) < 0
58
+ end
59
+
60
+ def fetch_more_facets
61
+ @next_facets
62
+ end
63
+
64
+ def more_facets_available
65
+ @next_facets = []
66
+
67
+ search = build_search
68
+ return false if search.results.empty?
69
+
70
+ sample_object = Fiona7::WriteObj.where(obj_id: search.results).first
71
+ return false if sample_object.nil?
72
+ new_values = get_attribute_values(sample_object)
73
+
74
+ new_values.each do |new_value|
75
+ next if @known_values.include?(new_value)
76
+ @known_values << new_value
77
+
78
+ @next_facets << {
79
+ value: new_value,
80
+ total: search.total
81
+ }
82
+ end
83
+
84
+ return !@next_facets.empty?
85
+ end
86
+
87
+ def build_search
88
+ facet_query = @query.dup
89
+ facet_query << {field: @attribute, operator: :__not_in__, value: serialize_known_values} unless @known_values.empty?
90
+ facet_query << any_value_present_in_attribute_query
91
+ # search engine likes to return object which do not exist anymore
92
+ # hence we try ten objects
93
+ facet_size = 10
94
+ facet_offset = 0
95
+ facet_sort = @attribute
96
+ facet_order = :desc
97
+
98
+ VeritySearchEngine.new(@klass, facet_query, facet_offset, facet_size, facet_sort, facet_order)
99
+ end
100
+
101
+ # TODO: remove this ugly code
102
+ def get_attribute_values(sample_object)
103
+ # TODO: extend this code to handle stringlists and multienums
104
+ type_definition = Fiona7::TypeRegister.instance.read_mangled(sample_object.obj_class)
105
+ attribute = type_definition.find_attribute(@attribute)
106
+
107
+ return nil unless attribute
108
+
109
+ if attribute.type == :stringlist
110
+ # TODO: remove deserialization duplication
111
+ deserialized = ::JSON.parse(sample_object[attribute.real_name]) rescue []
112
+ deserialized.kind_of?(Array) ? deserialized : []
113
+ elsif attribute.real_type == :multienum
114
+ sample_object[attribute.real_name] || []
115
+ else
116
+ # TODO: add warning/handling for wrong attributes
117
+ [sample_object[attribute.real_name].to_s]
118
+ end
119
+ end
120
+
121
+ def any_value_present_in_attribute_query
122
+ letters = ('a'..'z').map {|l| "*#{l}*" }
123
+ numbers = ('0'..'9').map {|l| "*#{l}*" }
124
+ sanity_patterns = letters + numbers
125
+
126
+ {field: @attribute, operator: :__in__, value: sanity_patterns}
127
+ end
128
+
129
+ def serialize_known_values
130
+ @known_values.map do |kv|
131
+ kv.blank? ? "dummy123dummy456dummy" : kv.to_s
132
+ end
133
+ end
134
+
135
+ end
136
+ end
@@ -1,3 +1,5 @@
1
+ require "fiona7/json/obj_decorator"
2
+
1
3
  module Fiona7
2
4
  module JSON
3
5
  class ReverseObjDecorator < ObjDecorator
@@ -1,14 +1,72 @@
1
1
  Rails.application.routes.draw do
2
- match '/', via: :all, to: 'scrivito/cms_dispatch#index', as: :scrivito_root
2
+ mount Scrivito::SdkEngine, at: '/', as: :scrivito_engine
3
+ end
3
4
 
4
- with_options via: :all, constraints: {id: /[0-9]{4,16}/} do |proxy|
5
- proxy.match '(/)(*slug-):id', to: 'scrivito/cms_dispatch#index', as: :cms_id
6
- proxy.match ':id(/*slug)', to: 'scrivito/cms_dispatch#legacy', as: :cms_legacy_id
7
- end
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}
8
41
 
9
- match '/*permalink',
10
- to: 'scrivito/cms_dispatch#index',
11
- as: :scrivito_permalink,
12
- format: false,
13
- via: :all
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
14
69
  end
70
+
71
+ Scrivito::PresetRoutes.install_into(Rails.application.routes)
72
+
@@ -1,20 +1,72 @@
1
1
  Rails.application.routes.draw do
2
- get '/f7(/)' => 'scrivito/cms_dispatch#index', as: :scrivito_root
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
3
29
 
4
- get '__scrivito/render_widget/:id/show_widget/:widget_id' => 'scrivito/cms_dispatch#show_widget'
5
- get '__scrivito/render_widget/:id/widget_details/:widget_id' => 'scrivito/cms_dispatch#widget_details'
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
6
39
 
7
- get '/__scrivito/details_page/:resource_id' => 'scrivito/cms_dispatch#details_page'
40
+ resources :tasks, controller: 'tasks', only: [:show], defaults: {format: :json}
8
41
 
9
- match '/f7/:id(/*slug)',
10
- to: 'scrivito/cms_dispatch#index',
11
- constraints: { id: /\d+|[0-9a-f]{16}/ },
12
- as: 'scrivito_id',
13
- via: :all
42
+ get 'blobs/upload_permission' => 'blobs#upload_permission', defaults: {format: :json}
43
+ put 'blobs/activate_upload' => 'blobs#activate_upload', defaults: {format: :json}
14
44
 
15
- match '/f7/*permalink',
16
- to: 'scrivito/cms_dispatch#index',
17
- as: :scrivito_permalink,
18
- format: false,
19
- via: :all
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
20
69
  end
70
+
71
+ Scrivito::PresetRoutes.install_slave_into(Rails.application.routes)
72
+
@@ -13,11 +13,11 @@ module Fiona7
13
13
 
14
14
  protected
15
15
  def scrivito_sdk_path
16
- Gem.loaded_specs['scrivito_sdk'].full_name
16
+ Gem.loaded_specs['scrivito_sdk'].full_gem_path
17
17
  end
18
18
 
19
19
  def fiona_connector_path
20
- Gem.loaded_specs['infopark_fiona_connector'].full_name
20
+ Gem.loaded_specs['infopark_fiona_connector'].full_gem_path
21
21
  end
22
22
 
23
23
  def reorder_view_paths(first, second)
@@ -3,15 +3,24 @@ require "fiona7/search_engine"
3
3
  module Fiona7
4
4
  class NaiveSearchEngine < SearchEngine
5
5
  def results
6
- #debugger
6
+ @objects || execute_search
7
+ @objects.map {|o| o.id}
8
+ end
9
+
10
+ def objects
11
+ @objects || execute_search
12
+ @objects
13
+ end
14
+
15
+ protected
16
+ def execute_search
7
17
  fetch_all
8
18
  apply_filters
9
19
  exclude_widgets
10
20
  order_results
11
21
  limit_size
12
- end
22
+ end
13
23
 
14
- protected
15
24
  def fetch_all
16
25
  obj_class_filter = @query.find {|q| (q[:field] == :_obj_class || q[:field] == "_obj_class") && q[:operator] == :equal }
17
26
  id_filter = @query.find {|q| (q[:field] == :id || q[:field] == "id") && q[:operator] == :equal }
@@ -77,7 +86,7 @@ module Fiona7
77
86
 
78
87
  def limit_size
79
88
  @count = @all.count
80
- if @all.kind_of?(Array)
89
+ @objects = if @all.kind_of?(Array)
81
90
  @all[@offset, @limit] || []
82
91
  else
83
92
  @all.offset(@offset).limit(@limit).to_a
@@ -91,7 +100,7 @@ module Fiona7
91
100
  value = filter[:value]
92
101
 
93
102
  case filter[:operator]
94
- when :equal
103
+ when :equals, :equal
95
104
  if field == :_modification || field == "_modification"
96
105
  if value != ["new", "edited", "deleted"]
97
106
  raise "Unsupported modification values: #{value.inspect}. Only #{["new", "edited", "deleted"].inspect} are supported"
@@ -99,6 +108,30 @@ module Fiona7
99
108
  # TODO: this can be solved with AR, faster
100
109
  @all = @all.to_a.select {|o| o.edited? }
101
110
  end
111
+ elsif field == :_path
112
+ value = [value] unless value.is_a?(Array)
113
+ value.map{|v| v.gsub!('.', '_') }
114
+ if (@all.is_a?(Array))
115
+ @all = @all.select do |o|
116
+ value.include?(o.path)
117
+ end
118
+ else
119
+ @all = @all.where(:path => value)
120
+ end
121
+ elsif field == :_parent_path
122
+ parent_obj = @klass.where(path: value).first
123
+ if parent_obj
124
+ parent_obj_id = parent_obj.id
125
+ if (@all.is_a?(Array))
126
+ @all = @all.select do |o|
127
+ o.parent_obj_id == parent_obj_id
128
+ end
129
+ else
130
+ @all = @all.where(:parent_obj_id => parent_obj_id)
131
+ end
132
+ else
133
+ @all = []
134
+ end
102
135
  else
103
136
  if value.is_a?(Array)
104
137
  @all = @all.to_a.select do |o|
@@ -127,6 +160,8 @@ module Fiona7
127
160
  end
128
161
  when :prefix, :prefix_search
129
162
  if !@all.is_a?(Array) && field.to_sym == :_path
163
+ # TODO: handle this properly
164
+ value = value.first if value.kind_of?(Array)
130
165
  @all = @all.where("path LIKE ?", "#{value}%")
131
166
  else
132
167
  @all = @all.to_a.select {|o| o.send(:[], resolve_field_name(o,field)).to_s.start_with?(value) }
@@ -0,0 +1,11 @@
1
+ module Fiona7
2
+ class ObjClassNameDemangler
3
+ def initialize(obj_class)
4
+ @obj_class = obj_class
5
+ end
6
+
7
+ def demangle
8
+ @obj_class.gsub('__', '::')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Fiona7
2
+ class ObjClassNameMangler
3
+ def initialize(obj_class)
4
+ @obj_class = obj_class
5
+ end
6
+
7
+ def mangle
8
+ @obj_class.gsub('::', '__')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require "fiona7/type_register"
2
+
3
+ module Fiona7
4
+ class ObjClassesFromCms
5
+ def initialize(type_register=Fiona7::TypeRegister.instance)
6
+ @type_register = type_register
7
+ end
8
+
9
+ def obj_classes
10
+ @type_register.read_all.map(&:virtual_name)
11
+
12
+ end
13
+ end
14
+ end