module Import # Feel free to add extra delimiters to this array. DELIMITERS = ["\t", '|', ","] def Import.import(klasses, params_data, args = {}, debug = false) args.merge!({:imported_at => Time.now.strftime("%Y-%m-%d %H:%M:%S")}) unless args.has_key?(:imported_at) klasses = [klasses] unless klasses.is_a?(Array) delim = auto_detect_delimiter(params_data.to_s) header_row = nil objects = [] FCSV.parse(params_data, {:col_sep => delim, :row_sep => :auto}) do |row| next if row.join("") !~ /\w/ # Skip blank rows. header_row ||= row next if header_row.join("") === row.join("") # Skip over duplicate header rows. # Clean up the data, get rid of leading/trailing spaces. row.collect {|str| str.to_s.strip!} h = Hash[*header_row.zip(row).flatten] klasses.each do |c| style = c.recognize_hash_style(h, debug) objects << c.import(h, args) if style end end # Return an array of everything that was imported in this batch. objects end def Import.import_from_file(klasses, filename, debug = false) args = {} args[:date] = Date.strptime($1) if filename =~ /([0-9]{4}-[0-9]{2}-[0-9]{2})/ import(klasses, File.read(filename), args, debug) end private def Import.import_if_valid_else_ignore begin yield rescue Exception => e puts e.inspect return nil end end # Guess the correct text file column delimiter. We look at the first row # of data and the most common character from the DELIMITERS array is # assumed to be the delimiter. You can add additional characters to the # DELIMITERS array but to avoid the risk of false positives it's probably # best not to add too many. def Import.auto_detect_delimiter(sample_text) sample_text = sample_text.split(/$/)[0] || "" delim = DELIMITERS[0] len = DELIMITERS.length DELIMITERS[1-len, len-1].each do |char| delim = char if sample_text.count(char) > sample_text.count(delim) end delim end end