# HG changeset patch # User Edouard Tisserant # Date 1553257591 -3600 # Node ID f2af2a655868c23ccea079f64afe15a75c37d832 # Parent 02d09fc6eb906417e06ad237fc132e4110533236# Parent 8f8735f558c73d7121e9d56447c4da058549a964 Merged diff -r 02d09fc6eb90 -r f2af2a655868 Beremiz_service.py --- a/Beremiz_service.py Fri Mar 22 11:10:37 2019 +0100 +++ b/Beremiz_service.py Fri Mar 22 13:26:31 2019 +0100 @@ -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 diff -r 02d09fc6eb90 -r f2af2a655868 PLCOpenEditor.py --- a/PLCOpenEditor.py Fri Mar 22 11:10:37 2019 +0100 +++ b/PLCOpenEditor.py Fri Mar 22 13:26:31 2019 +0100 @@ -62,7 +62,8 @@ # Define PLCOpenEditor FileMenu extra items id [ ID_PLCOPENEDITORFILEMENUGENERATE, -] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)] + ID_PLCOPENEDITORFILEMENUGENERATEAS, +] = [wx.NewId() for _init_coll_FileMenu_Items in range(2)] beremiz_dir = paths.AbsDir(__file__) @@ -86,6 +87,8 @@ kind=wx.ITEM_NORMAL, text=_(u'Save As...') + '\tCTRL+SHIFT+S') AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, kind=wx.ITEM_NORMAL, text=_(u'Generate Program') + '\tCTRL+G') + AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATEAS, + kind=wx.ITEM_NORMAL, text=_(u'Generate Program As...') + '\tCTRL+SHIFT+G') parent.AppendSeparator() AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, kind=wx.ITEM_NORMAL, text=_(u'Page Setup') + '\tCTRL+ALT+P') @@ -108,6 +111,8 @@ self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu, id=ID_PLCOPENEDITORFILEMENUGENERATE) + self.Bind(wx.EVT_MENU, self.OnGenerateProgramAsMenu, + id=ID_PLCOPENEDITORFILEMENUGENERATEAS) self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW) self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT) @@ -118,7 +123,8 @@ (wx.ID_OPEN, "open", _(u'Open'), None), (wx.ID_SAVE, "save", _(u'Save'), None), (wx.ID_SAVEAS, "saveas", _(u'Save As...'), None), - (wx.ID_PRINT, "print", _(u'Print'), None)]) + (wx.ID_PRINT, "print", _(u'Print'), None), + (ID_PLCOPENEDITORFILEMENUGENERATE, "Build", _(u'Generate Program'), None)]) def _init_coll_HelpMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_HELP, @@ -232,6 +238,8 @@ self.FileMenu.Enable(wx.ID_SAVEAS, True) MenuToolBar.EnableTool(wx.ID_SAVEAS, True) self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True) + MenuToolBar.EnableTool(ID_PLCOPENEDITORFILEMENUGENERATE, True) + self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATEAS, True) else: self.FileMenu.Enable(wx.ID_CLOSE, False) self.FileMenu.Enable(wx.ID_PAGE_SETUP, False) @@ -245,6 +253,8 @@ self.FileMenu.Enable(wx.ID_SAVEAS, False) MenuToolBar.EnableTool(wx.ID_SAVEAS, False) self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False) + MenuToolBar.EnableTool(ID_PLCOPENEDITORFILEMENUGENERATE, False) + self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATEAS, False) def OnNewProjectMenu(self, event): if self.Controler is not None and not self.CheckSaveBeforeClosing(): @@ -305,27 +315,39 @@ self.SaveProjectAs() def OnGenerateProgramMenu(self, event): + result = self.Controler.GetProgramFilePath() + if not result: + self.GenerateProgramAs() + else: + self.GenerateProgram(result) + + def OnGenerateProgramAsMenu(self, event): + self.GenerateProgramAs() + + def GenerateProgramAs(self): dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), os.path.basename(self.Controler.GetProgramFilePath()), _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE | wx.CHANGE_DIR) if dialog.ShowModal() == wx.ID_OK: - filepath = dialog.GetPath() - message_text = "" - header, icon = _("Done"), wx.ICON_INFORMATION - if os.path.isdir(os.path.dirname(filepath)): - _program, errors, warnings = self.Controler.GenerateProgram(filepath) - message_text += "".join([_("warning: %s\n") % warning for warning in warnings]) - if len(errors) > 0: - message_text += "".join([_("error: %s\n") % error for error in errors]) - message_text += _("Can't generate program to file %s!") % filepath - header, icon = _("Error"), wx.ICON_ERROR - else: - message_text += _("Program was successfully generated!") + self.GenerateProgram(dialog.GetPath()) + dialog.Destroy() + + def GenerateProgram(self, filepath=None): + message_text = "" + header, icon = _("Done"), wx.ICON_INFORMATION + if os.path.isdir(os.path.dirname(filepath)): + _program, errors, warnings = self.Controler.GenerateProgram(filepath) + message_text += "".join([_("warning: %s\n") % warning for warning in warnings]) + if len(errors) > 0: + message_text += "".join([_("error: %s\n") % error for error in errors]) + message_text += _("Can't generate program to file %s!") % filepath + header, icon = _("Error"), wx.ICON_ERROR else: - message_text += _("\"%s\" is not a valid folder!") % os.path.dirname(filepath) - header, icon = _("Error"), wx.ICON_ERROR - message = wx.MessageDialog(self, message_text, header, wx.OK | icon) - message.ShowModal() - message.Destroy() - dialog.Destroy() + message_text += _("Program was successfully generated!") + else: + message_text += _("\"%s\" is not a valid folder!") % os.path.dirname(filepath) + header, icon = _("Error"), wx.ICON_ERROR + message = wx.MessageDialog(self, message_text, header, wx.OK | icon) + message.ShowModal() + message.Destroy() def OnPLCOpenEditorMenu(self, event): wx.MessageBox(_("No documentation available.\nComing soon.")) diff -r 02d09fc6eb90 -r f2af2a655868 README.md --- a/README.md Fri Mar 22 11:10:37 2019 +0100 +++ b/README.md Fri Mar 22 13:26:31 2019 +0100 @@ -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 diff -r 02d09fc6eb90 -r f2af2a655868 connectors/ConnectorBase.py --- a/connectors/ConnectorBase.py Fri Mar 22 11:10:37 2019 +0100 +++ b/connectors/ConnectorBase.py Fri Mar 22 13:26:31 2019 +0100 @@ -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: diff -r 02d09fc6eb90 -r f2af2a655868 connectors/PYRO/PSK_Adapter.py --- a/connectors/PYRO/PSK_Adapter.py Fri Mar 22 11:10:37 2019 +0100 +++ b/connectors/PYRO/PSK_Adapter.py Fri Mar 22 13:26:31 2019 +0100 @@ -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 diff -r 02d09fc6eb90 -r f2af2a655868 connectors/PYRO/__init__.py --- a/connectors/PYRO/__init__.py Fri Mar 22 11:10:37 2019 +0100 +++ b/connectors/PYRO/__init__.py Fri Mar 22 13:26:31 2019 +0100 @@ -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) diff -r 02d09fc6eb90 -r f2af2a655868 connectors/PYRO_dialog.py --- a/connectors/PYRO_dialog.py Fri Mar 22 11:10:37 2019 +0100 +++ b/connectors/PYRO_dialog.py Fri Mar 22 13:26:31 2019 +0100 @@ -6,7 +6,6 @@ from __future__ import absolute_import from itertools import repeat, islice, chain -import wx from connectors.SchemeEditor import SchemeEditor diff -r 02d09fc6eb90 -r f2af2a655868 connectors/SchemeEditor.py --- a/connectors/SchemeEditor.py Fri Mar 22 11:10:37 2019 +0100 +++ b/connectors/SchemeEditor.py Fri Mar 22 13:26:31 2019 +0100 @@ -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: diff -r 02d09fc6eb90 -r f2af2a655868 connectors/__init__.py --- a/connectors/__init__.py Fri Mar 22 11:10:37 2019 +0100 +++ b/connectors/__init__.py Fri Mar 22 13:26:31 2019 +0100 @@ -28,9 +28,7 @@ from __future__ import absolute_import from os import listdir, path -import util.paths as paths from connectors.ConnectorBase import ConnectorBase -from types import ClassType connectors_packages = ["PYRO", "WAMP"] @@ -119,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): diff -r 02d09fc6eb90 -r f2af2a655868 controls/IDBrowser.py --- a/controls/IDBrowser.py Fri Mar 22 11:10:37 2019 +0100 +++ b/controls/IDBrowser.py Fri Mar 22 13:26:31 2019 +0100 @@ -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), ] diff -r 02d09fc6eb90 -r f2af2a655868 runtime/PLCObject.py --- a/runtime/PLCObject.py Fri Mar 22 11:10:37 2019 +0100 +++ b/runtime/PLCObject.py Fri Mar 22 13:26:31 2019 +0100 @@ -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, [] diff -r 02d09fc6eb90 -r f2af2a655868 runtime/Stunnel.py --- a/runtime/Stunnel.py Fri Mar 22 11:10:37 2019 +0100 +++ b/runtime/Stunnel.py Fri Mar 22 13:26:31 2019 +0100 @@ -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): diff -r 02d09fc6eb90 -r f2af2a655868 runtime/WampClient.py --- a/runtime/WampClient.py Fri Mar 22 11:10:37 2019 +0100 +++ b/runtime/WampClient.py Fri Mar 22 13:26:31 2019 +0100 @@ -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 diff -r 02d09fc6eb90 -r f2af2a655868 runtime/Worker.py --- a/runtime/Worker.py Fri Mar 22 11:10:37 2019 +0100 +++ b/runtime/Worker.py Fri Mar 22 13:26:31 2019 +0100 @@ -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): """ diff -r 02d09fc6eb90 -r f2af2a655868 runtime/spawn_subprocess.py --- a/runtime/spawn_subprocess.py Fri Mar 22 11:10:37 2019 +0100 +++ b/runtime/spawn_subprocess.py Fri Mar 22 13:26:31 2019 +0100 @@ -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 diff -r 02d09fc6eb90 -r f2af2a655868 tests/first_steps/plc.xml --- a/tests/first_steps/plc.xml Fri Mar 22 11:10:37 2019 +0100 +++ b/tests/first_steps/plc.xml Fri Mar 22 13:26:31 2019 +0100 @@ -1,7 +1,7 @@ - + @@ -676,11 +676,6 @@ - - - - - @@ -813,7 +808,7 @@ - + @@ -830,14 +825,6 @@ - - - - - - - - @@ -848,18 +835,18 @@ - + - + - + @@ -868,12 +855,12 @@ - + - - + + @@ -883,7 +870,7 @@ - + @@ -983,11 +970,6 @@ - - - - - diff -r 02d09fc6eb90 -r f2af2a655868 tests/tools/Docker/beremiz-requirements/Dockerfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/tools/Docker/beremiz-requirements/Dockerfile Fri Mar 22 13:26:31 2019 +0100 @@ -0,0 +1,69 @@ +# +# Dockerfile for Beremiz +# This container is used to run tests for Beremiz +# +# To run test localy use following command executed from beremiz directory: +# $ docker run --volume=$PWD:/beremiz --workdir="/beremiz" --volume=$PWD/../CanFestival-3:/CanFestival-3 --memory=1g --entrypoint=/beremiz/tests/tools/check_source.sh skvorl/beremiz-requirements +# + +FROM skvorl/python2.7-wxpython +MAINTAINER Andrey Skvortsov + +RUN set -xe \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + python-nevow \ + python-lxml \ + python-zeroconf \ + python-m2crypto \ + python-autobahn \ + python-future \ + python-simplejson \ + && apt-get install -y --no-install-recommends ca-certificates \ + && apt-get install -y --no-install-recommends wxglade python-cwiid \ + && apt-get install -y --no-install-recommends build-essential automake flex bison mercurial python-pip \ + && apt-get install -y --no-install-recommends \ + pep8 \ + pylint \ + python-pytest \ + python-pytest-timeout \ + gettext \ + python-ddt \ + libpython2.7-dev \ + \ + && apt-get install -y python3-pip \ + && pip3 install crossbar \ + \ + && /usr/bin/pip install gnosis \ + pyro \ + sslpsk \ + posix_spawn \ + && cd / \ + && hg clone http://dev.automforge.net/CanFestival-3 \ + && cd CanFestival-3 \ + && ./configure \ + \ + && cd / \ + && hg clone -r 24ef30a9bcee1e65b027be2c7f7a8d52c41a7479 https://bitbucket.org/automforge/matiec \ + && cd matiec \ + && autoreconf -i \ + && ./configure \ + && make \ + && make install \ + && mkdir /usr/lib/matiec \ + && cp -vR lib/* /usr/lib/matiec \ + && rm -rf /matiec \ + \ + && cd / \ + && hg clone https://bitbucket.org/mjsousa/modbus Modbus \ + && cd Modbus \ + && make \ + \ + && cd / \ + && svn checkout https://svn.code.sf.net/p/bacnet/code/trunk/bacnet-stack/ BACnet \ + && cd BACnet \ + && make MAKE_DEFINE='-fPIC' all \ + \ + && apt-get remove -y bison flex automake python-pip python3-pip libpython2.7-dev \ + && apt-get autoremove -y \ + && apt-get clean -y \ diff -r 02d09fc6eb90 -r f2af2a655868 tests/tools/Docker/python2.7-wxpython/Dockerfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/tools/Docker/python2.7-wxpython/Dockerfile Fri Mar 22 13:26:31 2019 +0100 @@ -0,0 +1,11 @@ +# +# Dockerfile for wxPython3.0 running on python2.7 +# + +FROM python:2.7-stretch + +RUN set -xe \ + && apt-get update \ + && apt-get install -y --no-install-recommends python-wxgtk3.0 python-matplotlib \ + && apt-get install -y --no-install-recommends python-xvfbwrapper xvfb \ + && apt-get clean diff -r 02d09fc6eb90 -r f2af2a655868 tests/tools/check_source.sh --- a/tests/tools/check_source.sh Fri Mar 22 11:10:37 2019 +0100 +++ b/tests/tools/check_source.sh Fri Mar 22 13:26:31 2019 +0100 @@ -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//') }