Add support for local files through open-uri

Some refactoring
Added tests for local files
Bump version to 1.1
This commit is contained in:
sdsykes 2009-06-25 13:04:07 +03:00
parent a12204424d
commit da31ecf44d
4 changed files with 87 additions and 37 deletions

View File

@ -1,4 +1,4 @@
---
:patch: 2
:patch: 0
:major: 1
:minor: 0
:minor: 1

View File

@ -2,7 +2,7 @@
Gem::Specification.new do |s|
s.name = %q{fastimage}
s.version = "1.0.2"
s.version = "1.1.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Stephen Sykes"]

View File

@ -23,6 +23,7 @@
# * http://imagesize.rubyforge.org/
#
require 'net/https'
require 'open-uri'
class FastImage
attr_reader :size, :type
@ -119,51 +120,68 @@ class FastImage
end
def initialize(uri, options={})
@type_only = options[:type_only]
setup_http(uri, options)
@http.request_get(@http_get_path) do |res|
raise ImageFetchFailure unless res.is_a?(Net::HTTPSuccess)
fetch_size_from_response(res)
@property = options[:type_only] ? :type : :size
@timeout = options[:timeout] || DefaultTimeout
@uri = uri
@parsed_uri = URI.parse(uri)
if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https"
fetch_using_http
else
fetch_using_open_uri
end
raise SizeNotFound if options[:raise_on_failure] && !@size
raise SizeNotFound if options[:raise_on_failure] && !@type_only && !@size
rescue Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET, ImageFetchFailure
raise ImageFetchFailure if options[:raise_on_failure]
rescue Errno::ENOENT
raise ImageFetchFailure if options[:raise_on_failure]
rescue UnknownImageType
raise UnknownImageType if options[:raise_on_failure]
end
private
def setup_http(uri, options)
u = URI.parse(uri)
@http = Net::HTTP.new(u.host, u.port)
@http.use_ssl = (u.scheme == "https")
def fetch_using_http
setup_http
@http.request_get(@parsed_uri.request_uri) do |res|
raise ImageFetchFailure unless res.is_a?(Net::HTTPSuccess)
fetch_from_response(res)
end
end
def setup_http
@http = Net::HTTP.new(@parsed_uri.host, @parsed_uri.port)
@http.use_ssl = (@parsed_uri.scheme == "https")
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@http.open_timeout = options[:timeout] || DefaultTimeout
@http.read_timeout = options[:timeout] || DefaultTimeout
@http_get_path = u.request_uri
@http.open_timeout = @timeout
@http.read_timeout = @timeout
end
def fetch_type_from_response(res)
fetch_from_response(res, :type){parse_type}
end
def fetch_size_from_response(res)
fetch_from_response(res, :size){parse_size}
end
def fetch_from_response(res, item)
@unused_str = ""
def fetch_from_response(res)
res.read_body do |str|
@str = @unused_str + str
@strpos = 0
begin
result = yield
if result
instance_variable_set("@#{item}", result)
break
end
rescue MoreCharsNeeded
break if parse_packet(str)
end
end
# returns true once result is achieved
#
def parse_packet(str)
@str = (@unused_str || "") + str
@strpos = 0
begin
result = send("parse_#{@property}")
if result
instance_variable_set("@#{@property}", result)
true
end
rescue MoreCharsNeeded
false
end
end
def fetch_using_open_uri
open(@uri) do |s|
while str = s.read(256)
break if parse_packet(str)
end
end
end

View File

@ -2,11 +2,13 @@ require 'rubygems'
require 'test/unit'
require 'fastimage'
PathHere = File.dirname(__FILE__)
require File.join(PathHere, "..", "lib", 'fastimage')
require 'fakeweb'
FixturePath = File.join(File.dirname(__FILE__), "fixtures")
FixturePath = File.join(PathHere, "fixtures")
GoodFixtures = {
"test.bmp"=>[:bmp, [40, 27]],
@ -75,4 +77,34 @@ class FasImageTest < Test::Unit::TestCase
FastImage.size(TestUrl + "test.ico", :raise_on_failure=>true)
end
end
def test_should_report_type_correctly_for_local_files
GoodFixtures.each do |fn, info|
assert_equal info[0], FastImage.type(File.join(FixturePath, fn))
end
end
def test_should_report_size_correctly_for_local_files
GoodFixtures.each do |fn, info|
assert_equal info[1], FastImage.size(File.join(FixturePath, fn))
end
end
def test_should_return_nil_on_fetch_failure_for_local_path
assert_nil FastImage.size("does_not_exist")
end
def test_should_return_nil_for_faulty_jpeg_where_size_cannot_be_found_for_local_file
assert_nil FastImage.size(File.join(FixturePath, "faulty.jpg"))
end
def test_should_return_nil_when_image_type_not_known_for_local_file
assert_nil FastImage.size(File.join(FixturePath, "test.ico"))
end
def test_should_raise_when_asked_to_when_size_cannot_be_found_for_local_file
assert_raises(FastImage::SizeNotFound) do
FastImage.size(File.join(FixturePath, "faulty.jpg"), :raise_on_failure=>true)
end
end
end