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.
- checksums.yaml +4 -4
- data/.markdownlint.json +4 -0
- data/.rubocop.yml +54 -15
- data/.ruby-version +1 -0
- data/CHANGELOG.md +485 -373
- data/ecoportal-api-v2.gemspec +13 -12
- data/lib/ecoportal/api/common/concerns/benchmarkable.rb +47 -34
- data/lib/ecoportal/api/common/concerns/threadable.rb +41 -0
- data/lib/ecoportal/api/common/concerns.rb +1 -0
- data/lib/ecoportal/api/common/content/array_model.rb +85 -79
- data/lib/ecoportal/api/common/content/class_helpers.rb +34 -31
- data/lib/ecoportal/api/common/content/collection_model.rb +77 -65
- data/lib/ecoportal/api/common/content/double_model.rb +105 -87
- data/lib/ecoportal/api/common/content/wrapped_response.rb +11 -11
- data/lib/ecoportal/api/v2/page/component/reference_field.rb +17 -13
- data/lib/ecoportal/api/v2/page/component.rb +67 -68
- data/lib/ecoportal/api/v2/page/components.rb +9 -9
- data/lib/ecoportal/api/v2/page/force.rb +6 -7
- data/lib/ecoportal/api/v2/page/stages.rb +5 -6
- data/lib/ecoportal/api/v2/page.rb +35 -33
- data/lib/ecoportal/api/v2/pages/page_stage.rb +22 -20
- data/lib/ecoportal/api/v2/pages.rb +18 -14
- data/lib/ecoportal/api/v2/people.rb +2 -3
- data/lib/ecoportal/api/v2/registers.rb +28 -13
- data/lib/ecoportal/api/v2/s3/data.rb +27 -0
- data/lib/ecoportal/api/v2/s3/files/batch_upload.rb +110 -0
- data/lib/ecoportal/api/v2/s3/files/poll.rb +82 -0
- data/lib/ecoportal/api/v2/s3/files/poll_status.rb +52 -0
- data/lib/ecoportal/api/v2/s3/files.rb +132 -0
- data/lib/ecoportal/api/v2/s3/upload.rb +154 -0
- data/lib/ecoportal/api/v2/s3.rb +66 -0
- data/lib/ecoportal/api/v2.rb +10 -3
- data/lib/ecoportal/api/v2_version.rb +1 -1
- 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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
44
|
+
key.to_s.strip.split('::').compact.map do |str|
|
45
45
|
str.slice(0).upcase + str.slice(1..-1)
|
46
|
-
end.join
|
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)
|
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
|
76
|
-
class_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
|
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
|
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
|
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 [
|
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
|
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
|
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
|
-
|
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
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
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
|
161
|
-
|
162
|
-
|
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 |
|
218
|
-
yield(
|
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
|
-
|
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
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
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
|
246
|
-
|
247
|
-
|
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(
|
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:
|
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:
|
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
|
-
|
313
|
-
|
314
|
-
|
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
|
-
|
319
|
-
|
320
|
-
|
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
|
341
|
+
pos -= 1 unless pos <= current_pos
|
328
342
|
end
|
329
343
|
|
330
|
-
pos =
|
331
|
-
|
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
|
-
|
339
|
-
|
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
|
-
|
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
|
-
|
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
|