ss2json 0.0.1 → 0.0.2
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.
- data/Changelog +10 -0
- data/README.md +84 -27
- data/Rakefile +7 -0
- data/lib/ss2json/cli.rb +13 -1
- data/lib/ss2json/options.rb +7 -1
- data/lib/ss2json/row_converter.rb +20 -6
- data/lib/ss2json/version.rb +1 -1
- data/test/row_converter_test.rb +60 -0
- metadata +68 -44
- data/CHANGELOG +0 -5
data/Changelog
ADDED
data/README.md
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
|
2
2
|
# ss2json
|
3
3
|
|
4
|
+
|
4
5
|
**ss2json** is a SpreadSheet To Json converter. It follow a few rules for generating nested hash.
|
5
6
|
|
7
|
+
## Tutorial
|
8
|
+
|
9
|
+
### Step 1
|
10
|
+
|
6
11
|
For example, this document:
|
7
12
|
|
8
|
-

|
9
14
|
|
10
15
|
We download as an OpenOffice document (ods), and run:
|
11
16
|
|
@@ -13,45 +18,92 @@ We download as an OpenOffice document (ods), and run:
|
|
13
18
|
|
14
19
|
Will converted in this:
|
15
20
|
|
16
|
-
```
|
21
|
+
```javascript
|
22
|
+
[
|
23
|
+
{
|
24
|
+
"id": 1,
|
25
|
+
"name": { "first": "Guillermo", "last": "Alvarez" },
|
26
|
+
"child": [ { "name": "pepe", "age": 2 }, { "name": "Juanjo" } ]
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"id": 2,
|
30
|
+
"name": { "first": "Martin", "last": "Luther" },
|
31
|
+
"child": [ { "name": "Jr" } ]
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"id": 3,
|
35
|
+
"name": { "first": "Jesper" }
|
36
|
+
},
|
37
|
+
{ "id": 4 },
|
38
|
+
{ "id": 5 },
|
39
|
+
{ "id": 6 }
|
40
|
+
]
|
41
|
+
```
|
42
|
+
|
43
|
+
### Step 2
|
44
|
+
|
45
|
+
We want to remove the last columns, so we need to tell **ss2json** to check for the name. We do that with the __-c__ parameter.
|
46
|
+
|
47
|
+
```
|
48
|
+
ss2json -f documents.ods -c name
|
49
|
+
```
|
50
|
+
|
51
|
+
```javascript
|
17
52
|
[
|
18
53
|
{
|
19
54
|
"id": 1,
|
20
|
-
"name": {
|
21
|
-
|
22
|
-
"last": "Alvarez"
|
23
|
-
},
|
24
|
-
"child": [
|
25
|
-
{
|
26
|
-
"name": "pepe",
|
27
|
-
"age": 2
|
28
|
-
},
|
29
|
-
{
|
30
|
-
"name": "Juanjo"
|
31
|
-
}
|
32
|
-
]
|
55
|
+
"name": { "first": "Guillermo", "last": "Alvarez" },
|
56
|
+
"child": [ { "name": "pepe", "age": 2 }, { "name": "Juanjo" } ]
|
33
57
|
},
|
34
58
|
{
|
35
59
|
"id": 2,
|
36
|
-
"name": {
|
37
|
-
|
38
|
-
"last": "Luther"
|
39
|
-
},
|
40
|
-
"child": [
|
41
|
-
{
|
42
|
-
"name": "Jr"
|
43
|
-
}
|
44
|
-
]
|
60
|
+
"name": { "first": "Martin","last": "Luther"},
|
61
|
+
"child": [{"name": "Jr"}]
|
45
62
|
},
|
46
63
|
{
|
47
64
|
"id": 3,
|
48
|
-
"name": {
|
49
|
-
"first": "Jesper"
|
50
|
-
}
|
65
|
+
"name": {"first": "Jesper"}
|
51
66
|
}
|
52
67
|
]
|
53
68
|
```
|
54
69
|
|
70
|
+
### Step 3
|
71
|
+
|
72
|
+
We have a crappy parser, and need to include blank_fieds, so we say that to ss2json.
|
73
|
+
|
74
|
+
```
|
75
|
+
ss2json -f documents.ods -c name -b
|
76
|
+
```
|
77
|
+
|
78
|
+
|
79
|
+
### Step 4
|
80
|
+
|
81
|
+
We have the rows with the title in colum 3, as in:
|
82
|
+
|
83
|
+

|
84
|
+
|
85
|
+
So we say to **ss2json** to start parsing in the row tree:
|
86
|
+
|
87
|
+
```
|
88
|
+
ss2json -f documents.ods -c name -r 3
|
89
|
+
```
|
90
|
+
|
91
|
+
### Step 5
|
92
|
+
|
93
|
+
We don't want to open the file to have a list of the sheets:
|
94
|
+
|
95
|
+
```
|
96
|
+
ss2json -f documents.ods -l
|
97
|
+
```
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
## Support
|
102
|
+
|
103
|
+
Right now ss2json supports ods and xlsx files.
|
104
|
+
|
105
|
+
|
106
|
+
|
55
107
|
## Install
|
56
108
|
|
57
109
|
gem install ss2json
|
@@ -78,6 +130,11 @@ Usage: ss2json -f FILENAME [options]
|
|
78
130
|
-h, --help Show this help
|
79
131
|
```
|
80
132
|
|
133
|
+
## TODO
|
134
|
+
|
135
|
+
* Support all the document formats from **roo** librarly.
|
136
|
+
* -c options should be able to check inside the hash, for example name.first should check {"name":{"first": null}}
|
137
|
+
|
81
138
|
## License
|
82
139
|
|
83
140
|
BSD
|
data/Rakefile
CHANGED
data/lib/ss2json/cli.rb
CHANGED
@@ -6,16 +6,28 @@ class Ss2Json
|
|
6
6
|
class Cli
|
7
7
|
attr_reader :content, :doc
|
8
8
|
|
9
|
+
# Parse the options from ARGV, initialize the conversion, and return the string with the output
|
9
10
|
def self.start
|
10
11
|
options = Ss2Json::Options.parse!
|
11
12
|
converter = new(options)
|
12
|
-
|
13
|
+
case options[:action]
|
14
|
+
when :list
|
13
15
|
converter.doc.sheets.join("\n")
|
14
16
|
else
|
15
17
|
JSON.pretty_generate(converter.content)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
# Create a new converter the options are:
|
22
|
+
#
|
23
|
+
# * **:file** Input file.
|
24
|
+
# * **:sheet** Name of the sheet to use.
|
25
|
+
# * **:first_row** Where the title of the columns is.
|
26
|
+
# * **:check_column** Output only the results with a value present on the specific field.
|
27
|
+
# * **:action** Could
|
28
|
+
# * *:convert* Do the normal conversion.
|
29
|
+
# * *:list* Will list the sheets.
|
30
|
+
# * **:converter**: Options passed to the converter: Ss2Json::RowConverter
|
19
31
|
def initialize(options)
|
20
32
|
@options = options
|
21
33
|
init_document
|
data/lib/ss2json/options.rb
CHANGED
@@ -9,10 +9,12 @@ class Ss2Json
|
|
9
9
|
:sheet => nil,
|
10
10
|
:file => nil,
|
11
11
|
:check_column => nil,
|
12
|
+
:action => :convert,
|
12
13
|
:converter => {
|
13
14
|
:show_null => false,
|
14
15
|
:dont_convert => false,
|
15
|
-
:ignored_values => []
|
16
|
+
:ignored_values => [],
|
17
|
+
:downcase_first_letter => true
|
16
18
|
}
|
17
19
|
|
18
20
|
}
|
@@ -59,6 +61,10 @@ class Ss2Json
|
|
59
61
|
@options[:converter][:dont_convert] = true
|
60
62
|
end
|
61
63
|
|
64
|
+
opts.on("-l", "--disable-first-letter", "Will disable the downcase of the first letter of the key") do
|
65
|
+
@options[:converter][:downcase_first_letter] = false
|
66
|
+
end
|
67
|
+
|
62
68
|
opts.separator ""
|
63
69
|
|
64
70
|
opts.on("-l", "--list-sheets", "Return the list of sheets") do |file|
|
@@ -3,6 +3,14 @@ require 'nested_hash'
|
|
3
3
|
class Ss2Json
|
4
4
|
class RowConverter < NestedHash
|
5
5
|
|
6
|
+
# Create a nested_hash from a hash with just one level (key,value).
|
7
|
+
#
|
8
|
+
# The options are:
|
9
|
+
#
|
10
|
+
# * **:ignored_values** Array of ignored values.
|
11
|
+
# * **:show_null** Export the keys with empty values.
|
12
|
+
# * **:dont_convert** Convert 10.0 float values to integers.
|
13
|
+
# * **:downcase_first_letter** Convert to downcase the first letter of each key.
|
6
14
|
def initialize(hash, options={})
|
7
15
|
@options = options
|
8
16
|
super(hash)
|
@@ -18,24 +26,30 @@ class Ss2Json
|
|
18
26
|
false
|
19
27
|
end
|
20
28
|
|
21
|
-
def sanitize_value(v)
|
22
|
-
return v if @options[:dont_convert]
|
23
|
-
end
|
24
|
-
|
25
29
|
def process(key,value)
|
26
30
|
super if valid_value?(value)
|
27
31
|
end
|
28
32
|
|
29
33
|
def valid_value?(value)
|
30
|
-
|
31
|
-
(@options[:show_null] || value )
|
34
|
+
@options[:show_null] || !ignored_values.include?(value)
|
32
35
|
end
|
33
36
|
|
37
|
+
def ignored_values
|
38
|
+
(@options[:ignored_values] || []) << nil
|
39
|
+
end
|
40
|
+
|
41
|
+
|
34
42
|
def sanitize_value(v)
|
35
43
|
return v if @options[:dont_convert]
|
36
44
|
return v.to_i if v.is_a?(Float) && v % 1 == 0
|
37
45
|
v
|
38
46
|
end
|
39
47
|
|
48
|
+
def sanitize_key(key)
|
49
|
+
return key unless is_valid_key?(key)
|
50
|
+
key = key[0..1].downcase + key[2..-1] if @options[:downcase_first_letter]
|
51
|
+
key
|
52
|
+
end
|
53
|
+
|
40
54
|
end
|
41
55
|
end
|
data/lib/ss2json/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
require 'ss2json'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class Ss2Json::RowConverterTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_class
|
8
|
+
nested_hash = Ss2Json::RowConverter.new({})
|
9
|
+
nested_hash.is_a?(Hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_ignored_values_option
|
13
|
+
options = {:ignored_values => ["???"]}
|
14
|
+
new_hash = Ss2Json::RowConverter.new({"adsf" => '???'},options)
|
15
|
+
assert_equal({}, new_hash)
|
16
|
+
new_hash = Ss2Json::RowConverter.new({"asdf" => 'asdf'}, options)
|
17
|
+
assert_equal({"asdf" => 'asdf' }, new_hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_show_null_option
|
21
|
+
initial_hash = {"asdf" => nil}
|
22
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash,{:show_null => false})
|
23
|
+
assert_equal({}, new_hash)
|
24
|
+
|
25
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash,{:show_null => true})
|
26
|
+
assert_equal({"asdf" => nil}, new_hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_dont_convert_option
|
30
|
+
initial_hash = { "asdf" => 3.0 }
|
31
|
+
|
32
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash, {:dont_convert => true})
|
33
|
+
assert_equal(initial_hash, new_hash)
|
34
|
+
|
35
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash, {:dont_convert => false})
|
36
|
+
assert_equal(initial_hash, { "asdf" => 3 })
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_downcase_first_letter
|
40
|
+
initial_hash = { "Asdf.pepe" => 3, "asdf.Jose" => 5 }
|
41
|
+
|
42
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash, {:downcase_first_letter => false})
|
43
|
+
assert_equal({"Asdf"=>{"pepe"=>3}, "asdf"=>{"Jose"=>5}}, new_hash)
|
44
|
+
|
45
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash, {:downcase_first_letter => true})
|
46
|
+
assert_equal({"asdf" => {"pepe" => 3, "jose" => 5}}, new_hash)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_it_ignore_ignored_fields
|
50
|
+
initial_hash = { "i.asdf" => 5}
|
51
|
+
|
52
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash)
|
53
|
+
assert_equal({}, new_hash)
|
54
|
+
|
55
|
+
initial_hash = { "name.i" => 5}
|
56
|
+
|
57
|
+
new_hash = Ss2Json::RowConverter.new(initial_hash)
|
58
|
+
assert_equal({"name" => {"i" => 5}}, new_hash)
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,48 +1,63 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ss2json
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
- Guillermo A
|
12
|
+
authors:
|
13
|
+
- "Guillermo A\xCC\x81lvarez"
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2012-05-23 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
15
22
|
name: nested_hash
|
16
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
25
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
22
33
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
26
36
|
name: roo
|
27
|
-
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
|
-
requirements:
|
30
|
-
- -
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
33
47
|
type: :runtime
|
34
|
-
|
35
|
-
version_requirements: *70291603210920
|
48
|
+
version_requirements: *id002
|
36
49
|
description: Convert SpreadSheet documents to json following some conventions.
|
37
|
-
email:
|
50
|
+
email:
|
38
51
|
- guillermo@cientifico.net
|
39
|
-
executables:
|
52
|
+
executables:
|
40
53
|
- ss2json
|
41
54
|
extensions: []
|
55
|
+
|
42
56
|
extra_rdoc_files: []
|
43
|
-
|
57
|
+
|
58
|
+
files:
|
44
59
|
- .gitignore
|
45
|
-
-
|
60
|
+
- Changelog
|
46
61
|
- Gemfile
|
47
62
|
- README.md
|
48
63
|
- Rakefile
|
@@ -55,34 +70,43 @@ files:
|
|
55
70
|
- lib/ss2json/row_converter.rb
|
56
71
|
- lib/ss2json/version.rb
|
57
72
|
- ss2json.gemspec
|
73
|
+
- test/row_converter_test.rb
|
58
74
|
- test/ss2json (1).ods
|
59
75
|
- test/ss2json.ods
|
60
76
|
- test/ss2json.xls
|
61
|
-
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: ""
|
62
79
|
licenses: []
|
80
|
+
|
63
81
|
post_install_message:
|
64
82
|
rdoc_options: []
|
65
|
-
|
83
|
+
|
84
|
+
require_paths:
|
66
85
|
- lib
|
67
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
87
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
96
|
none: false
|
75
|
-
requirements:
|
76
|
-
- -
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
79
104
|
requirements: []
|
105
|
+
|
80
106
|
rubyforge_project: ss2json
|
81
|
-
rubygems_version: 1.
|
107
|
+
rubygems_version: 1.6.2
|
82
108
|
signing_key:
|
83
109
|
specification_version: 3
|
84
110
|
summary: SpreadSheet to Json convert
|
85
|
-
test_files:
|
86
|
-
|
87
|
-
- test/ss2json.ods
|
88
|
-
- test/ss2json.xls
|
111
|
+
test_files: []
|
112
|
+
|