custom_currency 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0b72dd400d3130ffd71a28334e87e94f64f4f7ef
4
+ data.tar.gz: 9b84dbbfed117f25d67237144175a8b101904dc7
5
+ SHA512:
6
+ metadata.gz: d3d2d72bc9ddba2213992a86776f4b0e7d27f104b4edbcfbf1953c868fbf766e983fcb6bb8644fe8620fc7549ec0f475c4862ba8cb0269bbd4f80b72fe26e2ee
7
+ data.tar.gz: 12850c710164c0923984d493a2bcb02317dbca82fe5bbf127f19c6f2e4b0b72efe876cc181381f52ba9dd7fd2271743af21b788b8b94f2e2c2a7539020af3621
@@ -0,0 +1,100 @@
1
+ require 'money'
2
+ require 'money/rates_store/data_support'
3
+ require 'open-uri'
4
+
5
+ class Money
6
+ module Bank
7
+ class CustomCurrency < Money::Bank::VariableExchange
8
+ ECB_RATES_URL = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'.freeze
9
+ GOOGLE_RATES_URL = 'finance.google.com'.freeze
10
+ GOOGLE_RATES_PATH = '/finance/converter'.freeze
11
+ YAHOO_RATES_URL = 'download.finance.yahoo.com'.freeze
12
+ YAHOO_RATES_PATH = '/d/quotes.csv'.freeze
13
+
14
+ def initialize(*)
15
+ super
16
+ @store.extend Money::RatesStore::DataSupport
17
+ @currency_string = nil
18
+ end
19
+
20
+ def get_rate(from, to)
21
+ from_iso_code = from.is_a?(Money::Currency) ? from.iso_code : from.to_s
22
+ to_iso_code = to.is_a?(Money::Currency) ? to.iso_code : to.to_s
23
+
24
+ g_rate = google_rate(from_iso_code, to_iso_code)
25
+ y_rate = yahoo_rate(from_iso_code, to_iso_code)
26
+ # We don't use euc_rate, I just leave this here
27
+ # because someday we can change to
28
+ # euc_rate = eu_central_rate(from, to)
29
+ g_rate ? g_rate : y_rate
30
+ end
31
+
32
+ def save_rates(cache, url = ECB_RATES_URL)
33
+ raise InvalidCache unless cache
34
+ File.open(cache, 'w') do |file|
35
+ io = open(url)
36
+ io.each_line { |line| file.puts line }
37
+ end
38
+ end
39
+
40
+ def update_rates(cache, url = ECB_RATES_URL)
41
+ rates_source = cache.nil? ? url : cache
42
+ rates = Nokogiri::XML(open(rates_source)).
43
+ xpath('gesmes:Envelope/xmlns:Cube/xmlns:Cube//xmlns:Cube')
44
+
45
+ store.transaction true do
46
+ rates.each do |exchange_rate|
47
+ rate = BigDecimal(exchange_rate.attribute('rate').value)
48
+ currency = exchange_rate.attribute('currency').value
49
+ set_rate('EUR', currency, rate)
50
+ end
51
+ set_rate('EUR', 'EUR', 1)
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def google_rate(from, to)
58
+ query = "a=1&from=#{from}&to=#{to}"
59
+ uri = build_uri(GOOGLE_RATES_URL, GOOGLE_RATES_PATH, query)
60
+ rate = extract_rate(uri.read)
61
+ rate = (1 / extract_rate(uri.read)) if rate < 0.1
62
+
63
+ rate
64
+ rescue => ex
65
+ Logger.new(STDOUT).error("[CurrencyExchange][GOOGLE] #{ex.message}")
66
+ return nil
67
+ end
68
+
69
+ def yahoo_rate(from, to)
70
+ query = "s=#{from}#{to}=X&f=l1"
71
+ uri = build_uri(YAHOO_RATES_URL, YAHOO_RATES_PATH, query)
72
+
73
+ uri.read.to_d
74
+ rescue => ex
75
+ Logger.new(STDOUT).error("[CurrencyExchange][YAHOO] #{ex.message}")
76
+ return nil
77
+ end
78
+
79
+ def eu_central_rate(from, to)
80
+ from_base_rate = store.get_rate('EUR', from)
81
+ to_base_rate = store.get_rate('EUR', to)
82
+
83
+ to_base_rate / from_base_rate
84
+ end
85
+
86
+ def build_uri(url, path, query)
87
+ URI::HTTP.build(host: url, path: path, query: query)
88
+ end
89
+
90
+ def extract_rate(data)
91
+ case data
92
+ when %r{<span class=bld>(\d+\.?\d*) [A-Z]{3}<\/span}
93
+ BigDecimal(Regexp.last_match(1))
94
+ when /Could not convert\./
95
+ raise UnknownRate
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,60 @@
1
+ class Money
2
+ module RatesStore
3
+ module DataSupport
4
+ INDEX_DATE_SEPARATOR = '_AT_'.freeze
5
+
6
+ def add_rate(currency_iso_from, currency_iso_to, rate, date = nil)
7
+ transaction do
8
+ index[rate_key_for(currency_iso_from, currency_iso_to, date)] = rate
9
+ end
10
+ end
11
+
12
+ def get_rate(currency_iso_from, currency_iso_to, date = nil)
13
+ transaction do
14
+ index[rate_key_for(currency_iso_from, currency_iso_to, date)]
15
+ end
16
+ end
17
+
18
+ def transaction(force_sync = false, &block)
19
+ if @mutex.respond_to?(:owned?)
20
+ force_sync = false if @mutex.locked? && @mutex.owned?
21
+ else
22
+ force_sync = false
23
+ end
24
+
25
+ if !force_sync && (@in_transaction || options[:without_mutex])
26
+ yield self
27
+ else
28
+ @mutex.synchronize do
29
+ @in_transaction = true
30
+ result = yield
31
+ @in_transaction = false
32
+ result
33
+ end
34
+ end
35
+ end
36
+
37
+ def each_rate(&block)
38
+ enum = Enumerator.new do |yielder|
39
+ index.each do |key, rate|
40
+ iso_from, iso_to = key.split(Memory::INDEX_KEY_SEPARATOR)
41
+ iso_to, date = iso_to.split(INDEX_DATE_SEPARATOR)
42
+ date = Date.parse(date) if date
43
+ yielder.yield iso_from, iso_to, rate, date
44
+ end
45
+ end
46
+
47
+ block_given? ? enum.each(&block) : enum
48
+ end
49
+
50
+ private
51
+
52
+ def rate_key_for(currency_iso_from, currency_iso_to, date = nil)
53
+ key = [currency_iso_from, currency_iso_to].
54
+ join(Memory::INDEX_KEY_SEPARATOR)
55
+ key = [key, date.to_s].join(INDEX_DATE_SEPARATOR) if date
56
+ key.upcase
57
+ end
58
+ end
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: custom_currency
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Giordano Alves
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: money
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6.7'
27
+ description: Extends Money::Bank::VariableExchange and gives you access to the current
28
+ exchange rates of various providers
29
+ email: giordanofalves@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/bank/custom_currency.rb
35
+ - lib/rates_store/data_support.rb
36
+ homepage: https://github.com/giordanofalves/custom_currency
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.2.2
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Custom Currency!
60
+ test_files: []