pinch 0.2.1 → 0.3.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.
@@ -13,7 +13,11 @@ if we could bring that functionality to Ruby :)
13
13
 
14
14
  That version is available on https://github.com/epatel/pinch-objc/
15
15
 
16
- I’ve tested Pinch on 1.9.2, 1.8.7 and MacRuby 0.10, YMMV.
16
+ I’ve tested Pinch on 1.9.3, 1.9.2, 1.8.7, MacRuby 0.10, JRuby 1.6.4 and rbx-head, YMMV.
17
+
18
+ The specs currently blows up on MagLev.
19
+
20
+ {<img src="https://secure.travis-ci.org/peterhellberg/pinch.png?branch=master" />}[http://travis-ci.org/peterhellberg/pinch]
17
21
 
18
22
  == Installation
19
23
 
@@ -1,11 +1,12 @@
1
1
  # encoding: utf-8
2
2
  require 'net/https'
3
3
  require 'zlib'
4
+ require 'pinch_response'
4
5
 
5
6
  # @author Peter Hellberg
6
7
  # @author Edward Patel
7
8
  class Pinch
8
- VERSION = "0.2.1"
9
+ VERSION = "0.3.0"
9
10
 
10
11
  attr_reader :uri
11
12
 
@@ -19,8 +20,8 @@ class Pinch
19
20
  #
20
21
  # puts Pinch.get('http://peterhellberg.github.com/pinch/test.zip', 'data.json')
21
22
  #
22
- def self.get(url, file_name)
23
- new(url).get(file_name)
23
+ def self.get(url, file_name, &block)
24
+ new(url).get(file_name, &block)
24
25
  end
25
26
 
26
27
  ##
@@ -53,7 +54,7 @@ class Pinch
53
54
  # Initializes a new Pinch object
54
55
  #
55
56
  # @param [String] url Full URL to the ZIP file
56
- # @param [Strin] redirects (Optional) Number of redirects to follow
57
+ # @param [Fixnum] redirects (Optional) Number of redirects to follow
57
58
  # @note You might want to use Pinch.get instead.
58
59
  #
59
60
  def initialize(url, redirects = 5)
@@ -76,8 +77,8 @@ class Pinch
76
77
  #
77
78
  # @note You might want to use Pinch.get instead
78
79
  #
79
- def get(file_name)
80
- local_file(file_name)
80
+ def get(file_name, &block)
81
+ local_file(file_name, &block)
81
82
  end
82
83
 
83
84
  ##
@@ -137,19 +138,25 @@ private
137
138
  file_headers[file_name][11] +
138
139
  file_headers[file_name][12]
139
140
 
140
- response = fetch_data(offset_start, offset_end)
141
+ if block_given?
142
+ fetch_data(offset_start, offset_end) do |response|
143
+ yield PinchResponse.new(response)
144
+ end
145
+ else
146
+ response = fetch_data(offset_start, offset_end)
141
147
 
142
- local_file_header = response.body.unpack('VvvvvvVVVvv')
143
- file_data = response.body[30+local_file_header[9]+local_file_header[10]..-1]
148
+ local_file_header = response.body.unpack('VvvvvvVVVvv')
149
+ file_data = response.body[30+local_file_header[9]+local_file_header[10]..-1]
144
150
 
145
- if local_file_header[3] == 0
146
- # Uncompressed file
147
- offset = 30+local_file_header[9]+local_file_header[10]
148
- response.body[offset..(offset+local_file_header[8]-1)]
149
- else
150
- # Compressed file
151
- file_data = response.body[30+local_file_header[9]+local_file_header[10]..-1]
152
- Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(file_data)
151
+ if local_file_header[3] == 0
152
+ # Uncompressed file
153
+ offset = 30+local_file_header[9]+local_file_header[10]
154
+ response.body[offset..(offset+local_file_header[8]-1)]
155
+ else
156
+ # Compressed file
157
+ file_data = response.body[30+local_file_header[9]+local_file_header[10]..-1]
158
+ Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(file_data)
159
+ end
153
160
  end
154
161
  end
155
162
 
@@ -198,10 +205,11 @@ private
198
205
 
199
206
  response = fetch_data(offset_start, offset_end)
200
207
 
201
- if [200, 206].include?(response.code)
202
- raise RuntimeError, "Couldn’t find the ZIP file (HTTP: #{response.code})"
203
- else
208
+
209
+ if ['200', '206'].include?(response.code)
204
210
  response.body
211
+ else
212
+ raise RuntimeError, "Couldn’t find the ZIP file (HTTP: #{response.code})"
205
213
  end
206
214
  end
207
215
  end
@@ -237,10 +245,10 @@ private
237
245
 
238
246
  ##
239
247
  # Get range of data from URL
240
- def fetch_data(offset_start, offset_end)
248
+ def fetch_data(offset_start, offset_end, &block)
241
249
  request = Net::HTTP::Get.new(@uri.request_uri)
242
- request.set_range(offset_start, offset_end)
243
- connection(@uri).request(request)
250
+ request.set_range(offset_start..offset_end)
251
+ connection(@uri).request(request, &block)
244
252
  end
245
253
 
246
254
  ##
@@ -0,0 +1,42 @@
1
+ # This class only implements read_body
2
+ # The rest can be implemented when required
3
+ class PinchResponse
4
+ def initialize(http_response)
5
+ @http_response = http_response
6
+ @zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
7
+ @first_chunk = true
8
+ end
9
+
10
+ def read_body
11
+ if block_given?
12
+ @http_response.read_body do |chunk|
13
+ if @first_chunk
14
+ local_file_header = chunk.unpack('VvvvvvVVVvv')
15
+ @offset_start = 30+local_file_header[9]+local_file_header[10]
16
+ @compressed = (local_file_header[3] != 0)
17
+ @length = @compressed ? local_file_header[7] : local_file_header[8]
18
+
19
+ @cursor_start = @offset_start
20
+ @to_be_read = @length
21
+ @first_chunk = false
22
+ end
23
+
24
+ cursor_start = [@cursor_start, 0].max
25
+ cursor_end = [@to_be_read, chunk.length].min
26
+ data = chunk[cursor_start, cursor_end]
27
+ @cursor_start -= chunk.length
28
+
29
+ if data
30
+ @to_be_read -= data.length
31
+ if @compressed
32
+ yield @zstream.inflate(data)
33
+ else
34
+ yield data
35
+ end
36
+ end
37
+ end
38
+ else
39
+ @zstream.inflate @http_response.read_body
40
+ end
41
+ end
42
+ end
@@ -1,6 +1,19 @@
1
+ # encoding: utf-8
2
+
1
3
  # Require psych under MRI to remove warning messages
2
4
  if Object.const_defined?(:RUBY_ENGINE) && RUBY_ENGINE == "ruby"
3
- require 'psych'
5
+ begin
6
+ require 'psych'
7
+ rescue LoadError
8
+ # Psych isn’t installed
9
+ end
10
+ end
11
+
12
+ begin
13
+ gem 'minitest'
14
+ rescue LoadError
15
+ # Run the tests with the built in minitest instead
16
+ # if the gem isn’t installed.
4
17
  end
5
18
 
6
19
  require 'minitest/pride'
@@ -8,10 +21,10 @@ require 'minitest/autorun'
8
21
  require 'minitest/spec'
9
22
  require 'vcr'
10
23
 
11
- VCR.config do |c|
24
+ VCR.configure do |c|
12
25
  c.allow_http_connections_when_no_cassette = true
13
26
  c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
14
- c.stub_with :fakeweb
27
+ c.hook_into :fakeweb
15
28
  end
16
29
 
17
30
  require File.dirname(__FILE__) + '/../lib/pinch'
@@ -69,6 +82,19 @@ describe Pinch do
69
82
  end
70
83
  end
71
84
 
85
+ it "should yield to the block with PinchResponse object similar to HTTPResponse" do
86
+ body = ''
87
+ VCR.use_cassette('test_zip_with_block') do
88
+ Pinch.get(@url, @file) do |response|
89
+ response.must_be_kind_of PinchResponse
90
+ response.read_body do |chunk|
91
+ body << chunk
92
+ end
93
+ end
94
+ end
95
+ body.must_equal @data
96
+ end
97
+
72
98
  it "should retrieve the contents of the file data.json when passed a HTTPS url" do
73
99
  VCR.use_cassette('ssl_test') do
74
100
  @url = 'https://dl.dropbox.com/u/2230186/pinch_test.zip'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,52 +10,41 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-09-08 00:00:00.000000000Z
13
+ date: 2012-05-27 00:00:00.000000000 Z
14
14
  dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: yard
17
- requirement: &70351992865600 !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: '0'
23
- type: :development
24
- prerelease: false
25
- version_requirements: *70351992865600
26
15
  - !ruby/object:Gem::Dependency
27
16
  name: minitest
28
- requirement: &70351992864920 !ruby/object:Gem::Requirement
17
+ requirement: &70160741137260 !ruby/object:Gem::Requirement
29
18
  none: false
30
19
  requirements:
31
- - - ! '>='
20
+ - - ~>
32
21
  - !ruby/object:Gem::Version
33
- version: '0'
22
+ version: '2.12'
34
23
  type: :development
35
24
  prerelease: false
36
- version_requirements: *70351992864920
25
+ version_requirements: *70160741137260
37
26
  - !ruby/object:Gem::Dependency
38
27
  name: fakeweb
39
- requirement: &70351992864160 !ruby/object:Gem::Requirement
28
+ requirement: &70160741136600 !ruby/object:Gem::Requirement
40
29
  none: false
41
30
  requirements:
42
- - - ! '>='
31
+ - - ~>
43
32
  - !ruby/object:Gem::Version
44
- version: '0'
33
+ version: '1.3'
45
34
  type: :development
46
35
  prerelease: false
47
- version_requirements: *70351992864160
36
+ version_requirements: *70160741136600
48
37
  - !ruby/object:Gem::Dependency
49
38
  name: vcr
50
- requirement: &70351992863460 !ruby/object:Gem::Requirement
39
+ requirement: &70160741136020 !ruby/object:Gem::Requirement
51
40
  none: false
52
41
  requirements:
53
- - - ! '>='
42
+ - - ~>
54
43
  - !ruby/object:Gem::Version
55
- version: '0'
44
+ version: '2.0'
56
45
  type: :development
57
46
  prerelease: false
58
- version_requirements: *70351992863460
47
+ version_requirements: *70160741136020
59
48
  description: Pinch makes it possible to download a specific file from within a ZIP
60
49
  file over HTTP 1.1.
61
50
  email: peter@c7.se
@@ -66,6 +55,7 @@ extra_rdoc_files:
66
55
  - MIT-LICENSE
67
56
  files:
68
57
  - lib/pinch.rb
58
+ - lib/pinch_response.rb
69
59
  - MIT-LICENSE
70
60
  - README.rdoc
71
61
  - Rakefile
@@ -96,9 +86,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
86
  version: '0'
97
87
  requirements: []
98
88
  rubyforge_project:
99
- rubygems_version: 1.8.6
89
+ rubygems_version: 1.8.15
100
90
  signing_key:
101
91
  specification_version: 3
102
92
  summary: Retrieve a file from inside a zip file, over the network!
103
93
  test_files:
104
94
  - spec/pinch_spec.rb
95
+ has_rdoc: true