# 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

Module Capcode

(in files lib/capcode.rb )

Includes

Methods

Public Class method: Route(*u)

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

     # File lib/capcode.rb, line 240
240:     def Route *u
241:       Class.new {
242:         meta_def(:__urls__){
243:           # < Route '/hello/world/([^\/]*)/id(\d*)', '/hello/(.*)'
244:           # # => [ {'/hello/world' => '([^\/]*)/id(\d*)', '/hello' => '(.*)'}, 2, <Capcode::Klass> ]
245:           h = {}
246:           max = 0
247:           u.each do |_u|
248:             m = /\/([^\/]*\(.*)/.match( _u )
249:             if m.nil?
250:               raise Capcode::RouteError, "Route `#{_u}' already defined with regexp `#{h[_u]}' !", caller if h.keys.include?(_u)
251:               h[_u] = ''
252:             else
253:               _pre = m.pre_match
254:               _pre = "/" if _pre.size == 0
255:               raise Capcode::RouteError, "Route `#{_pre}' already defined with regexp `#{h[_pre]}' !", caller if h.keys.include?(_pre)
256:               h[_pre] = m.captures[0]
257:               max = Regexp.new(m.captures[0]).number_of_captures if max < Regexp.new(m.captures[0]).number_of_captures
258:             end
259:           end
260:           [h, max, self]
261:         }
262: 
263:         # Hash containing all the request parameters (GET or POST)
264:         def params
265:           @request.params
266:         end
267:         
268:         # Hash containing all the environment variables
269:         def env
270:           @env
271:         end
272:         
273:         # Hash session
274:         def session
275:           @env['rack.session']
276:         end
277:         
278:         # Return the Rack::Request object
279:         def request
280:           @request
281:         end
282:         
283:         # Return the Rack::Response object
284:         def response
285:           @response
286:         end
287:         
288:         def call( e ) #:nodoc:
289:           @env = e
290:           @response = Rack::Response.new
291:           @request = Rack::Request.new(@env)
292: 
293:           r = case @env["REQUEST_METHOD"]
294:             when "GET"
295:               finalPath = nil
296:               finalArgs = nil
297:               finalNArgs = nil
298:               
299:               aPath = @request.path.gsub( /^\//, "" ).split( "/" )
300:               self.class.__urls__[0].each do |p, r|
301:                 xPath = p.gsub( /^\//, "" ).split( "/" )
302:                 if (xPath - aPath).size == 0
303:                   diffArgs = aPath - xPath
304:                   diffNArgs = diffArgs.size
305:                   if finalNArgs.nil? or finalNArgs > diffNArgs
306:                     finalPath = p
307:                     finalNArgs = diffNArgs
308:                     finalArgs = diffArgs
309:                   end
310:                 end
311:                 
312:               end
313: 
314:               nargs = self.class.__urls__[1]
315:               regexp = Regexp.new( self.class.__urls__[0][finalPath] )
316:               args = regexp.match( Rack::Utils.unescape(@request.path).gsub( Regexp.new( "^#{finalPath}" ), "" ).gsub( /^\//, "" ) )
317:               if args.nil?
318:                 raise Capcode::ParameterError, "Path info `#{@request.path_info}' does not match route regexp `#{regexp.source}'"
319:               else
320:                 args = args.captures.map { |x| (x.size == 0)?nil:x }
321:               end
322:               
323:               while args.size < nargs
324:                 args << nil
325:               end
326:                                           
327:               get( *args )
328:             when "POST"
329:               post
330:           end
331:           if r.respond_to?(:to_ary)
332:             @response.status = r[0]
333:             r[1].each do |k,v|
334:               @response[k] = v
335:             end
336:             @response.body = r[2]
337:           else
338:             @response.write r
339:           end
340:           
341:           @response.finish
342:         end
343:                 
344:         include Capcode::Helpers
345:         include Capcode::Views
346:       }      
347:     end

Public Class method: env()

Hash containing all the environment variables

     # File lib/capcode.rb, line 269
269:         def env
270:           @env
271:         end

Public Class method: map( r ) {|| ...}

This method help you to map and URL to a Rack or What you want Helper

  Capcode.map( "/file" ) do
    Rack::File.new( "." )
  end
     # File lib/capcode.rb, line 354
354:     def map( r, &b )
355:       @@__ROUTES[r] = yield
356:     end

Public Class method: params()

Hash containing all the request parameters (GET or POST)

     # File lib/capcode.rb, line 264
264:         def params
265:           @request.params
266:         end

Public Class method: request()

Return the Rack::Request object

     # File lib/capcode.rb, line 279
279:         def request
280:           @request
281:         end

Public Class method: response()

Return the Rack::Response object

     # File lib/capcode.rb, line 284
284:         def response
285:           @response
286:         end

Public Class method: run( args = {} )

Start your application.

Options :

  • :port = Listen port
  • :host = Listen host
  • :server = Server type (webrick or mongrel)
  • :log = Output logfile (default: STDOUT)
  • :session = Session parameters. See Rack::Session for more informations
  • :pid = PID file (default: $0.pid)
  • :daemonize = Daemonize application (default: false)
  • :db_config = database configuration file (default: database.yml)
  • :root = root directory (default: "." — relative to the working directory)
  • :working_directory = Working directory (default: directory of the main.rb)
     # File lib/capcode.rb, line 371
371:     def run( args = {} )
372:       conf = {
373:         :port => args[:port]||3000, 
374:         :host => args[:host]||"localhost",
375:         :server => args[:server]||nil,
376:         :log => args[:log]||$stdout,
377:         :session => args[:session]||{},
378:         :pid => args[:pid]||"#{$0}.pid",
379:         :daemonize => args[:daemonize]||false,
380:         :db_config => args[:db_config]||"database.yml",
381:         :root => args[:root]||".",
382:         :working_directory => args[:working_directory]||File.expand_path(File.dirname($0))
383:       }
384:       
385:       # Run in the Working directory
386:       Dir.chdir( conf[:working_directory] ) do
387:         # Set root directory for helpers
388:         Capcode::Helpers.root = File.expand_path( conf[:root] )
389:         
390:         # Check that mongrel exists 
391:         if conf[:server].nil? || conf[:server] == "mongrel"
392:           begin
393:             require 'mongrel'
394:             conf[:server] = "mongrel"
395:           rescue LoadError 
396:             puts "!! could not load mongrel. Falling back to webrick."
397:             conf[:server] = "webrick"
398:           end
399:         end
400:             
401:         Capcode.constants.each do |k|
402:           begin
403:             if eval "Capcode::#{k}.public_methods(true).include?( '__urls__' )"
404:               u, m, c = eval "Capcode::#{k}.__urls__"
405:               u.keys.each do |_u|
406:                 raise Capcode::RouteError, "Route `#{_u}' already define !", caller if @@__ROUTES.keys.include?(_u)
407:                 @@__ROUTES[_u] = c.new
408:               end
409:             end
410:           rescue => e
411:             raise e.message
412:           end
413:         end
414:         
415:         app = Rack::URLMap.new(@@__ROUTES)
416:         app = Rack::Session::Cookie.new( app, conf[:session] )
417:         app = Capcode::HTTPError.new(app, conf[:root])
418:         app = Rack::ContentLength.new(app)
419:         app = Rack::Lint.new(app)
420:         app = Rack::ShowExceptions.new(app)
421: #        app = Rack::Reloader.new(app) ## -- NE RELOAD QUE capcode.rb -- So !!!
422:         app = Rack::CommonLogger.new( app, Logger.new(conf[:log]) )
423:         
424:         # From rackup !!!
425:         if conf[:daemonize]
426:           if RUBY_VERSION < "1.9"
427:             exit if fork
428:             Process.setsid
429:             exit if fork
430:             # Dir.chdir "/"
431:             File.umask 0000
432:             STDIN.reopen "/dev/null"
433:             STDOUT.reopen "/dev/null", "a"
434:             STDERR.reopen "/dev/null", "a"
435:           else
436:             Process.daemon
437:           end
438:         
439:           File.open(conf[:pid], 'w'){ |f| f.write("#{Process.pid}") }
440:           at_exit { File.delete(conf[:pid]) if File.exist?(conf[:pid]) }
441:         end
442:         
443:         # Start database
444:         if self.methods.include? "db_connect"
445:           db_connect( conf[:db_config], conf[:log] )
446:         end
447:         
448:         # Start server
449:         case conf[:server]
450:         when "mongrel"
451:           puts "** Starting Mongrel on #{conf[:host]}:#{conf[:port]}"
452:           Rack::Handler::Mongrel.run( app, {:Port => conf[:port], :Host => conf[:host]} ) { |server|
453:             trap "SIGINT", proc { server.stop }
454:           }
455:         when "webrick"
456:           puts "** Starting WEBrick on #{conf[:host]}:#{conf[:port]}"
457:           Rack::Handler::WEBrick.run( app, {:Port => conf[:port], :BindAddress => conf[:host]} ) { |server|
458:             trap "SIGINT", proc { server.shutdown }
459:           }
460:         end
461:       end
462:     end

Public Class method: session()

Hash session

     # File lib/capcode.rb, line 274
274:         def session
275:           @env['rack.session']
276:         end