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,9 +76,10 @@ 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
	
	 helmutm
						helmutm