scrivito_sdk 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/README +6 -0
  4. data/app/controllers/cms_controller.rb +7 -0
  5. data/app/controllers/scrivito/blobs_controller.rb +10 -0
  6. data/app/controllers/scrivito/default_cms_controller.rb +61 -0
  7. data/app/controllers/scrivito/objs_controller.rb +200 -0
  8. data/app/controllers/scrivito/tasks_controller.rb +11 -0
  9. data/app/controllers/scrivito/webservice_controller.rb +36 -0
  10. data/app/controllers/scrivito/workspaces_controller.rb +41 -0
  11. data/app/helpers/cms_helper.rb +7 -0
  12. data/app/helpers/cms_routing_helper.rb +7 -0
  13. data/app/helpers/scrivito/cms_asset_helper.rb +103 -0
  14. data/app/helpers/scrivito/cms_tag_helper.rb +231 -0
  15. data/app/helpers/scrivito/default_cms_helper.rb +21 -0
  16. data/app/helpers/scrivito/default_cms_routing_helper.rb +130 -0
  17. data/app/helpers/scrivito/display_helper.rb +71 -0
  18. data/app/helpers/scrivito/editing_helper.rb +26 -0
  19. data/app/helpers/scrivito/layout_helper.rb +28 -0
  20. data/app/models/named_link.rb +2 -0
  21. data/app/views/cms/_index.html.erb +7 -0
  22. data/app/views/cms/index.html.erb +1 -0
  23. data/app/views/scrivito/_editing_javascript.html.erb +7 -0
  24. data/app/views/scrivito/default_cms/show_widget.html.erb +1 -0
  25. data/app/views/scrivito/objs/copy_widget.html.erb +1 -0
  26. data/app/views/scrivito/objs/create_widget.html.erb +1 -0
  27. data/app/views/scrivito/widget_thumbnail.html.erb +9 -0
  28. data/config/ca-bundle.crt +3509 -0
  29. data/config/cms_routes.rb +17 -0
  30. data/config/locales/de.scrivito.errors.yml +7 -0
  31. data/config/locales/de.scrivito.lib.yml +6 -0
  32. data/config/locales/de.scrivito.models.yml +6 -0
  33. data/config/locales/en.scrivito.errors.yml +7 -0
  34. data/config/locales/en.scrivito.lib.yml +6 -0
  35. data/config/locales/en.scrivito.models.yml +6 -0
  36. data/config/routes.rb +37 -0
  37. data/lib/assets/images/180x120.gif +0 -0
  38. data/lib/assets/images/scrivito/image_placeholder.png +0 -0
  39. data/lib/assets/javascripts/scrivito_editing.js +14642 -0
  40. data/lib/assets/stylesheets/scrivito.css +180 -0
  41. data/lib/assets/stylesheets/scrivito_editing.css +2213 -0
  42. data/lib/generators/cms/migration/USAGE +9 -0
  43. data/lib/generators/cms/migration/migration_generator.rb +21 -0
  44. data/lib/generators/cms/migration/templates/migration.erb +10 -0
  45. data/lib/obj.rb +3 -0
  46. data/lib/scrivito/access_denied.rb +6 -0
  47. data/lib/scrivito/attribute_content.rb +194 -0
  48. data/lib/scrivito/backend_error.rb +4 -0
  49. data/lib/scrivito/basic_obj.rb +840 -0
  50. data/lib/scrivito/basic_widget.rb +238 -0
  51. data/lib/scrivito/blob.rb +48 -0
  52. data/lib/scrivito/cache.rb +41 -0
  53. data/lib/scrivito/cache_garbage_collector.rb +83 -0
  54. data/lib/scrivito/cache_middleware.rb +17 -0
  55. data/lib/scrivito/client_config.rb +62 -0
  56. data/lib/scrivito/client_error.rb +12 -0
  57. data/lib/scrivito/cms_accessible.rb +30 -0
  58. data/lib/scrivito/cms_backend.rb +238 -0
  59. data/lib/scrivito/cms_cache_storage.rb +51 -0
  60. data/lib/scrivito/cms_dispatch_controller.rb +46 -0
  61. data/lib/scrivito/cms_env.rb +63 -0
  62. data/lib/scrivito/cms_field_tag.rb +112 -0
  63. data/lib/scrivito/cms_rest_api.rb +151 -0
  64. data/lib/scrivito/cms_rest_api/attribute_serializer.rb +98 -0
  65. data/lib/scrivito/cms_rest_api/blob_uploader.rb +18 -0
  66. data/lib/scrivito/cms_rest_api/widget_extractor.rb +42 -0
  67. data/lib/scrivito/cms_test_request.rb +23 -0
  68. data/lib/scrivito/communication_error.rb +17 -0
  69. data/lib/scrivito/comparison.rb +67 -0
  70. data/lib/scrivito/configuration.rb +221 -0
  71. data/lib/scrivito/connection_manager.rb +100 -0
  72. data/lib/scrivito/content_conversion.rb +43 -0
  73. data/lib/scrivito/content_service.rb +118 -0
  74. data/lib/scrivito/content_state.rb +109 -0
  75. data/lib/scrivito/content_state_caching.rb +47 -0
  76. data/lib/scrivito/content_state_visitor.rb +19 -0
  77. data/lib/scrivito/controller_runtime.rb +35 -0
  78. data/lib/scrivito/date_attribute.rb +16 -0
  79. data/lib/scrivito/deprecation.rb +21 -0
  80. data/lib/scrivito/diff.rb +110 -0
  81. data/lib/scrivito/editing_context.rb +106 -0
  82. data/lib/scrivito/editing_context_middleware.rb +60 -0
  83. data/lib/scrivito/engine.rb +65 -0
  84. data/lib/scrivito/errors.rb +11 -0
  85. data/lib/scrivito/html_string.rb +18 -0
  86. data/lib/scrivito/link.rb +187 -0
  87. data/lib/scrivito/link_parser.rb +81 -0
  88. data/lib/scrivito/log_subscriber.rb +29 -0
  89. data/lib/scrivito/migration.rb +2 -0
  90. data/lib/scrivito/migrations.rb +12 -0
  91. data/lib/scrivito/migrations/cms_backend.rb +94 -0
  92. data/lib/scrivito/migrations/installer.rb +45 -0
  93. data/lib/scrivito/migrations/migration.rb +93 -0
  94. data/lib/scrivito/migrations/migration_dsl.rb +143 -0
  95. data/lib/scrivito/migrations/migration_store.rb +23 -0
  96. data/lib/scrivito/migrations/migrator.rb +135 -0
  97. data/lib/scrivito/migrations/workspace_lock.rb +39 -0
  98. data/lib/scrivito/model_identity.rb +13 -0
  99. data/lib/scrivito/modification.rb +8 -0
  100. data/lib/scrivito/named_link.rb +75 -0
  101. data/lib/scrivito/network_error.rb +11 -0
  102. data/lib/scrivito/obj_data.rb +140 -0
  103. data/lib/scrivito/obj_data_from_hash.rb +31 -0
  104. data/lib/scrivito/obj_data_from_service.rb +84 -0
  105. data/lib/scrivito/obj_params_parser.rb +61 -0
  106. data/lib/scrivito/obj_search_builder.rb +62 -0
  107. data/lib/scrivito/obj_search_enumerator.rb +374 -0
  108. data/lib/scrivito/rate_limit_exceeded.rb +5 -0
  109. data/lib/scrivito/revision.rb +9 -0
  110. data/lib/scrivito/string_tagging.rb +18 -0
  111. data/lib/scrivito/text_link.rb +52 -0
  112. data/lib/scrivito/text_link_conversion.rb +52 -0
  113. data/lib/scrivito/type_computer.rb +34 -0
  114. data/lib/scrivito/widget_field_params.rb +61 -0
  115. data/lib/scrivito/widget_garbage_collection.rb +97 -0
  116. data/lib/scrivito/workspace.rb +222 -0
  117. data/lib/scrivito/workspace_data_from_service.rb +80 -0
  118. data/lib/scrivito/workspace_selection_middleware.rb +23 -0
  119. data/lib/scrivito_sdk.rb +19 -0
  120. data/lib/tasks/cache.rake +12 -0
  121. data/lib/tasks/migration.rake +35 -0
  122. data/lib/widget.rb +3 -0
  123. metadata +291 -0
@@ -0,0 +1,23 @@
1
+ require 'singleton'
2
+
3
+ module Scrivito
4
+ module Migrations
5
+ class MigrationStore
6
+ include Singleton
7
+
8
+ def backend
9
+ @backend ||= CmsBackend.new
10
+ end
11
+
12
+ def versions
13
+ @versions ||= MultiJson.load(backend.read.presence || '[]')
14
+ end
15
+
16
+ def add_version(version)
17
+ versions << version
18
+
19
+ backend.save(MultiJson.dump(versions))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,135 @@
1
+ module Scrivito
2
+ module Migrations
3
+ class Migrator
4
+ class << self
5
+ def migrations_path
6
+ Rails.root + 'cms/migrate'
7
+ end
8
+
9
+ def determine_migrations(paths)
10
+ paths = Array(paths)
11
+ files = Dir[*paths.map { |path| "#{path}/**/[0-9]*_*.rb" }]
12
+ splitter = /([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/
13
+
14
+ migrations = files.map do |filename|
15
+ version, name, scope = filename.scan(splitter).first
16
+
17
+ unless version
18
+ raise ScrivitoError.new("Illegal name for migration file: #{filename}\n\t
19
+ (only lower case letters, numbers, and '_' allowed)")
20
+ end
21
+
22
+ version = version
23
+ name = name.camelize
24
+
25
+ require(File.expand_path(filename))
26
+ name.constantize.new(name, version, filename, scope)
27
+ end
28
+
29
+ migrations.sort_by(&:version)
30
+ end
31
+ end
32
+
33
+ attr_reader :migrations
34
+ attr_reader :workspace_lock
35
+
36
+ def initialize(migration_store=nil, workspace_lock=nil)
37
+ @migrations = determine_migrations
38
+ @migration_store = migration_store || MigrationStore.instance
39
+ @workspace_lock = workspace_lock || WorkspaceLock.instance
40
+
41
+ validate
42
+ end
43
+
44
+ def migrate
45
+ workspace.as_current do
46
+ runnable.each do |migration|
47
+ migration.migrate
48
+ @migration_store.add_version(migration.version)
49
+ end
50
+ end
51
+ end
52
+
53
+ def needs_migration?
54
+ runnable.present?
55
+ end
56
+
57
+ def publish
58
+ remove_workspace_with do
59
+ CmsRestApi.put("workspaces/#{workspace.id}/publish", {})
60
+ end
61
+ end
62
+
63
+ def abort
64
+ remove_workspace_with do
65
+ CmsRestApi.delete("workspaces/#{workspace.id}")
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def workspace
72
+ workspace = migration_workspace
73
+
74
+ if workspace
75
+ if workspace_lock.exists?
76
+ workspace_lock.validate(workspace)
77
+ end
78
+ else
79
+ CmsRestApi.post('workspaces', :workspace => { :title => 'rtc', :id => 'rtc' })
80
+ workspace = migration_workspace
81
+ workspace_lock.write(workspace)
82
+ end
83
+
84
+ workspace
85
+ end
86
+
87
+ def migration_workspace
88
+ Workspace.find('rtc')
89
+ rescue ResourceNotFound
90
+ end
91
+
92
+ def remove_workspace_with(&block)
93
+ workspace = migration_workspace
94
+
95
+ if workspace
96
+ workspace_lock.validate(workspace)
97
+
98
+ yield
99
+
100
+ workspace_lock.remove
101
+ else
102
+ raise ScrivitoError.new('Migration workspace does not exist')
103
+ end
104
+ end
105
+
106
+ def determine_migrations
107
+ self.class.determine_migrations(self.class.migrations_path)
108
+ end
109
+
110
+ def runnable
111
+ migrations.reject do |migration|
112
+ migrated_versions.include?(migration.version)
113
+ end
114
+ end
115
+
116
+ def migrated_versions
117
+ @migration_store.versions
118
+ end
119
+
120
+ def validate
121
+ name, _ = migrations.group_by(&:name).find { |_, value| value.length > 1 }
122
+
123
+ if name
124
+ raise ScrivitoError.new("Multiple migrations have the name #{name}")
125
+ end
126
+
127
+ version, _ = migrations.group_by(&:version).find { |_, value| value.length > 1 }
128
+
129
+ if version
130
+ raise ScrivitoError.new("Multiple migrations have the version number #{version}")
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,39 @@
1
+ require 'singleton'
2
+
3
+ module Scrivito
4
+ module Migrations
5
+ class WorkspaceLock
6
+ include Singleton
7
+
8
+ def validate(workspace)
9
+ unless exists? && workspace.revision_id == File.read(filename)
10
+ raise ScrivitoError.new("There is a migration in progress right now. \
11
+ Please try again after the migration working copy '#{workspace.id}' has \
12
+ been published or removed.")
13
+ end
14
+ end
15
+
16
+ def write(workspace)
17
+ File.open(filename, 'w') do |file|
18
+ file.write(workspace.revision_id)
19
+ end
20
+ end
21
+
22
+ def remove
23
+ if exists?
24
+ File.delete(filename)
25
+ end
26
+ end
27
+
28
+ def exists?
29
+ File.exists?(filename)
30
+ end
31
+
32
+ private
33
+
34
+ def filename
35
+ File.join(Rails.root, 'tmp/migration_store.lock')
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ module Scrivito
2
+
3
+ module ModelIdentity
4
+ def ==(other)
5
+ other.equal?(self) || other.instance_of?(self.class) && other.id == id
6
+ end
7
+
8
+ alias_method :eql?, :==
9
+
10
+ delegate :hash, to: :id
11
+ end
12
+
13
+ end
@@ -0,0 +1,8 @@
1
+ module Scrivito
2
+ module Modification
3
+ EDITED = 'edited'.freeze
4
+ NEW = 'new'.freeze
5
+ DELETED = 'deleted'.freeze
6
+ UNMODIFIED = nil
7
+ end
8
+ end
@@ -0,0 +1,75 @@
1
+ module Scrivito
2
+
3
+ # This class provides methods used to retrieve objects from CMS based an entry
4
+ # in CMS of the obj_class <tt>NamedLink</tt>.
5
+ # @api public
6
+ class NamedLink
7
+
8
+ # @api public
9
+ class NotFound < StandardError
10
+ end
11
+
12
+ @@named_links_cache = nil
13
+
14
+ # Generates a cache of named links based on the CMS objects related link list.
15
+ # Raises exceptions if zero or more than one objects have this obj_class
16
+ def self.generate_named_links_cache
17
+ return if @@named_links_cache
18
+
19
+ found_object = find_named_link_obj
20
+ if found_object.nil?
21
+ raise NotFound, "Couldn't find NamedLink CMS Object!"
22
+ else
23
+ @@named_links_cache = found_object.
24
+ related_links.
25
+ flatten(1).
26
+ each_with_object({}) do |link_obj, temp|
27
+ temp[link_obj.title] = link_obj.obj
28
+ end
29
+ end
30
+
31
+ return nil
32
+ end
33
+
34
+ # This method will be called to retrieve the NamedLink {BasicObj Obj}.
35
+ # By default it will look for the Obj at the path "_named_links".
36
+ # Overwrite this method only if you know what you are doing.
37
+ # @api public
38
+ def self.find_named_link_obj
39
+ BasicObj.find_by_path("/_named_links")
40
+ end
41
+
42
+ def self.cache_expiry_time=(value)
43
+ raise "NamedLink.cache_expiry_time is deprecated. NamedLink no longer has a separate cache."
44
+ end
45
+
46
+ def self.cache_expired?
47
+ true
48
+ end
49
+
50
+ # Returns the CMS object mapped to the given title or nil.
51
+ # The title can be a string of symbol.
52
+ # @api public
53
+ def self.get_object(title, options = {})
54
+ object = named_links[title.to_s]
55
+ raise NotFound, "The NamedLink '#{title.to_s}' does not exist" if object.nil?
56
+ object
57
+ end
58
+
59
+ def self.reset_cache
60
+ @@named_links_cache = nil
61
+ end
62
+
63
+ def self.named_links
64
+ reset_cache if cache_expired?
65
+ generate_named_links_cache unless named_links_cache
66
+ named_links_cache
67
+ end
68
+
69
+ def self.named_links_cache
70
+ @@named_links_cache
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,11 @@
1
+ module Scrivito
2
+
3
+ class NetworkError < Scrivito::CommunicationError
4
+ attr_reader :http_code
5
+
6
+ def self.from_socket_error(socket_error)
7
+ new(socket_error.message, 503)
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,140 @@
1
+ module Scrivito
2
+
3
+ class ObjData
4
+ MissingAttribute = Class.new
5
+
6
+ internal_key_list = %w[
7
+ last_changed
8
+ modification
9
+ permalink
10
+ text_links
11
+ conflicts
12
+ ]
13
+
14
+ INTERNAL_KEYS = Set.new(internal_key_list.map { |name| "_#{name}" } )
15
+
16
+ internal_comparison_key_list = %w[
17
+ path
18
+ permalink
19
+ widget_pool
20
+ ]
21
+
22
+ INTERNAL_COMPARISON_KEYS = Set.new(internal_comparison_key_list.map { |name| "_#{name}" })
23
+
24
+ SPECIAL_KEYS = Set.new(%w[ body title blob ])
25
+
26
+
27
+ def value_of(attribute_name)
28
+ value_and_type_of(attribute_name).first
29
+ end
30
+
31
+ def type_of(attribute_name)
32
+ value_and_type_of(attribute_name).second
33
+ end
34
+
35
+ def unchecked_value_of(attribute_name)
36
+ unchecked_value_and_type_of(attribute_name).first
37
+ end
38
+
39
+ def value_and_type_of(attribute_name)
40
+ value_and_type = internal_value_and_type_of(attribute_name)
41
+
42
+ if value_and_type.first.is_a?(MissingAttribute)
43
+ raise ScrivitoError.new("Illegal attribute name #{attribute_name}")
44
+ else
45
+ value_and_type
46
+ end
47
+ end
48
+
49
+ def unchecked_value_and_type_of(attribute_name)
50
+ value_and_type = internal_value_and_type_of(attribute_name)
51
+
52
+ if value_and_type.first.is_a?(MissingAttribute)
53
+ [nil, nil]
54
+ else
55
+ value_and_type
56
+ end
57
+ end
58
+
59
+ def all_custom_attributes
60
+ @all_custom_attributes ||= all_attributes.select do |attribute|
61
+ has_custom_attribute?(attribute)
62
+ end
63
+ end
64
+
65
+ def raw_value_and_type_of(attribute_name)
66
+ raise NotImplementedError, "implement in subclass"
67
+ end
68
+
69
+ def has_custom_attribute?(name)
70
+ raise NotImplementedError, "implement in subclass"
71
+ end
72
+
73
+ def all_attributes
74
+ raise NotImplementedError, "implement in subclass"
75
+ end
76
+
77
+ def ==(other)
78
+ if other.kind_of?(ObjData)
79
+ (all_attributes | other.all_attributes).each do |attr|
80
+ attr = attr.to_s
81
+
82
+ next if attr.start_with?('_') && !INTERNAL_COMPARISON_KEYS.include?(attr)
83
+
84
+ if unchecked_value_of(attr) != other.unchecked_value_of(attr)
85
+ return false
86
+ end
87
+ end
88
+
89
+ return true
90
+ end
91
+
92
+ false
93
+ end
94
+
95
+ private
96
+
97
+ def internal_value_and_type_of(attribute_name)
98
+ value_and_type = raw_value_and_type_of(attribute_name)
99
+
100
+ if value_and_type.blank?
101
+ if INTERNAL_KEYS.include?(attribute_name) || SPECIAL_KEYS.include?(attribute_name)
102
+ type = type_of_internal(attribute_name)
103
+ [default_attribute_value(attribute_name), type]
104
+ else
105
+ [ObjData::MissingAttribute.new, nil]
106
+ end
107
+ else
108
+ value_and_type
109
+ end
110
+ end
111
+
112
+ def type_of_internal(key)
113
+ case key
114
+ when "_permalink"
115
+ "string"
116
+ when "_text_links"
117
+ "linklist"
118
+ when "_last_changed"
119
+ "date"
120
+ when "title", "body"
121
+ "html"
122
+ when "blob"
123
+ "binary"
124
+ else
125
+ nil
126
+ end
127
+ end
128
+
129
+ def default_attribute_value(attribute_name)
130
+ case attribute_name
131
+ when "_text_links"
132
+ []
133
+ else
134
+ nil
135
+ end
136
+ end
137
+
138
+ end
139
+
140
+ end