provide classes and a view for managing service registrations for client objects (see IClientRegistrations)
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1878 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
c9987844b3
commit
d9ff76c433
4 changed files with 227 additions and 9 deletions
19
organize/browser/configure.zcml
Normal file
19
organize/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.organize.interfaces.IClientRegistrations"
|
||||||
|
name="index.html"
|
||||||
|
class="cybertools.organize.browser.service.ClientRegistrationsView"
|
||||||
|
permission="zope.View"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<defaultView
|
||||||
|
name="index.html"
|
||||||
|
for="cybertools.organize.interfaces.IClientRegistrations" />
|
||||||
|
|
||||||
|
</configure>
|
92
organize/browser/service.py
Normal file
92
organize/browser/service.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#
|
||||||
|
# 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 import component
|
||||||
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
|
||||||
|
from cybertools.organize.interfaces import IClientRegistrations
|
||||||
|
from cybertools.composer.schema.interfaces import IClientFactory
|
||||||
|
|
||||||
|
|
||||||
|
class RegistrationTemplateView(object):
|
||||||
|
|
||||||
|
clientName = None
|
||||||
|
|
||||||
|
def __init__(self, context, request):
|
||||||
|
self.context = context
|
||||||
|
self.request = request
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def services(self):
|
||||||
|
return self.context.services
|
||||||
|
|
||||||
|
def getRegistrations(self):
|
||||||
|
if not self.clientName:
|
||||||
|
form = self.request.form
|
||||||
|
self.clientName = form.get('id')
|
||||||
|
clientName = self.clientName
|
||||||
|
if not clientName:
|
||||||
|
return []
|
||||||
|
manager = self.context.getManager()
|
||||||
|
client = manager.getClients().get(clientName)
|
||||||
|
if client is None:
|
||||||
|
return []
|
||||||
|
regs = IClientRegistrations(client)
|
||||||
|
regs.template = self.context
|
||||||
|
return regs.getRegistrations()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
form = self.request.form
|
||||||
|
if not self.clientName:
|
||||||
|
self.clientName = form.get('id')
|
||||||
|
clientName = self.clientName
|
||||||
|
if not form.get('action'):
|
||||||
|
return True
|
||||||
|
manager = self.context.getManager()
|
||||||
|
if clientName:
|
||||||
|
client = manager.getClients().get(clientName)
|
||||||
|
if client is None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
client = IClientFactory(manager)()
|
||||||
|
clientName = self.clientName = manager.addClient(client)
|
||||||
|
regs = IClientRegistrations(client)
|
||||||
|
regs.template = self.context
|
||||||
|
allServices = self.context.services.values()
|
||||||
|
oldServices = [r.service for r in regs.getRegistrations()]
|
||||||
|
newServices = [manager.services[token]
|
||||||
|
for token in form.get('service_tokens', [])]
|
||||||
|
regs.register(newServices)
|
||||||
|
toDelete = [s for s in oldServices
|
||||||
|
if s in allServices and s not in newServices]
|
||||||
|
regs.unregister(toDelete)
|
||||||
|
return True
|
||||||
|
#self.request.response.redirect(self.nextUrl)
|
||||||
|
#return False
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def nextUrl(self):
|
||||||
|
from zope.traversing.browser import absoluteURL
|
||||||
|
url = absoluteURL(self.context, self.request)
|
||||||
|
return '%s/thankyou.html?id=%s' % (url, self.clientName)
|
|
@ -141,7 +141,11 @@ class IService(Interface):
|
||||||
""" A service that clients may register with.
|
""" A service that clients may register with.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serviceGroup = Attribute('The service group this object is an instance of.')
|
category = schema.TextLine(
|
||||||
|
title=_(u'Category'),
|
||||||
|
description=_(u'A tokenized term characterizing the type of '
|
||||||
|
'this service, e.g. an event or a transport.'),
|
||||||
|
required=False,)
|
||||||
capacity = schema.Int(
|
capacity = schema.Int(
|
||||||
title=_(u'Capacity'),
|
title=_(u'Capacity'),
|
||||||
description=_(u'The capacity (maximum number of clients) '
|
description=_(u'The capacity (maximum number of clients) '
|
||||||
|
@ -152,6 +156,13 @@ class IService(Interface):
|
||||||
'still available; a negative number means: '
|
'still available; a negative number means: '
|
||||||
'no restriction, i.e. unlimited capacity; '
|
'no restriction, i.e. unlimited capacity; '
|
||||||
'read-only')
|
'read-only')
|
||||||
|
|
||||||
|
token = Attribute('A name unique within the manager of this service '
|
||||||
|
'used for identifying the service e.g. in forms.')
|
||||||
|
serviceGroup = Attribute('The service group this object is an instance of.')
|
||||||
|
classification = Attribute('A sequence of tokenized terms characterizing '
|
||||||
|
'this service within a hierarchy of concepts.')
|
||||||
|
|
||||||
serviceProviders = Attribute('A collection of one or more service providers.')
|
serviceProviders = Attribute('A collection of one or more service providers.')
|
||||||
resources = Attribute('A collection of one or more resources.')
|
resources = Attribute('A collection of one or more resources.')
|
||||||
registrations = Attribute('A collection of client registrations.')
|
registrations = Attribute('A collection of client registrations.')
|
||||||
|
@ -162,6 +173,10 @@ class IService(Interface):
|
||||||
(e.g. if the service's capacity is exhausted) return None.
|
(e.g. if the service's capacity is exhausted) return None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def unregister(client):
|
||||||
|
""" Remove the client from this service's registrations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IScheduledService(IService):
|
class IScheduledService(IService):
|
||||||
""" A service that starts at a certain date/time and
|
""" A service that starts at a certain date/time and
|
||||||
|
@ -205,9 +220,42 @@ class IRegistration(Interface):
|
||||||
|
|
||||||
|
|
||||||
class IRegistrationTemplate(Interface):
|
class IRegistrationTemplate(Interface):
|
||||||
""" Provides and processes data for a service registration form.
|
""" A content object controlling access to service registrations
|
||||||
|
of a certain client.
|
||||||
|
|
||||||
|
The client should be accessed via an IClientRegistrations adapter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# TODO: provide fields for criteria for selecting the services
|
||||||
|
# that should be handled by this object, e.g. service
|
||||||
|
# category/ies or classification(s).
|
||||||
|
|
||||||
|
manager = Attribute('The service manager this object belongs to.')
|
||||||
|
services = Attribute('A collection of services to which this '
|
||||||
|
'object provides access. This may be all or part '
|
||||||
|
'of the services managed by the manager.')
|
||||||
|
|
||||||
|
|
||||||
|
class IClientRegistrations(Interface):
|
||||||
|
""" Provides access to a client object and allows to manage its service
|
||||||
|
registrations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
template = Attribute('A regstration template that is used '
|
||||||
|
'for controlling the registration process.')
|
||||||
|
|
||||||
|
def register(services):
|
||||||
|
""" Register the client for the services given.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def unregister(services):
|
||||||
|
""" Remove the client from the services given.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getRegistrations():
|
||||||
|
""" Return the client's service registrations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IResource(Interface):
|
class IResource(Interface):
|
||||||
""" A resource is needed by a service to be able to work, e.g. a
|
""" A resource is needed by a service to be able to work, e.g. a
|
||||||
|
|
|
@ -29,20 +29,24 @@ from zope.interface import implements
|
||||||
from cybertools.composer.interfaces import IInstance
|
from cybertools.composer.interfaces import IInstance
|
||||||
from cybertools.util.jeep import Jeep
|
from cybertools.util.jeep import Jeep
|
||||||
|
|
||||||
from cybertools.composer.schema.interfaces import IClientManager
|
from cybertools.composer.schema.interfaces import IClientManager, IClient
|
||||||
from cybertools.organize.interfaces import IServiceManager
|
from cybertools.organize.interfaces import IServiceManager
|
||||||
from cybertools.organize.interfaces import IService, IScheduledService
|
from cybertools.organize.interfaces import IService, IScheduledService
|
||||||
from cybertools.organize.interfaces import IRegistration, IRegistrationTemplate
|
from cybertools.organize.interfaces import IRegistration, IRegistrationTemplate
|
||||||
|
from cybertools.organize.interfaces import IClientRegistrations
|
||||||
|
|
||||||
|
|
||||||
class ServiceManager(object):
|
class ServiceManager(object):
|
||||||
|
|
||||||
implements(IServiceManager, IClientManager)
|
implements(IServiceManager, IClientManager)
|
||||||
|
|
||||||
servicesFactory = list
|
servicesFactory = Jeep
|
||||||
clientSchemasFactory = Jeep
|
clientSchemasFactory = Jeep
|
||||||
clientsFactory = OOBTree
|
clientsFactory = OOBTree
|
||||||
|
|
||||||
|
services = None
|
||||||
|
clients = None
|
||||||
|
|
||||||
clientNum = 0
|
clientNum = 0
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -73,9 +77,17 @@ class Service(object):
|
||||||
|
|
||||||
implements(IService)
|
implements(IService)
|
||||||
|
|
||||||
def __init__(self, capacity=-1):
|
registrationsFactory = OOBTree
|
||||||
|
|
||||||
|
def __init__(self, name=None, capacity=-1):
|
||||||
|
self.name = name
|
||||||
self.capacity = capacity
|
self.capacity = capacity
|
||||||
self.registrations = []
|
if self.registrationsFactory is not None:
|
||||||
|
self.registrations = self.registrationsFactory()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def token(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def availableCapacity(self):
|
def availableCapacity(self):
|
||||||
|
@ -84,27 +96,74 @@ class Service(object):
|
||||||
return self.capacity - len(self.registrations)
|
return self.capacity - len(self.registrations)
|
||||||
|
|
||||||
def register(self, client):
|
def register(self, client):
|
||||||
|
clientName = client.__name__
|
||||||
|
if clientName in self.registrations:
|
||||||
|
return self.registrations[clientName]
|
||||||
if self.availableCapacity:
|
if self.availableCapacity:
|
||||||
reg = Registration(client)
|
reg = Registration(client, self)
|
||||||
self.registrations.append(reg)
|
self.registrations[clientName] = reg
|
||||||
return reg
|
return reg
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def unregister(self, client):
|
||||||
|
clientName = client.__name__
|
||||||
|
if clientName in self.registrations:
|
||||||
|
del self.registrations[clientName]
|
||||||
|
|
||||||
|
|
||||||
class ScheduledService(Service):
|
class ScheduledService(Service):
|
||||||
|
|
||||||
implements(IScheduledService)
|
implements(IScheduledService)
|
||||||
|
|
||||||
|
|
||||||
|
# registration
|
||||||
|
|
||||||
class Registration(object):
|
class Registration(object):
|
||||||
|
|
||||||
implements(IRegistration)
|
implements(IRegistration)
|
||||||
|
|
||||||
def __init__(self, client):
|
def __init__(self, client, service):
|
||||||
self.client = client
|
self.client = client
|
||||||
|
self.service = service
|
||||||
|
|
||||||
|
|
||||||
class RegistrationTemplate(object):
|
class RegistrationTemplate(object):
|
||||||
|
|
||||||
implements(IRegistrationTemplate)
|
implements(IRegistrationTemplate)
|
||||||
|
|
||||||
|
def __init__(self, name=None, manager=None):
|
||||||
|
self.name = name
|
||||||
|
self.manager = manager
|
||||||
|
|
||||||
|
@property
|
||||||
|
def services(self):
|
||||||
|
return self.manager.services
|
||||||
|
|
||||||
|
def getManager(self):
|
||||||
|
return self.manager
|
||||||
|
|
||||||
|
|
||||||
|
class ClientRegistrations(object):
|
||||||
|
|
||||||
|
implements(IClientRegistrations)
|
||||||
|
adapts(IClient)
|
||||||
|
|
||||||
|
template = None
|
||||||
|
|
||||||
|
def __init__(self, context):
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
def register(self, services):
|
||||||
|
for service in services:
|
||||||
|
service.register(self.context)
|
||||||
|
|
||||||
|
def unregister(self, services):
|
||||||
|
for service in services:
|
||||||
|
service.unregister(self.context)
|
||||||
|
|
||||||
|
def getRegistrations(self):
|
||||||
|
for service in self.template.services:
|
||||||
|
for reg in service.registrations.values():
|
||||||
|
if self.context == reg.client:
|
||||||
|
yield reg
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue