Module: Parsers

Defined in:
app/models/parsers.rb

Defined Under Namespace

Classes: BioanalysisCsvParser, DilutionParser, PlateReaderParser, QuantParser

Constant Summary collapse

ENCODINGS =
%w[Windows-1252 iso-8859-1 utf-8 utf-16].freeze
PARSERS =
[QuantParser, BioanalysisCsvParser, PlateReaderParser].freeze

Class Method Summary collapse

Class Method Details

.parse_with_fallback_encodings(content) ⇒ Object


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'app/models/parsers.rb', line 20

def self.parse_with_fallback_encodings(content)
  encodings = ENCODINGS.dup
  begin
    CSV.parse(content)
  rescue ArgumentError => e
    # Fetch the next fallback encoding
    encoding = encodings.shift
    # Re-raise the exception if we've run out
    raise e if encoding.nil?

    # Force the new encoding
    content.force_encoding(encoding)
    # Try again
    retry unless encoding.nil?
  end
end

.parser_for(filename, content_type, content) ⇒ Object


8
9
10
11
12
13
14
15
16
17
18
# File 'app/models/parsers.rb', line 8

def self.parser_for(filename, content_type, content)
  return nil unless filename.downcase.end_with?('.csv') || content_type == 'text/csv'

  # While CSV tries to detect line endings, it isn't so great with some excel
  # exported CSVs, where a mix of \n and \r\n are used in the same document
  # This converts everything to \n before processing
  cleaned_content = LinefeedFix.scrub!(content.dup)
  csv = parse_with_fallback_encodings(cleaned_content)
  parser_class = PARSERS.detect { |parser| parser.parses?(csv) }
  parser_class ? parser_class.new(csv) : nil
end