def send_error(cls, status=500, msg=None):
     ''' Return an error for the current request '''
     if not msg:
         if status == 404:
             msg = "Page not found"
         elif status == 500:
             msg = "Server error"
         else:
             msg = "Unknown error"
     Logger.error("HTTP %s%s" % (status, (": " + msg if msg else "")))
     raise cherrypy.HTTPError(status, msg)
 def wrapper(*kargs, **kwargs):
     
     inst = f.im_self
     name = f.__name__
     is_render_view = (name is "render_view")
     is_async = (hasattr(f, 'is_async') and f.is_async is True)
     is_action = (is_render_view or is_async)
     
     # Session recovery
     try:
         user_data = session.recover()
         if user_data:
             inst._session_recovery(inst, user_data[0], user_data[1])
     except Exception, e:
         Logger.error("Could not recover session", e)  
 def forward(cls, controller, action=None, params=None):
     ''' Forward the current request to the given action '''
     action = action if action else "index"
     controller_inst = cls.instances[controller]
     if not controller_inst:
         cls.send_error(404, "Controller %s does not exist" % controller)
     try:
         action_meth = getattr(controller_inst, action)
         Logger.info("Forwarding to %s > %s with params = %s" % (controller, action, params)) 
         return action_meth(**params)
     except AttributeError:
         cls.send_error(404, "%s/%s does not exist" % (controller, action))
     except BaseException, e:
         Logger.error("Error while forwarding to %s > %s" % (controller, action), e)
         cls.send_error(500)
def _action_call_wrapper(f):
    ''' Monitor controller calls and performs some pre and post processing '''
    def wrapper(*kargs, **kwargs):
        
        inst = f.im_self
        name = f.__name__
        is_render_view = (name is "render_view")
        is_async = (hasattr(f, 'is_async') and f.is_async is True)
        is_action = (is_render_view or is_async)
        
        # Session recovery
        try:
            user_data = session.recover()
            if user_data:
                inst._session_recovery(inst, user_data[0], user_data[1])
        except Exception, e:
            Logger.error("Could not recover session", e)  
        
        # Format arguments
        formatted_kargs = format_http_args(kwargs)
        
        # Execute method
        start_time = time()
        if is_action:
            inst._before_action(name, **formatted_kargs)
            if is_async:
                res = _process_async_call(f, formatted_kargs)
            else:
                res = f(*kargs, **formatted_kargs)
            inst._after_action(name, **formatted_kargs)
        else:
            res = f(*kargs, **formatted_kargs)
        dt = round((time() - start_time) * 1000, 2)
        
        if is_render_view:
            Logger.debug("Rendered view %s in %s ms" % (kargs[0], dt))
        elif is_async:
            Logger.debug("Executed async call to %s in %s ms" % (name, dt))
        
        return res
 def redirect(cls, path, params=None):
     ''' Redirect the current request to the given path '''
     url = BaseController._make_url(path, params)
     Logger.info("Redirecting to %s" % url)
     cherrypy.lib.cptools.redirect(url, False)
     
        
        return res
    ret_f = wrapper
    ret_f.exposed = True
    return ret_f     

def _process_async_call(f, args):
    ''' Process an asynchronous action call and automatically format the response '''
    try:
        res = f(**args)
        data = res if res is not None else {}
        json_resp = format_async_response(data)
    except cherrypy.HTTPError, e:
        raise e
    except Exception, e:
        Logger.error("Error while processing call to %s" % f.__name__, e)
        json_resp = format_async_response(None, False, e)
    if Config.is_dev():
        Logger.debug("Async response to %s: %s" % (f.__name__, json_resp))
    return json_resp


##  CONTROLLER  #################################

class BaseController(object):
    ''' Base controller
    Abstract base for all controllers.
    Contains all sorts of helpers and structures that may be needed in controllers.
    '''
    
    instances = dict()