Skip to content

Instantly share code, notes, and snippets.

@jenseng
Created September 11, 2015 19:12
Show Gist options
  • Save jenseng/e5b7062d07f5c52180a8 to your computer and use it in GitHub Desktop.
Save jenseng/e5b7062d07f5c52180a8 to your computer and use it in GitHub Desktop.
yml <-> csv thingy for transifex
#!/usr/bin/env ruby
begin
require "ya2yaml"
rescue
`gem install ya2yaml`
require "ya2yaml"
end
begin
require "syck"
rescue
`gem install syck`
require "syck"
end
require "csv"
require "json"
def colorize(text, color_code)
return text unless $stdout.tty?
"\e[0;#{color_code}m#{text}\e[0m"
end
def red(text)
colorize(text, 31)
end
def usage
$stderr.puts "usage: yamlcsv <filename>"
end
def error(message)
$stderr.puts red "ERROR: #{message}"
puts
usage
exit 1
end
module HashExtensions
def flatten_keys(result = {}, prefix='')
each_pair do |k, v|
if v.is_a?(Hash)
v.flatten_keys(result, "#{prefix}#{k}.")
else
result["#{prefix}#{k}"] = v
end
end
result
end
def expand_keys(result = {})
each_pair do |k, v|
parts = k.split('.')
last = parts.pop
parts.inject(result) { |h, k2| h[k2] ||= {} }[last] = v
end
result
end
Hash.send(:include, HashExtensions)
end
def prompt_overwrite(file)
while true
puts "#{file} already exists. Overwrite? (Y/N)"
choice = $stdin.gets.strip.chomp[0].downcase
break if choice == "y"
exit if choice == "n"
end
end
def to_csv(file)
data = YAML.load_file(file) rescue error("`#{file}` is not a valid yml file")
target_file = file.sub(/\.ya?ml\z/, ".csv")
prompt_overwrite(target_file) if File.exist?(target_file)
CSV.open(target_file, "wb") do |csv|
data.flatten_keys.to_a.sort_by(&:first).each do |key, value|
csv << [key, value]
end
end
end
def to_yaml(file)
data = CSV.read(file) rescue(error "`#{file}` is not a valid csv file")
target_file = file.sub(/\.csv\z/, ".yml")
prompt_overwrite(target_file) if File.exist?(target_file)
data = data.each_with_index.inject({}) do |hash, (row, id)|
error "#{row.size} columns on row #{id + 1}; expected 2" if row.size != 2
key, value = *row
error "`#{key}` does not appear to be a valid i18n key on row #{id + 1}" unless key =~ /\A[a-z0-9_\. \/-]+\z/i
if value =~ /\A\[.*\]\z/ && ary = JSON.parse(value.gsub(/\bnil\b/, "null")) rescue nil
value = ary
elsif value =~ /\A\d+\z/ && key !~ /\.first_day_index\z/
value = value.to_i
elsif value =~ /\A(true|false)\z/
value = value == "true"
end
hash[key] = value
hash
end
data = data.expand_keys
error "more than one top-level locale key" if data.size > 1
File.open(target_file, "wb") do |f|
f.write data.ya2yaml(:syck_compatible => true)
end
end
file = ARGV.shift
error "no file specified" unless file
error "invalid file `#{file}`" unless File.exist?(file)
error "file must be a csv or yaml" unless file =~ /\.(ya?ml|csv)\z/
if file =~ /\.csv\z/
to_yaml(file)
else
to_csv(file)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment