dataset_explorer 0.1.1 → 1.0.0
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/.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:
|