extending composer and organize.schema to provide basis for tumsm
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1845 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
7aad7a6430
commit
242c4a4921
13 changed files with 225 additions and 31 deletions
|
@ -54,7 +54,9 @@ class Template(object):
|
|||
implements(ITemplate)
|
||||
|
||||
componentStorage = Jeep
|
||||
components = None
|
||||
|
||||
def __init__(self):
|
||||
if self.componentStorage is not None:
|
||||
self.components = self.componentStorage()
|
||||
|
||||
|
|
|
@ -31,25 +31,25 @@ class Instance(object):
|
|||
|
||||
implements(IInstance)
|
||||
|
||||
templateStorage = dict
|
||||
templateAttributeName = '__ctc_templates__'
|
||||
templateFactory = dict
|
||||
templateAttributeName = '__ctc_template__'
|
||||
|
||||
aspect = 'composer.default'
|
||||
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
self.instances = []
|
||||
|
||||
def setTemplate(self, template):
|
||||
templates = getattr(self.context,
|
||||
self.templateAttributeName, self.templateStorage())
|
||||
templates.setdefault(self.aspect, template)
|
||||
setattr(self.context, self.templateAttributeName, templates)
|
||||
def setTemplate(self, temp):
|
||||
template = getattr(self.context,
|
||||
self.templateAttributeName,
|
||||
self.templateFactory())
|
||||
template.setdefault(self.aspect, temp)
|
||||
setattr(self.context, self.templateAttributeName, template)
|
||||
def getTemplate(self):
|
||||
templates = getattr(self.context, self.templateAttributeName, {})
|
||||
return templates.get(self.aspect, None)
|
||||
template = getattr(self.context, self.templateAttributeName, {})
|
||||
return template.get(self.aspect, [])
|
||||
template = property(getTemplate, setTemplate)
|
||||
|
||||
def applyTemplate(self, *args, **kw):
|
||||
def applyTemplates(self, *args, **kw):
|
||||
raise ValueError('To be implemented by subclass')
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class IInstance(Interface):
|
|||
"""
|
||||
|
||||
context = Attribute('Object this instance adapter has been created for')
|
||||
template = Attribute('The template to be used for this instance')
|
||||
template = Attribute('A template to be used for this instance')
|
||||
aspect = Attribute('A dotted name that helps to store and retrieve the '
|
||||
'template.')
|
||||
|
||||
|
|
4
composer/schema/browser/__init__.py
Normal file
4
composer/schema/browser/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
"""
|
||||
$Id$
|
||||
"""
|
||||
|
34
composer/schema/browser/base.py
Normal file
34
composer/schema/browser/base.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# 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 browser view classes for composer.schema.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
|
||||
from cybertools.composer.instance import Instance
|
||||
|
||||
|
||||
class SchemaView(object):
|
||||
|
||||
@Lazy
|
||||
def fields(self):
|
||||
return self.context.fields
|
19
composer/schema/browser/configure.zcml
Normal file
19
composer/schema/browser/configure.zcml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<!-- $Id$ -->
|
||||
|
||||
<configure
|
||||
xmlns="http://namespaces.zope.org/browser"
|
||||
xmlns:zope="http://namespaces.zope.org/zope"
|
||||
i18n_domain="zope">
|
||||
|
||||
<page
|
||||
for="cybertools.composer.schema.interfaces.ISchema"
|
||||
name="index.html"
|
||||
class="cybertools.composer.schema.browser.base.SchemaView"
|
||||
permission="zope.View"
|
||||
/>
|
||||
|
||||
<defaultView
|
||||
name="index.html"
|
||||
for="cybertools.composer.schema.interfaces.ISchema" />
|
||||
|
||||
</configure>
|
|
@ -35,8 +35,15 @@ class Field(Component):
|
|||
|
||||
def __init__(self, name, title=None, renderFactory=None, **kw):
|
||||
assert name
|
||||
self.name = self.__name__ = name
|
||||
title = title is None and name or title
|
||||
self.__name__ = name
|
||||
title = title or u''
|
||||
self.renderFactory = renderFactory # use for rendering field content
|
||||
super(Field, self).__init__(title, __name__=name, **kw)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.__name__
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self.title or self.name
|
||||
|
|
|
@ -38,6 +38,9 @@ class ISchema(ITemplate):
|
|||
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')
|
||||
|
||||
|
||||
class IField(IComponent):
|
||||
""" May be used for data entry or display.
|
||||
|
|
|
@ -33,7 +33,12 @@ class Schema(Template):
|
|||
|
||||
implements(ISchema)
|
||||
|
||||
def __init__(self, *fields):
|
||||
name = u''
|
||||
manager = None
|
||||
|
||||
def __init__(self, *fields, **kw):
|
||||
self.name = kw.get('name', u'')
|
||||
self.manager = kw.get('manager', None)
|
||||
super(Schema, self).__init__()
|
||||
for f in fields:
|
||||
self.components.append(f)
|
||||
|
|
|
@ -128,6 +128,18 @@ 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.')
|
||||
|
||||
clientSchemas = Attribute('An optional collection of schema objects '
|
||||
'that describe the data fields of the client '
|
||||
'objects.')
|
||||
|
||||
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,
|
||||
|
@ -183,6 +195,24 @@ class IScheduledService(IService):
|
|||
duration = Attribute('Time delta between start and end date/time.')
|
||||
|
||||
|
||||
class IClient(Interface):
|
||||
""" An fairly abstract interface for objects to be used as clients
|
||||
for services.
|
||||
"""
|
||||
|
||||
manager = Attribute('The object that cares for this client.')
|
||||
|
||||
|
||||
class IClientFactory(Interface):
|
||||
""" Creates client objects.
|
||||
"""
|
||||
|
||||
def __call__(data):
|
||||
""" Creates and returns a client object built from the
|
||||
data set provided.
|
||||
"""
|
||||
|
||||
|
||||
class IRegistration(Interface):
|
||||
""" Information about the registration of a client with a service.
|
||||
"""
|
||||
|
|
|
@ -22,9 +22,15 @@ Service management classes.
|
|||
$Id$
|
||||
"""
|
||||
|
||||
from BTrees.OOBTree import OOBTree
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.component import adapts
|
||||
from zope.interface import implements
|
||||
from cybertools.composer.interfaces import IInstance
|
||||
from cybertools.util.jeep import Jeep
|
||||
|
||||
from cybertools.organize.interfaces import IServiceManager
|
||||
from cybertools.organize.interfaces import IClient, IClientFactory
|
||||
from cybertools.organize.interfaces import IService, IScheduledService
|
||||
|
||||
|
||||
|
@ -32,6 +38,30 @@ class ServiceManager(object):
|
|||
|
||||
implements(IServiceManager)
|
||||
|
||||
servicesFactory = list
|
||||
clientSchemasFactory = Jeep
|
||||
clientsFactory = OOBTree
|
||||
|
||||
clientNum = 0
|
||||
|
||||
def __init__(self):
|
||||
if self.servicesFactory is not None:
|
||||
self.services = self.servicesFactory()
|
||||
if self.clientSchemasFactory is not None:
|
||||
self.clientSchemas = self.clientSchemasFactory()
|
||||
|
||||
@Lazy
|
||||
def clients(self):
|
||||
return self.clientsFactory()
|
||||
|
||||
def addClient(self, client):
|
||||
name = self.generateClientName(client)
|
||||
self.clients[name] = client
|
||||
|
||||
def generateClientName(self, client):
|
||||
self.clientNum += 1
|
||||
return '%05i' % self.clientNum
|
||||
|
||||
|
||||
class Service(object):
|
||||
|
||||
|
@ -60,6 +90,57 @@ class ScheduledService(Service):
|
|||
implements(IScheduledService)
|
||||
|
||||
|
||||
class Client(object):
|
||||
|
||||
implements(IClient)
|
||||
|
||||
def __init__(self, manager):
|
||||
self.manager = manager
|
||||
|
||||
|
||||
class ClientFactory(object):
|
||||
|
||||
implements(IClientFactory)
|
||||
adapts(IServiceManager)
|
||||
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
|
||||
def __call__(self):
|
||||
return Client(self.context)
|
||||
|
||||
|
||||
class ClientInstanceAdapter(object):
|
||||
|
||||
implements(IInstance)
|
||||
adapts(IClient)
|
||||
|
||||
baseAspect = 'service.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)
|
||||
|
||||
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
|
||||
template = self.template
|
||||
attributes = self.context.attributes.setdefault(self.aspect, OOBTree())
|
||||
if template is not None:
|
||||
for c in template.components:
|
||||
name = c.name
|
||||
attributes[name] = data.get(name, u'')
|
||||
|
||||
|
||||
class Registration(object):
|
||||
|
||||
def __init__(self, client):
|
||||
|
|
12
util/jeep.py
12
util/jeep.py
|
@ -31,10 +31,10 @@ class Jeep(object):
|
|||
_attributes = ('_sequence',)
|
||||
|
||||
def __init__(self, seq=[]):
|
||||
self._sequence = []
|
||||
for item in seq:
|
||||
attr, value = item
|
||||
setattr(self, attr, value)
|
||||
sequence = self._sequence = []
|
||||
for attr, value in seq:
|
||||
sequence.append(attr)
|
||||
object.__setattr__(self, attr, value)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._sequence)
|
||||
|
@ -47,11 +47,11 @@ class Jeep(object):
|
|||
if not attr in self._attributes:
|
||||
if getattr(self, attr, _notfound) is _notfound:
|
||||
self._sequence.append(attr)
|
||||
object.__setattr__(self, attr, value)
|
||||
super(Jeep, self).__setattr__(attr, value)
|
||||
|
||||
def __delattr__(self, attr):
|
||||
del self._sequence[self.index(attr)]
|
||||
object.__delattr__(self, attr)
|
||||
super(Jeep, self).__delattr__(attr)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if type(key) in (int, long):
|
||||
|
|
|
@ -21,26 +21,33 @@ A general purpose (thus 'Jeep') class that provides most of the interfaces
|
|||
of sequences and dictionaries and in addition allows attribute access to
|
||||
the dictionary entries.
|
||||
|
||||
This is the Zope-based persistent variant of the Jeep class.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from persistent import Persistent
|
||||
from persistent.list import PersistentList
|
||||
from BTrees.OOBTree import OOBTree
|
||||
from zope.app.container.interfaces import IContainer
|
||||
from zope.interface import implements
|
||||
|
||||
_notfound = object()
|
||||
_nodefault = object()
|
||||
|
||||
|
||||
class Jeep(object):
|
||||
class Jeep(Persistent):
|
||||
|
||||
implements(IContainer)
|
||||
|
||||
_attributes = ('_sequence', '_mapping')
|
||||
|
||||
def __init__(self, seq=[]):
|
||||
self._sequence = PersistentList()
|
||||
self._mapping = OOBTree()
|
||||
for item in seq:
|
||||
attr, value = item
|
||||
setattr(self, attr, value)
|
||||
sequence = self._sequence = PersistentList()
|
||||
mapping = self._mapping = OOBTree()
|
||||
for attr, value in seq:
|
||||
sequence.append(attr)
|
||||
mapping[attr] = value
|
||||
|
||||
def __len__(self):
|
||||
return len(self._sequence)
|
||||
|
@ -60,7 +67,7 @@ class Jeep(object):
|
|||
|
||||
def __setattr__(self, attr, value):
|
||||
if attr in self._attributes:
|
||||
object.__setattr__(self, attr, value)
|
||||
super(Jeep, self).__setattr__(attr, value)
|
||||
else:
|
||||
if getattr(self, attr, _notfound) is _notfound:
|
||||
self._sequence.append(attr)
|
||||
|
@ -87,6 +94,8 @@ class Jeep(object):
|
|||
def __contains__(self, key):
|
||||
return getattr(self, key, _notfound) is not _notfound
|
||||
|
||||
has_key = __contains__
|
||||
|
||||
def keys(self):
|
||||
return [key for key in self._sequence]
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue