# frozen_string_literal: true require "em-http" require "em_promise" require "em-synchrony/em-http" # For aget vs get require "money/bank/open_exchange_rates_bank" require "nokogiri" require_relative "em" class BTCSellPrices def initialize(redis, oxr_app_id) @redis = redis @oxr = Money::Bank::OpenExchangeRatesBank.new( Money::RatesStore::Memory.new ) @oxr.app_id = oxr_app_id end def cad fetch_canadianbitcoins.then do |http| canadianbitcoins = Nokogiri::HTML.parse(http.response) bitcoin_row = canadianbitcoins.at("#ticker > table > tbody > tr") raise "Bitcoin row has moved" unless bitcoin_row.at("td").text == "Bitcoin" BigDecimal( bitcoin_row.at("td:nth-of-type(3)").text.match(/^\$(\d+\.\d+)/)[1] ) end end def usd EMPromise.all([cad, cad_to_usd]).then { |(a, b)| a * b } end protected def fetch_canadianbitcoins EM::HttpRequest.new( "https://www.canadianbitcoins.com", tls: { verify_peer: true } ).aget end def cad_to_usd @redis.get("cad_to_usd").then do |rate| next rate.to_f if rate EM.promise_defer { # OXR gem is not async, so defer to threadpool @oxr.update_rates @oxr.get_rate("CAD", "USD") }.then do |orate| @redis.setex("cad_to_usd", 60 * 60, orate).then { orate } end end end end