work in progress: rules and action handling
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2144 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
1b67c54099
commit
f9e8a3f45c
4 changed files with 64 additions and 32 deletions
|
@ -8,6 +8,10 @@ Rule-based Execution of Actions
|
||||||
>>> from cybertools.composer.rule.base import RuleManager, Rule, Action
|
>>> from cybertools.composer.rule.base import RuleManager, Rule, Action
|
||||||
>>> from cybertools.composer.rule.base import EventType, Event
|
>>> from cybertools.composer.rule.base import EventType, Event
|
||||||
|
|
||||||
|
>>> from cybertools.composer.rule.base import ActionHandler
|
||||||
|
>>> component.provideAdapter(ActionHandler, name='message')
|
||||||
|
>>> component.provideAdapter(ActionHandler, name='sendmail')
|
||||||
|
|
||||||
>>> manager = RuleManager()
|
>>> manager = RuleManager()
|
||||||
|
|
||||||
>>> loginEvent = EventType('login')
|
>>> loginEvent = EventType('login')
|
||||||
|
@ -18,7 +22,7 @@ Rule-based Execution of Actions
|
||||||
>>> checkoutRule.actions.append(Action('message',
|
>>> checkoutRule.actions.append(Action('message',
|
||||||
... parameters = dict(messageName='confirmation_mail')))
|
... parameters = dict(messageName='confirmation_mail')))
|
||||||
>>> checkoutRule.actions.append(Action('sendmail'))
|
>>> checkoutRule.actions.append(Action('sendmail'))
|
||||||
>>> manager.rules.append(checkoutRule)
|
>>> manager.addRule(checkoutRule)
|
||||||
|
|
||||||
>>> manager.handleEvent(Event(loginEvent))
|
>>> manager.handleEvent(Event(loginEvent))
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ Basic classes for rules and actions.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from zope import component
|
||||||
|
from zope.component import adapts
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
|
|
||||||
from cybertools.composer.base import Component, Element, Compound
|
from cybertools.composer.base import Component, Element, Compound
|
||||||
|
@ -42,12 +44,29 @@ class RuleManager(object):
|
||||||
rulesFactory = Jeep
|
rulesFactory = Jeep
|
||||||
rules = None
|
rules = None
|
||||||
|
|
||||||
def __init__(self):
|
def addRule(self, rule):
|
||||||
if self.rulesFactory is not None:
|
rule.manager = self
|
||||||
|
if self.rules is None:
|
||||||
self.rules = self.rulesFactory()
|
self.rules = self.rulesFactory()
|
||||||
|
for e in rule.events:
|
||||||
|
entry = self.rules.setdefault(e.name, [])
|
||||||
|
entry.append(rule)
|
||||||
|
|
||||||
|
def getRulesForEvent(self, event):
|
||||||
|
return self.rules.get(event.name, [])
|
||||||
|
|
||||||
def handleEvent(self, event):
|
def handleEvent(self, event):
|
||||||
pass
|
rules = self.getRulesForEvent(event)
|
||||||
|
for r in rules:
|
||||||
|
for c in r.conditions:
|
||||||
|
cond = component.getAdapter(r, ICondition, name=c)
|
||||||
|
if not cond(event):
|
||||||
|
continue
|
||||||
|
data = None
|
||||||
|
for action in r.actions:
|
||||||
|
handler = component.getAdapter(action, IActionHandler,
|
||||||
|
name=action.handlerName)
|
||||||
|
data = handler(data, event)
|
||||||
|
|
||||||
|
|
||||||
class Rule(Template):
|
class Rule(Template):
|
||||||
|
@ -101,21 +120,13 @@ class Event(object):
|
||||||
|
|
||||||
# conditions
|
# conditions
|
||||||
|
|
||||||
class ConditionType(object):
|
|
||||||
|
|
||||||
def __init__(self, name, title):
|
|
||||||
self.name = name
|
|
||||||
self.title = title
|
|
||||||
|
|
||||||
|
|
||||||
class Condition(object):
|
class Condition(object):
|
||||||
|
|
||||||
implements(ICondition)
|
implements(ICondition)
|
||||||
|
adapts(IRule)
|
||||||
|
|
||||||
def __init__(self, conditionType):
|
def __init__(self, context):
|
||||||
self.conditionType = conditionType
|
self.context = context
|
||||||
self.name = conditionType.name
|
|
||||||
self.title = conditionType.title
|
|
||||||
|
|
||||||
def __call__(self, context, params):
|
def __call__(self, context, params):
|
||||||
return True
|
return True
|
||||||
|
@ -123,7 +134,7 @@ class Condition(object):
|
||||||
|
|
||||||
# actions
|
# actions
|
||||||
|
|
||||||
class Action(object):
|
class Action(Component):
|
||||||
|
|
||||||
implements(IAction)
|
implements(IAction)
|
||||||
|
|
||||||
|
@ -133,17 +144,22 @@ class Action(object):
|
||||||
rule = None
|
rule = None
|
||||||
|
|
||||||
def __init__(self, name, **kw):
|
def __init__(self, name, **kw):
|
||||||
|
self.name = name
|
||||||
for k, v in kw.items():
|
for k, v in kw.items():
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
if self.parameters is None:
|
if self.parameters is None:
|
||||||
self.parameters = {}
|
self.parameters = {}
|
||||||
if not self.handlerName:
|
if not self.handlerName:
|
||||||
self.handlerName = self.name
|
self.handlerName = name
|
||||||
|
|
||||||
|
|
||||||
class ActionHandler(object):
|
class ActionHandler(object):
|
||||||
|
|
||||||
implements(IActionHandler)
|
implements(IActionHandler)
|
||||||
|
adapts(IAction)
|
||||||
|
|
||||||
def __call__(self, data, params):
|
def __init__(self, context):
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
def __call__(self, data, event, params={}):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -40,11 +40,21 @@ class IRuleManager(Interface):
|
||||||
description=_(u'The title of the object.'),
|
description=_(u'The title of the object.'),
|
||||||
required=True,)
|
required=True,)
|
||||||
|
|
||||||
rules = Attribute('An ordered collection of rules managed by this object.')
|
#rules = Attribute('An ordered collection of rules managed by this object.')
|
||||||
|
|
||||||
|
def addRule(rule):
|
||||||
|
""" Add the rule given to the rule manager's collection of rules,
|
||||||
|
registering it for the event types that are handled by
|
||||||
|
the rule.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getRulesForEvent(event):
|
||||||
|
""" Retrieve the rules that may handle the event given.
|
||||||
|
"""
|
||||||
|
|
||||||
def handleEvent(event):
|
def handleEvent(event):
|
||||||
""" Handle the event given and apply the corresponding rules
|
""" Handle the event given and apply the corresponding rules
|
||||||
to the client object.
|
to the event's context object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +76,8 @@ class IRule(ITemplate):
|
||||||
required=False,)
|
required=False,)
|
||||||
|
|
||||||
manager = Attribute('The associated rule manager.')
|
manager = Attribute('The associated rule manager.')
|
||||||
events = Attribute('The events to be handled by this rule.')
|
events = Attribute('The events (the event types, to be more precise) '
|
||||||
|
'to be handled by this rule.')
|
||||||
conditions = Attribute('Conditions to be checked.'
|
conditions = Attribute('Conditions to be checked.'
|
||||||
'This is typically a list of names of ICondition adapters.')
|
'This is typically a list of names of ICondition adapters.')
|
||||||
actions = Attribute('Sequence of actions to be carried out by this rule.')
|
actions = Attribute('Sequence of actions to be carried out by this rule.')
|
||||||
|
@ -81,7 +92,7 @@ class IEvent(Interface):
|
||||||
|
|
||||||
class ICondition(Interface):
|
class ICondition(Interface):
|
||||||
|
|
||||||
def __call__(context, params):
|
def __call__(context, event, params):
|
||||||
""" Should return True if the condition should be fulfilled;
|
""" Should return True if the condition should be fulfilled;
|
||||||
will allow the rule to call its actions.
|
will allow the rule to call its actions.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -45,18 +45,16 @@ from cybertools.organize.interfaces import IRegistration, IRegistrationTemplate
|
||||||
from cybertools.organize.interfaces import IClientRegistrations
|
from cybertools.organize.interfaces import IClientRegistrations
|
||||||
|
|
||||||
|
|
||||||
class ServiceManager(RuleManager):
|
class ServiceManager(object):
|
||||||
|
|
||||||
implements(IServiceManager, IClientManager)
|
implements(IServiceManager, IClientManager)
|
||||||
|
|
||||||
servicesFactory = Jeep
|
servicesFactory = Jeep
|
||||||
clientSchemasFactory = Jeep
|
clientSchemasFactory = Jeep
|
||||||
clientsFactory = OOBTree
|
clientsFactory = OOBTree
|
||||||
rulesFactory = Jeep
|
|
||||||
|
|
||||||
services = None
|
services = None
|
||||||
clients = None
|
clients = None
|
||||||
rules = None
|
|
||||||
|
|
||||||
allowRegWithNumber = False
|
allowRegWithNumber = False
|
||||||
allowDirectRegistration = True
|
allowDirectRegistration = True
|
||||||
|
@ -66,8 +64,6 @@ class ServiceManager(RuleManager):
|
||||||
self.services = self.servicesFactory()
|
self.services = self.servicesFactory()
|
||||||
if self.clientSchemasFactory is not None:
|
if self.clientSchemasFactory is not None:
|
||||||
self.clientSchemas = self.clientSchemasFactory()
|
self.clientSchemas = self.clientSchemasFactory()
|
||||||
if self.rulesFactory is not None:
|
|
||||||
self.rules = self.rulesFactory()
|
|
||||||
|
|
||||||
def getServices(self, categories=[]):
|
def getServices(self, categories=[]):
|
||||||
return self.services
|
return self.services
|
||||||
|
@ -94,9 +90,6 @@ class ServiceManager(RuleManager):
|
||||||
def checkClientName(self, name):
|
def checkClientName(self, name):
|
||||||
return name not in self.getClients()
|
return name not in self.getClients()
|
||||||
|
|
||||||
def getRules(self):
|
|
||||||
return self.rules
|
|
||||||
|
|
||||||
|
|
||||||
class Registration(object):
|
class Registration(object):
|
||||||
|
|
||||||
|
@ -351,13 +344,21 @@ class StatefulRegistration(StatefulAdapter):
|
||||||
statesDefinition = registrationStates
|
statesDefinition = registrationStates
|
||||||
|
|
||||||
|
|
||||||
# event types for rule-based processing
|
# rules and events
|
||||||
|
|
||||||
eventTypes = Jeep((
|
eventTypes = Jeep((
|
||||||
EventType('service.checkout'),
|
EventType('service.checkout'),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
class RuleManagerAdapter(RuleManager):
|
||||||
|
|
||||||
|
adapts(IServiceManager)
|
||||||
|
|
||||||
|
def __init__(self, context):
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
|
||||||
# Zope event handlers
|
# Zope event handlers
|
||||||
|
|
||||||
def clientRemoved(obj, event):
|
def clientRemoved(obj, event):
|
||||||
|
|
Loading…
Add table
Reference in a new issue