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