lib/merb/mixins/controller_mixin.rb in merb-0.3.4 vs lib/merb/mixins/controller_mixin.rb in merb-0.3.7

- old
+ new

@@ -1,17 +1,61 @@ module Merb module ControllerMixin + + # Returns a URL according to the defined route. Accepts the path and + # an options hash. The path specifies the route requested. The options + # hash fills in the dynamic parts of the route. + # + # Nested resources such as: + # r.resources :blogposts do |post| + # post.resources :comments + # end + # + # Provide the following routes: + # [:blogposts, "/blogposts"] + # [:blogpost, "/blogposts/:id"] + # [:edit_blogpost, "/blogposts/:id/edit"] + # [:new_blogpost, "/blogposts/new"] + # [:custom_new_blogpost, "/blogposts/new/:action"] + # [:comments, "/blogposts/:blogpost_id/comments"] + # [:comment, "/blogposts/:blogpost_id/comments/:id"] + # [:edit_comment, "/blogposts/:blogpost_id/comments/:id/edit"] + # [:new_comment, "/blogposts/:blogpost_id/comments/new"] + # [:custom_new_comment, "/blogposts/:blogpost_id/comments/new/:action"] + # + # Examples: + # + # @post = Post.find(1) + # @comment = @post.comments.find(1) + # + # url(:blogposts) # => /blogposts + # url(:new_post) # => /blogposts/new + # url(:blogpost, @post) # => /blogposts/1 + # url(:edit_blogpost, @post) # => /blogposts/1/edit + # url(:custom_new_blogpost, :action => 'alternate') # => /blogposts/new/alternate + # + # url(:comments, :blogpost => @post) # => /blogposts/1/comments + # url(:new_comment, :blogpost => @post) # => /blogposts/1/comments/new + # url(:comment, @comment) # => /blogposts/1/comments/1 + # url(:edit_comment, @comment) # => /blogposts/1/comments/1/edit + # url(:custom_new_comment, :blogpost => @post) + # + def url(path, o={}) + ::Merb::Router.generate(path,o) + end + + protected NAME_REGEX = /Content-Disposition:.* name="?([^\";]*)"?/ni.freeze CONTENT_TYPE_REGEX = /Content-Type: (.*)\r\n/ni.freeze FILENAME_REGEX = /Content-Disposition:.* filename="?([^\";]*)"?/ni.freeze CRLF = "\r\n".freeze EOL = CRLF - def parse_multipart(request,boundary) + def parse_multipart(request,boundary,env) boundary = "--#{boundary}" - paramhsh = MerbHash.new + paramhsh = {} buf = "" - content_length = @env['CONTENT_LENGTH'].to_i + content_length = env['CONTENT_LENGTH'].to_i input = request input.binmode if defined? input.binmode boundary_size = boundary.size + EOL.size bufsize = 16384 content_length -= boundary_size @@ -84,49 +128,46 @@ end def normalize_params(parms, key, val) case key when /(.+)\[(.+)\]\[\]$/ - parms[$1] ||= MerbHash.new + parms[$1] ||= {} parms[$1] = normalize_params(parms[$1], "#{$2}[]", val) when /(.+)\[(.+)\]$/ - parms[$1] ||= MerbHash.new + parms[$1] ||= {} parms[$1] = normalize_params(parms[$1], $2, val) when /(.+)\[\]$/ (parms[$1] ||= []) << val else parms[key] = val if val end parms end - def url(path, o={}) - ::Merb::Router.generator.generate(path,o) - end # parses a query string or the payload of a POST # request into the params hash. So for example: # /foo?bar=nik&post[title]=heya&post[body]=whatever # parses into: # {:bar => 'nik', :post => {:title => 'heya', :body => 'whatever'}} def query_parse(qs, d = '&;') - m = proc {|_,o,n|o.u(n,&m)rescue([*o]<<n)} - (qs||'').split(/[#{d}] */n).inject(MerbHash[]) { |h,p| + m = proc {|_,o,n|o.update(n,&m)rescue([*o]<<n)} + (qs||'').split(/[#{d}] */n).inject(Hash[]) { |h,p| k, v=unescape(p).split('=',2) - h.u(k.split(/[\]\[]+/).reverse. - inject(v) { |x,i| MerbHash[i,x] },&m) + h.update(k.split(/[\]\[]+/).reverse. + inject(v) { |x,i| Hash[i,x] },&m) } end # render using chunked encoding # def stream # prefix = '<p>' # suffix = "</p>\r\n" # render_chunked do # IO.popen("cat /tmp/test.log") do |io| # done = false - # until done == true do + # until done # sleep 0.3 # line = io.gets.chomp # if line == 'EOF' # done = true # else @@ -144,10 +185,19 @@ blk.call response.write("0\r\n\r\n") } end + def render_deferred(&blk) + Proc.new { + result = blk.call + response.send_status(result.length) + response.send_header + response.write(result) + } + end + # for use within a render_chunked response def send_chunk(data) response.write('%x' % data.size + "\r\n") response.write(data + "\r\n") end @@ -155,11 +205,11 @@ # redirect to another url It can be like /foo/bar # for redirecting within your same app. Or it can # be a fully qualified url to another site. def redirect(url) MERB_LOGGER.info("Redirecting to: #{url}") - @status = 302 + set_status(302) headers.merge!({'Location'=> url}) return '' end # pass in a path to a file and this will set the @@ -179,21 +229,21 @@ end # stream_file( { :filename => file_name, # :type => content_type, # :content_length => content_length }) do - # @response.send_status(opts[:content_length]) - # @response.send_header + # response.send_status(opts[:content_length]) + # response.send_header # AWS::S3::S3Object.stream(user.folder_name + "-" + user_file.unique_id, bucket_name) do |chunk| # @response.write chunk # end # end def stream_file(opts={}, &stream) opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts)) disposition = opts[:disposition].dup || 'attachment' disposition << %(; filename="#{opts[:filename]}") - @response.headers.update( + response.headers.update( 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers 'Content-Disposition' => disposition, 'Content-Transfer-Encoding' => 'binary', 'CONTENT-LENGTH' => opts[:content_length] ) @@ -226,20 +276,9 @@ def make_token require 'digest/md5' Digest::MD5.hexdigest("#{inspect}#{Time.now}#{rand}") end - def rand_uuid - "%04x%04x-%04x-%04x-%04x-%06x%06x" % [ - rand(0x0010000), - rand(0x0010000), - rand(0x0010000), - rand(0x0010000), - rand(0x0010000), - rand(0x1000000), - rand(0x1000000), - ] - end def escape_xml(obj) obj.to_s.gsub(/[&<>"']/) { |s| Merb::Const::ESCAPE_TABLE[s] } end alias h escape_xml