Module: Parsers

Defined in:
app/models/parsers.rb,
app/models/parsers/pbmc_count_parser.rb

Defined Under Namespace

Classes: BioanalysisCsvParser, DilutionParser, PbmcCountParser, PlateReaderParser, QuantParser

Constant Summary collapse

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

Class Method Summary collapse

Class Method Details

.parse_with_fallback_encodings(content) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/models/parsers.rb', line 26

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



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'app/models/parsers.rb', line 9

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 do |parser|
      parser.parses?(csv)
    rescue StandardError
      false
    end
  parser_class&.new(csv)
end