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 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
@@ -0,0 +1,5 @@
1
+ require_relative 'historic_bank_rates/rates'
2
+
3
+ module HistoricBankRates
4
+ VERSION = '0.2.0'
5
+ 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: []