Permalink
Browse files

Rouch, untested version of json2csv

  • Loading branch information...
1 parent 09b4294 commit 4e9bc491f8c9e49a958db2ba55bf4df93f21c670 rory committed Sep 15, 2012
Showing with 137 additions and 0 deletions.
  1. +82 −0 bin/json2csv
  2. +32 −0 lib/json2csv.rb
  3. +22 −0 test/test_json2csv.rb
  4. +1 −0 translated.json
View
@@ -0,0 +1,82 @@
+#!/usr/bin/env ruby
+
+require "rubygems"
+require 'optparse'
+require 'ostruct'
+require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'json2csv.rb') # this form is important for local development
+
+module JSON2CSVRunner
+
+ # command-line parsing
+ COMMAND = File.basename($0)
+ USAGE = "Usage: #{COMMAND} [INPUT] [OPTIONS]"
+
+ options = OpenStruct.new
+ options.output = "-"
+ options.separator = ","
+ options.pretty = false
+ options.headers = nil
+ options.skipFirstRow = false
+
+ opts = OptionParser.new do |o|
+ o.banner = USAGE
+ o.separator ""
+ o.separator "Specific options:"
+
+ o.on("-s", "--separator SEP", "Set separator character surrounded by single quotes (default is ',')") do |sep|
+ options.separator = sep
+ end
+
+ o.on("-o", "--output FILE", "Write output to a file") do |fn|
+ options.output = fn
+ end
+
+ o.on("-H", "--force-headers HEADERS", "Supply list of headers, and skip first row of input; use to override headers in file") do |headers|
+ if headers then
+ options.headers = headers.split(",")
+ options.skipFirstRow = true
+ end
+ end
+
+ o.on("-h", "--headers HEADERS", "Supply list of headers, where no headers exist in the file") do |headers|
+ if headers then
+ options.headers = headers.split(",")
+ end
+ end
+
+ o.on_tail("-h", "--help", "Show this message") do
+ puts o
+ exit
+ end
+
+ o.on_tail("-v", "--version", "Show version") do
+ puts CSV2JSON::VERSION
+ exit
+ end
+ end
+
+ begin
+ opts.parse!(ARGV)
+ rescue
+ raise "Unable to parse options: #{$!}"
+ end
+
+ # initialize output handle
+ if options.output == "-"
+ OUT = $stdout.clone
+ else
+ OUT = File.open(options.output, "w")
+ end
+
+ if ARGV.size > 0
+ IN = File.read(ARGV[0])
+ else
+ IN = StringIO.new($stdin.read) # cannot be just $stdin.clone because FasterCSV is seeking in file :-(
+ end
+
+ # run the command
+ JSON2CSV.parse(IN, OUT, options.headers, nil)
+
+ # leave in peace
+ OUT.flush
+end
View
@@ -0,0 +1,32 @@
+require 'rubygems'
+require 'fastercsv'
+require 'json'
+require 'csv2json-version.rb'
+
+module JSON2CSV
+
+ # convert an input string value to integer or float if applicable
+ def convert(val)
+ return Integer(val) if val.to_i.to_s == val
+ Float(val) rescue val
+ end
+
+
+ def parse(input, output, headers=nil, options={})
+ inputJSON = JSON.parse(input)
+
+ outputCSV = FasterCSV.generate do |csv|
+ csv << inputJSON[0].keys
+ inputJSON.each do |row|
+ csv << row.values
+ end
+ end
+
+ output << outputCSV
+ end
+
+
+ module_function :parse
+ module_function :convert
+
+end
View
@@ -0,0 +1,22 @@
+require 'helper'
+require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'csv2json.rb') # this form is important for local development
+
+class TestCsv2json < Test::Unit::TestCase
+ SEPS = {:comma => ',', :pipe => '|', :semicolon => ';'}
+ should "parse some test files" do
+ fixtures_dir = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
+ Dir.chdir(fixtures_dir) do
+ Dir.glob('*.csv') do |filename|
+ filename_parts = File.basename(filename, ".csv").split('_')
+ json_template = filename_parts[0] + '.json'
+ File.open(filename, "r") do |input|
+ output = StringIO.new()
+ CSV2JSON.parse(input, output, nil, :col_sep => SEPS[filename_parts[1].to_sym] )
+ template = File.read(json_template)
+ output.pos = 0
+ assert template == output.read
+ end
+ end
+ end
+ end
+end
View
@@ -0,0 +1 @@
+[{"columnC":"value1C","columnB":"value1B","columnA":"value1A"},{"columnC":"value2C","columnB":"value2B","columnA":"value2A"}]

0 comments on commit 4e9bc49

Please sign in to comment.