Sha256: 45a7bb728c689dc140dbe0afb853c5b4eec5aa176f6495fdebc302da9ae619eb

Contents?: true

Size: 1.14 KB

Versions: 4

Compression:

Stored size: 1.14 KB

Contents

require 'csv'

module SoapyBing
  class Ads
    module Reports
      module Parsers
        class CSVParser
          class FormatError < StandardError; end

          CSV_PAYLOAD_OFFSET_FRONT = 10 # First 10 csv lines are report metadata
          CSV_PAYLOAD_OFFSET_BACK = 2 # Last 2 csv lines are Microsoft copyright

          def initialize(raw)
            @raw = raw
          end

          def rows
            @rows ||= begin
              header, *body = extract_csv_payload
              fail FormatError if body.size != payload_rows_number
              body.map { |row| header.zip(row).to_h }
            end
          end

          private

          attr_reader :raw

          def extract_csv_payload
            text = raw.dup
            text.force_encoding(Encoding::UTF_8).encode! unless text.encoding == Encoding::UTF_8
            text.sub!(/^\xEF\xBB\xBF/, '') # cleanup BOM

            csv_rows = CSV.parse(text)
            csv_rows[CSV_PAYLOAD_OFFSET_FRONT...-CSV_PAYLOAD_OFFSET_BACK]
          end

          def payload_rows_number
            raw.match(/"Rows: (\d+)"/)[1].to_i
          end
        end
      end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
soapy_bing-0.0.4 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.0.3 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.0.2 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.0.1 lib/soapy_bing/ads/reports/parsers/csv_parser.rb