eco-helpers 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/eco-helpers.rb +1 -0
- data/lib/eco/api/common/people.rb +1 -0
- data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +1 -1
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +4 -1
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +1 -1
- data/lib/eco/api/common/people/entries.rb +10 -0
- data/lib/eco/api/common/people/supervisor_helpers.rb +142 -0
- data/lib/eco/cli/config/default/filters.rb +4 -4
- data/lib/eco/cli/config/default/options.rb +16 -0
- data/lib/eco/csv.rb +33 -0
- data/lib/eco/csv/table.rb +79 -0
- data/lib/eco/language/models/collection.rb +3 -4
- data/lib/eco/version.rb +1 -1
- metadata +24 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa39fb0038e03d65a129a3d7df06f5c3fba60518ef847cd89cfe0d973f27065e
|
4
|
+
data.tar.gz: f22d6d27a952af99e4f84eb1ed29a8b930d7226f0a67d60c86f6eabb4a15715f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 070ee0c500e334ef8bf149bdf3ec24fd20480a16a3b4742f25247fccd09a8ef476a3bdfcfb45119a4fa37dc1c0dbe415cf53de2fa6ecd4722fa81f65c3762450
|
7
|
+
data.tar.gz: c4456bbbfd19b4e03734f6dd9b388087c7a7aee44dba138ec2aa1dfc78ceff0024c222589d5e9857561b25ef730faf3f9e8008dfb5d4dd006cfaa47c15c197a7
|
data/lib/eco-helpers.rb
CHANGED
@@ -15,5 +15,6 @@ require_relative 'people/person_parser'
|
|
15
15
|
require_relative 'people/default_parsers'
|
16
16
|
require_relative 'people/person_entry_attribute_mapper'
|
17
17
|
require_relative 'people/person_entry'
|
18
|
+
require_relative 'people/supervisor_helpers'
|
18
19
|
require_relative 'people/entries'
|
19
20
|
require_relative 'people/entry_factory'
|
@@ -9,7 +9,10 @@ module Eco
|
|
9
9
|
@parsers.define_attribute(:csv, dependencies: @options) do |parser|
|
10
10
|
parser.def_parser do |data, deps|
|
11
11
|
arr_hash = []
|
12
|
-
CSV.parse(data, headers: true).
|
12
|
+
CSV.parse(data, headers: true, skip_blanks: true).reject do |row|
|
13
|
+
values = row.to_hash.values
|
14
|
+
values.all?(&:nil?) || values.map(&:to_s).all?(&:empty?)
|
15
|
+
end.each do |row|
|
13
16
|
row_hash = row.headers.uniq.each_with_object({}) do |attr, hash|
|
14
17
|
value = row[attr]
|
15
18
|
hash[attr] = value.to_s.empty?? nil : value
|
@@ -8,7 +8,7 @@ module Eco
|
|
8
8
|
def process
|
9
9
|
@parsers.define_attribute(:number, dependencies: @options) do |parser|
|
10
10
|
parser.def_parser do |value, deps|
|
11
|
-
value = value.to_s.strip
|
11
|
+
value = value.to_s.strip.empty? ? nil : (value.to_f rescue nil)
|
12
12
|
end.def_serializer do |value|
|
13
13
|
value.is_a?(Array) ? value.map { |v| v.to_s } : value.to_s
|
14
14
|
end
|
@@ -10,11 +10,20 @@ module Eco
|
|
10
10
|
|
11
11
|
alias_method :entries, :to_a
|
12
12
|
|
13
|
+
include Eco::API::Common::People::SupervisorHelpers
|
14
|
+
|
13
15
|
def initialize(data = [], klass:, factory:)
|
14
16
|
super(data, klass: klass, factory: factory)
|
15
17
|
@caches_init = false
|
16
18
|
end
|
17
19
|
|
20
|
+
# Override `each` to make it work with supervisor hiearchy
|
21
|
+
def each(params: {}, &block)
|
22
|
+
return to_enum(:each) unless block
|
23
|
+
@array_supers = sort_by_supervisors(@items) unless @caches_init
|
24
|
+
@array_supers.each(&block)
|
25
|
+
end
|
26
|
+
|
18
27
|
def [](id_or_ext)
|
19
28
|
id(id_or_ext) || external_id(id_or_ext)
|
20
29
|
end
|
@@ -96,6 +105,7 @@ module Eco
|
|
96
105
|
@by_id = to_h
|
97
106
|
@by_external_id = to_h('external_id')
|
98
107
|
@by_email = to_h('email')
|
108
|
+
@array_supers = sort_by_supervisors(@items)
|
99
109
|
@caches_init = true
|
100
110
|
end
|
101
111
|
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module Common
|
4
|
+
module People
|
5
|
+
# Used with `Enumerable` of objects that have the following methods:
|
6
|
+
# * `supervisor_id`
|
7
|
+
# * `external_id`
|
8
|
+
# * `id`
|
9
|
+
module SupervisorHelpers
|
10
|
+
|
11
|
+
# Reorders as follows:
|
12
|
+
# 1. supervisors, people with no supervisor or where their supervisor not present
|
13
|
+
# 2. subordinates
|
14
|
+
def sort_by_supervisors(values, supervisors_first: true)
|
15
|
+
raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
|
16
|
+
return [] unless values && values.is_a?(Enumerable)
|
17
|
+
roam = Proc.new do |tree|
|
18
|
+
[].tap do |out|
|
19
|
+
sub_outs = tree.empty?? [] : tree.map {|sup, subtree| roam.call(subtree)}
|
20
|
+
tree.each do |sup, subtree|
|
21
|
+
sout = subtree.empty?? [] :roam.call(subtree)
|
22
|
+
supervisors_first ? sout.unshift(sup) : sout.push(sup)
|
23
|
+
out.concat(sout)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
roam.call(supervisors_tree(values))
|
29
|
+
end
|
30
|
+
|
31
|
+
def tree_to_str(tree, lev: 0)
|
32
|
+
raise "Required Hash tree structure. Given: #{tree.class}" unless tree.is_a?(Hash)
|
33
|
+
"".tap do |str|
|
34
|
+
tree.each do |entry, subtree|
|
35
|
+
str << "#{" " * lev}+-- #{entry.id || entry.external_id}\n"
|
36
|
+
str << tree_to_str(subtree, lev: lev + 1) unless !subtree || subtree.empty?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def print_tree(tree, lev: 0)
|
42
|
+
puts tree_to_str(tree)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Generates a `Hash` tree structure, where:
|
46
|
+
# * **keys** are nodes
|
47
|
+
# * **values** are `Hash` subtree structures of `key` subordinates
|
48
|
+
# @note it is resilient to cyclic supervisors (it will just add the last at the top)
|
49
|
+
# @param values [Enumerable<Object>] of objects with methods:
|
50
|
+
# `id`, `external_id` and `supervisor_id`
|
51
|
+
# @return [Hash] the tree structure
|
52
|
+
def supervisors_tree(values)
|
53
|
+
raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
|
54
|
+
return {} unless values && values.is_a?(Enumerable)
|
55
|
+
idx = get_super_indexes(values)
|
56
|
+
|
57
|
+
processed = []
|
58
|
+
subtree = Proc.new do |entry, level, toptree|
|
59
|
+
if processed.include?(entry)
|
60
|
+
next {} unless toptree.key?(entry) && level > 0
|
61
|
+
# needs to be moved as a child
|
62
|
+
subnodes = toptree.delete(entry)
|
63
|
+
processed.delete(entry)
|
64
|
+
end
|
65
|
+
|
66
|
+
subnodes ||= {}.tap do |tree|
|
67
|
+
subs = idx[:subordinates].call(entry)
|
68
|
+
processed.push(entry)
|
69
|
+
next nil unless subs && !subs.empty?
|
70
|
+
subs.each do |sub|
|
71
|
+
sub_tree = subtree.call(sub, level + 1, toptree)
|
72
|
+
tree.merge!(sub_tree)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
{entry => subnodes}
|
77
|
+
end
|
78
|
+
|
79
|
+
{}.tap do |tree|
|
80
|
+
idx[:by_sup].keys.each do |sup_id|
|
81
|
+
if sup = idx[:supers][sup_id]
|
82
|
+
tree.merge!(subtree.call(sup, 0, tree))
|
83
|
+
else
|
84
|
+
idx[:by_sup][sup_id].each do |sub|
|
85
|
+
tree.merge!(subtree.call(sub, 0, tree))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def get_super_indexes(values)
|
95
|
+
raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
|
96
|
+
{}.tap do |indexes|
|
97
|
+
indexes[:by_id] = values.map do |e|
|
98
|
+
e.id && [e.id, e]
|
99
|
+
end.compact.to_h
|
100
|
+
indexes[:by_ext] = values.map do |e|
|
101
|
+
e.external_id && [e.external_id, e]
|
102
|
+
end.compact.to_h
|
103
|
+
|
104
|
+
indexes[:by_sup] = {}.tap do |by_s|
|
105
|
+
values.group_by do |e|
|
106
|
+
e.supervisor_id
|
107
|
+
end.tap do |by_sup|
|
108
|
+
by_s[nil] = by_sup.delete(nil) if by_sup.key?(nil)
|
109
|
+
by_s.merge!(by_sup)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
indexes[:supers] = {}.tap do |sups|
|
114
|
+
indexes[:by_ext].select do |ext, e|
|
115
|
+
ext && indexes[:by_sup].key?(ext)
|
116
|
+
end.tap {|found| sups.merge!(found)}
|
117
|
+
indexes[:by_id].select do |id, e|
|
118
|
+
id && indexes[:by_sup].key?(id)
|
119
|
+
end.tap {|found| sups.merge!(found)}
|
120
|
+
end
|
121
|
+
|
122
|
+
indexes[:is_super] = Proc.new do |entry|
|
123
|
+
!!(indexes[:supers][entry.id] || indexes[:supers][entry.external_id])
|
124
|
+
end
|
125
|
+
|
126
|
+
indexes[:subordinates] = Proc.new do |entry|
|
127
|
+
subs = nil
|
128
|
+
if sup = indexes[:supers][entry.id] || indexes[:supers][entry.external_id]
|
129
|
+
subs ||= indexes[:by_sup][sup.id] unless !sup.id
|
130
|
+
subs ||= indexes[:by_sup][sup.external_id] unless !sup.external_id
|
131
|
+
end
|
132
|
+
subs
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -56,13 +56,13 @@ ASSETS.cli.config do |cnf|
|
|
56
56
|
end
|
57
57
|
|
58
58
|
options.deep_merge!(people: {filter: {details: {schema_id: sch_id}}})
|
59
|
-
session.logger.info("Filtering
|
60
|
-
|
61
|
-
session.schema = sch_id
|
62
|
-
|
59
|
+
session.logger.info("Filtering people entries with schema #{session.schemas.to_name(sch_id)}")
|
60
|
+
|
63
61
|
filtered = people.select do |person|
|
64
62
|
person.details && (person.details.schema_id == sch_id)
|
65
63
|
end
|
64
|
+
session.logger.info("Filtered #{filtered.count} people out of #{people.count} total")
|
65
|
+
|
66
66
|
people.newFrom filtered
|
67
67
|
end
|
68
68
|
|
@@ -1,6 +1,22 @@
|
|
1
1
|
ASSETS.cli.config do |cnf|
|
2
2
|
cnf.options_set do |options_set, options|
|
3
3
|
|
4
|
+
options_set.add("-schema-id") do |options, session|
|
5
|
+
sch_name = SCR.get_arg("-schema-id", with_param: true)
|
6
|
+
sch_id = session.schemas.to_id(sch_name)
|
7
|
+
|
8
|
+
unless sch_id
|
9
|
+
msg = "You need to specify a schema id or name. '#{sch_id}' does not exist"
|
10
|
+
session.logger.error(msg)
|
11
|
+
exit(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
options.deep_merge!(people: {filter: {details: {schema_id: sch_id}}})
|
15
|
+
session.logger.info("Setting schema #{session.schemas.to_name(sch_id)}")
|
16
|
+
|
17
|
+
session.schema = sch_id
|
18
|
+
end
|
19
|
+
|
4
20
|
options_set.add("-entries-from") do |options, session|
|
5
21
|
options.deep_merge!(input: {entries_from: true})
|
6
22
|
end
|
data/lib/eco/csv.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Eco
|
4
|
+
class CSV < ::CSV
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def parse(data, **kargs, &block)
|
9
|
+
kargs = {headers: true, skip_blanks: true}.merge(kargs)
|
10
|
+
out = super(data, **kargs, &block).reject do |row|
|
11
|
+
values = row.to_hash.values
|
12
|
+
values.all?(&:nil?) || values.map(&:to_s).all?(&:empty?)
|
13
|
+
end
|
14
|
+
Eco::CSV::Table.new(out)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(file, **kargs)
|
18
|
+
coding = Eco::API::Common::Session::FileManager.encoding(file)
|
19
|
+
kargs = {headers: true, skip_blanks: true, encoding: coding}.merge(kargs)
|
20
|
+
out = super(file, **kargs).reject do |row|
|
21
|
+
values = row.to_hash.values
|
22
|
+
values.all?(&:nil?) || values.map(&:to_s).all?(&:empty?)
|
23
|
+
end
|
24
|
+
Eco::CSV::Table.new(out)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require_relative 'csv/table'
|
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
module Eco
|
3
|
+
class CSV
|
4
|
+
class Table < ::CSV::Table
|
5
|
+
|
6
|
+
# @param ary_arrays [Array<Row>, Array<Array>, Eco::CSV::Table, ::CSV::Table]
|
7
|
+
# - when `Array<Array>` => all `rows` as arrays where first array is the **header**
|
8
|
+
def initialize(input)
|
9
|
+
super(to_rows_array(input))
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Array<::CSV::Row>]
|
13
|
+
def rows
|
14
|
+
[].tap do |out|
|
15
|
+
self.each {|row| out << row}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Integer] total number of rows not including the header
|
20
|
+
def length
|
21
|
+
to_a.length - 1
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Array<Array>] each array is the column header followed by its values
|
25
|
+
def columns
|
26
|
+
to_a.transpose
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adds a new column at the end
|
30
|
+
# @param header_name [String] header of the new column
|
31
|
+
# @return [Eco::CSV::Table] with a new empty column
|
32
|
+
def add_column(header_name)
|
33
|
+
new_col = Array.new(length).unshift(header_name)
|
34
|
+
columns_to_table(columns.push(new_col))
|
35
|
+
end
|
36
|
+
|
37
|
+
# @note it will override columns with same header name
|
38
|
+
# @return [Hash] keys are headers, values are arrays
|
39
|
+
def columns_hash
|
40
|
+
columns.map do |col|
|
41
|
+
[col.first, col[1..-1]]
|
42
|
+
end.to_h
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def columns_to_table(columns_array)
|
48
|
+
data = to_rows_array(columns_array.transpose)
|
49
|
+
self.class.new(data)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_rows_array(data)
|
53
|
+
case data
|
54
|
+
when Array
|
55
|
+
return data unless data.length > 0
|
56
|
+
if data.first.is_a?(::CSV::Row)
|
57
|
+
data
|
58
|
+
elsif data.first.is_a?(Array)
|
59
|
+
headers = data.shift
|
60
|
+
data.map do |arr_row|
|
61
|
+
CSV::Row.new(headers, arr_row)
|
62
|
+
end.compact
|
63
|
+
else
|
64
|
+
raise "Expected data that can be transformed into Array<Array>"
|
65
|
+
end
|
66
|
+
when ::CSV::Table
|
67
|
+
to_rows_array(data.to_a)
|
68
|
+
when Hash
|
69
|
+
# hash of columns header as key and column array as value
|
70
|
+
rows_arrays = [a.keys].concat(a.values.first.zip(*a.values[1..-1]))
|
71
|
+
to_rows_array(data.keys)
|
72
|
+
else
|
73
|
+
raise "Input type not supported. Given: #{data.class}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -154,10 +154,9 @@ module Eco
|
|
154
154
|
self.attr(attr, value, modifier)
|
155
155
|
end
|
156
156
|
|
157
|
-
def group_by(attr)
|
158
|
-
to_h(attr)
|
159
|
-
|
160
|
-
#self.to_a.group_by { |object| object.method(attr).call }
|
157
|
+
def group_by(attr = nil, &block)
|
158
|
+
return to_h(attr) if attr
|
159
|
+
to_a.group_by(&block) if block
|
161
160
|
end
|
162
161
|
|
163
162
|
def to_h(attr)
|
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: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
@@ -82,22 +82,22 @@ dependencies:
|
|
82
82
|
name: redcarpet
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
|
-
- - ">="
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: 3.5.0
|
88
85
|
- - "~>"
|
89
86
|
- !ruby/object:Gem::Version
|
90
87
|
version: '3.5'
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 3.5.0
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - ">="
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: 3.5.0
|
98
95
|
- - "~>"
|
99
96
|
- !ruby/object:Gem::Version
|
100
97
|
version: '3.5'
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 3.5.0
|
101
101
|
- !ruby/object:Gem::Dependency
|
102
102
|
name: ecoportal-api
|
103
103
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,42 +142,42 @@ dependencies:
|
|
142
142
|
name: aws-sdk-ses
|
143
143
|
requirement: !ruby/object:Gem::Requirement
|
144
144
|
requirements:
|
145
|
-
- - ">="
|
146
|
-
- !ruby/object:Gem::Version
|
147
|
-
version: 1.14.0
|
148
145
|
- - "~>"
|
149
146
|
- !ruby/object:Gem::Version
|
150
147
|
version: '1.14'
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 1.14.0
|
151
151
|
type: :runtime
|
152
152
|
prerelease: false
|
153
153
|
version_requirements: !ruby/object:Gem::Requirement
|
154
154
|
requirements:
|
155
|
-
- - ">="
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: 1.14.0
|
158
155
|
- - "~>"
|
159
156
|
- !ruby/object:Gem::Version
|
160
157
|
version: '1.14'
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 1.14.0
|
161
161
|
- !ruby/object:Gem::Dependency
|
162
162
|
name: dotenv
|
163
163
|
requirement: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
|
-
- - ">="
|
166
|
-
- !ruby/object:Gem::Version
|
167
|
-
version: 2.6.0
|
168
165
|
- - "~>"
|
169
166
|
- !ruby/object:Gem::Version
|
170
167
|
version: '2.6'
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: 2.6.0
|
171
171
|
type: :runtime
|
172
172
|
prerelease: false
|
173
173
|
version_requirements: !ruby/object:Gem::Requirement
|
174
174
|
requirements:
|
175
|
-
- - ">="
|
176
|
-
- !ruby/object:Gem::Version
|
177
|
-
version: 2.6.0
|
178
175
|
- - "~>"
|
179
176
|
- !ruby/object:Gem::Version
|
180
177
|
version: '2.6'
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 2.6.0
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: net-sftp
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -235,6 +235,7 @@ files:
|
|
235
235
|
- lib/eco/api/common/people/person_factory.rb
|
236
236
|
- lib/eco/api/common/people/person_modifier.rb
|
237
237
|
- lib/eco/api/common/people/person_parser.rb
|
238
|
+
- lib/eco/api/common/people/supervisor_helpers.rb
|
238
239
|
- lib/eco/api/common/session.rb
|
239
240
|
- lib/eco/api/common/session/base_session.rb
|
240
241
|
- lib/eco/api/common/session/environment.rb
|
@@ -344,6 +345,8 @@ files:
|
|
344
345
|
- lib/eco/cli/scripting/argument.rb
|
345
346
|
- lib/eco/cli/scripting/arguments.rb
|
346
347
|
- lib/eco/common.rb
|
348
|
+
- lib/eco/csv.rb
|
349
|
+
- lib/eco/csv/table.rb
|
347
350
|
- lib/eco/data.rb
|
348
351
|
- lib/eco/data/crypto.rb
|
349
352
|
- lib/eco/data/crypto/encryption.rb
|
@@ -384,7 +387,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
384
387
|
- !ruby/object:Gem::Version
|
385
388
|
version: '0'
|
386
389
|
requirements: []
|
387
|
-
|
390
|
+
rubyforge_project:
|
391
|
+
rubygems_version: 2.7.6.2
|
388
392
|
signing_key:
|
389
393
|
specification_version: 4
|
390
394
|
summary: eco-helpers to manage people api cases
|