[Zope3-checkins] CVS: Zope3/src/zope/app/browser/services - serviceactivation.pt:1.2 configure.zcml:1.25 service.py:1.8 services.pt:1.4

Guido van Rossum guido@python.org
Fri, 7 Mar 2003 20:51:40 -0500


Update of /cvs-repository/Zope3/src/zope/app/browser/services
In directory cvs.zope.org:/tmp/cvs-serv20834

Modified Files:
	configure.zcml service.py services.pt 
Added Files:
	serviceactivation.pt 
Log Message:
Merge the short-lived service-config-branck back to the trunk.

This simplifies the default view of the service manager to just list
the configured services, relegating the service activation to a
separate view, reached via a link labeled "(configure)".

This no longer uses umpteen levels of nested views or macros, like the
original service manager default view . :-)


=== Zope3/src/zope/app/browser/services/serviceactivation.pt 1.1 => 1.2 ===
--- /dev/null	Fri Mar  7 20:51:39 2003
+++ Zope3/src/zope/app/browser/services/serviceactivation.pt	Fri Mar  7 20:51:38 2003
@@ -0,0 +1,62 @@
+<html metal:use-macro="views/standard_macros/page">
+
+<tal:block
+    metal:fill-slot="headers"
+    tal:define="global pagetip string:
+
+    To activate a particular service implementation,
+    check its radio button and click Update.
+
+    "
+    />
+
+
+<div metal:fill-slot="body">
+
+  <h2>
+    <span tal:replace="request/type|string:No service type specified" />
+  </h2>
+
+  <p tal:content="view/action">Message from action() goes here</p>
+
+  <form action="@@serviceActivation.html" method="GET">
+    <table tal:define="registry view/listRegistry">
+
+      <thead>
+        <tr> <td></td> <td>service</td> <td>configure</td> </tr>
+      </thead>
+
+      <tbody>
+
+        <tr tal:repeat="config registry">
+          <td><input type="radio" name="active" value="default/configure/1"
+                     tal:attributes="value config/id;
+                                     checked config/active" /></td>
+          <td><a href="foo"
+                 tal:content="config/name"
+                 tal:attributes="href config/url">Implementation</a>
+          </td>
+          <td><a href="foo"
+                 tal:content="config/id"
+                 tal:attributes="href config/config">Configuration</a>
+          </td>
+        </tr>
+
+        <tr>
+          <td><input type="radio" name="active" value="None"
+                     tal:attributes="checked view/isDisabled"></td>
+          <td>Disable</td>
+        </tr>
+      
+      </tbody>
+  
+    </table>
+
+    <input type="hidden" name="type" value="Events"
+           tal:attributes="value request/type|nothing" />
+    <input type="submit" value="Update">
+
+  </form>
+
+</div>
+</html>


=== Zope3/src/zope/app/browser/services/configure.zcml 1.24 => 1.25 ===
--- Zope3/src/zope/app/browser/services/configure.zcml:1.24	Fri Mar  7 11:44:43 2003
+++ Zope3/src/zope/app/browser/services/configure.zcml	Fri Mar  7 20:51:38 2003
@@ -564,7 +564,15 @@
      name="services.html"
      menu="zmi_views" title="Services"
      template="services.pt"
-     class=".namecomponentconfigurableview.NameComponentConfigurableView"
+     class=".service.ServiceSummary"
+     permission="zope.ManageServices"
+     />
+
+  <page
+     for="zope.app.interfaces.services.service.IServiceManager"
+     name="serviceActivation.html"
+     template="serviceactivation.pt"
+     class=".service.ServiceActivation"
      permission="zope.ManageServices"
      />
 


=== Zope3/src/zope/app/browser/services/service.py 1.7 => 1.8 ===
--- Zope3/src/zope/app/browser/services/service.py:1.7	Mon Mar  3 18:16:04 2003
+++ Zope3/src/zope/app/browser/services/service.py	Fri Mar  7 20:51:38 2003
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Adding components for components and configuration
+"""View support for adding and configuring services and other components.
 
 $Id$
 """
@@ -26,6 +26,7 @@
 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.traversing import getPhysicalPath
 from zope.app.interfaces.services.interfaces import ILocalService
 from zope.proxy.context import getWrapperContainer
 from zope.app.interfaces.services.configuration \
@@ -34,8 +35,7 @@
 __metaclass__ = type
 
 class ComponentAdding(Adding):
-    """Adding component for components
-    """
+    """Adding subclass used for configurable components."""
 
     menu_id = "add_component"
 
@@ -65,7 +65,7 @@
 
 
 class ServiceAdding(ComponentAdding):
-    """Adding a service."""
+    """Adding subclass used for adding services."""
 
     menu_id = "add_service"
 
@@ -87,14 +87,13 @@
 
 
 class ConfigurationAdding(Adding):
-    """Adding component for configuration
-    """
+    """Adding subclass for adding configurations."""
 
     menu_id = "add_configuration"
 
+
 class EditConfiguration(BrowserView):
-    """Adding component for service containers
-    """
+    """Adding component for service containers."""
 
     menu_id = "add_component"
 
@@ -103,10 +102,7 @@
         self.context = context
 
     def action(self):
-        """Perform actions depending on user input.
-
-
-        """
+        """Perform actions depending on user input."""
         if 'add_submit' in self.request:
             self.request.response.redirect('+')
             return ''
@@ -137,15 +133,13 @@
         return ''
 
     def remove_objects(self, key_list):
-        """Remove the directives from the container.
-        """
+        """Remove the directives from the container."""
         container = getAdapter(self.context, IZopeContainer)
         for item in key_list:
             del container[item]
 
     def configInfo(self):
-        """Render View for each direcitves.
-        """
+        """Render View for each directives."""
         r = []
         for name, directive in self.context.items():
             d = ContextWrapper(directive, self.context, name = name)
@@ -155,8 +149,8 @@
         return r
 
 
-class AddServiceConfiguration:
-    """A mixin class."""
+class AddServiceConfiguration(BrowserView):
+    """A view on a service implementation, used by add_svc_config.py."""
 
     def listServiceTypes(self):
 
@@ -189,3 +183,88 @@
                 sc.status = Registered
 
         self.request.response.redirect("@@useConfiguration.html")
+
+
+class ServiceSummary(BrowserView):
+    """A view on the service manager, used by services.pt."""
+
+    def listConfiguredServices(self):
+        names = list(self.context.listConfigurationNames())
+        names.sort()
+
+        items = []
+        for name in names:
+            registry = self.context.queryConfigurations(name)
+            assert registry
+            infos = registry.info()
+            assert infos
+            if infos[0]['active']:
+                # XXX This assumes if there is an active one it is the
+                # first one.  The implementation promises this, but
+                # the interface does not.  However Jim doesn't want
+                # the implementation changed so I guess the interface
+                # docs should be fixed.
+                configobj = infos[0]['configuration']
+                component = configobj.getComponent()
+                url = str(getView(component, 'absolute_url', self.request))
+            else:
+                url = ""
+            items.append({'name': name, 'url': url})
+
+        return items
+
+
+class ServiceActivation(BrowserView):
+    """A view on the service manager, used by serviceactivation.pt.
+
+    This really wants to be a view on a configuration registry
+    containing service configurations, but registries don't have names,
+    so we make it a view on the service manager; the request parameter
+    'type' determines which service is to be configured."""
+
+    def isDisabled(self):
+        sm = getServiceManager(self.context)
+        registry = sm.queryConfigurations(self.request.get('type'))
+        return not (registry and registry.active())
+
+    def listRegistry(self):
+        sm = getServiceManager(self.context)
+        registry = sm.queryConfigurations(self.request.get('type'))
+        if not registry:
+            return []
+
+        result = []
+        for info in registry.info():
+            configobj = info['configuration']
+            component = configobj.getComponent()
+            path = getPhysicalPath(component)
+            info['name'] = "/".join(path[-2:])
+            info['url'] = str(getView(component, 'absolute_url', self.request))
+            info['config'] = str(getView(configobj, 'absolute_url',
+                                         self.request))
+            result.append(info)
+        return result
+
+    def action(self):
+        active = self.request.get("active")
+        if not active:
+            return ""
+
+        sm = getServiceManager(self.context)
+        registry = sm.queryConfigurations(self.request.get('type'))
+        if not registry:
+            return "Invalid service type specified"
+        old_active = registry.active()
+        if active == "None":
+            new_active = None
+        else:
+            new_active = traverse(sm, "Packages/" + active)
+        if old_active == new_active:
+            return "No change"
+
+        if new_active is None:
+            old_active.status = Registered
+            return "Service deactivated"
+        else:
+            new_active.status = Active
+            return active + " activated"


=== Zope3/src/zope/app/browser/services/services.pt 1.3 => 1.4 ===
--- Zope3/src/zope/app/browser/services/services.pt:1.3	Sun Dec 29 17:24:16 2002
+++ Zope3/src/zope/app/browser/services/services.pt	Fri Mar  7 20:51:38 2003
@@ -1,12 +1,11 @@
 <html metal:use-macro="views/standard_macros/page">
 
-<tal:block  
-    metal:fill-slot="headers" 
+<tal:block
+    metal:fill-slot="headers"
     tal:define="global pagetip string:
 
-    To add a service, add a service component to a package and then
-    add an active configuration for it to the package's configuration
-    object.
+    To add a service, click on the Add Service link at the
+    top of this page.
 
     "
     />
@@ -14,27 +13,48 @@
 
 <div metal:fill-slot="body">
 
-  <div metal:use-macro="view/indexMacros/macros/body">
-
-  <h2 metal:fill-slot="heading">
-    Services configured in this service manager.
+  <h2>
+    Configured services in this service manager
   </h2>
 
-  <p metal:fill-slot="empty_text">No services have been configured</p>
-
-  <div metal:fill-slot="extra_top">
-
-    <p>For each service, the service name is given and all of the
-       components registered to provide the service are shown.  You
-       may select the component to provide the service or disable the
-       service.
-    </p>
+  <div tal:define="registries view/listConfiguredServices">
 
-    <p>Select a service name or a component name to visit the service
-       or component.
-    </p>
+      <p tal:condition="not:registries">No services are configured.</p>
 
-  </div>
+      <div tal:condition="registries">
+        <p>Unless a service is disabled, the service name
+           links to the active service.  The (configure) link allows
+           activating a different implementation or disabling the
+           service altogether.
+        </p>
+
+        <table>
+          <tbody>
+            <tr tal:repeat="reg registries">
+              <td>
+                <a href="(link to the active service)"
+                   tal:condition="reg/url"
+                   tal:attributes= "href
+                     string:${reg/url}/@@SelectedManagementView.html"
+                   tal:content="reg/name">
+                  Foobar (the service type)
+                </a>
+                <span tal:condition="not:reg/url">
+                  <span tal:content="reg/name" />
+                (disabled)</span>
+              </td>
+              <td>
+                <a href="xxx"
+                   tal:attributes=
+                   "href string:@@serviceActivation.html?type=${reg/name}"
+                   >
+                  (configure)
+                </a>
+              </td>
+            </tr>
+          <tbody>
+        </table>
+      </div>
 
   </div>
 </div>