banco_central 0.1.2 → 1.0.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
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