class Spout::Commands::Importer

Public Class Methods

new(argv) click to toggle source
# File lib/spout/commands/importer.rb, line 11
def initialize(argv)
  use_domains = !argv.delete("--domains").nil?
  use_forms = !argv.delete("--forms").nil?
  @preserve_case = !argv.delete("--preserve-case").nil?
  @csv_file = argv[1].to_s
  unless File.exist?(@csv_file)
    puts csv_usage
    return self
  end
  if use_domains
    import_domains
  elsif use_forms
    import_forms
  else
    import_variables
  end
end

Public Instance Methods

csv_usage() click to toggle source
# File lib/spout/commands/importer.rb, line 29
      def csv_usage
        usage = <<-EOT

Usage: spout import CSVFILE

The CSVFILE must be the location of a valid CSV file.

EOT
        usage
      end
import_domains() click to toggle source
# File lib/spout/commands/importer.rb, line 76
def import_domains
  domains = {}

  Spout::Helpers::CSVReader.read_csv(@csv_file) do |row|
    if not row.keys.include?("domain_id")
      puts "\nMissing column header `".red + "domain_id".cyan + "` in data dictionary.".red + additional_csv_info
      exit(1)
    end
    if not row.keys.include?("value")
      puts "\nMissing column header `".red + "value".cyan + "` in data dictionary.".red + additional_csv_info
      exit(1)
    end
    if not row.keys.include?("display_name")
      puts "\nMissing column header `".red + "display_name".cyan + "` in data dictionary.".red + additional_csv_info
      exit(1)
    end

    next if row["domain_id"].to_s == "" or row["value"].to_s == "" or row["display_name"].to_s == ""
    folder = File.join("domains", row["folder"].to_s).gsub(/[^a-zA-Z0-9_\/\.-]/, "_")
    domain_name = row["domain_id"].to_s.gsub(/[^a-zA-Z0-9_\/\.-]/, "_").downcase
    domains[domain_name] ||= {}
    domains[domain_name]["folder"] = folder
    domains[domain_name]["options"] ||= []

    hash = {}
    hash["value"] = row.delete("value").to_s
    hash["display_name"] = tenderize(row.delete("display_name").to_s)
    hash["description"] = row.delete("description").to_s
    hash["missing"] = true if hash["value"].match(/^[\.-]/)

    domains[domain_name]["options"] << hash
  end

  domains.each do |domain_name, domain_hash|
    folder = domain_hash["folder"]
    FileUtils.mkpath folder

    file_name = File.join(folder, "#{domain_name}.json")

    File.open(file_name, "w") do |file|
      file.write(JSON.pretty_generate(domain_hash["options"]) + "\n")
    end
    puts "      create".green + "  #{file_name}"
  end
end
import_forms() click to toggle source
# File lib/spout/commands/importer.rb, line 122
def import_forms
  Spout::Helpers::CSVReader.read_csv(@csv_file) do |row|
    unless row.keys.include?("id")
      puts "\nMissing column header `".red +
           "id".cyan +
           "` in data dictionary.".red +
           additional_csv_info
      exit(1)
    end
    unless row.keys.include?("display_name")
      puts "\nMissing column header `".red +
           "display_name".cyan +
           "` in data dictionary.".red +
           additional_csv_info
      exit(1)
    end
    next if row["id"] == ""
    folder = File.join("forms", row.delete("folder").to_s)
    FileUtils.mkpath folder
    hash = {}
    id = row.delete("id").to_s.downcase
    hash["id"] = id
    hash["display_name"] = tenderize(row.delete("display_name").to_s)
    hash["code_book"] = row.delete("code_book").to_s
    hash["other"] = row unless row.empty?
    file_name = File.join(folder, "#{id}.json")
    File.open(file_name, "w") do |file|
      file.write(JSON.pretty_generate(hash) + "\n")
    end
    puts "      create".green + "  #{file_name}"
  end
end
import_variables() click to toggle source
# File lib/spout/commands/importer.rb, line 40
def import_variables
  Spout::Helpers::CSVReader.read_csv(@csv_file) do |row|
    if not row.keys.include?("id")
      puts "\nMissing column header `".red + "id".cyan + "` in data dictionary.".red + additional_csv_info
      exit(1)
    end
    next if row["id"] == ""
    folder = File.join("variables", row.delete("folder").to_s)
    FileUtils.mkpath folder
    hash = {}
    id = row.delete("id").to_s.downcase
    hash["id"] = id
    hash["display_name"] = tenderize(row.delete("display_name").to_s)
    hash["description"] = row.delete("description").to_s
    hash["type"] = row.delete("type")
    domain = row.delete("domain").to_s.downcase
    hash["domain"] = domain if domain != ""
    units = row.delete("units").to_s
    hash["units"] = units if units != ""
    calculation = row.delete("calculation").to_s
    hash["calculation"] = calculation if calculation != ""
    labels = row.delete("labels").to_s.split(";")
    hash["labels"] = labels unless labels.empty?
    hash["commonly_used"] = true if row.delete("commonly_used").to_s.casecmp("true").zero?
    forms = row.delete("forms").to_s.split(";")
    hash["forms"] = forms unless forms.empty?
    hash["other"] = row unless row.empty?

    file_name = File.join(folder, "#{id}.json")
    File.open(file_name, "w") do |file|
      file.write(JSON.pretty_generate(hash) + "\n")
    end
    puts "      create".green + "  #{file_name}"
  end
end
tenderize(text) click to toggle source

Converts ALL-CAPS display names to title case Ex: BODY MASS INDEX changes to Body Mass Index Ex: Patient ID stays the same as Patient ID

# File lib/spout/commands/importer.rb, line 158
def tenderize(text)
  return text if @preserve_case
  if /[a-z]/ =~ text
    text
  else
    text.downcase.gsub(/\b\w/) { $&.upcase }
  end
end

Private Instance Methods

additional_csv_info() click to toggle source
# File lib/spout/commands/importer.rb, line 169
def additional_csv_info
  "\n\nFor additional information on specifying CSV column headers before import see:\n\n    " +
    "https://github.com/sleepepi/spout#generate-a-new-repository-from-an-existing-csv-file".cyan + "\n\n"
end