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.
authorEdouard Tisserant
Tue, 20 Nov 2018 11:32:42 +0100
changeset 2339 48b4eba13064
parent 2338 2c3222433244
child 2340 decf52efb7f7
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.
PSKManagement.py
connectors/PYRO/__init__.py
connectors/WAMP/__init__.py
connectors/__init__.py
controls/IDBrowser.py
runtime/Stunnel.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)
--- 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:
--- 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()
--- 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):
--- 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:
--- 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"]