Start getting middleman-more tests passing. About 50% done
This commit is contained in:
parent
c8a134a386
commit
73913f0ace
97 changed files with 267 additions and 161 deletions
|
@ -198,7 +198,7 @@ class Middleman::Base
|
|||
|
||||
# Automatically loaded extensions
|
||||
# @return [Array<Symbol>]
|
||||
set :default_extensions, [:lorem]
|
||||
set :default_extensions, [ :lorem ]
|
||||
|
||||
# Default layout name
|
||||
# @return [String, Symbold]
|
||||
|
@ -242,6 +242,10 @@ class Middleman::Base
|
|||
Middleman::Extensions::DirectoryIndexes }
|
||||
Middleman::Extensions.register(:lorem) {
|
||||
Middleman::Extensions::Lorem }
|
||||
Middleman::Extensions.register(:automatic_image_sizes) {
|
||||
Middleman::Extensions::AutomaticImageSizes }
|
||||
Middleman::Extensions.register(:asset_host) {
|
||||
Middleman::Extensions::AssetHost }
|
||||
|
||||
# Backwards-compatibility with old request.path signature
|
||||
attr :request
|
||||
|
@ -258,7 +262,7 @@ class Middleman::Base
|
|||
# @return [void]
|
||||
def current_path=(path)
|
||||
@_current_path = path
|
||||
@request = Thor::CoreExt::HashWithIndifferentAccess.new({ :path => path })
|
||||
@request = ::Thor::CoreExt::HashWithIndifferentAccess.new({ :path => path })
|
||||
end
|
||||
|
||||
# Initialize the Middleman project
|
||||
|
|
|
@ -11,7 +11,7 @@ module Middleman::Cli
|
|||
desc "version", "Show version"
|
||||
def version
|
||||
require 'middleman-core/version'
|
||||
say "Middleman #{Middleman::Core::VERSION}"
|
||||
say "Middleman #{Middleman::VERSION}"
|
||||
end
|
||||
|
||||
# Override the Thor help method to find help for subtasks
|
||||
|
|
35
middleman-core/lib/middleman-core/extensions/asset_host.rb
Normal file
35
middleman-core/lib/middleman-core/extensions/asset_host.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
module Middleman::Extensions
|
||||
module AssetHost
|
||||
class << self
|
||||
def registered(app)
|
||||
app.set :asset_host, false
|
||||
|
||||
# app.compass_config do |config|
|
||||
# if asset_host.is_a?(Proc)
|
||||
# config.asset_host(&asset_host)
|
||||
# end
|
||||
# end
|
||||
|
||||
app.send :include, InstanceMethods
|
||||
end
|
||||
alias :included :registered
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def asset_url(path, prefix="")
|
||||
original_output = super
|
||||
return original_output unless asset_host
|
||||
|
||||
# valid_extensions = %w(.png .gif .jpg .jpeg .svg .svgz .js .css)
|
||||
|
||||
asset_prefix = if asset_host.is_a?(Proc)
|
||||
asset_host.call(original_output)
|
||||
elsif asset_host.is_a?(String)
|
||||
asset_host
|
||||
end
|
||||
|
||||
File.join(asset_prefix, original_output)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
38
middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb
Executable file
38
middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb
Executable file
|
@ -0,0 +1,38 @@
|
|||
module Middleman::Extensions
|
||||
module AutomaticImageSizes
|
||||
class << self
|
||||
def registered(app)
|
||||
require "middleman-core/extensions/automatic_image_sizes/fastimage"
|
||||
|
||||
app.send :include, InstanceMethods
|
||||
end
|
||||
alias :included :registered
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def image_tag(path, params={})
|
||||
if !params.has_key?(:width) && !params.has_key?(:height) && !path.include?("://")
|
||||
params[:alt] ||= ""
|
||||
http_prefix = http_images_path rescue images_dir
|
||||
|
||||
begin
|
||||
real_path = File.join(source, images_dir, path)
|
||||
full_path = File.expand_path(real_path, root)
|
||||
http_prefix = http_images_path rescue images_dir
|
||||
if File.exists? full_path
|
||||
dimensions = ::FastImage.size(full_path, :raise_on_failure => true)
|
||||
params[:width] = dimensions[0]
|
||||
params[:height] = dimensions[1]
|
||||
end
|
||||
rescue
|
||||
# $stderr.puts params.inspect
|
||||
end
|
||||
end
|
||||
|
||||
super(path, params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
register :automatic_image_sizes, AutomaticImageSizes
|
||||
end
|
287
middleman-core/lib/middleman-core/extensions/automatic_image_sizes/fastimage.rb
Executable file
287
middleman-core/lib/middleman-core/extensions/automatic_image_sizes/fastimage.rb
Executable file
|
@ -0,0 +1,287 @@
|
|||
# FastImage finds the size or type of an image given its uri.
|
||||
# It is careful to only fetch and parse as much of the image as is needed to determine the result.
|
||||
# It does this by using a feature of Net::HTTP that yields strings from the resource being fetched
|
||||
# as soon as the packets arrive.
|
||||
#
|
||||
# No external libraries such as ImageMagick are used here, this is a very lightweight solution to
|
||||
# finding image information.
|
||||
#
|
||||
# FastImage knows about GIF, JPEG, BMP and PNG files.
|
||||
#
|
||||
# FastImage can also read files from the local filesystem by supplying the path instead of a uri.
|
||||
# In this case FastImage uses the open-uri library to read the file in chunks of 256 bytes until
|
||||
# it has enough. This is possibly a useful bandwidth-saving feature if the file is on a network
|
||||
# attached disk rather than truly local.
|
||||
#
|
||||
# === Examples
|
||||
# require 'fastimage'
|
||||
#
|
||||
# FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
|
||||
# => [266, 56]
|
||||
# FastImage.type("http://stephensykes.com/images/pngimage")
|
||||
# => :png
|
||||
# FastImage.type("/some/local/file.gif")
|
||||
# => :gif
|
||||
#
|
||||
# === References
|
||||
# * http://snippets.dzone.com/posts/show/805
|
||||
# * http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/
|
||||
# * http://pennysmalls.com/2008/08/19/find-jpeg-dimensions-fast-in-ruby/
|
||||
# * http://imagesize.rubyforge.org/
|
||||
#
|
||||
require 'net/https'
|
||||
require 'open-uri'
|
||||
|
||||
class FastImage
|
||||
attr_reader :size, :type
|
||||
|
||||
class FastImageException < StandardError # :nodoc:
|
||||
end
|
||||
class MoreCharsNeeded < FastImageException # :nodoc:
|
||||
end
|
||||
class UnknownImageType < FastImageException # :nodoc:
|
||||
end
|
||||
class ImageFetchFailure < FastImageException # :nodoc:
|
||||
end
|
||||
class SizeNotFound < FastImageException # :nodoc:
|
||||
end
|
||||
|
||||
DefaultTimeout = 2
|
||||
|
||||
LocalFileChunkSize = 256
|
||||
|
||||
# Returns an array containing the width and height of the image.
|
||||
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
||||
#
|
||||
# By default there is a timeout of 2 seconds for opening and reading from a remote server.
|
||||
# This can be changed by passing a :timeout => number_of_seconds in the options.
|
||||
#
|
||||
# If you wish FastImage to raise if it cannot size the image for any reason, then pass
|
||||
# :raise_on_failure => true in the options.
|
||||
#
|
||||
# FastImage knows about GIF, JPEG, BMP and PNG files.
|
||||
#
|
||||
# === Example
|
||||
#
|
||||
# require 'fastimage'
|
||||
#
|
||||
# FastImage.size("http://stephensykes.com/images/ss.com_x.gif")
|
||||
# => [266, 56]
|
||||
# FastImage.size("http://stephensykes.com/images/pngimage")
|
||||
# => [16, 16]
|
||||
# FastImage.size("http://farm4.static.flickr.com/3023/3047236863_9dce98b836.jpg")
|
||||
# => [500, 375]
|
||||
# FastImage.size("http://www-ece.rice.edu/~wakin/images/lena512.bmp")
|
||||
# => [512, 512]
|
||||
# FastImage.size("test/fixtures/test.jpg")
|
||||
# => [882, 470]
|
||||
# FastImage.size("http://pennysmalls.com/does_not_exist")
|
||||
# => nil
|
||||
# FastImage.size("http://pennysmalls.com/does_not_exist", :raise_on_failure=>true)
|
||||
# => raises FastImage::ImageFetchFailure
|
||||
# FastImage.size("http://stephensykes.com/favicon.ico", :raise_on_failure=>true)
|
||||
# => raises FastImage::UnknownImageType
|
||||
# FastImage.size("http://stephensykes.com/favicon.ico", :raise_on_failure=>true, :timeout=>0.01)
|
||||
# => raises FastImage::ImageFetchFailure
|
||||
# FastImage.size("http://stephensykes.com/images/faulty.jpg", :raise_on_failure=>true)
|
||||
# => raises FastImage::SizeNotFound
|
||||
#
|
||||
# === Supported options
|
||||
# [:timeout]
|
||||
# Overrides the default timeout of 2 seconds. Applies both to reading from and opening the http connection.
|
||||
# [:raise_on_failure]
|
||||
# If set to true causes an exception to be raised if the image size cannot be found for any reason.
|
||||
#
|
||||
def self.size(uri, options={})
|
||||
new(uri, options).size
|
||||
end
|
||||
|
||||
# Returns an symbol indicating the image type fetched from a uri.
|
||||
# It will return nil if the image could not be fetched, or if the image type was not recognised.
|
||||
#
|
||||
# By default there is a timeout of 2 seconds for opening and reading from a remote server.
|
||||
# This can be changed by passing a :timeout => number_of_seconds in the options.
|
||||
#
|
||||
# If you wish FastImage to raise if it cannot find the type of the image for any reason, then pass
|
||||
# :raise_on_failure => true in the options.
|
||||
#
|
||||
# === Example
|
||||
#
|
||||
# require 'fastimage'
|
||||
#
|
||||
# FastImage.type("http://stephensykes.com/images/ss.com_x.gif")
|
||||
# => :gif
|
||||
# FastImage.type("http://stephensykes.com/images/pngimage")
|
||||
# => :png
|
||||
# FastImage.type("http://farm4.static.flickr.com/3023/3047236863_9dce98b836.jpg")
|
||||
# => :jpeg
|
||||
# FastImage.type("http://www-ece.rice.edu/~wakin/images/lena512.bmp")
|
||||
# => :bmp
|
||||
# FastImage.type("test/fixtures/test.jpg")
|
||||
# => :jpeg
|
||||
# FastImage.type("http://pennysmalls.com/does_not_exist")
|
||||
# => nil
|
||||
#
|
||||
# === Supported options
|
||||
# [:timeout]
|
||||
# Overrides the default timeout of 2 seconds. Applies both to reading from and opening the http connection.
|
||||
# [:raise_on_failure]
|
||||
# If set to true causes an exception to be raised if the image type cannot be found for any reason.
|
||||
#
|
||||
def self.type(uri, options={})
|
||||
new(uri, options.merge(:type_only=>true)).type
|
||||
end
|
||||
|
||||
def initialize(uri, options={})
|
||||
@property = options[:type_only] ? :type : :size
|
||||
@timeout = options[:timeout] || DefaultTimeout
|
||||
@uri = uri
|
||||
begin
|
||||
@parsed_uri = URI.parse(uri)
|
||||
rescue URI::InvalidURIError
|
||||
fetch_using_open_uri
|
||||
else
|
||||
if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https"
|
||||
fetch_using_http
|
||||
else
|
||||
fetch_using_open_uri
|
||||
end
|
||||
end
|
||||
raise SizeNotFound if options[:raise_on_failure] && @property == :size && !@size
|
||||
rescue Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET,
|
||||
ImageFetchFailure, Net::HTTPBadResponse, EOFError, Errno::ENOENT
|
||||
raise ImageFetchFailure if options[:raise_on_failure]
|
||||
rescue NoMethodError # 1.8.7p248 can raise this due to a net/http bug
|
||||
raise ImageFetchFailure if options[:raise_on_failure]
|
||||
rescue UnknownImageType
|
||||
raise UnknownImageType if options[:raise_on_failure]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_using_http
|
||||
setup_http
|
||||
@http.request_get(@parsed_uri.request_uri) do |res|
|
||||
raise ImageFetchFailure unless res.is_a?(Net::HTTPSuccess)
|
||||
res.read_body do |str|
|
||||
break if parse_packet(str)
|
||||
end
|
||||
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 = @timeout
|
||||
@http.read_timeout = @timeout
|
||||
end
|
||||
|
||||
def fetch_using_open_uri
|
||||
open(@uri) do |s|
|
||||
while str = s.read(LocalFileChunkSize)
|
||||
break if parse_packet(str)
|
||||
end
|
||||
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 parse_size
|
||||
@type = parse_type unless @type
|
||||
@strpos = 0
|
||||
send("parse_size_for_#{@type}")
|
||||
end
|
||||
|
||||
def get_chars(n)
|
||||
if @strpos + n - 1 >= @str.size
|
||||
@unused_str = @str[@strpos..-1]
|
||||
raise MoreCharsNeeded
|
||||
else
|
||||
result = @str[@strpos..(@strpos + n - 1)]
|
||||
@strpos += n
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def get_byte
|
||||
get_chars(1).unpack("C")[0]
|
||||
end
|
||||
|
||||
def read_int(str)
|
||||
size_bytes = str.unpack("CC")
|
||||
(size_bytes[0] << 8) + size_bytes[1]
|
||||
end
|
||||
|
||||
def parse_type
|
||||
case get_chars(2)
|
||||
when "BM"
|
||||
:bmp
|
||||
when "GI"
|
||||
:gif
|
||||
when 0xff.chr + 0xd8.chr
|
||||
:jpeg
|
||||
when 0x89.chr + "P"
|
||||
:png
|
||||
else
|
||||
raise UnknownImageType
|
||||
end
|
||||
end
|
||||
|
||||
def parse_size_for_gif
|
||||
get_chars(11)[6..10].unpack('SS')
|
||||
end
|
||||
|
||||
def parse_size_for_png
|
||||
get_chars(25)[16..24].unpack('NN')
|
||||
end
|
||||
|
||||
def parse_size_for_jpeg
|
||||
loop do
|
||||
@state = case @state
|
||||
when nil
|
||||
get_chars(2)
|
||||
:started
|
||||
when :started
|
||||
get_byte == 0xFF ? :sof : :started
|
||||
when :sof
|
||||
c = get_byte
|
||||
if (0xe0..0xef).include?(c)
|
||||
:skipframe
|
||||
elsif [0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF].detect {|r| r.include? c}
|
||||
:readsize
|
||||
else
|
||||
:skipframe
|
||||
end
|
||||
when :skipframe
|
||||
@skip_chars = read_int(get_chars(2)) - 2
|
||||
:do_skip
|
||||
when :do_skip
|
||||
get_chars(@skip_chars)
|
||||
:started
|
||||
when :readsize
|
||||
s = get_chars(7)
|
||||
return [read_int(s[5..6]), read_int(s[3..4])]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def parse_size_for_bmp
|
||||
d = get_chars(29)[14..28]
|
||||
d.unpack("C")[0] == 40 ? d[4..-1].unpack('LL') : d[4..8].unpack('SS')
|
||||
end
|
||||
end
|
|
@ -1,3 +1,3 @@
|
|||
source :rubygems
|
||||
|
||||
gem "middleman", "~><%= Middleman::Core::VERSION %>"
|
||||
gem "middleman", "~><%= Middleman::VERSION %>"
|
|
@ -1,7 +1,13 @@
|
|||
# Using for version parsing
|
||||
require "rubygems"
|
||||
|
||||
module Middleman
|
||||
module Core
|
||||
# Current Version
|
||||
# @return [String]
|
||||
VERSION = "3.0.0.alpha.6"
|
||||
end
|
||||
# Current Version
|
||||
# @return [String]
|
||||
VERSION = "3.0.0.alpha.7" unless const_defined?(:VERSION)
|
||||
|
||||
# Parsed version for RubyGems
|
||||
# @private
|
||||
# @return [String]
|
||||
GEM_VERSION = ::Gem::Version.create(VERSION) unless const_defined?(:GEM_VERSION)
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue