bestchange-api 0.7 → 1.1

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
  SHA256:
3
- metadata.gz: a4519573ffcd91610bf68a30544ebd17c00506ab8c052b5412b74ff348f07d8a
4
- data.tar.gz: c6e1e36c2ed0d7c35a374e00576c8c5de2f433e86edb986a0ceaf5e17a04e167
3
+ metadata.gz: 5dbecec983d7bc4299795c4ef489c5c63c6e90c33ef70144c8521bd2420fd067
4
+ data.tar.gz: 2e2196a4c4c458d42ec13dd530e423db8b0a9016636be8a1b074a5bfc771a395
5
5
  SHA512:
6
- metadata.gz: 8677e25eb2333d11e437e0b06eb64bcc122994b12fba0b81693e10dee37a6f31ce71d47a3f124929dafd865d72280db7e37df2c3109c7f0c4d2231c7b7d89c84
7
- data.tar.gz: 5459ab729ad2777e2981b8ba1b55fd37a88a8720d85ddbf18167dcb2587c095b0c5ba6e85f1a2583cad53446545ad569e77fcbc53491f71134cc53d867285e02
6
+ metadata.gz: 61a22cb80ad3c8f6abec0da2dcca59f3a5829b0be7211b14e45e432196d6fc1c581b80420351d9dad1b2cff154a1755a67a3b92355be4d182f63096a6cd58bda
7
+ data.tar.gz: b837ec968c2959340e7363f7ea3c6f40f1c47e2b991f729df190fe67dc2d0d27fa6394b1f2933581a1055f810c7b1a81f00afbf6bd1b9d0587faff2436686e8a
data/.rubocop.yml CHANGED
@@ -1,3 +1,5 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1.3
1
3
  Style/Documentation:
2
4
  Enabled: false
3
5
  Metrics/MethodLength:
data/CHANGELOG.md CHANGED
@@ -1,7 +1,13 @@
1
1
  # Change log
2
2
 
3
+ ## [1.1]
4
+ Fix tempfile location
5
+
6
+ ## [1.0]
7
+ Add new Api interface, introduce Zip objects
8
+
3
9
  ## [0.7]
4
- Small improvements
10
+ Minor improvements
5
11
 
6
12
  ## [0.6]
7
13
  Pass zip entry via before_extract block
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bestchange-api (0.7)
4
+ bestchange-api (1.0)
5
5
  rubyzip (= 2.3.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  # bestchange-api
2
3
 
3
4
  bestchange-api is a simple library for getting data from Bestchange aggregator
@@ -21,31 +22,61 @@ Or install it yourself as:
21
22
  ## Usage
22
23
  [Bestchange api description](https://github.com/karpinovsky/bestchange-api/blob/master/API_DOC.txt)
23
24
 
24
- Add your own configuration or use the default one
25
+ ### info.zip
25
26
 
26
27
  ```ruby
27
28
  require 'bestchange'
28
29
 
29
- Bestchange.configure do |config|
30
- config.dir = "path/to/your/custom/folder" # default is Dir.pwd
31
- config.timeout = 20 # Timeout for getting & parsing data, default is 40
32
- end
30
+ api_client = Bestchange::Api.new
31
+ response = api_client.request # this will call api.bestchange.ru/info.zip by default
32
+ archive = Bestchange::ZipBuilder.new(response.body).call
33
+ tempfile = Bestchange::ZipExtractor.new(archive).call('bm_rates.dat')
33
34
  ```
34
35
 
35
- Fetch data
36
+ **NOTE**: Do not forget to close and unlink files at the end
36
37
  ```ruby
37
- Bestchange::Api.get_files(['bm_rates.dat']) # => [File]
38
+ archive.close
39
+ tempfile.close
38
40
  ```
39
- ### &before_extract
40
- You can also pass a block that will be called before `Zip::Entry#extract`. It might be helpful if you need to remove existed files or change files destination for example
41
+
42
+ ### Using blocks
43
+ The `Bestchange::ZipBuilder` and `Bestchange::ZipExtractor` classes support using blocks to ensure that tempfiles are closed automatically. This is useful when you want to avoid manual file management and prevent possible leaks
41
44
  ```ruby
42
- before_extract = ->(_zip_entry, pathname) do
43
- pathname.delete if pathname.exist?
45
+ response = Bestchange::Api.new.request
46
+
47
+ Bestchange::ZipBuilder.new(response.body).call do |archive|
48
+ # Work with archive here
49
+ # archive will be closed automatically when the block finishes
50
+ Bestchange::ZipExtractor.new(archive).call('bm_rates.dat') do |bm_rates|
51
+ # Work with bm_rates here
52
+ # bm_rates will be closed automatically when the block finishes
53
+ end
44
54
  end
55
+ ```
56
+
57
+ ### Custom connection
58
+ You can pass your own http connection object while initializing an api client. This can be useful if you want to set custom timeouts, for example
59
+ ```ruby
60
+ require 'bestchange'
45
61
 
46
- Bestchange::Api.get_files(['bm_rates.dat'], &before_extract)
62
+ uri = URI(Bestchange::Api::BASE_URI)
63
+ conn = Net::HTTP.new(uri.host, uri.port)
64
+ conn.open_timeout = 5
65
+ conn.read_timeout = 10
66
+ api_client = Bestchange::Api.new(conn)
47
67
  ```
48
68
 
69
+ ### Custom request
70
+ You can provide your own http request object to the `#request` method
71
+ ```ruby
72
+ require 'bestchange'
73
+
74
+ request = Net::HTTP::Head.new(URI(Bestchange::Api::BASE_URI))
75
+ response = api_client.request(request)
76
+ created_at = response['Date']
77
+ ```
78
+
79
+
49
80
  ## License
50
81
 
51
82
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -7,49 +7,27 @@ require 'timeout'
7
7
  require 'zip'
8
8
 
9
9
  module Bestchange
10
- module Api
11
- extend self
10
+ class Api
11
+ BASE_URI = 'http://api.bestchange.ru/info.zip'
12
12
 
13
- def get_files(filenames, &before_extract)
14
- Timeout.timeout(Bestchange.configuration.timeout) do
15
- fetch_files(filenames, &before_extract)
16
- end
13
+ def initialize(conn = default_conn)
14
+ @conn = conn
17
15
  end
18
16
 
19
- private
17
+ attr_reader :conn
20
18
 
21
- def fetch_files(filenames, &before_extract)
22
- response = make_request
23
- archive = make_archive(response)
24
- extract_files(archive, filenames, &before_extract)
25
- ensure
26
- archive.close if defined?(archive)
19
+ def request(request = default_request)
20
+ conn.request(request)
27
21
  end
28
22
 
29
- def make_request
30
- Net::HTTP.get(URI(BASE_URI))
31
- end
23
+ private
32
24
 
33
- def make_archive(response)
34
- archive = Tempfile.new(ARCHIVE_DATA_FILENAME, encoding: ARCHIVE_DATA_ENCODING)
35
- archive.write(response)
36
- archive
25
+ def default_conn
26
+ Net::HTTP.new(URI(BASE_URI).host, URI(BASE_URI).port)
37
27
  end
38
28
 
39
- def extract_files(archive, filenames, &before_extract)
40
- Zip::File.open(archive) do |zip_file|
41
- filenames.map do |filename|
42
- entry = zip_file.find_entry(filename)
43
-
44
- pathname = Pathname.new(Bestchange.configuration.dir).join(filename)
45
-
46
- before_extract&.call(entry, pathname)
47
-
48
- zip_file.extract(entry, pathname)
49
-
50
- pathname.open
51
- end
52
- end
29
+ def default_request
30
+ Net::HTTP::Get.new(URI(BASE_URI))
53
31
  end
54
32
  end
55
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bestchange
4
- VERSION = '0.7'
4
+ VERSION = '1.1'
5
5
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bestchange
4
+ class ZipBuilder
5
+ ARCHIVE_DATA_ENCODING = 'ASCII-8BIT'
6
+
7
+ def initialize(response_body)
8
+ @response_body = response_body
9
+ end
10
+
11
+ def call
12
+ zip_file = Tempfile.new('', encoding: ARCHIVE_DATA_ENCODING)
13
+ zip_file.write(@response_body)
14
+ zip_file.rewind
15
+
16
+ if block_given?
17
+ begin
18
+ yield zip_file
19
+ ensure
20
+ zip_file.close
21
+ end
22
+ else
23
+ zip_file
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zip'
4
+
5
+ module Bestchange
6
+ class ZipExtractor
7
+ def initialize(zip_file)
8
+ @zip_file = zip_file
9
+ end
10
+
11
+ def call(filename)
12
+ tempfile = Tempfile.new(filename)
13
+
14
+ Zip::File.open(@zip_file) do |zip_file|
15
+ entry = zip_file.find_entry(filename)
16
+
17
+ entry.extract(tempfile) { true }
18
+ end
19
+
20
+ tempfile.rewind
21
+
22
+ if block_given?
23
+ begin
24
+ yield tempfile
25
+ ensure
26
+ tempfile.close
27
+ end
28
+ else
29
+ tempfile
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/bestchange.rb CHANGED
@@ -1,24 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'bestchange/api'
4
- require_relative 'bestchange/configuration'
4
+ require_relative 'bestchange/zip_builder'
5
+ require_relative 'bestchange/zip_extractor'
5
6
 
6
7
  module Bestchange
7
- ARCHIVE_DATA_FILENAME = 'info.zip'
8
- ARCHIVE_DATA_ENCODING = 'ASCII-8BIT'
9
-
10
- BASE_URI = "http://api.bestchange.ru/#{ARCHIVE_DATA_FILENAME}".freeze
11
-
12
- DIRECTORY = Dir.pwd
13
- TIMEOUT = 40
14
-
15
- def self.configuration
16
- @configuration ||= Configuration.new
17
- end
18
-
19
- def self.configure
20
- return configuration unless block_given?
21
-
22
- yield(configuration)
23
- end
24
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bestchange-api
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.7'
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kirill Karpinovsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-17 00:00:00.000000000 Z
11
+ date: 2023-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -89,8 +89,9 @@ files:
89
89
  - bin/setup
90
90
  - lib/bestchange.rb
91
91
  - lib/bestchange/api.rb
92
- - lib/bestchange/configuration.rb
93
92
  - lib/bestchange/version.rb
93
+ - lib/bestchange/zip_builder.rb
94
+ - lib/bestchange/zip_extractor.rb
94
95
  homepage: https://github.com/karpinovsky/bestchange-api
95
96
  licenses:
96
97
  - MIT
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bestchange
4
- class Configuration
5
- def dir
6
- @dir || Bestchange::DIRECTORY
7
- end
8
-
9
- def timeout
10
- @timeout || Bestchange::TIMEOUT
11
- end
12
-
13
- attr_writer :dir, :timeout
14
- end
15
- end