exchange 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ .rvmrc
2
+
3
+ # rcov generated
4
+ coverage
5
+ coverage.data
6
+
7
+ # rdoc generated
8
+ rdoc
9
+
10
+ # yard generated
11
+ doc
12
+ .yardoc
13
+
14
+ # bundler
15
+ .bundle
16
+
17
+ # filestore
18
+ exchange_filestore
19
+
20
+ # jeweler generated
21
+ pkg
22
+
23
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
24
+ #
25
+ # * Create a file at ~/.gitignore
26
+ # * Include files you want ignored
27
+ # * Run: git config --global core.excludesfile ~/.gitignore
28
+ #
29
+ # After doing this, these files will be ignored in all your git projects,
30
+ # saving you from having to 'pollute' every project you touch with them
31
+ #
32
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
33
+ #
34
+ # For MacOS:
35
+ #
36
+ #.DS_Store
37
+
38
+ # For TextMate
39
+ #*.tmproj
40
+ #tmtags
41
+
42
+ # For emacs:
43
+ #*~
44
+ #\#*
45
+ #.\#*
46
+
47
+ # For vim:
48
+ #*.swp
49
+
50
+ # For redcar:
51
+ #.redcar
52
+
53
+ # For rubinius:
54
+ #*.rbc
@@ -4,4 +4,8 @@ rvm:
4
4
  - 1.9.2
5
5
  - 1.9.3
6
6
  - ree
7
+ - rbx-18mode
8
+ - rbx-19mode
9
+ - jruby
10
+
7
11
  script: bundle exec rspec
data/Gemfile CHANGED
@@ -1,26 +1,15 @@
1
1
  source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- #gem "nokogiri", ">= 1.5.0"
5
- #gem "json", ">= 1.6.5"
6
- #gem "memcached", ">= 1.3.0"
7
- #gem "redis", ">= 2.2.0"
8
-
9
- # Add dependencies to develop your gem here.
10
- # Include everything needed to run rake, tests, features, etc.
11
2
 
12
3
  gemspec
13
4
 
14
5
  group :development do
15
- gem "yard", "~> 0.7.4"
6
+ gem "yard", ">= 0.7.4"
16
7
  gem "bundler", ">= 1.0.0"
17
- gem "jeweler", "~> 1.8.3"
18
8
  end
19
9
 
20
10
  group :test do
21
11
  gem "nokogiri", ">= 1.5.0", :require => false
22
12
  gem "dalli", ">= 2.0.0", :require => false
23
13
  gem "redis", ">= 2.2.0", :require => false
24
- gem "shoulda", ">= 0"
25
14
  gem "rspec"
26
15
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exchange (0.6.0)
4
+ exchange (0.7.6)
5
5
  json (>= 1.0.0)
6
6
 
7
7
  GEM
@@ -9,43 +9,29 @@ GEM
9
9
  specs:
10
10
  dalli (2.2.1)
11
11
  diff-lcs (1.1.3)
12
- git (1.2.5)
13
- jeweler (1.8.3)
14
- bundler (~> 1.0)
15
- git (>= 1.2.5)
16
- rake
17
- rdoc
18
- json (1.6.6)
12
+ json (1.7.5)
19
13
  nokogiri (1.5.5)
20
- rake (0.9.2.2)
21
- rdoc (3.12)
22
- json (~> 1.4)
23
- redis (3.0.1)
24
- rspec (2.9.0)
25
- rspec-core (~> 2.9.0)
26
- rspec-expectations (~> 2.9.0)
27
- rspec-mocks (~> 2.9.0)
28
- rspec-core (2.9.0)
29
- rspec-expectations (2.9.1)
14
+ nokogiri (1.5.5-java)
15
+ redis (3.0.2)
16
+ rspec (2.11.0)
17
+ rspec-core (~> 2.11.0)
18
+ rspec-expectations (~> 2.11.0)
19
+ rspec-mocks (~> 2.11.0)
20
+ rspec-core (2.11.1)
21
+ rspec-expectations (2.11.3)
30
22
  diff-lcs (~> 1.1.3)
31
- rspec-mocks (2.9.0)
32
- shoulda (3.0.1)
33
- shoulda-context (~> 1.0.0)
34
- shoulda-matchers (~> 1.0.0)
35
- shoulda-context (1.0.0)
36
- shoulda-matchers (1.0.0)
37
- yard (0.7.5)
23
+ rspec-mocks (2.11.3)
24
+ yard (0.8.2.1)
38
25
 
39
26
  PLATFORMS
27
+ java
40
28
  ruby
41
29
 
42
30
  DEPENDENCIES
43
31
  bundler (>= 1.0.0)
44
32
  dalli (>= 2.0.0)
45
33
  exchange!
46
- jeweler (~> 1.8.3)
47
34
  nokogiri (>= 1.5.0)
48
35
  redis (>= 2.2.0)
49
36
  rspec
50
- shoulda
51
- yard (~> 0.7.4)
37
+ yard (>= 0.7.4)
@@ -1,68 +1,58 @@
1
- = exchange {<img src="https://secure.travis-ci.org/beatrichartz/exchange.png" />}[http://travis-ci.org/beatrichartz/exchange]
1
+ = exchange {<img src="https://secure.travis-ci.org/beatrichartz/exchange.png" />}[http://travis-ci.org/beatrichartz/exchange] {<img src="https://gemnasium.com/beatrichartz/exchange.png" alt="Dependency Status" />}[https://gemnasium.com/beatrichartz/exchange] {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/beatrichartz/exchange]
2
2
 
3
- The Exchange Gem gives you easy access to currency functions directly on your Numbers. It has been tested against ruby 1.8.7, ree, ruby 1.9.2 and 1.9.3. You can use it with just plain ruby projects, in Rails 2 and 3, Sinatra or whatever Framework you like.
3
+ The Exchange Gem gives you easy access to currency functions directly on your Numbers. {It is tested against}[http://travis-ci.org/beatrichartz/exchange]: ruby 1.9, ruby 1.8.7, ree, rubinius (1.8 and 1.9 mode) and jruby
4
4
 
5
- === Changelog
5
+ You can use it with just plain ruby projects, in Rails 2 and 3, Sinatra or whatever Framework you like.
6
6
 
7
- == 0.6
8
- - Memcached, Redis, JSON and Nokogiri have been removed as explicit dependencies of the gem. The gem will now try to load the gems
9
- you want to use with it during runtime, and it will throw an exception if a gem required according to your configuration is not present.
10
- - The cache class is now a singleton and no class singleton anymore. This makes it easier to write a seamlessly integrating custom cache class for it.
11
- == 0.5
12
- - Changed the currency bot api to openexchangerates.org and changed the default api to xaviermedia. Since the openexchangerates.org api still supports a free plan with reasonable conditions, it will still be supported by the exchange gem, although it may be moved to a separate gem in the future
13
- == 0.4
14
- - Some potential 0 values on conversions when caching with memcached have been fixed.
15
- == 0.3
16
- - The ECB API has been added to the standard apis
17
-
18
- ==== Features
7
+ == Features
19
8
 
20
9
  === Easy Conversion
21
10
 
22
- Imagine a conversion as easy as
11
+ Conversion of currencies does not get any easier
23
12
  1.eur.to_usd
24
- or even better
13
+ or better for historic dates
25
14
  1.eur.to_usd(:at => Time.now - 84600)
26
- which gets you an exchange at the rates of yesterday.
27
15
 
28
16
  === Only one request per day to keep you up to date
29
17
 
30
- You're hitting the internet only daily to get new rates with this gem (hourly updates are available if you're eager to have the absolutely newest ones)
18
+ You're hitting the internet only daily to get new rates (hourly updates are available if you're eager to have the absolutely newest ones)
31
19
 
32
20
  === ISO 4217 Currency formatting
33
21
  On of the issues with currencies is: You never know the format they should be in. With Exchange, you can just use the currencies
34
- to_s method, which takes care of the right format for you. A version with symbols is under construction. You can either have a
35
- a string with the currency code in front, or just the amount in the right format
22
+ to_s method, which takes care of the right format for you. You can either have a string with the currency code in front, or just the amount in the right format
36
23
 
37
24
  Exchange::Currency.new(49.567, :usd).to_s #=> "USD 49.57"
38
25
  Exchange::Currency.new(45, :jpy).to_s #=> "JPY 45"
39
26
  Exchange::Currency.new(34.34, :omr).to_s #=> "OMR 34.340"
40
27
  Exchange::ISO4217.stringif(34.34, :omr).to_s(:iso) #=> "34.340"
41
28
 
42
- === Use three great APIs or your own great API
29
+
30
+ === Use three great APIs or your own
43
31
 
44
32
  Three open APIs are already included:
45
33
 
46
- - Xaviermedia (http://www.xavierforum.com/viewtopic.php?f=5&t=10979&sid=671a685edbfa5dbec219fbc6793d5057)
47
- - European Central Bank (http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html)
48
- - Currency Bot (http://currencybot.github.com/)
34
+ - {Xaviermedia}[http://www.xavierforum.com/viewtopic.php?f=5&t=10979&sid=671a685edbfa5dbec219fbc6793d5057]
35
+ - {European Central Bank}[http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html]
36
+ - {Currency Bot}[http://currencybot.github.com/]
49
37
 
50
- but if you have another API you like to use, it becomes as easy as writing one Class and two methods to use it with the Exchange gem. Just visit the documentation here: http://rubydoc.info/github/beatrichartz/exchange/Exchange/ExternalAPI to see an example of a custom API Extension
38
+ but if you have another API you like to use, it becomes as easy as writing one Class and two methods to use it.
39
+ {Example of a custom API Extension}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/ExternalAPI]
51
40
 
52
41
  === Use great caches or your own great cache
53
42
 
54
- Also, the gem allows you to use one of three available caching solutions:
43
+ Use one of three available caching solutions:
55
44
 
56
- - Memcached via the Memcached gem
45
+ - Memcached via the Dalli gem
57
46
  - Redis via the redis gem
58
47
  - Rails cache (This gem does however not depend on rails)
59
48
 
60
- But, same here, if you don't like any of these or want to use your own caching solution, it is as easy as writing one Class and two methods to use it with Exchange. Just visit the documentation here: http://rubydoc.info/github/beatrichartz/exchange/Exchange/Cache for an example of a cache extension
49
+ But, same here, if you don't like any of these or want to use your own caching solution, it is as easy as writing one Class and two methods to use it.
50
+ {Example of a custom cache extension}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/Cache]
61
51
 
62
52
  == Installation
63
53
  === Bundler / Rails
64
54
  Add it to your Gemfile
65
- gem "exchange", ">=0.2.6"
55
+ gem "exchange", ">=0.7.3"
66
56
  === Manually
67
57
  Just install it as a gem
68
58
  gem install exchange
@@ -157,7 +147,7 @@ Access the original currency and its value after conversion, even over multiple
157
147
 
158
148
  You can configure the exchange gem to a variety of options, allowing you to control restrictions on operations, caching and which API the gem uses. Just set the configuration with
159
149
 
160
- Exchange::Configuration.define do |c|
150
+ Exchange.configuration = Exchange::Configuration.new do |c|
161
151
  # your configuration goes here
162
152
  end
163
153
 
@@ -166,49 +156,64 @@ You can configure the exchange gem to a variety of options, allowing you to cont
166
156
 
167
157
  The options available are
168
158
 
169
- :cache (default :memcached) The cache type to use. Possible Values: :redis, :memcached or :rails or false to disable caching
170
- :cache_host (default '127.0.0.1') A string with the hostname or IP to set the cache host to. Does not have to be set for Rails cache
171
- :cache_port (default 11211) An integer for the cache port. Does not have to be set for Rails cache
172
- :api (default :currency_bot) The API to use. Possible Values: :currency_bot (Open Source currency bot API) or :xavier_media (Xavier Media API)
173
- :retries (default 5) The number of times the gem should retry to connect to the api host
159
+ :cache Takes the cache options as a hash, the options are:
160
+ :subclass (default :memcached) The cache subclass to use for caching. Available: Rails cache, Redis, Memcached, Filecache
161
+ :host (default '127.0.0.1') A string with the hostname or IP to set the cache host to. Does not have to be set for Rails cache
162
+ :port (default 11211) An integer for the cache port. Does not have to be set for Rails cache
163
+ :expire (default :daily) Which period is used to expire the cache, :daily or :hourly are available
164
+
165
+ :api Takes the conversion api as a hash, the options are:
166
+ :subclass (default :xavier_media) The api to use. Available: Xavier Media, ECB, Currency Bot
167
+ :retries (default 5) The number of times the gem should retry to connect to the api host
168
+ :app_id (default nil) The app id to use with your api request
169
+
174
170
  :allow_mixed_opterations (default true) If set to false, Operations with with different currencies raise errors.
175
- :update (default :daily) The regularity of updates for the API. Possible values: :daily, :hourly.
176
171
 
177
- If your afraid of mixed currency operations, just don't allow them
178
- Exchange::Configuration.allow_mixed_operations = false
172
+ If you're afraid of mixed currency operations, just don't allow them
173
+ Exchange.configuration.allow_mixed_operations = false
179
174
  1.usd + 1.eur #=> MixedCurrencyError
180
175
 
181
176
  === Caching Options
182
177
 
183
178
  Use Memcached to cache the result (default). Exchange will cache the API files with a key starting with 'exchange_'
184
- Exchange::Configuration.define do |c|
185
- c.cache = :memcached
186
- c.cache_host = 'yourhost'
187
- c.cache_port = 2423 #your port
179
+ Exchange.configuration = Exchange::Configuration.new do |c|
180
+ c.cache = {
181
+ :subclass => :memcached,
182
+ :host => 'yourhost',
183
+ :port => 2434, #yourport
184
+ }
188
185
  end
189
186
 
190
187
  Use Redis to cache the result. Exchange will cache the API files with a key starting with 'exchange_'
191
- Exchange::Configuration.define do |c|
192
- c.cache = :redis
193
- c.cache_host = 'yourhost'
194
- c.cache_port = 2423 #your port
188
+ Exchange.configuration = Exchange::Configuration.new do |c|
189
+ c.cache = {
190
+ :subclass => :redis,
191
+ :host => 'yourhost',
192
+ :port => 2434, #yourport
193
+ }
195
194
  end
196
195
 
197
196
  Use Rails to cache the result. Exchange will cache the API files with a key starting with 'exchange_'
198
- Exchange::Configuration.define do |c|
199
- c.cache = :rails
197
+ Exchange.configuration = Exchange::Configuration.new do |c|
198
+ c.cache = {
199
+ :subclass => :rails
200
+ }
200
201
  end
201
202
 
202
203
  === API Options
203
204
 
204
- Use the currencybot Open Source API as a source of your conversion rates (default)
205
- Exchange::Configuration.define do |c|
206
- c.api = :currency_bot
205
+ Use the Xaviermedia API as the source of your conversion rates
206
+ Exchange.configuration = Exchange::Configuration.new do |c|
207
+ c.api = {
208
+ :subclass => :xavier_media
209
+ }
207
210
  end
208
211
 
209
- Use the Xaviermedia API as the source of your conversion rates
210
- Exchange::Configuration.define do |c|
211
- c.api = :xavier_media
212
+ Use the currencybot Open Source API as a source of your conversion rates
213
+ Exchange.configuration = Exchange::Configuration.new do |c|
214
+ c.api = {
215
+ :subclass => :currency_bot
216
+ }
212
217
  end
213
218
 
214
219
  == Connect your own API and Cache
@@ -222,21 +227,36 @@ Easily connect to your custom API by writing an ExternalAPI Class, or use your o
222
227
  # Define here which currencies your API can handle
223
228
  CURRENCIES = %W(usd chf)
224
229
 
225
- # Every instance of ExternalAPI Class has to have an update function which gets the rates from the API
230
+ # Every instance of ExternalAPI Class has to have an update function which gets
231
+ # the rates from the API
232
+ #
226
233
  def update(opts={})
227
234
  # assure that you will get a Time object for the historical dates
235
+ #
228
236
  time = assure_time(opts[:at])
229
237
 
230
- # call your API (shown here with a helper function that builds your API URL). Like this, your calls will get cached.
238
+ # Call your API (shown here with a helper function that builds your API URL).
239
+ # Like this, your calls will get cached.
240
+ #
231
241
  Call.new(api_url(time), :at => time) do |result|
232
242
 
233
- # assign the currency conversion base, attention, this is readonly, so don't do self.base =
243
+ # Assign the currency conversion base.
244
+ # Attention, this is readonly, self.base= won't work
245
+ #
234
246
  @base = result['base']
235
247
 
236
- # assign the rates, this has to be a hash with the following format: {'USD' => 1.23242, 'CHF' => 1.34323}. Attention, this is readonly.
248
+ # assign the rates, this has to be a hash with the following format:
249
+ # {'USD' => 1.23242, 'CHF' => 1.34323}.
250
+ #
251
+ # Attention, this is readonly, self.rates= won't work
252
+ #
237
253
  @rates = result['rates']
238
254
 
239
- # timestamp the api call result. This may come in handy to assure you have the right result. Attention, this is readonly.
255
+ # Timestamp the api call result. This may come in handy to assure you have
256
+ # the right result.
257
+ #
258
+ # Attention, this is readonly, self.timestamp= won't work
259
+ #
240
260
  @timestamp = result['timestamp'].to_i
241
261
  end
242
262
  end
@@ -253,7 +273,7 @@ Easily connect to your custom API by writing an ExternalAPI Class, or use your o
253
273
 
254
274
  Now, you can configure your API in the configuration. The Symbol will get camelcased and constantized
255
275
 
256
- Exchange::Configuration.api = :my_custom
276
+ Exchange::Configuration.api.subclass = :my_custom
257
277
 
258
278
  Have fun, and don't forget to write tests.
259
279
 
@@ -262,19 +282,22 @@ Have fun, and don't forget to write tests.
262
282
  Write your own caching module to use the gem with your own custom caching solution.
263
283
  module Cache
264
284
  class MyCustomCache < Base
265
- class << self
266
- # a cache class has to have the class method "cached"
267
- def cached api, opts={}, &block
268
- # generate the key with key(api, opts[:at]) and you will get a unique key to store in your cache
269
- # Your code goes here
270
- end
285
+ # A cache class has to have the method "cached".
286
+ # The cache Base is a singleton and forwards the method "cached"
287
+ # to the instance
288
+ #
289
+ def cached api, opts={}, &block
290
+ # generate the storage with key(api, opts[:at]) and you will get a
291
+ # unique key to store in your cache
292
+ #
293
+ # Your code goes here
271
294
  end
272
295
  end
273
296
  end
274
297
 
275
298
  Now, you can configure your Caching solution in the configuration. The Symbol will get camelcased and constantized
276
299
 
277
- Exchange::Configuration.cache = :my_custom_cache
300
+ Exchange.configuration.cache.subclass = :my_custom_cache
278
301
 
279
302
  Have fun, and don't forget to write tests.
280
303
 
@@ -1,6 +1,25 @@
1
1
  = Changes to Exchange
2
2
 
3
- == 0.3.0
3
+ == 0.7.3
4
+ - jruby compatibility, horray!
5
+
6
+ == 0.7.1
7
+ - The DSL is now included into Numeric, which makes currency operations available for all subclasses (including your own) of Numeric
8
+ - Some structurally unsound behaviour with ruby base operators (+, -, *, /, round, floor, ceil) has been corrected. It is recommended to update to this latest version of exchange if you are using a version less than 0.7.1.
9
+ - the api classes have been refactored to less complex, more readable code,
10
+ - general performance has improved quite a bit.
11
+
12
+ == 0.6
13
+ - Memcached, Redis, JSON and Nokogiri have been removed as explicit dependencies of the gem. The gem will now try to load the gems you want to use with it during runtime, and it will throw an exception if a gem required according to your configuration is not present.
14
+ - The cache class is now a singleton and no class singleton anymore. This makes it easier to write a seamlessly integrating custom cache class for it.
15
+
16
+ == 0.5
17
+ - Changed the currency bot api to openexchangerates.org and changed the default api to xaviermedia. Since the openexchangerates.org api still supports a free plan with reasonable conditions, it will still be supported by the exchange gem, although it may be moved to a separate gem in the future
18
+
19
+ == 0.4
20
+ - Some potential 0 values on conversions when caching with memcached have been fixed.
21
+
22
+ == 0.3
4
23
  - All Currencies & Rates get handled in BigDecimal now, preventing floating point errors
5
24
  - Major Performance inprovements on the DSL methods
6
25
  - New ECB API configuration possibility