sdsykes-fastimage 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +7 -3
- data/VERSION.yml +2 -2
- data/lib/fastimage.rb +59 -32
- data/test/test.rb +34 -2
- metadata +1 -1
data/README.textile
CHANGED
@@ -14,6 +14,8 @@ FastImage does this minimal fetch for image types GIF, JPEG, PNG and BMP. And i
|
|
14
14
|
|
15
15
|
You only need supply the uri, and FastImage will do the rest.
|
16
16
|
|
17
|
+
Fastimage can also read local (and other) files, and uses the open-uri library to do so.
|
18
|
+
|
17
19
|
h2. Examples
|
18
20
|
|
19
21
|
<pre>
|
@@ -24,6 +26,8 @@ FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
|
|
24
26
|
=> [266, 56] # width, height
|
25
27
|
FastImage.type("http://stephensykes.com/images/pngimage")
|
26
28
|
=> :png
|
29
|
+
FastImage.type("/some/local/file.gif")
|
30
|
+
=> :gif
|
27
31
|
</code>
|
28
32
|
</pre>
|
29
33
|
|
@@ -62,10 +66,10 @@ You'll need to 'sudo gem install fakeweb' to be able to run the tests.
|
|
62
66
|
ruby test/test.rb
|
63
67
|
Loaded suite test/test
|
64
68
|
Started
|
65
|
-
|
66
|
-
Finished in 0.
|
69
|
+
...............
|
70
|
+
Finished in 0.059392 seconds.
|
67
71
|
|
68
|
-
|
72
|
+
15 tests, 27 assertions, 0 failures, 0 errors
|
69
73
|
</code>
|
70
74
|
</pre>
|
71
75
|
|
data/VERSION.yml
CHANGED
data/lib/fastimage.rb
CHANGED
@@ -8,6 +8,11 @@
|
|
8
8
|
#
|
9
9
|
# FastImage knows about GIF, JPEG, BMP and PNG files.
|
10
10
|
#
|
11
|
+
# FastImage can also read files from the local filesystem by supplying the path instead of a uri.
|
12
|
+
# In this case FastImage uses the open-uri library to read the file in chunks of 256 bytes until
|
13
|
+
# it has enough. This is possibly a useful bandwidth-saving feature if the file is on a network
|
14
|
+
# attached disk rather than truly local.
|
15
|
+
#
|
11
16
|
# === Examples
|
12
17
|
# require 'fastimage'
|
13
18
|
#
|
@@ -15,6 +20,8 @@
|
|
15
20
|
# => [266, 56]
|
16
21
|
# FastImage.type("http://stephensykes.com/images/pngimage")
|
17
22
|
# => :png
|
23
|
+
# FastImage.type("/some/local/file.gif")
|
24
|
+
# => :gif
|
18
25
|
#
|
19
26
|
# === References
|
20
27
|
# * http://snippets.dzone.com/posts/show/805
|
@@ -23,6 +30,7 @@
|
|
23
30
|
# * http://imagesize.rubyforge.org/
|
24
31
|
#
|
25
32
|
require 'net/https'
|
33
|
+
require 'open-uri'
|
26
34
|
|
27
35
|
class FastImage
|
28
36
|
attr_reader :size, :type
|
@@ -39,11 +47,13 @@ class FastImage
|
|
39
47
|
end
|
40
48
|
|
41
49
|
DefaultTimeout = 2
|
50
|
+
|
51
|
+
LocalFileChunkSize = 256
|
42
52
|
|
43
53
|
# Returns an array containing the width and height of the image.
|
44
54
|
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
45
55
|
#
|
46
|
-
# By default there is a timeout of 2 seconds for opening and reading from
|
56
|
+
# By default there is a timeout of 2 seconds for opening and reading from a remote server.
|
47
57
|
# This can be changed by passing a :timeout => number_of_seconds in the options.
|
48
58
|
#
|
49
59
|
# If you wish FastImage to raise if it cannot size the image for any reason, then pass
|
@@ -63,6 +73,8 @@ class FastImage
|
|
63
73
|
# => [500, 375]
|
64
74
|
# FastImage.size("http://www-ece.rice.edu/~wakin/images/lena512.bmp")
|
65
75
|
# => [512, 512]
|
76
|
+
# FastImage.size("test/fixtures/test.jpg")
|
77
|
+
# => [882, 470]
|
66
78
|
# FastImage.size("http://pennysmalls.com/does_not_exist")
|
67
79
|
# => nil
|
68
80
|
# FastImage.size("http://pennysmalls.com/does_not_exist", :raise_on_failure=>true)
|
@@ -87,7 +99,7 @@ class FastImage
|
|
87
99
|
# Returns an symbol indicating the image type fetched from a uri.
|
88
100
|
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
89
101
|
#
|
90
|
-
# By default there is a timeout of 2 seconds for opening and reading from
|
102
|
+
# By default there is a timeout of 2 seconds for opening and reading from a remote server.
|
91
103
|
# This can be changed by passing a :timeout => number_of_seconds in the options.
|
92
104
|
#
|
93
105
|
# If you wish FastImage to raise if it cannot find the type of the image for any reason, then pass
|
@@ -105,6 +117,8 @@ class FastImage
|
|
105
117
|
# => :jpg
|
106
118
|
# FastImage.type("http://www-ece.rice.edu/~wakin/images/lena512.bmp")
|
107
119
|
# => :bmp
|
120
|
+
# FastImage.type("test/fixtures/test.jpg")
|
121
|
+
# => :jpg
|
108
122
|
# FastImage.type("http://pennysmalls.com/does_not_exist")
|
109
123
|
# => nil
|
110
124
|
#
|
@@ -119,52 +133,65 @@ class FastImage
|
|
119
133
|
end
|
120
134
|
|
121
135
|
def initialize(uri, options={})
|
122
|
-
@
|
123
|
-
|
124
|
-
@
|
125
|
-
|
126
|
-
|
136
|
+
@property = options[:type_only] ? :type : :size
|
137
|
+
@timeout = options[:timeout] || DefaultTimeout
|
138
|
+
@uri = uri
|
139
|
+
@parsed_uri = URI.parse(uri)
|
140
|
+
if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https"
|
141
|
+
fetch_using_http
|
142
|
+
else
|
143
|
+
fetch_using_open_uri
|
127
144
|
end
|
128
|
-
raise SizeNotFound if options[:raise_on_failure] && !@size
|
145
|
+
raise SizeNotFound if options[:raise_on_failure] && !@type_only && !@size
|
129
146
|
rescue Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET, ImageFetchFailure
|
130
147
|
raise ImageFetchFailure if options[:raise_on_failure]
|
148
|
+
rescue Errno::ENOENT
|
149
|
+
raise ImageFetchFailure if options[:raise_on_failure]
|
131
150
|
rescue UnknownImageType
|
132
151
|
raise UnknownImageType if options[:raise_on_failure]
|
133
152
|
end
|
134
153
|
|
135
154
|
private
|
136
155
|
|
137
|
-
def
|
138
|
-
|
139
|
-
@http
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
156
|
+
def fetch_using_http
|
157
|
+
setup_http
|
158
|
+
@http.request_get(@parsed_uri.request_uri) do |res|
|
159
|
+
raise ImageFetchFailure unless res.is_a?(Net::HTTPSuccess)
|
160
|
+
res.read_body do |str|
|
161
|
+
break if parse_packet(str)
|
162
|
+
end
|
163
|
+
end
|
145
164
|
end
|
146
165
|
|
147
|
-
def
|
148
|
-
|
166
|
+
def setup_http
|
167
|
+
@http = Net::HTTP.new(@parsed_uri.host, @parsed_uri.port)
|
168
|
+
@http.use_ssl = (@parsed_uri.scheme == "https")
|
169
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
170
|
+
@http.open_timeout = @timeout
|
171
|
+
@http.read_timeout = @timeout
|
149
172
|
end
|
150
173
|
|
151
|
-
def
|
152
|
-
|
174
|
+
def fetch_using_open_uri
|
175
|
+
open(@uri) do |s|
|
176
|
+
while str = s.read(LocalFileChunkSize)
|
177
|
+
break if parse_packet(str)
|
178
|
+
end
|
179
|
+
end
|
153
180
|
end
|
154
181
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
166
|
-
rescue MoreCharsNeeded
|
182
|
+
# returns true once result is achieved
|
183
|
+
#
|
184
|
+
def parse_packet(str)
|
185
|
+
@str = (@unused_str || "") + str
|
186
|
+
@strpos = 0
|
187
|
+
begin
|
188
|
+
result = send("parse_#{@property}")
|
189
|
+
if result
|
190
|
+
instance_variable_set("@#{@property}", result)
|
191
|
+
true
|
167
192
|
end
|
193
|
+
rescue MoreCharsNeeded
|
194
|
+
false
|
168
195
|
end
|
169
196
|
end
|
170
197
|
|
data/test/test.rb
CHANGED
@@ -2,11 +2,13 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
|
5
|
-
|
5
|
+
PathHere = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
require File.join(PathHere, "..", "lib", 'fastimage')
|
6
8
|
|
7
9
|
require 'fakeweb'
|
8
10
|
|
9
|
-
FixturePath = File.join(
|
11
|
+
FixturePath = File.join(PathHere, "fixtures")
|
10
12
|
|
11
13
|
GoodFixtures = {
|
12
14
|
"test.bmp"=>[:bmp, [40, 27]],
|
@@ -75,4 +77,34 @@ class FasImageTest < Test::Unit::TestCase
|
|
75
77
|
FastImage.size(TestUrl + "test.ico", :raise_on_failure=>true)
|
76
78
|
end
|
77
79
|
end
|
80
|
+
|
81
|
+
def test_should_report_type_correctly_for_local_files
|
82
|
+
GoodFixtures.each do |fn, info|
|
83
|
+
assert_equal info[0], FastImage.type(File.join(FixturePath, fn))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_report_size_correctly_for_local_files
|
88
|
+
GoodFixtures.each do |fn, info|
|
89
|
+
assert_equal info[1], FastImage.size(File.join(FixturePath, fn))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_return_nil_on_fetch_failure_for_local_path
|
94
|
+
assert_nil FastImage.size("does_not_exist")
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_should_return_nil_for_faulty_jpeg_where_size_cannot_be_found_for_local_file
|
98
|
+
assert_nil FastImage.size(File.join(FixturePath, "faulty.jpg"))
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_should_return_nil_when_image_type_not_known_for_local_file
|
102
|
+
assert_nil FastImage.size(File.join(FixturePath, "test.ico"))
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_should_raise_when_asked_to_when_size_cannot_be_found_for_local_file
|
106
|
+
assert_raises(FastImage::SizeNotFound) do
|
107
|
+
FastImage.size(File.join(FixturePath, "faulty.jpg"), :raise_on_failure=>true)
|
108
|
+
end
|
109
|
+
end
|
78
110
|
end
|