ccy_convertor 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 +15 -0
- data/.gitignore +14 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +166 -0
- data/Rakefile +1 -0
- data/ccy_convertor.gemspec +26 -0
- data/lib/ccy_convertor.rb +39 -0
- data/lib/ccy_convertor/configuration.rb +21 -0
- data/lib/ccy_convertor/constant.rb +187 -0
- data/lib/ccy_convertor/exception.rb +9 -0
- data/lib/ccy_convertor/extension.rb +5 -0
- data/lib/ccy_convertor/money.rb +21 -0
- data/lib/ccy_convertor/process_and_validate_option.rb +45 -0
- data/lib/ccy_convertor/rate_cache.rb +28 -0
- data/lib/ccy_convertor/rate_providers/json_rate.rb +13 -0
- data/lib/ccy_convertor/rate_providers/open_exchange_rate.rb +13 -0
- data/lib/ccy_convertor/rate_providers/rate_provider.rb +58 -0
- data/lib/ccy_convertor/rate_providers/yahoo_finance.rb +19 -0
- data/lib/ccy_convertor/version.rb +3 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZTYwZTU1NWIzNTZkOTE3N2EwMjdiYjllOTQ3ZjQzM2IzZWE1NmQxZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZWYyN2JmMjU3M2QxMTM4ZTRmZWU3OTNkMDBlNDg0OTkxMTM0MTVhMw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGJhMjAzYWJiMWQzYTcxM2ZlZDA4NDI0MjZkZDVmOTRmNzYxN2U3N2EzMTM4
|
10
|
+
ODdiOTEzMTUzZTdiYjk1NWZhNTRhNTEyYTk0ZjI5ZTg3OWQ4ZmM0MmYyNDc0
|
11
|
+
NDY0YTBkYjBjZmE1ZTkzOTBhMjEwODM1Y2FkOTU4NGE4Y2M0MmI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjRkODRkN2Q0NjFiMDYxNDRmMDE3MDZiNzg0ZTQwZmQ4MDY4ZTA3ZDY5NGEx
|
14
|
+
OWYyYWIxN2JkYWFiNzNjNThkZTVmNTk0OGQ2OGEzZWNjOGM3MGYwYWJmNjMz
|
15
|
+
NTgzMmFmMDNmNzk4NGI5ODEzYjljODczZjBmMzY4M2I2ZWI4Mzc=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Rohan Pujari
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# CcyConvertor
|
2
|
+
|
3
|
+
CcyConvertor provides live currency rate for various currencies and allows to convert money from one currency to other. Currently it supports 3 rate provider. New rate provider can be easily plugged in
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'ccy_convertor'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install ccy_convertor
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Once gem is installed you can find out exchange rate between currency as follows
|
24
|
+
```ruby
|
25
|
+
CcyConvertor.rate(from_ccy: 'USD', to_ccy: 'NZD') # will use default rate provider to get rate
|
26
|
+
```
|
27
|
+
Note: Default rate provider is CcyConvertor::YahooFinance. You can change default rate provider. Check [configuration section](#configuration)
|
28
|
+
|
29
|
+
Rate provider can also be provided as a parameter. Rate provider is a class which provides rate by using rest_api
|
30
|
+
```ruby
|
31
|
+
CcyConvertor.rate(from_ccy: 'USD', to_ccy: 'NZD', rate_provider: CcyConvertor::OpenExchangeRate)
|
32
|
+
CcyConvertor.rate(from_ccy: 'USD', to_ccy: 'NZD', rate_provider: CcyConvertor::JSONRates)
|
33
|
+
```
|
34
|
+
You can also directly use rate provider class as follows.
|
35
|
+
```ruby
|
36
|
+
CcyConvertor::OpenExchangeRate.rate('USD', 'INR') # will return USD/INR rate
|
37
|
+
```
|
38
|
+
Note: CcyConvertor::OpenExchangeRate and CcyConvertor::JSONRate requires api_key. You can register at respective websites to get a api key
|
39
|
+
|
40
|
+
#### Rate Providers
|
41
|
+
| Rate provider class name | rest api source | Api key required |
|
42
|
+
|---|---|---|
|
43
|
+
| CcyConvertor::YahooFinance | 'yahoo.finance.xchange' table yql | no |
|
44
|
+
| CcyConvertor::OpenExchangeRate | www.openexchangerates.org | yes |
|
45
|
+
| CcyConvertor::JSONRate | www.jsonrates.com | yes |
|
46
|
+
|
47
|
+
Api key can be provided individually to this classes as
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
CcyConvertor::OpenExchangeRate.api_key = 'XXXXXXXXX'
|
51
|
+
CcyConvertor::OpenExchangeRate.api_key = 'XXXXXXXXX'
|
52
|
+
```
|
53
|
+
|
54
|
+
Also check [configuration section](#configuration) to know other ways to provide api_key to rate provider classes
|
55
|
+
|
56
|
+
You can convert money from one currency to another in following ways
|
57
|
+
Below code will use rate provided from www.openexchangerates.org
|
58
|
+
```ruby
|
59
|
+
CcyConvertor::OpenExchangeRate.convert(from_ccy: 'USD', to_ccy: 'NZD', amount: 10)
|
60
|
+
10.usd.to_nzd(rate_provider: Ccyconvertor::OpenExchangeRate)
|
61
|
+
```
|
62
|
+
|
63
|
+
Below code will use default rate provider. Default rate provider is configurable . Check [configuration section](#configuration)
|
64
|
+
```ruby
|
65
|
+
CcyConvertor.convert(from_ccy: 'USD', to_ccy: 'NZD', amount: 10)
|
66
|
+
10.usd.to_nzd
|
67
|
+
```
|
68
|
+
You can also get all the rates of currency with respect to particular base currency
|
69
|
+
```ruby
|
70
|
+
Ccyconvertor::OpenExchangeRate.rate_matrix
|
71
|
+
```
|
72
|
+
Above method will return hash with currency code as key and rate as value. All rates would be with respect to USD. OpenExchangeRate do not allow us to specify other base currency and USD is always the base currency.
|
73
|
+
|
74
|
+
For Ccyconvertor::JSONRate we can specify the base currency
|
75
|
+
```ruby
|
76
|
+
Ccyconvertor::OpenExchangeRate.rate_matrix('NZD')
|
77
|
+
```
|
78
|
+
All rates returned would be with respect to NZD. If no parameter is given then base currency is USD by default
|
79
|
+
Note: Ccyconvertor::YahooFinance do not support rate_matrix method
|
80
|
+
|
81
|
+
## Configuration
|
82
|
+
|
83
|
+
You can configure following parameters
|
84
|
+
|
85
|
+
1. default_rate-provider: Default rate provider is the rate provider which is used when no rate provider is species. Rate provider is a api service that this gem uses to provide rate. By default default rate provider is CcyConvertor::YahooFinance. Check rate providers details [here](#rate-providers)
|
86
|
+
|
87
|
+
2. api_keys: CcyConvertor::OpenExchangeRate and CcyConvertor::JSONRate provider requires api_key. You can register at there respective sites to get the api_key
|
88
|
+
|
89
|
+
3. cache_duration: specifies the time for which the response would be cached. By default this time is zero seconds i.e no caching is done by default. If cache_duration is 60 seconds and if you want a exchange rate of USD/INR multiple times in your application, request to rate provider would be made only once in 60 seconds and after 60 seconds next request would be made.
|
90
|
+
ActiveSupport::Cache is used for caching
|
91
|
+
|
92
|
+
4. roud_up_rate: This takes fixnum which tells number of decimal places to which the rate would be rounded to.
|
93
|
+
|
94
|
+
5. roud_up_amount: This takes fixnum which tells number of decimal places to which the rate would be rounded to.
|
95
|
+
|
96
|
+
Sample configuration:
|
97
|
+
```ruby
|
98
|
+
CcyConvertor.configure do |config|
|
99
|
+
config.round_up_rate = 4
|
100
|
+
config.round_up_amount = 4
|
101
|
+
config.default_rate_provider = CcyConvertor::JSONRate
|
102
|
+
config.api_keys = {
|
103
|
+
open_exchange_rate: 'XXXXXXXXX',
|
104
|
+
json_rate: 'XXXXXX'
|
105
|
+
}
|
106
|
+
config.cache_duration = {
|
107
|
+
open_exchange_rate: 20,
|
108
|
+
yahoo_finance: 30,
|
109
|
+
json_rate: 20
|
110
|
+
}
|
111
|
+
end
|
112
|
+
```
|
113
|
+
If you are using rails, above code can be pasted in config/initializers/ccy_convertor.rb
|
114
|
+
|
115
|
+
Note: api_keys and cache_duration expects hash. Hash key is name of the class without module name in a underscore format
|
116
|
+
|
117
|
+
## Adding new rate provider
|
118
|
+
|
119
|
+
Its simple to add a new rate provider. You can plug in any rate provider which provides rest api.
|
120
|
+
|
121
|
+
##### Steps for adding rate provider that support api call to get all rate in single api call:
|
122
|
+
|
123
|
+
1. Make a class with appropriate name inherit it from CccyConvertor::RateProvider
|
124
|
+
2. Add following class methods
|
125
|
+
```ruby
|
126
|
+
rest_url_for_rate_matrix(base_ccy=nil)
|
127
|
+
```
|
128
|
+
Above method should return rest api url to get rates of alll currencies.
|
129
|
+
```ruby
|
130
|
+
rate_matrix(base_ccy=nil)
|
131
|
+
```
|
132
|
+
Above method should return rates in hash format as
|
133
|
+
```ruby
|
134
|
+
{
|
135
|
+
'currency_code1' => rate with respect to base_ccy,
|
136
|
+
'currency_code2' => rate with respect to base_ccy
|
137
|
+
}
|
138
|
+
```
|
139
|
+
Note: currency_code should be in upper case
|
140
|
+
You can call ``` rate_matrix_response(base_ccy) ``` method inside ```rate_matrix(base_ccy)``` method to get response from url returned by ```rest_url_for_rate_matrix(base_ccy=nil)``` method
|
141
|
+
Once you get response from rate_matrix_response method you can convert it to response format as mentioned above
|
142
|
+
|
143
|
+
##### Steps for adding rate provider that does not support api call to get all rate in single api call:
|
144
|
+
|
145
|
+
1. Make a class with appropriate name inherit it from CccyConvertor::RateProvider
|
146
|
+
2. Add following class methods
|
147
|
+
```ruby
|
148
|
+
rest_url_for_rate(from_ccy, to_ccy)
|
149
|
+
```
|
150
|
+
Above method should return url for geting exchange rate between from_ccy and to_ccy
|
151
|
+
```ruby
|
152
|
+
rate(from_ccy, to_ccy)
|
153
|
+
```
|
154
|
+
Above method should return exchange rate(Numeric type) between from_ccy and to_ccy. You can call ```rate_response(from_ccy, to_ccy)``` inside ```rate(from_ccy, to_ccy)``` to get response from url returned by ```rest_url_for_rate(from_ccy, to_ccy)```
|
155
|
+
|
156
|
+
Now you can directly use new rate provider added by you as an existing rate provider present in the gem. You can also use all the cofiguration present for th rate provider. If rate provider added by you require api_key, you can provide it as metioned in configurtion section.
|
157
|
+
If you want to use api_key inside you rate provider class, you can use class method api_key to access it.
|
158
|
+
Check rate providers inside lib/rate_providers for more information
|
159
|
+
|
160
|
+
## Contributing
|
161
|
+
|
162
|
+
1. Fork it ( https://github.com/rohanpujaris/ccy_convertor/fork )
|
163
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
164
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
165
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
166
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ccy_convertor/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ccy_convertor"
|
8
|
+
spec.version = CcyConvertor::VERSION
|
9
|
+
spec.authors = ["Rohan Pujari"]
|
10
|
+
spec.email = ["rohanpujaris@gmail.com"]
|
11
|
+
spec.summary = %q{CcyConvertor provides live currency rate for various currencies and allows to convert money from one currency to other}
|
12
|
+
spec.description = %q{CcyConvertor provides live currency rate for various currencies and allows to convert money from one currency to other. Currently it supports 3 rate provider. New rate provider can be easily plugged in}
|
13
|
+
spec.homepage = "https://github.com/rohanpujaris/ccy_convertor"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "activesupport", ">= 3.0"
|
25
|
+
spec.add_runtime_dependency "httparty"
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'active_support/cache.rb'
|
3
|
+
require 'httparty'
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
require 'ccy_convertor/version'
|
7
|
+
require 'ccy_convertor/configuration'
|
8
|
+
require 'ccy_convertor/constant'
|
9
|
+
require 'ccy_convertor/extension'
|
10
|
+
require 'ccy_convertor/money'
|
11
|
+
require 'ccy_convertor/exception'
|
12
|
+
require 'ccy_convertor/rate_cache'
|
13
|
+
require 'ccy_convertor/process_and_validate_option'
|
14
|
+
require 'ccy_convertor/rate_providers/rate_provider'
|
15
|
+
require 'ccy_convertor/rate_providers/yahoo_finance'
|
16
|
+
require 'ccy_convertor/rate_providers/open_exchange_rate'
|
17
|
+
require 'ccy_convertor/rate_providers/json_rate'
|
18
|
+
|
19
|
+
module CcyConvertor
|
20
|
+
class << self
|
21
|
+
def rate(options)
|
22
|
+
RateProvider.process_options!(options)
|
23
|
+
RateProvider.validate_presence_of_hash_keys!(options, [:from_ccy, :to_ccy])
|
24
|
+
rate = rate_provider(options).rate(options[:to_ccy], options[:from_ccy])
|
25
|
+
return rate if CcyConvertor.configuration.round_up_rate.nil?
|
26
|
+
rate.to_f.round(CcyConvertor.configuration.round_up_rate)
|
27
|
+
end
|
28
|
+
|
29
|
+
def convert(options)
|
30
|
+
amount = rate_provider(options).convert(options)
|
31
|
+
return amount if CcyConvertor.configuration.round_up_amount.nil?
|
32
|
+
amount.to_f.round(CcyConvertor.configuration.round_up_amount)
|
33
|
+
end
|
34
|
+
|
35
|
+
def rate_provider(options)
|
36
|
+
options[:rate_provider] || CcyConvertor.configuration.default_rate_provider
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
class << self
|
3
|
+
attr_accessor :configuration
|
4
|
+
|
5
|
+
def configuration
|
6
|
+
@configuration ||= Configuration.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def configure
|
10
|
+
yield(configuration) if block_given?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Configuration
|
15
|
+
attr_accessor :round_up_rate, :round_up_amount, :api_keys, :default_rate_provider, :cache_duration
|
16
|
+
|
17
|
+
def default_rate_provider
|
18
|
+
@default_rate_provider || CcyConvertor::YahooFinance
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
module Constant
|
3
|
+
CCY_CODE_AND_NAME = {
|
4
|
+
'AED' => 'United Arab Emirates dirham',
|
5
|
+
'AFN' => 'Afghani',
|
6
|
+
'ALL' => 'Lek',
|
7
|
+
'AMD' => 'Armenian Dram',
|
8
|
+
'ANG' => 'Netherlands Antillian Guilder',
|
9
|
+
'AOA' => 'Kwanza',
|
10
|
+
'ARS' => 'Argentine Peso',
|
11
|
+
'AUD' => 'Australian Dollar',
|
12
|
+
'AWG' => 'Aruban Guilder',
|
13
|
+
'AZN' => 'Azerbaijanian Manat',
|
14
|
+
'BAM' => 'Convertible Marks',
|
15
|
+
'BBD' => 'Barbados Dollar',
|
16
|
+
'BDT' => 'Bangladeshi Taka',
|
17
|
+
'BGN' => 'Bulgarian Lev',
|
18
|
+
'BHD' => 'Bahraini Dinar',
|
19
|
+
'BIF' => 'Burundian Franc',
|
20
|
+
'BMD' => 'Bermudian Dollar (customarily known as Bermuda Dollar)',
|
21
|
+
'BND' => 'Brunei Dollar',
|
22
|
+
'BOB' => 'Boliviano',
|
23
|
+
'BOV' => 'Bolivian Mvdol (Funds code)',
|
24
|
+
'BRL' => 'Brazilian Real',
|
25
|
+
'BSD' => 'Bahamian Dollar',
|
26
|
+
'BTN' => 'Ngultrum',
|
27
|
+
'BWP' => 'Pula',
|
28
|
+
'BYR' => 'Belarussian Ruble',
|
29
|
+
'BZD' => 'Belize Dollar',
|
30
|
+
'CAD' => 'Canadian Dollar',
|
31
|
+
'CDF' => 'Franc Congolais',
|
32
|
+
'CHE' => 'WIR Euro (complementary currency)',
|
33
|
+
'CHF' => 'Swiss Franc',
|
34
|
+
'CHW' => 'WIR Franc (complementary currency)',
|
35
|
+
'CLF' => 'Unidades de formento (Funds code)',
|
36
|
+
'CLP' => 'Chilean Peso',
|
37
|
+
'CNY' => 'Yuan Renminbi',
|
38
|
+
'COP' => 'Colombian Peso',
|
39
|
+
'COU' => 'Unidad de Valor Real',
|
40
|
+
'CRC' => 'Costa Rican Colon',
|
41
|
+
'CUP' => 'Cuban Peso',
|
42
|
+
'CVE' => 'Cape Verde Escudo',
|
43
|
+
'CYP' => 'Cyprus Pound',
|
44
|
+
'CZK' => 'Czech Koruna',
|
45
|
+
'DJF' => 'Djibouti Franc',
|
46
|
+
'DKK' => 'Danish Krone',
|
47
|
+
'DOP' => 'Dominican Peso',
|
48
|
+
'DZD' => 'Algerian Dinar',
|
49
|
+
'EEK' => 'Kroon',
|
50
|
+
'EGP' => 'Egyptian Pound',
|
51
|
+
'ERN' => 'Nakfa',
|
52
|
+
'ETB' => 'Ethiopian Birr',
|
53
|
+
'EUR' => 'Euro',
|
54
|
+
'FJD' => 'Fiji Dollar',
|
55
|
+
'FKP' => 'Falkland Islands Pound',
|
56
|
+
'GBP' => 'Pound Sterling',
|
57
|
+
'GEL' => 'Lari',
|
58
|
+
'GHS' => 'Cedi',
|
59
|
+
'GIP' => 'Gibraltar pound',
|
60
|
+
'GMD' => 'Dalasi',
|
61
|
+
'GNF' => 'Guinea Franc',
|
62
|
+
'GTQ' => 'Quetzal',
|
63
|
+
'GYD' => 'Guyana Dollar',
|
64
|
+
'HKD' => 'Hong Kong Dollar',
|
65
|
+
'HNL' => 'Lempira',
|
66
|
+
'HRK' => 'Croatian Kuna',
|
67
|
+
'HTG' => 'Haiti Gourde',
|
68
|
+
'HUF' => 'Forint',
|
69
|
+
'IDR' => 'Rupiah',
|
70
|
+
'ILS' => 'New Israeli Shekel',
|
71
|
+
'INR' => 'Indian Rupee',
|
72
|
+
'IQD' => 'Iraqi Dinar',
|
73
|
+
'IRR' => 'Iranian Rial',
|
74
|
+
'ISK' => 'Iceland Krona',
|
75
|
+
'JMD' => 'Jamaican Dollar',
|
76
|
+
'JOD' => 'Jordanian Dinar',
|
77
|
+
'JPY' => 'Japanese yen',
|
78
|
+
'KES' => 'Kenyan Shilling',
|
79
|
+
'KGS' => 'Som',
|
80
|
+
'KHR' => 'Riel',
|
81
|
+
'KMF' => 'Comoro Franc',
|
82
|
+
'KPW' => 'North Korean Won',
|
83
|
+
'KRW' => 'South Korean Won',
|
84
|
+
'KWD' => 'Kuwaiti Dinar',
|
85
|
+
'KYD' => 'Cayman Islands Dollar',
|
86
|
+
'KZT' => 'Tenge',
|
87
|
+
'LAK' => 'Kip',
|
88
|
+
'LBP' => 'Lebanese Pound',
|
89
|
+
'LKR' => 'Sri Lanka Rupee',
|
90
|
+
'LRD' => 'Liberian Dollar',
|
91
|
+
'LSL' => 'Loti',
|
92
|
+
'LTL' => 'Lithuanian Litas',
|
93
|
+
'LVL' => 'Latvian Lats',
|
94
|
+
'LYD' => 'Libyan Dinar',
|
95
|
+
'MAD' => 'Moroccan Dirham',
|
96
|
+
'MDL' => 'Moldovan Leu',
|
97
|
+
'MGA' => 'Malagasy Ariary',
|
98
|
+
'MKD' => 'Denar',
|
99
|
+
'MMK' => 'Kyat',
|
100
|
+
'MNT' => 'Tugrik',
|
101
|
+
'MOP' => 'Pataca',
|
102
|
+
'MRO' => 'Ouguiya',
|
103
|
+
'MTL' => 'Maltese Lira',
|
104
|
+
'MUR' => 'Mauritius Rupee',
|
105
|
+
'MVR' => 'Rufiyaa',
|
106
|
+
'MWK' => 'Kwacha',
|
107
|
+
'MXN' => 'Mexican Peso',
|
108
|
+
'MXV' => 'Mexican Unidad de Inversion (UDI) (Funds code)',
|
109
|
+
'MYR' => 'Malaysian Ringgit',
|
110
|
+
'MZN' => 'Metical',
|
111
|
+
'NAD' => 'Namibian Dollar',
|
112
|
+
'NGN' => 'Naira',
|
113
|
+
'NIO' => 'Cordoba Oro',
|
114
|
+
'NOK' => 'Norwegian Krone',
|
115
|
+
'NPR' => 'Nepalese Rupee',
|
116
|
+
'NZD' => 'New Zealand Dollar',
|
117
|
+
'OMR' => 'Rial Omani',
|
118
|
+
'PAB' => 'Balboa',
|
119
|
+
'PEN' => 'Nuevo Sol',
|
120
|
+
'PGK' => 'Kina',
|
121
|
+
'PHP' => 'Philippine Peso',
|
122
|
+
'PKR' => 'Pakistan Rupee',
|
123
|
+
'PLN' => 'Zloty',
|
124
|
+
'PYG' => 'Guarani',
|
125
|
+
'QAR' => 'Qatari Rial',
|
126
|
+
'RON' => 'Romanian New Leu',
|
127
|
+
'RSD' => 'Serbian Dinar',
|
128
|
+
'RUB' => 'Russian Ruble',
|
129
|
+
'RWF' => 'Rwanda Franc',
|
130
|
+
'SAR' => 'Saudi Riyal',
|
131
|
+
'SBD' => 'Solomon Islands Dollar',
|
132
|
+
'SCR' => 'Seychelles Rupee',
|
133
|
+
'SDG' => 'Sudanese Pound',
|
134
|
+
'SEK' => 'Swedish Krona',
|
135
|
+
'SGD' => 'Singapore Dollar',
|
136
|
+
'SHP' => 'Saint Helena Pound',
|
137
|
+
'SKK' => 'Slovak Koruna',
|
138
|
+
'SLL' => 'Leone',
|
139
|
+
'SOS' => 'Somali Shilling',
|
140
|
+
'SRD' => 'Surinam Dollar',
|
141
|
+
'STD' => 'Dobra',
|
142
|
+
'SYP' => 'Syrian Pound',
|
143
|
+
'SZL' => 'Lilangeni',
|
144
|
+
'THB' => 'Baht',
|
145
|
+
'TJS' => 'Somoni',
|
146
|
+
'TMM' => 'Manat',
|
147
|
+
'TND' => 'Tunisian Dinar',
|
148
|
+
'TOP' => 'Pa\'anga',
|
149
|
+
'TRY' => 'New Turkish Lira',
|
150
|
+
'TTD' => 'Trinidad and Tobago Dollar',
|
151
|
+
'TWD' => 'New Taiwan Dollar',
|
152
|
+
'TZS' => 'Tanzanian Shilling',
|
153
|
+
'UAH' => 'Hryvnia',
|
154
|
+
'UGX' => 'Uganda Shilling',
|
155
|
+
'USD' => 'US Dollar',
|
156
|
+
'USN' => '',
|
157
|
+
'USS' => '',
|
158
|
+
'UYU' => 'Peso Uruguayo',
|
159
|
+
'UZS' => 'Uzbekistan Som',
|
160
|
+
'VEB' => 'Venezuelan bolivar',
|
161
|
+
'VND' => 'Vietnamese dong',
|
162
|
+
'VUV' => 'Vatu',
|
163
|
+
'WST' => 'Samoan Tala',
|
164
|
+
'XAF' => 'CFA Franc BEAC',
|
165
|
+
'XAG' => 'Silver (one Troy ounce)',
|
166
|
+
'XAU' => 'Gold (one Troy ounce)',
|
167
|
+
'XBA' => 'European Composite Unit (EURCO) (Bonds market unit)',
|
168
|
+
'XBB' => 'European Monetary Unit (E.M.U.-6) (Bonds market unit)',
|
169
|
+
'XBC' => 'European Unit of Account 9 (E.U.A.-9) (Bonds market unit)',
|
170
|
+
'XBD' => 'European Unit of Account 17 (E.U.A.-17) (Bonds market unit)',
|
171
|
+
'XCD' => 'East Caribbean Dollar',
|
172
|
+
'XDR' => 'Special Drawing Rights',
|
173
|
+
'XFO' => 'Gold franc (special settlement currency)',
|
174
|
+
'XFU' => 'UIC franc (special settlement currency)',
|
175
|
+
'XOF' => 'CFA Franc BCEAO',
|
176
|
+
'XPD' => 'Palladium (one Troy ounce)',
|
177
|
+
'XPF' => 'CFP franc',
|
178
|
+
'XPT' => 'Platinum (one Troy ounce)',
|
179
|
+
'XTS' => 'Code reserved for testing purposes',
|
180
|
+
'XXX' => 'No currency',
|
181
|
+
'YER' => 'Yemeni Rial',
|
182
|
+
'ZAR' => 'South African Rand',
|
183
|
+
'ZMK' => 'Kwacha',
|
184
|
+
'ZWD' => 'Zimbabwe Dollar'
|
185
|
+
}
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
class Money
|
3
|
+
attr_accessor :code, :name, :amount
|
4
|
+
|
5
|
+
def initialize(code, amount)
|
6
|
+
@code = code
|
7
|
+
@amount = amount
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
CcyConvertor::Constant::CCY_CODE_AND_NAME[code]
|
12
|
+
end
|
13
|
+
|
14
|
+
CcyConvertor::Constant::CCY_CODE_AND_NAME.each do |code, name|
|
15
|
+
define_method("to_#{code.downcase}") do |options = {}|
|
16
|
+
options.merge!(money: self, to_ccy: code)
|
17
|
+
CcyConvertor.convert(options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
module ProcessAndValidateOption
|
3
|
+
def process_options!(options)
|
4
|
+
unless options[:money].nil?
|
5
|
+
options.merge!(from_ccy: options[:money].code, amount: options[:money].amount)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate_options!(options)
|
10
|
+
validate_presence_of_hash_keys!(options, [:from_ccy, :to_ccy, :amount])
|
11
|
+
validate_amount!(options[:amount])
|
12
|
+
validate_currency_codes!([options[:from_ccy], options[:to_ccy]])
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_presence_of_hash_keys!(options, keys)
|
16
|
+
options_not_provided = keys - options.keys
|
17
|
+
if options_not_provided.count != 0
|
18
|
+
raise ArgumentError,
|
19
|
+
"argument hash should have #{options_not_provided.join(', ')} #{options_not_provided.count > 1 ? 'keys' : 'key'}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_amount!(amount)
|
24
|
+
unless amount.is_a?(Numeric)
|
25
|
+
raise CcyConvertor::InvalidAmount, 'options[:amount] must be a number'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate_currency_codes!(currency_codes)
|
30
|
+
currency_codes.each do |code|
|
31
|
+
unless CcyConvertor::Constant::CCY_CODE_AND_NAME[code]
|
32
|
+
raise CcyConvertor::InvalidCurrencyCode, "Currency code '#{code}' doesn't exists"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_currency_support!(currencies, rate_matrix)
|
38
|
+
currencies.each do |ccy|
|
39
|
+
if rate_matrix[ccy].nil?
|
40
|
+
raise CcyConvertor::CurrencyNotSupported, "Currency '#{ccy}' is not supported by OpenExchangeRate"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
module RateCache
|
3
|
+
attr_writer :cache_duration
|
4
|
+
|
5
|
+
def cache
|
6
|
+
@cache ||= {}
|
7
|
+
@cache[rate_provider_name] ||= ActiveSupport::Cache::MemoryStore.new(expires_in: cache_duration)
|
8
|
+
end
|
9
|
+
|
10
|
+
def cache_duration
|
11
|
+
@cache_duration ||= if cache_duration_nil?
|
12
|
+
0
|
13
|
+
else
|
14
|
+
CcyConvertor.configuration.cache_duration[rate_provider_name]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def cache_duration_nil?
|
19
|
+
@cache_duration.nil? &&
|
20
|
+
(CcyConvertor.configuration.cache_duration.nil? ||
|
21
|
+
CcyConvertor.configuration.cache_duration[rate_provider_name].nil?)
|
22
|
+
end
|
23
|
+
|
24
|
+
def cache_key(request_url)
|
25
|
+
Digest::SHA2.hexdigest request_url
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
class JSONRate < CcyConvertor::RateProvider
|
3
|
+
class << self
|
4
|
+
def rest_url_for_rate_matrix(base_ccy)
|
5
|
+
"http://jsonrates.com/get/?apiKey=#{api_key}&base=#{base_ccy || 'USD'}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def rate_matrix(base_ccy = nil)
|
9
|
+
JSON.parse(rate_matrix_response(base_ccy))['rates']
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
class OpenExchangeRate < CcyConvertor::RateProvider
|
3
|
+
class << self
|
4
|
+
def rest_url_for_rate_matrix(base_ccy = nil)
|
5
|
+
"https://openexchangerates.org/api/latest.json?app_id=#{api_key}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def rate_matrix
|
9
|
+
rate_matrix_response['rates']
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
class RateProvider
|
3
|
+
extend CcyConvertor::RateCache
|
4
|
+
extend CcyConvertor::ProcessAndValidateOption
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_writer :api_key
|
8
|
+
|
9
|
+
def api_key
|
10
|
+
if api_key_nil?
|
11
|
+
raise CcyConvertor::NoApiKeyPresent, "api_key not set for #{name}"
|
12
|
+
end
|
13
|
+
@api_key ||= CcyConvertor.configuration.api_keys[rate_provider_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def api_key_nil?
|
17
|
+
@api_key.nil? &&
|
18
|
+
(CcyConvertor.configuration.api_keys.nil? ||
|
19
|
+
CcyConvertor.configuration.api_keys[rate_provider_name].nil?)
|
20
|
+
end
|
21
|
+
|
22
|
+
def rate_provider_name
|
23
|
+
self.name.demodulize.underscore.to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def response_hash(request_url)
|
27
|
+
cache_key = cache_key(request_url)
|
28
|
+
return cache.read(cache_key) if cache.exist?(cache_key)
|
29
|
+
response = HTTParty.get(request_url).parsed_response
|
30
|
+
puts cache.write(cache_key, response, expires_in: cache_duration)
|
31
|
+
response
|
32
|
+
end
|
33
|
+
|
34
|
+
def rate_matrix_response(base_ccy = nil)
|
35
|
+
response_hash(rest_url_for_rate_matrix(base_ccy))
|
36
|
+
end
|
37
|
+
|
38
|
+
def rate_response(from_ccy, to_ccy)
|
39
|
+
response_hash(rest_url_for_rate(from_ccy, to_ccy))
|
40
|
+
end
|
41
|
+
|
42
|
+
def rate_from_rate_matrix(from_ccy, to_ccy)
|
43
|
+
rate_matrix = rate_matrix()
|
44
|
+
validate_currency_support!([from_ccy, to_ccy], rate_matrix)
|
45
|
+
rate_matrix[from_ccy].to_f / rate_matrix[to_ccy].to_f
|
46
|
+
end
|
47
|
+
alias :rate :rate_from_rate_matrix
|
48
|
+
|
49
|
+
def convert(options)
|
50
|
+
process_options!(options)
|
51
|
+
validate_options!(options)
|
52
|
+
converted_rate = options[:amount] * rate(options[:to_ccy], options[:from_ccy])
|
53
|
+
return converted_rate if CcyConvertor.configuration.round_up_amount.nil?
|
54
|
+
converted_rate.round(CcyConvertor.configuration.round_up_amount)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CcyConvertor
|
2
|
+
class YahooFinance < CcyConvertor::RateProvider
|
3
|
+
class << self
|
4
|
+
def rest_url_for_rate(from_ccy, to_ccy)
|
5
|
+
'https://query.yahooapis.com/v1/public/yql?q='\
|
6
|
+
"select%20%20Rate%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22#{to_ccy}#{from_ccy}%22)"\
|
7
|
+
'&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rate(from_ccy, to_ccy)
|
11
|
+
rate = rate_response(from_ccy, to_ccy)['query']['results']['rate']['Rate']
|
12
|
+
if rate.nil? || rate == 'N/A'
|
13
|
+
raise CcyConvertor::CurrencyNotSupported, "No rates available for #{from_ccy}/#{to_ccy}"
|
14
|
+
end
|
15
|
+
rate.to_f
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ccy_convertor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rohan Pujari
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
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: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: httparty
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: CcyConvertor provides live currency rate for various currencies and allows
|
70
|
+
to convert money from one currency to other. Currently it supports 3 rate provider.
|
71
|
+
New rate provider can be easily plugged in
|
72
|
+
email:
|
73
|
+
- rohanpujaris@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- .gitignore
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- ccy_convertor.gemspec
|
84
|
+
- lib/ccy_convertor.rb
|
85
|
+
- lib/ccy_convertor/configuration.rb
|
86
|
+
- lib/ccy_convertor/constant.rb
|
87
|
+
- lib/ccy_convertor/exception.rb
|
88
|
+
- lib/ccy_convertor/extension.rb
|
89
|
+
- lib/ccy_convertor/money.rb
|
90
|
+
- lib/ccy_convertor/process_and_validate_option.rb
|
91
|
+
- lib/ccy_convertor/rate_cache.rb
|
92
|
+
- lib/ccy_convertor/rate_providers/json_rate.rb
|
93
|
+
- lib/ccy_convertor/rate_providers/open_exchange_rate.rb
|
94
|
+
- lib/ccy_convertor/rate_providers/rate_provider.rb
|
95
|
+
- lib/ccy_convertor/rate_providers/yahoo_finance.rb
|
96
|
+
- lib/ccy_convertor/version.rb
|
97
|
+
homepage: https://github.com/rohanpujaris/ccy_convertor
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.2.2
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: CcyConvertor provides live currency rate for various currencies and allows
|
121
|
+
to convert money from one currency to other
|
122
|
+
test_files: []
|