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.
- data/README.rdoc +5 -1
- data/lib/pinch.rb +31 -23
- data/lib/pinch_response.rb +42 -0
- data/spec/pinch_spec.rb +29 -3
- metadata +17 -26
data/README.rdoc
CHANGED
@@ -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
|
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
|
|
data/lib/pinch.rb
CHANGED
@@ -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.
|
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 [
|
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
|
-
|
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
|
-
|
143
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
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
|
-
|
202
|
-
|
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
|
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
|
data/spec/pinch_spec.rb
CHANGED
@@ -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
|
-
|
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.
|
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.
|
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.
|
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:
|
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: &
|
17
|
+
requirement: &70160741137260 !ruby/object:Gem::Requirement
|
29
18
|
none: false
|
30
19
|
requirements:
|
31
|
-
- -
|
20
|
+
- - ~>
|
32
21
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
22
|
+
version: '2.12'
|
34
23
|
type: :development
|
35
24
|
prerelease: false
|
36
|
-
version_requirements: *
|
25
|
+
version_requirements: *70160741137260
|
37
26
|
- !ruby/object:Gem::Dependency
|
38
27
|
name: fakeweb
|
39
|
-
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: '
|
33
|
+
version: '1.3'
|
45
34
|
type: :development
|
46
35
|
prerelease: false
|
47
|
-
version_requirements: *
|
36
|
+
version_requirements: *70160741136600
|
48
37
|
- !ruby/object:Gem::Dependency
|
49
38
|
name: vcr
|
50
|
-
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: *
|
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.
|
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
|