cbr_converter 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c664f4c5d1454be3586e7b24937b94fe4352efa765413c67811f6c3c5cefe50e
4
+ data.tar.gz: 120252e8dd915afe48f9eeacdf93057be1af5f24dd52bdf4fdc8a4e787506e52
5
+ SHA512:
6
+ metadata.gz: 20720a52af028a621085f437acba845668420584ae16eb9543d48e4cc8ee8b47b95111efd69ae1d82aecaea58d64af74cea334e9fee3c1e7c0ba19b94523b505
7
+ data.tar.gz: e4416761af7d3fe9cb2ea889016f3db434539cc59c82282a3b023565cbd7eff298aee0e8e14ea5d3b6c96cdaf69cb8b4b0192f6930e1acb4e2b55fa05cd2ee91
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ echo "Запуск RuboCop перед коммитом..."
4
+
5
+ bundle exec rubocop -A
6
+
7
+ if [ $? -ne 0 ]; then
8
+ echo "RuboCop нашел сложные ошибки. Исправьте их вручную."
9
+ exit 1
10
+ fi
11
+
12
+ git add .
data/CHANGELOG.md ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Batuev Yakov Denisovich
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # CBR-converter
2
+
3
+ **cbr_converter** — Ruby gem для получения актуальных данных о курсах валют и драгоценных металлов с официального сайта Центрального Банка Российской Федерации. Гем парсит официальные XML-фиды ЦБ и предоставляет удобный интерфейс для работы с данными, включая конвертацию и математические операции.
4
+
5
+ ## Особенности
6
+ - **Актуальные курсы валют** — USD, EUR, CNY и 40+ других валют на текущую дату
7
+ - **Драгоценные металлы** — золото, серебро, платина, палладий в граммах
8
+ - **Операции** — конвертация валют, расчет стоимости металлов, сравнение их между собой
9
+
10
+ ## Установка
11
+
12
+ Вы можете установить гем напрямую:
13
+
14
+ ```bash
15
+ gem install cbr_converter
16
+ ```
17
+
18
+ Или добавьте его в ваш Gemfile:
19
+
20
+ ```ruby
21
+ gem 'cbr_converter'
22
+ ```
23
+
24
+ Затем выполните:
25
+ ```bash
26
+ bundle install
27
+ ```
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test rubocop]
@@ -0,0 +1,327 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CbrConverter
4
+ class CLI
5
+ def initialize
6
+ @running = true
7
+ @commands = {
8
+ "1" => -> { show_currency_rates },
9
+ "2" => ->(currency = nil) { show_currency_rate(currency) },
10
+ "3" => ->(first = nil, second = nil) { compare_currencies(first, second) },
11
+ "4" => -> { show_currencies },
12
+ "5" => ->(amount = nil, from = nil, to = nil) { convert_currency(amount, from, to) },
13
+ "6" => -> { refresh_currency_rates },
14
+ "7" => -> { show_metals_rates },
15
+ "8" => ->(metal = nil) { show_metal_rate(metal) },
16
+ "9" => ->(first = nil, second = nil) { compare_metals(first, second) },
17
+ "10" => -> { show_metals },
18
+ "11" => ->(amount = nil, from = nil, to = nil) { convert_metals(amount, from, to) },
19
+ "12" => -> { refresh_metals_rates },
20
+ "13" => -> { show_help },
21
+ "14" => -> { exit_console }
22
+ }
23
+ end
24
+
25
+ def self.start
26
+ new.start
27
+ end
28
+
29
+ def start
30
+ puts "CBR Converter - Консольное приложение"
31
+ puts "Курсы валют ЦБ РФ"
32
+ show_help
33
+ run
34
+ end
35
+
36
+ private
37
+
38
+ def run
39
+ while @running
40
+ print "\n> "
41
+ input = gets.chomp.strip
42
+ parse_and_execute(input)
43
+ end
44
+ end
45
+
46
+ def parse_and_execute(input)
47
+ return if input.empty?
48
+
49
+ parts = input.split
50
+ command = parts[0].downcase
51
+ args = parts[1..]
52
+
53
+ if @commands.key?(command)
54
+ @commands[command].call(*args)
55
+ else
56
+ puts "Неизвестная команда: #{command}"
57
+ puts "Введите 'help' для списка доступных команд"
58
+ end
59
+ rescue CbrConverter::Error => e
60
+ puts "Ошибка: #{e.message}"
61
+ rescue StandardError => e
62
+ puts "Произошла ошибка: #{e.message}"
63
+ end
64
+
65
+ def show_help
66
+ puts "\nДоступные команды:"
67
+ puts "Команды для валют:"
68
+ puts " 1. - Показать все курсы валют"
69
+ puts " 2. <код валюты> - Показать курс конкретной валюты"
70
+ puts " 3. <валюта1> <валюта2> - Сравнить две валюты"
71
+ puts " 4. - Показать список доступных валют"
72
+ puts " 5. <сумма> <из> <в> - Конвертировать сумму из одной валюты в другую"
73
+ puts " 6. - Обновить курсы валют"
74
+ puts "Команды для металлов:"
75
+ puts " 7. - Показать все курсы металлов"
76
+ puts " 8. <код металла> - Показать конкретный металл"
77
+ puts " 9. <металл1> <металл2> - Сравнить два металла"
78
+ puts " 10. - Показать список доступных металлов"
79
+ puts " 11. <вес> <из> <в> - Конвертировать вес из одного металла другой"
80
+ puts " 12. - Обновить курсы металлов"
81
+ puts "Дополнительные команды:"
82
+ puts " 13. - Показать справку"
83
+ puts " 14. - Выйти из программы"
84
+ puts "\nПримеры:"
85
+ puts " 2 USD"
86
+ puts " 3 USD EUR"
87
+ puts " 5 100 USD RUB"
88
+ puts " 5 50.5 EUR USD"
89
+ puts " 11 1.1 gold silver"
90
+ puts " 8 gold"
91
+ end
92
+
93
+ def show_currency_rates
94
+ puts "\nТекущие курсы валют (1 единица валюты в рублях):"
95
+ puts "-" * 50
96
+
97
+ rates = CbrConverter.current_currency_rates
98
+ rates = rates.sort_by { |currency, _| currency }.to_h
99
+
100
+ rates.each_key do |currency|
101
+ next if currency == "RUB"
102
+
103
+ value = CbrConverter.get_currency_rate(currency)
104
+ puts " #{currency.ljust(5)}: #{format_rate(value)} руб."
105
+ end
106
+
107
+ puts "\n RUB : 1.00 руб."
108
+ puts "-" * 50
109
+ puts "Всего валют: #{rates.size - 1}"
110
+ puts "Данные от: #{Time.now.strftime("%d.%m.%Y %H:%M")}"
111
+ end
112
+
113
+ def show_currency_rate(currency)
114
+ if currency.nil?
115
+ puts "Использование: 2 <код валюты>"
116
+ puts "Пример: 2 USD"
117
+ return
118
+ end
119
+
120
+ currency = currency.upcase
121
+ rate = CbrConverter.get_currency_rate(currency)
122
+
123
+ puts "\nКурс #{currency}:"
124
+ puts " 1 #{currency} = #{format_rate(rate)} руб."
125
+ rescue CbrConverter::Error
126
+ puts "Валюта '#{currency}' не найдена. Используйте 4 для просмотра доступных валют."
127
+ end
128
+
129
+ def compare_currencies(first, second)
130
+ if first.nil? || second.nil?
131
+ puts "Использование: 3 <валюта1> <валюта2>"
132
+ puts "Пример: 3 USD EUR"
133
+ return
134
+ end
135
+
136
+ first = first.upcase
137
+ second = second.upcase
138
+
139
+ ratio = CbrConverter.compare_currencies(first, second)
140
+
141
+ puts "\nСравнение #{first} и #{second}:"
142
+ puts " 1 #{first} = #{format_rate(ratio)} #{second}"
143
+
144
+ reverse_ratio = 1.0 / ratio
145
+ puts " #{format("%.4f", reverse_ratio).gsub(/\.?0+$/, "")} #{first} = 1 #{second}"
146
+ rescue CbrConverter::Error => e
147
+ puts "Ошибка: #{e.message}"
148
+ end
149
+
150
+ def show_currencies
151
+ currencies = CbrConverter.available_currencies
152
+ currencies.delete("RUB")
153
+
154
+ puts "\nДоступные валюты (#{currencies.size}):"
155
+ puts "-" * 50
156
+
157
+ currencies.each_slice(10) do |slice|
158
+ puts " #{slice.join(" ")}"
159
+ end
160
+ end
161
+
162
+ def convert_currency(amount, from, to)
163
+ if amount.nil? || from.nil? || to.nil?
164
+ puts "Использование: 5 <сумма> <из валюты> <в валюту>"
165
+ puts "Пример: 5 100 USD RUB"
166
+ puts "Пример: 5 50.5 EUR USD"
167
+ return
168
+ end
169
+
170
+ begin
171
+ amount = Float(amount)
172
+ rescue ArgumentError
173
+ puts "Ошибка: сумма должна быть числом"
174
+ return
175
+ end
176
+
177
+ from = from.upcase
178
+ to = to.upcase
179
+
180
+ from_rate = CbrConverter.get_currency_rate(from)
181
+ to_rate = CbrConverter.get_currency_rate(to)
182
+
183
+ result_in_rub = amount * from_rate
184
+ result = BigDecimal(result_in_rub / to_rate).to_s
185
+
186
+ puts "\nРезультат конвертации:"
187
+ puts " #{format_number(amount)} #{from} = #{format_number(result)} #{to}"
188
+ puts " Курс: 1 #{from} = #{format_rate(from_rate)} руб."
189
+ puts " Курс: 1 #{to} = #{format_rate(to_rate)} руб."
190
+ rescue CbrConverter::Error => e
191
+ puts "Ошибка: #{e.message}"
192
+ end
193
+
194
+ def refresh_currency_rates
195
+ puts "Обновление курсов валют..."
196
+ CbrConverter.refresh_rates!
197
+ puts "Курсы успешно обновлены!"
198
+ end
199
+
200
+ def show_metals_rates
201
+ puts "\nТекущие курсы металлов (1 единица валюты в рублях):"
202
+ puts "-" * 50
203
+
204
+ rates = CbrConverter.current_metal_rates
205
+ rates = rates.sort_by { |metal, _| metal }.to_h
206
+
207
+ rates.each_key do |metal|
208
+ value = CbrConverter.get_metal_rate(metal)
209
+ puts " #{metal.to_s.ljust(11)}: #{format_rate(value)} руб."
210
+ end
211
+
212
+ puts "-" * 50
213
+ puts "Всего металлов: #{rates.size - 1}"
214
+ puts "Данные от: #{Time.now.strftime("%d.%m.%Y %H:%M")}"
215
+ end
216
+
217
+ def show_metal_rate(metal)
218
+ if metal.nil?
219
+ puts "Использование: 8 <код металла>"
220
+ puts "Пример: 8 gold"
221
+ return
222
+ end
223
+
224
+ metal = metal.downcase
225
+ rate = CbrConverter.get_metal_rate(metal)
226
+
227
+ puts "\nКурс #{metal}:"
228
+ puts " 1г. #{metal} = #{format_rate(rate)} руб."
229
+ rescue CbrConverter::Error
230
+ puts "Металл '#{metal}' не найден. Используйте 10 для просмотра доступных металлов."
231
+ end
232
+
233
+ def compare_metals(first, second)
234
+ if first.nil? || second.nil?
235
+ puts "Использование: 9 <металл1> <металл2>"
236
+ puts "Пример: 9 gold silver"
237
+ return
238
+ end
239
+
240
+ first = first.downcase
241
+ second = second.downcase
242
+
243
+ ratio = CbrConverter.compare_metals(first, second)
244
+
245
+ puts "\nСравнение #{first} и #{second}:"
246
+ puts " 1г. #{first} = #{format_rate(ratio)} #{second}"
247
+
248
+ reverse_ratio = 1.0 / ratio
249
+ puts " #{format("%.4f", reverse_ratio).gsub(/\.?0+$/, "")} #{first} = 1г. #{second}"
250
+ rescue CbrConverter::Error => e
251
+ puts "Ошибка: #{e.message}"
252
+ end
253
+
254
+ def show_metals
255
+ metals = CbrConverter.available_metals
256
+ puts "\nДоступные металлы (#{metals.size}):"
257
+ puts "-" * 50
258
+
259
+ metals.each_slice(5) do |slice|
260
+ puts " #{slice.join(" ")}"
261
+ end
262
+ end
263
+
264
+ def convert_metals(amount, from, to)
265
+ if amount.nil? || from.nil? || to.nil?
266
+ puts "Использование: 1 <вес> <из металла> <в металл>"
267
+ puts "Пример: 11 10 gold silver"
268
+ puts "Пример: 11 27.5 silver gold"
269
+ return
270
+ end
271
+
272
+ begin
273
+ amount = Float(amount)
274
+ rescue ArgumentError
275
+ puts "Ошибка: вес должна быть числом"
276
+ return
277
+ end
278
+
279
+ from = from.downcase
280
+ to = to.downcase
281
+
282
+ from_rate = CbrConverter.get_metal_rate(from)
283
+ to_rate = CbrConverter.get_metal_rate(to)
284
+
285
+ result_in_rub = amount * from_rate
286
+ result = BigDecimal(result_in_rub / to_rate).to_s
287
+
288
+ puts "\nРезультат конвертации:"
289
+ puts " #{format_number(amount)}г. #{from} = #{format_number(result)}г. #{to}"
290
+ puts " Курс: 1г. #{from} = #{format_rate(from_rate)} руб."
291
+ puts " Курс: 1г. #{to} = #{format_rate(to_rate)} руб."
292
+ rescue CbrConverter::Error => e
293
+ puts "Ошибка: #{e.message}"
294
+ end
295
+
296
+ def refresh_metals_rates
297
+ puts "Обновление курсов металлов..."
298
+ CbrConverter.refresh_rates!
299
+ puts "Металлы успешно обновлены!"
300
+ end
301
+
302
+ def exit_console
303
+ puts "\nДо свидания!"
304
+ @running = false
305
+ end
306
+
307
+ def format_rate(rate)
308
+ rate.to_s("F")
309
+ end
310
+
311
+ def format_number(number)
312
+ if number.is_a?(BigDecimal)
313
+ formatted = number.to_s("F")
314
+ else
315
+ formatted = format("%.4f", number)
316
+ formatted.gsub!(/\.?0+$/, "")
317
+ end
318
+ formatted
319
+ end
320
+ end
321
+
322
+ # Запуск приложения
323
+ if __FILE__ == $PROGRAM_NAME
324
+ console = CbrConverterConsole.new
325
+ console.start
326
+ end
327
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "nokogiri"
6
+ require "bigdecimal"
7
+
8
+ module CbrConverter
9
+ class CurrencyParser
10
+ URL = "http://www.cbr.ru/scripts/XML_daily.asp"
11
+
12
+ def fetch_rates
13
+ response = Net::HTTP.get_response(URI.parse(URL))
14
+
15
+ raise Error, "Сервер ЦБ не доступен: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
16
+
17
+ response.body
18
+ end
19
+
20
+ def parse_rates
21
+ doc = Nokogiri::XML(fetch_rates)
22
+ rates = {}
23
+
24
+ doc.xpath("//Valute").each do |valute_node|
25
+ char_code, rate = extract_rate(valute_node)
26
+ rates[char_code] = rate if char_code
27
+ end
28
+
29
+ rates
30
+ end
31
+
32
+ private
33
+
34
+ def extract_rate(node)
35
+ char_code = node.at_xpath("CharCode")&.text
36
+ value_text = node.at_xpath("Value")&.text
37
+ nominal_text = node.at_xpath("Nominal")&.text
38
+
39
+ return nil if [char_code, value_text, nominal_text].any?(&:nil?)
40
+
41
+ value = BigDecimal(value_text.gsub(",", "."))
42
+ nominal = BigDecimal(nominal_text)
43
+
44
+ return nil if nominal.zero?
45
+
46
+ [char_code, value / nominal]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "nokogiri"
6
+ require "bigdecimal"
7
+ require "date"
8
+
9
+ module CbrConverter
10
+ class MetalsParser
11
+ BASE_URL = "http://www.cbr.ru/scripts/xml_metall.asp"
12
+ METALS = {
13
+ "1" => :gold,
14
+ "2" => :silver,
15
+ "3" => :platinum,
16
+ "4" => :palladium
17
+ }.freeze
18
+
19
+ def fetch_rates
20
+ date = Date.today
21
+ attempts = 0
22
+
23
+ while attempts < 7
24
+ formatted_date = (date - attempts).strftime("%d/%m/%Y")
25
+ url = "#{BASE_URL}?date_req1=#{formatted_date}&date_req2=#{formatted_date}"
26
+
27
+ response = Net::HTTP.get_response(URI.parse(url))
28
+
29
+ return response.body if response.is_a?(Net::HTTPSuccess) && contains_data?(response.body)
30
+
31
+ attempts += 1
32
+ end
33
+ raise Error, "Не удалось получить данные по металлам за последнюю неделю"
34
+ end
35
+
36
+ def parse_rates
37
+ doc = Nokogiri::XML(fetch_rates)
38
+ rates = {}
39
+
40
+ doc.xpath("//Record").each do |record_node|
41
+ metal_name, price = extract_metal_data(record_node)
42
+ rates[metal_name] = price if metal_name
43
+ end
44
+
45
+ rates
46
+ end
47
+
48
+ private
49
+
50
+ def contains_data?(xml_body)
51
+ doc = Nokogiri::XML(xml_body)
52
+ doc.xpath("//Record").any?
53
+ end
54
+
55
+ def extract_metal_data(node)
56
+ code = node["Code"]
57
+ buy_text = node.at_xpath("Buy")&.text
58
+ return nil if code.nil? || buy_text.nil?
59
+
60
+ metal_name = METALS[code]
61
+ price = BigDecimal(buy_text.gsub(",", "."))
62
+
63
+ [metal_name, price]
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CbrConverter
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cbr_converter/version"
4
+ require_relative "cbr_converter/currency_parser"
5
+ require_relative "cbr_converter/metal_parser"
6
+ require_relative "cbr_converter/console"
7
+
8
+ module CbrConverter
9
+ class Error < StandardError; end
10
+
11
+ def self.current_currency_rates
12
+ @current_currency_rates ||= begin
13
+ parser = CurrencyParser.new.parse_rates
14
+ parser["RUB"] = BigDecimal("1.0")
15
+ parser
16
+ end
17
+ end
18
+
19
+ def self.current_metal_rates
20
+ @current_metal_rates ||= MetalsParser.new.parse_rates
21
+ end
22
+
23
+ def self.get_currency_rate(currency)
24
+ rates = current_currency_rates
25
+
26
+ raise Error, "Валюта (#{currency}) не найдена в данных ЦБ" unless rates[currency]
27
+
28
+ rates[currency].truncate(4)
29
+ end
30
+
31
+ def self.get_metal_rate(metal)
32
+ rates = current_metal_rates
33
+ metal_sym = metal.to_sym
34
+
35
+ raise Error, "Металл (#{metal}) не найден в данных ЦБ" unless rates[metal_sym]
36
+
37
+ rates[metal_sym].truncate(4)
38
+ end
39
+
40
+ def self.compare_currencies(first_currency, second_currency)
41
+ first_rate = get_currency_rate(first_currency)
42
+ second_rate = get_currency_rate(second_currency)
43
+
44
+ (first_rate / second_rate).truncate(4)
45
+ end
46
+
47
+ def self.compare_metals(first_metal, second_metal)
48
+ first_rate = get_metal_rate(first_metal)
49
+ second_rate = get_metal_rate(second_metal)
50
+
51
+ (first_rate / second_rate).truncate(4)
52
+ end
53
+
54
+ def self.available_currencies
55
+ current_currency_rates.keys.sort
56
+ end
57
+
58
+ def self.available_metals
59
+ current_metal_rates.keys.sort
60
+ end
61
+
62
+ def self.refresh_rates!
63
+ @current_currency_rates = nil
64
+ end
65
+
66
+ def self.refresh_metals!
67
+ @current_metal_rates = nil
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module CbrConverter
2
+ VERSION: String
3
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cbr_converter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Batuev Yakov Denisovich
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: httparty
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.21'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.21'
26
+ - !ruby/object:Gem::Dependency
27
+ name: nokogiri
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.15'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.15'
40
+ description: Позволяет получать актуальные данные XML с сайта Центрального Банка РФ
41
+ и выполнять конвертацию.
42
+ email:
43
+ - batuev@sfedu.ru
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".githooks/pre-commit"
49
+ - CHANGELOG.md
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - lib/cbr_converter.rb
54
+ - lib/cbr_converter/console.rb
55
+ - lib/cbr_converter/currency_parser.rb
56
+ - lib/cbr_converter/metal_parser.rb
57
+ - lib/cbr_converter/version.rb
58
+ - sig/cbr_converter.rbs
59
+ homepage: https://github.com/NeMoYaxa/CBR-converter
60
+ licenses:
61
+ - MIT
62
+ metadata:
63
+ homepage_uri: https://github.com/NeMoYaxa/CBR-converter
64
+ source_code_uri: https://github.com/NeMoYaxa/CBR-converter
65
+ changelog_uri: https://github.com/NeMoYaxa/CBR-converter/blob/main/CHANGELOG.md
66
+ rubygems_mfa_required: 'true'
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 3.2.0
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubygems_version: 4.0.6
82
+ specification_version: 4
83
+ summary: Библиотека для конвертации валют и драгоценных металлов по курсам ЦБ РФ.
84
+ test_files: []