ecoportal-api-oozes 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6ecefc83d30f273a4ededb781765cde494d5e6e0facad8a501fc6ef023e73ee
4
- data.tar.gz: b1e0b4dab879d237580bb4d599ea500fe7a5154f6f7f874e418360bfefc9700d
3
+ metadata.gz: 65d013d143d1c5dc7b19de58086d973dedc454dbdc89f4ac1d5525e58342c457
4
+ data.tar.gz: f083e27753e51add116d0aeb12ebc13632dc1834a42e5b690f0da353216b2f4f
5
5
  SHA512:
6
- metadata.gz: 98694b883b97f35fc71c0633717d92ec9da2704bd6d63c824a38c43eca512645ab6f3ecd77924d41ae527d112ffc36fcc4190f82e06b4b6453d21ccca44de22d
7
- data.tar.gz: 9ef14de17795590c48d3b3cb0a6e2ba96be3b1d1ff76cee959a1860cbf1689d17b0551842352b7326094d1c8071a8569cf58c6b8feb5dd8933da8cd6a69521fc
6
+ metadata.gz: 90b0d48b663d8698b33e56d113a44b84197a48fc47b29640abae653fe4b49740bc975fb6e0781e24dea5ee5bc3a29dababafab008adc893c13fda0157ae91793
7
+ data.tar.gz: af2a47022b66bc5238b2c5a3235c192d5f164493d221d3f94c95f3156962dcbdb5749376abc8218cd8023d84b03c6a31fd8c23d54c2324f815c4e41b3e464041
@@ -0,0 +1,17 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## [0.6.0] - 2020-07-xx
5
+
6
+ ### Added
7
+ ### Changed
8
+ - upgraded `ecoportal-api` gem
9
+ ### Fixed
10
+
11
+ ## [0.5.9] - 2020-07-02
12
+
13
+ ### Added
14
+ - helper `Ecoportal::API::Common::Content::StringDigest#indexable_label`: to see the part of a label that gets indexed
15
+ - this `CHANGELOG.md` file
16
+ ### Changed
17
+ ### Fixed
@@ -5,7 +5,7 @@ require "ecoportal/api/v2/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "ecoportal-api-oozes"
8
- spec.version = Ecoportal::API::V2::VERSION
8
+ spec.version = Ecoportal::API::V2::GEM_VERSION
9
9
  spec.authors = ["Oscar Segura"]
10
10
  spec.email = ["rien@ecoportal.co.nz", "oscar@ecoportal.co.nz", "bozydar@ecoportal.co.nz"]
11
11
 
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "redcarpet", "~> 3.5", ">= 3.5.0"
28
28
  spec.add_development_dependency "pry"
29
29
 
30
- spec.add_dependency 'ecoportal-api', '~> 0.5', '>= 0.5.5'
30
+ spec.add_dependency 'ecoportal-api', '~> 0.6', '>= 0.6.0'
31
31
  end
@@ -6,5 +6,5 @@ module Ecoportal
6
6
  end
7
7
  end
8
8
 
9
- require "ecoportal/api/common"
10
- require "ecoportal/api/v2"
9
+ require_relative "api/common"
10
+ require_relative "api/v2"
@@ -219,7 +219,6 @@ module Ecoportal
219
219
  end
220
220
  end
221
221
 
222
- # TODO
223
222
  def insert_one(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
224
223
  i = index(value)
225
224
  return i if (i && uniq?)
@@ -145,18 +145,20 @@ module Ecoportal
145
145
  # Tries to find the element `value`, if it exists, it updates it
146
146
  # Otherwise it pushes it to the end
147
147
  # @return the element
148
- def upsert!(value)
148
+ def upsert!(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
149
149
  unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
150
150
  raise "'Content::DoubleModel' or 'Hash' doc required"
151
151
  end
152
152
  item_doc = value.is_a?(Content::DoubleModel)? value.doc : value
153
+ item_doc = JSON.parse(item_doc.to_json)
153
154
  if item = self[value]
154
- item.replace_doc(JSON.parse(item_doc.to_json))
155
+ item.replace_doc(item_doc)
155
156
  else
156
- item = new_item(item_doc)
157
- _doc_items << item.doc
157
+ _doc_upsert(item_doc, pos: pos, before: before, after: after)
158
+ end
159
+ (item || self[item_doc]).tap do |item|
160
+ yield(item) if block_given?
158
161
  end
159
- item
160
162
  end
161
163
 
162
164
  protected
@@ -165,6 +167,10 @@ module Ecoportal
165
167
  def uniq?; self.class.uniq; end
166
168
  def items_key; self.class.items_key; end
167
169
 
170
+ def on_change
171
+ variables_remove!
172
+ end
173
+
168
174
  # Gets the `key` of the object
169
175
  def get_key(value)
170
176
  case value
@@ -198,11 +204,9 @@ module Ecoportal
198
204
  self.class.new_item(value, parent: self)
199
205
  end
200
206
 
201
- private
202
-
203
207
  # Helper to remove tracked down instance variables
204
208
  def variable_remove!(key)
205
- if (k = get_key(key)) && (item = @items_by_key[k])
209
+ if @items_by_key && (k = get_key(key)) && (item = @items_by_key[k])
206
210
  _items.delete(item) if _items.include?(item)
207
211
  @items_by_key.delete(k)
208
212
  else
@@ -216,6 +220,36 @@ module Ecoportal
216
220
  super
217
221
  end
218
222
 
223
+ def _doc_upsert(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
224
+ current_pos = _doc_key(value)
225
+ pos = case
226
+ when used_param?(pos)
227
+ pos
228
+ when used_param?(before)
229
+ _doc_key(before)
230
+ when used_param?(after)
231
+ puts "to add after #{after.id}"
232
+ if i = _doc_key(after)
233
+ i + 1
234
+ end
235
+ end
236
+
237
+ pos ||= current_pos
238
+
239
+ if current_pos && pos
240
+ _doc_items.delete(current_pos)
241
+ pos = (pos <= current_pos)? pos : pos - 1
242
+ end
243
+
244
+ pos = (pos && pos < _doc_items.length)? pos : _doc_items.length
245
+
246
+ pos.tap do |i|
247
+ _doc_items.insert(pos, value)
248
+ on_change
249
+ end
250
+
251
+ end
252
+
219
253
  end
220
254
  end
221
255
  end
@@ -1,3 +1,5 @@
1
+ require 'securerandom'
2
+
1
3
  module Ecoportal
2
4
  module API
3
5
  module Common
@@ -28,6 +30,10 @@ module Ecoportal
28
30
  @key = value.to_s.freeze
29
31
  end
30
32
 
33
+ def new_uuid(length: 12)
34
+ SecureRandom.hex(length)
35
+ end
36
+
31
37
  # Same as `attr_reader` but links to a subjacent `Hash` model property
32
38
  # @note it does **not** create an _instance variable_
33
39
  def pass_reader(*methods)
@@ -153,6 +159,7 @@ module Ecoportal
153
159
 
154
160
  embeds_one(method, key: key, multiple: true, klass: dim_class)
155
161
  end
162
+
156
163
  end
157
164
 
158
165
  attr_reader :_parent, :_key
@@ -250,16 +257,6 @@ module Ecoportal
250
257
  # self
251
258
  #end
252
259
 
253
- protected
254
-
255
- def is_root?
256
- _parent == self && !!defined?(@doc)
257
- end
258
-
259
- def linked?
260
- is_root? || !!_parent.doc
261
- end
262
-
263
260
  def replace_doc(new_doc)
264
261
  raise UnlinkedModel.new(from: "#{self.class}#replace_doc", key: _key) unless linked?
265
262
  if is_root?
@@ -271,6 +268,16 @@ module Ecoportal
271
268
  end
272
269
  end
273
270
 
271
+ protected
272
+
273
+ def is_root?
274
+ _parent == self && !!defined?(@doc)
275
+ end
276
+
277
+ def linked?
278
+ is_root? || !!_parent.doc
279
+ end
280
+
274
281
  def replace_original_doc(new_doc)
275
282
  raise UnlinkedModel.new(from: "#{self.class}#replace_original_doc", key: _key) unless linked?
276
283
  if is_root?
@@ -298,7 +305,7 @@ module Ecoportal
298
305
 
299
306
  # Removes all the persistent variables
300
307
  def variables_remove!
301
- @_dim_vars.map {|k| variable_remove!(k)}
308
+ @_dim_vars.dup.map {|k| variable_remove!(k)}
302
309
  end
303
310
 
304
311
  private
@@ -31,6 +31,8 @@ module Ecoportal
31
31
  # 3. the `data` property holds the specific changes of the object
32
32
  # - the `patch_ver` (compulsory) is **incremental** (for data integrity)
33
33
  # - the properties that have changed
34
+ # @note
35
+ # * there should not be difference between `null` and `""` (empty string)
34
36
  # @param a [Hash] current hash model
35
37
  # @param b [Hash] previous hash model
36
38
  # @return [Hash] a `patch data`
@@ -51,12 +53,19 @@ module Ecoportal
51
53
 
52
54
  private
53
55
 
56
+ def equal_values(a, b)
57
+ if a.is_a?(String) || b.is_a?(String)
58
+ return true if a.to_s.strip.empty? && b.to_s.strip.empty?
59
+ end
60
+ a == b
61
+ end
62
+
54
63
  def patch_data(a, b = nil)
55
64
  {}.tap do |data_hash|
56
65
  a.each do |key, a_value|
57
66
  b_value = b[key] if b_has_key = b && b.key?(key)
58
67
  is_meta_key = META_KEYS.include?(key)
59
- skip_equals = b_has_key && a_value == b_value
68
+ skip_equals = b_has_key && equal_values(a_value, b_value)
60
69
  next if is_meta_key || skip_equals
61
70
  data_hash[key] = patch_diff(a_value, b_value)
62
71
  data_hash.delete(key) if data_hash[key] == NO_CHANGES
@@ -99,14 +108,19 @@ module Ecoportal
99
108
  end
100
109
 
101
110
  def patch_data_array(a, b)
111
+ original_b = b
102
112
  a ||= []; b ||= []
103
113
  if !nested_array?(a, b)
104
114
  if a.length == b.length && (a & b).length == b.length
105
- NO_CHANGES
115
+ if original_b
116
+ NO_CHANGES
117
+ else
118
+ a
119
+ end
106
120
  else
107
121
  a
108
122
  end
109
- else
123
+ else # array with nested elements
110
124
  a_ids = array_ids(a)
111
125
  b_ids = array_ids(b)
112
126
 
@@ -116,19 +130,20 @@ module Ecoportal
116
130
 
117
131
  arr_delete = del_ids.map do |id|
118
132
  patch_delete(array_id_item(b, id))
119
- end
133
+ end.compact
120
134
 
121
135
  arr_update = oth_ids.map do |id|
122
136
  patch_update(array_id_item(a, id), array_id_item(b, id))
123
- end
137
+ end.compact
124
138
 
125
139
  arr_new = new_ids.map do |id|
126
140
  patch_new(array_id_item(a, id))
127
- end
141
+ end.compact
128
142
 
129
143
  (arr_delete.concat(arr_update).concat(arr_new)).tap do |patch_array|
130
144
  # remove data with no `id`
131
145
  patch_array.reject! {|item| !item.is_a?(Hash)}
146
+ return NO_CHANGES if patch_array.empty?
132
147
  end
133
148
  end
134
149
  end
@@ -7,12 +7,17 @@ module Ecoportal
7
7
  module StringDigest
8
8
  MAX_HASH_LABEL = 64
9
9
 
10
+ def indexable_label(str)
11
+ return nil unless str
12
+ lbl = str.downcase.gsub(/[^A-Za-z]+/,"-").slice(0, MAX_HASH_LABEL)
13
+ return nil unless lbl.length >= 3
14
+ lbl
15
+ end
16
+
10
17
  # Calculates the Hash of the field based on label
11
18
  def hash_label(str)
12
- return false unless str
13
- label = str.downcase.gsub(/[^A-Za-z]+/,"-").slice(0, MAX_HASH_LABEL)
14
- return false unless label.length >= 3
15
- return "z" + Digest::MD5.hexdigest(label).slice(0, 8);
19
+ return nil unless lbl = indexable_label(str)
20
+ "z" + Digest::MD5.hexdigest(lbl).slice(0, 8);
16
21
  end
17
22
 
18
23
  end
@@ -45,4 +45,3 @@ end
45
45
 
46
46
  require 'ecoportal/api/v2/registers'
47
47
  require 'ecoportal/api/v2/pages'
48
- #require 'ecoportal/api/v2/stages'
@@ -2,6 +2,7 @@ module Ecoportal
2
2
  module API
3
3
  class V2
4
4
  class Page < Common::Content::DoubleModel
5
+ ALLOWED_KEYS = %w[id patch_ver name template_id base_tags tags time_zone created_at updated_at can components sections stages]
5
6
  passkey :id
6
7
  passthrough :patch_ver
7
8
  passthrough :name, :template_id
@@ -17,6 +18,17 @@ module Ecoportal
17
18
  embeds_one :components, multiple: true, klass: :components_class
18
19
  embeds_one :sections, multiple: true, klass: :sections_class
19
20
  embeds_one :stages, multiple: true, klass: :stages_class
21
+
22
+ def as_update
23
+ super.tap do |hash|
24
+ unless !hash
25
+ hash["data"].select! do |key, value|
26
+ ALLOWED_KEYS.include?(key)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
20
32
  end
21
33
  end
22
34
  end
@@ -23,6 +23,13 @@ module Ecoportal
23
23
  class_resolver :law_field_class, "Ecoportal::API::V2::Page::Component::LawField"
24
24
 
25
25
  class << self
26
+ def new_doc(type:)
27
+ {
28
+ "id" => new_uuid,
29
+ "type" => type
30
+ }
31
+ end
32
+
26
33
  def get_class(doc)
27
34
  if doc.is_a?(Hash)
28
35
  case doc["type"]
@@ -81,6 +88,10 @@ module Ecoportal
81
88
  root.sections.find {|sec| sec.component?(id)}
82
89
  end
83
90
 
91
+ def indexable_label
92
+ self.class.indexable_label(label)
93
+ end
94
+
84
95
  end
85
96
  end
86
97
  end
@@ -4,8 +4,8 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class ActionField < Page::Component
7
- class_resolver :action_class, "Ecoportal::API::V2::Page::Component::Action"
8
- embeds_multiple :actions, klass: :action_class, order_key: :weight
7
+ #class_resolver :action_class, "Ecoportal::API::V2::Page::Component::Action"
8
+ embeds_multiple :actions, klass: "Ecoportal::API::V2::Page::Component::Action", order_key: :weight
9
9
  end
10
10
  end
11
11
  end
@@ -4,8 +4,8 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class ChecklistField < Page::Component
7
- class_resolver :checklist_item_class, "Ecoportal::API::V2::Page::Component::ChecklistItem"
8
- embeds_multiple :items, klass: :checklist_item_class, order_key: :weight
7
+ #class_resolver :checklist_item_class, "Ecoportal::API::V2::Page::Component::ChecklistItem"
8
+ embeds_multiple :items, klass: "Ecoportal::API::V2::Page::Component::ChecklistItem", order_key: :weight
9
9
  end
10
10
  end
11
11
  end
@@ -4,8 +4,8 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class FilesField < Page::Component
7
- class_resolver :file_class, "Ecoportal::API::V2::Page::File"
8
- embeds_multiple :items, klass: :file_class, order_key: :position
7
+ #class_resolver :file_class, "Ecoportal::API::V2::Page::File"
8
+ embeds_multiple :items, klass: "Ecoportal::API::V2::Page::File", order_key: :position
9
9
  end
10
10
  end
11
11
  end
@@ -4,8 +4,8 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class ImagesField < Page::Component
7
- class_resolver :image_class, "Ecoportal::API::V2::Page::Image"
8
- embeds_multiple :images, klass: :image_class, order_key: :weight
7
+ #class_resolver :image_class, "Ecoportal::API::V2::Page::Image"
8
+ embeds_multiple :images, klass: "Ecoportal::API::V2::Page::Image", order_key: :weight
9
9
  end
10
10
  end
11
11
  end
@@ -5,6 +5,11 @@ module Ecoportal
5
5
  class Component
6
6
  class PeopleField < Page::Component
7
7
  passarray :people_ids
8
+
9
+ def add(id)
10
+ people_ids << id
11
+ end
12
+
8
13
  end
9
14
  end
10
15
  end
@@ -6,8 +6,69 @@ module Ecoportal
6
6
  class SelectionField < Page::Component
7
7
  passthrough :multiple, :other, :other_desc
8
8
 
9
- class_resolver :selection_option_class, "Ecoportal::API::V2::Page::Component::SelectionOption"
10
- embeds_multiple :options, klass: :selection_option_class, order_key: :weight
9
+ #class_resolver :selection_option_class, "Ecoportal::API::V2::Page::Component::SelectionOption"
10
+ embeds_multiple :options, klass: "Ecoportal::API::V2::Page::Component::SelectionOption", order_key: :weight
11
+
12
+ def select(value)
13
+ opt = options.find {|opt| opt.value == value}
14
+ sel = selected
15
+ return true if !multiple && opt == sel
16
+ sel.selected = false if !multiple && sel
17
+ opt.selected = true unless !opt
18
+ end
19
+
20
+ def selected
21
+ if multiple
22
+ options.select {|opt| opt.selected}
23
+ else
24
+ options.find {|opt| opt.selected}
25
+ end
26
+ end
27
+
28
+ def value
29
+ if multiple
30
+ selected.map {|opt| opt.value}
31
+ else
32
+ selected&.value
33
+ end
34
+ end
35
+
36
+ # a server bug prevents to add new options to an existing field
37
+ def add_option(name:, value:, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
38
+ opt_doc = Ecoportal::API::V2::Page::Component::SelectionOption.new_doc
39
+ options.upsert!(opt_doc, pos: pos, before: before, after: after) do |option|
40
+ option.name = name
41
+ option.value = value
42
+ if prev = previous_option(option)
43
+ option.weight = prev.weight
44
+ end
45
+ yield(option) if block_given?
46
+ fix_option_weights!
47
+ end
48
+ end
49
+
50
+ def ordered_options
51
+ options.each_with_index.sort_by do |option, index|
52
+ (option.weight >= 9999) ? [index, index] : [option.weight, index]
53
+ end.map(&:first)
54
+ end
55
+
56
+ private
57
+
58
+ def fix_option_weights!
59
+ ordered_options.each_with_index do |option, index|
60
+ option.weight = index
61
+ end
62
+ end
63
+
64
+ def previous_option(value)
65
+ opts = ordered_options
66
+ pos = opts.index(value) - 1
67
+ return if pos < 0
68
+ opts[pos]
69
+ end
70
+
71
+
11
72
  end
12
73
  end
13
74
  end
@@ -4,6 +4,15 @@ module Ecoportal
4
4
  class Page
5
5
  class Component
6
6
  class SelectionOption < Common::Content::DoubleModel
7
+ class << self
8
+ def new_doc
9
+ {
10
+ "id" => new_uuid,
11
+ "weight" => 9999
12
+ }
13
+ end
14
+ end
15
+
7
16
  passkey :id
8
17
  passthrough :patch_ver, :name, :value
9
18
  passthrough :weight, :selected
@@ -13,6 +13,28 @@ module Ecoportal
13
13
 
14
14
  order_matters = true
15
15
 
16
+ def get_by_type(type)
17
+ self.select do |comp|
18
+ comp.type.downcase == type.to_s.strip.downcase
19
+ end
20
+ end
21
+
22
+ def get_by_name(name, type: nil)
23
+ pool = type ? get_by_type(type) : self
24
+
25
+ pool.select do |comp|
26
+ comp.label.to_s.strip.downcase == name.to_s.strip.downcase
27
+ end.first
28
+ end
29
+
30
+ def add(label:, type:)
31
+ fld_doc = Ecoportal::API::V2::Page::Component.new_doc(type: type)
32
+ upsert!(fld_doc) do |fld|
33
+ fld.label = label
34
+ yield(fld) if block_given?
35
+ end
36
+ end
37
+
16
38
  end
17
39
  end
18
40
  end
@@ -3,6 +3,28 @@ module Ecoportal
3
3
  class V2
4
4
  class Page
5
5
  class Section < Common::Content::DoubleModel
6
+ class << self
7
+ def new_doc(split: false)
8
+ {
9
+ "id" => new_uuid,
10
+ "type" => split ? "split" : "content",
11
+ "weight" => 9999
12
+ }.tap do |out|
13
+ component_ids = if split
14
+ {
15
+ "left_component_ids" => [],
16
+ "right_component_ids" => []
17
+ }
18
+ else
19
+ {
20
+ "component_ids" => []
21
+ }
22
+ end
23
+ out.merge!(component_ids)
24
+ end
25
+ end
26
+ end
27
+
6
28
  passkey :id
7
29
  passthrough :patch_ver, :weight, :type
8
30
  passthrough :heading, :left_heading, :right_heading
@@ -22,9 +44,9 @@ module Ecoportal
22
44
  end
23
45
 
24
46
  def components
25
- sec_ids = all_component_ids
26
- root.components.values_at(*sec_ids).select.with_index do |fld, i|
27
- puts "Warning: section #{id} points to missing field #{sec_ids[i]}" if !fld
47
+ fld_ids = all_component_ids
48
+ root.components.values_at(*fld_ids).select.with_index do |fld, i|
49
+ puts "Warning: field #{id} points to missing field #{fld_ids[i]}" if !fld
28
50
  fld && (!block_given? || yield(fld))
29
51
  end
30
52
  end
@@ -7,6 +7,39 @@ module Ecoportal
7
7
 
8
8
  self.klass = :section_class
9
9
 
10
+ def add(name: nil, split: false, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
11
+ sec_doc = Ecoportal::API::V2::Page::Section.new_doc(split: split)
12
+ upsert!(sec_doc, pos: pos, before: before, after: after) do |section|
13
+ section.heading = name
14
+ if prev = previous_section(section)
15
+ section.weight = prev.weight
16
+ end
17
+ yield(section) if block_given?
18
+ #fix_weights! # a server bug prevents to set the weight of existing sections
19
+ end
20
+ end
21
+
22
+ def ordered
23
+ each_with_index.sort_by do |section, index|
24
+ (section.weight >= 9999) ? [index, index] : [section.weight, index]
25
+ end.map(&:first)
26
+ end
27
+
28
+ private
29
+
30
+ def fix_weights!
31
+ ordered.each_with_index do |section, index|
32
+ section.weight = index
33
+ end
34
+ end
35
+
36
+ def previous_section(value)
37
+ secs = ordered
38
+ pos = secs.index(value) - 1
39
+ return if pos < 0
40
+ secs[pos]
41
+ end
42
+
10
43
  end
11
44
  end
12
45
  end
@@ -9,6 +9,19 @@ module Ecoportal
9
9
  passarray :subtags, order_matters: false
10
10
  passarray :section_ids
11
11
  passthrough :can
12
+
13
+ def sections
14
+ sec_ids = section_ids.to_a
15
+ root.sections.values_at(*sec_ids).select.with_index do |sec, i|
16
+ puts "Warning: section #{id} points to missing section #{sec_ids[i]}" if !sec
17
+ fld && (!block_given? || yield(sec))
18
+ end.sort_by {|sec| sec.weight}
19
+ end
20
+
21
+ def attach_section(section)
22
+ section_ids.insert_one(section.id)
23
+ end
24
+
12
25
  end
13
26
  end
14
27
  end
@@ -7,6 +7,12 @@ module Ecoportal
7
7
 
8
8
  self.klass = :stage_class
9
9
 
10
+ def get_by_name(name)
11
+ find do |stage|
12
+ stage.name.strip.downcase == name.to_s.strip.downcase
13
+ end
14
+ end
15
+
10
16
  end
11
17
  end
12
18
  end
@@ -3,9 +3,11 @@ module Ecoportal
3
3
  class V2
4
4
  # @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
5
5
  class Pages
6
+ STAGE_REX = /stages\/(?<sid>.*)/
6
7
  extend Common::BaseClass
7
8
  include Common::Content::DocHelpers
8
9
 
10
+ class_resolver :stages_class, "Ecoportal::API::V2::Pages::Stages"
9
11
  class_resolver :page_class, "Ecoportal::API::V2::Page"
10
12
 
11
13
  attr_reader :client
@@ -16,14 +18,30 @@ module Ecoportal
16
18
  @client = client
17
19
  end
18
20
 
21
+ # Obtain specific object for pages api requests.
22
+ # @return [V2::Pages::Stages] an instance object ready to make pages api requests.
23
+ def stages
24
+ stages_class.new(client)
25
+ end
26
+
19
27
  # Gets a page via api.
20
- # @note if the request has `success?` the returned `object.result` gives an object with that `Page`.
28
+ # @note
29
+ # - if the request has `success?` the returned `object.result` gives an object with that `Page`.
30
+ # - if it failed to obtain the full page, it returns a `PageStage` with the active stage data.
21
31
  # @param doc [String, Hash, Page] data containing an `id` of the target page.
22
- # @return [Ecoportal::API::V2::Page] the target page.
32
+ # @return [Ecoportal::API::V2::Page, Ecoportal::API::V2::Pages::PageStage] the target page.
23
33
  def get(doc)
24
- id = get_id(doc)
25
- response = client.get("/pages/#{CGI.escape(id)}")
26
- Common::Content::WrappedResponse.new(response, page_class).result
34
+ pid = get_id(doc)
35
+ response = client.get("/pages/#{CGI.escape(pid)}")
36
+ wrapped = Common::Content::WrappedResponse.new(response, page_class)
37
+
38
+ return wrapped.result if wrapped.success?
39
+ if (response.status == 302) && (url = response.body["data"])
40
+ if sid = url_to_stage_id(url)
41
+ return stages.get(pid: pid, sid: sid)
42
+ end
43
+ end
44
+ raise "Could not get page #{pid} - Error #{response.status}: #{response.body}"
27
45
  end
28
46
 
29
47
  # Gets a `new` non-existing page via api with all the ids initialized.
@@ -32,8 +50,10 @@ module Ecoportal
32
50
  def get_new(from)
33
51
  id = get_id(from)
34
52
  response = client.get("/pages/new", params: {template_id: id})
35
- # TODO: make it so the obtained `doc` can be used as `doc`, yet `source_doc` to be empty {}
36
- #Common::Content::WrappedResponse.new(response, page_class).result
53
+ wrapped = Common::Content::WrappedResponse.new(response, page_class)
54
+
55
+ return wrapped.result if wrapped.success?
56
+ raise "Could not get new page from template #{id} - Error #{response.status}: #{response.body}"
37
57
  end
38
58
 
39
59
  # Requests a creation of a page via api.
@@ -55,9 +75,16 @@ module Ecoportal
55
75
  client.patch("/pages/#{CGI.escape(id)}", data: body)
56
76
  end
57
77
 
78
+ private
79
+
80
+ def url_to_stage_id(url)
81
+ (matches = url.match(STAGE_REX)) && matches[:sid]
82
+ end
83
+
58
84
  end
59
85
  end
60
86
  end
61
87
  end
62
88
 
63
89
  require 'ecoportal/api/v2/page'
90
+ require 'ecoportal/api/v2/pages/stages'
@@ -0,0 +1,11 @@
1
+ module Ecoportal
2
+ module API
3
+ class V2
4
+ class Pages
5
+ class PageStage < V2::Page
6
+
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,52 @@
1
+ module Ecoportal
2
+ module API
3
+ class V2
4
+ class Pages
5
+ # This API Integration level has been added due to relative permissions
6
+ # - a **user** with api access may have access to a specific `stage` but not to the full `page`
7
+ #
8
+ # @attr_reader client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
9
+ class Stages
10
+ extend Common::BaseClass
11
+ include Common::Content::DocHelpers
12
+
13
+ class_resolver :page_stage_class, "Ecoportal::API::V2::Pages::PageStage"
14
+
15
+ attr_reader :client
16
+
17
+ # @param client [Common::Client] a `Common::Client` object that holds the configuration of the api connection.
18
+ # @return [Schemas] an instance object ready to make schema api requests.
19
+ def initialize(client)
20
+ @client = client
21
+ end
22
+
23
+ # Gets a stage via api.
24
+ # @note if the request has `success?` the returned `object.result` gives an object with that `Stage`.
25
+ # @param doc [String, Hash, Stage] data containing an `id` of the target page.
26
+ # @return [Ecoportal::API::V2::Stage, Ecoportal::API::V2::Pages::PageStage] the target stage.
27
+ def get(pid:, sid:)
28
+ pid = get_id(pid)
29
+ response = client.get("/pages/#{CGI.escape(pid)}/stages/#{CGI.escape(sid)}/")
30
+ wrapped = Common::Content::WrappedResponse.new(response, page_stage_class)
31
+
32
+ return wrapped.result if wrapped.success?
33
+ raise "Could not get stage {#{sid}} of page #{pid} - Error #{response.status}: #{response.body}"
34
+ end
35
+
36
+ # Requests to update an existing stage via api.
37
+ # @param doc [Hash, Stage] data that at least contains an `id` (internal or external) of the target stage.
38
+ # @return [Response] an object with the api response.
39
+ def update(doc, pid: nil, sid:)
40
+ body = get_body(doc)
41
+ pid = pid || get_id(doc)
42
+ path = "/pages/#{CGI.escape(pid)}/stages/#{CGI.escape(sid)}/"
43
+ client.patch(path, data: body)
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ require 'ecoportal/api/v2/pages/page_stage'
@@ -1,7 +1,7 @@
1
1
  module Ecoportal
2
2
  module API
3
3
  class V2
4
- VERSION = "0.5.5"
4
+ GEM_VERSION = "0.6.0"
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecoportal-api-oozes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-30 00:00:00.000000000 Z
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -110,22 +110,22 @@ dependencies:
110
110
  name: ecoportal-api
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '0.5'
116
113
  - - ">="
117
114
  - !ruby/object:Gem::Version
118
- version: 0.5.5
115
+ version: 0.6.0
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '0.6'
119
119
  type: :runtime
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - "~>"
124
- - !ruby/object:Gem::Version
125
- version: '0.5'
126
123
  - - ">="
127
124
  - !ruby/object:Gem::Version
128
- version: 0.5.5
125
+ version: 0.6.0
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '0.6'
129
129
  description:
130
130
  email:
131
131
  - rien@ecoportal.co.nz
@@ -140,6 +140,7 @@ files:
140
140
  - ".rubocop.yml"
141
141
  - ".travis.yml"
142
142
  - ".yardopts"
143
+ - CHANGELOG.md
143
144
  - Gemfile
144
145
  - LICENSE
145
146
  - README.md
@@ -189,6 +190,8 @@ files:
189
190
  - lib/ecoportal/api/v2/page/stage.rb
190
191
  - lib/ecoportal/api/v2/page/stages.rb
191
192
  - lib/ecoportal/api/v2/pages.rb
193
+ - lib/ecoportal/api/v2/pages/page_stage.rb
194
+ - lib/ecoportal/api/v2/pages/stages.rb
192
195
  - lib/ecoportal/api/v2/register.rb
193
196
  - lib/ecoportal/api/v2/registers.rb
194
197
  - lib/ecoportal/api/v2/template.rb