ss2json 0.3.2 → 1.0.0.pre
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/README.md +29 -2
- data/Rakefile +12 -4
- data/balance.xlsx +0 -0
- data/bin/ss2json +38 -3
- data/lib/ss2json-commands/cat.rb +71 -0
- data/lib/ss2json-commands/compress.rb +67 -0
- data/lib/ss2json-commands/constants.rb +132 -0
- data/lib/ss2json-commands/humanize.rb +72 -0
- data/lib/ss2json-commands/ls.rb +71 -0
- data/lib/ss2json-commands/merge.rb +87 -0
- data/lib/ss2json-commands/to_array.rb +128 -0
- data/lib/ss2json-commands/to_hash.rb +137 -0
- data/lib/ss2json/command.rb +22 -0
- data/lib/ss2json/converter.rb +95 -0
- data/lib/ss2json/row_converter.rb +1 -2
- data/lib/ss2json/version.rb +2 -2
- data/ss2json.gemspec +13 -2
- data/test/catss.fixture +9 -0
- data/test/catss2.fixture +7 -0
- data/test/cli_test.rb +61 -0
- data/test/integration_test.rb +90 -0
- data/test/row_converter_test.rb +0 -12
- data/test/ss2json.xls +0 -0
- metadata +65 -27
- data/bin/merge_jsons +0 -32
- data/lib/ss2json.rb +0 -8
- data/lib/ss2json/cli.rb +0 -120
- data/lib/ss2json/options.rb +0 -146
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
require 'ss2json/command'
|
6
|
+
require 'ss2json/converter'
|
7
|
+
require 'optparse'
|
8
|
+
require 'terminal-table'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
class Ls < SS2JSON::Command
|
12
|
+
|
13
|
+
def self.name
|
14
|
+
"ls"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.description
|
18
|
+
"List SpreadSheet. List the sheets included in the spreadsheet."
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(options)
|
22
|
+
options = Options.new(options).options
|
23
|
+
converter = SS2JSON::Converter.new(options)
|
24
|
+
converter = SS2JSON::Converter.new(options)
|
25
|
+
puts converter.sheets.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
class Options < ::OptionParser
|
29
|
+
attr_reader :options
|
30
|
+
DEFAULT_OPTIONS = {
|
31
|
+
:sheet => nil,
|
32
|
+
:file => nil,
|
33
|
+
}
|
34
|
+
|
35
|
+
def initialize(args)
|
36
|
+
@options = DEFAULT_OPTIONS
|
37
|
+
@help = nil
|
38
|
+
super() do |opts|
|
39
|
+
@help = opts
|
40
|
+
|
41
|
+
opts.banner = "Usage: #{$0} FILENAME"
|
42
|
+
|
43
|
+
opts.separator "\n"
|
44
|
+
|
45
|
+
opts.on_tail("-h","--help", "Show this help") do
|
46
|
+
puts opts
|
47
|
+
exit 0
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on_tail("--version", "Show the version") do
|
51
|
+
require 'ss2json/version'
|
52
|
+
puts "#{$0} Version: #{SS2JSON::VERSION}"
|
53
|
+
exit 0
|
54
|
+
end
|
55
|
+
end.parse!(args)
|
56
|
+
|
57
|
+
if file = args.shift
|
58
|
+
@options[:file] = file
|
59
|
+
else
|
60
|
+
die("Incorrect number of parameters")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def die(msg)
|
65
|
+
$stderr.puts msg
|
66
|
+
$stderr.puts @help
|
67
|
+
exit -1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'ss2json/command'
|
2
|
+
require 'optparse'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Merge < SS2JSON::Command
|
6
|
+
|
7
|
+
def self.name
|
8
|
+
"merge"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.description
|
12
|
+
"Merge a list of json in a single file"
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
options = Options.new(options).options
|
17
|
+
global_hash = {}
|
18
|
+
options[:files].each do |file|
|
19
|
+
begin
|
20
|
+
json = JSON.parse(File.read(file))
|
21
|
+
rescue => e
|
22
|
+
die "Could not read the file #{file}"
|
23
|
+
exit -1
|
24
|
+
end
|
25
|
+
key = File.basename(file).split(".").first
|
26
|
+
global_hash[key] = json
|
27
|
+
end
|
28
|
+
output = options[:compress] ? JSON.dump(global_hash) : JSON.pretty_generate(global_hash)
|
29
|
+
puts output
|
30
|
+
end
|
31
|
+
|
32
|
+
class Options < ::OptionParser
|
33
|
+
attr_reader :options
|
34
|
+
DEFAULT_OPTIONS = { }
|
35
|
+
|
36
|
+
def initialize(args)
|
37
|
+
@options = DEFAULT_OPTIONS
|
38
|
+
opts = super() do |opts|
|
39
|
+
@help = opts
|
40
|
+
|
41
|
+
opts.banner = "Usage: #{$0} filename1 [filename2] [filename3]... "
|
42
|
+
|
43
|
+
opts.separator "\n"
|
44
|
+
# \nmerge_jsons will receive several files as an arguments and will generate
|
45
|
+
# and write to the stdout the a json hash with the name of the filename
|
46
|
+
# (without the extension) as a key, and the content of the file as a value
|
47
|
+
# for each file passed.
|
48
|
+
|
49
|
+
opts.on_tail("-h","--help", "Show this help") do
|
50
|
+
puts opts
|
51
|
+
exit 0
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on("-c","--compress", "Output a compressed json") do
|
55
|
+
@options[:compress] = true
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on_tail("--version", "Show the version") do
|
59
|
+
require 'ss2json/version'
|
60
|
+
puts "#{$0} Version: #{SS2JSON::VERSION}"
|
61
|
+
exit 0
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
opts.parse!(args)
|
66
|
+
|
67
|
+
if args.size < 1
|
68
|
+
die "You should provide a list of files"
|
69
|
+
end
|
70
|
+
|
71
|
+
@options[:files] = args
|
72
|
+
|
73
|
+
@options[:files].each do |f|
|
74
|
+
File.file?(f) or die("File #{f} not found")
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def die(msg)
|
81
|
+
$stderr.puts msg
|
82
|
+
$stderr.puts @help
|
83
|
+
exit -1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
|
2
|
+
require 'ss2json/command'
|
3
|
+
require 'ss2json/converter'
|
4
|
+
require 'optparse'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
class ToArray < SS2JSON::Command
|
8
|
+
|
9
|
+
def self.name
|
10
|
+
"to_array"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.description
|
14
|
+
"Convert a spreadsheet to a json array, respecting the order in wich the rows are."
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
options = Options.new(options).options
|
19
|
+
output = Converter.new(options).process
|
20
|
+
puts JSON.pretty_generate(output)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Options < OptionParser
|
24
|
+
attr_reader :options
|
25
|
+
DEFAULT_OPTIONS = {
|
26
|
+
:title_row => 1,
|
27
|
+
:first_row => 2,
|
28
|
+
:sheet => nil,
|
29
|
+
:file => nil,
|
30
|
+
:check_column => nil,
|
31
|
+
:key_column => 1,
|
32
|
+
:value_column => 2,
|
33
|
+
:converter => {
|
34
|
+
:show_null => false,
|
35
|
+
:dont_convert => false,
|
36
|
+
:ignored_values => [],
|
37
|
+
:downcase_first_letter => true
|
38
|
+
}
|
39
|
+
|
40
|
+
}
|
41
|
+
|
42
|
+
def initialize(args)
|
43
|
+
@options = DEFAULT_OPTIONS
|
44
|
+
@help = nil
|
45
|
+
super() do |opts|
|
46
|
+
@help = opts
|
47
|
+
|
48
|
+
opts.banner = "Usage: #{$0} FILENAME [options]"
|
49
|
+
|
50
|
+
opts.on("-s", "--sheet SHEET_NAME", "Use other that the first table") do |sheet|
|
51
|
+
@options[:sheet] = sheet
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on("-t", "--title-row ROW_NUMBER", "Row in wich the titles are. Default: #{DEFAULT_OPTIONS[:title_row]}") do |row|
|
55
|
+
die("Can't understand the row #{row}. Use a number") unless row =~ /\A\d*\z/
|
56
|
+
@options[:title_row] = row.to_i
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on("-r", "--first-row ROW_NUMBER", "Set the first row") do |row|
|
60
|
+
die("Can't understand the row #{row}. Use a number") unless row =~ /\A\d*\z/
|
61
|
+
@options[:first_row] = row.to_i
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on("-c", "--check-column NAME", "Only output objects wich his property NAME is not in IGNORED VALUES") do |t|
|
65
|
+
@options[:check_column] = t
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.separator "\nData options:"
|
69
|
+
|
70
|
+
opts.on("-i", "--ignore-value VALUE", "Ignore the fields with that value. Could be use several times") do |t|
|
71
|
+
@options[:converter][:ignored_values] << t
|
72
|
+
end
|
73
|
+
|
74
|
+
opts.on("-b", "--include-blank", "Generate a json with the values included in the ignore list") do |t|
|
75
|
+
@options[:converter][:show_null] = true
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.on("-d", "--disable-conversion", "Disable the conversion from floats to integers") do
|
79
|
+
@options[:converter][:dont_convert] = true
|
80
|
+
end
|
81
|
+
|
82
|
+
opts.on("-l", "--disable-first-letter", "Will disable the downcase of the first letter of the key") do
|
83
|
+
@options[:converter][:downcase_first_letter] = false
|
84
|
+
end
|
85
|
+
|
86
|
+
opts.separator "\n"
|
87
|
+
|
88
|
+
opts.on_tail("-h","--help", "Show this help") do
|
89
|
+
puts opts
|
90
|
+
exit 0
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on_tail("--version", "Show the version") do
|
94
|
+
puts "#{File.basename($0)} Version: #{SS2JSON::VERSION}"
|
95
|
+
exit 0
|
96
|
+
end
|
97
|
+
|
98
|
+
end.parse!(args)
|
99
|
+
|
100
|
+
if (args.size == 1)
|
101
|
+
@options[:file] = args.first
|
102
|
+
unless File.file?(@options[:file])
|
103
|
+
$stderr.puts "File #{@options.file} not found"
|
104
|
+
exit -5
|
105
|
+
end
|
106
|
+
else
|
107
|
+
die("Incorrect number of parameters")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def die(msg)
|
112
|
+
$stderr.puts msg
|
113
|
+
$stderr.puts @help
|
114
|
+
exit -1
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Converter < SS2JSON::Converter
|
119
|
+
def process
|
120
|
+
@options[:first_row] += 1
|
121
|
+
@content = []
|
122
|
+
each_hash_row do |hash|
|
123
|
+
@content << hash
|
124
|
+
end
|
125
|
+
@content
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
|
2
|
+
require 'ss2json/command'
|
3
|
+
require 'ss2json/converter'
|
4
|
+
require 'optparse'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
class ToHash < SS2JSON::Command
|
8
|
+
|
9
|
+
def self.name
|
10
|
+
"to_hash"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.description
|
14
|
+
"Convert a spreadsheet to a json hash usign one column as a key"
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
options = Options.new(options).options
|
19
|
+
output = Converter.new(options).process
|
20
|
+
puts JSON.pretty_generate(output)
|
21
|
+
end
|
22
|
+
|
23
|
+
class Options < ::OptionParser
|
24
|
+
attr_reader :options
|
25
|
+
DEFAULT_OPTIONS = {
|
26
|
+
:title_row => 1,
|
27
|
+
:first_row => 2,
|
28
|
+
:sheet => nil,
|
29
|
+
:file => nil,
|
30
|
+
:key_column => 1,
|
31
|
+
:value_column => 2,
|
32
|
+
:header_line => 1,
|
33
|
+
:converter => {
|
34
|
+
:show_null => false,
|
35
|
+
:dont_convert => false,
|
36
|
+
:ignored_values => [],
|
37
|
+
:ignored_keys => [],
|
38
|
+
:downcase_first_letter => true
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
def initialize(args)
|
43
|
+
@options = DEFAULT_OPTIONS
|
44
|
+
@help = nil
|
45
|
+
super() do |opts|
|
46
|
+
@help = opts
|
47
|
+
|
48
|
+
opts.banner = "Usage: #{$0} FILENAME KEY [options]"
|
49
|
+
|
50
|
+
opts.on("-s", "--sheet SHEET_NAME", "Use other that the first table") do |sheet|
|
51
|
+
@options[:sheet] = sheet
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on("-t", "--title-row ROW_NUMBER", "Row in wich the titles are. Default: #{DEFAULT_OPTIONS[:title_row]}") do |row|
|
55
|
+
die("Can't understand the row #{row}. Use a number") unless row =~ /\A\d*\z/
|
56
|
+
@options[:title_row] = row.to_i
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on("-r", "--first-row ROW_NUMBER", "Set the first row of real data. Default: #{DEFAULT_OPTIONS[:first_row]}") do |row|
|
60
|
+
die("Can't understand the row #{row}. Use a number") unless row =~ /\A\d*\z/
|
61
|
+
@options[:first_row] = row.to_i
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on("-n", "--dont-remove-key", "When using a column in the excel as a key for the hash, that column is removed. This option avoid that behaviour") do
|
65
|
+
@options[:dont_remove_key] = true
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.separator "\nData options:"
|
69
|
+
|
70
|
+
opts.on("-i", "--ignore-value VALUE", "Ignore the fields with that value. Could be use several times") do |t|
|
71
|
+
@options[:converter][:ignored_values] << t
|
72
|
+
end
|
73
|
+
|
74
|
+
# TODO
|
75
|
+
# opts.on("-i", "--ignore-key VALUE", "Ignore the fields with that key. Could be use several times") do |t|
|
76
|
+
# @options[:converter][:ignored_keys] << t
|
77
|
+
# end
|
78
|
+
|
79
|
+
opts.on("-b", "--include-blank", "Generate a json with the values included in the ignore list") do |t|
|
80
|
+
@options[:converter][:show_null] = true
|
81
|
+
end
|
82
|
+
|
83
|
+
opts.on("-d", "--disable-conversion", "Disable the conversion from floats to integers") do
|
84
|
+
@options[:converter][:dont_convert] = true
|
85
|
+
end
|
86
|
+
|
87
|
+
opts.on("-l", "--disable-first-letter", "Will disable the downcase of the first letter of the key") do
|
88
|
+
@options[:converter][:downcase_first_letter] = false
|
89
|
+
end
|
90
|
+
|
91
|
+
opts.separator "\n"
|
92
|
+
|
93
|
+
opts.on_tail("-h","--help", "Show this help") do
|
94
|
+
puts opts
|
95
|
+
exit 0
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.on_tail("--version", "Show the version") do
|
99
|
+
require 'ss2json/version'
|
100
|
+
puts "#{$0} Version: #{SS2JSON::VERSION}"
|
101
|
+
exit 0
|
102
|
+
end
|
103
|
+
|
104
|
+
end.parse!(args)
|
105
|
+
|
106
|
+
if args.size == 2
|
107
|
+
@options[:file] = args.first
|
108
|
+
unless File.file?(@options[:file])
|
109
|
+
$stderr.puts "File #{@options.file} not found"
|
110
|
+
exit -5
|
111
|
+
end
|
112
|
+
@options[:hash_key] = args.last
|
113
|
+
else
|
114
|
+
die("Incorrect number of parameters")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def die(msg)
|
119
|
+
$stderr.puts msg
|
120
|
+
$stderr.puts @help
|
121
|
+
exit -1
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class Converter < SS2JSON::Converter
|
126
|
+
def process
|
127
|
+
@content = {}
|
128
|
+
each_hash_row do |hash|
|
129
|
+
if value = hash.get(@options[:hash_key])
|
130
|
+
hash.delete(@options[:hash_key]) unless @options[:dont_remove_key]
|
131
|
+
@content[value] = hash
|
132
|
+
end
|
133
|
+
end
|
134
|
+
@content
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SS2JSON
|
2
|
+
class Command
|
3
|
+
|
4
|
+
@commands = []
|
5
|
+
def self.load_all
|
6
|
+
require 'rubygems' unless defined?(Gem)
|
7
|
+
Gem.find_files('ss2json-commands/*.rb').each do |file|
|
8
|
+
require(file)
|
9
|
+
end
|
10
|
+
@commands
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.commands
|
14
|
+
@commands
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.inherited(kclass)
|
18
|
+
@commands << kclass
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|