eco-helpers 2.0.60 → 2.0.61

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 182922a2146b1fa50b0372253a5279eb7d801c4fabd8fcd5303dd6322091c91c
4
- data.tar.gz: 5f807f72bc3b6fc7a376bbd43d7a10b99cb5144a606ded5f9eb6817b82740788
3
+ metadata.gz: 21aabfeb392bd158c029ee8c1cd2503d0d6686d339333c80757a7fda273e9095
4
+ data.tar.gz: 23e15a543b809c2b8b9c0e51e17982da4915c7af170ddb18207b162d74752d22
5
5
  SHA512:
6
- metadata.gz: 40cb65992b4c9524e025b7f7073f699062cd22008202491c593089b662c9b72ac611eb9cfcccfe14a2f62e1d519eb5dad14fef9389b6e2cbee1798ced0baa54f
7
- data.tar.gz: 3e3154fcf629162a1445acbafd96f2d00f8d2a84f77bfb9b2cb68ce6c7f36ed4e8f5fea3cee43e897ac1b50b0210fd14bf9489b0a6708a6bc954093a7b1af3f8
6
+ metadata.gz: 777199fdf96345d5a694233c376317b008d6eb25abb736a42a1e8298b354ab7e13198149c81f699fdbc42aa414feaa05b0dd5a75bc34a0e43e75aa6a7c495a70
7
+ data.tar.gz: 9bca2a777df96adf7f6245627523f80480ba2e3626d89a179251507998365ca518b927267e381356fa2b9fc287a6593d4f1d60767c94fdd7f724a76b835aee77
data/CHANGELOG.md CHANGED
@@ -1,13 +1,38 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [2.0.60] - 2022-06-xx
4
+ ## [2.0.61] - 2022-07-xx
5
5
 
6
6
  ### Added
7
+ - patch for `Ecoportal::API::Common::Client#host` exposed `host` property
8
+ - `skip-header-checks` option
9
+ - It prevents checks done in the `Eco::API::Common::People::DefaultParsers::CSVParser`
10
+ - **Export Helpers** to be able to automate exports via `APIv2`
11
+ - `Eco::API::UseCases::OozeSamples::Helpers::ExportableRegister`
12
+ - `Eco::API::UseCases::OozeSamples::Helpers::ExportableOoze`
13
+ - `Eco::API::UseCases::OozeCases::ExportRegisterCase` to export registers
14
+ - First ooze native use case (besides the samples)
15
+
7
16
  ### Changed
17
+ - upgraded `ecoportal-api-v2` to version `0.8.30`
18
+
19
+ ### Fixed
20
+ - `-entries-to-csv` case; option `-out` was not being used
21
+ - `Eco::API::Common::People::Entries#export` made it so it creates one column per key
22
+ - It was wrongly merging the entries assuming all of them had the same keys
23
+ - This also fixes the `-entries-to-csv` case, which can be used with `entries-from` option to correctly merge multiple input files with no data loss
24
+ - `Eco::API::UseCases::OozeSamples::RegisterExportCase`
25
+ - On prompt to launch, it answers `Yes`
26
+ - It correctly captures the `state` based on the stages `state`
27
+ - It was not building the model
28
+ - Optimized
29
+ - It returns a `PageStage` (rather than `Page`), to ensure all supported properties are accessible (i.e. `uid`)
30
+
31
+ ## [2.0.60] - 2022-07-01
32
+
8
33
  ### Fixed
9
34
  - `Ecoportal::API::V1::PersonDetails.key?` patched
10
-
35
+
11
36
  ## [2.0.59] - 2022-06-07
12
37
 
13
38
  ### Added
data/eco-helpers.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 3.6"
32
32
 
33
33
  spec.add_dependency 'ecoportal-api', '>= 0.8.5', '< 0.9'
34
- spec.add_dependency 'ecoportal-api-v2', '>= 0.8.28', '< 0.9'
34
+ spec.add_dependency 'ecoportal-api-v2', '>= 0.8.30', '< 0.9'
35
35
  spec.add_dependency 'aws-sdk-s3', '>= 1.83.0', '< 2'
36
36
  spec.add_dependency 'aws-sdk-ses', '>= 1.36.0', '< 2'
37
37
  spec.add_dependency 'dotenv', '>= 2.7.6', '< 2.8'
@@ -3,7 +3,7 @@ class Eco::API::Common::People::DefaultParsers::CSVParser < Eco::API::Common::Lo
3
3
 
4
4
  def parser(data, deps)
5
5
  Eco::CSV.parse(data, headers: true, skip_blanks: true).tap do |table|
6
- check_headers(table) if deps[:check_headers]
6
+ check_headers(table) if deps[:check_headers] && !options.dig(:input, :skip_header_check)
7
7
  end.each_with_object([]) do |row, arr_hash|
8
8
  row_hash = row.headers.uniq.each_with_object({}) do |attr, hash|
9
9
  next if attr.to_s.strip.empty?
@@ -26,6 +26,10 @@ class Eco::API::Common::People::DefaultParsers::CSVParser < Eco::API::Common::Lo
26
26
 
27
27
  private
28
28
 
29
+ def options
30
+ ASSETS.cli.options
31
+ end
32
+
29
33
  def parse_string(value)
30
34
  return nil if value.to_s.empty?
31
35
  return nil if null?(value)
@@ -154,12 +154,13 @@ module Eco
154
154
  # Helper to dump the entries into a CSV
155
155
  # @param filename [String] the destination file
156
156
  def export(filename)
157
+ header = each_with_object([]) do |entry, header|
158
+ header.push(*entry.internal_entry.keys).uniq!
159
+ end
157
160
  CSV.open(filename, "w") do |csv|
158
- entry = self.first
159
- header = entry.internal_entry.keys
160
161
  csv << header
161
162
  self.each do |entry|
162
- csv << entry.internal_entry.values
163
+ csv << entry.internal_entry.values_at(*header)
163
164
  end
164
165
  end
165
166
  end
@@ -0,0 +1,9 @@
1
+ module Ecoportal
2
+ module API
3
+ module Common
4
+ class Client
5
+ attr_reader :host
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,4 @@
1
+ require_relative 'ecoportal_api/client'
1
2
  require_relative 'ecoportal_api/external_person'
2
3
  require_relative 'ecoportal_api/external_details'
3
4
  require_relative 'ecoportal_api/internal_person'
@@ -4,6 +4,7 @@ module Eco
4
4
  class DefaultCases < Eco::API::UseCases
5
5
  autoloads_children_of "Eco::API::Common::Loaders::UseCase"
6
6
  autoload_namespace "Eco::API::UseCases::DefaultCases"
7
+ autoload_namespace "Eco::API::UseCases::OozeCases"
7
8
  end
8
9
  end
9
10
  end
@@ -0,0 +1,99 @@
1
+ # Use case to export a register into a CSV
2
+ class Eco::API::UseCases::OozeCases::ExportRegisterCase < Eco::API::UseCases::OozeSamples::RegisterExportCase
3
+ name "export-register"
4
+ type :other
5
+ batch_size 5
6
+
7
+ def main(session, options, usecase)
8
+
9
+ super(session, options, usecase) do
10
+ # Save the File
11
+ CSV.open(filename, "w") do |csv|
12
+ csv << exportable_register.header(refresh: true)
13
+ exportable_register.each(as_values: true) do |values|
14
+ csv << values
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def process_ooze(ooz)
21
+ exportable_register.add_ooze(ooz)
22
+ exportable_register.header
23
+ end
24
+
25
+ def filters
26
+ [].tap do |fltrs|
27
+ [:any, :all].each {|mode| fltrs << build_tags_filter(mode)}
28
+ [:created_at, :updated_at].each {|key| fltrs << build_range_filter(key)}
29
+ end.compact
30
+ end
31
+
32
+ private
33
+
34
+ def exportable_register
35
+ @exportable_register ||= exportable_register_class.new(**export_options)
36
+ end
37
+
38
+ def exportable_register_class
39
+ Eco::API::UseCases::OozeSamples::Helpers::ExportableRegister
40
+ end
41
+
42
+ def build_tags_filter(mode = :any)
43
+ tags = option_tags(mode)
44
+ return nil if !tags || tags.empty?
45
+ tags_filter(tags, any: mode == :any)
46
+ end
47
+
48
+ def build_range_filter(key = :update_at)
49
+ from = from_date(key); to = to_date(key)
50
+ return nil unless from || to
51
+ date_range_filter(from: from, to: to, key: key)
52
+ end
53
+
54
+ def from_date(key)
55
+ options.dig(:export, :options, :filters, key, :from)
56
+ end
57
+
58
+ def to_date(key)
59
+ options.dig(:export, :options, :filters, key, :to)
60
+ end
61
+
62
+ def option_tags(mode = :any)
63
+ options.dig(:export, :options, :filters, :tags, mode)
64
+ end
65
+
66
+ def export_options
67
+ @export_options ||= {
68
+ delimiter: options_delimiter,
69
+ only_indexed: include_deindexed?,
70
+ only_labeled: include_unnamed?,
71
+ only_with_ref: include_unhashed?
72
+ }
73
+ end
74
+
75
+ def include_unnamed?
76
+ options.dig(:export, :options, :include, :unnamed)
77
+ end
78
+
79
+ def options_delimiter
80
+ options.dig(:export, :options, :delimiter) || "|"
81
+ end
82
+
83
+ def include_deindexed?
84
+ options.dig(:export, :options, :include, :deindexed)
85
+ end
86
+
87
+ def include_unhashed?
88
+ options.dig(:export, :options, :include, :unhashed)
89
+ end
90
+
91
+ def filename
92
+ @filename ||= (options[:file] || options.dig(:export, :file, :name)).tap do |filename|
93
+ unless filename
94
+ session.logger.error("Destination file not specified")
95
+ return false
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,10 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeCases
5
+ end
6
+ end
7
+ end
8
+ end
9
+
10
+ require_relative 'ooze_cases/export_register_case'
@@ -0,0 +1,169 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+ module Helpers
6
+ # Class to ease the export process
7
+ class ExportableOoze
8
+ MERGE_DELIMITER = "#:#"
9
+
10
+ META_FIELDS = {
11
+ "id" => "Internal ID",
12
+ "uid" => "Unique ID",
13
+ "name" => "Name of Page",
14
+ "state" => "State of Page",
15
+ "time_zone" => "Time Zone",
16
+ "created_at" => "Page Created",
17
+ "updated_at" => "Last updated",
18
+ "tags" => "Location Tags"
19
+ }
20
+
21
+ class << self
22
+ def label?(field)
23
+ !label(field).to_s.strip.empty?
24
+ end
25
+
26
+ def label(field, default: nil)
27
+ value = nil
28
+ value ||= field.label.to_s.strip if field.respond_to?(:label)
29
+ value = (!value || value.empty?) ? nil : value
30
+ return value if value || !default
31
+ default || "Unnamed field:"
32
+ end
33
+
34
+ def key_ref_label(field, default: nil)
35
+ "#{field_ref(field)}#{MERGE_DELIMITER}#{label(field, default: default)}"
36
+ end
37
+
38
+ def key_to_label(str)
39
+ return str unless str.include?(MERGE_DELIMITER)
40
+ str.split(MERGE_DELIMITER).last
41
+ end
42
+
43
+ def key_to_ref(str)
44
+ return str unless str.include?(MERGE_DELIMITER)
45
+ ref = str.split(MERGE_DELIMITER).first
46
+ ref.to_s.strip.empty?? nil : ref
47
+ end
48
+
49
+ def indexed?(field)
50
+ !field.deindex
51
+ end
52
+
53
+ def with_ref?(field)
54
+ !field.ref_backend.to_s.strip.empty?
55
+ end
56
+
57
+ def field_ref(field)
58
+ field.ref_backend || field.ref(any_length: true)
59
+ end
60
+ end
61
+
62
+ include Eco::API::UseCases::OozeSamples::Helpers::OozeHandlers
63
+
64
+ attr_reader :ooze
65
+ attr_reader :options
66
+
67
+ def initialize(ooze, **options)
68
+ raise "Expecting Ecoportal::API::V2::Page. Given: #{ooze.class}" unless ooze.is_a?(Ecoportal::API::V2::Page)
69
+ @ooze = ooze
70
+ @options = options.merge({
71
+ delimiter: "\n",
72
+ only_indexed: true,
73
+ only_labeled: true,
74
+ only_with_ref: true
75
+ })
76
+ end
77
+
78
+ def delimiter
79
+ options[:delimiter] || "\n"
80
+ end
81
+
82
+ # It offers an intermediate structure that can be aligned with other oozes
83
+ # @note
84
+ # - This method merges indexed values
85
+ # - It overrides even between fields of different type
86
+ # @param only_indexed: [Boolean]
87
+ # @param only_labeled: [Boolean]
88
+ # @param only_with_ref: [Boolean]
89
+ # @return [Array[Hash]]
90
+ def key_typed_data(**options)
91
+ options.merge!(options)
92
+ meta_fields.tap do |data|
93
+ with_field_section_pairs do |field, section|
94
+ next unless export?(field)
95
+ key = self.class.key_ref_label(field, default: alternative_label(field, section))
96
+ data[key] = merge_values(data[key], to_value(field), klass: field.class, delimiter: delimiter)
97
+ end
98
+ end
99
+ end
100
+
101
+ # Helper to go through fields and sections in the order they appear.
102
+ # @note
103
+ # 1. It prevents duplicated sections
104
+ # @yield [field, section] once per field and section.
105
+ # @yieldparam field [Component] a field.
106
+ # @yieldparam section [Section] the section that holds the field.
107
+ # @return [Array<Array] Ordered `Array` of pairs of field and section thereof.
108
+ def with_field_section_pairs
109
+ sections = []
110
+ ordered_sections.each_with_object([]) do |section, out|
111
+ next if sections.include?(section)
112
+ sections << section
113
+ section.components.each do |field|
114
+ out << [field, section]
115
+ yield(field, section) if block_given?
116
+ end
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ def meta_fields
123
+ META_FIELDS.each_with_object({}) do |(attr, name), data|
124
+ data[name] = ooze.respond_to?(attr)? ooze.send(attr).to_s : nil
125
+ end
126
+ end
127
+
128
+ def ordered_sections
129
+ if ooze.stages?
130
+ ooze.stages.ordered.each_with_object([]) do |stage, sections|
131
+ sections.push(*stage.sections).uniq!
132
+ end
133
+ else
134
+ ooze.sections.sort_by.with_index do |sec, index|
135
+ [sec.weight, index]
136
+ end
137
+ end
138
+ end
139
+
140
+ def export?(field, **opts)
141
+ opts = options.merge(opts)
142
+ return false unless field.respond_to?(:to_s)
143
+ return false if opts[:only_indexed] && !self.class.indexed?(field)
144
+ return false if opts[:only_labeled] && !self.class.label?(field)
145
+ return false if opts[:only_with_ref] && !self.class.with_ref?(field)
146
+ true
147
+ end
148
+
149
+ def alternative_label(field, section)
150
+ "#{field.type.upcase}::#{section.heading}"
151
+ end
152
+
153
+ def to_value(field, delimiter: self.delimiter)
154
+ return nil unless field.respond_to?(:to_s)
155
+ return field.to_s unless offers_delimiter?(field.method(:to_s))
156
+ field.to_s(delimiter: delimiter)
157
+ end
158
+
159
+ def offers_delimiter?(method)
160
+ method.parameters.any? do |(type, name)|
161
+ (type == :key) && name == :delimiter
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,72 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+ module Helpers
6
+ # Class to ease the export process
7
+ class ExportableRegister
8
+
9
+ attr_reader :options
10
+
11
+ include Eco::API::UseCases::OozeSamples::Helpers::OozeHandlers
12
+ include Enumerable
13
+
14
+ def initialize(**options)
15
+ @options = options.merge({
16
+ delimiter: "\n",
17
+ only_indexed: true,
18
+ only_labeled: true,
19
+ only_with_ref: true
20
+ })
21
+ end
22
+
23
+ def add_ooze(ooze)
24
+ ooz = ExportableOoze.new(ooze, **options)
25
+ data = ooz.key_typed_data
26
+ @typed_header = merge_arrays(data.keys, typed_header)
27
+ key_typed_data << data
28
+ end
29
+
30
+ def empty?
31
+ count < 1
32
+ end
33
+
34
+ def each(as_values: true, as_row: false, &block)
35
+ return to_enum(:each, as_row: as_row) unless block
36
+ key_typed_data.each do |ooze_data|
37
+ values = ooze_data.values_at(*typed_header)
38
+ case
39
+ when as_values
40
+ values
41
+ when as_row
42
+ ::CSV::Row.new(values, header)
43
+ else
44
+ header.zip(values)
45
+ end.tap do |out|
46
+ yield(out)
47
+ end
48
+ end
49
+ end
50
+
51
+ def header(refresh: false)
52
+ return @header if instance_variable_defined?(:@header) && !refresh
53
+ @header = typed_header.map do |name|
54
+ ExportableOoze.key_to_label(name)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def typed_header
61
+ @typed_header ||= []
62
+ end
63
+
64
+ def key_typed_data
65
+ @typed_keyed_data ||= []
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,72 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+ module Helpers
6
+ module Filters
7
+ FILTER_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
8
+
9
+ def tags_filter(tags, any: true, negate: false)
10
+ tags = [tags].flatten.compact
11
+ return nil if tags.empty?
12
+ key, name = field_key_name(:tags)
13
+ {
14
+ "tags": tags,
15
+ "mode": any ? "any" : "all",
16
+ "negate": negate,
17
+ "key": key,
18
+ "name": name,
19
+ "type": "tag_filter"
20
+ }
21
+ end
22
+
23
+ def date_range_filter(from: nil, to: nil, key: :updated_at)
24
+ return nil unless from || to
25
+ key, name = field_key_name(key)
26
+ {
27
+ "relstart": "today",
28
+ "time_zone": "Pacific/Auckland",
29
+ "relative": false,
30
+ "key": key,
31
+ "name": name,
32
+ "type": "date_filter"
33
+ }.tap do |out|
34
+ out.merge!("lbound": to_date_filter(from)) if from
35
+ out.merge!("ubound": to_date_filter(to)) if to
36
+ end
37
+ end
38
+
39
+ def to_date_filter(date)
40
+ daystart(date).utc.strftime(FILTER_TIME_FORMAT)
41
+ end
42
+
43
+ def set_time(date, h, m, s); Time.new(date.year, date.month, date.day, h, m, s); end
44
+ def weeks(num); num * days(7); end
45
+ def days(num); num * 60 * 60 * 24; end
46
+ def today; Date.today.to_time; end
47
+ def sunday(date); date + days(7 - weekday(date)); end
48
+ def midnight(date); set_time(date, 23, 59, 59); end
49
+ def daystart(date); set_time(date, 0, 0, 0); end
50
+ def previous_sunday(date); midnight(sunday(date - weeks(1))); end
51
+ def this_monday(date); set_time(previous_sunday(as_at_date) + days(1), 0, 0, 0); end
52
+
53
+ def field_key_name(value)
54
+ case value
55
+ when :updated_at
56
+ ["updated_at", "Last updated"]
57
+ when :created_at
58
+ ["created_at", "Page created"]
59
+ when Ecoportal::API::V2::Page::Component
60
+ [value.ref_backend, value.label]
61
+ when :tags
62
+ ["tags", "Location Tags"]
63
+ else
64
+ [nil , nil]
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,85 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+ module Helpers
6
+ module OozeHandlers
7
+ def merge_values(origin, append, klass: nil, delimiter: "\n")
8
+ return origin if !append || append.to_s.strip.empty?
9
+ return append if !origin || origin.to_s.strip.empty?
10
+ case klass
11
+ when Ecoportal::API::V2::Page::Component::RichTextField
12
+ merge_values(origin, append, delimiter: "\n")
13
+ when Ecoportal::API::V2::Page::Component::PlainTextField
14
+ merge_values(origin, append, delimiter: "\n")
15
+ when Ecoportal::API::V2::Page::Component::SelectionField
16
+ merge_values(origin, append, delimiter: delimiter)
17
+ when Ecoportal::API::V2::Page::Component::ReferenceField
18
+ merge_values(origin, append, delimiter: delimiter)
19
+ when Ecoportal::API::V2::Page::Component::PeopleField
20
+ merge_values(origin, append, delimiter: delimiter)
21
+ when Ecoportal::API::V2::Page::Component::DateField
22
+ origin
23
+ when Ecoportal::API::V2::Page::Component::NumberField
24
+ origin
25
+ when Ecoportal::API::V2::Page::Component::GaugeField
26
+ origin
27
+ when Ecoportal::API::V2::Page::Component::ChecklistField
28
+ merge_values(origin, append, delimiter: delimiter)
29
+ when Ecoportal::API::V2::Page::Component::ActionField
30
+ merge_values(origin, append, delimiter: delimiter)
31
+ when Ecoportal::API::V2::Page::Component::FilesField
32
+ merge_values(origin, append, delimiter: delimiter)
33
+ when Ecoportal::API::V2::Page::Component::ImagesField
34
+ merge_values(origin, append, delimiter: delimiter)
35
+ when Ecoportal::API::V2::Page::Component::GeoField
36
+ merge_values(origin, append, delimiter: delimiter)
37
+ when Ecoportal::API::V2::Page::Component::LawField
38
+ merge_values(origin, append, delimiter: delimiter)
39
+ else
40
+ [origin, append].join(delimiter)
41
+ end
42
+ end
43
+
44
+ def merge_arrays(ref, plus)
45
+ return ref if ref == plus
46
+ href_idx = array_indexes(ref)
47
+ hplus_idx = array_indexes(plus)
48
+
49
+ shared = ref & plus
50
+ hshared_ref_idx = href_idx.slice(*shared)
51
+
52
+ # hidx_plus_shared = hplus_idx.slice(*shared).each_with_object({}) do |(e, idx), reversed|
53
+ # reversed[idx] = e
54
+ # end
55
+ # shared_plus_idxs = hidx_plus_shared.keys.reverse
56
+ shared_plus_idxs = hplus_idx.values_at(*shared).sort.reverse
57
+
58
+ only_plus = plus - ref
59
+ honly_plus_idx = hplus_idx.slice(*only_plus)
60
+
61
+ hplus_ref_idx = honly_plus_idx.each_with_object({}) do |(e, idx), hplus_ref_idx|
62
+ ps_idx = shared_plus_idxs.bsearch {|i| idx >= i}
63
+ rs_idx = ps_idx ? hshared_ref_idx[plus[ps_idx]] : -1
64
+ hplus_ref_idx[e] = rs_idx
65
+ end.group_by do |e, idx|
66
+ idx
67
+ end.to_a.sort_by do |(idx, pairs)|
68
+ idx
69
+ end.reverse.to_h.transform_values do |pairs|
70
+ pairs.map(&:first)
71
+ end
72
+ hplus_ref_idx.each_with_object(ref.dup) do |(idx, elements), ref|
73
+ ref.insert(idx+1, *elements)
74
+ end
75
+ end
76
+
77
+ def array_indexes(ary)
78
+ ary.each_with_index.to_h
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,4 +1,5 @@
1
- require_relative 'helpers/shortcuts.rb'
1
+ require_relative 'helpers/shortcuts'
2
+ require_relative 'helpers/filters'
2
3
 
3
4
  module Eco
4
5
  module API
@@ -6,8 +7,13 @@ module Eco
6
7
  class OozeSamples
7
8
  module Helpers
8
9
  include OozeSamples::Helpers::Shortcuts
10
+ include OozeSamples::Helpers::Filters
9
11
  end
10
12
  end
11
13
  end
12
14
  end
13
15
  end
16
+
17
+ require_relative 'helpers/ooze_handlers'
18
+ require_relative 'helpers/exportable_ooze'
19
+ require_relative 'helpers/exportable_register'
@@ -1,4 +1,4 @@
1
- # Use case to update a register
1
+ # Use case to offer the basics to export a register
2
2
  # @note
3
3
  # - You can define methods `filters` and `search` to change the target entries of the register
4
4
  # - You need to define the `process_ooze` method
@@ -62,34 +62,35 @@ class Eco::API::UseCases::OozeSamples::RegisterExportCase < Eco::API::Common::Lo
62
62
  def build_full_ooze(ooze_id)
63
63
  if page = ooze(ooze_id)
64
64
  return page unless page.is_a?(Ecoportal::API::V2::Pages::PageStage)
65
+ pending_stage_ids = page.stages.ordered.map(&:id) - [page.current_stage_id]
66
+ state = page.state
65
67
  secs_doc = page.sections.doc
66
68
  flds_doc = page.components.doc
67
- pending_stage_ids = page.stages.map(&:id) - [page.current_stage_id]
69
+ hsecs = secs_doc.each_with_object({}) {|sec, h| h[sec["id"]] = sec}
70
+ hflds = flds_doc.each_with_object({}) {|fld, h| h[fld["id"]] = fld}
68
71
  pending_stage_ids.each do |id|
69
- if page = stage(id, ooze: page)
70
- page.sections.doc.each do |sec_doc|
71
- unless secs_doc.find {|sec| sec["id"] == sec_doc["id"]}
72
+ if other_stage = stage(id, ooze: page)
73
+ state = "inprogress" unless other_stage.state == "complete"
74
+ other_stage.sections.doc.each do |sec_doc|
75
+ unless hsecs.key?(id = sec_doc["id"])
76
+ hsecs[id] = sec_doc
72
77
  secs_doc << sec_doc
73
78
  end
74
79
  end
75
- page.components.doc.each do |comp_doc|
76
- unless flds_doc.find {|fld| fld["id"] == comp_doc["id"]}
80
+ other_stage.components.doc.each do |comp_doc|
81
+ unless hflds.key?(id = comp_doc["id"])
82
+ hflds[id] = comp_doc
77
83
  flds_doc << comp_doc
78
84
  end
79
85
  end
80
86
  end
81
87
  end
82
- Ecoportal::API::V2::Page.new(page.doc)
88
+ Ecoportal::API::V2::Pages::PageStage.new(page.doc).tap do |ozz|
89
+ ozz.state = state
90
+ end
83
91
  end
84
92
  end
85
93
 
86
- #def update_oozes(batched_oozes = batch_queue)
87
- # batched_oozes.each do |ooze|
88
- # update_ooze(ooze)
89
- # end
90
- # batched_oozes.clear
91
- #end
92
-
93
94
  def batched_search_results
94
95
  raise "Missing block. It yields in slices of #{self.class.batch_size} results" unless block_given?
95
96
  results_preview
@@ -137,10 +138,14 @@ class Eco::API::UseCases::OozeSamples::RegisterExportCase < Eco::API::Common::Lo
137
138
  exit_error "Stage '#{id_name}' doesn't exist in ooze '#{ooze_id}'"
138
139
  end
139
140
 
141
+ def default_proceed
142
+ "Y"
143
+ end
144
+
140
145
  def results_preview
141
146
  apiv2.registers.search(register_id, search_options.merge(only_first: true)).tap do |search_results|
142
147
  str_results = "Total target entries: #{search_results.total} (out of #{search_results.total_before_filtering})"
143
- session.prompt_user("Do you want to proceed (y/N):", explanation: str_results, default: "N", timeout: 10) do |res|
148
+ session.prompt_user("Do you want to proceed (y/N):", explanation: str_results, default: default_proceed, timeout: 10) do |res|
144
149
  unless res.upcase.start_with?("Y")
145
150
  puts "..."
146
151
  logger.info "Aborting script..."
@@ -180,5 +185,4 @@ class Eco::API::UseCases::OozeSamples::RegisterExportCase < Eco::API::Common::Lo
180
185
  logger.error(msg)
181
186
  exit(1)
182
187
  end
183
-
184
188
  end
@@ -163,3 +163,4 @@ require_relative 'usecases/base_io'
163
163
  require_relative 'usecases/use_case_io'
164
164
  require_relative 'usecases/default_cases'
165
165
  require_relative 'usecases/ooze_samples'
166
+ require_relative 'usecases/ooze_cases'
@@ -40,6 +40,11 @@ ASSETS.cli.config do |cnf|
40
40
  STDOUT.reopen(file, "w+")
41
41
  end
42
42
 
43
+ desc = "Skips the check of the headers"
44
+ options_set.add("-skip-header-check", desc) do |options, session|
45
+ options.deep_merge!(input: {skip_header_check: true})
46
+ end
47
+
43
48
  desc = "Fix the current session to work with this schema"
44
49
  options_set.add("-schema-id", desc) do |options, session|
45
50
  sch_name = SCR.get_arg("-schema-id", with_param: true)
@@ -147,7 +147,7 @@ ASSETS.cli.config do |cnf|
147
147
  cases.add("-entries-to-csv", :import, desc, case_name: "entries-to-csv")
148
148
  .add_option("-out") do |options|
149
149
  file = SCR.get_file("-out")
150
- options.deep_merge(export: {file: file})
150
+ options.deep_merge!(export: {file: file})
151
151
  end
152
152
 
153
153
  desc = "Usage '-org-data-convert backup.json -restore-db-from'."
@@ -254,5 +254,53 @@ ASSETS.cli.config do |cnf|
254
254
  .add_option("-append-starters", as1) do |options|
255
255
  options.deep_merge!(people: {append_created: true})
256
256
  end
257
+
258
+ # Ooze cases
259
+ desc = "APIv2 Case: Exports the target register into a CSV"
260
+ cases.add("-export-register", :other, desc, case_name: "export-register") do |session, options, usecase|
261
+ file = SCR.get_file("-export-register", required: false, should_exist: false)
262
+ options.deep_merge!(export: {file: {name: file || "RegisterExport.csv", format: :csv}})
263
+
264
+ unless options.dig(:source, :register_id)
265
+ session.logger.error "You should specify the target register id"
266
+ exit(1)
267
+ end
268
+ end.add_option("-register-id", "Target register id") do |options|
269
+ reg_id = SCR.get_arg("-register-id", with_param: true)
270
+ options.deep_merge!(source: {register_id: reg_id})
271
+ end.add_option("-include-deindexed", "Tells if deindexed fields should be included") do |options|
272
+ options.deep_merge!(export: {options: {include: {deindexed: true}}})
273
+ end.add_option("-include-unnamed", "Tells if unnamed fields should be included") do |options|
274
+ options.deep_merge!(export: {options: {include: {unnamed: true}}})
275
+ end.add_option("-include-unhashed", "Tells if fields with no hash reference (very short label) should be included") do |options|
276
+ options.deep_merge!(export: {options: {include: {unhashed: true}}})
277
+ end.add_option("-delimiter", "Sets the delimiter to be used in fields multi value") do |options|
278
+ str = SCR.get_arg("-delimiter", with_param: true)
279
+ options.deep_merge!(export: {options: {delimiter: str}})
280
+ end.add_option("-created-from", "Filters the register to the entries created FROM the specified date") do |options|
281
+ str = SCR.get_arg("-created-from", with_param: true)
282
+ date = Time.parse(str)
283
+ options.deep_merge!(export: {options: {filters: {created_at: {from: date}}}})
284
+ end.add_option("-created-to", "Filters the register to the entries created up TO the specified date") do |options|
285
+ str = SCR.get_arg("-created-to", with_param: true)
286
+ date = Time.parse(str)
287
+ options.deep_merge!(export: {options: {filters: {created_at: {to: date}}}})
288
+ end.add_option("-updated-from", "Filters the register by entries updated FROM the specified date") do |options|
289
+ str = SCR.get_arg("-updated-from", with_param: true)
290
+ date = Time.parse(str)
291
+ options.deep_merge!(export: {options: {filters: {updated_at: {from: date}}}})
292
+ end.add_option("-updated-to", "Filters the register by entries updated up TO the specified date") do |options|
293
+ str = SCR.get_arg("-updated-to", with_param: true)
294
+ date = Time.parse(str)
295
+ options.deep_merge!(export: {options: {filters: {updated_at: {to: date}}}})
296
+ end.add_option("-all-tags", "Filters the register to entries with ALL specified tags (| separator)") do |options|
297
+ str = SCR.get_arg("-all-tags", with_param: true)
298
+ tags = str.split("|")
299
+ options.deep_merge!(export: {options: {filters: {tags: {all: tags}}}})
300
+ end.add_option("-any-tags", "Filters the register to entries with ANY specified tags (| separator)") do |options|
301
+ str = SCR.get_arg("-all-tags", with_param: true)
302
+ tags = str.split("|")
303
+ options.deep_merge!(export: {options: {filters: {tags: {any: tags}}}})
304
+ end
257
305
  end
258
306
  end
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = "2.0.60"
2
+ VERSION = "2.0.61"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.60
4
+ version: 2.0.61
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -136,7 +136,7 @@ dependencies:
136
136
  requirements:
137
137
  - - ">="
138
138
  - !ruby/object:Gem::Version
139
- version: 0.8.28
139
+ version: 0.8.30
140
140
  - - "<"
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0.9'
@@ -146,7 +146,7 @@ dependencies:
146
146
  requirements:
147
147
  - - ">="
148
148
  - !ruby/object:Gem::Version
149
- version: 0.8.28
149
+ version: 0.8.30
150
150
  - - "<"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0.9'
@@ -437,6 +437,7 @@ files:
437
437
  - lib/eco/api/common/session/sftp.rb
438
438
  - lib/eco/api/common/version_patches.rb
439
439
  - lib/eco/api/common/version_patches/ecoportal_api.rb
440
+ - lib/eco/api/common/version_patches/ecoportal_api/client.rb
440
441
  - lib/eco/api/common/version_patches/ecoportal_api/external_details.rb
441
442
  - lib/eco/api/common/version_patches/ecoportal_api/external_person.rb
442
443
  - lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb
@@ -564,8 +565,14 @@ files:
564
565
  - lib/eco/api/usecases/default_cases/update_case.rb
565
566
  - lib/eco/api/usecases/default_cases/update_details_case.rb
566
567
  - lib/eco/api/usecases/default_cases/upsert_case.rb
568
+ - lib/eco/api/usecases/ooze_cases.rb
569
+ - lib/eco/api/usecases/ooze_cases/export_register_case.rb
567
570
  - lib/eco/api/usecases/ooze_samples.rb
568
571
  - lib/eco/api/usecases/ooze_samples/helpers.rb
572
+ - lib/eco/api/usecases/ooze_samples/helpers/exportable_ooze.rb
573
+ - lib/eco/api/usecases/ooze_samples/helpers/exportable_register.rb
574
+ - lib/eco/api/usecases/ooze_samples/helpers/filters.rb
575
+ - lib/eco/api/usecases/ooze_samples/helpers/ooze_handlers.rb
569
576
  - lib/eco/api/usecases/ooze_samples/helpers/shortcuts.rb
570
577
  - lib/eco/api/usecases/ooze_samples/ooze_base_case.rb
571
578
  - lib/eco/api/usecases/ooze_samples/ooze_from_doc_case.rb