From 904b824c8bdbcd60d543db6fcaac069cfdb67c3e Mon Sep 17 00:00:00 2001 From: Ilya Konanykhin Date: Wed, 15 Mar 2017 15:17:40 +0600 Subject: [PATCH] Create rake task (import:bikes:csv, import:bikes:analyze_csv) & importing class --- app/models/bikes_csv_importer.rb | 67 ++++++++++++++++++++++++++++++++ lib/tasks/import.rake | 19 +++++++++ 2 files changed, 86 insertions(+) create mode 100644 app/models/bikes_csv_importer.rb create mode 100644 lib/tasks/import.rake diff --git a/app/models/bikes_csv_importer.rb b/app/models/bikes_csv_importer.rb new file mode 100644 index 0000000..9c957ee --- /dev/null +++ b/app/models/bikes_csv_importer.rb @@ -0,0 +1,67 @@ +require 'csv' + +class BikesCsvImporter + attr_reader :file + + def initialize(file) + @file = file + end + + def run + fetch do |bike_hash| + import_bike bike_hash + end + end + + def analyze(fields = []) + fields = fields.map &:downcase + grouped = {} + fetch do |bike_hash| + bike_hash.each do |key, value| + next if fields.any? && !fields.include?(key.downcase) + grouped[key] ||= {} + grouped[key][value] ||= 0 + grouped[key][value] += 1 + end + end + grouped + end + + + + private + + def fetch + CSV.foreach(file).each_with_index do |row, i| + if i.zero? + parse_header row + else + yield parse_bike(row) + end + end + end + + def parse_header(row) + @header = row + end + + def parse_bike(row) + @header.zip(row).to_h + end + + def import_bike(bike_hash) + # TODO + end + + def clean_value(value) + value_or_nil strip_value(value) + end + + def strip_value(value) + value.try(:strip).try(:gsub, /\n|\r/, '') + end + + def value_or_nil(value) + return value unless ['?', 'n/a', 'missing', ''].include? value.try(:downcase) + end +end diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake new file mode 100644 index 0000000..760e9e6 --- /dev/null +++ b/lib/tasks/import.rake @@ -0,0 +1,19 @@ +namespace :import do + namespace :bikes do + # Imports bikes info from CSV file + task :csv, [:file] => :environment do |t, args| + file = args[:file] + next puts "Usage: rake #{t.name}[$csv_file_path]" unless file + next puts "File #{file} does not exist or is unreachable" unless File.readable? file + pp BikesCsvImporter.new(file).run + end + + # Analyze a single field from CSV file + task :analyze_csv, [:file, :field] => :environment do |t, args| + file, field = args.values_at :file, :field + next puts "Usage: rake #{t.name}[$csv_file_path[,\"$field_name\"]]" unless file + next puts "File #{file} does not exist or is unreachable" unless File.readable? file + pp BikesCsvImporter.new(file).analyze field ? [field] : [] + end + end +end