currency-rate 1.5.4 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. metadata +9 -122
  3. data/.document +0 -5
  4. data/.gitignore +0 -22
  5. data/.rspec +0 -1
  6. data/Gemfile +0 -6
  7. data/LICENSE.txt +0 -20
  8. data/README.md +0 -73
  9. data/Rakefile +0 -34
  10. data/api_keys.yml.sample +0 -4
  11. data/bin/rake +0 -29
  12. data/bin/rspec +0 -29
  13. data/currency-rate.gemspec +0 -41
  14. data/lib/adapter.rb +0 -66
  15. data/lib/adapters/crypto/binance_adapter.rb +0 -42
  16. data/lib/adapters/crypto/bitfinex_adapter.rb +0 -40
  17. data/lib/adapters/crypto/bitpay_adapter.rb +0 -29
  18. data/lib/adapters/crypto/bitstamp_adapter.rb +0 -26
  19. data/lib/adapters/crypto/btc_china_adapter.rb +0 -11
  20. data/lib/adapters/crypto/btc_e_adapter.rb +0 -18
  21. data/lib/adapters/crypto/coin_market_cap_adapter.rb +0 -31
  22. data/lib/adapters/crypto/coinbase_adapter.rb +0 -30
  23. data/lib/adapters/crypto/exmo_adapter.rb +0 -27
  24. data/lib/adapters/crypto/huobi_adapter.rb +0 -17
  25. data/lib/adapters/crypto/kraken_adapter.rb +0 -46
  26. data/lib/adapters/crypto/localbitcoins_adapter.rb +0 -25
  27. data/lib/adapters/crypto/okcoin_adapter.rb +0 -19
  28. data/lib/adapters/crypto/yadio_adapter.rb +0 -19
  29. data/lib/adapters/fiat/bonbast_adapter.rb +0 -25
  30. data/lib/adapters/fiat/coinmonitor_adapter.rb +0 -14
  31. data/lib/adapters/fiat/currency_layer_adapter.rb +0 -32
  32. data/lib/adapters/fiat/fixer_adapter.rb +0 -18
  33. data/lib/adapters/fiat/forge_adapter.rb +0 -25
  34. data/lib/adapters/fiat/free_forex_adapter.rb +0 -32
  35. data/lib/adapters/fiat/yahoo_adapter.rb +0 -35
  36. data/lib/configuration.rb +0 -29
  37. data/lib/currency_rate.rb +0 -84
  38. data/lib/currency_rate/version.rb +0 -3
  39. data/lib/fetcher.rb +0 -78
  40. data/lib/storage/file_storage.rb +0 -29
  41. data/lib/storage/serializers/yaml_serializer.rb +0 -15
  42. data/lib/synchronizer.rb +0 -51
@@ -1,19 +0,0 @@
1
- module CurrencyRate
2
- class YadioAdapter < Adapter
3
- SUPPORTED_CURRENCIES = %w(VES)
4
-
5
- ANCHOR_CURRENCY = "BTC"
6
-
7
- FETCH_URL = "https://api.yadio.io/rate/BTC"
8
-
9
- def normalize(data)
10
- return nil unless super
11
-
12
- {
13
- "anchor" => ANCHOR_CURRENCY,
14
- "USD" => BigDecimal(data["usd"].to_s),
15
- "VES" => BigDecimal(data["rate"].to_s),
16
- }
17
- end
18
- end
19
- end
@@ -1,25 +0,0 @@
1
- module CurrencyRate
2
- class BonbastAdapter < Adapter
3
- # No need to use it for fetching, just additional information about supported currencies
4
- SUPPORTED_CURRENCIES = %w(USD IRR)
5
- ANCHOR_CURRENCY = "USD"
6
- FETCH_URL = "https://www.bonbast.com/"
7
-
8
- def normalize(data)
9
- sell = data.match(/<td id="usd1"[^>]*>(\d+)<\/td>/)[1].to_f
10
- buy = data.match(/<td id="usd2"[^>]*>(\d+)<\/td>/)[1].to_f
11
- { "anchor" => self.class::ANCHOR_CURRENCY, "IRR" => BigDecimal(([buy, sell].reduce(:+).fdiv(2)*10).to_s) }
12
- end
13
-
14
- def request(url)
15
-
16
- http_client = HTTP.timeout(connect:
17
- CurrencyRate.configuration.connect_timeout, read:
18
- CurrencyRate.configuration.read_timeout
19
- )
20
- http_client.get(url).to_s
21
-
22
- end
23
-
24
- end
25
- end
@@ -1,14 +0,0 @@
1
- module CurrencyRate
2
- class CoinmonitorAdapter < Adapter
3
- # No need to use it for fetching, just additional information about supported currencies
4
- SUPPORTED_CURRENCIES = %w(ARS)
5
- ANCHOR_CURRENCY = "USD"
6
- FETCH_URL = "https://ar.coinmonitor.info/api/dolar_ar/"
7
-
8
- def normalize(data)
9
- return nil unless super
10
-
11
- { "anchor" => ANCHOR_CURRENCY }.merge({ SUPPORTED_CURRENCIES.first => BigDecimal(data["DOL_blue"].to_s) })
12
- end
13
- end
14
- end
@@ -1,32 +0,0 @@
1
- module CurrencyRate
2
- class CurrencyLayerAdapter < Adapter
3
- # No need to use it for fetching, just additional information about supported currencies
4
- SUPPORTED_CURRENCIES = %w(
5
- AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN
6
- BHD BIF BMD BND BOB BRL BSD BTC BTN BWP BYN BYR BZD CAD
7
- CDF CHF CLF CLP CNY COP CRC CUC CUP CVE CZK DJF DKK DOP
8
- DZD EGP ERN ETB EUR FJD FKP GBP GEL GGP GHS GIP GMD GNF
9
- GTQ GYD HKD HNL HRK HTG HUF IDR ILS IMP INR IQD IRR ISK
10
- JEP JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK
11
- LBP LKR LRD LSL LTL LVL LYD MAD MDL MGA MKD MMK MNT MOP
12
- MRO MUR MVR MWK MXN MYR MZN NAD NGN NIO NOK NPR NZD OMR
13
- PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD
14
- SCR SDG SEK SGD SHP SLL SOS SRD STD SVC SYP SZL THB TJS
15
- TMT TND TOP TRY TTD TWD TZS UAH UGX USD UYU UZS VEF VND
16
- VUV WST XAF XAG XAU XCD XDR XOF XPF YER ZAR ZMK ZMW ZWL
17
- )
18
-
19
- ANCHOR_CURRENCY = "USD"
20
- FETCH_URL = "http://www.apilayer.net/api/live"
21
- API_KEY_PARAM = "access_key"
22
-
23
- def normalize(data)
24
- return nil unless super
25
- rates = { "anchor" => self.class::ANCHOR_CURRENCY }
26
- data["quotes"].each do |key, value|
27
- rates[key.sub(self.class::ANCHOR_CURRENCY, "")] = BigDecimal(value.to_s)
28
- end
29
- rates
30
- end
31
- end
32
- end
@@ -1,18 +0,0 @@
1
- module CurrencyRate
2
- class FixerAdapter < Adapter
3
- # EUR is the only currency available as a base on free plan
4
- ANCHOR_CURRENCY = "EUR"
5
- FETCH_URL = "http://data.fixer.io/latest"
6
- API_KEY_PARAM = "access_key"
7
-
8
- def normalize(data)
9
- return nil unless super
10
- rates = { "anchor" => ANCHOR_CURRENCY }
11
- data["rates"].each do |k, v|
12
- rates[k] = BigDecimal(v.to_s)
13
- end
14
- rates
15
- end
16
-
17
- end
18
- end
@@ -1,25 +0,0 @@
1
- module CurrencyRate
2
- class ForgeAdapter < Adapter
3
- SUPPORTED_CURRENCIES = %w(
4
- JPY CHF CAD SEK NOK MXN ZAR TRY CNH EUR GBP AUD NZD XAU XAG
5
- )
6
-
7
- ANCHOR_CURRENCY = "USD"
8
- FETCH_URL = "https://forex.1forge.com/1.0.2/quotes?pairs=" + SUPPORTED_CURRENCIES.map { |c| "#{ANCHOR_CURRENCY}#{c}" }.join(",")
9
- API_KEY_PARAM = "api_key"
10
-
11
- def normalize(data)
12
- return nil unless super
13
- rates = { "anchor" => self.class::ANCHOR_CURRENCY }
14
- data.each do |rate|
15
- if rate["error"]
16
- CurrencyRate.logger.error("Forge exchange returned error")
17
- return nil
18
- end
19
- rates[rate["symbol"].sub(self.class::ANCHOR_CURRENCY, "")] = BigDecimal(rate["price"].to_s)
20
- end
21
- rates
22
- end
23
-
24
- end
25
- end
@@ -1,32 +0,0 @@
1
- module CurrencyRate
2
- class FreeForexAdapter < Adapter
3
- SUPPORTED_CURRENCIES = %w(
4
- AED AFN ALL AMD ANG AOA ARS ATS AUD AWG AZM AZN BAM BBD BDT
5
- BEF BGN BHD BIF BMD BND BOB BRL BSD BTN BWP BYN BYR BZD CAD
6
- CDF CLP CNH CNY COP CRC CUC CUP CVE CYP CZK DEM DJF DKK DOP
7
- DZD EEK EGP ERN ESP ETB EUR FIM FJD FKP FRF GBP GEL GGP GHC
8
- GHS GIP GMD GNF GRD GTQ GYD HKD HNL HRK HTG HUF IDR IEP ILS
9
- IMP INR IQD IRR ISK ITL JEP JMD JOD KES KGS KHR KMF KPW KRW
10
- KWD KYD KZT LAK LBP LKR LRD LSL LTL LUF LVL LYD MAD MDL MGA
11
- MGF MKD MMK MNT MOP MRO MRU MTL MUR MVR MWK MXN MYR MZM MZN
12
- NAD NGN NIO NLG NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PTE
13
- PYG QAR ROL RON RSD RUB RWF SAR SBD SCR SDD SDG SEK SGD SHP
14
- SIT SKK SLL SOS SPL SRD SRG STD STN SVC SYP SZL THB TJS TMM
15
- TMT TND TOP TRL TRY TTD TVD TWD TZS UAH UGX UYU UZS VAL VEB
16
- VEF VES VND VUV WST XAF XAG XAU XBT XCD XDR XOF XPD XPF XPT
17
- YER ZAR ZMK ZMW ZWD
18
- )
19
-
20
- ANCHOR_CURRENCY = "USD"
21
- FETCH_URL = "https://www.freeforexapi.com/api/live?pairs=" + SUPPORTED_CURRENCIES.map{|cur| "USD#{cur}"}.join(",")
22
-
23
- def normalize(data)
24
- return nil unless super
25
- rates = { "anchor" => self.class::ANCHOR_CURRENCY }
26
- data["rates"].each do |pair, payload|
27
- rates[pair.sub(self.class::ANCHOR_CURRENCY, "")] = BigDecimal(payload["rate"].to_s)
28
- end
29
- rates
30
- end
31
- end
32
- end
@@ -1,35 +0,0 @@
1
- module CurrencyRate
2
- class YahooAdapter < Adapter
3
- SUPPORTED_CURRENCIES = %w(
4
- AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND
5
- BRL BSD BTN BWP BYR BZD CAD CHF CLF CLP CNY COP CRC CUC CUP CVE CZK DEM
6
- DJF DKK DOP DZD ECS EGP ERN ETB EUR FJD FKP FRF GBP GEL GHS GIP GMD GNF
7
- GTQ GYD HKD HNL HRK HTG HUF IDR IEP ILS INR IQD ISK ITL JMD JOD JPY KES
8
- KGS KHR KMF KWD KYD KZT LAK LBP LKR LRD LSL LTL LVL LYD MAD MGA MMK MNT
9
- MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN
10
- PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SLL SOS
11
- SRD STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD UAH UGX USD UYU UZS VND
12
- VUV WST XAF XAG XAU XCD XDR XOF XPD XPF XPT YER ZAR ZMW ZWL
13
- )
14
-
15
- ANCHOR_CURRENCY = "USD"
16
-
17
- FETCH_URL = "http://query.yahooapis.com/v1/public/yql?" + URI.encode_www_form(
18
- format: 'json',
19
- env: "store://datatables.org/alltableswithkeys",
20
- q: "SELECT * FROM yahoo.finance.xchange WHERE pair IN" +
21
- # The following line is building array string in SQL: '("USDJPY", "USDRUB", ...)'
22
- "(#{SUPPORTED_CURRENCIES.map{|x| '"' + ANCHOR_CURRENCY + x.upcase + '"'}.join(',')})"
23
- )
24
-
25
- def normalize(data)
26
- return nil unless super
27
- rates = { "anchor" => self.class::ANCHOR_CURRENCY }
28
- data["query"]["results"]["rate"].each do |rate|
29
- rates[rate["Name"].split("/")[1]] = BigDecimal(rate["Rate"].to_s)
30
- end
31
- rates
32
- end
33
-
34
- end
35
- end
data/lib/configuration.rb DELETED
@@ -1,29 +0,0 @@
1
- module CurrencyRate
2
- class Configuration
3
- attr_accessor :api_keys
4
- attr_accessor :file_storage
5
- attr_accessor :logger
6
- attr_accessor :crypto_adapters
7
- attr_accessor :fiat_adapters
8
- attr_accessor :connect_timeout
9
- attr_accessor :read_timeout
10
- attr_accessor :limit_sources_for_fiat_currencies
11
- attr_accessor :crypto_currencies
12
-
13
- def initialize
14
- @api_keys = { }
15
- @file_storage = { path: "" }
16
- @logger = {
17
- device: $stdout,
18
- level: :info,
19
- formatter: nil,
20
- }
21
- @crypto_adapters = CurrencyRate.adapters :crypto
22
- @fiat_adapters = CurrencyRate.adapters :fiat
23
- @connect_timeout = 4
24
- @read_timeout = 4
25
- @limit_sources_for_fiat_currencies = {}
26
- @crypto_currencies = []
27
- end
28
- end
29
- end
data/lib/currency_rate.rb DELETED
@@ -1,84 +0,0 @@
1
- require "bigdecimal"
2
- require "logger"
3
- require "singleton"
4
- require "json"
5
- require "http"
6
-
7
- require_relative "configuration"
8
- require_relative "adapter"
9
- require_relative "fetcher"
10
- require_relative "synchronizer"
11
-
12
- Dir["#{File.expand_path __dir__}/adapters/**/*.rb"].each { |f| require f }
13
- Dir["#{File.expand_path __dir__}/storage/**/*.rb"].each { |f| require f }
14
-
15
- module CurrencyRate
16
- class << self
17
- attr_writer :configuration
18
- end
19
-
20
- def self.method_missing(m, *args, &block)
21
- if m.to_s.end_with? "_adapters"
22
- self.send(:adapters, m[0..-10])
23
- else
24
- super
25
- end
26
- end
27
-
28
- def self.adapters(type)
29
- Dir[File.join self.root, "lib/adapters/#{type}/*"].map do |file|
30
- File.basename(file, ".rb").split('_')[0...-1].map {|w| w.capitalize}.join
31
- end
32
- end
33
-
34
- def self.configuration
35
- @configuration ||= Configuration.new
36
- end
37
-
38
- def self.configure
39
- yield(configuration)
40
- end
41
-
42
- def self.fetcher
43
- @fetcher ||= Fetcher.new(fiat_exchanges: configuration.fiat_adapters,
44
- crypto_exchanges: configuration.crypto_adapters,
45
- limit_sources_for_fiat_currencies: configuration.limit_sources_for_fiat_currencies)
46
- end
47
-
48
- def self.fetch_crypto(exchange, from, to)
49
- fetcher.fetch_crypto(exchange, from, to)
50
- end
51
-
52
- def self.fetch_fiat(from, to)
53
- fetcher.fetch_fiat(from, to)
54
- end
55
-
56
- def self.logger
57
- return @logger if @logger
58
- @logger = Logger.new(configuration.logger[:device])
59
- @logger.progname = "CurrencyRate"
60
- @logger.level = configuration.logger[:level]
61
- @logger.formatter = configuration.logger[:formatter] if configuration.logger[:formatter]
62
- @logger
63
- end
64
-
65
- def self.synchronizer
66
- @synchronizer ||= Synchronizer.new
67
- end
68
-
69
- def self.sync_crypto!
70
- synchronizer.sync_crypto!
71
- end
72
-
73
- def self.sync_fiat!
74
- synchronizer.sync_fiat!
75
- end
76
-
77
- def self.sync!
78
- synchronizer.sync!
79
- end
80
-
81
- def self.root
82
- File.expand_path("../", File.dirname(__FILE__))
83
- end
84
- end
@@ -1,3 +0,0 @@
1
- module CurrencyRate
2
- VERSION = "1.5.4"
3
- end
data/lib/fetcher.rb DELETED
@@ -1,78 +0,0 @@
1
- module CurrencyRate
2
- class Fetcher
3
- attr_accessor :storage
4
- attr_accessor :fiat_exchanges
5
- attr_accessor :crypto_exchanges
6
- attr_accessor :limit_sources_for_fiat_currencies
7
-
8
- def initialize(fiat_exchanges: nil, crypto_exchanges: nil, storage: nil, limit_sources_for_fiat_currencies: {})
9
- @storage = storage || FileStorage.new
10
- @fiat_exchanges = fiat_exchanges || ["Yahoo", "Fixer", "Forge"]
11
- @crypto_exchanges = crypto_exchanges || ["Bitstamp", "Binance"]
12
- @limit_sources_for_fiat_currencies = limit_sources_for_fiat_currencies
13
- end
14
-
15
- def fetch_crypto(exchange, from, to)
16
- from = from.strip.upcase
17
- to = to.strip.upcase
18
- rates = @storage.read(exchange)
19
-
20
- if rates.nil?
21
- CurrencyRate.logger.warn("Fetcher#fetch_crypto: rates for #{exchange} not found in storage <#{@storage.class.name}>")
22
- return nil
23
- end
24
-
25
- rate = calculate_rate(rates, from, to)
26
- return rate unless rate.nil?
27
-
28
- if to != "USD"
29
- usd_fiat = fetch_fiat("USD", to)
30
- return BigDecimal(rates["USD"] * usd_fiat) if usd_fiat && rates["USD"]
31
- end
32
- nil
33
- end
34
-
35
- def fetch_fiat(from, to)
36
- from = from.strip.upcase
37
- to = to.strip.upcase
38
-
39
- exchanges = @fiat_exchanges.dup
40
- exchanges += @crypto_exchanges if is_crypto_currency?(from) || is_crypto_currency?(to)
41
-
42
- if(@limit_sources_for_fiat_currencies[from])
43
- exchanges.select! { |ex| @limit_sources_for_fiat_currencies[from].include?(ex) }
44
- end
45
- if(@limit_sources_for_fiat_currencies[to])
46
- exchanges.select! { |ex| @limit_sources_for_fiat_currencies[to].include?(ex) }
47
- end
48
-
49
- exchanges.each do |exchange|
50
- rates = @storage.read(exchange)
51
- next if rates.nil?
52
-
53
- rate = calculate_rate(rates, from, to)
54
- return rate unless rate.nil?
55
- end
56
- nil
57
- end
58
-
59
- private
60
-
61
- def calculate_rate(rates, from, to)
62
- anchor = rates.delete("anchor")
63
-
64
- return BigDecimal(rates[to]) if anchor == from && rates[to]
65
- return BigDecimal(1 / rates[from]) if anchor == to && rates[from]
66
- return BigDecimal(rates[to] / rates[from]) if rates[from] && rates[to]
67
-
68
- CurrencyRate.logger.warn("Fetcher: rate for #{from}_#{to} not found.")
69
- nil
70
- end
71
-
72
- def is_crypto_currency?(currency)
73
- CurrencyRate.configuration.crypto_currencies.include?(currency)
74
- end
75
-
76
- end
77
- end
78
-
@@ -1,29 +0,0 @@
1
- module CurrencyRate
2
- class FileStorage
3
- attr_reader :path
4
- attr_accessor :serializer
5
-
6
- def initialize(path = nil, serializer: nil)
7
- @path = path || CurrencyRate.configuration.file_storage[:path]
8
- @serializer = serializer || Storage::YAMLSerializer.new
9
- end
10
-
11
- def read(exchange_name)
12
- path = path_for exchange_name.downcase
13
- @serializer.deserialize File.read(path)
14
- rescue StandardError => e
15
- CurrencyRate.logger.error(e)
16
- nil
17
- end
18
-
19
- def write(exchange_name, data = "")
20
- File.write path_for(exchange_name.downcase), @serializer.serialize(data)
21
- rescue StandardError => e
22
- CurrencyRate.logger.error(e)
23
- end
24
-
25
- def path_for(exchange_name)
26
- File.join @path, "#{exchange_name}_rates.yml"
27
- end
28
- end
29
- end