work in progress: service managment with composer.schema for tumsm

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1851 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-07-31 09:15:48 +00:00
parent 59923d2830
commit e6e73ab46d
7 changed files with 142 additions and 67 deletions

View file

@ -22,13 +22,60 @@ Basic browser view classes for composer.schema.
$Id$
"""
from zope import component
from zope.cachedescriptors.property import Lazy
from zope.traversing.browser import absoluteURL
from cybertools.composer.instance import Instance
from cybertools.composer.interfaces import IInstance
from cybertools.composer.schema.interfaces import IClientFactory
class SchemaView(object):
def __init__(self, context, request):
self.context = context
self.request = request
self.clientName = None
@Lazy
def fields(self):
return self.context.fields
@Lazy
def data(self):
form = self.request.form
clientName = self.clientName = form.get('id')
if not clientName:
return {}
manager = self.context.manager
client = manager.clients.get(clientName)
if client is None:
return {}
instance = IInstance(client)
instance.template = self.context
return instance.applyTemplate()
def update(self):
form = self.request.form
if not form.get('action'):
return True
manager = self.context.manager
clientName = form.get('id')
if clientName:
client = manager.clients.get(clientName)
if client is None:
# TODO: provide error message (?)
return True
else:
client = IClientFactory(manager)()
clientName = self.clientName = manager.addClient(client)
instance = component.getAdapter(client, IInstance, name='editor')
instance.template = self.context
instance.applyTemplate(form)
self.request.response.redirect(self.nextUrl)
return False
@Lazy
def nextUrl(self):
url = absoluteURL(self.context, self.request)
return '%s/thank_you?id=%s' % (url, self.clientName)

View file

@ -22,6 +22,7 @@ Client implementations.
$Id$
"""
from persistent import Persistent
from zope.component import adapts
from zope.interface import implements
@ -29,11 +30,11 @@ from cybertools.composer.schema.interfaces import IClient
from cybertools.composer.schema.interfaces import IClientManager, IClientFactory
class Client(object):
class Client(Persistent):
implements(IClient)
def __init__(self, manager):
def __init__(self, manager=None):
self.manager = manager

View file

@ -44,33 +44,56 @@ class Editor(Instance):
print c.name, getattr(self.context, c.name, '-')
class ClientInstanceAdapter(object):
class ClientInstance(object):
implements(IInstance)
adapts(IClient)
attrsName = '__schema_attributes__'
template = None
baseAspect = 'schema.client.'
schema = 'default'
@property
def aspect(self):
return self.baseAspect + self.schema
@property
def template(self):
return self.context.manager.clientSchemas.get(self.schema, None)
return self.baseAspect + self.template.name
def __init__(self, context):
self.context = context
def applyTemplate(self, data={}, schema='default', **kw):
if getattr(self.context, 'attributes', None) is None:
self.context.attributes = OOBTree()
self.schema = schema
def applyTemplate(self, **kw):
""" Return a mapping of field names from self.template (a schema)
to the corresponding values from the context object.
"""
result = {}
attrs = getattr(self.context, self.attrsName, None)
if attrs is None:
return result
template = self.template
attributes = self.context.attributes.setdefault(self.aspect, OOBTree())
values = attrs.setdefault(self.aspect, {})
if template is not None:
for c in template.components:
name = c.name
attributes[name] = data.get(name, u'')
result[name] = values.get(name, u'')
result['__name__'] = self.context.__name__
return result
class ClientInstanceEditor(ClientInstance):
def applyTemplate(self, data={}, **kw):
""" Store the attributes described by self.template (a schema)
using corresponding values from the data argument.
"""
attrs = getattr(self.context, self.attrsName, None)
if attrs is None:
attrs = OOBTree()
setattr(self.context, self.attrsName, attrs)
template = self.template
values = attrs.setdefault(self.aspect, OOBTree())
if template is not None:
for c in template.components:
name = c.name
if name in data:
values[name] = data[name]

View file

@ -35,11 +35,14 @@ class ISchema(ITemplate):
""" Represents an ordered sequence of fields.
"""
name = Attribute('An internal name of the schema; will be used '
'to identify data fields of instance objects that '
'are associated with this schema.')
fields = Attribute('The components the schema is built up of. '
'Should be a sequence of IField objects.')
manager = Attribute('A manager object that may provide special '
'features, e.g. a factory of o')
'features, e.g. a factory for objects to be associated '
'with this schema.')
class IField(IComponent):
@ -47,31 +50,31 @@ class IField(IComponent):
"""
name = schema.ASCII(
title=_(u'Fieldname'),
description=_(u'The internal name of the field'),
required=True,)
title=_(u'Fieldname'),
description=_(u'The internal name of the field'),
required=True,)
title = schema.TextLine(
title=_(u'Title'),
description=_(u'The title or label of the field'),
required=True,)
title=_(u'Title'),
description=_(u'The title or label of the field'),
required=True,)
description = schema.Text(
title=_(u'Description'),
description=_(u'A more lengthy description of the field'),
required=False,)
title=_(u'Description'),
description=_(u'A more lengthy description of the field'),
required=False,)
fieldType = schema.Choice(
title=_(u'Field type'),
description=_(u'The type of the field'),
required=True,
default='textline',
values=('textline', 'textarea', 'date'))
title=_(u'Field type'),
description=_(u'The type of the field'),
required=True,
default='textline',
values=('textline', 'textarea', 'date'))
defaultValue = schema.TextLine(
title=_(u'Default'),
description=_(u'Value with which to pre-set the field contents'),
required=False,)
title=_(u'Default'),
description=_(u'Value with which to pre-set the field contents'),
required=False,)
required = schema.Bool(
title=_(u'Required'),
description=_(u'Must a value been entered into this field?'),
required=False,)
title=_(u'Required'),
description=_(u'Must a value been entered into this field?'),
required=False,)
# clients
@ -97,8 +100,14 @@ class IClientManager(Interface):
""" Cares for a client typically providing schemas.
"""
clients = Attribute('A collection of client objects (e.g. persons) '
'associated with this client manager.')
clientSchemas = Attribute('A collection of schema objects '
'that describe the data fields of the client '
'objects.')
'that describe the data fields of the client '
'objects.')
def addClient(client):
""" Add the client object given to the collection of clients.
"""

View file

@ -38,7 +38,7 @@ class Schema(Template):
def __init__(self, *fields, **kw):
self.name = kw.get('name', u'')
self.manager = kw.get('manager', None)
self.manager = self.__parent__ = kw.get('manager', None)
super(Schema, self).__init__()
for f in fields:
self.components.append(f)
@ -46,3 +46,7 @@ class Schema(Template):
@property
def fields(self):
return self.components
@property
def __name__(self):
return self.name

View file

@ -128,43 +128,32 @@ class IServiceManager(Interface):
services = Attribute('A collection of services managed by this object.')
clients = Attribute('A collection of client objects (e.g. persons) '
'that have registered or want to register for '
'services managed by this service manager.')
def addClient(client):
""" Add the client object given to the collection of clients.
"""
class IServiceGroup(Interface):
""" A group of related services or a general service definition,
e.g. a regular bus service or a series of trainings.
"""
services = Attribute('A collection of services belonging to this object.')
class IService(Interface):
""" A service that clients may register with.
"""
serviceGroup = Attribute('The service group this object is an instance of.')
capacity = schema.Int(
title=_(u'Capacity'),
description=_(u'The capacity (maximum number of clients) '
title=_(u'Capacity'),
description=_(u'The capacity (maximum number of clients) '
'of this service; a negative number means: '
'no restriction, i.e. unlimited capacity.'),
required=False,)
required=False,)
availableCapacity = Attribute('Available capacity, i.e. number of seats '
'still available; a negative number means: '
'no restriction, i.e. unlimited capacity; '
'read-only')
'still available; a negative number means: '
'no restriction, i.e. unlimited capacity; '
'read-only')
serviceProviders = Attribute('A collection of one or more service providers.')
resources = Attribute('A collection of one or more resources.')
registrations = Attribute('A collection of client registrations.')
def register(client):
@ -180,14 +169,13 @@ class IScheduledService(IService):
"""
start = schema.Date(
title=_(u'Start date/time'),
description=_(u'The date/time when the service starts'),
required=False,)
title=_(u'Start date/time'),
description=_(u'The date/time when the service starts'),
required=False,)
end = schema.Date(
title=_(u'End date/time'),
description=_(u'The date/time when the service ends'),
required=False,)
title=_(u'End date/time'),
description=_(u'The date/time when the service ends'),
required=False,)
duration = Attribute('Time delta between start and end date/time.')

View file

@ -57,6 +57,9 @@ class ServiceManager(object):
def addClient(self, client):
name = self.generateClientName(client)
self.clients[name] = client
client.__name__ = name
client.__parent__ = self
return name
def generateClientName(self, client):
self.clientNum += 1