ecoportal-api-v2 1.1.7 → 2.0.0

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 (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