pinch 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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