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 |
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")[ |