Files
deb-python-pecan/pecan/hooks.py
Jonathan LaCour ccde2c07c8 Some reorganization, more tests, improved handling of errors, and
support for prioritized hooks.
2010-09-30 10:11:21 -04:00

78 lines
2.1 KiB
Python

from inspect import getmembers, ismethod
from routing import iscontroller
__all__ = ['PecanHook', 'TransactionHook', 'HookController']
def walk_controller(root_class, controller, hooks):
if hasattr(controller, '_lookup'):
# TODO: what about this?
pass
if not isinstance(controller, (int, dict)):
for name, value in controller.__dict__.iteritems():
if name == 'controller': continue
if name.startswith('__') and name.endswith('__'): continue
if iscontroller(value):
for hook in hooks:
value.pecan.setdefault('hooks', []).append(hook)
elif hasattr(value, '__class__'):
if name.startswith('__') and name.endswith('__'): continue
walk_controller(root_class, value, hooks)
class HookController(object):
__hooks__ = []
class __metaclass__(type):
def __init__(cls, name, bases, dict_):
walk_controller(cls, cls, dict_['__hooks__'])
class PecanHook(object):
priority = 100
def before(self, state):
pass
def after(self, state):
pass
def on_error(self, state, e):
pass
class TransactionHook(PecanHook):
def __init__(self, start, start_ro, commit, rollback, clear):
self.start = start
self.start_ro = start_ro
self.commit = commit
self.rollback = rollback
self.clear = clear
def is_transactional(self, state):
if state.request.method not in ('GET', 'HEAD'):
return True
return False
def before(self, state):
state.request.error = False
if self.is_transactional(state):
state.request.transactional = True
self.start()
else:
state.request.transactional = False
self.start_ro()
def on_error(self, state, e):
state.request.error = True
def after(self, state):
if state.request.transactional:
if state.request.error:
self.rollback()
else:
self.commit()
self.clear()