Sha256: 5048f42ade07e93dd2b58c91e483c8ba18e53f607ecbb75b541faa867366e140

Contents?: true

Size: 1.17 KB

Versions: 5

Compression:

Stored size: 1.17 KB

Contents

# frozen_string_literal: true
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
              raise 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

5 entries across 5 versions & 1 rubygems

Version Path
soapy_bing-0.3.1 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.3.0 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.2.0 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.1.0 lib/soapy_bing/ads/reports/parsers/csv_parser.rb
soapy_bing-0.0.5 lib/soapy_bing/ads/reports/parsers/csv_parser.rb