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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/fiona7.js +1 -282
- data/app/assets/javascripts/fiona7_ui.js +335 -0
- data/app/assets/stylesheets/fiona7.css.scss +4 -36
- data/app/assets/stylesheets/fiona7_ui.css.scss +39 -0
- data/app/controllers/fiona7/blobs_controller.rb +13 -23
- data/app/controllers/fiona7/release_controller.rb +1 -0
- data/app/controllers/fiona7/sessions_controller.rb +3 -5
- data/app/helpers/fiona7_override_helper.rb +6 -2
- data/app/models/fiona7/edited_obj.rb +6 -1
- data/app/models/fiona7/released_obj.rb +11 -3
- data/app/models/fiona7/write_obj.rb +18 -3
- data/app/models/fiona7_login_page.rb +3 -0
- data/app/views/scrivito/ui/index.html.erb +16 -0
- data/config/routes.rb +2 -0
- data/infopark_fiona7.gemspec +6 -4
- data/lib/fiona7/builder/batch_widget_writer.rb +7 -3
- data/lib/fiona7/builder/obj_builder.rb +130 -42
- data/lib/fiona7/builder/obj_class_builder.rb +3 -59
- data/lib/fiona7/builder/obj_class_updater.rb +7 -44
- data/lib/fiona7/builder/obj_updater.rb +25 -7
- data/lib/fiona7/builder/widget_builder.rb +24 -0
- data/lib/fiona7/builder/widget_building.rb +2 -7
- data/lib/fiona7/builder/widget_updater.rb +21 -0
- data/lib/fiona7/controllers/content_service/obj_controller.rb +16 -25
- data/lib/fiona7/controllers/rest_api/blob_controller.rb +41 -2
- data/lib/fiona7/controllers/rest_api/obj_controller.rb +19 -7
- data/lib/fiona7/controllers/rest_api/workspace_controller.rb +1 -1
- data/lib/fiona7/engine.rb +58 -7
- data/lib/fiona7/fiona_connector_patches/basic_obj.rb +46 -0
- data/lib/fiona7/initializer.rb +15 -11
- data/lib/fiona7/json/obj_decorator.rb +53 -31
- data/lib/fiona7/json/reverse_obj_decorator.rb +36 -0
- data/lib/fiona7/json/widget_decorator.rb +3 -1
- data/lib/fiona7/link_converter/fiona_to_scrivito.rb +45 -13
- data/lib/fiona7/link_converter/scrivito_to_fiona.rb +1 -1
- data/lib/fiona7/middleware/server_detection_middleware.rb +27 -0
- data/lib/fiona7/middleware/table_switching_middleware.rb +33 -0
- data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +5 -11
- data/lib/fiona7/mode_switch/composite.rb +2 -4
- data/lib/fiona7/naive_search_engine.rb +66 -16
- data/lib/fiona7/routers/rest_api.rb +50 -45
- data/lib/fiona7/routing_monkey_patch.rb +5 -3
- data/lib/fiona7/scrivito_patches/attribute_content.rb +9 -10
- data/lib/fiona7/scrivito_patches/attribute_serializer.rb +15 -0
- data/lib/fiona7/scrivito_patches/basic_obj.rb +25 -19
- data/lib/fiona7/scrivito_patches/basic_widget.rb +4 -0
- data/lib/fiona7/scrivito_patches/binary.rb +452 -33
- data/lib/fiona7/scrivito_patches/client_config.rb +0 -19
- data/lib/fiona7/scrivito_patches/cms_backend.rb +48 -0
- data/lib/fiona7/scrivito_patches/cms_field_tag.rb +19 -0
- data/lib/fiona7/scrivito_patches/cms_rest_api.rb +20 -3
- data/lib/fiona7/scrivito_patches/cms_routing.rb +20 -34
- data/lib/fiona7/scrivito_patches/controller_actions.rb +0 -8
- data/lib/fiona7/scrivito_patches/migrator.rb +4 -0
- data/lib/fiona7/scrivito_patches/objs_controller.rb +18 -0
- data/lib/fiona7/scrivito_patches/type_computer.rb +12 -12
- data/lib/fiona7/scrivito_patches/webservice_controller.rb +21 -0
- data/lib/fiona7/scrivito_patches/workspace.rb +8 -5
- data/lib/fiona7/shadow_classes.rb +74 -0
- data/lib/fiona7/table_switcher.rb +39 -0
- data/lib/fiona7/type_loader.rb +63 -0
- data/lib/fiona7/type_register.rb +170 -89
- data/lib/fiona7/type_synchronizer.rb +68 -0
- data/lib/fiona7/version.rb +1 -1
- data/lib/fiona7/version_helper.rb +35 -54
- data/lib/fiona7/widget_resolver.rb +1 -1
- data/lib/tasks/fiona7_tasks.rake +0 -8
- metadata +57 -18
- data/lib/fiona7/controllers/rest_api/obj_class_controller.rb +0 -39
- data/lib/fiona7/json/obj_class_decorator.rb +0 -45
- data/lib/fiona7/mode_switch/constants.rb +0 -86
- data/lib/fiona7/type_register_mixin.rb +0 -9
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'scrivito/client_config'
|
2
|
-
|
3
|
-
module Scrivito
|
4
|
-
class ClientConfig
|
5
|
-
alias_method :original_obj_config, :obj_config
|
6
|
-
|
7
|
-
alias_method :original_user_permissions_config, :user_permissions_config
|
8
|
-
|
9
|
-
def user_permissions_config
|
10
|
-
original_user_permissions_config.tap do |config|
|
11
|
-
# TODO: optimize this find away
|
12
|
-
if obj && obj.id
|
13
|
-
config[:write_obj] = Fiona7::WriteObj.find(obj.id).permission.write?
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'scrivito/cms_backend'
|
2
|
+
|
3
|
+
module Scrivito
|
4
|
+
class CmsBackend
|
5
|
+
def die_content_service
|
6
|
+
# TODO: remove this
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
# prevent the use of local URLs (localhost:7104) from cache
|
11
|
+
# when running under a server
|
12
|
+
def find_blob_data_from_cache(id, access, verb, transformation_definition)
|
13
|
+
cache_key = blob_data_cache_key(normalize_blob_id(id), access, verb, transformation_definition)
|
14
|
+
data = CmsDataCache.cache.read(cache_key)
|
15
|
+
|
16
|
+
if !data.nil? && Fiona7::Middleware::ServerDetectionMiddleware.server_detected?
|
17
|
+
tainted_data = data['url'] =~ /\Ahttps?:\/\/localhost:7104/
|
18
|
+
|
19
|
+
if tainted_data
|
20
|
+
nil
|
21
|
+
else
|
22
|
+
data
|
23
|
+
end
|
24
|
+
else
|
25
|
+
data
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# prevent real get requests since we run everything locally
|
30
|
+
def request_blob_metadata_from_s3(url)
|
31
|
+
@query_counter += 1
|
32
|
+
|
33
|
+
blob_id = /\/_b\/([0-9]+)/.match(url)[1]
|
34
|
+
|
35
|
+
raise ScrivitoError, "Unexpected 's3' url: #{url}" unless blob_id.present?
|
36
|
+
|
37
|
+
rest_api_meta_data = Fiona7::Controllers::RestAPI::BlobController.new.metadata(blob_id)
|
38
|
+
|
39
|
+
meta_data = {}
|
40
|
+
meta_data[:content_type] = rest_api_meta_data['meta_data']['content_type'].last
|
41
|
+
meta_data[:content_length] = rest_api_meta_data['meta_data']['content_length'].last
|
42
|
+
meta_data[:cache_control] = 'no-transform,public,max-age=300,s-maxage=900'
|
43
|
+
|
44
|
+
meta_data
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'scrivito/cms_field_tag'
|
2
|
+
|
3
|
+
module Scrivito
|
4
|
+
class CmsFieldTag
|
5
|
+
# support shadowclassing
|
6
|
+
def build_valid_widget_classes
|
7
|
+
obj_or_widget.valid_widget_ruby_classes_for(field_name).map do |widget_class|
|
8
|
+
real_widget_class_name = widget_class.name
|
9
|
+
fake_widget_class = widget_class.to_s
|
10
|
+
widget_class = widget_class.to_s
|
11
|
+
{
|
12
|
+
name: fake_widget_class,
|
13
|
+
description: description_for_widget_class(real_widget_class_name),
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -3,9 +3,26 @@ require 'scrivito/cms_rest_api.rb'
|
|
3
3
|
module Scrivito
|
4
4
|
class CmsRestApi
|
5
5
|
# Stub upload_file since the uploads are handled directly in ruby.
|
6
|
-
def self.upload_file(file)
|
7
|
-
#
|
8
|
-
|
6
|
+
def self.upload_file(file, obj_id)
|
7
|
+
# TODO: code deduplication with obj builder
|
8
|
+
parent = Fiona7::WriteObj.find(obj_id.to_i)
|
9
|
+
ext = ::File.extname(file.path).to_s[1..-1]
|
10
|
+
name = ::File.basename(file.path, '.' + ext.to_s)
|
11
|
+
obj_class = if ['jpg', 'jpeg', 'gif', 'png', 'tif', 'tiff'].include?(ext)
|
12
|
+
'X_Image'
|
13
|
+
else
|
14
|
+
'X_Generic'
|
15
|
+
end
|
16
|
+
|
17
|
+
raise Scrivito::ScrivitoError.new("File extension of uploaded file cannot be identified", 422) if ext.nil?
|
18
|
+
|
19
|
+
upload = Fiona7::WriteObj.upload(file, ext, {name: name, parent: parent, obj_class: obj_class}).tap(&:release!)
|
20
|
+
encoded_id = '%032d' % upload.id
|
21
|
+
{'id' => encoded_id}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.activate_upload(*args)
|
25
|
+
raise "This method is not implemented"
|
9
26
|
end
|
10
27
|
end
|
11
28
|
end
|
@@ -2,12 +2,26 @@ require 'scrivito/cms_routing'
|
|
2
2
|
|
3
3
|
module Scrivito
|
4
4
|
class CmsRouting
|
5
|
-
# patch link converter to understand numerical IDs
|
6
5
|
def convert_links(html)
|
7
6
|
if html
|
8
|
-
html.gsub(%r{
|
7
|
+
html.to_str.gsub(%r{\bobjid:([a-f0-9]{4,16})\b([^"']*)}) do
|
9
8
|
if obj = Obj.find_by_id($1)
|
10
|
-
|
9
|
+
options = {}
|
10
|
+
|
11
|
+
if $2.present?
|
12
|
+
begin
|
13
|
+
uri = URI.parse($2)
|
14
|
+
options.merge!(extract_query(uri))
|
15
|
+
options['anchor'] = uri.fragment
|
16
|
+
rescue
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if editing_context.display_mode == 'editing'
|
21
|
+
id_path_or_url_for_objs(obj, :path, options)
|
22
|
+
else
|
23
|
+
path_or_url(obj, :path, options)
|
24
|
+
end
|
11
25
|
else
|
12
26
|
"#__target_object_not_reachable"
|
13
27
|
end
|
@@ -15,11 +29,10 @@ module Scrivito
|
|
15
29
|
end
|
16
30
|
end
|
17
31
|
|
18
|
-
# patch router to output proper binary urls fo uploaded files
|
19
32
|
def path_or_url_without_editing_context(target, path_or_url, options)
|
20
33
|
if target.is_a?(Link)
|
21
34
|
path_or_url_for_links(target, path_or_url, options)
|
22
|
-
elsif target.is_a?(BasicObj)
|
35
|
+
elsif target.is_a?(Obj) || target.is_a?(BasicObj)
|
23
36
|
path_or_url_for_objs(target, path_or_url, options)
|
24
37
|
elsif target.respond_to?(:first)
|
25
38
|
if target.first.is_a?(Link)
|
@@ -28,37 +41,10 @@ module Scrivito
|
|
28
41
|
return LINK_TO_EMPTY_LINKLIST
|
29
42
|
end
|
30
43
|
elsif target.is_a?(Binary)
|
31
|
-
|
32
|
-
main_app.public_send("fiona7_blob_#{path_or_url}", {id: binary.send(:id), name: binary.filename})
|
44
|
+
binary_url(target)
|
33
45
|
else
|
34
46
|
raise "scrivito_path or scrivito_url was called with an instance of #{target.class}. "+
|
35
|
-
"It must only be called with
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# patch router to output proper binary urls fo uploaded files
|
40
|
-
def path_or_url_for_objs(obj, path_or_url, options = {})
|
41
|
-
permalink = obj.permalink
|
42
|
-
if permalink
|
43
|
-
main_app.public_send("scrivito_permalink_#{path_or_url}", options.merge(:permalink => permalink))
|
44
|
-
elsif obj.homepage?
|
45
|
-
main_app.public_send("scrivito_root_#{path_or_url}", options)
|
46
|
-
else
|
47
|
-
if obj.binary? && editing_context.display_mode != "editing"
|
48
|
-
if obj.binary
|
49
|
-
main_app.public_send("fiona7_blob_#{path_or_url}", {id: obj.binary.send(:id), name: obj.binary.filename})
|
50
|
-
else
|
51
|
-
LINK_TO_EMPTY_BLOB
|
52
|
-
end
|
53
|
-
else
|
54
|
-
main_app.public_send(
|
55
|
-
"scrivito_id_#{path_or_url}",
|
56
|
-
options.merge(
|
57
|
-
id: obj.id,
|
58
|
-
slug: obj.slug.presence
|
59
|
-
)
|
60
|
-
)
|
61
|
-
end
|
47
|
+
"It must only be called with an Obj or a Link or a non-empty LinkList."
|
62
48
|
end
|
63
49
|
end
|
64
50
|
end
|
@@ -2,13 +2,5 @@ require 'scrivito/controller_actions'
|
|
2
2
|
|
3
3
|
module Scrivito
|
4
4
|
module ControllerActions
|
5
|
-
# different handling of binary objs
|
6
|
-
def deliver_file
|
7
|
-
if binary = @obj.binary
|
8
|
-
redirect_to fiona7_blob_path(id: binary.send(:id), name: binary.filename), :status => :moved_permanently
|
9
|
-
else
|
10
|
-
render text: 'Empty Blob', status: 404
|
11
|
-
end
|
12
|
-
end
|
13
5
|
end
|
14
6
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Scrivito
|
2
|
+
# trigger load
|
3
|
+
ObjsController
|
4
|
+
class ObjsController < WebserviceController
|
5
|
+
|
6
|
+
# optimized away
|
7
|
+
def is_outdated
|
8
|
+
@is_outdated = false
|
9
|
+
end
|
10
|
+
|
11
|
+
# optimized away
|
12
|
+
def conflicting_workspaces
|
13
|
+
@workspaces = []
|
14
|
+
render :workspaces
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -3,23 +3,23 @@ require 'scrivito/type_computer'
|
|
3
3
|
module Scrivito
|
4
4
|
class TypeComputer
|
5
5
|
private
|
6
|
-
|
7
|
-
def load_class(
|
8
|
-
klass = nil
|
6
|
+
|
7
|
+
def load_class(obj_class_name)
|
9
8
|
begin
|
10
|
-
klass =
|
9
|
+
klass = obj_class_name.constantize
|
10
|
+
klass = nil if !inherits_from_base?(klass)
|
11
11
|
rescue NameError
|
12
|
+
klass = ::ShadowClasses.const_get(obj_class_name)
|
13
|
+
klass = nil if !inherits_from_base?(klass)
|
12
14
|
end
|
13
|
-
return klass if klass && inherits_from_base?(klass)
|
14
15
|
|
15
|
-
if
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
return klass if klass && inherits_from_base?(klass)
|
16
|
+
if !klass
|
17
|
+
klass = ::ShadowClasses.const_get(obj_class_name)
|
18
|
+
klass if inherits_from_base?(klass)
|
19
|
+
else
|
20
|
+
klass
|
22
21
|
end
|
22
|
+
rescue NameError
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
# trigger load
|
4
|
+
WebserviceController
|
5
|
+
|
6
|
+
class WebserviceController < ActionController::Base
|
7
|
+
|
8
|
+
# Workaround for https://github.com/rails/rails/issues/8832
|
9
|
+
def merge_correctly_parsed_json_params
|
10
|
+
if request.format.json?
|
11
|
+
body = request.body.read
|
12
|
+
request.body.rewind
|
13
|
+
params.merge!(ActiveSupport::JSON.decode(body)) if body.present? && !request.form_data?
|
14
|
+
end
|
15
|
+
rescue JSON::ParserError => e
|
16
|
+
# Rails TestRequest mixes up arguments, therefore ignore elements here
|
17
|
+
raise e unless Rails.env.test?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -2,11 +2,14 @@ require 'scrivito/workspace'
|
|
2
2
|
|
3
3
|
module Scrivito
|
4
4
|
class Workspace
|
5
|
-
#
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
# there are no conflicts.
|
6
|
+
def conflict_warning_for(*args)
|
7
|
+
[]
|
8
|
+
end
|
9
|
+
|
10
|
+
# there are no outdated workspaces
|
11
|
+
def outdated?
|
12
|
+
false
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ShadowClassesSupport
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
alias_method :real_to_s, :to_s
|
8
|
+
# NOTE: this workaround is neccessary, because
|
9
|
+
# in many places scrivito_sdk assumes that
|
10
|
+
# class.name == obj_class_name which isn't
|
11
|
+
# true for shadow classes
|
12
|
+
# it breaks the bijection that scrivito_sdk
|
13
|
+
# expects, but injection is mostly ok
|
14
|
+
def to_s
|
15
|
+
self.name.sub(/\AShadowClasses::/, '')
|
16
|
+
end
|
17
|
+
|
18
|
+
def real_to_s
|
19
|
+
self.name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ShadowClasses
|
25
|
+
def self.fetch(name,type)
|
26
|
+
# false skips inheritance chain, it checks only this module
|
27
|
+
if self.const_defined?(name, false)
|
28
|
+
self.const_get(name, false)
|
29
|
+
else
|
30
|
+
self.define(name,type)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.define(name,type)
|
35
|
+
if name =~ /::/
|
36
|
+
raise "Invalid name: #{name}, nesting of classes not allowed"
|
37
|
+
end
|
38
|
+
|
39
|
+
if type == 'Obj'
|
40
|
+
if name == 'Obj'
|
41
|
+
self.const_set(name, scrivito_obj_class)
|
42
|
+
else
|
43
|
+
self.const_set(
|
44
|
+
name,
|
45
|
+
Class.new(scrivito_obj_class) do
|
46
|
+
include ::ShadowClassesSupport
|
47
|
+
end
|
48
|
+
)
|
49
|
+
end
|
50
|
+
elsif type == 'Widget'
|
51
|
+
parent_class = 'Widget'.safe_constantize || Scrivito::BasicWidget
|
52
|
+
self.const_set(
|
53
|
+
name,
|
54
|
+
Class.new(parent_class) do
|
55
|
+
include ::ShadowClassesSupport
|
56
|
+
end
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.scrivito_obj_class
|
63
|
+
if !::Scrivito.const_defined?('Obj', false)
|
64
|
+
if Fiona7.mode == :standalone
|
65
|
+
::Scrivito.const_set('Obj', ::Obj)
|
66
|
+
elsif Fiona7.mode == :legacy
|
67
|
+
::Scrivito.const_set('Obj', Class.new(::Scrivito::BasicObj))
|
68
|
+
else
|
69
|
+
raise "Invalid Fiona7.mode = #{Fiona7.mode}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
::Scrivito.const_get('Obj', false)
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Fiona7
|
2
|
+
|
3
|
+
class TableSwitcher
|
4
|
+
attr_accessor :klass, :table_suffix, :table_prefix, :table_name
|
5
|
+
|
6
|
+
def initialize(klass, table_suffix)
|
7
|
+
self.klass = klass
|
8
|
+
self.table_prefix = klass.table_name_prefix
|
9
|
+
self.table_suffix = table_suffix
|
10
|
+
self.table_name = "#{self.table_prefix}#{self.table_suffix}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def switch
|
14
|
+
if klass.table_name != self.table_name
|
15
|
+
value = self.table_name
|
16
|
+
klass_name = klass.name
|
17
|
+
Rails.logger.debug "Switching table name to #{value} on #{self.klass.name}"
|
18
|
+
# TODO: cache values for two modes somehow? (to improve performance)
|
19
|
+
# NOTE: we abuse the fact that the two tables have identical schemes
|
20
|
+
# and only swap out the table name sneakly, skipping DB schema lookup
|
21
|
+
# and also reloading of attributes, which can break the app
|
22
|
+
# (by removing primary key accessor :id)
|
23
|
+
klass.instance_eval do
|
24
|
+
connection.clear_cache!
|
25
|
+
@table_name = value
|
26
|
+
@quoted_table_name = nil
|
27
|
+
@arel_table = nil
|
28
|
+
@sequence_name = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name
|
29
|
+
@relation = ActiveRecord::Relation.create(self, arel_table)
|
30
|
+
|
31
|
+
# reset associations, otherwise they go out of sync
|
32
|
+
has_many :children, :class_name => klass_name, :foreign_key => 'parent_obj_id'
|
33
|
+
belongs_to :parent, :class_name => klass_name, :foreign_key => 'parent_obj_id'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|