trials 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/trial +7 -2
- data/lib/trials.rb +2 -4
- data/lib/trials/utils/aws.rb +1 -2
- data/lib/trials/utils/csvs.rb +3 -3
- data/lib/trials/utils/files.rb +71 -109
- data/lib/trials/utils/google_drive.rb +2 -2
- data/lib/trials/utils/h_array.rb +14 -0
- data/lib/trials/utils/jsons.rb +4 -4
- data/lib/trials/utils/logging.rb +2 -2
- data/lib/trials/utils/pdfs.rb +1 -1
- data/lib/trials/utils/sqls.rb +2 -2
- data/lib/trials/utils/various.rb +18 -0
- metadata +1 -4
- data/lib/trials/data_handling/addresses.rb +0 -37
- data/lib/trials/data_handling/names.rb +0 -84
- data/lib/trials/utils/hashes.rb +0 -90
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f8af3df6ab16bb8ba4b08d0ea7b1dd11507aeb2c6113a0598a5e9965d0264c9
|
4
|
+
data.tar.gz: c1e9cc7305f5cee913a7091d321811153d33e9e67d383bad0f1518034a195556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4bdc989741b4f86a3b80f91979a3882c2666da4749ee7864f0b45596311cbdebd297e17950d27bb84d39efc6d30b16fa18fc1a1bd4f65b98cd213ec4e0cbba7
|
7
|
+
data.tar.gz: d3fa929a7157792cd5fce04b64f0d0312ce240f59de755d323dc1ee910a21f9a966e74342a5e4c0d05d732291ab28a7b7a324bad6a5e1afb3c0293ea0c682c1c
|
data/bin/trial
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require_relative '../lib/trials'
|
4
|
-
|
5
3
|
# env
|
6
4
|
START_TIME = Time.now
|
7
5
|
SCRIPT_NAME = ARGV[0].gsub('.rb', '')
|
8
6
|
RUN = "#{START_TIME.strftime("%Y%m%dT%H%M%S")}_#{SCRIPT_NAME}"
|
9
7
|
ROOT = Dir.pwd
|
8
|
+
|
9
|
+
require_relative '../lib/trials'
|
10
|
+
|
10
11
|
SECRETS = begin
|
11
12
|
if File.exists?(File.expand_path('~/.trials/secrets.yml'))
|
12
13
|
JSON.parse(
|
@@ -22,6 +23,10 @@ end
|
|
22
23
|
FileUtils.mkdir_p("seeds")
|
23
24
|
FileUtils.mkdir_p("results/#{RUN}")
|
24
25
|
FileUtils.mkdir_p("tmp")
|
26
|
+
FileUtils.mkdir_p("cache")
|
27
|
+
|
28
|
+
# allow to init the current folder
|
29
|
+
return if SCRIPT_NAME == 'init'
|
25
30
|
|
26
31
|
# log start
|
27
32
|
log "starting #{SCRIPT_NAME} at #{START_TIME.iso8601}"
|
data/lib/trials.rb
CHANGED
@@ -10,18 +10,18 @@ require 'nokogiri'
|
|
10
10
|
require 'ostruct'
|
11
11
|
require 'pp'
|
12
12
|
require 'pry'
|
13
|
+
require 'rack'
|
13
14
|
require 'rest-client'
|
15
|
+
require 'securerandom'
|
14
16
|
require 'set'
|
15
17
|
require 'smalltext'
|
16
18
|
require 'sqlite3'
|
17
19
|
require 'street_address'
|
18
20
|
require 'tty-table'
|
19
21
|
require 'yaml'
|
20
|
-
require 'rack'
|
21
22
|
|
22
23
|
require_relative 'trials/utils/various'
|
23
24
|
require_relative 'trials/utils/csvs'
|
24
|
-
require_relative 'trials/utils/hashes'
|
25
25
|
require_relative 'trials/utils/logging'
|
26
26
|
require_relative 'trials/utils/strings'
|
27
27
|
require_relative 'trials/utils/files'
|
@@ -34,7 +34,5 @@ require_relative 'trials/utils/rollbar'
|
|
34
34
|
require_relative 'trials/utils/aws'
|
35
35
|
require_relative 'trials/utils/google_drive'
|
36
36
|
require_relative 'trials/utils/h_array'
|
37
|
-
require_relative 'trials/data_handling/addresses'
|
38
|
-
require_relative 'trials/data_handling/names'
|
39
37
|
require_relative 'trials/extensions/hash'
|
40
38
|
require_relative 'trials/extensions/array'
|
data/lib/trials/utils/aws.rb
CHANGED
@@ -6,7 +6,7 @@ def ddb_connection
|
|
6
6
|
)
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def ddb_scan_with_cache(query)
|
10
10
|
json_cache(query.dig(:table_name)) { ddb_scan(query) }
|
11
11
|
end
|
12
12
|
|
@@ -31,7 +31,6 @@ end
|
|
31
31
|
|
32
32
|
def ddb_scan_without_segmentation(query)
|
33
33
|
result = nil
|
34
|
-
requests = 0
|
35
34
|
items = []
|
36
35
|
|
37
36
|
loop do
|
data/lib/trials/utils/csvs.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
def read_csv(filename)
|
2
2
|
CSV
|
3
|
-
.foreach(
|
3
|
+
.foreach(seed_path(filename), headers: true)
|
4
4
|
.map(&:to_h)
|
5
5
|
.map(&:symbolize_keys)
|
6
6
|
.select { |i| i.values.any?(&:present?) }
|
7
7
|
end
|
8
8
|
|
9
9
|
def write_csv_from_hashes(file, hash_set, attrs: nil)
|
10
|
-
attrs ||=
|
10
|
+
attrs ||= hash_set.to_harray.uniq_keys
|
11
11
|
|
12
|
-
CSV.open(
|
12
|
+
CSV.open(result_path(file), 'w') do |csv|
|
13
13
|
csv << attrs
|
14
14
|
|
15
15
|
hash_set.each do |c|
|
data/lib/trials/utils/files.rb
CHANGED
@@ -1,110 +1,72 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
def append(file, content)
|
74
|
-
File.open(results_path(file), 'a') { |f| f << content }
|
75
|
-
end
|
76
|
-
|
77
|
-
alias append_result append
|
78
|
-
alias append_results append
|
79
|
-
|
80
|
-
# deleting
|
81
|
-
|
82
|
-
def delete(file)
|
83
|
-
return unless result_exists?(file)
|
84
|
-
FileUtils.rm_r(results_path(file))
|
85
|
-
end
|
86
|
-
|
87
|
-
alias delete_result delete
|
88
|
-
alias delete_results delete
|
89
|
-
|
90
|
-
def delete_tmp(file)
|
91
|
-
return unless tmp_exists?(file)
|
92
|
-
FileUtils.rm_r(tmp_path(file))
|
93
|
-
end
|
94
|
-
|
95
|
-
def delete_seeds(file)
|
96
|
-
return unless seed_exists?(file)
|
97
|
-
FileUtils.rm_r(seeds_path(file))
|
98
|
-
end
|
99
|
-
|
100
|
-
alias delete_seed delete_seeds
|
101
|
-
|
102
|
-
# other
|
103
|
-
|
104
|
-
def make_seed(file)
|
105
|
-
FileUtils.cp(results_path(file), seeds_path(file))
|
106
|
-
end
|
107
|
-
|
108
|
-
def make_tmp(file)
|
109
|
-
FileUtils.cp(results_path(file), tmp_path(file))
|
1
|
+
dirs = {
|
2
|
+
seed: { run: false, pluralized: ActiveSupport::Inflector.pluralize('seed') },
|
3
|
+
result: { run: true, pluralized: ActiveSupport::Inflector.pluralize('result') },
|
4
|
+
tmp: { run: false, pluralized: 'tmp' },
|
5
|
+
cache: { run: false, pluralized: 'cache' },
|
6
|
+
}
|
7
|
+
|
8
|
+
dirs.each do |dir, opts|
|
9
|
+
eval <<~RUBY
|
10
|
+
def #{opts.dig(:pluralized)}_root
|
11
|
+
File.join(
|
12
|
+
ROOT,
|
13
|
+
'#{opts.dig(:pluralized)}',
|
14
|
+
'#{opts.dig(:run) ? RUN : nil}',
|
15
|
+
).to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def #{dir}_path(name)
|
19
|
+
File.join(
|
20
|
+
#{opts.dig(:pluralized)}_root,
|
21
|
+
name,
|
22
|
+
).to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def #{dir}_exists?(name)
|
26
|
+
File.exist?(#{dir}_path(name))
|
27
|
+
end
|
28
|
+
|
29
|
+
def list_#{opts.dig(:pluralized)}(name = nil)
|
30
|
+
Dir[
|
31
|
+
File.join(
|
32
|
+
*[
|
33
|
+
#{opts.dig(:pluralized)}_root,
|
34
|
+
name,
|
35
|
+
'**',
|
36
|
+
'*',
|
37
|
+
].compact
|
38
|
+
)
|
39
|
+
].reject { |d| File.directory?(d) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_#{dir}(name)
|
43
|
+
File.read(#{dir}_path(name)) if #{dir}_exists?(name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def readlines_#{dir}(name)
|
47
|
+
read_#{dir}(name).split("\\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_#{dir}(name, content)
|
51
|
+
FileUtils.mkdir_p(File.dirname(#{dir}_path(name)))
|
52
|
+
File.open(#{dir}_path(name), 'w') { |f| f << content }
|
53
|
+
end
|
54
|
+
|
55
|
+
def append_to_#{dir}(name, content)
|
56
|
+
File.open(#{dir}_path(name), 'a') { |f| f << content }
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_#{dir}(name)
|
60
|
+
FileUtils.rm_r(#{dir}_path(name)) if #{dir}_exists?(name)
|
61
|
+
end
|
62
|
+
RUBY
|
63
|
+
|
64
|
+
dirs.each do |o_dir, o_opts|
|
65
|
+
next if o_dir == dir
|
66
|
+
eval <<~RUBY
|
67
|
+
def cp_#{o_dir}_to_#{opts.dig(:pluralized)}(name)
|
68
|
+
FileUtils.cp(#{o_dir}_path(name), #{dir}_path(name))
|
69
|
+
end
|
70
|
+
RUBY
|
71
|
+
end
|
110
72
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
def gd_session
|
2
2
|
@gd_session ||= begin
|
3
|
-
|
4
|
-
session = GoogleDrive::Session.from_config(
|
3
|
+
write_tmp('config.json', secrets.google.drive_config_json)
|
4
|
+
session = GoogleDrive::Session.from_config(tmp_path("config.json"))
|
5
5
|
delete('config.json')
|
6
6
|
session
|
7
7
|
end
|
data/lib/trials/utils/h_array.rb
CHANGED
@@ -20,6 +20,14 @@ class HArray < Array
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def normalize_keys
|
24
|
+
hashes.map do |h|
|
25
|
+
h
|
26
|
+
.map { |k, v| [normalize_key(k), v] }
|
27
|
+
.to_h
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
23
31
|
def uniq_keys
|
24
32
|
hashes.flat_map(&:keys).uniq.compact
|
25
33
|
end
|
@@ -49,4 +57,10 @@ class HArray < Array
|
|
49
57
|
.reduce(&:merge)
|
50
58
|
end
|
51
59
|
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def normalize_key(k)
|
64
|
+
k.downcase.to_sym
|
65
|
+
end
|
52
66
|
end
|
data/lib/trials/utils/jsons.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
def read_json(filename)
|
2
|
-
result = JSON.parse(
|
2
|
+
result = JSON.parse(read_seed(filename))
|
3
3
|
|
4
4
|
aggressive_deep_symbolize_keys(result)
|
5
5
|
end
|
@@ -11,12 +11,12 @@ end
|
|
11
11
|
def json_cache(key)
|
12
12
|
name = "json/#{key}.json"
|
13
13
|
|
14
|
-
return aggressive_deep_symbolize_keys(JSON.parse(
|
14
|
+
return aggressive_deep_symbolize_keys(JSON.parse(read_cache(name))) if cache_exists?(name)
|
15
15
|
|
16
|
-
|
16
|
+
write_cache(name, yield.to_json)
|
17
17
|
json_cache(key)
|
18
18
|
end
|
19
19
|
|
20
20
|
def invalidate_json_cache
|
21
|
-
|
21
|
+
delete_cache("json")
|
22
22
|
end
|
data/lib/trials/utils/logging.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
def render_table_from_hashes(hash_set, sort: true, headers: nil)
|
2
2
|
return 'no data' if hash_set.blank?
|
3
3
|
|
4
|
-
headers = headers ||
|
4
|
+
headers = headers || hash_set.to_harray.uniq_keys
|
5
5
|
|
6
6
|
headers.sort! if sort
|
7
7
|
|
@@ -21,7 +21,7 @@ def log(item, nl: true, quiet: false, each: true)
|
|
21
21
|
return
|
22
22
|
end
|
23
23
|
|
24
|
-
File.open(
|
24
|
+
File.open(result_path('log.txt'), 'a') do |f|
|
25
25
|
f << begin
|
26
26
|
if item.is_a?(String) || item.is_a?(Numeric)
|
27
27
|
item.to_s
|
data/lib/trials/utils/pdfs.rb
CHANGED
data/lib/trials/utils/sqls.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
def db(db_name = nil)
|
2
2
|
db_name ||= 'data.db'
|
3
|
-
db = SQLite3::Database.new(
|
3
|
+
db = SQLite3::Database.new(cache_path(db_name))
|
4
4
|
db.results_as_hash = true
|
5
5
|
db
|
6
6
|
end
|
@@ -14,7 +14,7 @@ def get_db(db_name = nil)
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def import_csv_into_db(db_name = 'data.db', table, csv)
|
17
|
-
system("sqlite3 -csv #{
|
17
|
+
system("sqlite3 -csv #{cache_path(db_name)} '.import #{seed_path(csv)} #{table}'")
|
18
18
|
end
|
19
19
|
|
20
20
|
def query_db(db_name = nil, query)
|
data/lib/trials/utils/various.rb
CHANGED
@@ -2,6 +2,14 @@ def secrets
|
|
2
2
|
SECRETS
|
3
3
|
end
|
4
4
|
|
5
|
+
def run
|
6
|
+
RUN
|
7
|
+
end
|
8
|
+
|
9
|
+
def root_path
|
10
|
+
ROOT
|
11
|
+
end
|
12
|
+
|
5
13
|
def or_nil
|
6
14
|
val = yield
|
7
15
|
raise if val.blank?
|
@@ -25,3 +33,13 @@ def aggressive_deep_symbolize_keys(maybe)
|
|
25
33
|
|
26
34
|
maybe
|
27
35
|
end
|
36
|
+
|
37
|
+
def marshal_fetch(key)
|
38
|
+
return Marshal.load(read_cache(key)) if cache_exists?(key)
|
39
|
+
|
40
|
+
File.open(cache_path(key), 'wb') do |f|
|
41
|
+
f.write(Marshal.dump(yield))
|
42
|
+
end
|
43
|
+
|
44
|
+
marshal_fetch(key)
|
45
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trials
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- grahamotte
|
@@ -299,8 +299,6 @@ extra_rdoc_files: []
|
|
299
299
|
files:
|
300
300
|
- bin/trial
|
301
301
|
- lib/trials.rb
|
302
|
-
- lib/trials/data_handling/addresses.rb
|
303
|
-
- lib/trials/data_handling/names.rb
|
304
302
|
- lib/trials/extensions/array.rb
|
305
303
|
- lib/trials/extensions/hash.rb
|
306
304
|
- lib/trials/utils/aws.rb
|
@@ -309,7 +307,6 @@ files:
|
|
309
307
|
- lib/trials/utils/files.rb
|
310
308
|
- lib/trials/utils/google_drive.rb
|
311
309
|
- lib/trials/utils/h_array.rb
|
312
|
-
- lib/trials/utils/hashes.rb
|
313
310
|
- lib/trials/utils/jsons.rb
|
314
311
|
- lib/trials/utils/logging.rb
|
315
312
|
- lib/trials/utils/pdfs.rb
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# normal format <number> <STREET NAME>, <CITY>, <STATE> <postal>
|
2
|
-
|
3
|
-
def normalize_address(address)
|
4
|
-
return if address.blank?
|
5
|
-
|
6
|
-
cleaner_string = if address.respond_to?(:address1)
|
7
|
-
"#{address.address1}, #{address.city}, #{address.state} #{address.postal_code}"
|
8
|
-
else
|
9
|
-
address
|
10
|
-
end
|
11
|
-
|
12
|
-
cleaner_string = cleaner_string.gsub('#', ' #').squish
|
13
|
-
parsed = StreetAddress::US.parse(cleaner_string)
|
14
|
-
|
15
|
-
return if parsed.blank?
|
16
|
-
return if parsed.number.blank?
|
17
|
-
return if parsed.street.blank?
|
18
|
-
return if parsed.city.blank?
|
19
|
-
return if parsed.state.blank?
|
20
|
-
return if parsed.postal_code.blank?
|
21
|
-
|
22
|
-
parsed.prefix = nil
|
23
|
-
parsed.suffix = nil
|
24
|
-
parsed.unit_prefix = nil
|
25
|
-
parsed.unit = nil
|
26
|
-
parsed.postal_code_ext = nil
|
27
|
-
|
28
|
-
parsed.to_s.upcase
|
29
|
-
end
|
30
|
-
|
31
|
-
def parse_address(address_string)
|
32
|
-
StreetAddress::US.parse(address_string)
|
33
|
-
end
|
34
|
-
|
35
|
-
def normalize_and_parse_address(address_string)
|
36
|
-
StreetAddress::US.parse(normalize_address(address_string))
|
37
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# normal <FIRST> <LAST>
|
2
|
-
|
3
|
-
Name = Struct.new(:first_name, :middle_name, :last_name)
|
4
|
-
|
5
|
-
class NamePartsParser
|
6
|
-
def initialize(name_string)
|
7
|
-
@namae = Namae.parse((name_string || '').upcase).first
|
8
|
-
end
|
9
|
-
|
10
|
-
def first
|
11
|
-
normalize_name(split_first_and_middle(given).first)
|
12
|
-
end
|
13
|
-
|
14
|
-
def middle
|
15
|
-
normalize_name(split_first_and_middle(given).last)
|
16
|
-
end
|
17
|
-
|
18
|
-
def last
|
19
|
-
normalize_name(family)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def given
|
25
|
-
@namae&.given || ''
|
26
|
-
end
|
27
|
-
|
28
|
-
def family
|
29
|
-
@namae&.family || ''
|
30
|
-
end
|
31
|
-
|
32
|
-
def split_first_and_middle(first_and_middle)
|
33
|
-
names = first_and_middle.split(' ', 2)
|
34
|
-
names.length == 1 ? names + [''] : names
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def normalize_name(name)
|
39
|
-
return if name.blank?
|
40
|
-
|
41
|
-
name = name_from_parts(name) if name.respond_to?(:first_name)
|
42
|
-
|
43
|
-
name.strip.upcase.delete('^A-Z\ \-').squeeze(" ")
|
44
|
-
end
|
45
|
-
|
46
|
-
def normalize_full_names(names)
|
47
|
-
Array.wrap(names)
|
48
|
-
.map { |n| normalize_full_name(n) }
|
49
|
-
.map(&:to_s)
|
50
|
-
.map(&:presence)
|
51
|
-
.compact
|
52
|
-
.uniq
|
53
|
-
end
|
54
|
-
|
55
|
-
def normalize_full_name(name)
|
56
|
-
return if name.blank?
|
57
|
-
|
58
|
-
name.strip.upcase.delete('^A-Z\ \-').squeeze(" ")
|
59
|
-
end
|
60
|
-
|
61
|
-
def parse_name(name)
|
62
|
-
NamePartsParser.new(name)
|
63
|
-
end
|
64
|
-
|
65
|
-
def normalize_and_parse_name(name)
|
66
|
-
NamePartsParser.new(normalize_name(name))
|
67
|
-
end
|
68
|
-
|
69
|
-
# private
|
70
|
-
|
71
|
-
def name_from_parts(name)
|
72
|
-
first = normalize_name_part(name.first_name)
|
73
|
-
last = normalize_name_part(name.last_name)
|
74
|
-
|
75
|
-
[first, last].join(' ')
|
76
|
-
end
|
77
|
-
|
78
|
-
def full_name_from_parts(name)
|
79
|
-
first = normalize_name_part(name.first_name)
|
80
|
-
middle = normalize_name_part(name.middle_name)
|
81
|
-
last = normalize_name_part(name.last_name)
|
82
|
-
|
83
|
-
[first, middle, last].join(' ')
|
84
|
-
end
|
data/lib/trials/utils/hashes.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
def uniq_hash_keys(hashes)
|
2
|
-
hashes.flat_map(&:keys).uniq.compact
|
3
|
-
end
|
4
|
-
|
5
|
-
def sanitize_hash_value(hash, key:, type:, date_format: '%Y-%m-%d')
|
6
|
-
hash.merge(
|
7
|
-
key => or_nil do
|
8
|
-
case type
|
9
|
-
when :date
|
10
|
-
Date.strptime(hash.dig(key), date_format)
|
11
|
-
when :datetime
|
12
|
-
DateTime.parse(hash.dig(key))
|
13
|
-
when :integer, :int
|
14
|
-
hash.dig(key).to_i
|
15
|
-
when :float
|
16
|
-
hash.dig(key).to_f
|
17
|
-
when :string
|
18
|
-
hash.dig(key).to_s
|
19
|
-
when :alphanum
|
20
|
-
string_to_alphanum(hash.dig(key))
|
21
|
-
when :present?
|
22
|
-
hash.dig(key).present?
|
23
|
-
end
|
24
|
-
end
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
def sanitize_hash_values(hash, scheme = {})
|
29
|
-
scheme.each do |k, v|
|
30
|
-
hash = sanitize_hash_value(hash, key: k, type: v)
|
31
|
-
end
|
32
|
-
|
33
|
-
hash
|
34
|
-
end
|
35
|
-
|
36
|
-
def rename_hash_key(hash, from:, to:)
|
37
|
-
hash[to] = hash.delete(from)
|
38
|
-
hash
|
39
|
-
end
|
40
|
-
|
41
|
-
def rename_hash_keys(hash, scheme = {})
|
42
|
-
scheme.each do |k, v|
|
43
|
-
hash = rename_hash_key(hash, from: k, to: v)
|
44
|
-
end
|
45
|
-
|
46
|
-
hash
|
47
|
-
end
|
48
|
-
|
49
|
-
def merge_hash_groups(*groups, key:, join_type: :inner)
|
50
|
-
groups = groups.map { |group| group.map { |g| [g.dig(key), g] }.to_h }
|
51
|
-
|
52
|
-
keys = begin
|
53
|
-
case join_type
|
54
|
-
when :inner
|
55
|
-
groups.map(&:keys).reduce(&:&)
|
56
|
-
when :all
|
57
|
-
groups.flat_map(&:keys).uniq
|
58
|
-
when :first
|
59
|
-
groups.first.keys
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
keys.map { |key| groups.map { |g| g.dig(key) }.compact.reduce(&:merge) }
|
64
|
-
end
|
65
|
-
|
66
|
-
def count_for_group_by(batch, &block)
|
67
|
-
batch
|
68
|
-
.group_by(&block)
|
69
|
-
.map { |k, v| [k, v.length] }
|
70
|
-
.to_h
|
71
|
-
end
|
72
|
-
|
73
|
-
def array_to_count_hash(list)
|
74
|
-
list.uniq.reduce({}) do |h, i|
|
75
|
-
h[i] = list.count(i)
|
76
|
-
h
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def update_counts_hash(counts, update)
|
81
|
-
update.each do |k, v|
|
82
|
-
if counts.key?(k)
|
83
|
-
counts[k] += v
|
84
|
-
else
|
85
|
-
counts[k] = v
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
counts
|
90
|
-
end
|