infopark_cloud_connector 6.9.1.3.22208381 → 6.9.2.1.125136549

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