historic_bank_rates 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +72 -0
- data/lib/historic_bank_rates/bank_scrapers/bank_of_tanzania.rb +75 -0
- data/lib/historic_bank_rates/bank_scrapers/central_bank_of_kenya.rb +73 -0
- data/lib/historic_bank_rates/bank_scrapers/rate_scraper.rb +50 -0
- data/lib/historic_bank_rates/rates.rb +60 -0
- data/lib/historic_bank_rates.rb +5 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ec4e067c61d7a2a2019467a7fe7d4a67e5ebcd6b
|
4
|
+
data.tar.gz: b3c08906e498dfd73398d22c13d516ddac679ad3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d1b4b51374c3da98e47ee018f9179d86de3400dd2c7b2392f7f3683c41a273d8cba9aa3d9814cef8fb7c81c75f78afa6e0851380534f72845a5c310a3555cba
|
7
|
+
data.tar.gz: 87782f7295536eeda089bccc0363e45db7745c0f6f3561d0e0553206cee76d9dd10a76ef444e36c76f73facf5a2179215e1828cc3a6f44c1adc27a0de546eed0
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 mobisol
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Historic Bank Rates
|
2
|
+
[![Build Status](https://travis-ci.org/plugintheworld/historic_bank_rates.svg?branch=master)](https://travis-ci.org/plugintheworld/historic_bank_rates)
|
3
|
+
|
4
|
+
Wraps a simple scraper to retrieve the historic exchange rates. Returns the average rates for yesterday or any day specified and supported by the Central Bank of Kenya.
|
5
|
+
|
6
|
+
## Install
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'historic_bank_rates'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
$ bundle
|
18
|
+
```
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
$ gem install historic_bank_rates
|
24
|
+
```
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
### Initialize (NOTE: the date used can affect the success of the import! method)
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
scraper = HistoricBankRates::BankScraper::CentralBankOfKenya.new
|
32
|
+
hbr = HistoricBankRates::Rates.new(scraper, Date.new(2016, 05, 30))
|
33
|
+
hbr.import! # => true
|
34
|
+
```
|
35
|
+
|
36
|
+
import! returns true if rates have been found. Might also throw HTTP errors. It will also return false when requesting rates for weekend days.
|
37
|
+
|
38
|
+
Update an instance's import_date and rerun the import process:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
hbr.import!(Date.new(2015, 06, 30)) # => true
|
42
|
+
```
|
43
|
+
|
44
|
+
### Retrieve a specific rate
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
hbr.rate('KES', 'EUR') # => 112.2322
|
48
|
+
```
|
49
|
+
|
50
|
+
Get all available currencies:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
hbr.currencies # => ['ZAR', 'USD', 'EUR', 'RWF'… ]
|
54
|
+
```
|
55
|
+
|
56
|
+
Get all rates
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
hbr.rates # => { 'ZAR'=>6.4373, 'USD'=>100.6606, … }
|
60
|
+
```
|
61
|
+
|
62
|
+
## Legal
|
63
|
+
|
64
|
+
The author of this gem is not affiliated with any of the banks referenced/scraped by the gem.
|
65
|
+
|
66
|
+
### License
|
67
|
+
|
68
|
+
MIT, see LICENSE file
|
69
|
+
|
70
|
+
### No Warranty
|
71
|
+
|
72
|
+
The Software is provided "as is" without warranty of any kind, either express or implied, including without limitation any implied warranties of condition, uninterrupted use, merchantability, fitness for a particular purpose, or non-infringement.
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative 'rate_scraper.rb'
|
2
|
+
module HistoricBankRates
|
3
|
+
module BankScrapers
|
4
|
+
class BankOfTanzania < HistoricBankRates::BankScrapers::RateScraper
|
5
|
+
TRANSLATE = { 'Kenya SHS' => 'KES',
|
6
|
+
'Uganda SHS' => 'UGX',
|
7
|
+
'Rwandan Franc' => 'RWF',
|
8
|
+
'Burundi Franc' => 'BFI',
|
9
|
+
'USD' => 'USD',
|
10
|
+
'Pound STG' => 'GBP',
|
11
|
+
'EURO' => 'EUR',
|
12
|
+
'Canadian $' => 'CAD',
|
13
|
+
'Switz. Franc' => 'CHF',
|
14
|
+
'Japanese YEN' => 'JPY',
|
15
|
+
'Swedish Kronor' => 'SEK',
|
16
|
+
'Norweg. Kronor' => 'NOK',
|
17
|
+
'Danish Kronor' => 'DKK',
|
18
|
+
'Australian $' => 'AUD',
|
19
|
+
'Indian RPS' => 'INR',
|
20
|
+
'Pakistan RPS' => 'PKR',
|
21
|
+
'Zambian Kwacha' => 'ZAK',
|
22
|
+
'Malawian Kwacha' => 'MWK',
|
23
|
+
'Mozambique-MET' => 'MZN',
|
24
|
+
'Zimbabwe $' => 'ZWD',
|
25
|
+
'SDR' => 'XDR',
|
26
|
+
'S. African Rand' => 'ZAR',
|
27
|
+
'UAE Dirham' => 'AED',
|
28
|
+
'Singapore $' => 'SGD',
|
29
|
+
'Honk Kong $' => 'HKD',
|
30
|
+
'Saud Arabian Rial' => 'SAR',
|
31
|
+
'Kuwait Dinar' => 'KWD',
|
32
|
+
'Botswana Pula' => 'BWP',
|
33
|
+
'Chinese Yuan' => 'CNY',
|
34
|
+
'Malaysia Ringgit' => 'MYR',
|
35
|
+
'South Korea Won' => 'KRW',
|
36
|
+
'Newzealand' => 'NZD' }
|
37
|
+
|
38
|
+
def base_currency
|
39
|
+
'TZS'
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def rates
|
45
|
+
response = Net::HTTP.post_form(URI(form_url), form_params)
|
46
|
+
dom = Nokogiri::HTML(response.body)
|
47
|
+
rows = dom.css(element_matcher)
|
48
|
+
|
49
|
+
Hash[rows.map do |row|
|
50
|
+
currency = TRANSLATE[row.css(':nth-child(1) font').text.split.join(' ')]
|
51
|
+
buy = Float(row.css(':nth-child(3) font').text.delete(',', '')) rescue nil
|
52
|
+
sell = Float(row.css(':nth-child(4) font').text.delete(',', '')) rescue nil
|
53
|
+
next if currency.nil? || buy.nil? || sell.nil?
|
54
|
+
|
55
|
+
# average of by and sell, divide by 100 b/c conversion is given in 100 units
|
56
|
+
[currency, (buy + sell) / 200]
|
57
|
+
end.compact]
|
58
|
+
end
|
59
|
+
|
60
|
+
def form_url
|
61
|
+
@form_url ||= 'http://www.bot-tz.org/FinancialMarkets/ExchangeRates/ShowExchangeRates.asp'
|
62
|
+
end
|
63
|
+
|
64
|
+
def form_params
|
65
|
+
{
|
66
|
+
'SelectedExchandeDate' => start_date.strftime('%m/%d/%y')
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def element_matcher
|
71
|
+
'#table1 > tr > td > table > tr > td > div > table > tr > td > table > tr'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative 'rate_scraper.rb'
|
2
|
+
|
3
|
+
module HistoricBankRates
|
4
|
+
module BankScrapers
|
5
|
+
class CentralBankOfKenya < HistoricBankRates::BankScrapers::RateScraper
|
6
|
+
TRANSLATE = { 'US DOLLAR' => 'USD',
|
7
|
+
'STG POUND' => 'GBP',
|
8
|
+
'EURO' => 'EUR',
|
9
|
+
'SA RAND' => 'ZAR',
|
10
|
+
'KES / USHS' => 'UGX',
|
11
|
+
'KES / TSHS' => 'TZS',
|
12
|
+
'KES / RWF' => 'RWF',
|
13
|
+
'KES / BIF' => 'BIF',
|
14
|
+
'AE DIRHAM' => 'AED',
|
15
|
+
'CAN $' => 'CAD',
|
16
|
+
'S FRANC' => 'CHF',
|
17
|
+
'JPY (100)' => 'JPY',
|
18
|
+
'SW KRONER' => 'SEK',
|
19
|
+
'NOR KRONER' => 'NOK',
|
20
|
+
'DAN KRONER' => 'DKK',
|
21
|
+
'IND RUPEE' => 'INR',
|
22
|
+
'HONGKONG DOLLAR' => 'HKD',
|
23
|
+
'SINGAPORE DOLLAR' => 'SGD',
|
24
|
+
'SAUDI RIYAL' => 'SAR',
|
25
|
+
'CHINESE YUAN' => 'CNY',
|
26
|
+
'AUSTRALIAN $' => 'AUD' }
|
27
|
+
|
28
|
+
def base_currency
|
29
|
+
'KES'
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def rates
|
35
|
+
response = Net::HTTP.post_form(URI(form_url), form_params)
|
36
|
+
dom = Nokogiri::HTML(response.body)
|
37
|
+
rows = dom.css(element_matcher)
|
38
|
+
|
39
|
+
Hash[rows.map do |row|
|
40
|
+
currency = TRANSLATE[row.css(':nth-child(2)').text]
|
41
|
+
next if currency.nil?
|
42
|
+
next if currency.empty?
|
43
|
+
avrg = row.css(':nth-child(5)').text
|
44
|
+
next if avrg.nil?
|
45
|
+
next if avrg.empty?
|
46
|
+
|
47
|
+
[currency, Float(avrg)] rescue nil
|
48
|
+
end.compact]
|
49
|
+
end
|
50
|
+
|
51
|
+
def form_url
|
52
|
+
@form_url ||= 'https://www.centralbank.go.ke/index.php/rate-and-statistics/exchange-rates-2'
|
53
|
+
end
|
54
|
+
|
55
|
+
def form_params
|
56
|
+
{
|
57
|
+
'date' => start_date.strftime('%d'),
|
58
|
+
'month' => start_date.strftime('%m').upcase,
|
59
|
+
'year' => start_date.strftime('%Y'),
|
60
|
+
'tdate' => start_date.strftime('%d'),
|
61
|
+
'tmonth' => start_date.strftime('%m').upcase,
|
62
|
+
'tyear' => start_date.strftime('%Y'),
|
63
|
+
'currency' => '',
|
64
|
+
'searchForex' => 'Search'
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def element_matcher
|
69
|
+
'#cont1 > #cont3 > div.item-page > #interbank > table > tr > td > table > tr'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'uri'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
module HistoricBankRates
|
6
|
+
module BankScrapers
|
7
|
+
class RateScraper
|
8
|
+
TRANSLATE = {}
|
9
|
+
|
10
|
+
attr_reader :start_date
|
11
|
+
attr_accessor :form_url
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
end
|
15
|
+
|
16
|
+
def call start_date
|
17
|
+
@start_date = start_date
|
18
|
+
|
19
|
+
rates
|
20
|
+
end
|
21
|
+
|
22
|
+
def base_currency
|
23
|
+
# Must implement
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def rates
|
30
|
+
# Must implement
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
def form_url
|
35
|
+
# Must implement
|
36
|
+
raise NotImplementedError
|
37
|
+
end
|
38
|
+
|
39
|
+
def form_params
|
40
|
+
# Must implement
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
def element_matcher
|
45
|
+
# Must implement
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'date'
|
2
|
+
require_relative 'bank_scrapers/central_bank_of_kenya'
|
3
|
+
require_relative 'bank_scrapers/bank_of_tanzania'
|
4
|
+
|
5
|
+
module HistoricBankRates
|
6
|
+
class MissingRates < StandardError; end
|
7
|
+
class Rates
|
8
|
+
attr_reader :start_date
|
9
|
+
attr_accessor :rate_scraper
|
10
|
+
|
11
|
+
def initialize rate_scraper, start_date=nil
|
12
|
+
@rate_scraper = rate_scraper
|
13
|
+
@start_date = start_date || date_yesterday
|
14
|
+
end
|
15
|
+
|
16
|
+
def rate(iso_from, iso_to)
|
17
|
+
case rate_scraper.base_currency
|
18
|
+
when iso_from
|
19
|
+
rates[iso_to] ? 1/rates[iso_to] : nil
|
20
|
+
when iso_to
|
21
|
+
rates[iso_from]
|
22
|
+
else
|
23
|
+
fail_if_rates_missing
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns a list of ISO currencies
|
28
|
+
def currencies
|
29
|
+
rates.keys
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns all rates imported
|
33
|
+
def rates
|
34
|
+
fail_if_rates_missing
|
35
|
+
@rates
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns true when reading the website was successful
|
39
|
+
def has_rates?
|
40
|
+
@rates && @rates.any?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Triggers the scraping
|
44
|
+
def import! import_date=nil
|
45
|
+
@start_date = import_date unless import_date.nil?
|
46
|
+
@rates = rate_scraper.call(start_date)
|
47
|
+
has_rates?
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def date_yesterday
|
53
|
+
Date.today - 1
|
54
|
+
end
|
55
|
+
|
56
|
+
def fail_if_rates_missing
|
57
|
+
fail MissingRates unless has_rates?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: historic_bank_rates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Donkin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nyan-cat-formatter
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: vcr
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: |-
|
84
|
+
Wraps a simple scraper to retrieve the historic exchange
|
85
|
+
rates of specific banks. Returns the average (between buy
|
86
|
+
and sell) rates for any day specified (if date isn't
|
87
|
+
specified it defaults to yesterday).
|
88
|
+
email:
|
89
|
+
- alexander_donkin@yahoo.co.uk
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- LICENSE
|
95
|
+
- README.md
|
96
|
+
- lib/historic_bank_rates.rb
|
97
|
+
- lib/historic_bank_rates/bank_scrapers/bank_of_tanzania.rb
|
98
|
+
- lib/historic_bank_rates/bank_scrapers/central_bank_of_kenya.rb
|
99
|
+
- lib/historic_bank_rates/bank_scrapers/rate_scraper.rb
|
100
|
+
- lib/historic_bank_rates/rates.rb
|
101
|
+
homepage: http://github.com/plugintheworld/historic_bank_rates
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
metadata: {}
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 2.4.8
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: Scrapes various bank websites to generate a list of currencies and their
|
125
|
+
historic rates.
|
126
|
+
test_files: []
|