# Module: Capcode [ "README", "AUTHORS", "COPYING", "lib/capcode.rb", nil].each do Capcode.view_html Capcode::Views.view_html Capcode::Helpers.view_html Capcode::HTTPError.view_html Capcode::RenderError.view_html Capcode::RouteError.view_html Capcode::ParameterError.view_html end |
Add routes to a controller class
module Capcode class Hello < Route '/hello/(.*)', '/hello/([^#]*)#(.*)' def get( arg1, arg2 ) ... end end end
In the get method, you will receive the maximum of parameters declared by the routes. In this example, you will receive 2 parameters. So if you go to /hello/world#friend then arg1 will be set to world and arg2 will be set to friend. Now if you go to /hello/you, then arg1 will be set to you and arg2 will be set to nil
If the regexp in the route does not match, all arguments will be nil
[ show source ]
# File lib/capcode.rb, line 202 202: def Route *u 203: Class.new { 204: meta_def(:__urls__){ 205: # < Route '/hello/world/([^\/]*)/id(\d*)', '/hello/(.*)' 206: # # => [ {'/hello/world' => '([^\/]*)/id(\d*)', '/hello' => '(.*)'}, 2, <Capcode::Klass> ] 207: h = {} 208: max = 0 209: u.each do |_u| 210: m = /\/([^\/]*\(.*)/.match( _u ) 211: if m.nil? 212: raise Capcode::RouteError, "Route `#{_u}' already defined with regexp `#{h[_u]}' !", caller if h.keys.include?(_u) 213: h[_u] = '' 214: else 215: _pre = m.pre_match 216: _pre = "/" if _pre.size == 0 217: raise Capcode::RouteError, "Route `#{_pre}' already defined with regexp `#{h[_pre]}' !", caller if h.keys.include?(_pre) 218: h[_pre] = m.captures[0] 219: max = Regexp.new(m.captures[0]).number_of_captures if max < Regexp.new(m.captures[0]).number_of_captures 220: end 221: end 222: [h, max, self] 223: } 224: 225: # Hash containing all the request parameters (GET or POST) 226: def params 227: @request.params 228: end 229: 230: # Hash containing all the environment variables 231: def env 232: @env 233: end 234: 235: # Hash session 236: def session 237: @env['rack.session'] 238: end 239: 240: # Return the Rack::Request object 241: def request 242: @request 243: end 244: 245: # Return the Rack::Response object 246: def response 247: @response 248: end 249: 250: def call( e ) #:nodoc: 251: @env = e 252: @response = Rack::Response.new 253: @request = Rack::Request.new(@env) 254: 255: # __k = self.class.to_s.split( /::/ )[-1].downcase.to_sym 256: # @@__FILTERS.each do |f| 257: # proc = f.delete(:action) 258: # __run = true 259: # if f[:only] 260: # __run = f[:only].include?(__k) 261: # end 262: # if f[:except] 263: # __run = !f[:except].include?(__k) 264: # end 265: # 266: # # proc.call(self) if __run 267: # puts "call #{proc} for #{__k}" 268: # end 269: 270: r = case @env["REQUEST_METHOD"] 271: when "GET" 272: finalPath = nil 273: finalArgs = nil 274: finalNArgs = nil 275: 276: aPath = @request.path.gsub( /^\//, "" ).split( "/" ) 277: self.class.__urls__[0].each do |p, r| 278: xPath = p.gsub( /^\//, "" ).split( "/" ) 279: if (xPath - aPath).size == 0 280: diffArgs = aPath - xPath 281: diffNArgs = diffArgs.size 282: if finalNArgs.nil? or finalNArgs > diffNArgs 283: finalPath = p 284: finalNArgs = diffNArgs 285: finalArgs = diffArgs 286: end 287: end 288: 289: end 290: 291: nargs = self.class.__urls__[1] 292: regexp = Regexp.new( self.class.__urls__[0][finalPath] ) 293: args = regexp.match( Rack::Utils.unescape(@request.path).gsub( Regexp.new( "^#{finalPath}" ), "" ).gsub( /^\//, "" ) ) 294: if args.nil? 295: raise Capcode::ParameterError, "Path info `#{@request.path_info}' does not match route regexp `#{regexp.source}'" 296: else 297: args = args.captures.map { |x| (x.size == 0)?nil:x } 298: end 299: 300: while args.size < nargs 301: args << nil 302: end 303: 304: get( *args ) 305: when "POST" 306: post 307: end 308: if r.respond_to?(:to_ary) 309: @response.status = r[0] 310: r[1].each do |k,v| 311: @response[k] = v 312: end 313: @response.body = r[2] 314: else 315: @response.write r 316: end 317: 318: @response.finish 319: end 320: 321: include Capcode::Helpers 322: include Capcode::Views 323: } 324: end
Hash containing all the environment variables
[ show source ]
# File lib/capcode.rb, line 231 231: def env 232: @env 233: end
This method help you to map and URL to a Rack or What you want Helper
Capcode.map( "/file" ) do Rack::File.new( "." ) end
[ show source ]
# File lib/capcode.rb, line 331 331: def map( r, &b ) 332: @@__ROUTES[r] = yield 333: end
Hash containing all the request parameters (GET or POST)
[ show source ]
# File lib/capcode.rb, line 226 226: def params 227: @request.params 228: end
Return the Rack::Request object
[ show source ]
# File lib/capcode.rb, line 241 241: def request 242: @request 243: end
Return the Rack::Response object
[ show source ]
# File lib/capcode.rb, line 246 246: def response 247: @response 248: end
Start your application.
Options :
[ show source ]
# File lib/capcode.rb, line 348 348: def run( args = {} ) 349: __VERBOSE = false 350: 351: conf = { 352: :port => args[:port]||3000, 353: :host => args[:host]||"localhost", 354: :server => args[:server]||nil, 355: :log => args[:log]||$stdout, 356: :session => args[:session]||{}, 357: :pid => args[:pid]||"#{$0}.pid", 358: :daemonize => args[:daemonize]||false, 359: :db_config => args[:db_config]||"database.yml", 360: :static => args[:static]||nil, 361: :root => args[:root]||File.expand_path(File.dirname($0)), 362: 363: :console => false 364: } 365: 366: # Parse options 367: opts = OptionParser.new do |opts| 368: opts.banner = "Usage: #{File.basename($0)} [options]" 369: opts.separator "" 370: opts.separator "Specific options:" 371: 372: opts.on( "-C", "--console", "Run in console mode with IRB (default: false)" ) { 373: conf[:console] = true 374: } 375: opts.on( "-h", "--host HOSTNAME", "Host for web server to bind to (default: #{conf[:host]})" ) { |h| 376: conf[:host] = h 377: } 378: opts.on( "-p", "--port NUM", "Port for web server (default: #{conf[:port]})" ) { |p| 379: conf[:port] = p 380: } 381: opts.on( "-d", "--daemonize [true|false]", "Daemonize (default: #{conf[:daemonize]})" ) { |d| 382: conf[:daemonize] = d 383: } 384: opts.on( "-r", "--root PATH", "Working directory (default: #{conf[:root]})" ) { |w| 385: conf[:root] = w 386: } 387: opts.on( "-s", "--static PATH", "Static directory -- relative to the root directory (default: #{conf[:static]})" ) { |r| 388: conf[:static] = r 389: } 390: 391: opts.separator "" 392: opts.separator "Common options:" 393: 394: opts.on("-?", "--help", "Show this message") do 395: puts opts 396: exit 397: end 398: opts.on("-v", "--version", "Show versions") do 399: puts "Capcode version #{Capcode::CAPCOD_VERION} (ruby v#{RUBY_VERSION})" 400: exit 401: end 402: opts.on_tail( "-V", "--verbose", "Run in verbose mode" ) do 403: __VERBOSE = true 404: end 405: end 406: 407: begin 408: opts.parse! ARGV 409: rescue OptionParser::ParseError => ex 410: STDERR.puts "!! #{ex.message}" 411: puts "** use `#{File.basename($0)} --help` for more details..." 412: exit 1 413: end 414: 415: # Run in the Working directory 416: puts "** Go on root directory (#{File.expand_path(conf[:root])})" if __VERBOSE 417: Dir.chdir( conf[:root] ) do 418: 419: # Check that mongrel exists 420: if conf[:server].nil? || conf[:server] == "mongrel" 421: begin 422: require 'mongrel' 423: conf[:server] = "mongrel" 424: rescue LoadError 425: puts "!! could not load mongrel. Falling back to webrick." 426: conf[:server] = "webrick" 427: end 428: end 429: 430: Capcode.constants.each do |k| 431: begin 432: if eval "Capcode::#{k}.public_methods(true).include?( '__urls__' )" 433: u, m, c = eval "Capcode::#{k}.__urls__" 434: u.keys.each do |_u| 435: raise Capcode::RouteError, "Route `#{_u}' already define !", caller if @@__ROUTES.keys.include?(_u) 436: @@__ROUTES[_u] = c.new 437: end 438: end 439: rescue => e 440: raise e.message 441: end 442: end 443: 444: # Set Static directory 445: @@__STATIC_DIR = File.expand_path(File.join("/", conf[:static])) 446: 447: # Initialize Rack App 448: puts "** Map routes." if __VERBOSE 449: app = Rack::URLMap.new(@@__ROUTES) 450: puts "** Initialize static directory (#{conf[:static]})" if __VERBOSE 451: app = Rack::Static.new( 452: app, 453: :urls => [@@__STATIC_DIR], 454: :root => File.expand_path(conf[:root]) 455: ) unless conf[:static].nil? 456: puts "** Initialize session" if __VERBOSE 457: app = Rack::Session::Cookie.new( app, conf[:session] ) 458: app = Capcode::HTTPError.new(app) 459: app = Rack::ContentLength.new(app) 460: app = Rack::Lint.new(app) 461: app = Rack::ShowExceptions.new(app) 462: # app = Rack::Reloader.new(app) ## -- NE RELOAD QUE capcode.rb -- So !!! 463: app = Rack::CommonLogger.new( app, Logger.new(conf[:log]) ) 464: 465: # From rackup !!! 466: if conf[:daemonize] 467: if /java/.match(RUBY_PLATFORM).nil? 468: if RUBY_VERSION < "1.9" 469: exit if fork 470: Process.setsid 471: exit if fork 472: # Dir.chdir "/" 473: File.umask 0000 474: STDIN.reopen "/dev/null" 475: STDOUT.reopen "/dev/null", "a" 476: STDERR.reopen "/dev/null", "a" 477: else 478: Process.daemon 479: end 480: else 481: puts "!! daemonize option unavailable on #{RUBY_PLATFORM} platform." 482: end 483: 484: File.open(conf[:pid], 'w'){ |f| f.write("#{Process.pid}") } 485: at_exit { File.delete(conf[:pid]) if File.exist?(conf[:pid]) } 486: end 487: 488: # Start database 489: if self.methods.include? "db_connect" 490: db_connect( conf[:db_config], conf[:log] ) 491: end 492: 493: if block_given? 494: yield( self ) 495: end 496: 497: if conf[:console] 498: puts "Run console..." 499: IRB.start 500: exit 501: end 502: 503: # Start server 504: case conf[:server] 505: when "mongrel" 506: puts "** Starting Mongrel on #{conf[:host]}:#{conf[:port]}" 507: Rack::Handler::Mongrel.run( app, {:Port => conf[:port], :Host => conf[:host]} ) { |server| 508: trap "SIGINT", proc { server.stop } 509: } 510: when "webrick" 511: puts "** Starting WEBrick on #{conf[:host]}:#{conf[:port]}" 512: Rack::Handler::WEBrick.run( app, {:Port => conf[:port], :BindAddress => conf[:host]} ) { |server| 513: trap "SIGINT", proc { server.shutdown } 514: } 515: end 516: end 517: end
Hash session
[ show source ]
# File lib/capcode.rb, line 236 236: def session 237: @env['rack.session'] 238: end