infopark_cloud_connector 6.9.1.3.22208381 → 6.9.2.1.125136549

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 (28) hide show
  1. data/app/controllers/rails_connector/blobs_controller.rb +1 -1
  2. data/app/controllers/rails_connector/objs_controller.rb +29 -9
  3. data/app/controllers/rails_connector/tasks_controller.rb +1 -1
  4. data/app/controllers/rails_connector/widget_renderer.rb +66 -0
  5. data/app/controllers/rails_connector/workspaces_controller.rb +9 -5
  6. data/app/helpers/rails_connector/cms_tag_helper.rb +40 -12
  7. data/app/views/rails_connector/objs/create_widget.html.erb +1 -1
  8. data/app/views/rails_connector/objs/show.html.erb +1 -0
  9. data/config/routes.rb +1 -1
  10. data/lib/assets/javascripts/infopark_editing.js +5598 -3254
  11. data/lib/assets/stylesheets/infopark_editing.css +366 -311
  12. data/lib/generators/cms/migration/templates/migration.rb +7 -9
  13. data/lib/rails_connector/backend_not_available.rb +1 -1
  14. data/lib/rails_connector/basic_obj.rb +10 -21
  15. data/lib/rails_connector/cache.rb +1 -1
  16. data/lib/rails_connector/cms_cache_storage.rb +10 -1
  17. data/lib/rails_connector/cms_rest_api.rb +80 -40
  18. data/lib/rails_connector/content_service.rb +1 -1
  19. data/lib/rails_connector/date_attribute.rb +1 -1
  20. data/lib/rails_connector/link.rb +0 -4
  21. data/lib/rails_connector/migrations/migration_dsl.rb +116 -12
  22. data/lib/rails_connector/migrations/migrator.rb +0 -1
  23. data/lib/rails_connector/workspace.rb +1 -1
  24. metadata +5 -7
  25. data/lib/rails_connector/cms_api_search_request.rb +0 -50
  26. data/lib/rails_connector/default_search_request.rb +0 -6
  27. data/lib/rails_connector/elasticsearch_request.rb +0 -78
  28. data/lib/rails_connector/widget_renderer.rb +0 -41
@@ -1,17 +1,15 @@
1
1
  class <%= class_name %> < ::RailsConnector::Migration
2
2
  def up
3
- # get_attribute('test')
4
- # create_attribute(:name => 'test', :type => :string)
5
- # update_attribute('test', :title => 'Test Title')
6
- # delete_attribute('test')
7
-
8
3
  # get_obj_class('Test')
9
- # create_obj_class(:name => 'Test', :type => :publication)
10
- # update_obj_class('Test', :title => 'Test Title')
4
+ # create_obj_class(name: 'Test', type: :publication, attributes: [])
5
+ # update_obj_class('Test', title: 'Test Title')
6
+ # add_attribute_to('Test', { name: 'test', type: 'string' })
7
+ # update_attribute_for('Test', 'test', { title: 'New Title' })
8
+ # delete_attribute_from('Test', 'test')
11
9
 
12
10
  # get_obj('a1b2c3')
13
- # create_obj(:_path => '/test', :_obj_class => 'Test')
14
- # update_obj('a1b2c3', :title => 'Test Title')
11
+ # create_obj(_path: '/test', _obj_class: 'Test')
12
+ # update_obj('a1b2c3', title: 'Test Title')
15
13
  # delete_obj('a1b2c3')
16
14
  end
17
15
  end
@@ -8,7 +8,7 @@ module RailsConnector
8
8
  end
9
9
 
10
10
  def initialize(message, http_code)
11
- @http_code = http_code
11
+ @http_code = http_code.to_i
12
12
  super(message)
13
13
  end
14
14
  end
@@ -8,7 +8,6 @@ module RailsConnector
8
8
  extend ActiveModel::Naming
9
9
 
10
10
  include DateAttribute
11
- include SEO
12
11
  include ModelIdentity
13
12
 
14
13
  # Create a new Obj instance with the given values and attributes.
@@ -343,12 +342,11 @@ module RailsConnector
343
342
  object_type == :document
344
343
  end
345
344
 
346
- # Returns true if this object is active (time_when is in object's time interval)
345
+ # Returns true if this object is active.
347
346
  # @api public
348
- def active?(time_when = nil)
347
+ def active?
349
348
  return false unless valid_from
350
- time_then = time_when || BasicObj.preview_time
351
- valid_from <= time_then && (!valid_until || time_then <= valid_until)
349
+ valid_from <= Time.now && (!valid_until || Time.now <= valid_until)
352
350
  end
353
351
 
354
352
  # compatibility with legacy apps.
@@ -365,8 +363,8 @@ module RailsConnector
365
363
  end
366
364
 
367
365
  # Returns true if the export of the object is not suppressed and the content is active?
368
- def exportable?(current_time = nil)
369
- !suppressed? && active?(current_time)
366
+ def exportable?
367
+ !suppressed? && active?
370
368
  end
371
369
 
372
370
  # Returns the file name to which the Content.file_extension has been appended.
@@ -404,8 +402,7 @@ module RailsConnector
404
402
  # @api public
405
403
  def toclist(*args)
406
404
  return [] unless publication?
407
- time = args.detect {|value| value.kind_of? Time}
408
- toclist = children.select{ |toc| toc.exportable?(time) }
405
+ toclist = children.select{ |toc| toc.exportable? }
409
406
  toclist = toclist.reject { |toc| toc.binary? } unless args.include?(:all)
410
407
  toclist
411
408
  end
@@ -638,10 +635,6 @@ module RailsConnector
638
635
  end
639
636
  end
640
637
 
641
- def to_liquid
642
- LiquidSupport::ObjDrop.new(self)
643
- end
644
-
645
638
  def respond_to?(method_id, include_private=false)
646
639
  if has_attribute?(method_id)
647
640
  true
@@ -650,14 +643,6 @@ module RailsConnector
650
643
  end
651
644
  end
652
645
 
653
- def self.preview_time=(t)
654
- Thread.current[:preview_time] = t
655
- end
656
-
657
- def self.preview_time
658
- Thread.current[:preview_time] || Time.now
659
- end
660
-
661
646
  def inspect
662
647
  "<#{self.class} id=\"#{id}\" path=\"#{path}\">"
663
648
  end
@@ -697,6 +682,10 @@ module RailsConnector
697
682
  CmsRestApi.delete("revisions/#{Workspace.current.revision_id}/objs/#{id}")
698
683
  end
699
684
 
685
+ def widget_container
686
+ @widget_container ||= self.class.find(parent_path.split('/').last)
687
+ end
688
+
700
689
  private
701
690
 
702
691
  attr_accessor :data_from_cms
@@ -1,7 +1,7 @@
1
1
  module RailsConnector
2
2
 
3
3
  class Cache
4
- attr_reader :cache_prefix
4
+ attr_reader :cache_prefix, :fallback_backend
5
5
 
6
6
  def initialize(options = {})
7
7
  @fallback_backend, @cache_prefix = options[:fallback_backend], options[:cache_prefix]
@@ -11,10 +11,19 @@ module CmsCacheStorage
11
11
  @cache ||= begin
12
12
  prefix = VERSION.dup
13
13
  prefix.concat('-utf8') if String.new.encoding_aware?
14
- Cache.new(fallback_backend: Rails.cache, cache_prefix: prefix)
14
+ Cache.new(fallback_backend: backend_cache, cache_prefix: prefix)
15
15
  end
16
16
  end
17
17
 
18
+ def backend_cache=(new_cache)
19
+ @backend_cache = new_cache
20
+ @cache = nil
21
+ end
22
+
23
+ def backend_cache
24
+ @backend_cache || Rails.cache
25
+ end
26
+
18
27
  def read_workspace_data(workspace_id)
19
28
  cache.read("workspace/#{workspace_id}")
20
29
  end
@@ -19,23 +19,38 @@ module RailsConnector
19
19
  #
20
20
  # @example Delete an Obj:
21
21
  # RailsConnector::CmsRestApi.delete('revisions/001384beff9e5845/objs/f4123622ff07b70b')
22
+ #
23
+ # @example Specify a poll interval (in seconds; default: 2) to use in case the response
24
+ # is a task reference response and the final response is polled for:
25
+ # RailsConnector::CmsRestApi.put('workspace/rtc/publish', nil, :interval => 10)
26
+ #
27
+ # @example Return immediately with the first response (without polling in case it is a
28
+ # task reference response):
29
+ # RailsConnector::CmsRestApi.task_unaware_request(:put, 'workspace/rtc/publish', nil)
30
+ #
22
31
  class CmsRestApi
32
+
23
33
  cattr_accessor :credentials
24
34
 
25
- def self.get(resource_path, payload = nil)
26
- request_cms_api(:get, resource_path, payload)
35
+ def self.get(resource_path, payload = nil, options = nil)
36
+ request_cms_api(:get, resource_path, payload, options)
27
37
  end
28
38
 
29
- def self.put(resource_path, payload)
30
- request_cms_api(:put, resource_path, payload)
39
+ def self.put(resource_path, payload, options = nil)
40
+ request_cms_api(:put, resource_path, payload, options)
31
41
  end
32
42
 
33
- def self.post(resource_path, payload)
34
- request_cms_api(:post, resource_path, payload)
43
+ def self.post(resource_path, payload, options = nil)
44
+ request_cms_api(:post, resource_path, payload, options)
35
45
  end
36
46
 
37
- def self.delete(resource_path, payload = nil)
38
- request_cms_api(:delete, resource_path, payload)
47
+ def self.delete(resource_path, payload = nil, options = nil)
48
+ request_cms_api(:delete, resource_path, payload, options)
49
+ end
50
+
51
+ def self.task_unaware_request(method, resource_path, payload = nil)
52
+ raise "Unexpected method #{method}" unless [:delete, :get, :post, :put].include?(method)
53
+ response_for_request_cms_api(method, resource_path, payload)
39
54
  end
40
55
 
41
56
  # @param [Hash] value
@@ -44,48 +59,73 @@ module RailsConnector
44
59
  @@credentials = value.symbolize_keys
45
60
  end
46
61
 
47
- private
62
+ class << self
48
63
 
49
- def self.request_cms_api(action, resource_path, payload)
50
- request_params = basic_request_params
51
- request_params[:method] = action
52
- request_params[:url] = url(resource_path)
53
- request_params[:payload] = MultiJson.encode(payload) if payload.present?
64
+ private
65
+
66
+ def request_cms_api(action, resource_path, payload, options)
67
+ decoded = response_for_request_cms_api(action, resource_path, payload)
68
+ return decoded unless Hash === decoded
69
+ return decoded unless decoded.keys == ["task"]
70
+ task_data = decoded["task"]
71
+ return decoded unless Hash === task_data
72
+ task_path = "tasks/#{task_data["id"]}"
73
+ final_response(task_path, options)
74
+ end
54
75
 
55
- begin
76
+ def response_for_request_cms_api(action, resource_path, payload)
77
+ request_params = basic_request_params
78
+ request_params[:method] = action
79
+ request_params[:url] = url(resource_path)
80
+ request_params[:payload] = MultiJson.encode(payload) if payload.present?
56
81
  MultiJson.decode(RestClient::Request.execute(request_params))
57
82
  rescue RestClient::ExceptionWithResponse => e
58
- begin
59
- if e.http_code == 403
60
- raise AccessDenied.new(e.http_body)
61
- elsif e.http_code.to_s.match(/4\d{2}/) &&
62
- (specific_output = MultiJson.decode(e.http_body)['error'])
63
- raise ClientError.new(specific_output, e.http_code)
83
+ http_code = e.http_code
84
+ if http_code == 403
85
+ raise AccessDenied.new(e.http_body)
86
+ elsif 400 <= http_code && http_code < 500
87
+ begin
88
+ specific_output = MultiJson.decode(e.http_body)['error']
89
+ rescue MultiJson::DecodeError
90
+ # fall through
91
+ else
92
+ raise ClientError.new(specific_output, http_code)
64
93
  end
65
- rescue MultiJson::DecodeError
66
94
  end
95
+ raise BackendNotAvailable.new(e.http_body, http_code)
96
+ end
67
97
 
68
- raise BackendNotAvailable.new(e.http_body, e.http_code)
98
+ def final_response(task_path, options)
99
+ options ||= {}
100
+ wait = options[:interval].presence.try(:to_f) || 2
101
+ task_data = response = nil
102
+ loop do
103
+ sleep wait
104
+ task_data = response_for_request_cms_api(:get, task_path, nil)
105
+ break unless task_data["status"] == "open"
106
+ end
107
+ return task_data["result"] if task_data["status"] == "success"
108
+ message = task_data["message"] || "Missing error message in task response #{task_data}"
109
+ raise ClientError.new(message, 400)
69
110
  end
70
- end
71
111
 
72
- def self.basic_request_params
73
- headers = {
74
- :content_type => :json,
75
- :accept => :json,
76
- }
77
- headers[:host] = credentials[:http_host] if credentials[:http_host].present?
78
-
79
- {
80
- :user => credentials[:login],
81
- :password => credentials[:api_key],
82
- :headers => headers,
83
- }
84
- end
112
+ def basic_request_params
113
+ headers = {
114
+ :content_type => :json,
115
+ :accept => :json,
116
+ }
117
+ headers[:host] = credentials[:http_host] if credentials[:http_host].present?
85
118
 
86
- def self.url(resource_path)
87
- "#{credentials[:url]}/#{resource_path}"
119
+ {
120
+ :user => credentials[:login],
121
+ :password => credentials[:api_key],
122
+ :headers => headers,
123
+ }
124
+ end
125
+
126
+ def url(resource_path)
127
+ "#{credentials[:url]}/#{resource_path}"
128
+ end
88
129
  end
89
130
  end
90
-
91
131
  end
@@ -107,7 +107,7 @@ class ContentService
107
107
  elsif response.code == "429"
108
108
  raise RateLimitExceeded.new(response["Retry-After"])
109
109
  else
110
- raise "Server responded with status code #{response.code}"
110
+ raise BackendNotAvailable.new("Server responded with status code #{response.code}", response.code)
111
111
  end
112
112
  end
113
113
 
@@ -19,7 +19,7 @@ module RailsConnector
19
19
  end
20
20
 
21
21
  def self.parse(iso_date_time)
22
- Time.from_iso(iso_date_time).localtime
22
+ Time.from_iso(iso_date_time).in_time_zone
23
23
  rescue ArgumentError
24
24
  raise "The value is not a valid ISO date time: #{iso_date_time.inspect}"
25
25
  end
@@ -135,10 +135,6 @@ module RailsConnector
135
135
  nil
136
136
  end
137
137
 
138
- def to_liquid
139
- LiquidSupport::LinkDrop.new(self)
140
- end
141
-
142
138
  private
143
139
 
144
140
  def resolved_internal?
@@ -7,7 +7,7 @@ module RailsConnector
7
7
  #
8
8
  # @example Create "test" Attribute
9
9
  #
10
- # create_attribute(:name => 'test', :type => 'string')
10
+ # create_attribute(name: 'test', type: 'string')
11
11
  #
12
12
  # @param attributes [Hash] The attributes and their values of the new
13
13
  # CMS attribute.
@@ -20,14 +20,94 @@ module RailsConnector
20
20
  warn_deprecated __callee__, 'create_obj_class', 'update_obj_class'
21
21
  endpoint = "revisions/#{Workspace.current.revision_id}/attributes"
22
22
 
23
- CmsRestApi.post(endpoint, :attribute => attributes)
23
+ CmsRestApi.post(endpoint, attribute: attributes)
24
+ end
25
+
26
+ # Adds an attribute to an object class.
27
+ #
28
+ # @example Add "test" attribute to object class "Foo.
29
+ #
30
+ # add_attribute_to('Foo', { name: 'test', type: 'string' })
31
+ #
32
+ # @param obj_class_name [String] The class name of the object class.
33
+ # @param params [Hash] The definition of the new attribute.
34
+ #
35
+ # @return nothing
36
+ def add_attribute_to(obj_class_name, params)
37
+ attributes = get_obj_class(obj_class_name)['attributes']
38
+ attributes << params
39
+
40
+ update_obj_class(obj_class_name, attributes: attributes)
41
+ end
42
+
43
+ # Deletes an attribute from an object class.
44
+ #
45
+ # @example Delete "test" attribute from object class "Foo.
46
+ #
47
+ # delete_attribute_from('Foo', 'test')
48
+ #
49
+ # @param obj_class_name [String] The class name of the object class.
50
+ # @param attribute_name [String] The name of the attribute that should be
51
+ # deleted.
52
+ #
53
+ # @return nothing
54
+ def delete_attribute_from(obj_class_name, attribute_name)
55
+ attributes = get_obj_class(obj_class_name)['attributes']
56
+ attributes = attributes.delete_if do |attribute|
57
+ # handle global and local attributes
58
+ name = attribute.is_a?(String) ? attribute : attribute['name']
59
+
60
+ name == attribute_name.to_s
61
+ end
62
+
63
+ update_obj_class(obj_class_name, attributes: attributes)
64
+ end
65
+
66
+ # Updates an attribute for an object class. Turns local into global
67
+ # attribute if found.
68
+ #
69
+ # @example Update "test" attribute for object class "Foo.
70
+ #
71
+ # update_attribute_for('Foo', 'test', { title: 'New Title' })
72
+ #
73
+ # @param obj_class_name [String] The class name of the object class.
74
+ # @param attribute_name [String] The name of the attribute that should be
75
+ # updated.
76
+ # @param params [Hash] Hash of updated attributes.
77
+ #
78
+ # @return nothing
79
+ def update_attribute_for(obj_class_name, attribute_name, params)
80
+ attribute_name = attribute_name.to_s
81
+ attributes = get_obj_class(obj_class_name)['attributes']
82
+ found = false
83
+
84
+ attributes.each_with_index do |attribute, index|
85
+ name = attribute.is_a?(String) ? attribute : attribute['name']
86
+
87
+ if name == attribute_name
88
+ if attribute.is_a?(String)
89
+ attribute = get_attribute(attribute)
90
+ end
91
+
92
+ attributes[index] = attribute.merge(params.stringify_keys)
93
+ update_obj_class(obj_class_name, attributes: attributes)
94
+
95
+ found = true
96
+
97
+ break
98
+ end
99
+ end
100
+
101
+ unless found
102
+ raise ArgumentError.new("Object class '#{obj_class_name}' does not have attribute '#{attribute_name}'.")
103
+ end
24
104
  end
25
105
 
26
106
  # Creates a CMS object.
27
107
  #
28
108
  # @example Create "/test" Object
29
109
  #
30
- # create_obj(:_path => '/test', :_obj_class => 'Test')
110
+ # create_obj(_path: '/test', _obj_class: 'Test')
31
111
  #
32
112
  # @param attributes [Hash] The attributes and their values of the new
33
113
  # CMS object.
@@ -37,14 +117,14 @@ module RailsConnector
37
117
  def create_obj(attributes = {})
38
118
  endpoint = "revisions/#{Workspace.current.revision_id}/objs"
39
119
 
40
- CmsRestApi.post(endpoint, :obj => attributes)
120
+ CmsRestApi.post(endpoint, obj: attributes)
41
121
  end
42
122
 
43
123
  # Creates a CMS object class.
44
124
  #
45
125
  # @example Create "Test" Object Class
46
126
  #
47
- # create_obj_class(:name => 'Test', :type => 'publication')
127
+ # create_obj_class(name: 'Test', type: 'publication')
48
128
  #
49
129
  # @param attributes [Hash] The attributes and their values of the new
50
130
  # CMS object class.
@@ -54,7 +134,7 @@ module RailsConnector
54
134
  def create_obj_class(attributes = {})
55
135
  endpoint = "revisions/#{Workspace.current.revision_id}/obj_classes"
56
136
 
57
- CmsRestApi.post(endpoint, :obj_class => attributes)
137
+ CmsRestApi.post(endpoint, obj_class: attributes)
58
138
  end
59
139
 
60
140
  # Deletes a CMS attribute.
@@ -145,7 +225,7 @@ module RailsConnector
145
225
  #
146
226
  # @example Update the title of the "test" Attribute
147
227
  #
148
- # update_attribute(:title => 'Test Title')
228
+ # update_attribute(title: 'Test Title')
149
229
  #
150
230
  # @param id [String] The ID of the attribute.
151
231
  # @param attributes [Hash] The updated attributes and their values.
@@ -157,14 +237,14 @@ module RailsConnector
157
237
  warn_deprecated __callee__, 'update_obj_class'
158
238
  endpoint = "revisions/#{Workspace.current.revision_id}/attributes/#{id}"
159
239
 
160
- CmsRestApi.put(endpoint, :attribute => attributes)
240
+ CmsRestApi.put(endpoint, attribute: attributes)
161
241
  end
162
242
 
163
243
  # Updates a CMS object.
164
244
  #
165
245
  # @example Update the title of the "a1b2c3" Object
166
246
  #
167
- # update_attribute('a1b2c3', :title => 'Test Title')
247
+ # update_attribute('a1b2c3', title: 'Test Title')
168
248
  #
169
249
  # @param id [String] The ID of the CMS object.
170
250
  # @param attributes [Hash] The updated attributes and their values.
@@ -174,14 +254,14 @@ module RailsConnector
174
254
  def update_obj(id, attributes = {})
175
255
  endpoint = "revisions/#{Workspace.current.revision_id}/objs/#{id}"
176
256
 
177
- CmsRestApi.put(endpoint, :obj => attributes)
257
+ CmsRestApi.put(endpoint, obj: attributes)
178
258
  end
179
259
 
180
260
  # Updates a CMS object class.
181
261
  #
182
262
  # @example Update the title of the "Test" Object Class
183
263
  #
184
- # update_obj_class('Test', :title => 'Test Title')
264
+ # update_obj_class('Test', title: 'Test Title')
185
265
  #
186
266
  # @param id [String] The ID of the CMS object class.
187
267
  # @param attributes [Hash] The updated attributes and their values.
@@ -191,7 +271,31 @@ module RailsConnector
191
271
  def update_obj_class(id, attributes = {})
192
272
  endpoint = "revisions/#{Workspace.current.revision_id}/obj_classes/#{id}"
193
273
 
194
- CmsRestApi.put(endpoint, :obj_class => attributes)
274
+ CmsRestApi.put(endpoint, obj_class: attributes)
275
+ end
276
+
277
+ # Uploads a file to the content store.
278
+ #
279
+ # @example Upload "image.png" and store it in an "Image" CMS object.
280
+ #
281
+ # filename = 'image.png'
282
+ # file = File.new(filename)
283
+ # blob = upload_file(file)
284
+ # create_obj(_path: "/resources/images/#{filename}", _obj_class: 'Image', blob: blob)
285
+ #
286
+ # @param file [IO] The file IO object that gets uploaded.
287
+ #
288
+ # @return The blob of the uploaded file that can be stored on a CMS object.
289
+ # @api public
290
+ def upload_file(file)
291
+ upload_permission = RailsConnector::CmsRestApi.get('blobs/upload_permission')
292
+
293
+ fields = upload_permission['fields'].map { |name, value| [name, value] }
294
+ fields << [:file, file]
295
+
296
+ RestClient.post(upload_permission['url'], fields)
297
+
298
+ upload_permission['blob']
195
299
  end
196
300
 
197
301
  private