125 lines
2.2 KiB
Ruby
125 lines
2.2 KiB
Ruby
require 'rubygems'
|
|
require 'rack'
|
|
|
|
module Sinatra
|
|
|
|
Result = Struct.new(:block, :params)
|
|
|
|
class Event
|
|
|
|
URI_CHAR = '[^/?:,&#]'.freeze unless defined?(URI_CHAR)
|
|
PARAM = /:(#{URI_CHAR}+)/.freeze unless defined?(PARAM)
|
|
|
|
attr_reader :path, :block, :param_keys, :pattern
|
|
|
|
def initialize(path, &b)
|
|
@path = path
|
|
@block = b
|
|
@param_keys = []
|
|
regex = @path.to_s.gsub(PARAM) do
|
|
@param_keys << $1.intern
|
|
"(#{URI_CHAR}+)"
|
|
end
|
|
@pattern = /^#{regex}$/
|
|
end
|
|
|
|
def invoke(env)
|
|
return unless pattern =~ env['PATH_INFO'].squeeze('/')
|
|
params = param_keys.zip($~.captures.map(&:from_param)).to_hash
|
|
Result.new(block, params)
|
|
end
|
|
|
|
end
|
|
|
|
class Application
|
|
|
|
attr_reader :events
|
|
|
|
def initialize
|
|
@events = Hash.new { |hash, key| hash[key] = [] }
|
|
end
|
|
|
|
def define_event(method, path, &b)
|
|
events[method] << event = Event.new(path, &b)
|
|
event
|
|
end
|
|
|
|
def lookup(env)
|
|
events[env['REQUEST_METHOD'].downcase.to_sym].eject(&[:invoke, env])
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
module Kernel
|
|
|
|
def silence_warnings
|
|
old_verbose, $VERBOSE = $VERBOSE, nil
|
|
yield
|
|
ensure
|
|
$VERBOSE = old_verbose
|
|
end
|
|
|
|
end
|
|
|
|
class String
|
|
|
|
# Converts +self+ to an escaped URI parameter value
|
|
# 'Foo Bar'.to_param # => 'Foo%20Bar'
|
|
def to_param
|
|
URI.escape(self)
|
|
end
|
|
|
|
# Converts +self+ from an escaped URI parameter value
|
|
# 'Foo%20Bar'.from_param # => 'Foo Bar'
|
|
def from_param
|
|
URI.unescape(self)
|
|
end
|
|
|
|
end
|
|
|
|
class Hash
|
|
|
|
def to_params
|
|
map { |k,v| "#{k}=#{URI.escape(v)}" }.join('&')
|
|
end
|
|
|
|
def symbolize_keys
|
|
self.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
|
|
end
|
|
|
|
def pass(*keys)
|
|
reject { |k,v| !keys.include?(k) }
|
|
end
|
|
|
|
end
|
|
|
|
class Symbol
|
|
|
|
def to_proc
|
|
Proc.new { |*args| args.shift.__send__(self, *args) }
|
|
end
|
|
|
|
end
|
|
|
|
class Array
|
|
|
|
def to_hash
|
|
self.inject({}) { |h, (k, v)| h[k] = v; h }
|
|
end
|
|
|
|
def to_proc
|
|
Proc.new { |*args| args.shift.__send__(self[0], *(args + self[1..-1])) }
|
|
end
|
|
|
|
end
|
|
|
|
module Enumerable
|
|
|
|
def eject(&block)
|
|
find { |e| result = block[e] and break result }
|
|
end
|
|
|
|
end
|