runtime/NevowServer.py
changeset 3856 054c4f1b2ea7
parent 3855 beccb995b10e
child 3858 dcc83e03d065
equal deleted inserted replaced
3855:beccb995b10e 3856:054c4f1b2ea7
   181 
   181 
   182         setattr(self, 'action_' + name, callback)
   182         setattr(self, 'action_' + name, callback)
   183 
   183 
   184         self.bindingsNames.append(name)
   184         self.bindingsNames.append(name)
   185             
   185             
       
   186     customSettingsURLs = {}
       
   187     def addCustomURL(self, segment, func):
       
   188         self.customSettingsURLs[segment] = func
       
   189 
       
   190     def removeCustomURL(self, segment):
       
   191         del self.customSettingsURLs[segment]
       
   192 
       
   193     def customLocateChild(self, ctx, segments):
       
   194         segment = segments[0]
       
   195         if segment in self.customSettingsURLs:
       
   196             return self.customSettingsURLs[segment](ctx, segments)
   186 
   197 
   187 ConfigurableSettings = ConfigurableBindings()
   198 ConfigurableSettings = ConfigurableBindings()
   188 
   199 
   189 def newExtensionSetting(display, token):
   200 def newExtensionSetting(display, token):
   190     global extensions_settings_od
   201     global extensions_settings_od
   208 
   219 
   209 class ISettings(annotate.TypedInterface):
   220 class ISettings(annotate.TypedInterface):
   210     platform = annotate.String(label=_("Platform"),
   221     platform = annotate.String(label=_("Platform"),
   211                                default=lambda *a,**k:_getVersions(),
   222                                default=lambda *a,**k:_getVersions(),
   212                                immutable=True)
   223                                immutable=True)
   213 
       
   214     # TODO version ?
       
   215 
   224 
   216     # pylint: disable=no-self-argument
   225     # pylint: disable=no-self-argument
   217     def sendLogMessage(
   226     def sendLogMessage(
   218             ctx=annotate.Context(),
   227             ctx=annotate.Context(),
   219             level=annotate.Choice(LogLevels,
   228             level=annotate.Choice(LogLevels,
   250     uploadFile = annotate.autocallable(uploadFile,
   259     uploadFile = annotate.autocallable(uploadFile,
   251                                            label=_(
   260                                            label=_(
   252                                                "Upload a file to PLC working directory"),
   261                                                "Upload a file to PLC working directory"),
   253                                            action=_("Upload"))
   262                                            action=_("Upload"))
   254 
   263 
   255 customSettingsURLs = {
       
   256 }
       
   257 
       
   258 extensions_settings_od = collections.OrderedDict()
   264 extensions_settings_od = collections.OrderedDict()
   259 
   265 
   260 class SettingsPage(rend.Page):
   266 
   261     # We deserve a slash
   267 CSS_tags = [tags.link(rel='stylesheet',
       
   268                       type='text/css',
       
   269                       href=url.here.child("webform_css")),
       
   270            tags.link(rel='stylesheet',
       
   271                       type='text/css',
       
   272                       href=url.here.child("webinterface_css"))]
       
   273 
       
   274 class StyledSettingsPage(rend.Page):
   262     addSlash = True
   275     addSlash = True
   263 
   276 
   264     # This makes webform_css url answer some default CSS
   277     # This makes webform_css url answer some default CSS
   265     child_webform_css = webform.defaultCSS
   278     child_webform_css = webform.defaultCSS
   266     child_webinterface_css = File(paths.AbsNeighbourFile(__file__, 'webinterface.css'), 'text/css')
   279     child_webinterface_css = File(paths.AbsNeighbourFile(__file__, 'webinterface.css'), 'text/css')
   267 
   280 
       
   281 class SettingsPage(StyledSettingsPage):
       
   282 
   268     implements(ISettings)
   283     implements(ISettings)
   269    
   284    
   270     def __getattr__(self, name):
   285     # def __getattr__(self, name):
   271         global extensions_settings_od
   286     #     global extensions_settings_od
   272         if name.startswith('configurable_'):
   287     #     if name.startswith('configurable_'):
   273             token = name[13:]
   288     #         token = name[13:]
   274             def configurable_something(ctx):
   289     #         def configurable_something(ctx):
   275                 settings, _display = extensions_settings_od[token]
   290     #             settings, _display = extensions_settings_od[token]
   276                 return settings
   291     #             return settings
   277             return configurable_something
   292     #         return configurable_something
   278         raise AttributeError
   293     #     raise AttributeError
   279     
   294     
   280     def extensions_settings(self, context, data):
   295     def extensions_settings(self, context, data):
   281         """ Project extensions settings
   296         """ Project extensions settings
   282         Extensions added to Configuration Tree in IDE have their setting rendered here
   297         Extensions added to Configuration Tree in IDE have their setting rendered here
   283         """
   298         """
   284         global extensions_settings_od
   299         global extensions_settings_od
   285         res = []
   300         res = []
   286         for token in extensions_settings_od:
   301         for token in extensions_settings_od:
   287             _settings, display = extensions_settings_od[token]
   302             _settings, display = extensions_settings_od[token]
   288             res += [tags.h2[display], webform.renderForms(token)] 
   303             #res += [tags.a(href=token)[display]] 
       
   304             res += [tags.p[tags.a(href=token)[display]]]
       
   305             # res += [tags.h2[display], webform.renderForms(token)] 
   289         return res
   306         return res
   290 
   307 
   291     docFactory = loaders.stan([tags.html[
   308     docFactory = loaders.stan([tags.html[
   292         tags.head[
   309         tags.head[
   293             tags.title[_("Beremiz Runtime Settings")],
   310             tags.title[_("Beremiz Runtime Settings")],
   294             tags.link(rel='stylesheet',
   311             CSS_tags
   295                       type='text/css',
       
   296                       href=url.here.child("webform_css")),
       
   297             tags.link(rel='stylesheet',
       
   298                       type='text/css',
       
   299                       href=url.here.child("webinterface_css"))
       
   300         ],
   312         ],
   301         tags.body[
   313         tags.body[
       
   314             tags.h1["Settings:"],
   302             tags.a(href='/')['Back'],
   315             tags.a(href='/')['Back'],
   303             tags.h1["Runtime settings:"],
   316             tags.h2["Runtime service:"],
   304             webform.renderForms('staticSettings'),
   317             webform.renderForms('staticSettings'),
   305             tags.h1["Extensions settings:"],
   318             tags.h2["Target specific:"],
   306             webform.renderForms('dynamicSettings'),
   319             webform.renderForms('dynamicSettings'),
       
   320             tags.h2["Extensions:"],
   307             extensions_settings
   321             extensions_settings
   308         ]]])
   322         ]]])
   309 
   323 
   310     def configurable_staticSettings(self, ctx):
   324     def configurable_staticSettings(self, ctx):
   311         return configurable.TypedInterfaceConfigurable(self)
   325         return configurable.TypedInterfaceConfigurable(self)
   334             with open(uploadedfile.filename, 'w') as destfd:
   348             with open(uploadedfile.filename, 'w') as destfd:
   335                 fobj.seek(0)
   349                 fobj.seek(0)
   336                 shutil.copyfileobj(fobj,destfd)
   350                 shutil.copyfileobj(fobj,destfd)
   337 
   351 
   338     def locateChild(self, ctx, segments):
   352     def locateChild(self, ctx, segments):
   339         if segments[0] in customSettingsURLs:
   353         segment = segments[0]
   340             return customSettingsURLs[segments[0]](ctx, segments)
   354         if segment in extensions_settings_od:
       
   355             settings, display = extensions_settings_od[segment]
       
   356             return ExtensionSettingsPage(settings, display), segments[1:]
       
   357         else:
       
   358             res = ConfigurableSettings.customLocateChild(ctx, segments)
       
   359             if res:
       
   360                 return res 
   341         return super(SettingsPage, self).locateChild(ctx, segments)
   361         return super(SettingsPage, self).locateChild(ctx, segments)
   342 
   362 
       
   363 class ExtensionSettingsPage(StyledSettingsPage):
       
   364 
       
   365     docFactory = loaders.stan([
       
   366         tags.html[
       
   367             tags.head()[
       
   368                 tags.title[tags.directive("title")],
       
   369                 CSS_tags
       
   370             ],
       
   371             tags.body[
       
   372                 tags.h1[tags.directive("title")],
       
   373                 tags.a(href='/settings')['Back'],
       
   374                 webform.renderForms('settings')
       
   375             ]]])
       
   376 
       
   377     def render_title(self, ctx, data):
       
   378         return self._display_name
       
   379 
       
   380     def configurable_settings(self, ctx):
       
   381         return self._settings
       
   382 
       
   383     def __init__(self, settings, display):
       
   384         self._settings = settings
       
   385         self._display_name = display
       
   386 
       
   387     def locateChild(self, ctx, segments):
       
   388         res = self._settings.customLocateChild(ctx, segments)
       
   389         if res:
       
   390             return res 
       
   391         return super(ExtensionSettingsPage, self).locateChild(ctx, segments)
   343 
   392 
   344 class WebInterface(athena.LivePage):
   393 class WebInterface(athena.LivePage):
   345 
   394 
   346     docFactory = loaders.stan([tags.raw(xhtml_header),
   395     docFactory = loaders.stan([tags.raw(xhtml_header),
   347                                tags.html(xmlns="http://www.w3.org/1999/xhtml")[
   396                                tags.html(xmlns="http://www.w3.org/1999/xhtml")[