banco_central 0.1.2 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d6e52dcabf6c0b4bef82235c84a15d9ad30c104
4
- data.tar.gz: 940519cc51b45ec89d53d92ec958c5ec5e8e14b8
3
+ metadata.gz: e2b98916ce52a33d03a5c13149d2deb09e58ac3e
4
+ data.tar.gz: a48f8692c19cd9a406668ada7829bac2797f93b4
5
5
  SHA512:
6
- metadata.gz: 6052734bae8dfb11a1123fa1db07e6b0f25ca5c6edf87f411622b478981f71b14c1dfa09a9bd3f18371bfd0fb7d043a982a1482716459b2b6e01aa95adfb1575
7
- data.tar.gz: 6ad2376752c2e4ef8eebf742f2cf1af51c19542e1f6d8e4bbc000167a37a7d71159038cfe490ed3277b37a798bcfba3772e5184cbdfef85b39e58404beb77e70
6
+ metadata.gz: 5ed03e3953fd9c391b4c6e01dc8abf9f223b76426d92f2a23aefea0a075db9b550fe51f58ead3ebd2162bbbf14318d8e65c9f54180d5aec334f43c5241358395
7
+ data.tar.gz: cac607a3e688ab543db38e6d0ce68b771ca6cb2031b5d0d2d7398fd210aa7afa680d67b7d9621a28c35189f98a68615c5b3ec0b4971eebf29427c8876ac60312
data/README.md CHANGED
@@ -85,14 +85,14 @@ The indicators must have the same periodicity.
85
85
 
86
86
  ### Logging
87
87
 
88
- To specify the log level use the `:log_level` option. Valid values are `:fatal`, `:error`, `:warn`, `:info`, `:debug`. In practice, it will affect the output of Savon calls.
88
+ To specify the log level set the `log_level` attribute. Valid values are `:fatal`, `:error`, `:warn`, `:info`, `:debug`. In practice, it will affect the output of Savon calls.
89
89
  ```ruby
90
- BancoCentral.all(:ipca, log_level: :debug)
90
+ BancoCentral.log_level = :debug
91
91
  ```
92
92
 
93
- The default logger is STDOUT. To use a different one just use the `:logger` option.
93
+ The default logger is STDOUT. To use a different one just set the `:logger` attribute.
94
94
  ```ruby
95
- BancoCentral.all(:ipca, log_level: :debug, logger: @logger)
95
+ BancoCentral.logger = @logger
96
96
  ```
97
97
 
98
98
 
data/lib/banco_central.rb CHANGED
@@ -1,132 +1,177 @@
1
- require "banco_central/version"
2
- require "savon"
3
- require "yaml"
4
-
5
- # BancoCentral.last(:ipca)
6
- # BancoCentral.all(:ipca)
7
- # BancoCentral.all(:ipca, start: "1/7/2014")
8
- # BancoCentral.all(:ipca, finish: "1/8/2014")
9
- # BancoCentral.all(:ipca, start: "1/7/2014", finish: "1/8/2014")
10
- # BancoCentral.all([:importacoes, :exportacoes])
11
- # BancoCentral.find(:dolar, date: "3/7/2014")
12
- # BancoCentral::LABELS
13
- # BancoCentral.exp(1)
14
- module BancoCentral
1
+ # frozen_string_literal: true
15
2
 
16
- CONFIG = YAML.load_file(File.join File.dirname(__dir__), "config/labels.yml")
3
+ require 'banco_central/version'
4
+ require 'savon'
5
+ require 'yaml'
17
6
 
18
- WSDL_URI = CONFIG["wsdl_uri"]
7
+ # Fetch social and economic indicators from the Central Bank of Brazil
8
+ # (Banco Central do Brasil) WebService. It fires a SOAP request behind
9
+ # the scenes and parse the result for easy use.
10
+ module BancoCentral
19
11
 
20
- LABELS = CONFIG["labels"]
12
+ CONFIG = YAML.load_file(File.join(File.dirname(__dir__), 'config/labels.yml'))
13
+ WSDL_URI = CONFIG['wsdl_uri']
14
+ LABELS = CONFIG['labels']
21
15
 
22
16
  class << self
23
17
 
24
- def exp(id, log_level: nil, logger: nil)
25
- client(log_level, logger).call(
26
- :get_ultimo_valor_vo,
27
- message: {
28
- in0: get_id(id)
29
- }
30
- )
31
- end
18
+ attr_accessor :log_level
19
+ attr_accessor :logger
32
20
 
33
- def find(id, date, log_level: nil, logger: nil)
34
- client(log_level, logger).call(
21
+ # Get the indicator's value for a specific date. It calls +GetValor+ method
22
+ # from the WebService and returns only a float number.
23
+ #
24
+ # BancoCentral.find(:dolar, "3/7/2014")
25
+ # => 0.75
26
+ def find(id, date)
27
+ client.call(
35
28
  :get_valor,
36
29
  message: {
37
- in0: get_id(id),
30
+ in0: label_to_int(id),
38
31
  in1: date
39
32
  }
40
33
  ).to_hash[:multi_ref].to_f
41
34
  end
42
35
 
43
- def last(id, log_level: nil, logger: nil)
44
- xml = client(log_level, logger).call(
45
- :get_ultimo_valor_xml,
46
- message: {
47
- in0: get_id(id)
48
- }
49
- ).to_hash[:get_ultimo_valor_xml_response][:get_ultimo_valor_xml_return]
36
+ # Get the last value of the an indicator, and also the name, unit, date and
37
+ # periodicity. This method calls +GetUltimoValorXml+ method from the
38
+ # WebService.
39
+ #
40
+ # BancoCentral.last(:dolar)
41
+ # => {
42
+ # :id => 1,
43
+ # :name => "Taxa de câmbio - Livre - Dólar americano (venda) - diário",
44
+ # :unit => "u.m.c./US$",
45
+ # :date => 2016-10-18 00:00:00 -0200,
46
+ # :value => 3.1874,
47
+ # :periodicity => :daily
48
+ # }
49
+ def last(id)
50
+ indicator_xml = sanitize(last_as_xml(id))
51
+ indicator = Nori.new.parse(indicator_xml)['resposta']['SERIE']
52
+ {
53
+ id: label_to_int(id),
54
+ name: indicator['NOME'],
55
+ unit: indicator['UNIDADE'],
56
+ date: parse_date(indicator['DATA']),
57
+ value: parse_value(indicator['VALOR']),
58
+ periodicity: parse_periodicity(indicator['PERIODICIDADE'])
59
+ }
60
+ end
50
61
 
51
- # Prevent exception when parsing if indicator's name has the & character
52
- xml.gsub!(/&(?!(?:amp|lt|gt|quot|apos);)/, '&amp;')
62
+ # Get all the values of the indicator. This method calls
63
+ # +GetValoresSeriesXMLResponse+ method from the WebService.
64
+ #
65
+ # This method accepts a string, symbol or an array of string or
66
+ # symbols as indicator names. In case an array is given, it will
67
+ # return a hash of hashes.
68
+ #
69
+ # BancoCentral.all(:ipca)
70
+ # => {"1/1980"=>"6.62", "2/1980"=>"4.62", ... }
71
+ #
72
+ # BancoCentral.all(:ipca, start: "1/7/2014", finish: "1/8/2014")
73
+ # => {"7/2014"=>"0.01", "8/2014"=>"0.25"}
74
+ #
75
+ # BancoCentral.all([:importacoes, :exportacoes])
76
+ # => {
77
+ # 2946 => {"1/1954"=>"122603000", "2/1954"=>"125851000", ...},
78
+ # 3034 => {"1/1973"=>"370706000", "2/1973"=>"390279000", ...}
79
+ # }
80
+ #
81
+ def all(id, start: nil, finish: nil)
82
+ indicators_xml = all_as_xml(id, start, finish)
83
+ indicators_doc = Nokogiri::XML(indicators_xml, &:noblanks)
84
+
85
+ # Convert response XML to a hash (for one id) or a hash of
86
+ # hashes (for more than one id)
87
+ indicators = {}
88
+ indicators_doc.css('SERIE').each do |serie|
89
+ array = serie.css('DATA, VALOR').map(&:text)
90
+ indicators[serie['ID'].to_i] = Hash[array.each_slice(2).to_a]
91
+ end
53
92
 
54
- hash = Nori.new.parse(xml)["resposta"]["SERIE"]
93
+ id.is_a?(Array) ? indicators : indicators[label_to_int(id)]
94
+ end
55
95
 
56
- {
57
- id: get_id(id),
58
- name: hash["NOME"],
59
- unit: hash["UNIDADE"],
60
- date: parse_date(hash["DATA"]),
61
- value: parse_value(hash["VALOR"]),
62
- periodicity: parse_periodicity(hash["PERIODICIDADE"])
96
+ private
97
+
98
+ # Prevent exception when parsing if indicator's name has the & character
99
+ def sanitize(indicator_name)
100
+ indicator_name.gsub(/&(?!(?:amp|lt|gt|quot|apos);)/, '&amp;')
101
+ end
102
+
103
+ def client
104
+ options = {
105
+ encoding: 'UTF-8',
106
+ ssl_verify_mode: :none,
107
+ wsdl: WSDL_URI
63
108
  }
109
+ if @log_level
110
+ options[:log] = true
111
+ options[:log_level] = @log_level
112
+ options[:logger] = @logger if @logger
113
+ end
114
+ Savon.client(options)
64
115
  end
65
116
 
66
- # BancoCentral.all([:ipca], start: "1/7/2014")
67
- def all(id, start: nil, finish: nil, log_level: nil, logger: nil)
117
+ def last_as_xml(id)
118
+ client
119
+ .call(
120
+ :get_ultimo_valor_xml,
121
+ message: {
122
+ in0: label_to_int(id)
123
+ }
124
+ )
125
+ .to_hash[:get_ultimo_valor_xml_response][:get_ultimo_valor_xml_return]
126
+ .gsub("<?xml version='1.0' encoding='ISO-8859-1'?>\n", '')
127
+ end
68
128
 
69
- # Build request arguments
129
+ def all_as_xml(id, start, finish)
70
130
  ids = id.is_a?(Array) ? id : [id]
131
+
132
+ # Build SOAP request arguments
71
133
  args = {}
72
- ids.each_with_index do |_id, i|
73
- args["ins#{i}:int"] = get_id(_id)
134
+ ids.each_with_index do |indicator_id, i|
135
+ args["ins#{i}:int"] = label_to_int(indicator_id)
74
136
  end
75
137
 
76
138
  # Request the WebService
77
- xml = client(log_level, logger).call(
78
- :get_valores_series_xml,
79
- message: {
80
- in0: args,
81
- in1: start,
82
- in2: finish
83
- }
84
- ).to_hash[:get_valores_series_xml_response][:get_valores_series_xml_return]
85
-
86
- # Convert response XML to a hash (for one id) or a hash of hashes (more than one id)
87
- doc = Nokogiri::XML(xml) { |config| config.noblanks }
88
- data = {}
89
- doc.css("SERIE").each do |serie|
90
- array = serie.css("DATA, VALOR").map(&:text)
91
- data[serie["ID"].to_i] = Hash[array.each_slice(2).to_a]
92
- end
93
-
94
- id.is_a?(Array) ? data : data[get_id(id)]
139
+ client
140
+ .call(
141
+ :get_valores_series_xml,
142
+ message: {
143
+ in0: args,
144
+ in1: start,
145
+ in2: finish
146
+ }
147
+ )
148
+ .to_hash[:get_valores_series_xml_response][:get_valores_series_xml_return]
149
+ .gsub("<?xml version='1.0' encoding='ISO-8859-1'?>\n", '')
95
150
  end
96
151
 
97
- private
98
-
99
- def client(log_level = nil, logger = nil)
100
- options = {
101
- encoding: "UTF-8",
102
- ssl_verify_mode: :none,
103
- wsdl: WSDL_URI
104
- }
105
- if log_level
106
- options[:log] = true
107
- options[:log_level] = log_level # one of [:debug, :info, :warn, :error, :fatal]
108
- options[:logger] = logger if logger
109
- end
110
- Savon.client(options)
111
- end
112
-
113
- def get_id(id)
114
- return id if id.is_a? Integer
152
+ def label_to_int(id)
153
+ if id.is_a? Integer
154
+ id
155
+ else
115
156
  LABELS[id.to_s] || raise(ArgumentError, 'Label not found')
116
157
  end
158
+ end
117
159
 
118
- def parse_periodicity(periodicity)
119
- {"D" => :daily, "M" => :monthly, "T" => :quarterly, "A" => :yearly}[periodicity]
120
- end
121
-
122
- def parse_date(date)
123
- Time.new(date["ANO"], date["MES"], date["DIA"])
124
- end
160
+ def parse_periodicity(periodicity)
161
+ {
162
+ 'D' => :daily,
163
+ 'M' => :monthly,
164
+ 'T' => :quarterly,
165
+ 'A' => :yearly
166
+ }[periodicity]
167
+ end
125
168
 
126
- def parse_value(value)
127
- value.gsub(",", ".").to_f
128
- end
169
+ def parse_date(date)
170
+ Time.new(date['ANO'], date['MES'], date['DIA'])
171
+ end
129
172
 
173
+ def parse_value(value)
174
+ value.tr(',', '.').to_f
175
+ end
130
176
  end
131
-
132
177
  end
@@ -1,3 +1,3 @@
1
1
  module BancoCentral
2
- VERSION = "0.1.2"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: banco_central
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrique G. Testa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-19 00:00:00.000000000 Z
11
+ date: 2017-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon