Carrierwave: очистить CSV перед загрузкой - PullRequest
1 голос
/ 14 октября 2019

У меня есть загрузчик Carrierwave InventoryUploader, который я использую для хранения файлов формата text/csv или application/vnd.ms-excel. Я получаю некоторые недопустимые ошибки последовательности байтов при обработке файлов, поэтому я хотел бы очистить их перед загрузкой.

Я создал process :clean_file обратный вызов на загрузчике Carrierwave, но изо всех сил пытаюсь найтихороший способ очистить любые символы BOM / funky перед загрузкой.

Есть ли удобный способ сделать это? Я пытаюсь что-то вроде:

class InventoryUploader < CarrierWave::Uploader::Base
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.id}"
  end  

  def content_type_whitelist
    %w(text/csv application/vnd.ms-excel)
  end

  process :clean_file

  private

  def clean_file
    # Perhaps something like this?
    # but how can I ensure it removes all weird
    # character sequences?
    CSV.foreach(file.path, headers: true, encoding: 'UTF-8') do |row|
      row.each do |field|
        field[1].gsub!("\xEF\xBB\xBF".force_encoding("UTF-8"), '')
      end
    end
  end
end

Заранее спасибо!

1 Ответ

0 голосов
/ 16 октября 2019

смог сделать это с помощью следующего кода:

require 'tempfile'

class InventoryUploader < CarrierWave::Uploader::Base
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.id}"
  end

  def content_type_whitelist
    %w(text/csv application/vnd.ms-excel)
  end

  process :clean_file

  private

  def clean_file
    tempfile = Tempfile.open('temp_csv', encoding: 'utf-8') do |f|
      File.foreach(current_path) do |line|
        f.puts line.encode('UTF-8', invalid: :replace, undef: :replace)
      end
      f
    end
    FileUtils.mv(tempfile.path, current_path)
  end
end
...