root / trunk / lib / camping.rb

Revision 242, 3.9 kB (checked in by zimbatm, 2 months ago)

Yet another attempt to fix #147

Line 
1%w[tempfile uri].map{|l|require l};class Object;def meta_def m,&b;(class<<self
2self end).send:define_method,m,&b end end;module Camping;C=self
3S=IO.read(__FILE__)rescue nil;P="<h1>Cam\\ping Problem!</h1><h2>%s</h2>"
4class H<Hash
5def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end
6alias u merge!;undef id,type;end;module Helpers;def R c,*g
7p,h=/\(.+?\)/,g.grep(Hash);g-=h;raise"bad route"unless u=c.urls.find{|x|
8break x if x.scan(p).size==g.size&&/^#{x}\/?$/=~(x=g.inject(x){|x,a|
9x.sub p,C.escape((a[a.class.primary_key]rescue a))})}
10h.any?? u+"?"+h[0].map{|x|x.map{|z|C.escape z}*"="}*"&":u end;def / p
11p[/^\//]?@root+p:p end;def URL c='/',*a;c=R(c, *a) if c.respond_to?:urls
12c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//];URI c end end;module Base
13attr_accessor:input,:cookies,:env,:headers,:body,:status,:root;Z="\r\n"
14def method_missing *a,&b;a.shift if a[0]==:render;m=Mab.new({},self)
15s=m.capture{send(*a,&b)};s=m.capture{send(:layout){s}}if/^_/!~a[0].to_s and
16m.respond_to?:layout;s end;def r s,b,h={};@status=s;headers.u(h);@body=b
17end;def redirect *a;r 302,'','Location'=>URL(*a)end;def r404 p=env.PATH
18r 404,P%"#{p} not found"end;def r500 k,m,x
19r 500,P%"#{k}.#{m}"+"<h3>#{x.class} #{x.message}: <ul>#{x.
20backtrace.map{|b|"<li>#{b}</li>"}}</ul></h3>"end;def r501 m=@method
21r 501,P%"#{m.upcase} not implemented"end;def to_a
22[status,body,headers]end;def initialize r,e,m;@status,@method,@env,@headers,
23@root=200,m,e,H['Content-Type','text/html'],e.SCRIPT_NAME.sub(/\/$/,'')
24@k=C.kp e.HTTP_COOKIE;q=C.qsp e.QUERY_STRING;@in=r;case e.CONTENT_TYPE
25when%r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n
26b=/(?:\r?\n|\A)#{Regexp.quote"--#$1"}(?:--)?\r$/;until@in.eof?;fh=H[]
27for l in@in;case l;when Z;break;when/^Content-D.+?: form-data;/
28fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten]
29when/^Content-Type: (.+?)(\r$|\Z)/m: fh.type = $1 end end;fn=fh.name
30o=if fh.filename;o=fh.tempfile=Tempfile.new(:C);o.binmode;else;fh="";end;s=8192
31k='';l=@in.read(s*2);while l;if(k<<l)=~b;o<<$`.chomp
32@in.seek(-$'.size,IO::SEEK_CUR);break end;o<<k.slice!(0...s);l=@in.read(s) end
33C.qsp(fn,'&;',fh,q)if fn;fh.tempfile.rewind if fh.is_a?H end;when
34"application/x-www-form-urlencoded": q.u(C.qsp(@in.read))end
35@cookies,@input=@k.dup,q.dup end;def service *a;@body=send @method,*a
36headers['Set-Cookie']=cookies.map{|k,v|"#{k}=#{C.escape(v)}; path=#{self/
37"/"}"if v!=@k[k]}-[nil];self end;def to_s;"Status: #@status#{Z+(headers.inject([
38]){|a,o|[*o[1]].map{|v|a<<[o[0],v]*": "if v&&v.to_s.any?};a}*Z)+Z+Z}#@body"end
39end;X=module Controllers;@r=[];class<<self;def r;@r end;def R *u;r=@r
40Class.new{meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end
41def D p,m;r.map{|k|k.urls.map{|x|return(k.instance_method(m)rescue nil)?
42[k,m,*$~[1..-1]]:[I,'r501',m]if p=~/^#{x}\/?$/}};[I,'r404',p]
43end;def M;def M;end;constants.map{|c|k=const_get(c)
44k.send:include,C,Base,Helpers,Models;@r=[k]+r if r-[k]==r
45k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end end;class I<R()
46end;self end;class<<self;def goes m
47eval S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING end;def escape s
48s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr' ','+'
49end;def un s;s.tr('+',' ').gsub(/%([\da-f]{2})/in){[$1].pack'H*'}end
50def qsp q,d='&;',y=nil,z=H[];m=proc{|_,o,n|o.u(n,&m)rescue([*o]<<n)}
51(q.to_s.split(/[#{d}]+ */n)-[""]).inject((b,z=z,H[])[0]){|h,p|k,v=un(p).
52split'=',2;h.u k.split(/[\]\[]+/).reverse.inject(y||v){|x,i|H[i,x]},&m}end
53def kp s;c=qsp s,';,'end;def run r=$stdin,e=ENV;X.M;e=H[e.to_hash];k,m,*a=X.D e.
54PATH_INFO=un("/#{e.PATH_INFO}".gsub(/\/+/,'/')),
55(e.REQUEST_METHOD||'get').downcase
56k.new(r,e,m).Y.service(*a);rescue=>x;X::I.new(r,e,'r500').service k,m,x
57end;def method_missing m,c,*a;X.M;k=X.const_get(c).new StringIO.new,
58H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s
59H[a.pop].each{|e,f|k.send"#{e}=",f}if Hash===a[-1];k.service(*a)end end
60module Views;include X,Helpers end;module Models;autoload:Base,'camping/db'
61def Y;self;end end;autoload:Mab,'camping/mab'end
Note: See TracBrowser for help on using the browser.