[Zope3-checkins] CVS: Zope3/src/zope/app/browser/services - add_svc_config.pt:1.2 useconfiguration.pt:1.2 useconfiguration.py:1.2 configure.zcml:1.21 service.py:1.7 add_service_1.pt:NONE add_service_2.pt:NONE
Guido van Rossum
guido@python.org
Mon, 3 Mar 2003 18:16:36 -0500
Update of /cvs-repository/Zope3/src/zope/app/browser/services
In directory cvs.zope.org:/tmp/cvs-serv7820/src/zope/app/browser/services
Modified Files:
configure.zcml service.py
Added Files:
add_svc_config.pt useconfiguration.pt useconfiguration.py
Removed Files:
add_service_1.pt add_service_2.pt
Log Message:
Merge from use-config-branch. (A joint production by Jim, Tim and Guido.)
- Refactor the service creation and configuration code, making the UI
for creating and configuring services much more pleasant.
- Add a new marker interface, IUseConfigurable, which is used to say
that an object records dependencies between it and its
configurations. (This applies to other configurable objects besides
services.) Another marker interface, IAttributeUseConfigurable,
says that these dependencies are stored as annotations. And finally
IUseConfiguration defines the actual interface for discussing these
dependencies; implementing IUseConfigurable is a promise that such
an adapter exists (and implementing IAttributeUseConfigurable is one
way of making this promise come true :-).
- Add a new view tab for services, called "Configurations", which
displays links to its configurations with summary information. (Try
it for the Events service, which has two configurations by default.)
- Add a new interface, ILocalService, which all local services must
implement. Also add ISimpleService, which extends ILocalService
with IAttributeUseConfigurable. All existing local service
implementations implement this.
- Some miscellaneous cleanup (e.g. made the browser namespace the
default namespace in zope/app/browser/services/configure.zcml).
=== Zope3/src/zope/app/browser/services/add_svc_config.pt 1.1 => 1.2 ===
--- /dev/null Mon Mar 3 18:16:36 2003
+++ Zope3/src/zope/app/browser/services/add_svc_config.pt Mon Mar 3 18:16:04 2003
@@ -0,0 +1,48 @@
+<html metal:use-macro="context/@@standard_macros/page">
+ <body>
+ <div metal:fill-slot="body">
+
+ <form action="add_svc_config.html">
+
+ <p>Configure this object to provide the following service(s):
+
+ <table>
+
+ <thead>
+ <tr>
+ <th>Configure</th>
+ <th>Service name</th>
+ <th>Activate</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr tal:repeat="item view/listServiceTypes">
+
+ <td>
+ <input type="checkbox" name="name:list" value="value" checked
+ tal:attributes="value item/name">
+ </td>
+ <td tal:content="item/name">Events
+ </td>
+
+ <td>
+ <input type="checkbox" name="active:list" value="value"
+ tal:attributes="value item/name;
+ checked item/checked">
+ </td>
+
+ </tr>
+ </tbody>
+
+ </table>
+
+ <input type="reset" value="Reset form">
+ <input type="submit" value="Submit">
+
+
+ </form>
+
+ </div>
+ </body>
+</html>
=== Zope3/src/zope/app/browser/services/useconfiguration.pt 1.1 => 1.2 ===
--- /dev/null Mon Mar 3 18:16:36 2003
+++ Zope3/src/zope/app/browser/services/useconfiguration.pt Mon Mar 3 18:16:04 2003
@@ -0,0 +1,24 @@
+<html metal:use-macro="context/@@standard_macros/page">
+ <body>
+ <div metal:fill-slot="body">
+
+ <p>Configurations for this object:</p>
+
+ <ul>
+
+ <li tal:repeat="use view/uses">
+
+ <a href="http://."
+ tal:attributes="href use/url"
+ tal:content="use/name">
+ Example Service
+ </a> (<span tal:replace="use/status">Active</span>)
+
+ </li>
+ </ul>
+
+ <p><a href="addConfiguration.html">Add a configuration for this object</a>
+
+ </div>
+ </body>
+</html>
=== Zope3/src/zope/app/browser/services/useconfiguration.py 1.1 => 1.2 ===
--- /dev/null Mon Mar 3 18:16:36 2003
+++ Zope3/src/zope/app/browser/services/useconfiguration.py Mon Mar 3 18:16:04 2003
@@ -0,0 +1,40 @@
+##############################################################################
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+##############################################################################
+"""Use-Configuration view
+
+$Id$
+"""
+__metaclass__ = type
+
+from zope.component import getAdapter, getView
+from zope.app.interfaces.services.configuration import IUseConfiguration
+from zope.app.traversing import traverse
+
+class UseConfiguration:
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def uses(self):
+ component = self.context
+ useconfig = getAdapter(component, IUseConfiguration)
+ result = []
+ for path in useconfig.usages():
+ config = traverse(component, path)
+ url = getView(config, 'absolute_url', self.request)
+ result.append({'name': config.name,
+ 'path': path,
+ 'url': url(),
+ 'status': config.status,
+ })
+ return result
=== Zope3/src/zope/app/browser/services/configure.zcml 1.20 => 1.21 === (930/1030 lines abridged)
--- Zope3/src/zope/app/browser/services/configure.zcml:1.20 Fri Feb 21 09:50:05 2003
+++ Zope3/src/zope/app/browser/services/configure.zcml Mon Mar 3 18:16:04 2003
@@ -1,33 +1,34 @@
<zopeConfigure
- xmlns='http://namespaces.zope.org/zope'
- xmlns:browser='http://namespaces.zope.org/browser'
+ xmlns='http://namespaces.zope.org/browser'
>
<!--Error Reporting Service -->
- <browser:pages
+ <pages
for="zope.app.interfaces.services.error.IErrorReportingService"
permission="zope.Public"
class="zope.app.browser.services.error.EditErrorLog">
- <browser:page name="index.html" template="error.pt" />
- <browser:page name="edit.html" attribute="updateProperties" />
- <browser:page name="showEntry.html" template="errorentry.pt"/>
- <browser:page name="showTextTBEntry.html"
+ <page name="index.html" template="error.pt" />
+ <page name="edit.html" attribute="updateProperties" />
+ <page name="showEntry.html" template="errorentry.pt"/>
+ <page name="showTextTBEntry.html"
template="texttbentry.pt"/>
- </browser:pages>
+ </pages>
- <browser:menuItem menu="add_component"
+ <menuItem
+ menu="add_service"
for="zope.app.interfaces.container.IAdding"
- action="ErrorReportingService" title='Error Reporting Service'
- description='Error Reporting Service for Logging Errors'
+ action="ErrorReportingService"
+ title="Error Reporting Service"
+ description="Error Reporting Service for Logging Errors"
/>
- <browser:icon name="zmi_icon"
+ <icon name="zmi_icon"
for="zope.app.interfaces.services.error.IErrorReportingService"
file="error_service.gif" />
- <browser:menuItem
+ <menuItem
for="zope.app.interfaces.services.error.IErrorReportingService"
menu="zmi_views"
title="Errors"
[-=- -=- -=- 930 lines omitted -=- -=- -=-]
+<page
name="index.html"
menu="zmi_views" title="Control"
permission="zope.ManageServices"
@@ -831,18 +846,41 @@
attribute="index"
/>
- <browser:menuItem
- menu="add_component"
+ <menuItem
+ menu="add_service"
for="zope.app.interfaces.container.IAdding"
action="ObjectHub"
- title='ObjectHub'
+ title="ObjectHub Service"
description="An object hub, for cataloging, unique object ids, and
more: use sparingly"
/>
- <browser:icon
+ <icon
name="zmi_icon"
for="zope.app.interfaces.services.hub.IObjectHub"
file="hub.gif" />
+
+
+<!-- "Add Service" menu -->
+
+<menuItem
+ menu="add_component"
+ for="zope.app.interfaces.container.IAdding"
+ action="../AddService"
+ title="Service"
+ description="Takes you to a menu of services to add"
+ permission="zope.ManageServices"
+ />
+
+ <view
+ name="AddService"
+ for="zope.app.interfaces.services.package.IPackage"
+ permission="zope.ManageServices"
+ class="zope.app.browser.services.service.ServiceAdding">
+
+ <page name="index.html" attribute="index" />
+ <page name="action.html" attribute="action" />
+
+ </view>
</zopeConfigure>
=== Zope3/src/zope/app/browser/services/service.py 1.6 => 1.7 ===
--- Zope3/src/zope/app/browser/services/service.py:1.6 Fri Feb 21 09:53:34 2003
+++ Zope3/src/zope/app/browser/services/service.py Mon Mar 3 18:16:04 2003
@@ -16,7 +16,7 @@
$Id$
"""
-from zope.app.browser.container.adding import Adding as ContentAdding
+from zope.app.browser.container.adding import Adding
from zope.component import getView, getAdapter
from zope.proxy.context import ContextWrapper, ContextSuper
from zope.app.interfaces.container import IZopeContainer
@@ -25,30 +25,68 @@
from zope.app.services.service import ServiceConfiguration
from zope.app.interfaces.services.configuration import IConfiguration
from zope.app.form.utility import setUpWidgets, getWidgetsDataForContent
+from zope.app.traversing import traverse, getPhysicalPathString
+from zope.app.interfaces.services.interfaces import ILocalService
+from zope.proxy.context import getWrapperContainer
+from zope.app.interfaces.services.configuration \
+ import Unregistered, Registered, Active
__metaclass__ = type
-class ComponentAdding(ContentAdding):
+class ComponentAdding(Adding):
"""Adding component for components
"""
menu_id = "add_component"
def action(self, type_name, id):
+ if type_name == "../AddService":
+ # Special case
+ url = type_name
+ if id:
+ url += "?id=" + id
+ self.request.response.redirect(url)
+ return
+
if not id:
# Generate an id from the type name
id = type_name
l = id.rfind('.')
if l >= 0:
id = id[l+1:]
- if id in self.context:
- i=2
- while ("%s-%s" % (id, i)) in self.context:
- i=i+1
- id = "%s-%s" % (id, i)
- return ContextSuper(ComponentAdding, self).action(type_name, id)
+ i = 1
+ while ("%s-%s" % (id, i)) in self.context:
+ i=i+1
+ id = "%s-%s" % (id, i)
+
+ # Call the superclass action() method.
+ # As a side effect, self.added_object is set by add() above.
+ ContextSuper(ComponentAdding, self).action(type_name, id)
+
+
+class ServiceAdding(ComponentAdding):
+ """Adding a service."""
+
+ menu_id = "add_service"
+
+ def add(self, content):
+ # Override so as to save a reference to the added object
+ self.added_object = ContextSuper(ComponentAdding, self).add(content)
+ return self.added_object
+
+ def action(self, type_name, id):
+ # Call the superclass action() method.
+ # As a side effect, self.added_object is set by add() above.
+ ContextSuper(ServiceAdding, self).action(type_name, id)
+
+ if not ILocalService.isImplementedBy(self.added_object):
+ raise TypeError("%s is not a local service" % self.added_object)
+
+ url = getPhysicalPathString(self.added_object)
+ self.request.response.redirect(url + "/addConfiguration.html")
+
-class ConfigurationAdding(ContentAdding):
+class ConfigurationAdding(Adding):
"""Adding component for configuration
"""
@@ -116,31 +154,38 @@
r.append({'key': name, 'view': view})
return r
-class AddServiceConfiguration(BrowserView):
- def __init__(self, *args):
- super(AddServiceConfiguration, self).__init__(*args)
- setUpWidgets(self, IConfiguration)
-
- def services(self):
- service = getServiceManager(self.context.context)
- definitions = service.getServiceDefinitions()
- names = [name for (name, interface) in definitions]
- names.sort()
- return names
-
- def components(self):
- service_type = self.request['service_type']
- service = getServiceManager(self.context.context)
- type = service.getInterfaceFor(service_type)
- paths = [info['path']
- for info in service.queryComponent(type=type)
- ]
- paths.sort()
- return paths
-
- def action(self, service_type, component_path):
- sd = ServiceConfiguration(service_type, component_path)
- sd = self.context.add(sd)
- getWidgetsDataForContent(self, IConfiguration, sd, strict=False)
- self.request.response.redirect(self.context.nextURL())
+class AddServiceConfiguration:
+ """A mixin class."""
+
+ def listServiceTypes(self):
+
+ # Collect all defined services interfaces that it implements.
+ sm = getServiceManager(self.context)
+ lst = []
+ for servicename, interface in sm.getServiceDefinitions():
+ if interface.isImplementedBy(self.context):
+ registry = sm.queryConfigurations(servicename)
+ checked = True
+ if registry and registry.active():
+ checked = False
+ d = {'name': servicename, 'checked': checked}
+ lst.append(d)
+ return lst
+
+ def action(self, name=[], active=[]):
+ path = getPhysicalPathString(self.context)
+ configure = traverse(getWrapperContainer(self.context), 'configure')
+ container = getAdapter(configure, IZopeContainer)
+
+ for nm in name:
+ # XXX Shouldn't hardcode 'configure'
+ sc = ServiceConfiguration(nm, path, self.context)
+ name = container.setObject("", sc)
+ sc = container[name]
+ if nm in active:
+ sc.status = Active
+ else:
+ sc.status = Registered
+
+ self.request.response.redirect("@@useConfiguration.html")
=== Removed File Zope3/src/zope/app/browser/services/add_service_1.pt ===
=== Removed File Zope3/src/zope/app/browser/services/add_service_2.pt ===