dataset_explorer 0.1.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/README.md +71 -71
- data/dataset_explorer.gemspec +2 -0
- data/lib/dataset_explorer.rb +1 -0
- data/lib/dataset_explorer/collector.rb +18 -4
- data/lib/dataset_explorer/item_collector.rb +22 -6
- data/lib/dataset_explorer/value_evaluator.rb +134 -0
- data/lib/dataset_explorer/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0325eced24214509e9177b70341bc1120ea26c5b523918501f2884fdd57c92a
|
4
|
+
data.tar.gz: face9b64530c6b771258d23f512c24955e6bd073d881802d6b538dd0f5b046b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1c7aa73cd0f51295b1cf01b1ece8e7756c9a5e498a22f475efccecb2036f065844f0564e9fd6c05379cefe35729ec7cdc84aea57577f81c46a17e3ab628586b
|
7
|
+
data.tar.gz: 0d75d122ea2a1696a06215c631e14760b1d6cba3271c73462af85ade96f85b886f72f6fb5a0500fd2794720a5c46509c2d2e4c14ca3e7ab632a00ec4863e6532
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -56,82 +56,82 @@ urls = {
|
|
56
56
|
COLLECTOR = DatasetExplorer::Collector.instance
|
57
57
|
|
58
58
|
urls.each do |provider, url|
|
59
|
-
data =
|
60
|
-
|
61
|
-
data.each do |item|
|
62
|
-
COLLECTOR.collect(provider, item)
|
63
|
-
end
|
59
|
+
data = JSON.parse(open(url).read)
|
60
|
+
COLLECTOR.collect(provider, data)
|
64
61
|
end
|
65
62
|
|
66
|
-
|
63
|
+
COLLECTOR.explain_all(format: :table).each do |type, explanation|
|
64
|
+
puts type
|
65
|
+
puts explanation
|
66
|
+
end
|
67
67
|
```
|
68
68
|
|
69
69
|
Explanation will be:
|
70
70
|
|
71
|
-
```
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
]
|
134
|
-
|
71
|
+
```
|
72
|
+
github
|
73
|
+
+------------------------------+--------------------------------------------------------------------------+
|
74
|
+
| jekyll | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
75
|
+
| jekyll-sass-converter | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
76
|
+
| kramdown | Possible types: [string], NULL, Min/max Length: 6/6 |
|
77
|
+
| jekyll-commonmark-ghpages | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
78
|
+
| liquid | Possible types: [string], NULL, Min/max Length: 5/5 |
|
79
|
+
| rouge | Possible types: [string], NULL, Min/max Length: 6/6 |
|
80
|
+
| github-pages-health-check | Possible types: [string], NULL, Min/max Length: 6/6 |
|
81
|
+
| jekyll-redirect-from | Possible types: [string], NULL, Min/max Length: 6/6 |
|
82
|
+
| jekyll-sitemap | Possible types: [string], NULL, Min/max Length: 5/5 |
|
83
|
+
| jekyll-feed | Possible types: [string], NULL, Min/max Length: 6/6 |
|
84
|
+
| jekyll-gist | Possible types: [string], NULL, Min/max Length: 5/5 |
|
85
|
+
| jekyll-paginate | Possible types: [string], NULL, Min/max Length: 5/5 |
|
86
|
+
| jekyll-coffeescript | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
87
|
+
| jekyll-seo-tag | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
88
|
+
| jekyll-github-metadata | Possible types: [string], NULL, Min/max Length: 6/6 |
|
89
|
+
| jekyll-avatar | Possible types: [string], NULL, Min/max Length: 5/5 |
|
90
|
+
| jekyll-remote-theme | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
91
|
+
| jemoji | Possible types: [date, time, string], NULL, Min/max Length: 6/6 |
|
92
|
+
| jekyll-mentions | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
93
|
+
| jekyll-relative-links | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
94
|
+
| jekyll-optional-front-matter | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
95
|
+
| jekyll-readme-index | Possible types: [string], NULL, Min/max Length: 5/5 |
|
96
|
+
| jekyll-default-layout | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
97
|
+
| jekyll-titles-from-headings | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
98
|
+
| jekyll-swiss | Possible types: [string], NULL, Min/max Length: 5/5 |
|
99
|
+
| minima | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
100
|
+
| jekyll-theme-primer | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
101
|
+
| jekyll-theme-architect | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
102
|
+
| jekyll-theme-cayman | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
103
|
+
| jekyll-theme-dinky | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
104
|
+
| jekyll-theme-hacker | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
105
|
+
| jekyll-theme-leap-day | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
106
|
+
| jekyll-theme-merlot | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
107
|
+
| jekyll-theme-midnight | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
108
|
+
| jekyll-theme-minimal | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
109
|
+
| jekyll-theme-modernist | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
110
|
+
| jekyll-theme-slate | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
111
|
+
| jekyll-theme-tactile | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
112
|
+
| jekyll-theme-time-machine | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
113
|
+
| ruby | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
114
|
+
| github-pages | Possible types: [date, time, string, integer], NULL, Min/max Length: 3/3 |
|
115
|
+
| html-pipeline | Possible types: [date, time, string], NULL, Min/max Length: 6/6 |
|
116
|
+
| sass | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
|
117
|
+
| safe_yaml | Possible types: [string], NULL, Min/max Length: 5/5 |
|
118
|
+
| nokogiri | Possible types: [date, time, string], NULL, Min/max Length: 6/6 |
|
119
|
+
+------------------------------+--------------------------------------------------------------------------+
|
120
|
+
github_repo_contents
|
121
|
+
+-----------------+---------------------------------------------------------+
|
122
|
+
| [].name | Possible types: [string], NULL, Min/max Length: 2/14 |
|
123
|
+
| [].path | Possible types: [string], NULL, Min/max Length: 2/14 |
|
124
|
+
| [].sha | Possible types: [string], NULL, Min/max Length: 40/40 |
|
125
|
+
| [].size | Possible types: [integer], NULL |
|
126
|
+
| [].url | Possible types: [string], NULL, Min/max Length: 75/87 |
|
127
|
+
| [].html_url | Possible types: [string], NULL, Min/max Length: 57/69 |
|
128
|
+
| [].git_url | Possible types: [string], NULL, Min/max Length: 103/103 |
|
129
|
+
| [].download_url | Possible types: [string], NULL, Min/max Length: 72/79 |
|
130
|
+
| [].type | Possible types: [string], NULL, Min/max Length: 3/4 |
|
131
|
+
| []._links.self | Possible types: [string], NULL, Min/max Length: 75/87 |
|
132
|
+
| []._links.git | Possible types: [string], NULL, Min/max Length: 103/103 |
|
133
|
+
| []._links.html | Possible types: [string], NULL, Min/max Length: 57/69 |
|
134
|
+
+-----------------+---------------------------------------------------------+
|
135
135
|
```
|
136
136
|
|
137
137
|
Or if you try like this
|
@@ -155,7 +155,7 @@ data = {
|
|
155
155
|
}
|
156
156
|
|
157
157
|
DatasetExplorer::Collector.instance.collect(:achievements, data)
|
158
|
-
result = DatasetExplorer::Collector.
|
158
|
+
result = DatasetExplorer::Collector.instance.explain(:achievements).keys
|
159
159
|
|
160
160
|
# result is:
|
161
161
|
|
data/dataset_explorer.gemspec
CHANGED
data/lib/dataset_explorer.rb
CHANGED
@@ -14,14 +14,20 @@ module DatasetExplorer
|
|
14
14
|
collector_for(type).add(item)
|
15
15
|
end
|
16
16
|
|
17
|
-
def explain_all
|
17
|
+
def explain_all(format: :hash)
|
18
18
|
@collectors.keys.map do |key|
|
19
|
-
[key, explain(key)]
|
19
|
+
[key, explain(key, format: format)]
|
20
20
|
end.to_h
|
21
21
|
end
|
22
22
|
|
23
|
-
def explain(type)
|
24
|
-
@collectors.fetch(type).
|
23
|
+
def explain(type, format: :hash)
|
24
|
+
explanation = @collectors.fetch(type).explain
|
25
|
+
|
26
|
+
if format == :table
|
27
|
+
explanation = to_table(explanation)
|
28
|
+
end
|
29
|
+
|
30
|
+
explanation
|
25
31
|
end
|
26
32
|
|
27
33
|
private
|
@@ -30,6 +36,14 @@ module DatasetExplorer
|
|
30
36
|
@collectors[type] ||= ItemCollector.new
|
31
37
|
end
|
32
38
|
|
39
|
+
def to_table(fields)
|
40
|
+
rows = []
|
41
|
+
fields.each do |key, description|
|
42
|
+
rows << [key, description]
|
43
|
+
end
|
44
|
+
Terminal::Table.new(rows: rows)
|
45
|
+
end
|
46
|
+
|
33
47
|
private_class_method :new
|
34
48
|
end
|
35
49
|
end
|
@@ -3,10 +3,19 @@
|
|
3
3
|
module DatasetExplorer
|
4
4
|
class ItemCollector
|
5
5
|
def initialize
|
6
|
-
@
|
6
|
+
@keys = []
|
7
|
+
@evaluators = {}
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
+
def explain
|
11
|
+
{}.tap do |explanation|
|
12
|
+
@evaluators.each do |field, evaluator|
|
13
|
+
explanation[field] = evaluator.describe
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :keys
|
10
19
|
|
11
20
|
def add(item)
|
12
21
|
unless item.is_a?(Array)
|
@@ -25,15 +34,17 @@ module DatasetExplorer
|
|
25
34
|
map_keys(item[key], key, prefix)
|
26
35
|
end.flatten.map(&:to_s).uniq
|
27
36
|
|
28
|
-
@
|
29
|
-
@
|
37
|
+
@keys << new_values
|
38
|
+
@keys = @keys.flatten.uniq
|
30
39
|
end
|
31
40
|
|
32
41
|
# rubocop:disable Metrics/MethodLength
|
42
|
+
# rubocop:disable Metrics/AbcSize
|
33
43
|
def map_keys(value, key = nil, prefix = nil)
|
34
44
|
prefix = [prefix, key].compact.join('.')
|
35
45
|
|
36
46
|
unless mappable?(value)
|
47
|
+
evaluator_for(prefix).evaluate(value)
|
37
48
|
return prefix
|
38
49
|
end
|
39
50
|
|
@@ -45,9 +56,9 @@ module DatasetExplorer
|
|
45
56
|
|
46
57
|
if value.respond_to?(:each)
|
47
58
|
prefix = "#{prefix}.[]"
|
48
|
-
return [].tap do |
|
59
|
+
return [].tap do |keys|
|
49
60
|
value.each do |item_value|
|
50
|
-
|
61
|
+
keys << map_keys(item_value, nil, prefix)
|
51
62
|
end
|
52
63
|
end
|
53
64
|
end
|
@@ -55,6 +66,7 @@ module DatasetExplorer
|
|
55
66
|
raise Error, 'Unforseen scenario'
|
56
67
|
end
|
57
68
|
# rubocop:enable Metrics/MethodLength
|
69
|
+
# rubocop:enable Metrics/AbcSize
|
58
70
|
|
59
71
|
def mappable?(value)
|
60
72
|
if behaves_like_hash?(value)
|
@@ -75,5 +87,9 @@ module DatasetExplorer
|
|
75
87
|
def behaves_like_array?(value)
|
76
88
|
value.respond_to?(:each)
|
77
89
|
end
|
90
|
+
|
91
|
+
def evaluator_for(field)
|
92
|
+
@evaluators[field.to_s] ||= ValueEvaluator.new(field)
|
93
|
+
end
|
78
94
|
end
|
79
95
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require 'time'
|
5
|
+
require 'terminal-table'
|
6
|
+
|
7
|
+
module DatasetExplorer
|
8
|
+
class ValueEvaluator
|
9
|
+
attr_reader :min_length
|
10
|
+
attr_reader :max_length
|
11
|
+
|
12
|
+
def initialize(field_name)
|
13
|
+
@field_name = field_name
|
14
|
+
@null = true
|
15
|
+
@evaluators = {
|
16
|
+
'date' => DateEvaluator.new,
|
17
|
+
'time' => TimeEvaluator.new,
|
18
|
+
'string' => StringEvaluator.new,
|
19
|
+
'float' => FloatEvaluator.new,
|
20
|
+
'integer' => IntegerEvaluator.new,
|
21
|
+
'boolean' => BooleanEvaluator.new
|
22
|
+
}
|
23
|
+
@min_length = nil
|
24
|
+
@max_length = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def evaluate(value)
|
28
|
+
if value.nil?
|
29
|
+
@null = true
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
evaluate_length(value)
|
34
|
+
|
35
|
+
@evaluators.each do |key, evaluator|
|
36
|
+
unless evaluator.accept?(value)
|
37
|
+
@evaluators.delete(key)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def types
|
43
|
+
@evaluators.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
def describe
|
47
|
+
parts = ["Possible types: [#{types.join(', ')}]"]
|
48
|
+
if @null
|
49
|
+
parts << 'NULL'
|
50
|
+
end
|
51
|
+
|
52
|
+
if min_length
|
53
|
+
parts << "Min/max Length: #{min_length}/#{max_length}"
|
54
|
+
end
|
55
|
+
|
56
|
+
parts.join(', ')
|
57
|
+
end
|
58
|
+
|
59
|
+
def evaluate_length(value)
|
60
|
+
unless value.respond_to?(:length)
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
length = value.length
|
65
|
+
@min_length ||= length
|
66
|
+
@max_length ||= length
|
67
|
+
|
68
|
+
if @min_length > length
|
69
|
+
@min_length = length
|
70
|
+
end
|
71
|
+
|
72
|
+
if @max_length < length
|
73
|
+
@max_length = length
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class TimeEvaluator
|
78
|
+
def accept?(value)
|
79
|
+
if value.is_a?(String)
|
80
|
+
return Time.parse(value.to_s)
|
81
|
+
end
|
82
|
+
|
83
|
+
value.is_a?(Time)
|
84
|
+
rescue ArgumentError
|
85
|
+
false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class DateEvaluator
|
90
|
+
def accept?(value)
|
91
|
+
if value.is_a?(String)
|
92
|
+
return Date.parse(value.to_s)
|
93
|
+
end
|
94
|
+
|
95
|
+
value.is_a?(Date)
|
96
|
+
rescue ArgumentError
|
97
|
+
false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class StringEvaluator
|
102
|
+
def accept?(value)
|
103
|
+
value.is_a?(String)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class FloatEvaluator
|
108
|
+
def accept?(value)
|
109
|
+
Float(value).to_s == value.to_s
|
110
|
+
rescue ArgumentError, TypeError
|
111
|
+
false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class IntegerEvaluator
|
116
|
+
def accept?(value)
|
117
|
+
Integer(value)
|
118
|
+
rescue ArgumentError, TypeError
|
119
|
+
false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class BooleanEvaluator
|
124
|
+
ACCEPT = %w[
|
125
|
+
true
|
126
|
+
false
|
127
|
+
].freeze
|
128
|
+
|
129
|
+
def accept?(value)
|
130
|
+
ACCEPT.include?(value.to_s.downcase)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dataset_explorer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcelo Jacobus
|
@@ -9,7 +9,21 @@ autorequire:
|
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 2020-05-25 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: terminal-table
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Explore and maps fields from a dataset - I.E. Api response
|
14
28
|
email:
|
15
29
|
- marcelo.jacobus@gmail.com
|
@@ -32,6 +46,7 @@ files:
|
|
32
46
|
- lib/dataset_explorer.rb
|
33
47
|
- lib/dataset_explorer/collector.rb
|
34
48
|
- lib/dataset_explorer/item_collector.rb
|
49
|
+
- lib/dataset_explorer/value_evaluator.rb
|
35
50
|
- lib/dataset_explorer/version.rb
|
36
51
|
homepage: https://github.com/mjacobus/dataset_explorer
|
37
52
|
licenses:
|