initial set up for new composer.rule package
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2118 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
2ab7fc800b
commit
c701a05d9e
11 changed files with 422 additions and 5 deletions
|
@ -37,11 +37,15 @@ class MessageManager(object):
|
|||
messagesFactory = Jeep
|
||||
|
||||
messages = None
|
||||
manager = None
|
||||
|
||||
def __init__(self):
|
||||
if self.messagesFactory is not None:
|
||||
self.messages = self.messagesFactory()
|
||||
|
||||
def getManager(self):
|
||||
return self.manager
|
||||
|
||||
|
||||
class Message(Template):
|
||||
|
||||
|
@ -55,5 +59,3 @@ class Message(Template):
|
|||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
|
||||
|
||||
|
|
28
composer/rule/README.txt
Normal file
28
composer/rule/README.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
===============================
|
||||
Rule-based Execution of Actions
|
||||
===============================
|
||||
|
||||
($Id$)
|
||||
|
||||
>>> from zope import component
|
||||
>>> from cybertools.composer.rule.base import RuleManager, Rule, Action
|
||||
>>> from cybertools.composer.rule.base import EventType, Event
|
||||
|
||||
>>> manager = RuleManager()
|
||||
|
||||
>>> loginEvent = EventType('login')
|
||||
>>> checkoutEvent = EventType('service.checkout')
|
||||
|
||||
>>> checkoutRule = Rule('regcheckoutmail', manager=manager)
|
||||
>>> checkoutRule.events.append(checkoutEvent)
|
||||
>>> checkoutRule.actions.append(Action('message',
|
||||
... parameters = dict(messageName='confirmation_mail')))
|
||||
>>> checkoutRule.actions.append(Action('sendmail'))
|
||||
>>> manager.rules.append(checkoutRule)
|
||||
|
||||
>>> manager.handleEvent(Event(loginEvent))
|
||||
|
||||
>>> client = object()
|
||||
|
||||
>>> manager.handleEvent(Event(checkoutEvent, client))
|
||||
|
4
composer/rule/__init__.py
Normal file
4
composer/rule/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
"""
|
||||
$Id$
|
||||
"""
|
||||
|
149
composer/rule/base.py
Normal file
149
composer/rule/base.py
Normal file
|
@ -0,0 +1,149 @@
|
|||
#
|
||||
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Basic classes for rules and actions.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.interface import implements
|
||||
|
||||
from cybertools.composer.base import Component, Element, Compound
|
||||
from cybertools.composer.base import Template
|
||||
from cybertools.composer.interfaces import IInstance
|
||||
from cybertools.composer.rule.interfaces import IRuleManager, IRule
|
||||
from cybertools.composer.rule.interfaces import IEvent, ICondition
|
||||
from cybertools.composer.rule.interfaces import IAction, IActionHandler
|
||||
from cybertools.util.jeep import Jeep
|
||||
|
||||
|
||||
# rules
|
||||
|
||||
class RuleManager(object):
|
||||
|
||||
implements(IRuleManager)
|
||||
|
||||
rulesFactory = Jeep
|
||||
rules = None
|
||||
|
||||
def __init__(self):
|
||||
if self.rulesFactory is not None:
|
||||
self.rules = self.rulesFactory()
|
||||
|
||||
def handleEvent(self, event):
|
||||
pass
|
||||
|
||||
|
||||
class Rule(Template):
|
||||
|
||||
implements(IRule)
|
||||
|
||||
name = title = description = u''
|
||||
manager = None
|
||||
actions = None
|
||||
events = None
|
||||
conditions = None
|
||||
|
||||
def __init__(self, name, **kw):
|
||||
self.name = name
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
self.events = []
|
||||
self.conditions = []
|
||||
self.actions = []
|
||||
|
||||
|
||||
class RuleInstance(object):
|
||||
|
||||
implements(IInstance)
|
||||
|
||||
template = None
|
||||
|
||||
def applyTemplate(self):
|
||||
pass
|
||||
|
||||
|
||||
# events
|
||||
|
||||
class EventType(object):
|
||||
|
||||
def __init__(self, name, title=None):
|
||||
self.name = name
|
||||
self.title = title or name
|
||||
|
||||
|
||||
class Event(object):
|
||||
|
||||
implements(IEvent)
|
||||
|
||||
def __init__(self, eventType, context=None):
|
||||
self.eventType = eventType
|
||||
self.name = eventType.name
|
||||
self.title = eventType.title
|
||||
self.context = context
|
||||
|
||||
|
||||
# conditions
|
||||
|
||||
class ConditionType(object):
|
||||
|
||||
def __init__(self, name, title):
|
||||
self.name = name
|
||||
self.title = title
|
||||
|
||||
|
||||
class Condition(object):
|
||||
|
||||
implements(ICondition)
|
||||
|
||||
def __init__(self, conditionType):
|
||||
self.conditionType = conditionType
|
||||
self.name = conditionType.name
|
||||
self.title = conditionType.title
|
||||
|
||||
def __call__(self, context, params):
|
||||
return True
|
||||
|
||||
|
||||
# actions
|
||||
|
||||
class Action(object):
|
||||
|
||||
implements(IAction)
|
||||
|
||||
name = u''
|
||||
handlerName = u''
|
||||
parameters = None
|
||||
rule = None
|
||||
|
||||
def __init__(self, name, **kw):
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
if self.parameters is None:
|
||||
self.parameters = {}
|
||||
if not self.handlerName:
|
||||
self.handlerName = self.name
|
||||
|
||||
|
||||
class ActionHandler(object):
|
||||
|
||||
implements(IActionHandler)
|
||||
|
||||
def __call__(self, data, params):
|
||||
pass
|
8
composer/rule/configure.zcml
Normal file
8
composer/rule/configure.zcml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!-- $Id$ -->
|
||||
|
||||
<configure
|
||||
xmlns="http://namespaces.zope.org/zope"
|
||||
xmlns:browser="http://namespaces.zope.org/browser"
|
||||
i18n_domain="zope">
|
||||
|
||||
</configure>
|
43
composer/rule/instance.py
Normal file
43
composer/rule/instance.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Rule instance and related classes.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from string import Template
|
||||
from zope import component
|
||||
from zope.interface import implements
|
||||
|
||||
from cybertools.composer.instance import Instance
|
||||
from cybertools.composer.interfaces import IInstance
|
||||
|
||||
|
||||
class RuleInstance(Instance):
|
||||
|
||||
template = client = None
|
||||
|
||||
def __init__(self, client, template):
|
||||
self.client = client
|
||||
self.template = template
|
||||
|
||||
def applyTemplate(self, **kw):
|
||||
pass
|
||||
|
112
composer/rule/interfaces.py
Normal file
112
composer/rule/interfaces.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
#
|
||||
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Message management.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.interface import Interface, Attribute
|
||||
from zope.i18nmessageid import MessageFactory
|
||||
from zope import schema
|
||||
|
||||
from cybertools.composer.interfaces import ITemplate, IComponent
|
||||
|
||||
_ = MessageFactory('zope')
|
||||
|
||||
|
||||
class IRuleManager(Interface):
|
||||
""" A manager (or container) for rules.
|
||||
"""
|
||||
|
||||
title = schema.TextLine(
|
||||
title=_(u'Title'),
|
||||
description=_(u'The title of the object.'),
|
||||
required=True,)
|
||||
|
||||
rules = Attribute('An ordered collection of rules managed by this object.')
|
||||
|
||||
def handleEvent(event):
|
||||
""" Handle the event given and apply the corresponding rules
|
||||
to the client object.
|
||||
"""
|
||||
|
||||
|
||||
class IRule(ITemplate):
|
||||
""" A rule that will be applied .
|
||||
"""
|
||||
|
||||
name = schema.ASCII(
|
||||
title=_(u'Name'),
|
||||
description=_(u'The internal name of the rule.'),
|
||||
required=True,)
|
||||
title = schema.TextLine(
|
||||
title=_(u'Title'),
|
||||
description=_(u'The title or label of the rule.'),
|
||||
required=True,)
|
||||
description = schema.Text(
|
||||
title=_(u'Description'),
|
||||
description=_(u'A brief description of the rule.'),
|
||||
required=False,)
|
||||
|
||||
manager = Attribute('The associated rule manager.')
|
||||
events = Attribute('The events to be handled by this rule.')
|
||||
conditions = Attribute('Conditions to be checked.'
|
||||
'This is typically a list of names of ICondition adapters.')
|
||||
actions = Attribute('Sequence of actions to be carried out by this rule.')
|
||||
|
||||
|
||||
class IEvent(Interface):
|
||||
|
||||
name = Attribute('The name by which the event will be identified.')
|
||||
title = Attribute('A human readable title or label.')
|
||||
context = Attribute('An object that is associated with the event.')
|
||||
|
||||
|
||||
class ICondition(Interface):
|
||||
|
||||
def __call__(context, params):
|
||||
""" Should return True if the condition should be fulfilled;
|
||||
will allow the rule to call its actions.
|
||||
"""
|
||||
|
||||
|
||||
class IAction(IComponent):
|
||||
""" Controls what will be done.
|
||||
"""
|
||||
|
||||
name = schema.ASCII(
|
||||
title=_(u'Name'),
|
||||
description=_(u'The name of the action.'),
|
||||
required=True,)
|
||||
|
||||
handlerName = Attribute('Name of the adapter that will carry out the action.')
|
||||
parameters = Attribute('Mapping with additional preset informations that '
|
||||
'will be supplied to the action handlers.')
|
||||
rule = Attribute('The rule the action belongs to.')
|
||||
|
||||
|
||||
class IActionHandler(Interface):
|
||||
""" Does the real work.
|
||||
"""
|
||||
|
||||
def __call__(data, params):
|
||||
""" Execute the action, using the data and parameters given (mappings).
|
||||
"""
|
||||
|
33
composer/rule/mail.py
Normal file
33
composer/rule/mail.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Event definitions.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.interface import implements
|
||||
|
||||
from cybertools.composer.rule.base import ActionHandler
|
||||
|
||||
|
||||
class MailActionHandler(ActionHandler):
|
||||
|
||||
pass
|
||||
|
22
composer/rule/tests.py
Executable file
22
composer/rule/tests.py
Executable file
|
@ -0,0 +1,22 @@
|
|||
# $Id$
|
||||
|
||||
import unittest, doctest
|
||||
from zope.testing.doctestunit import DocFileSuite
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
"Basic tests."
|
||||
|
||||
def testBasics(self):
|
||||
pass
|
||||
|
||||
|
||||
def test_suite():
|
||||
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
|
||||
return unittest.TestSuite((
|
||||
unittest.makeSuite(Test),
|
||||
DocFileSuite('README.txt', optionflags=flags),
|
||||
))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -17,7 +17,8 @@
|
|||
#
|
||||
|
||||
"""
|
||||
Basic classes for a complex template structures.
|
||||
Basic classes for schemas, i.e. sets of fields that may be used for creating
|
||||
editing forms or display views for objects.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
|
|
@ -31,6 +31,7 @@ from zope import component
|
|||
from zope.interface import implements, Interface
|
||||
|
||||
from cybertools.composer.interfaces import IInstance
|
||||
from cybertools.composer.rule.base import RuleManager, EventType
|
||||
from cybertools.composer.schema.interfaces import IClientManager, IClient
|
||||
from cybertools.stateful.definition import registerStatesDefinition
|
||||
from cybertools.stateful.definition import StatesDefinition
|
||||
|
@ -43,16 +44,18 @@ from cybertools.organize.interfaces import IRegistration, IRegistrationTemplate
|
|||
from cybertools.organize.interfaces import IClientRegistrations
|
||||
|
||||
|
||||
class ServiceManager(object):
|
||||
class ServiceManager(RuleManager):
|
||||
|
||||
implements(IServiceManager, IClientManager)
|
||||
|
||||
servicesFactory = Jeep
|
||||
clientSchemasFactory = Jeep
|
||||
clientsFactory = OOBTree
|
||||
rulesFactory = Jeep
|
||||
|
||||
services = None
|
||||
clients = None
|
||||
rules = None
|
||||
|
||||
allowRegWithNumber = False
|
||||
allowDirectRegistration = True
|
||||
|
@ -62,6 +65,8 @@ class ServiceManager(object):
|
|||
self.services = self.servicesFactory()
|
||||
if self.clientSchemasFactory is not None:
|
||||
self.clientSchemas = self.clientSchemasFactory()
|
||||
if self.rulesFactory is not None:
|
||||
self.rules = self.rulesFactory()
|
||||
|
||||
def getServices(self, categories=[]):
|
||||
return self.services
|
||||
|
@ -88,6 +93,9 @@ class ServiceManager(object):
|
|||
def checkClientName(self, name):
|
||||
return name not in self.getClients()
|
||||
|
||||
def getRules(self):
|
||||
return self.rules
|
||||
|
||||
|
||||
class Service(object):
|
||||
|
||||
|
@ -274,7 +282,14 @@ registerStatesDefinition(
|
|||
))
|
||||
|
||||
|
||||
# event handlers
|
||||
# event types
|
||||
|
||||
eventTypes = Jeep((
|
||||
EventType('service.checkout'),
|
||||
))
|
||||
|
||||
|
||||
# Zope event handlers
|
||||
|
||||
def clientRemoved(obj, event):
|
||||
""" Handle removal of a client object.
|
||||
|
|
Loading…
Add table
Reference in a new issue