merge
authorAndrey Skvortsov <andrej.skvortzov@gmail.com>
Mon, 18 Mar 2019 12:10:36 +0300
changeset 2548 82c10dcec29c
parent 2547 fc7de3c128cd (diff)
parent 2533 e09e4b4caff1 (current diff)
child 2549 8f8735f558c7
merge
PLCOpenEditor.py
--- a/Beremiz_service.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/Beremiz_service.py	Mon Mar 18 12:10:36 2019 +0300
@@ -31,7 +31,6 @@
 import getopt
 import threading
 from threading import Thread, Semaphore, Lock, currentThread
-import __builtin__
 from builtins import str as text
 from past.builtins import execfile
 from six.moves import builtins
--- a/README.md	Mon Mar 18 07:13:04 2019 +0000
+++ b/README.md	Mon Mar 18 12:10:36 2019 +0300
@@ -25,6 +25,9 @@
 		sudo apt-get install python-nevow python-matplotlib python-lxml python-zeroconf python-cycler
 		sudo apt-get install python-autobahn python-u-msgpack
 
+		sudo apt-get install libpython2.7-dev
+		pip2 install --use sslpsk posix_spawn
+
 * Prepare
 
 		mkdir ~/Beremiz
@@ -66,7 +69,8 @@
 		cd ~/Beremiz
 		svn checkout https://svn.code.sf.net/p/bacnet/code/trunk/bacnet-stack/ BACnet
 		cd BACnet
-		make MAKE_DEFINE='-fPIC' all
+		make MAKE_DEFINE='-fPIC' MY_BACNET_DEFINES='-DPRINT_ENABLED=1 -DBACAPP_ALL -DBACFILE -DINTRINSIC_REPORTING -DBACNET_TIME_MASTER -DBACNET_PROPERTY_LISTS=1 -DBACNET_PROTOCOL_REVISION=16' library
+
 
 * Launch Beremiz IDE
 
--- a/connectors/ConnectorBase.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/connectors/ConnectorBase.py	Mon Mar 18 12:10:36 2019 +0300
@@ -4,7 +4,7 @@
 # See COPYING file for copyrights details.
 
 from __future__ import absolute_import
-import md5
+import hashlib
 
 
 class ConnectorBase(object):
@@ -12,7 +12,7 @@
     chuncksize = 1024*1024
 
     def BlobFromFile(self, filepath, seed):
-        s = md5.new()
+        s = hashlib.new('md5')
         s.update(seed)
         blobID = self.SeedBlob(seed)
         with open(filepath, "rb") as f:
--- a/connectors/PYRO/PSK_Adapter.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/connectors/PYRO/PSK_Adapter.py	Mon Mar 18 12:10:36 2019 +0300
@@ -1,10 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of Beremiz, a Integrated Development Environment for
+# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#
+# Copyright (C) 2019: Edouard TISSERANT
+#
+# See COPYING file for copyrights details.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+"""
+The TLS-PSK adapter that handles SSL connections instead of regular sockets,
+but using Pre Shared Keys instead of Certificates
+"""
+
 from __future__ import absolute_import
 from __future__ import print_function
 
 import socket
 import re
+import ssl
 import sslpsk
-import ssl
 import Pyro
 from Pyro.core import PyroURI
 from Pyro.protocol import _connect_socket, TCPConnection, PYROAdapter
@@ -12,13 +42,13 @@
 from Pyro.util import Log
 
 
-# The TLS-PSK adapter that handles SSL connections instead of regular sockets,
-# but using Pre Shared Keys instead of Certificates
-#
 class PYROPSKAdapter(PYROAdapter):
-    # This is essentialy the same as in Pyro/protocol.py
-    # only raw_sock wrapping into sock through sslpsk.wrap_socket was added
-    # Pyro unfortunately doesn't allow cleaner customization
+    """
+    This is essentialy the same as in Pyro/protocol.py
+    only raw_sock wrapping into sock through sslpsk.wrap_socket was added
+    Pyro unfortunately doesn't allow cleaner customization
+    """
+
     def bindToURI(self, URI):
         with self.lock:   # only 1 thread at a time can bind the URI
             try:
@@ -37,7 +67,7 @@
                 # receive the authentication challenge string, and use that to build the actual identification string.
                 try:
                     authChallenge = self.recvAuthChallenge(conn)
-                except ProtocolError, x:
+                except ProtocolError as x:
                     # check if we were denied
                     if hasattr(x, "partialMsg") and x.partialMsg[:len(self.denyMSG)] == self.denyMSG:
                         raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(x.partialMsg[-1])])
@@ -70,9 +100,6 @@
     return _getProtocolAdapter(protocol)
 
 
-Pyro.protocol.getProtocolAdapter = getProtocolAdapter
-
-
 _processStringURI = Pyro.core.processStringURI
 
 
@@ -91,4 +118,13 @@
     return _processStringURI(URI)
 
 
-Pyro.core.processStringURI = processStringURI
+def setupPSKAdapter():
+    """
+    Add PyroAdapter to the list of available in
+    Pyro adapters and handle new supported protocols
+
+    This function should be called after
+    reimport of Pyro module to enable PYROS:// again.
+    """
+    Pyro.protocol.getProtocolAdapter = getProtocolAdapter
+    Pyro.core.processStringURI = processStringURI
--- a/connectors/PYRO/__init__.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/connectors/PYRO/__init__.py	Mon Mar 18 12:10:36 2019 +0300
@@ -37,13 +37,19 @@
 from Pyro.errors import PyroError
 
 import PSKManagement as PSK
+import connectors.PYRO.PSK_Adapter
 from runtime import PlcStatus
 
-# this module attribute contains a list of DNS-SD (Zeroconf) service types
-# supported by this connector confnode.
-#
-# for connectors that do not support DNS-SD, this attribute can be omitted
-# or set to an empty list.
+
+def switch_pyro_adapter(use_ssl):
+    """
+    Reloads Pyro module with new settings.
+    This is workaround for Pyro, because it doesn't work with SSL wrapper.
+    """
+    # Pyro.config.PYRO_BROKEN_MSGWAITALL = use_ssl
+    reload(Pyro.protocol)
+    if use_ssl:
+        connectors.PYRO.PSK_Adapter.setupPSKAdapter()
 
 
 def PYRO_connector_factory(uri, confnodesroot):
@@ -53,8 +59,9 @@
     confnodesroot.logger.write(_("PYRO connecting to URI : %s\n") % uri)
 
     scheme, location = uri.split("://")
-    if scheme == "PYROS":
-        import connectors.PYRO.PSK_Adapter # pylint: disable=wrong-import-order,unused-import,wrong-import-position
+    use_ssl = scheme == "PYROS"
+    switch_pyro_adapter(use_ssl)
+    if use_ssl:
         schemename = "PYROLOCPSK"
         url, ID = location.split('#')  # TODO fix exception when # not found
         # load PSK from project
@@ -73,10 +80,10 @@
     # Try to get the proxy object
     try:
         RemotePLCObjectProxy = Pyro.core.getAttrProxyForURI(schemename + "://" + location + "/PLCObject")
-    except Exception, e:
+    except Exception as e:
         confnodesroot.logger.write_error(
             _("Connection to {loc} failed with exception {ex}\n").format(
-                loc=location, exo=str(e)))
+                loc=location, ex=str(e)))
         return None
 
     RemotePLCObjectProxy.adapter.setTimeout(60)
--- a/connectors/PYRO_dialog.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/connectors/PYRO_dialog.py	Mon Mar 18 12:10:36 2019 +0300
@@ -6,7 +6,6 @@
 from __future__ import absolute_import
 
 from itertools import repeat, islice, chain
-import wx
 
 from connectors.SchemeEditor import SchemeEditor
 
--- a/connectors/SchemeEditor.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/connectors/SchemeEditor.py	Mon Mar 18 12:10:36 2019 +0300
@@ -26,7 +26,7 @@
             self.txtctrls[tag] = txtctrl
             for win, flag in [
                     (wx.StaticText(self, label=label),
-                    wx.ALIGN_CENTER_VERTICAL),
+                     wx.ALIGN_CENTER_VERTICAL),
                     (txtctrl, wx.GROW)]:
                 self.fieldsizer.AddWindow(win, flag=flag)
 
@@ -39,7 +39,7 @@
                 self, parent.ctr,
                 # use a callafter, as editor can be deleted by calling SetURI
                 partial(wx.CallAfter, parent.SetURI),
-                self.txtctrls[tag].SetValue)
+                self.txtctrls["ID"].SetValue)
             self.mainsizer.AddWindow(self.idselector)
             self.SetSizer(self.mainsizer)
         else:
--- a/connectors/__init__.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/connectors/__init__.py	Mon Mar 18 12:10:36 2019 +0300
@@ -29,7 +29,6 @@
 from __future__ import absolute_import
 from os import listdir, path
 from connectors.ConnectorBase import ConnectorBase
-from types import ClassType
 
 connectors_packages = ["PYRO", "WAMP"]
 
@@ -118,8 +117,8 @@
         return None
 
     # new class inheriting from generic and specific connector base classes
-    return ClassType(_scheme + "_connector",
-                     (ConnectorBase, connector_specific_class), {})()
+    return type(_scheme + "_connector",
+                (ConnectorBase, connector_specific_class), {})()
 
 
 def EditorClassFromScheme(scheme):
--- a/controls/IDBrowser.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/controls/IDBrowser.py	Mon Mar 18 12:10:36 2019 +0300
@@ -98,8 +98,8 @@
             args(_("Last URI"), COL_URI, width=300 if big else 80),
             args(_("Description"), COL_DESC, width=300 if big else 200,
                  mode=dv.DATAVIEW_CELL_EDITABLE
-                      if self.isManager
-                      else dv.DATAVIEW_CELL_INERT),
+                 if self.isManager
+                 else dv.DATAVIEW_CELL_INERT),
             args(_("Last connection"), COL_LAST, width=120),
         ]
 
--- a/runtime/PLCObject.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/runtime/PLCObject.py	Mon Mar 18 12:10:36 2019 +0300
@@ -28,14 +28,14 @@
 import os
 import sys
 import traceback
+import shutil
 from time import time
-import _ctypes  # pylint: disable=wrong-import-order
+import hashlib
+from tempfile import mkstemp
+from functools import wraps, partial
 from six.moves import xrange
 from past.builtins import execfile
-import md5
-from tempfile import mkstemp
-import shutil
-from functools import wraps, partial
+import _ctypes
 
 from runtime.typemapping import TypeTranslator
 from runtime.loglevels import LogLevelsDefault, LogLevelsCount
@@ -465,7 +465,7 @@
 
     @RunInMain
     def SeedBlob(self, seed):
-        blob = (mkstemp(dir=self.tmpdir) + (md5.new(),))
+        blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),))
         _fobj, _path, md5sum = blob
         md5sum.update(seed)
         newBlobID = md5sum.digest()
@@ -606,7 +606,7 @@
 
     @RunInMain
     def GetTraceVariables(self, DebugToken):
-        if (DebugToken is not None and DebugToken == self.DebugToken):
+        if DebugToken is not None and DebugToken == self.DebugToken:
             return self.PLCStatus, self._TracesSwap()
         return PlcStatus.Broken, []
 
--- a/runtime/Stunnel.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/runtime/Stunnel.py	Mon Mar 18 12:10:36 2019 +0300
@@ -1,4 +1,5 @@
 from __future__ import absolute_import
+from __future__ import print_function
 import os
 from binascii import b2a_hqx
 try:
@@ -11,6 +12,17 @@
 _PSKpath = None
 
 
+def restartStunnel():
+    """
+    Restart stunnel service using SysV init stript
+    to apply new generated credentials
+    """
+    try:
+        call(restart_stunnel_cmdline)
+    except OSError:
+        print(_("Couldn't restart stunnel service"))
+
+
 def PSKgen(ID, PSKpath):
 
     # b2a_hqx output len is 4/3 input len
@@ -20,7 +32,7 @@
     PSKstring = ID+":"+secretstring
     with open(PSKpath, 'w') as f:
         f.write(PSKstring)
-    call(restart_stunnel_cmdline)
+    restartStunnel()
 
 
 def ensurePSK(ID, PSKpath):
--- a/runtime/WampClient.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/runtime/WampClient.py	Mon Mar 18 12:10:36 2019 +0300
@@ -135,7 +135,7 @@
             self.register(GetCallee(name), u'.'.join((ID, name)), registerOptions)
 
         for name in SubscribedEvents:
-            self.subscribe(GetCallee(name), unicode(name))
+            self.subscribe(GetCallee(name), text(name))
 
         for func in DoOnJoin:
             func(self)
@@ -151,7 +151,7 @@
 
     def publishWithOwnID(self, eventID, value):
         ID = self.config.extra["ID"]
-        self.publish(unicode(ID+'.'+eventID), value)
+        self.publish(text(ID+'.'+eventID), value)
 
 
 class ReconnectingWampWebSocketClientFactory(WampWebSocketClientFactory, ReconnectingClientFactory):
@@ -343,12 +343,12 @@
 
 def PublishEvent(eventID, value):
     if getWampStatus() == "Attached":
-        _WampSession.publish(unicode(eventID), value)
+        _WampSession.publish(text(eventID), value)
 
 
 def PublishEventWithOwnID(eventID, value):
     if getWampStatus() == "Attached":
-        _WampSession.publishWithOwnID(unicode(eventID), value)
+        _WampSession.publishWithOwnID(text(eventID), value)
 
 
 # WEB CONFIGURATION INTERFACE
--- a/runtime/Worker.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/runtime/Worker.py	Mon Mar 18 12:10:36 2019 +0300
@@ -9,9 +9,9 @@
 
 from __future__ import absolute_import
 import sys
-import thread
 from threading import Lock, Condition
 import six
+from six.moves import _thread
 
 
 class job(object):
@@ -51,20 +51,27 @@
         self.free = Condition(self.mutex)
         self.job = None
 
+    def reraise(self, job):
+        """
+        reraise exception happend in a job
+        @param job: job where original exception happend
+        """
+        exc_type = job.exc_info[0]
+        exc_value = job.exc_info[1]
+        exc_traceback = job.exc_info[2]
+        six.reraise(exc_type, exc_value, exc_traceback)
+
     def runloop(self, *args, **kwargs):
         """
         meant to be called by worker thread (blocking)
         """
-        self._threadID = thread.get_ident()
+        self._threadID = _thread.get_ident()
         self.mutex.acquire()
         if args or kwargs:
             _job = job(*args, **kwargs)
             _job.do()
-            if _job.success:
-                # result is ignored
-                pass
-            else:
-                raise _job.exc_info[0], _job.exc_info[1], _job.exc_info[2]
+            if not _job.success:
+                self.reraise(_job)
 
         while not self._finish:
             self.todo.wait()
@@ -86,7 +93,7 @@
 
         _job = job(*args, **kwargs)
 
-        if self._threadID == thread.get_ident():
+        if self._threadID == _thread.get_ident():
             # if caller is worker thread execute immediately
             _job.do()
         else:
@@ -106,10 +113,7 @@
         if _job.success:
             return _job.result
         else:
-            exc_type = _job.exc_info[0]
-            exc_value = _job.exc_info[1]
-            exc_traceback = _job.exc_info[2]
-            six.reraise(exc_type, exc_value, exc_traceback)
+            self.reraise(_job)
 
     def quit(self):
         """
--- a/runtime/spawn_subprocess.py	Mon Mar 18 07:13:04 2019 +0000
+++ b/runtime/spawn_subprocess.py	Mon Mar 18 12:10:36 2019 +0300
@@ -3,6 +3,7 @@
 
 # subset of subprocess built-in module using posix_spawn rather than fork.
 
+from __future__ import print_function
 from __future__ import absolute_import
 import os
 import signal
--- a/tests/first_steps/plc.xml	Mon Mar 18 07:13:04 2019 +0000
+++ b/tests/first_steps/plc.xml	Mon Mar 18 12:10:36 2019 +0300
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='utf-8'?>
 <project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
   <fileHeader companyName="Beremiz" productName="Beremiz" productVersion="1" creationDateTime="2016-10-24T18:09:22"/>
-  <contentHeader name="First Steps" modificationDateTime="2019-02-13T10:30:06">
+  <contentHeader name="First Steps" modificationDateTime="2018-09-26T12:52:51">
     <coordinateInfo>
       <fbd>
         <scaling x="0" y="0"/>
@@ -676,11 +676,6 @@
                 <INT/>
               </type>
             </variable>
-            <variable name="R2">
-              <type>
-                <BOOL/>
-              </type>
-            </variable>
           </localVars>
           <externalVars constant="true">
             <variable name="ResetCounterValue">
@@ -813,7 +808,7 @@
                 <relPosition x="85" y="15"/>
               </connectionPointOutAction>
             </step>
-            <actionBlock localId="8" height="63" width="148" executionOrderId="0">
+            <actionBlock localId="8" height="52" width="164" executionOrderId="0">
               <position x="154" y="191"/>
               <connectionPointIn>
                 <relPosition x="0" y="15"/>
@@ -830,14 +825,6 @@
                   </ST>
                 </inline>
               </action>
-              <action localId="0" qualifier="S">
-                <relPosition x="0" y="0"/>
-                <inline>
-                  <ST>
-                    <xhtml:p><![CDATA[ R2 := True;]]></xhtml:p>
-                  </ST>
-                </inline>
-              </action>
               <action localId="0">
                 <relPosition x="0" y="0"/>
                 <inline>
@@ -848,18 +835,18 @@
               </action>
             </actionBlock>
             <selectionConvergence localId="10" height="1" width="431">
-              <position x="70" y="657"/>
+              <position x="70" y="273"/>
               <connectionPointIn>
                 <relPosition x="0" y="0"/>
                 <connection refLocalId="13">
-                  <position x="70" y="657"/>
+                  <position x="70" y="273"/>
                   <position x="70" y="244"/>
                 </connection>
               </connectionPointIn>
               <connectionPointIn>
                 <relPosition x="431" y="0"/>
                 <connection refLocalId="14">
-                  <position x="501" y="657"/>
+                  <position x="501" y="273"/>
                   <position x="501" y="250"/>
                 </connection>
               </connectionPointIn>
@@ -868,12 +855,12 @@
               </connectionPointOut>
             </selectionConvergence>
             <jumpStep localId="12" targetName="Start" height="13" width="12">
-              <position x="280" y="701"/>
+              <position x="280" y="317"/>
               <connectionPointIn>
                 <relPosition x="6" y="0"/>
                 <connection refLocalId="10">
-                  <position x="286" y="701"/>
-                  <position x="286" y="658"/>
+                  <position x="286" y="317"/>
+                  <position x="286" y="274"/>
                 </connection>
               </connectionPointIn>
             </jumpStep>
@@ -883,7 +870,7 @@
                 <relPosition x="10" y="0"/>
                 <connection refLocalId="7">
                   <position x="70" y="242"/>
-                  <position x="70" y="221"/>
+                  <position x="70" y="215"/>
                 </connection>
               </connectionPointIn>
               <connectionPointOut>
@@ -983,11 +970,6 @@
             </variable>
           </inputVars>
           <outputVars>
-            <variable name="Reset0">
-              <type>
-                <BOOL/>
-              </type>
-            </variable>
             <variable name="Out">
               <type>
                 <INT/>
--- a/tests/tools/check_source.sh	Mon Mar 18 07:13:04 2019 +0000
+++ b/tests/tools/check_source.sh	Mon Mar 18 12:10:36 2019 +0300
@@ -66,7 +66,7 @@
     # remove compiled Python files
     find . -name '*.pyc' -exec rm -f {} \;
 
-    for i in $py_files; do
+    for i in $py3_files; do
         # echo $i
         python3 -m py_compile $i
         if [ $? -ne 0 ]; then
@@ -444,6 +444,8 @@
         echo "No files to check"
         exit 0;
     fi
+
+    py3_files=$(echo $py_files | sed 's/ [[:alnum:]_\-\/.]*pyjslib.py//')
 }