dollar_to_euro 0.1.0
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +122 -0
- data/LICENSE.txt +204 -0
- data/README.md +47 -0
- data/README.rdoc +23 -0
- data/Rakefile +66 -0
- data/bin/console +7 -0
- data/bin/dollar_to_euro +37 -0
- data/bin/setup +8 -0
- data/config/schedule.rb +32 -0
- data/csv/dollars.csv +4943 -0
- data/dollar_to_euro.gemspec +34 -0
- data/lib/dollar_to_euro/dollar.rb +5 -0
- data/lib/dollar_to_euro/ecb_url.rb +3 -0
- data/lib/dollar_to_euro/exchange_rate_converter.rb +57 -0
- data/lib/dollar_to_euro/version.rb +3 -0
- data/lib/dollar_to_euro/worker.rb +57 -0
- data/lib/dollar_to_euro.rb +5 -0
- data/mongoid.yml +16 -0
- metadata +237 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'dollar_to_euro/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'dollar_to_euro'
|
7
|
+
spec.license = 'APACHE'
|
8
|
+
spec.version = DollarToEuro::VERSION
|
9
|
+
spec.authors = ['nisevi']
|
10
|
+
spec.email = ['nicolas.s.vidal@gmail.com']
|
11
|
+
spec.summary = 'Convert dollar to euro.'
|
12
|
+
spec.description = 'Convert dollar to euro.'
|
13
|
+
spec.homepage = 'https://github.com/nisevi/dollar_to_euro'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = 'bin'
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_development_dependency 'aruba'
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'byebug'
|
25
|
+
spec.add_dependency 'holidays'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'rdoc'
|
28
|
+
spec.add_dependency 'methadone'
|
29
|
+
spec.add_dependency 'mongoid'
|
30
|
+
spec.add_development_dependency 'rspec'
|
31
|
+
spec.add_dependency 'sidekiq'
|
32
|
+
spec.add_development_dependency 'simplecov'
|
33
|
+
spec.add_dependency 'whenever'
|
34
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative 'dollar'
|
2
|
+
require 'holidays'
|
3
|
+
require 'holidays/core_extensions/date'
|
4
|
+
|
5
|
+
class Date
|
6
|
+
include Holidays::CoreExtensions::Date
|
7
|
+
end
|
8
|
+
|
9
|
+
class ExchangeRateConverter
|
10
|
+
class << self
|
11
|
+
def convert(amount, date)
|
12
|
+
parsed_date = Date.parse(date)
|
13
|
+
# if converting at oldest or latest rate
|
14
|
+
return calculate_with_default_rate(amount, parsed_date) if default_date?(parsed_date)
|
15
|
+
# if exchange rate exists for the given date return the exchange
|
16
|
+
register = Dollar.where(date: parsed_date)
|
17
|
+
return register.first.value * amount if register.exists?
|
18
|
+
# if the date is holiday or weekend pick the previous available rate exchange
|
19
|
+
previous_rate_available(parsed_date) * amount if date_is_holiday_or_weekend?(date)
|
20
|
+
end
|
21
|
+
|
22
|
+
def calculate_with_default_rate(amount, parsed_date)
|
23
|
+
return Dollar.last.value * amount if parsed_date >= Date.today
|
24
|
+
return Dollar.first.value * amount if parsed_date < Dollar.first.date
|
25
|
+
end
|
26
|
+
|
27
|
+
# returns true if date is oldest than the oldest register we have
|
28
|
+
# returns true if date is todays date
|
29
|
+
def default_date?(parsed_date)
|
30
|
+
parsed_date >= Date.today || parsed_date < Dollar.first.date
|
31
|
+
end
|
32
|
+
|
33
|
+
def previous_rate_available(date)
|
34
|
+
Dollar.where(:date.lte => date).last.value
|
35
|
+
end
|
36
|
+
|
37
|
+
def date_is_holiday_or_weekend?(date)
|
38
|
+
weekend?(date) || holiday?(date)
|
39
|
+
end
|
40
|
+
|
41
|
+
def holiday?(date)
|
42
|
+
Holidays.cache_between(Time.now, 2.years.from_now, :us, :observed)
|
43
|
+
y, m, d = date.split '-'
|
44
|
+
parsed_date = Date.civil(y.to_i, m.to_i, d.to_i)
|
45
|
+
parsed_date.holiday?(:us)
|
46
|
+
end
|
47
|
+
|
48
|
+
def weekend?(date)
|
49
|
+
[6, 7].include?(Date.parse(date).cwday)
|
50
|
+
end
|
51
|
+
|
52
|
+
def database_is_out_of_date?
|
53
|
+
# TODO: handle more complex scenarios
|
54
|
+
Dollar.count.zero?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'sidekiq'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'mongoid'
|
4
|
+
require 'digest'
|
5
|
+
require 'date'
|
6
|
+
require_relative 'dollar'
|
7
|
+
|
8
|
+
Sidekiq.configure_client do |config|
|
9
|
+
config.redis = { db: 1 }
|
10
|
+
end
|
11
|
+
|
12
|
+
Sidekiq.configure_server do |config|
|
13
|
+
config.redis = { db: 1 }
|
14
|
+
end
|
15
|
+
|
16
|
+
class UpdateDatabase
|
17
|
+
include Sidekiq::Worker
|
18
|
+
Mongoid.load!('mongoid.yml', :development)
|
19
|
+
|
20
|
+
def perform(url)
|
21
|
+
download_file(url)
|
22
|
+
attrs = process_csv_attributes
|
23
|
+
clean_attrs = setup_attributes(attrs)
|
24
|
+
update_database(clean_attrs)
|
25
|
+
end
|
26
|
+
|
27
|
+
def download_file(url)
|
28
|
+
IO.copy_stream(open(url), 'csv/dollars.csv')
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_csv_attributes
|
32
|
+
file = File.open('csv/dollars.csv', 'r')
|
33
|
+
count = 0
|
34
|
+
attributes = []
|
35
|
+
while line = file.gets
|
36
|
+
# skip first 5 lines
|
37
|
+
count += 1
|
38
|
+
next if count < 6
|
39
|
+
date, value = line.split(',')
|
40
|
+
attributes << { date: Date.parse(date), value: value.strip.to_f }
|
41
|
+
end
|
42
|
+
attributes
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_attributes(attributes)
|
46
|
+
# if it is the first time the database is being loaded
|
47
|
+
return attributes.reverse if Dollar.count.zero?
|
48
|
+
# if the database is already up to date
|
49
|
+
return {} if attributes.first[:date] == Dollar.last.date
|
50
|
+
# we nee to load some registers to update the database
|
51
|
+
attributes.select { |dollar| dollar[:date] > Dollar.last.date }.reverse
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_database(attrs)
|
55
|
+
Dollar.create(attrs) unless attrs.empty?
|
56
|
+
end
|
57
|
+
end
|
data/mongoid.yml
ADDED
metadata
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dollar_to_euro
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nisevi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aruba
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
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: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: byebug
|
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: holidays
|
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
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
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: rdoc
|
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: methadone
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: mongoid
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sidekiq
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: simplecov
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: whenever
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
description: Convert dollar to euro.
|
182
|
+
email:
|
183
|
+
- nicolas.s.vidal@gmail.com
|
184
|
+
executables:
|
185
|
+
- console
|
186
|
+
- dollar_to_euro
|
187
|
+
- setup
|
188
|
+
extensions: []
|
189
|
+
extra_rdoc_files: []
|
190
|
+
files:
|
191
|
+
- ".gitignore"
|
192
|
+
- ".rspec"
|
193
|
+
- ".ruby-version"
|
194
|
+
- Gemfile
|
195
|
+
- Gemfile.lock
|
196
|
+
- LICENSE.txt
|
197
|
+
- README.md
|
198
|
+
- README.rdoc
|
199
|
+
- Rakefile
|
200
|
+
- bin/console
|
201
|
+
- bin/dollar_to_euro
|
202
|
+
- bin/setup
|
203
|
+
- config/schedule.rb
|
204
|
+
- csv/dollars.csv
|
205
|
+
- dollar_to_euro.gemspec
|
206
|
+
- lib/dollar_to_euro.rb
|
207
|
+
- lib/dollar_to_euro/dollar.rb
|
208
|
+
- lib/dollar_to_euro/ecb_url.rb
|
209
|
+
- lib/dollar_to_euro/exchange_rate_converter.rb
|
210
|
+
- lib/dollar_to_euro/version.rb
|
211
|
+
- lib/dollar_to_euro/worker.rb
|
212
|
+
- mongoid.yml
|
213
|
+
homepage: https://github.com/nisevi/dollar_to_euro
|
214
|
+
licenses:
|
215
|
+
- APACHE
|
216
|
+
metadata: {}
|
217
|
+
post_install_message:
|
218
|
+
rdoc_options: []
|
219
|
+
require_paths:
|
220
|
+
- lib
|
221
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
222
|
+
requirements:
|
223
|
+
- - ">="
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: '0'
|
226
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
|
+
requirements:
|
228
|
+
- - ">="
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
version: '0'
|
231
|
+
requirements: []
|
232
|
+
rubyforge_project:
|
233
|
+
rubygems_version: 2.7.3
|
234
|
+
signing_key:
|
235
|
+
specification_version: 4
|
236
|
+
summary: Convert dollar to euro.
|
237
|
+
test_files: []
|