# HG changeset patch # User Edouard Tisserant # Date 1542709962 -3600 # Node ID 48b4eba1306406cee838bd224b5fb65a668c27ac # Parent 2c3222433244c0401b4e3e56ae065eaa73da2474 IDManager : refactored a bit, moved some code into PSKManagement.py. Now captures URI and PSK on new PYRO(S) and propose them when editing URI. Import/export still to be implemented. diff -r 2c3222433244 -r 48b4eba13064 PSKManagement.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PSKManagement.py Tue Nov 20 11:32:42 2018 +0100 @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# See COPYING file for copyrights details. + +from __future__ import absolute_import +import os +import time +import json + +COL_ID,COL_URI,COL_DESC,COL_LAST = range(4) + +def _pskpath(project_path): + return os.path.join(project_path, 'psk') + +def _mgtpath(project_path): + return os.path.join(_pskpath(project_path), 'management.json') + +def _default(): + return ['', # default description + None, # last known URI + None] # last connection date + +def _LoadData(project_path): + if os.path.isdir(_pskpath(project_path)): + _path = _mgtpath(project_path) + # load known keys metadata + # {ID:(Desc, LastKnownURI, LastConnect)} + return json.loads(open(_path).read()) \ + if os.path.exists(_path) else {} + return {} + +def GetData(project_path): + # [(ID, Desc, LastKnownURI, LastConnect) + data = [] + loaded_data = _LoadData(project_path) + # go through all secret files available an build data + # out of data recoverd from json and list of secret. + # this implicitly filters IDs out of metadata who's + # secret is missing + psk_files = os.listdir(_pskpath(project_path)) + for filename in psk_files: + if filename.endswith('.secret'): + ID = filename[:-7] # strip filename extension + meta = loaded_data.get(ID,_default()) + data.append([ID]+meta) + return data + + +def DeleteID(project_path, ID): + secret_path = os.path.join(_pskpath(project_path), ID+'.secret') + os.remove(secret_path) + +def _StoreData(project_path, data): + pskpath = _pskpath(project_path) + if not os.path.isdir(pskpath): + os.mkdir(pskpath) + with open(_mgtpath(project_path), 'w') as f: + f.write(json.dumps(data)) + +def SaveData(project_path, data): + to_store = {row[0]:row[1:] for row in data} + _StoreData(project_path, to_store) + +def UpdateID(project_path, ID, secret, URI): + pskpath = _pskpath(project_path) + if not os.path.exists(pskpath): + os.mkdir(pskpath) + + secpath = os.path.join(pskpath, ID+'.secret') + with open(secpath, 'w') as f: + f.write(ID+":"+secret) + + data = _LoadData(project_path) + dataForID = [ID] + (data.get(ID, _default()) if data else _default()) + dataForID[COL_URI] = URI + # FIXME : could store time instead os a string and use DVC model's cmp + # then date display could be smarter, etc - sortable sting hack for now + dataForID[COL_LAST] = time.strftime('%y/%M/%d-%H:%M:%S') + data[ID] = dataForID[1:] + _StoreData(project_path, data) diff -r 2c3222433244 -r 48b4eba13064 connectors/PYRO/__init__.py --- a/connectors/PYRO/__init__.py Mon Nov 19 10:39:50 2018 +0100 +++ b/connectors/PYRO/__init__.py Tue Nov 20 11:32:42 2018 +0100 @@ -36,6 +36,7 @@ import Pyro.util from Pyro.errors import PyroError +import PSKManagement as PSK zeroconf_service_type = '_PYRO._tcp.local.' # this module attribute contains a list of DNS-SD (Zeroconf) service types @@ -124,14 +125,8 @@ confnodesroot.logger.write_error(_("Cannot get PLC ID - connection failed.\n")) return None - if scheme != "PYROS": - ID,PSK = IDPSK - secdir = os.path.join(str(confnodesroot.ProjectPath), 'psk') - if not os.path.exists(secdir): - os.mkdir(secdir) - secpath = os.path.join(secdir, ID+'.secret') - with open(secpath, 'w') as f: - f.write(ID+":"+PSK) + ID,secret = IDPSK + PSK.UpdateID(confnodesroot.ProjectPath, ID, secret, uri) _special_return_funcs = { "StartPLC": False, @@ -145,6 +140,7 @@ A proxy proxy class to handle Beremiz Pyro interface specific behavior. And to put Pyro exception catcher in between caller and Pyro proxy """ + def __getattr__(self, attrName): member = self.__dict__.get(attrName, None) if member is None: diff -r 2c3222433244 -r 48b4eba13064 connectors/WAMP/__init__.py --- a/connectors/WAMP/__init__.py Mon Nov 19 10:39:50 2018 +0100 +++ b/connectors/WAMP/__init__.py Tue Nov 20 11:32:42 2018 +0100 @@ -151,6 +151,9 @@ self.__dict__[attrName] = member return member + # TODO : GetPLCID() + # TODO : PSK.UpdateID() + # Try to get the proxy object try: return WampPLCObjectProxy() diff -r 2c3222433244 -r 48b4eba13064 connectors/__init__.py --- a/connectors/__init__.py Mon Nov 19 10:39:50 2018 +0100 +++ b/connectors/__init__.py Tue Nov 20 11:32:42 2018 +0100 @@ -81,8 +81,8 @@ return None # import module according to uri type + connectorclass = connectors[scheme]() return connectorclass(uri, confnodesroot) - connectorclass = connectors[scheme]() def EditorClassFromScheme(scheme): diff -r 2c3222433244 -r 48b4eba13064 controls/IDBrowser.py --- a/controls/IDBrowser.py Mon Nov 19 10:39:50 2018 +0100 +++ b/controls/IDBrowser.py Tue Nov 20 11:32:42 2018 +0100 @@ -7,57 +7,18 @@ import os import wx import wx.dataview as dv -import json - -def _GetInitialData(psk_path): - # [(ID, Desc, LastKnownURI, LastConnect) - data = [] - - data_path = os.path.join(psk_path, 'management.json') - - if os.path.isdir(psk_path): - # load known keys metadata - # {ID:(Desc, LastKnownURI, LastConnect)} - recovered_data = json.loads(open(data_path).read()) \ - if os.path.exists(data_path) else {} - - # go through all secret files available an build data - # out of data recoverd from json and list of secret. - # this implicitly filters IDs out of metadata who's - # secret is missing - psk_files = os.listdir(psk_path) - for filename in psk_files: - if filename.endswith('.secret'): - ID = filename[:-7] # strip filename extension - meta = recovered_data.get(ID, - ['', # default description - None, # last known URI - None]) # last connection date - - data.append([ID]+meta) - return data - -def _DeleteID(psk_path, ID): - secret_path = os.path.join(psk_path, ID+'.secret') - os.remove(secret_path) - -def _SaveData(psk_path, data): - if not os.path.isdir(psk_path): - os.mkdir(psk_path) - data_path = os.path.join(psk_path, 'management.json') - to_store = {row[0]:row[1:] for row in data} - with open(data_path, 'w') as f: - f.write(json.dumps(to_store)) +import PSKManagement as PSK +from PSKManagement import COL_ID,COL_URI,COL_DESC,COL_LAST class IDBrowserModel(dv.PyDataViewIndexListModel): def __init__(self, psk_path, columncount): self.psk_path = psk_path self.columncount = columncount - self.data = _GetInitialData(psk_path) + self.data = PSK.GetData(psk_path) dv.PyDataViewIndexListModel.__init__(self, len(self.data)) def _saveData(self): - _SaveData(self.psk_path, self.data) + PSK.SaveData(self.psk_path, self.data) def GetColumnType(self, col): return "string" @@ -98,8 +59,8 @@ rows.sort(reverse=True) for row in rows: + PSK.DeleteID(self.psk_path, self.data[row][COL_ID]) del self.data[row] - _DeleteID(self.psk_path, ID) self.RowDeleted(row) self._saveData() @@ -109,7 +70,6 @@ self._saveData() colflags = dv.DATAVIEW_COL_RESIZABLE|dv.DATAVIEW_COL_SORTABLE -COL_ID,COL_URI,COL_DESC,COL_LAST = range(4) class IDBrowser(wx.Panel): def __init__(self, parent, ctr, SelectURICallBack=None, SelectIDCallBack=None, **kwargs): @@ -137,9 +97,7 @@ args(_("Last connection"), COL_LAST, width = 100), ] - self.model = IDBrowserModel( - os.path.join(str(ctr.ProjectPath), 'psk'), - len(ColumnsDesc)) + self.model = IDBrowserModel(ctr.ProjectPath, len(ColumnsDesc)) self.dvc.AssociateModel(self.model) for a,k in ColumnsDesc: diff -r 2c3222433244 -r 48b4eba13064 runtime/Stunnel.py --- a/runtime/Stunnel.py Mon Nov 19 10:39:50 2018 +0100 +++ b/runtime/Stunnel.py Tue Nov 20 11:32:42 2018 +0100 @@ -1,6 +1,9 @@ import os from binascii import b2a_hqx -from runtime.spawn_subprocess import call +try: + from runtime.spawn_subprocess import call +except ImportError: + from subprocess import call restart_stunnel_cmdline = ["/etc/init.d/S50stunnel","restart"]