--- a/Beremiz_service.py Wed May 10 17:02:05 2023 +0200
+++ b/Beremiz_service.py Fri May 12 18:09:55 2023 +0200
@@ -31,7 +31,7 @@
import shlex
import traceback
import threading
-from threading import Thread, Semaphore, Lock, currentThread
+from threading import Thread, Semaphore, Lock, current_thread
import builtins
from functools import partial
@@ -208,19 +208,7 @@
# Define locale domain
loc.AddCatalog(domain)
- global default_locale
- default_locale = locale.getdefaultlocale()[1]
-
- # sys.stdout.encoding = default_locale
- # if Beremiz_service is started from Beremiz IDE
- # sys.stdout.encoding is None (that means 'ascii' encoding').
- # And unicode string returned by wx.GetTranslation() are
- # automatically converted to 'ascii' string.
- def unicode_translation(message):
- return wx.GetTranslation(message).encode(default_locale)
-
- builtins.__dict__['_'] = unicode_translation
- # builtins.__dict__['_'] = wx.GetTranslation
+ builtins.__dict__['_'] = wx.GetTranslation
# Life is hard... have a candy.
@@ -371,7 +359,7 @@
_servicename = self.pyroserver.servicename
_servicename = '' if _servicename is None else _servicename
dlg = ParamsEntryDialog(None, _("Enter a name "), defaultValue=_servicename)
- dlg.SetTests([(lambda name: len(name) is not 0, _("Name must not be null!"))])
+ dlg.SetTests([(lambda name: len(name) != 0, _("Name must not be null!"))])
if dlg.ShowModal() == wx.ID_OK:
self.pyroserver.servicename = dlg.GetValue()
self.pyroserver.Restart()
@@ -448,10 +436,10 @@
obj.res = default_evaluator(tocall, *args, **kwargs)
wx_eval_lock.release()
- main_thread_id = currentThread().ident
+ main_thread_id = current_thread().ident
def evaluator(tocall, *args, **kwargs):
# To prevent deadlocks, check if current thread is not one already main
- current_id = currentThread().ident
+ current_id = current_thread().ident
if main_thread_id != current_id:
o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
--- a/runtime/NevowServer.py Wed May 10 17:02:05 2023 +0200
+++ b/runtime/NevowServer.py Fri May 12 18:09:55 2023 +0200
@@ -29,7 +29,7 @@
import collections
import shutil
import platform as platform_module
-from zope.interface import implements
+from zope.interface import implementer
from nevow import appserver, inevow, tags, loaders, athena, url, rend
from nevow.page import renderer
from nevow.static import File
@@ -44,7 +44,7 @@
PAGE_TITLE = 'Beremiz Runtime Web Interface'
-xhtml_header = '''<?xml version="1.0" encoding="utf-8"?>
+xhtml_header = b'''<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
'''
@@ -248,6 +248,7 @@
extensions_settings_od = collections.OrderedDict()
+@implementer(ISettings)
class SettingsPage(rend.Page):
# We deserve a slash
addSlash = True
@@ -255,8 +256,6 @@
# 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')
-
- implements(ISettings)
def __getattr__(self, name):
global extensions_settings_od
--- a/runtime/PyroServer.py Wed May 10 17:02:05 2023 +0200
+++ b/runtime/PyroServer.py Fri May 12 18:09:55 2023 +0200
@@ -14,11 +14,42 @@
import sys
import os
-import Pyro
-import Pyro.core as pyro
+import Pyro5
+import Pyro5.server
+
import runtime
from runtime.ServicePublisher import ServicePublisher
+def make_pyro_exposed_stub(method_name):
+ stub = lambda self, *args, **kwargs: \
+ getattr(self.plc_object_instance, method_name)(self, *args, **kwargs)
+ stub.__name__ = method_name
+ Pyro5.server.expose(stub)
+ return stub
+
+
+class PLCObjectPyroAdapter(type("PLCObjectPyroStubs", (), {
+ name: make_pyro_exposed_stub(name) for name in [
+ "AppendChunkToBlob",
+ "GetLogMessage",
+ "GetPLCID",
+ "GetPLCstatus",
+ "GetTraceVariables",
+ "MatchMD5",
+ "NewPLC",
+ "PurgeBlobs",
+ "RemoteExec",
+ "RepairPLC",
+ "ResetLogCount",
+ "SeedBlob",
+ "SetTraceVariablesList",
+ "StartPLC",
+ "StopPLC"
+ ]
+})):
+ def __init__(self, plc_object_instance):
+ self.plc_object_instance = plc_object_instance
+
class PyroServer(object):
def __init__(self, servicename, ip_addr, port):
@@ -47,33 +78,14 @@
self.Publish()
while self.continueloop:
- Pyro.config.PYRO_MULTITHREADED = 0
- pyro.initServer()
- self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port)
+ self.daemon = Pyro5.server.Daemon(host=self.ip_addr, port=self.port)
- # pyro never frees memory after connection close if no timeout set
- # taking too small timeout value may cause
- # unwanted diconnection when IDE is kept busy for long periods
- self.daemon.setTimeout(60)
-
- pyro_obj = Pyro.core.ObjBase()
- pyro_obj.delegateTo(runtime.GetPLCObjectSingleton())
-
- self.daemon.connect(pyro_obj, "PLCObject")
+ self.daemon.register(PLCObjectPyroAdapter(runtime.GetPLCObjectSingleton()), "PLCObject")
when_ready()
- # "pipe to self" trick to to accelerate runtime shutdown
- # instead of waiting for arbitrary pyro timeout.
- others = []
- if not sys.platform.startswith('win'):
- self.piper, self.pipew = os.pipe()
- others.append(self.piper)
+ self.daemon.requestLoop()
- self.daemon.requestLoop(others=others, callback=lambda x: None)
- self.piper, self.pipew = None, None
- if hasattr(self, 'sock'):
- self.daemon.sock.close()
self.Unpublish()
def Restart(self):
@@ -81,8 +93,7 @@
def Quit(self):
self.continueloop = False
- self.daemon.shutdown(True)
- self.daemon.closedown()
+ self.daemon.shutdown()
if not sys.platform.startswith('win'):
if self.pipew is not None:
os.write(self.pipew, "goodbye")