|
|
@ -3,6 +3,7 @@ defmodule Explorer.ExchangeRates.Source do |
|
|
|
Behaviour for fetching exchange rates from external sources. |
|
|
|
Behaviour for fetching exchange rates from external sources. |
|
|
|
""" |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
alias Explorer.ExchangeRates.Source.CoinMarketCap |
|
|
|
alias Explorer.ExchangeRates.Token |
|
|
|
alias Explorer.ExchangeRates.Token |
|
|
|
alias HTTPoison.{Error, Response} |
|
|
|
alias HTTPoison.{Error, Response} |
|
|
|
|
|
|
|
|
|
|
@ -11,6 +12,31 @@ defmodule Explorer.ExchangeRates.Source do |
|
|
|
""" |
|
|
|
""" |
|
|
|
@spec fetch_exchange_rates(module) :: {:ok, [Token.t()]} | {:error, any} |
|
|
|
@spec fetch_exchange_rates(module) :: {:ok, [Token.t()]} | {:error, any} |
|
|
|
def fetch_exchange_rates(source \\ exchange_rates_source()) do |
|
|
|
def fetch_exchange_rates(source \\ exchange_rates_source()) do |
|
|
|
|
|
|
|
if(source == CoinMarketCap) do |
|
|
|
|
|
|
|
fetch_exchange_rates_from_paginable_source(source) |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
fetch_exchange_rates_request(source) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defp fetch_exchange_rates_from_paginable_source(source, page \\ 1) do |
|
|
|
|
|
|
|
case HTTPoison.get(source.source_url(page), headers()) do |
|
|
|
|
|
|
|
{:ok, %Response{body: body, status_code: 200}} -> |
|
|
|
|
|
|
|
cond do |
|
|
|
|
|
|
|
body =~ Explorer.coin() -> {:ok, source.format_data(body)} |
|
|
|
|
|
|
|
page == source.max_page_number -> {:error, "exchange rates not found for this network"} |
|
|
|
|
|
|
|
true -> fetch_exchange_rates_from_paginable_source(source, page + 1) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{:ok, %Response{body: body, status_code: status_code}} when status_code in 400..499 -> |
|
|
|
|
|
|
|
{:error, decode_json(body)["error"]} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{:error, %Error{reason: reason}} -> |
|
|
|
|
|
|
|
{:error, reason} |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defp fetch_exchange_rates_request(source) do |
|
|
|
case HTTPoison.get(source.source_url(), headers()) do |
|
|
|
case HTTPoison.get(source.source_url(), headers()) do |
|
|
|
{:ok, %Response{body: body, status_code: 200}} -> |
|
|
|
{:ok, %Response{body: body, status_code: 200}} -> |
|
|
|
{:ok, source.format_data(body)} |
|
|
|
{:ok, source.format_data(body)} |
|
|
@ -43,6 +69,8 @@ defmodule Explorer.ExchangeRates.Source do |
|
|
|
|
|
|
|
|
|
|
|
def to_decimal(nil), do: nil |
|
|
|
def to_decimal(nil), do: nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def to_decimal(%Decimal{} = value), do: value |
|
|
|
|
|
|
|
|
|
|
|
def to_decimal(value) when is_float(value) do |
|
|
|
def to_decimal(value) when is_float(value) do |
|
|
|
Decimal.from_float(value) |
|
|
|
Decimal.from_float(value) |
|
|
|
end |
|
|
|
end |
|
|
|