infopark_fiona7 0.71.1.12 → 1.1.0.0.0

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