ecoportal-api-v2 1.1.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.markdownlint.json +4 -0
  3. data/.rubocop.yml +54 -15
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +485 -373
  6. data/ecoportal-api-v2.gemspec +13 -12
  7. data/lib/ecoportal/api/common/concerns/benchmarkable.rb +47 -34
  8. data/lib/ecoportal/api/common/concerns/threadable.rb +41 -0
  9. data/lib/ecoportal/api/common/concerns.rb +1 -0
  10. data/lib/ecoportal/api/common/content/array_model.rb +85 -79
  11. data/lib/ecoportal/api/common/content/class_helpers.rb +34 -31
  12. data/lib/ecoportal/api/common/content/collection_model.rb +77 -65
  13. data/lib/ecoportal/api/common/content/double_model.rb +105 -87
  14. data/lib/ecoportal/api/common/content/wrapped_response.rb +11 -11
  15. data/lib/ecoportal/api/v2/page/component/reference_field.rb +17 -13
  16. data/lib/ecoportal/api/v2/page/component.rb +67 -68
  17. data/lib/ecoportal/api/v2/page/components.rb +9 -9
  18. data/lib/ecoportal/api/v2/page/force.rb +6 -7
  19. data/lib/ecoportal/api/v2/page/stages.rb +5 -6
  20. data/lib/ecoportal/api/v2/page.rb +35 -33
  21. data/lib/ecoportal/api/v2/pages/page_stage.rb +22 -20
  22. data/lib/ecoportal/api/v2/pages.rb +18 -14
  23. data/lib/ecoportal/api/v2/people.rb +2 -3
  24. data/lib/ecoportal/api/v2/registers.rb +28 -13
  25. data/lib/ecoportal/api/v2/s3/data.rb +27 -0
  26. data/lib/ecoportal/api/v2/s3/files/batch_upload.rb +110 -0
  27. data/lib/ecoportal/api/v2/s3/files/poll.rb +82 -0
  28. data/lib/ecoportal/api/v2/s3/files/poll_status.rb +52 -0
  29. data/lib/ecoportal/api/v2/s3/files.rb +132 -0
  30. data/lib/ecoportal/api/v2/s3/upload.rb +154 -0
  31. data/lib/ecoportal/api/v2/s3.rb +66 -0
  32. data/lib/ecoportal/api/v2.rb +10 -3
  33. data/lib/ecoportal/api/v2_version.rb +1 -1
  34. metadata +53 -54
@@ -5,7 +5,7 @@ module Ecoportal
5
5
  module Content
6
6
  module ClassHelpers
7
7
  include Common::BaseClass
8
- NOT_USED = "no_used!"
8
+ NOT_USED = "no_used!".freeze
9
9
 
10
10
  # Class resolver
11
11
  # @note it caches the resolved `klass`es
@@ -18,21 +18,21 @@ module Ecoportal
18
18
  @resolved ||= {}
19
19
  @resolved[klass] ||=
20
20
  case klass
21
- when Class
22
- klass
23
- when String
24
- begin
25
- Kernel.const_get(klass)
26
- rescue NameError => e
27
- raise if exception
28
- end
29
- when Symbol
30
- source_class.resolve_class(source_class.send(klass))
31
- when Hash
32
- referrer, referred = klass.first
33
- resolve_class(referred, source_class: referrer, exception: exception)
34
- else
35
- raise "Unknown class: #{klass}" if exception
21
+ when Class
22
+ klass
23
+ when String
24
+ begin
25
+ Kernel.const_get(klass)
26
+ rescue NameError
27
+ raise if exception
28
+ end
29
+ when Symbol
30
+ source_class.resolve_class(source_class.send(klass))
31
+ when Hash
32
+ referrer, referred = klass.first
33
+ resolve_class(referred, source_class: referrer, exception: exception)
34
+ else
35
+ raise "Unknown class: #{klass}" if exception
36
36
  end
37
37
  end
38
38
 
@@ -41,11 +41,11 @@ module Ecoportal
41
41
  # @param key [String, Symbol] to be normalized
42
42
  # @return [String] a correct constant name
43
43
  def to_constant(key)
44
- str_name = key.to_s.strip.split(/::/).compact.map do |str|
44
+ key.to_s.strip.split('::').compact.map do |str|
45
45
  str.slice(0).upcase + str.slice(1..-1)
46
- end.join("").split(/[\-\_ :]+/i).compact.map do |str|
46
+ end.join.split(/[\-\_ :]+/i).compact.map do |str|
47
47
  str.slice(0).upcase + str.slice(1..-1)
48
- end.join("")
48
+ end.join
49
49
  end
50
50
 
51
51
  # Helper to create an instance variable `name`
@@ -60,22 +60,24 @@ module Ecoportal
60
60
  # Generates random ids in hexadecimal to use in class name generation.
61
61
  # @param len [Integeter] length of the `uid`
62
62
  # @return [String] a random unique id of length `len`
63
- def uid(len = 8);
63
+ def uid(len = 8)
64
64
  SecureRandom.hex(len/2)
65
65
  end
66
66
 
67
67
  # If the class for `name` exists, it returns it. Otherwise it generates it.
68
68
  # @param name [String, Symbol] the name of the new class
69
69
  # @param inherits [Class] the parent class to _inherit_ from
70
- # @param namespace [Class, String] an existing `constant` (class or module) the new class will be namespaced on
70
+ # @param namespace [Class, String] an existing `constant` (class or module)
71
+ # the new class will be namespaced on
71
72
  # @yield [child_class] configure the new class
72
73
  # @yieldparam child_class [Class] the new class
73
74
  # @return [Class] the new generated class
74
75
  def new_class(name = "Child#{uid}", inherits: self, namespace: inherits)
75
- name = name.to_s.to_sym.freeze
76
- class_name = to_constant(name)
76
+ name = name.to_s.to_sym.freeze
77
+ class_name = to_constant(name)
78
+ target_class = resolve_class("#{namespace}::#{class_name}", exception: false)
77
79
 
78
- unless target_class = resolve_class("#{namespace}::#{class_name}", exception: false)
80
+ unless target_class
79
81
  target_class = Class.new(inherits)
80
82
  Kernel.const_get(namespace.to_s).const_set class_name, target_class
81
83
  end
@@ -92,19 +94,17 @@ module Ecoportal
92
94
  # @return
93
95
  def to_time(value, exception: true)
94
96
  case value
95
- when NilClass
97
+ when Time, NilClass
96
98
  value
97
99
  when String
98
100
  begin
99
101
  Time.parse(value)
100
- rescue ArgumentArgument => e
102
+ rescue ArgumentArgument
101
103
  raise if exception
102
104
  nil
103
105
  end
104
106
  when Date
105
107
  Time.parse(value.to_s)
106
- when Time
107
- value
108
108
  else
109
109
  to_time(value.to_s) if value.respond_to?(:to_s)
110
110
  end
@@ -133,9 +133,11 @@ module Ecoportal
133
133
  # Builds the attr_reader and attr_writer of `attrs` and registers the associated instance variable as inheritable.
134
134
  def inheritable_attrs(*attrs)
135
135
  attrs.each do |attr|
136
- class_eval %(
137
- class << self; attr_accessor :#{attr} end
138
- )
136
+ class_eval <<-DEF_CLSS_ATTR, __FILE__, __LINE__ + 1
137
+ class << self # class << self
138
+ attr_accessor :#{attr} # attr_accessor :coolio
139
+ end # end
140
+ DEF_CLSS_ATTR
139
141
  end
140
142
  inheritable_class_vars(*attrs)
141
143
  end
@@ -147,6 +149,7 @@ module Ecoportal
147
149
  # - mutating methods would reflect the changes on other classes as well
148
150
  # - therefore, `freeze` will be called on the values that are inherited.
149
151
  def inherited(subclass)
152
+ super
150
153
  inheritable_class_vars.each do |var|
151
154
  instance_var = instance_variable_name(var)
152
155
  value = instance_variable_get(instance_var)
@@ -32,15 +32,18 @@ module Ecoportal
32
32
  # @yield [doc] identifies the target `class` of the raw object
33
33
  # @yieldparam doc [Hash]
34
34
  # @yieldreturn [Klass] the target `class`
35
- # @return [Klass] the target `class`
35
+ # @return [Class, Proc, Hash] the target `class`
36
+ # - `Hash` tracks a symbol pending to be resovle from its referrer
37
+ # - `Class` an already resolve class
38
+ # - `Proc` a forker that pivots between multiple classes
36
39
  def klass(value = NOT_USED, &block)
37
40
  @klass = block if block_given?
38
41
 
39
- if @klass && !@class.is_a?(Proc)
40
- @klass = resolve_class(@klass, exception: false) unless @klass.is_a?(Class)
41
- @klass
42
- elsif @klass.is_a?(Proc) && used_param?(value)
42
+ if @klass.is_a?(Proc) && used_param?(value)
43
43
  @klass.call(value)
44
+ elsif @klass && !@klass.is_a?(Proc) && !@klass.is_a?(Class)
45
+ @klass = resolve_class(@klass, exception: false)
46
+ @klass
44
47
  else
45
48
  @klass
46
49
  end.tap do |result|
@@ -58,7 +61,7 @@ module Ecoportal
58
61
  # Optimization
59
62
  def new_item_class_based?
60
63
  return false if @new_item.is_a?(Proc)
61
- return false if @klass.is_a?(Proc)
64
+ return false if klass.is_a?(Proc)
62
65
  return true if klass.is_a?(Class)
63
66
  false
64
67
  end
@@ -78,7 +81,10 @@ module Ecoportal
78
81
  # Meaning that there is actually no need to define this argument.
79
82
  # @return [Klass] instance object of the target `klass`
80
83
  def new_item(doc = NOT_USED, parent: nil, key: nil, read_only: false, &block)
81
- return (@new_item = block; nil) if block_given
84
+ if block_given?
85
+ @new_item = block
86
+ return
87
+ end
82
88
 
83
89
  msg = "To define the 'new_item' callback (factory), you need to use a block"
84
90
  raise msg unless used_param?(doc)
@@ -86,18 +92,11 @@ module Ecoportal
86
92
  raise msg unless klass?
87
93
  return @new_item.call(doc, parent, key) if @new_item.is_a?(Proc)
88
94
 
89
- raise "Could not find a class for: #{doc}" unless target_class = klass(doc)
95
+ raise "Could not find a class for: #{doc}" unless (target_class = klass(doc))
90
96
  return doc if doc.is_a?(target_class)
91
97
 
92
98
  target_class.new(doc, parent: parent, key: key, read_only: read_only)
93
99
  end
94
-
95
- def doc_class(name)
96
- dim_class = new_class(name, inherits: Common::Content::ArrayModel) do |klass|
97
- klass.order_matters = order_matters
98
- klass.uniq = uniq
99
- end
100
- end
101
100
  end
102
101
 
103
102
  include Enumerable
@@ -105,18 +104,18 @@ module Ecoportal
105
104
  inheritable_class_vars :klass, :order_matters, :order_key, :items_key, :new_item
106
105
 
107
106
  def initialize(ini_doc = [], parent: self, key: nil, read_only: false)
108
- unless self.class.klass?
109
- raise "Undefined base 'klass' or 'new_item' callback for #{self.class}"
110
- end
111
-
112
- ini_doc = case ini_doc
113
- when Array
114
- ini_doc
115
- when Enumerable
116
- ini_doc.to_a
117
- else
118
- []
119
- end
107
+ msg = "Undefined base 'klass' or 'new_item' callback for #{self.class}"
108
+ raise msg unless self.class.klass?
109
+
110
+ ini_doc =
111
+ case ini_doc
112
+ when Array
113
+ ini_doc
114
+ when Enumerable
115
+ ini_doc.to_a
116
+ else
117
+ []
118
+ end
120
119
 
121
120
  super(ini_doc, parent: parent, key: key, read_only: read_only)
122
121
  end
@@ -137,13 +136,13 @@ module Ecoportal
137
136
  def _doc_key(value)
138
137
  #print "*(#{value.class})"
139
138
  return super(value) unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
140
- if id = get_key(value)
139
+ if (id = get_key(value))
141
140
  #print "^"
142
141
  _doc_items.index {|item| get_key(item) == id}.tap do |p|
143
142
  #print "{{#{p}}}"
144
143
  end
145
144
  else
146
- show_str = \
145
+ show_str =
147
146
  case value
148
147
  when Hash
149
148
  value.pretty_inspect
@@ -157,9 +156,17 @@ module Ecoportal
157
156
  end
158
157
  end
159
158
 
160
- def length; count; end
161
- def empty?; count == 0; end
162
- def present?; count > 0; end
159
+ def length
160
+ count
161
+ end
162
+
163
+ def empty?
164
+ count&.zero?
165
+ end
166
+
167
+ def present?
168
+ count&.positive?
169
+ end
163
170
 
164
171
  def each(&block)
165
172
  return to_enum(:each) unless block
@@ -206,7 +213,7 @@ module Ecoportal
206
213
  end
207
214
  item_doc = value.is_a?(Content::DoubleModel)? value.doc : value
208
215
  item_doc = JSON.parse(item_doc.to_json)
209
- if item = self[value]
216
+ if (item = self[value])
210
217
  item.replace_doc(item_doc)
211
218
  else
212
219
  _doc_upsert(item_doc, pos: pos, before: before, after: after).tap do |pos_idx|
@@ -214,14 +221,14 @@ module Ecoportal
214
221
  @indexed = false
215
222
  end
216
223
  end
217
- (item || self[item_doc]).tap do |item|
218
- yield(item) if block_given?
224
+ (item || self[item_doc]).tap do |itm|
225
+ yield(itm) if block_given?
219
226
  end
220
227
  end
221
228
 
222
229
  # Deletes all the elements of this `CollectionModel` instance
223
230
  def clear
224
- self.to_a.each {|item| delete!(item)}
231
+ to_a.each {|item| delete!(item)}
225
232
  end
226
233
 
227
234
  # Deletes `value` from this `CollectionModel` instance
@@ -233,18 +240,25 @@ module Ecoportal
233
240
  unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel) || value.is_a?(String)
234
241
  raise "'Content::DoubleModel' or 'Hash' doc required"
235
242
  end
236
- if item = self[value]
237
- _doc_delete(item.doc)
238
- @indexed = false
239
- _items.delete(item)
240
- end
243
+ return unless (item = self[value])
244
+ _doc_delete(item.doc)
245
+ @indexed = false
246
+ _items.delete(item)
241
247
  end
242
248
 
243
249
  protected
244
250
 
245
- def order_matters?; self.class.order_matters; end
246
- def uniq?; self.class.uniq; end
247
- def items_key; self.class.items_key; end
251
+ def order_matters?
252
+ self.class.order_matters
253
+ end
254
+
255
+ def uniq?
256
+ self.class.uniq
257
+ end
258
+
259
+ def items_key
260
+ self.class.items_key
261
+ end
248
262
 
249
263
  def on_change
250
264
  @indexed = false
@@ -261,7 +275,7 @@ module Ecoportal
261
275
  when String
262
276
  value
263
277
  when Numeric
264
- get_key(self.to_a[value])
278
+ get_key(to_a[value])
265
279
  end
266
280
  end
267
281
 
@@ -284,9 +298,9 @@ module Ecoportal
284
298
 
285
299
  def new_item(value)
286
300
  if self.class.new_item_class_based?
287
- self.class.klass.new(value, parent: self, read_only: self._read_only)
301
+ self.class.klass.new(value, parent: self, read_only: _read_only)
288
302
  else
289
- self.class.new_item(value, parent: self, read_only: self._read_only)
303
+ self.class.new_item(value, parent: self, read_only: _read_only)
290
304
  end
291
305
  end
292
306
 
@@ -309,48 +323,46 @@ module Ecoportal
309
323
  # Deletes `value` from `doc` (here referred as `_doc_items`)
310
324
  # @return [Object] the element deleted from `doc`
311
325
  def _doc_delete(value)
312
- if current_pos = _doc_key(value)
313
- _doc_items.delete_at(current_pos)
314
- end
326
+ return unless (current_pos = _doc_key(value))
327
+
328
+ _doc_items.delete_at(current_pos)
315
329
  end
316
330
 
317
331
  def _doc_upsert(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
318
- current_pos = if elem = self[value]
319
- _doc_key(elem)
320
- end
332
+ elem = self[value]
333
+ current_pos = nil
334
+ current_pos = _doc_key(elem) if elem
321
335
 
322
336
  pos = scope_position(pos: pos, before: before, after: after)
323
337
  pos ||= current_pos
324
338
 
325
339
  if current_pos && pos
326
340
  _doc_items.delete_at(current_pos)
327
- pos = (pos <= current_pos)? pos : pos - 1
341
+ pos -= 1 unless pos <= current_pos
328
342
  end
329
343
 
330
- pos = (pos && pos < _doc_items.length)? pos : _doc_items.length
331
- pos.tap do |i|
344
+ pos = _doc_items.length unless pos && pos < _doc_items.length
345
+
346
+ pos.tap do |_i|
332
347
  _doc_items.insert(pos, value)
333
348
  end
334
-
335
349
  end
336
350
 
337
351
  def scope_position(pos: NOT_USED, before: NOT_USED, after: NOT_USED)
338
- case
339
- when used_param?(pos)
340
- if elem = self[pos]
352
+ if used_param?(pos)
353
+ if (elem = self[pos])
341
354
  _doc_key(elem) - 1
342
355
  end
343
- when used_param?(before)
344
- if elem = self[before]
356
+ elsif used_param?(before)
357
+ if (elem = self[before])
345
358
  _doc_key(elem) - 1
346
359
  end
347
- when used_param?(after)
348
- if elem = self[after]
360
+ elsif used_param?(after)
361
+ if (elem = self[after])
349
362
  _doc_key(elem)
350
363
  end
351
364
  end
352
365
  end
353
-
354
366
  end
355
367
  end
356
368
  end