# -*- Coding: utf-8 -*- require "cuba" require 'ixtlan/babel/factory' module CubaApi module WriteAspect module ClassMethods def append_aspect( arg ) aspects << arg warn "[CubaAPI] Appended aspect #{arg}" end def prepend_aspect( arg ) aspects.insert( 0, arg ) warn "[CubaAPI] Prepended aspect #{arg}" end def aspects self[ :aspects ] ||= [] end end def head( status ) res.status = status res.write '' end def write( obj, args = {} ) self.res.status = args[:status] || 200 # make sure we inherit aspects and repsect the order aspects = self.class == CubaAPI ? [] : self.class.superclass[ :aspects ] (aspects + self.class[ :aspects ]).uniq.each do |w| obj = send( w, obj, args ) if obj end res.write obj.to_s end end module Serializer def serializer_factory @_factory ||= Ixtlan::Babel::Factory.new end private :serializer_factory def serializer( obj, args = {}) if args[:serializer] == false || obj.is_a?( String ) obj else s = serializer_factory.new( obj ) s.use( args[ :use ] ) if args[ :use ] s end end def self.included( base ) base.append_aspect :serializer end end module CurrentUser module ClassMethods def sessions self[ :sessions ] end end def current_user( user = nil ) if user session['user'] = self.class.sessions.to_session( user ) @_current_user = user else @_current_user ||= self.class.sessions.from_session( session['user'] ) end end def reset_current_user session[ 'user' ] = nil end def authenticated? session[ 'user' ] != nil end def current_user_name authenticated? ? current_user.login : "???" end end module Guard def allowed?( *group_names ) authenticated? && ( allowed_groups( *group_names ).size > 0 ) end def allowed_groups( *group_names ) current_groups.select { |g| group_names.member?( g.name ) } end def current_groups current_user.groups end end module AcceptContent module ClassMethods MIMES = { :yaml => ['application/x-yaml', 'text/yaml'], :json => ['application/json'], :xml => ['application/xml'] } def accept( *args ) args.each do |arg| (MIMES[ arg ] || []).each do |mime| mimes[ mime ] = "to_#{arg}".to_sym end end warn "[CubaAPI] Accept: #{mimes.keys.join(', ')}" end def mimes self[ :mimes ] ||= {} end end def accept_content( obj, options = {} ) script = env[ 'SCRIPT_NAME' ] if script =~ /\./ extension = script.sub( /^.*\./, '' ) mime = ClassMethods::MIMES[ extension.to_sym ] || [] accept( obj, mime.first ) else accept( obj, env[ 'HTTP_ACCEPT' ] ) end end def accept( obj, mime ) if self.class[ :mimes ].key?( mime ) res[ "Content-Type" ] = mime + "; charset=utf-8" obj.send self.class[ :mimes ][ mime ] else no_body 404 nil end end private :accept def self.included( base ) base.append_aspect :accept_content end end end class CubaAPI < Cuba def self.map @map ||= {} end def self.[]( key ) map[ key ] || settings[ key ] || (superclass == Cuba ? Cuba.settings[ key ] : superclass[ key ]) end def self.[]=( key, value ) map[ key ] = value end plugin Ixtlan::Write plugin Ixtlan::Serializer plugin Ixtlan::AcceptContent plugin Ixtlan::CurrentUser plugin Ixtlan::Guard end