24 |
24 |
25 |
25 |
26 from __future__ import absolute_import |
26 from __future__ import absolute_import |
27 from __future__ import print_function |
27 from __future__ import print_function |
28 import os |
28 import os |
|
29 import collections |
29 import platform as platform_module |
30 import platform as platform_module |
30 from zope.interface import implements |
31 from zope.interface import implements |
31 from nevow import appserver, inevow, tags, loaders, athena, url, rend |
32 from nevow import appserver, inevow, tags, loaders, athena, url, rend |
32 from nevow.page import renderer |
33 from nevow.page import renderer |
33 from nevow.static import File |
34 from nevow.static import File |
163 default=default, |
164 default=default, |
164 immutable=True)) |
165 immutable=True)) |
165 setattr(self, 'bind_' + name, _bind) |
166 setattr(self, 'bind_' + name, _bind) |
166 self.bindingsNames.append(name) |
167 self.bindingsNames.append(name) |
167 |
168 |
168 def addSettings(self, name, desc, fields, btnlabel, callback, |
169 def addSettings(self, name, desc, fields, btnlabel, callback): |
169 addAfterName = None): |
|
170 def _bind(ctx): |
170 def _bind(ctx): |
171 return annotate.MethodBinding( |
171 return annotate.MethodBinding( |
172 'action_' + name, |
172 'action_' + name, |
173 annotate.Method( |
173 annotate.Method( |
174 arguments=[ |
174 arguments=[ |
178 action=btnlabel) |
178 action=btnlabel) |
179 setattr(self, 'bind_' + name, _bind) |
179 setattr(self, 'bind_' + name, _bind) |
180 |
180 |
181 setattr(self, 'action_' + name, callback) |
181 setattr(self, 'action_' + name, callback) |
182 |
182 |
183 if addAfterName not in self.bindingsNames: |
183 self.bindingsNames.append(name) |
184 # Just append new setting if not yet present |
|
185 if name not in self.bindingsNames: |
|
186 self.bindingsNames.append(name) |
|
187 else: |
|
188 # We need to insert new setting |
|
189 # imediately _after_ addAfterName |
|
190 |
184 |
191 # First remove new setting if already present |
|
192 # to make sure it goes into correct place |
|
193 if name in self.bindingsNames: |
|
194 self.bindingsNames.remove(name) |
|
195 # Now add new setting in correct place |
|
196 self.bindingsNames.insert( |
|
197 self.bindingsNames.index(addAfterName)+1, |
|
198 name) |
|
199 |
|
200 |
|
201 |
|
202 def delSettings(self, name): |
|
203 if name in self.bindingsNames: |
|
204 self.bindingsNames.remove(name) |
|
205 |
|
206 |
185 |
207 ConfigurableSettings = ConfigurableBindings() |
186 ConfigurableSettings = ConfigurableBindings() |
208 |
187 |
|
188 def newExtensionSetting(ext_name): |
|
189 global extensions_settings_od |
|
190 settings = ConfigurableBindings() |
|
191 extensions_settings_od[ext_name] = settings |
|
192 return settings |
|
193 |
|
194 def removeExtensionSetting(ext_name): |
|
195 global extensions_settings_od |
|
196 extensions_settings_od.pop(ext_name) |
209 |
197 |
210 class ISettings(annotate.TypedInterface): |
198 class ISettings(annotate.TypedInterface): |
211 platform = annotate.String(label=_("Platform"), |
199 platform = annotate.String(label=_("Platform"), |
212 default=platform_module.system() + |
200 default=platform_module.system() + |
213 " " + platform_module.release(), |
201 " " + platform_module.release(), |
231 |
219 |
232 |
220 |
233 customSettingsURLs = { |
221 customSettingsURLs = { |
234 } |
222 } |
235 |
223 |
|
224 extensions_settings_od = collections.OrderedDict() |
236 |
225 |
237 class SettingsPage(rend.Page): |
226 class SettingsPage(rend.Page): |
238 # We deserve a slash |
227 # We deserve a slash |
239 addSlash = True |
228 addSlash = True |
240 |
229 |
241 # This makes webform_css url answer some default CSS |
230 # This makes webform_css url answer some default CSS |
242 child_webform_css = webform.defaultCSS |
231 child_webform_css = webform.defaultCSS |
243 child_webinterface_css = File(paths.AbsNeighbourFile(__file__, 'webinterface.css'), 'text/css') |
232 child_webinterface_css = File(paths.AbsNeighbourFile(__file__, 'webinterface.css'), 'text/css') |
244 |
233 |
245 implements(ISettings) |
234 implements(ISettings) |
|
235 |
|
236 def __getattr__(self, name): |
|
237 global extensions_settings_od |
|
238 if name.startswith('configurable_'): |
|
239 ext_name = name[13:] |
|
240 def configurable_something(ctx): |
|
241 return extensions_settings_od[ext_name] |
|
242 return configurable_something |
|
243 raise AttributeError |
|
244 |
|
245 def extensions_settings(self, context, data): |
|
246 """ Project extensions settings |
|
247 Extensions added to Configuration Tree in IDE have their setting rendered here |
|
248 """ |
|
249 global extensions_settings_od |
|
250 res = [] |
|
251 for ext_name in extensions_settings_od: |
|
252 res += [tags.h2[ext_name], webform.renderForms(ext_name)] |
|
253 return res |
246 |
254 |
247 docFactory = loaders.stan([tags.html[ |
255 docFactory = loaders.stan([tags.html[ |
248 tags.head[ |
256 tags.head[ |
249 tags.title[_("Beremiz Runtime Settings")], |
257 tags.title[_("Beremiz Runtime Settings")], |
250 tags.link(rel='stylesheet', |
258 tags.link(rel='stylesheet', |
258 tags.a(href='/')['Back'], |
266 tags.a(href='/')['Back'], |
259 tags.h1["Runtime settings:"], |
267 tags.h1["Runtime settings:"], |
260 webform.renderForms('staticSettings'), |
268 webform.renderForms('staticSettings'), |
261 tags.h1["Extensions settings:"], |
269 tags.h1["Extensions settings:"], |
262 webform.renderForms('dynamicSettings'), |
270 webform.renderForms('dynamicSettings'), |
|
271 extensions_settings |
263 ]]]) |
272 ]]]) |
264 |
273 |
265 def configurable_staticSettings(self, ctx): |
274 def configurable_staticSettings(self, ctx): |
266 return configurable.TypedInterfaceConfigurable(self) |
275 return configurable.TypedInterfaceConfigurable(self) |
267 |
276 |
268 def configurable_dynamicSettings(self, ctx): |
277 def configurable_dynamicSettings(self, ctx): |
|
278 """ Runtime Extensions settings |
|
279 Extensions loaded through Beremiz_service -e or optional runtime features render setting forms here |
|
280 """ |
269 return ConfigurableSettings |
281 return ConfigurableSettings |
270 |
282 |
271 def sendLogMessage(self, level, message, **kwargs): |
283 def sendLogMessage(self, level, message, **kwargs): |
272 level = LogLevelsDict[level] |
284 level = LogLevelsDict[level] |
273 if _PySrv.plcobj is not None: |
285 if _PySrv.plcobj is not None: |