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
@@ -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
- # file is good enough. :-)
8
- file
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{<?\bobjid:([1-9][0-9]{3,})\b>?}) do
7
+ html.to_str.gsub(%r{\bobjid:([a-f0-9]{4,16})\b([^"']*)}) do
9
8
  if obj = Obj.find_by_id($1)
10
- path_or_url(obj, "path")
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
- binary = target
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 a descendant of Scrivito::BasicObj or a Link or a non-empty LinkList."
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
@@ -8,6 +8,10 @@ module Scrivito
8
8
  def remove_workspace_with(&block)
9
9
  yield
10
10
  end
11
+
12
+ def workspace
13
+ Workspace.find('rtc')
14
+ end
11
15
  end
12
16
  end
13
17
  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
- # In legacy mode we allow for an objects inside global namespace and Scrivito:: namespace
7
- def load_class(obj_class)
8
- klass = nil
6
+
7
+ def load_class(obj_class_name)
9
8
  begin
10
- klass = obj_class.constantize
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 Fiona7.mode == :legacy
16
- obj_class = "Scrivito::#{obj_class}"
17
- begin
18
- klass = obj_class.safe_constantize
19
- rescue NameError
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
- # Backport a "solution" for broken diff view
6
- def base_revision
7
- if base_revision_id
8
- @base_revision ||= Revision.new(id: base_revision_id, content_state: base_content_state, workspace: self)
9
- end
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