bloomberg_currency 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5750a9ea831b7ce49a0e34ea6f50dd02e055a84c
4
- data.tar.gz: d8d18e027f2fb8af17eecb69272e7eba0db81dab
2
+ SHA256:
3
+ metadata.gz: d93abee4c1b84e8d2f7f697463b6c980f3bb11c1444c726b438ad486fd7b7f4a
4
+ data.tar.gz: e3643047ac9eb1addbe921c7bd34a7875895de1f2b34df26ba29b08c2fa99049
5
5
  SHA512:
6
- metadata.gz: fae8f01e406f1ad92d792eaa7a3e4bc90faa3f39b75cace02be43b9fd1226c9c9b2e71e7ac5eb16b1730c1c4687839f79d869f9cde3b1fa7c449a00911a7db1b
7
- data.tar.gz: fa004d8549d9606417bc50b3d5230ac8eeabf7897e3f49750bd9febaa98980831ee57a059560ffa40db49cc7e9cf10bf7bc6d4f289ae93faaff816eb7e45111f
6
+ metadata.gz: 17d85ed4ce21f18931f73453fd73c366b67695fb211e20197daa7159df590a852511fe3e09bceb8b0f7165359a45aede0dd090635671eba4d11f08c221b4a667
7
+ data.tar.gz: edf076ecd3c68af199a69f1275012193b606c15efba3dece0a9c275abe19dbfe160135f0f6cb1c3db6b24ddb41e3724f14aa864de2fff1439ec1c65721dba7e3
data/.gitignore CHANGED
@@ -14,4 +14,4 @@ codeclimate-coverage-reporter.sh
14
14
  .DS_Store
15
15
  */**/.DS_Store
16
16
 
17
- .byebug_history
17
+ /.byebug_history
data/.rubocop.yml CHANGED
@@ -5,10 +5,18 @@ AllCops:
5
5
  - '**/Rakefile'
6
6
  - '**/config.ru'
7
7
  Exclude:
8
+ - bloomberg_currency.gemspec
8
9
  - 'db/**/*'
9
10
  - 'config/**/*'
10
11
  - 'script/**/*'
12
+ - 'spec/**/*'
11
13
  - !ruby/regexp /old_and_unused\.rb$/
12
14
 
13
15
  Metrics/LineLength:
14
- Max: 120
16
+ Max: 120
17
+
18
+ Metrics/MethodLength:
19
+ Max: 12
20
+
21
+ Metrics/AbcSize:
22
+ Max: 18
data/.rubocop_todo.yml CHANGED
@@ -1,7 +1,25 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-11-11 16:25:35 -0500 using RuboCop version 0.45.0.
3
+ # on 2018-01-17 08:55:47 -0500 using RuboCop version 0.49.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Cop supports --auto-correct.
11
+ Layout/EmptyLineAfterMagicComment:
12
+ Exclude:
13
+ - 'Gemfile'
14
+
15
+ # Offense count: 1
16
+ # Configuration parameters: CountComments, ExcludedMethods.
17
+ Metrics/BlockLength:
18
+ Max: 28
19
+
20
+ # Offense count: 1
21
+ # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
22
+ # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
23
+ Style/FileName:
24
+ Exclude:
25
+ - 'Gemfile'
data/.ruby_version ADDED
@@ -0,0 +1 @@
1
+ 2.6.5
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.2.4
5
- before_install: gem install bundler -v 1.13.6
6
- before_script: rubocop
4
+ - 2.6.5
5
+ before_install: gem install bundler -v 1.17.2
6
+ before_script: rubocop
@@ -34,12 +34,15 @@ Gem::Specification.new do |spec|
34
34
  spec.require_paths = ['lib']
35
35
 
36
36
  spec.add_development_dependency 'bundler', '~> 1.13'
37
- spec.add_development_dependency 'rake', '~> 10.0'
37
+ spec.add_development_dependency 'rake', '>= 12.3.3'
38
38
  spec.add_development_dependency 'rspec', '~> 3.0'
39
39
  spec.add_development_dependency 'simplecov', '~> 0.11'
40
40
  spec.add_development_dependency 'rubocop', '~> 0.49.0'
41
41
  spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0', '>= 1.0.0'
42
42
  spec.add_development_dependency 'pry-byebug', '~> 3.5.1'
43
+ spec.add_development_dependency 'vcr', '~> 6.0.0'
44
+ spec.add_development_dependency 'webmock', '~> 3.5.0'
43
45
 
44
46
  spec.add_runtime_dependency 'nokogiri', '~> 1.6', '>= 1.6.8'
47
+ spec.add_runtime_dependency 'faraday', '~> 0.9.2'
45
48
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bloomberg_currency/version'
4
+ require 'bloomberg_currency/api'
4
5
  require 'bloomberg_currency/api/site'
5
6
  require 'bloomberg_currency/api/host'
6
7
  require 'bloomberg_currency/quote'
@@ -0,0 +1,7 @@
1
+ module BC
2
+ module API
3
+ USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) '\
4
+ 'AppleWebKit/537.36 (KHTML, like Gecko) '\
5
+ 'Chrome/88.0.4324.150 Safari/537.36'.freeze
6
+ end
7
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'open-uri'
3
+ require 'faraday'
4
4
  require 'nokogiri'
5
5
  require 'bigdecimal'
6
6
 
@@ -21,8 +21,14 @@ module BC
21
21
  end
22
22
 
23
23
  def load_site(currency_one, currency_two)
24
- file = open("#{BC::API::Host::URL}#{currency_one}#{currency_two}:CUR")
25
- Nokogiri::HTML(file)
24
+ url = "#{BC::API::Host::URL}#{currency_one}#{currency_two}:CUR"
25
+ headers = {
26
+ 'user-agent' => BC::API::USER_AGENT,
27
+ 'referer' => 'https://www.google.com/'
28
+ }
29
+ file = Faraday.get(url, nil, headers)
30
+
31
+ Nokogiri::HTML(file.body)
26
32
  end
27
33
 
28
34
  def parse(document)
@@ -32,30 +38,57 @@ module BC
32
38
  end
33
39
 
34
40
  def parse_quote(document)
35
- price_container = document.xpath("//div[contains(@class, 'price-container')]")
36
- detailed_quote_container = document.xpath("//div[contains(@class, 'detailed-quote')]")
37
-
38
- price_element = price_container.xpath("//div[@class='price']")
39
- price_datetime_element = price_container.xpath("//div[@class='price-datetime']")
40
-
41
+ price_container = document.xpath("//section[contains(@class, 'quotePageSnapshot')]")
42
+ detailed_quote_container = document.xpath("//div[contains(@class, 'details__')]")
43
+ price_element = price_container.xpath("//span[starts-with(@class, 'priceText__')]")
44
+ price_datetime_element = price_container.xpath("//div[contains(@class, 'time__')]")
41
45
  price = price_element.text.strip.tr(',', '').to_f
42
- datetime = DateTime.strptime(price_datetime_element.text.strip, 'As of %H:%M %p %z %m/%d/%Y')
46
+ datetime = calculate_datetime(price_datetime_element.children.first.text.strip)
43
47
  details_hash = quote_details(detailed_quote_container)
44
48
 
45
49
  { price: price, datetime: datetime, detail: BC::QuoteDetail.new(details_hash), available: true }
46
50
  end
47
51
 
48
52
  def quote_details(container)
49
- detail_elements = container.xpath("//div[@class='data-table data-table_detailed']").xpath(
50
- "//div[contains(@class, 'cell') and contains(@class, 'cell__mobile-basic')]"
51
- )
52
-
53
- details_hash = {}
54
- details_matrix = detail_elements.map { |a| a.text.strip.split(' ') }
55
- details_matrix.each do |key_value_array|
56
- details_hash[key_value_array[0].downcase.tr(' ', '_').to_sym] = key_value_array[1]
53
+ open_price = extract_value_from_detail(container, 'openprice')
54
+ previous_close = extract_value_from_detail(container, 'previousclosingpriceonetradingdayago')
55
+ total_return_ytd = extract_value_from_detail(container, 'totalreturnytd')
56
+ range_one_day = extract_values_for_range(container, 'rangeoneday')
57
+ range_52_weeks = extract_values_for_range(container, 'range52weeks')
58
+
59
+ {
60
+ open: open_price,
61
+ day_range: range_one_day,
62
+ previous_close: previous_close,
63
+ range_52_wks: range_52_weeks,
64
+ ytd_return: total_return_ytd
65
+ }
66
+ end
67
+
68
+ def extract_value_from_detail(container, section)
69
+ container
70
+ .xpath("//section[contains(@class, '#{section}')]")
71
+ .children[1].text
72
+ end
73
+
74
+ def extract_values_for_range(container, section)
75
+ container
76
+ .xpath("//section[contains(@class, '#{section}')]")
77
+ .children[1]
78
+ .children[0]
79
+ .children
80
+ .map(&:text)
81
+ .join('-')
82
+ end
83
+
84
+ def calculate_datetime(datetime_str)
85
+ if datetime_str.index(':')
86
+ DateTime.strptime(datetime_str, 'As of %H:%M %p %z %m/%d/%Y').to_s
87
+ else
88
+ DateTime.strptime(datetime_str, 'As of %m/%d/%Y').to_date.to_s
57
89
  end
58
- details_hash
90
+ rescue
91
+ ''
59
92
  end
60
93
  end
61
94
  end
@@ -4,6 +4,7 @@ module BC
4
4
  # Quote Information Class
5
5
  class Quote
6
6
  attr_accessor :price, :datetime, :detail, :available
7
+
7
8
  def initialize(currency_one, currency_two)
8
9
  result = BC::API::Site.quote(currency_one, currency_two)
9
10
 
@@ -9,7 +9,7 @@ module BC
9
9
  @open = process_float(attributes[:open])
10
10
  @day_range = process_range(attributes[:day_range])
11
11
  @previous_close = process_float(attributes[:previous_close])
12
- @last_52_weeks_range = process_range(attributes[:"52wk_range"])
12
+ @last_52_weeks_range = process_range(attributes[:range_52_wks])
13
13
  @ytd_return = process_float(attributes[:ytd_return])
14
14
  end
15
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BC
4
- VERSION = '1.0.0'.freeze
4
+ VERSION = '1.1.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bloomberg_currency
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Jimenez Velez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-16 00:00:00.000000000 Z
11
+ date: 2021-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -84,22 +84,22 @@ dependencies:
84
84
  name: codeclimate-test-reporter
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '1.0'
90
87
  - - ">="
91
88
  - !ruby/object:Gem::Version
92
89
  version: 1.0.0
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: '1.0'
93
93
  type: :development
94
94
  prerelease: false
95
95
  version_requirements: !ruby/object:Gem::Requirement
96
96
  requirements:
97
- - - "~>"
98
- - !ruby/object:Gem::Version
99
- version: '1.0'
100
97
  - - ">="
101
98
  - !ruby/object:Gem::Version
102
99
  version: 1.0.0
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.0'
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: pry-byebug
105
105
  requirement: !ruby/object:Gem::Requirement
@@ -114,6 +114,34 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: 3.5.1
117
+ - !ruby/object:Gem::Dependency
118
+ name: vcr
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 6.0.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 6.0.0
131
+ - !ruby/object:Gem::Dependency
132
+ name: webmock
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 3.5.0
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: 3.5.0
117
145
  - !ruby/object:Gem::Dependency
118
146
  name: nokogiri
119
147
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +162,20 @@ dependencies:
134
162
  - - ">="
135
163
  - !ruby/object:Gem::Version
136
164
  version: 1.6.8
165
+ - !ruby/object:Gem::Dependency
166
+ name: faraday
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: 0.9.2
172
+ type: :runtime
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: 0.9.2
137
179
  description: Provides an easy to use API to get currency rates data from the Bloomberg
138
180
  website
139
181
  email:
@@ -142,11 +184,11 @@ executables: []
142
184
  extensions: []
143
185
  extra_rdoc_files: []
144
186
  files:
145
- - ".byebug_history"
146
187
  - ".gitignore"
147
188
  - ".rspec"
148
189
  - ".rubocop.yml"
149
190
  - ".rubocop_todo.yml"
191
+ - ".ruby_version"
150
192
  - ".simplecov"
151
193
  - ".travis.yml"
152
194
  - CODE_OF_CONDUCT.md
@@ -158,6 +200,7 @@ files:
158
200
  - bin/setup
159
201
  - bloomberg_currency.gemspec
160
202
  - lib/bloomberg_currency.rb
203
+ - lib/bloomberg_currency/api.rb
161
204
  - lib/bloomberg_currency/api/host.rb
162
205
  - lib/bloomberg_currency/api/site.rb
163
206
  - lib/bloomberg_currency/quote.rb
@@ -183,8 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
226
  - !ruby/object:Gem::Version
184
227
  version: '0'
185
228
  requirements: []
186
- rubyforge_project:
187
- rubygems_version: 2.6.11
229
+ rubygems_version: 3.0.3
188
230
  signing_key:
189
231
  specification_version: 4
190
232
  summary: Bloomberg Currency helps you pull currency rates data from the Bloomberg