runtime/NevowServer.py
changeset 3881 0b3ac94f494c
parent 3804 ef65e5b07464
parent 3861 7e17f7e02a2b
child 3882 c7ec55cbd35a
--- a/runtime/NevowServer.py	Sat Nov 25 00:18:05 2023 +0100
+++ b/runtime/NevowServer.py	Thu Dec 07 22:41:32 2023 +0100
@@ -28,7 +28,6 @@
 import os
 import collections
 import shutil
-import platform as platform_module
 from zope.interface import implementer
 from nevow import appserver, inevow, tags, loaders, athena, url, rend
 from nevow.page import renderer
@@ -99,6 +98,17 @@
 
         self.bindingsNames.append(name)
             
+    customSettingsURLs = {}
+    def addCustomURL(self, segment, func):
+        self.customSettingsURLs[segment] = func
+
+    def removeCustomURL(self, segment):
+        del self.customSettingsURLs[segment]
+
+    def customLocateChild(self, ctx, segments):
+        segment = segments[0]
+        if segment in self.customSettingsURLs:
+            return self.customSettingsURLs[segment](ctx, segments)
 
 ConfigurableSettings = ConfigurableBindings()
 
@@ -112,13 +122,12 @@
     global extensions_settings_od
     extensions_settings_od.pop(token)
 
+
 class ISettings(annotate.TypedInterface):
     platform = annotate.String(label=_("Platform"),
-                               default=platform_module.system() +
-                               " " + platform_module.release(),
+                               default=lambda *a,**k:GetPLCObjectSingleton().GetVersions(),
                                immutable=True)
 
-    # TODO version ?
 
     # pylint: disable=no-self-argument
     def sendLogMessage(
@@ -159,30 +168,26 @@
                                                "Upload a file to PLC working directory"),
                                            action=_("Upload"))
 
-customSettingsURLs = {
-}
-
 extensions_settings_od = collections.OrderedDict()
 
+
+CSS_tags = [tags.link(rel='stylesheet',
+                      type='text/css',
+                      href=url.here.child("webform_css")),
+           tags.link(rel='stylesheet',
+                      type='text/css',
+                      href=url.here.child("webinterface_css"))]
+
 @implementer(ISettings)
-class SettingsPage(rend.Page):
-    # We deserve a slash
+class StyledSettingsPage(rend.Page):
     addSlash = True
 
     # This makes webform_css url answer some default CSS
     child_webform_css = webform.defaultCSS
     child_webinterface_css = File(paths.AbsNeighbourFile(__file__, 'webinterface.css'), 'text/css')
+
+class SettingsPage(StyledSettingsPage):
    
-    def __getattr__(self, name):
-        global extensions_settings_od
-        if name.startswith('configurable_'):
-            token = name[13:]
-            def configurable_something(ctx):
-                settings, _display = extensions_settings_od[token]
-                return settings
-            return configurable_something
-        raise AttributeError
-    
     def extensions_settings(self, context, data):
         """ Project extensions settings
         Extensions added to Configuration Tree in IDE have their setting rendered here
@@ -191,25 +196,22 @@
         res = []
         for token in extensions_settings_od:
             _settings, display = extensions_settings_od[token]
-            res += [tags.h2[display], webform.renderForms(token)] 
+            res += [tags.p[tags.a(href=token)[display]]]
         return res
 
     docFactory = loaders.stan([tags.html[
         tags.head[
             tags.title[_("Beremiz Runtime Settings")],
-            tags.link(rel='stylesheet',
-                      type='text/css',
-                      href=url.here.child("webform_css")),
-            tags.link(rel='stylesheet',
-                      type='text/css',
-                      href=url.here.child("webinterface_css"))
+            CSS_tags
         ],
         tags.body[
+            tags.h1["Settings"],
             tags.a(href='/')['Back'],
-            tags.h1["Runtime settings:"],
+            tags.h2["Runtime service"],
             webform.renderForms('staticSettings'),
-            tags.h1["Extensions settings:"],
+            tags.h2["Target specific"],
             webform.renderForms('dynamicSettings'),
+            tags.h2["Extensions"],
             extensions_settings
         ]]])
 
@@ -242,10 +244,47 @@
                 shutil.copyfileobj(fobj,destfd)
 
     def locateChild(self, ctx, segments):
-        if segments[0] in customSettingsURLs:
-            return customSettingsURLs[segments[0]](ctx, segments)
+        segment = segments[0]
+        if segment in extensions_settings_od:
+            settings, display = extensions_settings_od[segment]
+            return ExtensionSettingsPage(settings, display), segments[1:]
+        else:
+            res = ConfigurableSettings.customLocateChild(ctx, segments)
+            if res:
+                return res 
         return super(SettingsPage, self).locateChild(ctx, segments)
 
+class ExtensionSettingsPage(StyledSettingsPage):
+
+    docFactory = loaders.stan([
+        tags.html[
+            tags.head()[
+                tags.title[tags.directive("title")],
+                CSS_tags
+            ],
+            tags.body[
+                tags.h1[tags.directive("title")],
+                tags.a(href='/settings')['Back'],
+                webform.renderForms('settings')
+            ]]])
+
+    def render_title(self, ctx, data):
+        return self._display_name
+
+    def configurable_settings(self, ctx):
+        return self._settings
+
+    def __init__(self, settings, display):
+        self._settings = settings
+        self._display_name = display
+
+    def locateChild(self, ctx, segments):
+        res = self._settings.customLocateChild(ctx, segments)
+        if res:
+            return res 
+        return super(ExtensionSettingsPage, self).locateChild(ctx, segments)
+
+
 def RegisterWebsite(iface, port):
     website = SettingsPage()
     site = appserver.NevowSite(website)