csv2json 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Antonin Hildebrand
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ = csv2json
2
+
3
+ Clients were sending me XLS files, but my webs consume JSON. So I needed to convert them to JSON easily from command-line.
4
+ Tried to google for solution and surprisingly enough nothing solid existed.
5
+
6
+ == Solution
7
+
8
+ - export XLS as a CSV file (I use OpenOffice.org for this)
9
+ - run `csv2json file.csv > file.json`
10
+ - there is no step 3
11
+
12
+ === Sample
13
+
14
+ note: make sure your XLS table has the first row with column names
15
+
16
+ This CSV file:
17
+
18
+ thumbpath,imgpath,imgsrc,width,height,thumbsrc,thumbwidth,thumbheight
19
+ thumbnails/,images/,paris_01.jpg,350,262,paris_01.jpg,75,56
20
+ thumbnails/,images/,paris_02.jpg,262,350,paris_02.jpg,75,56
21
+
22
+ gets turned into this JSON:
23
+
24
+ [
25
+ {
26
+ "thumbwidth": 75,
27
+ "imgsrc": "paris_01.jpg",
28
+ "thumbsrc": "paris_01.jpg",
29
+ "height": 262,
30
+ "imgpath": "images/",
31
+ "thumbheight": 56,
32
+ "thumbpath": "thumbnails/",
33
+ "width": 350
34
+ },
35
+ {
36
+ "thumbwidth": 75,
37
+ "imgsrc": "paris_02.jpg",
38
+ "thumbsrc": "paris_02.jpg",
39
+ "height": 350,
40
+ "imgpath": "images/",
41
+ "thumbheight": 56,
42
+ "thumbpath": "thumbnails/",
43
+ "width": 262
44
+ }
45
+ ]
46
+
47
+ === Installation
48
+
49
+ `sudo gem install csv2json --source gemcutter.org`
50
+
51
+ === Usage
52
+
53
+ Usage: csv2json [INPUT] [OPTIONS]
54
+
55
+ Specific options:
56
+ -o, --output FILE Write output to a file
57
+ -h, --help Show this message
58
+ -v, --version Show version
59
+
60
+ === Alternative usage
61
+
62
+ common usage is `csv2json file.csv > file.json`
63
+
64
+ csv2json should behave like proper unix command-line utility working with pipes, redirects, etc.
65
+
66
+ `cat file.csv | csv2json | gzip > file.json.gz`
67
+
68
+ === Usage as a library
69
+
70
+ with files
71
+
72
+ require 'csv2json'
73
+
74
+ File.open('input.csv', 'r') do |input|
75
+ File.open('output.json', 'w') do |output|
76
+ CSV2JSON.parse(input, output)
77
+ end
78
+ end
79
+
80
+ or in-memory
81
+
82
+ require 'csv2json'
83
+
84
+ input = StringIO.new(csv_string)
85
+ output = StringIO.new()
86
+ CSV2JSON.parse(input, output)
87
+
88
+ output.pos = 0
89
+ puts output.read
90
+
91
+ == Want to contribute?
92
+
93
+ * Fork the project.
94
+ * Make your feature addition or bug fix.
95
+ * Add tests for it. This is important so I don't break it in a
96
+ future version unintentionally.
97
+ * Commit, do not mess with rakefile, version, or history.
98
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
99
+ * Send me a pull request. Bonus points for topic branches.
100
+
101
+ == Copyright
102
+
103
+ Copyright (c) 2009 Antonin Hildebrand. See LICENSE for details.
104
+
105
+ Check out [http://binaryage.com](http://binaryage.com)
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'lib', 'csv2json.rb')
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.version = CSV2JSON::VERSION
9
+ gem.name = "csv2json"
10
+ gem.summary = %Q{.csv to .json converter}
11
+ gem.description = %Q{handy for converting xls files to json}
12
+ gem.email = "antonin@hildebrand.cz"
13
+ gem.homepage = "http://github.com/darwin/csv2json"
14
+ gem.authors = ["Antonin Hildebrand"]
15
+ gem.add_development_dependency "shoulda", ">= 0"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/**/test_*.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/**/test_*.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :test => :check_dependencies
44
+
45
+ task :default => :test
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "csv2json #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/bin/csv2json ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require 'optparse'
5
+ require 'ostruct'
6
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'csv2json.rb') # this form is important for local development
7
+
8
+ module CSV2JSONRunner
9
+
10
+ # command-line parsing
11
+ COMMAND = File.basename($0)
12
+ USAGE = "Usage: #{COMMAND} [INPUT] [OPTIONS]"
13
+
14
+ options = OpenStruct.new
15
+ options.output = "-"
16
+
17
+ opts = OptionParser.new do |o|
18
+ o.banner = USAGE
19
+ o.separator ""
20
+ o.separator "Specific options:"
21
+
22
+ o.on("-o", "--output FILE", "Write output to a file") do |fn|
23
+ options.output = fn
24
+ end
25
+
26
+ o.on_tail("-h", "--help", "Show this message") do
27
+ puts o
28
+ exit
29
+ end
30
+
31
+ o.on_tail("-v", "--version", "Show version") do
32
+ puts CSV2JSON::VERSION
33
+ exit
34
+ end
35
+ end
36
+
37
+ begin
38
+ opts.parse!(ARGV)
39
+ rescue
40
+ die "Unable to parse options: #{$!}"
41
+ end
42
+
43
+ # initialize output handle
44
+ if options.output == "-"
45
+ OUT = $stdout.clone
46
+ else
47
+ OUT = File.open(options.output, "w")
48
+ end
49
+
50
+ if ARGV.size > 0
51
+ IN = File.open(ARGV[0], "r")
52
+ else
53
+ IN = StringIO.new($stdin.read) # cannot be just $stdin.clone because FasterCSV is seeking in file :-(
54
+ end
55
+
56
+ # run the command
57
+ CSV2JSON.parse(IN, OUT)
58
+
59
+ # leave in peace
60
+ OUT.flush
61
+ end
data/lib/csv2json.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'fastercsv'
2
+ require 'json'
3
+
4
+ module CSV2JSON
5
+ VERSION = "0.1.0"
6
+
7
+ # convert an input string value to integer or float if applicable
8
+ def convert(val)
9
+ return Integer(val) if val.to_i.to_s == val
10
+ Float(val) rescue val
11
+ end
12
+
13
+ # input and output are file objects, you can use StringIO if you want to work in memory
14
+ def parse(input, output, headers=nil)
15
+ result = Array.new
16
+
17
+ FasterCSV.new(input).each do |row|
18
+ # treat first row as headers if the caller didn't provide them
19
+ unless headers
20
+ headers = row
21
+ next
22
+ end
23
+
24
+ # build JSON snippet and append it to the result
25
+ snippet = Hash.new
26
+ headers.each_index { |i| snippet[headers[i]] = self.convert(row[i]) }
27
+ result << snippet
28
+ end
29
+
30
+ output << JSON.pretty_generate(result)
31
+ end
32
+
33
+ module_function :parse
34
+ module_function :convert
35
+
36
+ end
@@ -0,0 +1,16 @@
1
+ Office,Address1,Address2,Address3,City,State,Zip,Phone,Fax
2
+ Headquarters,1600 Amphitheatre Parkway,,,Mountain View,CA,94043,650-253-0000,650-253-0001
3
+ New York Sales & Engineering Office,76 Ninth Avenue,,,New York,NY,10011,212-565-0000,212-565-0001
4
+ Ann Arbor Sales Office,201 South Division Street,,,Ann Arbor,MI,48104,734-332-6500,734-332-6501
5
+ Atlanta Sales & Engineering Office,10 10th Street NE,,,Atlanta,GA,30309,404-487-9000,404-487-9001
6
+ Boulder Sales & Engineering Office,2590 Pearl St.,,,Boulder,CO,80302,303-245-0086,303-535-5592
7
+ Cambridge Sales & Engineering Office,5 Cambridge Center,,,Cambridge,MA,02142,617-682-3635,617-249-0199
8
+ Chicago Sales & Engineering Office,20 West Kinzie St.,,,Chicago,IL,60610,312-840-4100,312-840-4101
9
+ Coppell Sales Office,701 Canyon Drive,,,Coppell,TX,75019,214-451-4000,214-451-4001
10
+ Detroit Sales Office,114 Willits Street,,,Birmingham,MI,48009,248-351-6220,248-351-6227
11
+ Irvine Sales & Engineering Office,19540 Jamboree Road,,,Irvine,CA,92612,949-794-1600,949-794-1601
12
+ Pittsburgh Engineering Office,4720 Forbes Avenue,,,Pittsburgh,PA,15213,,
13
+ Santa Monica Sales & Engineering Office,604 Arizona Avenue,,,Santa Monica,CA,90401,310-460-4000,310-309-6840
14
+ Seattle Engineering Office,720 4th Avenue,,,Kirkland,WA,98033,425-739-5600,425-739-5601
15
+ Seattle Sales Office,501 N. 34th Street,,,Seattle,WA,98103,206-876-1500,206-876-1501
16
+ Washington D.C. Public Policy Office,1001 Pennsylvania Avenue NW,,,Washington,DC,20004,202-742-6520,
@@ -0,0 +1,167 @@
1
+ [
2
+ {
3
+ "Address3": null,
4
+ "Zip": 94043,
5
+ "City": "Mountain View",
6
+ "Phone": "650-253-0000",
7
+ "Fax": "650-253-0001",
8
+ "State": "CA",
9
+ "Office": "Headquarters",
10
+ "Address1": "1600 Amphitheatre Parkway",
11
+ "Address2": null
12
+ },
13
+ {
14
+ "Address3": null,
15
+ "Zip": 10011,
16
+ "City": "New York",
17
+ "Phone": "212-565-0000",
18
+ "Fax": "212-565-0001",
19
+ "State": "NY",
20
+ "Office": "New York Sales & Engineering Office",
21
+ "Address1": "76 Ninth Avenue",
22
+ "Address2": null
23
+ },
24
+ {
25
+ "Address3": null,
26
+ "Zip": 48104,
27
+ "City": "Ann Arbor",
28
+ "Phone": "734-332-6500",
29
+ "Fax": "734-332-6501",
30
+ "State": "MI",
31
+ "Office": "Ann Arbor Sales Office",
32
+ "Address1": "201 South Division Street",
33
+ "Address2": null
34
+ },
35
+ {
36
+ "Address3": null,
37
+ "Zip": 30309,
38
+ "City": "Atlanta",
39
+ "Phone": "404-487-9000",
40
+ "Fax": "404-487-9001",
41
+ "State": "GA",
42
+ "Office": "Atlanta Sales & Engineering Office",
43
+ "Address1": "10 10th Street NE",
44
+ "Address2": null
45
+ },
46
+ {
47
+ "Address3": null,
48
+ "Zip": 80302,
49
+ "City": "Boulder",
50
+ "Phone": "303-245-0086",
51
+ "Fax": "303-535-5592",
52
+ "State": "CO",
53
+ "Office": "Boulder Sales & Engineering Office",
54
+ "Address1": "2590 Pearl St.",
55
+ "Address2": null
56
+ },
57
+ {
58
+ "Address3": null,
59
+ "Zip": 2142.0,
60
+ "City": "Cambridge",
61
+ "Phone": "617-682-3635",
62
+ "Fax": "617-249-0199",
63
+ "State": "MA",
64
+ "Office": "Cambridge Sales & Engineering Office",
65
+ "Address1": "5 Cambridge Center",
66
+ "Address2": null
67
+ },
68
+ {
69
+ "Address3": null,
70
+ "Zip": 60610,
71
+ "City": "Chicago",
72
+ "Phone": "312-840-4100",
73
+ "Fax": "312-840-4101",
74
+ "State": "IL",
75
+ "Office": "Chicago Sales & Engineering Office",
76
+ "Address1": "20 West Kinzie St.",
77
+ "Address2": null
78
+ },
79
+ {
80
+ "Address3": null,
81
+ "Zip": 75019,
82
+ "City": "Coppell",
83
+ "Phone": "214-451-4000",
84
+ "Fax": "214-451-4001",
85
+ "State": "TX",
86
+ "Office": "Coppell Sales Office",
87
+ "Address1": "701 Canyon Drive",
88
+ "Address2": null
89
+ },
90
+ {
91
+ "Address3": null,
92
+ "Zip": 48009,
93
+ "City": "Birmingham",
94
+ "Phone": "248-351-6220",
95
+ "Fax": "248-351-6227",
96
+ "State": "MI",
97
+ "Office": "Detroit Sales Office",
98
+ "Address1": "114 Willits Street",
99
+ "Address2": null
100
+ },
101
+ {
102
+ "Address3": null,
103
+ "Zip": 92612,
104
+ "City": "Irvine",
105
+ "Phone": "949-794-1600",
106
+ "Fax": "949-794-1601",
107
+ "State": "CA",
108
+ "Office": "Irvine Sales & Engineering Office",
109
+ "Address1": "19540 Jamboree Road",
110
+ "Address2": null
111
+ },
112
+ {
113
+ "Address3": null,
114
+ "Zip": 15213,
115
+ "City": "Pittsburgh",
116
+ "Phone": null,
117
+ "Fax": null,
118
+ "State": "PA",
119
+ "Office": "Pittsburgh Engineering Office",
120
+ "Address1": "4720 Forbes Avenue",
121
+ "Address2": null
122
+ },
123
+ {
124
+ "Address3": null,
125
+ "Zip": 90401,
126
+ "City": "Santa Monica",
127
+ "Phone": "310-460-4000",
128
+ "Fax": "310-309-6840",
129
+ "State": "CA",
130
+ "Office": "Santa Monica Sales & Engineering Office",
131
+ "Address1": "604 Arizona Avenue",
132
+ "Address2": null
133
+ },
134
+ {
135
+ "Address3": null,
136
+ "Zip": 98033,
137
+ "City": "Kirkland",
138
+ "Phone": "425-739-5600",
139
+ "Fax": "425-739-5601",
140
+ "State": "WA",
141
+ "Office": "Seattle Engineering Office",
142
+ "Address1": "720 4th Avenue",
143
+ "Address2": null
144
+ },
145
+ {
146
+ "Address3": null,
147
+ "Zip": 98103,
148
+ "City": "Seattle",
149
+ "Phone": "206-876-1500",
150
+ "Fax": "206-876-1501",
151
+ "State": "WA",
152
+ "Office": "Seattle Sales Office",
153
+ "Address1": "501 N. 34th Street",
154
+ "Address2": null
155
+ },
156
+ {
157
+ "Address3": null,
158
+ "Zip": 20004,
159
+ "City": "Washington",
160
+ "Phone": "202-742-6520",
161
+ "Fax": null,
162
+ "State": "DC",
163
+ "Office": "Washington D.C. Public Policy Office",
164
+ "Address1": "1001 Pennsylvania Avenue NW",
165
+ "Address2": null
166
+ }
167
+ ]