[Zope3-checkins] CVS: Zope3/src/zope/app/browser/services - bundle.pt:1.4 bundle.py:1.4

Guido van Rossum guido@python.org
Mon, 16 Jun 2003 17:00:30 -0400


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

Modified Files:
	bundle.pt bundle.py 
Log Message:
Another checkpoint or milestone.  We now can activate the bundle,
reporting conflicts to the UI.  Neat. :-)


=== Zope3/src/zope/app/browser/services/bundle.pt 1.3 => 1.4 ===
--- Zope3/src/zope/app/browser/services/bundle.pt:1.3	Mon Jun 16 13:54:59 2003
+++ Zope3/src/zope/app/browser/services/bundle.pt	Mon Jun 16 17:00:29 2003
@@ -1,6 +1,6 @@
 <html metal:use-macro="views/standard_macros/page">
 
-<div metal:fill-slot="body">
+<div metal:fill-slot="body" tal:define="message view/update">
 
 <h1>Bundle Information</h1>
 
@@ -8,23 +8,24 @@
 
 <ul>
   <li tal:repeat="svc view/listServices">
-    <i tal:content="svc/service">Foo</i> service
+    <i tal:content="svc/service">Foo</i> service:
     <span tal:condition="svc/insite">
       present in site at
-      <a tal:content="svc/path" tal:attributes="href svc/path">/somewhere</a>
+      <a tal:content="svc/path" tal:attributes="href svc/path">/path</a>
     </span>
     <span tal:condition="not:svc/insite">
       <span tal:condition="svc/inbundle">
-        present in bundle at
+        configured in bundle at
         <a tal:content="svc/inbundle"
-           tal:attributes="href svc/inbundle">somewhere</a>
+           tal:attributes="href svc/inbundle">path</a>
       </span>
       <span tal:condition="not:svc/inbundle">
         <font size="+1" color="red">
-          <i><b>UNFULFILLED DEPENDENCY</b></i>
+          <b>UNFULFILLED DEPENDENCY</b>
         </font>
-        <br><b>(You must add a <i tal:content="svc/service">Foo</i>
-        service to this site before you can activate this bundle)</b>
+        <br><b>(You must <a href="../default/AddService">add a
+        <i tal:content="svc/service">Foo</i>
+        service to this site</a> before you can activate this bundle)</b>
       </span>
     </span>
   </li>
@@ -32,24 +33,64 @@
 
 <h4>Configurations in this bundle</h4>
 
-<tal:block tal:repeat="svc view/listServices">
+  <div class="message" tal:condition="message">
+    <span tal:replace="message">view/update message here</span>
+    <br><br><i><a href="@@bundle.html">(click to clear message)</a></i>
+  </div>
+
+<form action="@@bundle.html" method="GET">
+
+  <p><input type="submit" value="Submit all changes" /></p>
+
+  <p><input type="reset" value="Reset form" /></p>
+
+  <p>
+    <input type="checkbox" name="allclear" value="1" />
+    Unregister all configurations in this bundle (ignoring the rest of
+    this form).
+  </p>
+
+  <tal:block tal:repeat="svc view/listServices">
+
+    <p>For <i tal:content="svc/service">Foo</i> service</p>
+
+    <ul>
+      <tal:block tal:repeat="cnf view/listConfigurations">
+        <li tal:condition="python: cnf['service'] == svc['service']">
+          <a tal:content="cnf/path" tal:attributes="href cnf/path">path</a>
+          <br>
+          <i tal:content="cnf/usage">Usage summary</i>
+          implemented by
+          <i tal:content="cnf/implementation">Implementation summary</i>
+          <br>
+          <span tal:condition="not:cnf/conflict">
+            Advice:
+            <b><input type="radio" tal:attributes="name cnf/path"
+                   value="Registered" />Registered</b>
+            <b><input type="radio" tal:attributes="name cnf/path"
+                   value="Active" checked />Active</b>
+	  </span>
+          <span tal:condition="cnf/conflict">
+            <font color="red">
+              Conflicts with <a tal:content="cnf/conflict"
+                                 tal:attributes="href cnf/conflict">path</a>
+            </font>
+            <br>Advice:
+            <b><input type="radio" tal:attributes="name cnf/path"
+                   value="Registered" checked />Registered</b>
+            <b><input type="radio" tal:attributes="name cnf/path"
+                   value="Active" />Active</b>
+          </span>
+          (currently <span tal:replace="cnf/status">Active</span>)
+        </li>
+      </tal:block>
+    </ul>
 
-  <p>For <i tal:content="svc/service">Foo</i> service</p>
+  </tal:block>
 
-  <ul>
-    <tal:block tal:repeat="cnf view/listConfigurations">
-      <li tal:condition="python: cnf['service'] == svc['service']">
-        <a tal:content="cnf/path" tal:attributes="href cnf/path">somewhere</a>
-        (status <b tal:content="cnf/status">Active</b>)
-        <br>
-        <i tal:content="cnf/usage">Usage summary</i>
-        implemented by
-        <i tal:content="cnf/implementation">Implementation summary</i>
-      </li>
-    </tal:block>
-  </ul>
+  <p><input type="submit" value="Submit all changes" /></p>
 
-</tal:block>
+</form>
 
 </div>
 


=== Zope3/src/zope/app/browser/services/bundle.py 1.3 => 1.4 ===
--- Zope3/src/zope/app/browser/services/bundle.py:1.3	Mon Jun 16 13:54:59 2003
+++ Zope3/src/zope/app/browser/services/bundle.py	Mon Jun 16 17:00:29 2003
@@ -35,8 +35,11 @@
 from zope.app.interfaces.container import IReadContainer
 from zope.app.interfaces.services.configuration import IConfiguration
 from zope.app.interfaces.services.configuration import IConfigurationManager
+from zope.app.interfaces.services.configuration import Active, Registered
+from zope.app.interfaces.services.configuration import Unregistered
 from zope.app.interfaces.services.folder import ISiteManagementFolder
 from zope.app.interfaces.services.service import IServiceConfiguration
+from zope.component import ComponentLookupError
 from zope.proxy import removeAllProxies
 from zope.publisher.browser import BrowserView
 
@@ -44,29 +47,53 @@
 
     def __init__(self, context, request):
         BrowserView.__init__(self, context, request)
+        self.sitepath = zapi.getPath(zapi.getParent(self.context))
         self.configurations = self.findConfigurations(self.context, "")
         self.configurations.sort(self.compareConfigurations)
-        self.services = self.find_services()
+        self.services = self.findServices()
 
     # Methods called from the page template (bundle.pt)
 
+    def update(self):
+        if "allclear" in self.request:
+            count = 0
+            for path, obj in self.configurations:
+                if obj.status != Unregistered:
+                    obj.status = Unregistered
+                    count += 1
+            return "unregistered %d configurations" % count
+        activated = []
+        registered = []
+        for key, value in self.request.form.items():
+            if value not in (Active, Registered):
+                continue
+            for path, obj in self.configurations:
+                if key == path:
+                    break
+            else:
+                raise ComponentLookupError(key)
+        for path, obj in self.configurations:
+            value = self.request.form.get(path)
+            if value not in (Active, Registered):
+                continue
+            if obj.status != value:
+                if value == Active:
+                    activated.append(path)
+                    obj.status = Active
+                else:
+                    registered.append(path)
+                    obj.status = Registered
+        s = ""
+        if activated:
+            s += "Activated: %s.\n" % (", ".join(activated))
+        if registered:
+            s += "Registered: %s.\n" % (", ".join(registered))
+        return s
+
     def listServices(self):
-        sitepath = zapi.getPath(zapi.getParent(self.context))
         infos = []
         for name in self.services:
-            try:
-                svc = zapi.getService(self.context, name)
-            except:
-                svc = None
-            path = ""
-            insite = False
-            if svc:
-                try:
-                    path = zapi.getPath(svc)
-                except:
-                    path = ""
-                insite = path == sitepath or path.startswith(sitepath + "/")
-            inbundle = self.findServiceConfiguration(name)
+            path, insite, inbundle = self.getServiceStatus(name)
             d = {"service": name,
                  "path": path,
                  "insite": insite,
@@ -77,8 +104,11 @@
     def listConfigurations(self):
         infos = []
         for path, obj in self.configurations:
+            name, advice, conflict = self.getAdvice(obj)
             d = {"path": path,
-                 "service": self.getServiceName(obj),
+                 "service": name,
+                 "advice": advice,
+                 "conflict": conflict,
                  "status": obj.status,
                  "usage": obj.usageSummary(),
                  "implementation": obj.implementationSummary()}
@@ -87,6 +117,44 @@
 
     # The rest are helper methods
 
+    def getServiceStatus(self, name):
+        try:
+            svc = zapi.getService(self.context, name)
+        except:
+            svc = None
+        path = ""
+        insite = False
+        if svc:
+            try:
+                path = zapi.getPath(svc)
+            except:
+                pass
+            else:
+                insite = (path == self.sitepath or
+                          path.startswith(self.sitepath + "/"))
+        inbundle = self.findServiceConfiguration(name)
+        return path, insite, inbundle
+
+    def getAdvice(self, obj):
+        name = self.getServiceName(obj)
+        conflict = ""
+        sm = zapi.getServiceManager(obj)
+        service = sm.queryLocalService(name)
+        if not service:
+            advice = Active
+        else:
+            registry = service.queryConfigurationsFor(obj)
+            if not registry:
+                advice = Active
+            else:
+                active = registry.active()
+                if not active or active == obj:
+                    advice = Active
+                else:
+                    advice = Registered
+                    conflict = zapi.getPath(active)
+        return name, advice, conflict
+
     def findServiceConfiguration(self, name):
         for path, obj in self.configurations:
             if IServiceConfiguration.isImplementedBy(obj):
@@ -114,7 +182,7 @@
               obj2.implementationSummary())
         return cmp(t1, t2)
 
-    def find_services(self):
+    def findServices(self):
         sd = {}
         for path, obj in self.configurations:
             sd[self.getServiceName(obj)] = 1