ecb_exchange_rates_api 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +9 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +118 -0
- data/Guardfile +34 -0
- data/LICENSE.txt +21 -0
- data/README.md +111 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ecb_exchange_rates_api.gemspec +42 -0
- data/lib/ecb_exchange_rates_api/client.rb +81 -0
- data/lib/ecb_exchange_rates_api/constants.rb +16 -0
- data/lib/ecb_exchange_rates_api/errors.rb +6 -0
- data/lib/ecb_exchange_rates_api/options.rb +41 -0
- data/lib/ecb_exchange_rates_api/result.rb +39 -0
- data/lib/ecb_exchange_rates_api/shared_methods/attributes.rb +27 -0
- data/lib/ecb_exchange_rates_api/shared_methods.rb +51 -0
- data/lib/ecb_exchange_rates_api/version.rb +5 -0
- data/lib/ecb_exchange_rates_api.rb +5 -0
- metadata +168 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6da5762fe7f7e48e41dd1b0e9f9acc87cce3eec9
|
4
|
+
data.tar.gz: a3446ca9eecdf2fac5f78ea861cad9001ee6805c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7ef18ee9cd2a3c4770bd57e1aa6f5eb7bad22e1f3fb891b9754f7582e6e57a486a875b057adb1fb81812c368b68f60c7394b578ecbe64808dd630a131e99cb04
|
7
|
+
data.tar.gz: dec49c2eeee01340ba59d41c272c1fafd99491ca92876bd75e5ec6d9d6a40907d8b24187cb267c95d4e8c6006d3ff4db5b1a28b01e24b63ca603342ef2e2afd9
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
|
4
|
+
Metrics/BlockLength:
|
5
|
+
Exclude:
|
6
|
+
- 'spec/**/*'
|
7
|
+
- 'ecb_exchange_rates_api.gemspec'
|
8
|
+
|
9
|
+
Style/Documentation:
|
10
|
+
Exclude:
|
11
|
+
- 'spec/**/*'
|
12
|
+
|
13
|
+
Style/StringLiterals:
|
14
|
+
EnforcedStyle: double_quotes
|
15
|
+
|
16
|
+
Layout/LineLength:
|
17
|
+
Max: 120
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ecb_exchange_rates_api (0.1.0)
|
5
|
+
activesupport
|
6
|
+
httparty
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (5.2.4.1)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 0.7, < 2)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
tzinfo (~> 1.1)
|
16
|
+
addressable (2.7.0)
|
17
|
+
public_suffix (>= 2.0.2, < 5.0)
|
18
|
+
ast (2.4.0)
|
19
|
+
coderay (1.1.2)
|
20
|
+
concurrent-ruby (1.1.5)
|
21
|
+
crack (0.4.3)
|
22
|
+
safe_yaml (~> 1.0.0)
|
23
|
+
diff-lcs (1.3)
|
24
|
+
ffi (1.11.3)
|
25
|
+
formatador (0.2.5)
|
26
|
+
guard (2.16.1)
|
27
|
+
formatador (>= 0.2.4)
|
28
|
+
listen (>= 2.7, < 4.0)
|
29
|
+
lumberjack (>= 1.0.12, < 2.0)
|
30
|
+
nenv (~> 0.1)
|
31
|
+
notiffany (~> 0.0)
|
32
|
+
pry (>= 0.9.12)
|
33
|
+
shellany (~> 0.0)
|
34
|
+
thor (>= 0.18.1)
|
35
|
+
guard-compat (1.2.1)
|
36
|
+
guard-rspec (4.7.3)
|
37
|
+
guard (~> 2.1)
|
38
|
+
guard-compat (~> 1.1)
|
39
|
+
rspec (>= 2.99.0, < 4.0)
|
40
|
+
hashdiff (1.0.0)
|
41
|
+
httparty (0.17.3)
|
42
|
+
mime-types (~> 3.0)
|
43
|
+
multi_xml (>= 0.5.2)
|
44
|
+
i18n (1.8.1)
|
45
|
+
concurrent-ruby (~> 1.0)
|
46
|
+
jaro_winkler (1.5.4)
|
47
|
+
listen (3.2.1)
|
48
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
49
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
50
|
+
lumberjack (1.1.1)
|
51
|
+
method_source (0.9.2)
|
52
|
+
mime-types (3.3.1)
|
53
|
+
mime-types-data (~> 3.2015)
|
54
|
+
mime-types-data (3.2019.1009)
|
55
|
+
minitest (5.13.0)
|
56
|
+
multi_xml (0.6.0)
|
57
|
+
nenv (0.3.0)
|
58
|
+
notiffany (0.1.3)
|
59
|
+
nenv (~> 0.1)
|
60
|
+
shellany (~> 0.0)
|
61
|
+
parallel (1.19.1)
|
62
|
+
parser (2.7.0.2)
|
63
|
+
ast (~> 2.4.0)
|
64
|
+
pry (0.12.2)
|
65
|
+
coderay (~> 1.1.0)
|
66
|
+
method_source (~> 0.9.0)
|
67
|
+
public_suffix (4.0.3)
|
68
|
+
rainbow (3.0.0)
|
69
|
+
rb-fsevent (0.10.3)
|
70
|
+
rb-inotify (0.10.1)
|
71
|
+
ffi (~> 1.0)
|
72
|
+
rspec (3.9.0)
|
73
|
+
rspec-core (~> 3.9.0)
|
74
|
+
rspec-expectations (~> 3.9.0)
|
75
|
+
rspec-mocks (~> 3.9.0)
|
76
|
+
rspec-core (3.9.1)
|
77
|
+
rspec-support (~> 3.9.1)
|
78
|
+
rspec-expectations (3.9.0)
|
79
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
80
|
+
rspec-support (~> 3.9.0)
|
81
|
+
rspec-mocks (3.9.1)
|
82
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
83
|
+
rspec-support (~> 3.9.0)
|
84
|
+
rspec-support (3.9.2)
|
85
|
+
rubocop (0.79.0)
|
86
|
+
jaro_winkler (~> 1.5.1)
|
87
|
+
parallel (~> 1.10)
|
88
|
+
parser (>= 2.7.0.1)
|
89
|
+
rainbow (>= 2.2.2, < 4.0)
|
90
|
+
ruby-progressbar (~> 1.7)
|
91
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
92
|
+
ruby-progressbar (1.10.1)
|
93
|
+
safe_yaml (1.0.5)
|
94
|
+
shellany (0.0.1)
|
95
|
+
thor (1.0.1)
|
96
|
+
thread_safe (0.3.6)
|
97
|
+
tzinfo (1.2.6)
|
98
|
+
thread_safe (~> 0.1)
|
99
|
+
unicode-display_width (1.6.0)
|
100
|
+
vcr (5.0.0)
|
101
|
+
webmock (3.7.6)
|
102
|
+
addressable (>= 2.3.6)
|
103
|
+
crack (>= 0.3.2)
|
104
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
105
|
+
|
106
|
+
PLATFORMS
|
107
|
+
ruby
|
108
|
+
|
109
|
+
DEPENDENCIES
|
110
|
+
ecb_exchange_rates_api!
|
111
|
+
guard-rspec
|
112
|
+
rspec
|
113
|
+
rubocop
|
114
|
+
vcr
|
115
|
+
webmock
|
116
|
+
|
117
|
+
BUNDLED WITH
|
118
|
+
2.0.2
|
data/Guardfile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A sample Guardfile
|
4
|
+
# More info at https://github.com/guard/guard#readme
|
5
|
+
|
6
|
+
## Uncomment and set this to only include directories you want to watch
|
7
|
+
# directories %w(app lib config test spec features) \
|
8
|
+
# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
9
|
+
|
10
|
+
## Note: if you are using the `directories` clause above and you are not
|
11
|
+
## watching the project directory ('.'), then you will want to move
|
12
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
13
|
+
#
|
14
|
+
# $ mkdir config
|
15
|
+
# $ mv Guardfile config/
|
16
|
+
# $ ln -s config/Guardfile .
|
17
|
+
#
|
18
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
19
|
+
|
20
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
21
|
+
# rspec may be run, below are examples of the most common uses.
|
22
|
+
# * bundler: 'bundle exec rspec'
|
23
|
+
# * bundler binstubs: 'bin/rspec'
|
24
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
25
|
+
# installed the spring binstubs per the docs)
|
26
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
27
|
+
# * 'just' rspec: 'rspec'
|
28
|
+
#
|
29
|
+
guard :rspec, cmd: "rspec" do
|
30
|
+
watch(%r{^spec/.+_spec\.rb$})
|
31
|
+
watch(%r{^spec/*/.+_spec\.rb$})
|
32
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
33
|
+
watch("spec/spec_helper.rb") { "spec" }
|
34
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Roman Ovcharov
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# ECBExchangeRatesApi
|
2
|
+
|
3
|
+
This is an unofficial wrapper for the awesome, free ExchangeRatesAPI, which provides exchange rate lookups courtesy of the European Central Bank.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'ecb_exchange_rates_api'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install ecb_exchange_rates_api
|
20
|
+
|
21
|
+
## Getting Started
|
22
|
+
|
23
|
+
Since the CurrencyExchangeAPI does not require API keys or authentication in order to access and interrogate its API, getting started with this library is easy. The following examples show how to achieve various functions using the library.
|
24
|
+
|
25
|
+
### Basic usage:
|
26
|
+
|
27
|
+
Fetch the latest exchange rates from the European Central Bank:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
query = ECBExchangeRatesApi::Client.new
|
31
|
+
query.fetch
|
32
|
+
```
|
33
|
+
|
34
|
+
###Historical data:
|
35
|
+
|
36
|
+
Get historical rates for any day since 1999:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
query.at("2010-09-21").fetch
|
40
|
+
```
|
41
|
+
|
42
|
+
or specify some date range:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
query.from("2010-09-21").to("2010-10-21").fetch
|
46
|
+
```
|
47
|
+
|
48
|
+
### Set the base currency:
|
49
|
+
|
50
|
+
By default, the base currency is set to Euro (EUR), but it can be changed:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
query.with_base("USD").fetch
|
54
|
+
```
|
55
|
+
|
56
|
+
currency code should be passed as an ISO 4217 code.
|
57
|
+
|
58
|
+
### Fetch specific rates:
|
59
|
+
If you do not want all current rates, it's possible to specify only the currencies you want using `for_rate(symbol)` or `for_rates(array_of_symbols)`. The following code fetches only the exchange rate between GBP and EUR:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
query.with_base("GBP").for_rate("EUR").fetch
|
63
|
+
```
|
64
|
+
|
65
|
+
Please refer to the [API website](https://exchangeratesapi.io/) for further information and full API docs.
|
66
|
+
|
67
|
+
### Supported Currencies:
|
68
|
+
|
69
|
+
The library supports any currency currently available on the European Central Bank's web service, which at the time of the latest release are as follows:
|
70
|
+
|
71
|
+
![](https://www.ecb.europa.eu/shared/img/flags/AUD.gif) Australian Dollar (AUD)<br />
|
72
|
+
![](https://www.ecb.europa.eu/shared/img/flags/BRL.gif) Brazilian Real (BRL)<br />
|
73
|
+
![](https://www.ecb.europa.eu/shared/img/flags/GBP.gif) British Pound Sterline (GBP)<br />
|
74
|
+
![](https://www.ecb.europa.eu/shared/img/flags/BGN.gif) Bulgarian Lev (BGN)<br />
|
75
|
+
![](https://www.ecb.europa.eu/shared/img/flags/CAD.gif) Canadian Dollar (CAD)<br />
|
76
|
+
![](https://www.ecb.europa.eu/shared/img/flags/CNY.gif) Chinese Yuan Renminbi (CNY)<br />
|
77
|
+
![](https://www.ecb.europa.eu/shared/img/flags/HRK.gif) Croatian Kuna (HRK)<br />
|
78
|
+
![](https://www.ecb.europa.eu/shared/img/flags/CZK.gif) Czech Koruna (CZK)<br />
|
79
|
+
![](https://www.ecb.europa.eu/shared/img/flags/DKK.gif) Danish Krone (DKK)<br />
|
80
|
+
![](https://www.ecb.europa.eu/shared/img/flags/EUR.gif) Euro (EUR)<br />
|
81
|
+
![](https://www.ecb.europa.eu/shared/img/flags/HKD.gif) Hong Kong Dollar (HKD)<br />
|
82
|
+
![](https://www.ecb.europa.eu/shared/img/flags/HUF.gif) Hungarian Forint (HUF)<br />
|
83
|
+
![](https://www.ecb.europa.eu/shared/img/flags/ISK.gif) Icelandic Krona (ISK)<br />
|
84
|
+
![](https://www.ecb.europa.eu/shared/img/flags/IDR.gif) Indonesian Rupiah (IDR)<br />
|
85
|
+
![](https://www.ecb.europa.eu/shared/img/flags/INR.gif) Indian Rupee (INR)<br />
|
86
|
+
![](https://www.ecb.europa.eu/shared/img/flags/ILS.gif) Israeli Shekel (ILS)<br />
|
87
|
+
![](https://www.ecb.europa.eu/shared/img/flags/JPY.gif) Japanese Yen (JPY)<br />
|
88
|
+
![](https://www.ecb.europa.eu/shared/img/flags/MYR.gif) Malaysian Ringgit (MYR)<br />
|
89
|
+
![](https://www.ecb.europa.eu/shared/img/flags/MXN.gif) Mexican Peso (MXN)<br />
|
90
|
+
![](https://www.ecb.europa.eu/shared/img/flags/NZD.gif) New Zealand Dollar (NZD)<br />
|
91
|
+
![](https://www.ecb.europa.eu/shared/img/flags/NOK.gif) Norwegian Krone (NOK)<br />
|
92
|
+
![](https://www.ecb.europa.eu/shared/img/flags/PHP.gif) Philippine Peso (PHP)<br />
|
93
|
+
![](https://www.ecb.europa.eu/shared/img/flags/PLN.gif) Polish Zloty (PLN)<br />
|
94
|
+
![](https://www.ecb.europa.eu/shared/img/flags/RON.gif) Romanian Leu (RON)<br />
|
95
|
+
![](https://www.ecb.europa.eu/shared/img/flags/RUB.gif) Russian Rouble (RUB)<br />
|
96
|
+
![](https://www.ecb.europa.eu/shared/img/flags/SGD.gif) Singapore Dollar (SGD)<br />
|
97
|
+
![](https://www.ecb.europa.eu/shared/img/flags/ZAR.gif) South African Rand (ZAR)<br />
|
98
|
+
![](https://www.ecb.europa.eu/shared/img/flags/KRW.gif) South Korean Won (KRW)<br />
|
99
|
+
![](https://www.ecb.europa.eu/shared/img/flags/SEK.gif) Swedish Krona (SEK)<br />
|
100
|
+
![](https://www.ecb.europa.eu/shared/img/flags/CHF.gif) Swiss Franc (CHF)<br />
|
101
|
+
![](https://www.ecb.europa.eu/shared/img/flags/THB.gif) Thai Baht (THB)<br />
|
102
|
+
![](https://www.ecb.europa.eu/shared/img/flags/TRY.gif) Turkish Lira (TRY)<br />
|
103
|
+
![](https://www.ecb.europa.eu/shared/img/flags/USD.gif) US Dollar (USD)<br />
|
104
|
+
|
105
|
+
## Contributing
|
106
|
+
|
107
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/overchind/ECBExchangeRatesApi. This project is intended to be a safe, welcoming space for collaboration.
|
108
|
+
|
109
|
+
## License
|
110
|
+
|
111
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "ecb_exchange_rates_api"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/ecb_exchange_rates_api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ecb_exchange_rates_api"
|
7
|
+
spec.version = ECBExchangeRatesApi::VERSION
|
8
|
+
spec.authors = ["Roman Ovcharov"]
|
9
|
+
spec.email = ["overchind@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Client library for ExchangeRates API"
|
12
|
+
spec.description = <<-DESCRIPTION
|
13
|
+
This is an unofficial wrapper for the awesome, free ExchangeRatesAPI,
|
14
|
+
which provides exchange rate lookups courtesy of the Central European Bank."
|
15
|
+
DESCRIPTION
|
16
|
+
spec.homepage = "https://github.com/overchind/ExchangeRatesAPI"
|
17
|
+
spec.license = "MIT"
|
18
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
19
|
+
|
20
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
21
|
+
|
22
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
# The `git ls-files -z`
|
26
|
+
# loads the files in the RubyGem that have been added into git.
|
27
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
28
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
|
+
end
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
spec.add_dependency "activesupport"
|
35
|
+
spec.add_dependency "httparty"
|
36
|
+
|
37
|
+
spec.add_development_dependency "guard-rspec"
|
38
|
+
spec.add_development_dependency "rspec"
|
39
|
+
spec.add_development_dependency "rubocop"
|
40
|
+
spec.add_development_dependency "vcr"
|
41
|
+
spec.add_development_dependency "webmock"
|
42
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ecb_exchange_rates_api/options"
|
4
|
+
require "ecb_exchange_rates_api/shared_methods"
|
5
|
+
require "forwardable"
|
6
|
+
require "httparty"
|
7
|
+
|
8
|
+
module ECBExchangeRatesApi
|
9
|
+
# Client. Provides ways for different configurations.
|
10
|
+
class Client
|
11
|
+
include SharedMethods
|
12
|
+
include ::HTTParty
|
13
|
+
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
def_delegators :@options, :start_at, :end_at, :specific_date, :base, :symbols
|
17
|
+
|
18
|
+
base_uri "https://api.exchangeratesapi.io"
|
19
|
+
format :json
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@options = ECBExchangeRatesApi::Options.new
|
23
|
+
yield self if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
def fetch
|
27
|
+
response = self.class.get(path, query: options.to_params)
|
28
|
+
ECBExchangeRatesApi::Result.new(response.parsed_response, status: response.code)
|
29
|
+
end
|
30
|
+
|
31
|
+
def from(date)
|
32
|
+
@options.start_at = date
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def to(date)
|
37
|
+
@options.end_at = date
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def at(date)
|
42
|
+
@options.specific_date = date
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_base(code)
|
47
|
+
@options.base = code
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def for_rates(codes)
|
52
|
+
codes.each(&method(:for_rate))
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def for_rate(code)
|
57
|
+
@options.append_symbol(code)
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def currency_is_supported?(code)
|
62
|
+
supported_currency?(validated_currency_code(code))
|
63
|
+
end
|
64
|
+
|
65
|
+
def supported_currencies
|
66
|
+
CURRENCIES
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
attr_reader :options
|
72
|
+
|
73
|
+
def path
|
74
|
+
return "/#{specific_date}" if specific_date
|
75
|
+
|
76
|
+
return "/history" if start_at && end_at
|
77
|
+
|
78
|
+
"/latest"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ECBExchangeRatesApi
|
4
|
+
module Constants
|
5
|
+
CURRENCIES = %w[USD GBP EUR JPY BGN CZK DKK HUF PLN RON
|
6
|
+
SEK CHF ISK NOK HRK RUB TRY AUD BRL CAD
|
7
|
+
CNY HKD IDR ILS INR KRW MXN MYR NZD PHP
|
8
|
+
SGD THB ZAR].freeze
|
9
|
+
|
10
|
+
CURRENCY_REGEXP = /^[A-Z]{3}$/.freeze
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/LineLength
|
13
|
+
DATE_REGEXP = /^[0-9]{4}-((([13578]|0[13578]|(10|12))-([1-9]|0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|(([469]|0[469]|11)-([1-9]|0[1-9]|[1-2][0-9]|30)))$/.freeze
|
14
|
+
# rubocop:enable Metrics/LineLength
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ecb_exchange_rates_api/shared_methods"
|
4
|
+
|
5
|
+
module ECBExchangeRatesApi
|
6
|
+
# Presents API params
|
7
|
+
class Options
|
8
|
+
include SharedMethods
|
9
|
+
|
10
|
+
attr_reader :start_at, :end_at, :specific_date, :base, :symbols
|
11
|
+
date_attr_writer :start_at, :end_at, :specific_date
|
12
|
+
code_attr_writer :base
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@start_at = nil
|
16
|
+
@end_at = nil
|
17
|
+
@specific_date = nil
|
18
|
+
@base = nil
|
19
|
+
@symbols = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def append_symbol(code)
|
23
|
+
@symbols << validated_currency_code(code)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_params
|
27
|
+
options_params.reject { |_, val| val.nil? || val.empty? }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def options_params
|
33
|
+
instance_variables.each_with_object({}) do |var, hash|
|
34
|
+
key = var.to_s[1..-1].to_sym
|
35
|
+
variable = instance_variable_get(var)
|
36
|
+
value = key == :symbols ? variable&.join(",") : variable
|
37
|
+
hash[key] = value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash"
|
4
|
+
|
5
|
+
module ECBExchangeRatesApi
|
6
|
+
# Wrapper for HTTParty response object
|
7
|
+
class Result
|
8
|
+
attr_reader :data, :status
|
9
|
+
|
10
|
+
def initialize(data, status: 200)
|
11
|
+
data = {} unless data.is_a?(Hash)
|
12
|
+
|
13
|
+
@status = status
|
14
|
+
@data = OpenStruct.new(data.with_indifferent_access)
|
15
|
+
end
|
16
|
+
|
17
|
+
def success?
|
18
|
+
status == 200
|
19
|
+
end
|
20
|
+
|
21
|
+
def error?
|
22
|
+
!success?
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def method_missing(method_name, *arguments, &block)
|
28
|
+
if @data.respond_to?(method_name)
|
29
|
+
@data.send(method_name, *arguments, &block)
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def respond_to_missing?(method_name, include_private = false)
|
36
|
+
@data.respond_to?(method_name) || super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ECBExchangeRatesApi
|
4
|
+
# Presents API params
|
5
|
+
module SharedMethods
|
6
|
+
# ::nodoc::
|
7
|
+
module Attributes
|
8
|
+
private
|
9
|
+
|
10
|
+
def date_attr_writer(*attr_names)
|
11
|
+
attr_names.each do |attr_name|
|
12
|
+
define_method("#{attr_name}=") do |date|
|
13
|
+
instance_variable_set("@#{attr_name}", represent_date(date))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def code_attr_writer(*attr_names)
|
19
|
+
attr_names.each do |attr_name|
|
20
|
+
define_method("#{attr_name}=") do |code|
|
21
|
+
instance_variable_set("@#{attr_name}", validated_currency_code(code))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ecb_exchange_rates_api/shared_methods/attributes"
|
4
|
+
require "ecb_exchange_rates_api/constants"
|
5
|
+
require "ecb_exchange_rates_api/errors"
|
6
|
+
|
7
|
+
module ECBExchangeRatesApi
|
8
|
+
# ::nodoc::
|
9
|
+
module SharedMethods
|
10
|
+
extend SharedMethods::Attributes
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.send :extend, SharedMethods::Attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def represent_date(date)
|
19
|
+
return date.strftime("%Y-%m-%d") if time_or_date_instance?(date)
|
20
|
+
|
21
|
+
return date if date.is_a?(String) && date =~ ECBExchangeRatesApi::Constants::DATE_REGEXP
|
22
|
+
|
23
|
+
raise InvalidDateFormatError, date
|
24
|
+
end
|
25
|
+
|
26
|
+
def time_or_date_instance?(instance)
|
27
|
+
instance.is_a?(Date) || instance.is_a?(Time)
|
28
|
+
end
|
29
|
+
|
30
|
+
def validated_currency_code(code)
|
31
|
+
currency = sanitize_currency_code(code)
|
32
|
+
raise InvalidCurrencyCodeError, "Ivalid code format #{code}" unless valid_currency_code_format?(currency)
|
33
|
+
|
34
|
+
raise InvalidCurrencyCodeError, "Unsupported currency #{code}" unless supported_currency?(currency)
|
35
|
+
|
36
|
+
currency
|
37
|
+
end
|
38
|
+
|
39
|
+
def supported_currency?(currency)
|
40
|
+
ECBExchangeRatesApi::Constants::CURRENCIES.include?(currency)
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid_currency_code_format?(currency_code)
|
44
|
+
!currency_code.nil? && currency_code =~ ECBExchangeRatesApi::Constants::CURRENCY_REGEXP
|
45
|
+
end
|
46
|
+
|
47
|
+
def sanitize_currency_code(code)
|
48
|
+
code&.strip&.upcase
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ecb_exchange_rates_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roman Ovcharov
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-rspec
|
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: rspec
|
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: rubocop
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: vcr
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: |2
|
112
|
+
This is an unofficial wrapper for the awesome, free ExchangeRatesAPI,
|
113
|
+
which provides exchange rate lookups courtesy of the Central European Bank."
|
114
|
+
email:
|
115
|
+
- overchind@gmail.com
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".rspec"
|
122
|
+
- ".rubocop.yml"
|
123
|
+
- ".travis.yml"
|
124
|
+
- Gemfile
|
125
|
+
- Gemfile.lock
|
126
|
+
- Guardfile
|
127
|
+
- LICENSE.txt
|
128
|
+
- README.md
|
129
|
+
- Rakefile
|
130
|
+
- bin/console
|
131
|
+
- bin/setup
|
132
|
+
- ecb_exchange_rates_api.gemspec
|
133
|
+
- lib/ecb_exchange_rates_api.rb
|
134
|
+
- lib/ecb_exchange_rates_api/client.rb
|
135
|
+
- lib/ecb_exchange_rates_api/constants.rb
|
136
|
+
- lib/ecb_exchange_rates_api/errors.rb
|
137
|
+
- lib/ecb_exchange_rates_api/options.rb
|
138
|
+
- lib/ecb_exchange_rates_api/result.rb
|
139
|
+
- lib/ecb_exchange_rates_api/shared_methods.rb
|
140
|
+
- lib/ecb_exchange_rates_api/shared_methods/attributes.rb
|
141
|
+
- lib/ecb_exchange_rates_api/version.rb
|
142
|
+
homepage: https://github.com/overchind/ExchangeRatesAPI
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
metadata:
|
146
|
+
allowed_push_host: https://rubygems.org
|
147
|
+
homepage_uri: https://github.com/overchind/ExchangeRatesAPI
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 2.3.0
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 2.5.1
|
165
|
+
signing_key:
|
166
|
+
specification_version: 4
|
167
|
+
summary: Client library for ExchangeRates API
|
168
|
+
test_files: []
|