Sha256: 4181f5c34f787bc94f1bd75fe3fc78ab3eac6effd89d8b911a389a8a1b576c23

Contents?: true

Size: 1.88 KB

Versions: 3

Compression:

Stored size: 1.88 KB

Contents

require 'danconia/errors/api_error'
require 'net/http'
require 'nokogiri'

module Danconia
  module Exchanges
    # The BNA does not provide an API to pull the rates, so this implementation scrapes the home HTML directly.
    # Returns rates of both types, "Billetes" and "Divisas", and only the "tipo de cambio vendedor" ones.
    # See `examples/bna.rb` for a complete usage example.
    class BNA < Exchange
      attr_reader :store

      def initialize store: Stores::InMemory.new
        @store = store
      end

      def fetch_rates
        response = Net::HTTP.get URI 'https://www.bna.com.ar/Personas'
        scrape_rates(response, 'billetes') + scrape_rates(response, 'divisas')
      end

      def update_rates!
        @store.save_rates fetch_rates
      end

      def rates rate_type:, date: nil
        array_of_rates_to_hash @store.rates(rate_type: rate_type, date: date)
      end

      private

      def scrape_rates response, type
        doc = Nokogiri::XML(response).css("##{type}")

        if doc.css('thead th:last-child').text != 'Venta'
          raise Errors::APIError, "Could not scrape '#{type}' rates. Maybe the format changed?"
        end

        doc.css('tbody tr').map do |row|
          pair = parse_pair(row.css('td:first-child').text) or next
          rate = parse_rate(row.css('td:last-child').text, pair)
          date = Date.parse(doc.css('.fechaCot').text)
          {pair: pair, rate: rate, date: date, rate_type: type}
        end.compact.presence or raise Errors::APIError, "Could not scrape '#{type}' rates. Maybe the format changed?"
      end

      def parse_pair cur_name
        case cur_name
        when 'Dolar U.S.A' then 'USDARS'
        when 'Euro' then 'EURARS'
        when 'Real *' then 'BRLARS'
        end
      end

      def parse_rate str, pair
        val = Float(str.tr(',', '.'))
        pair == 'BRLARS' ? val / 100.0 : val
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
danconia-0.4.0 lib/danconia/exchanges/bna.rb
danconia-0.3.1 lib/danconia/exchanges/bna.rb
danconia-0.3.0 lib/danconia/exchanges/bna.rb