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 +4 -4
- data/CHANGELOG.md +27 -2
- data/eco-helpers.gemspec +1 -1
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +5 -1
- data/lib/eco/api/common/people/entries.rb +4 -3
- data/lib/eco/api/common/version_patches/ecoportal_api/client.rb +9 -0
- data/lib/eco/api/common/version_patches/ecoportal_api.rb +1 -0
- data/lib/eco/api/usecases/default_cases.rb +1 -0
- data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +99 -0
- data/lib/eco/api/usecases/ooze_cases.rb +10 -0
- data/lib/eco/api/usecases/ooze_samples/helpers/exportable_ooze.rb +169 -0
- data/lib/eco/api/usecases/ooze_samples/helpers/exportable_register.rb +72 -0
- data/lib/eco/api/usecases/ooze_samples/helpers/filters.rb +72 -0
- data/lib/eco/api/usecases/ooze_samples/helpers/ooze_handlers.rb +85 -0
- data/lib/eco/api/usecases/ooze_samples/helpers.rb +7 -1
- data/lib/eco/api/usecases/ooze_samples/register_export_case.rb +21 -17
- data/lib/eco/api/usecases.rb +1 -0
- data/lib/eco/cli/config/default/options.rb +5 -0
- data/lib/eco/cli/config/default/usecases.rb +49 -1
- data/lib/eco/version.rb +1 -1
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21aabfeb392bd158c029ee8c1cd2503d0d6686d339333c80757a7fda273e9095
|
4
|
+
data.tar.gz: 23e15a543b809c2b8b9c0e51e17982da4915c7af170ddb18207b162d74752d22
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
163
|
+
csv << entry.internal_entry.values_at(*header)
|
163
164
|
end
|
164
165
|
end
|
165
166
|
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,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
|
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
|
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
|
-
|
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
|
70
|
-
|
71
|
-
|
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
|
-
|
76
|
-
unless
|
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::
|
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:
|
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
|
data/lib/eco/api/usecases.rb
CHANGED
@@ -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
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.
|
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.
|
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.
|
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
|