IDE: refactor ERPC URI editor, add serial and USB URI types
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Mon, 18 Nov 2024 13:37:08 +0100
changeset 4038 4b47b4ce0f12
parent 4037 4127c64df073
child 4039 9ff455817691
IDE: refactor ERPC URI editor, add serial and USB URI types
connectors/ERPC_URI.py
connectors/ERPC_dialog.py
connectors/__init__.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectors/ERPC_URI.py	Mon Nov 18 13:37:08 2024 +0100
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# See COPYING file for copyrights details.
+
+from itertools import repeat, islice, chain
+
+## URI parsing functions
+
+def split_as_dict(s, sep, labels):
+    return dict(zip(labels, islice(chain(s.split(sep), repeat("")), len(labels))))
+
+def parse_tcp(loc):
+    return split_as_dict(loc, ":", ["host", "port"])
+
+def parse_sslpsk(loc):
+    locals().update(**split_as_dict(loc, "#", ["hostport", "ID"]))
+    return dict(**parse_tcp(hostport), ID=ID) # type: ignore
+
+def parse_serial(loc):
+    return split_as_dict(loc, "@", ["device", "baudrate"])
+
+def parse_usb(loc):
+    return split_as_dict(loc, ":", ["VID", "PID", "serialnumber"])
+
+## URI building functions
+
+def build_tcp(fields):
+    if fields['port']:
+        return "{host}:{port}".format(**fields)
+    return fields['host']
+
+def build_sslpsk(fields):
+    return "{hostport}#{ID}".format(hostport=build_tcp(fields), **fields)
+
+def build_serial(fields):
+    if fields['baudrate']:
+        return "{device}@{baudrate}".format(**fields)
+    return fields['device']
+
+def build_usb(fields):
+    if fields['serialnumber']:
+        return "{VID}:{PID}:{serialnumber}".format(**fields)
+    if fields['PID']:
+        return "{VID}:{PID}".format(**fields)
+    return fields['VID']
+    
+## Dialog fields definition
+
+model_tcp = [('host', _("Host:")),
+             ('port', _("Port:"))]
+
+model_serial = [('device', _("Device:")),
+                ('baudrate', _("Baud rate:"))]
+
+model_usb = [('VID', _("Vendor ID:")),
+             ('PID', _("Product ID:")),
+             ('serialnumber', _("Serial number:"))]
+
+
+## Schemes description
+
+schemes_desc = [
+#   ( scheme name ,  data model , use ID,   parser   ,    builder  )
+    ("LOCAL",       [],           False, lambda x: {}, lambda x: ""),
+    ("ERPC",        model_tcp,    False, parse_tcp,    build_tcp   ),
+    ("ERPCS",       model_tcp,    True,  parse_sslpsk, build_sslpsk),
+    ("ERPC-SERIAL", model_serial, False, parse_serial, build_serial),
+    ("ERPC-USB",    model_usb,    False, parse_usb,    build_usb   )]
+
+per_scheme_model = {sch: desc for sch, *desc in schemes_desc}
+
--- a/connectors/ERPC_dialog.py	Wed Nov 13 23:10:36 2024 +0100
+++ b/connectors/ERPC_dialog.py	Mon Nov 18 13:37:08 2024 +0100
@@ -3,46 +3,24 @@
 
 # See COPYING file for copyrights details.
 
+from connectors.ERPC_URI import schemes_desc, per_scheme_model
+from connectors.SchemeEditor import SchemeEditor
+
+## Scheme list for the dialog's combobox
+
+Schemes = list(zip(*schemes_desc))[0]
 
 
-from itertools import repeat, islice, chain
-
-from connectors.SchemeEditor import SchemeEditor
-
-
-model = [('host', _("Host:")),
-         ('port', _("Port:"))]
-
-# (scheme, model, secure)
-models = [("LOCAL", [], False), ("ERPC", model, False), ("ERPCS", model, True)]
-
-Schemes = list(zip(*models))[0]
-
-_PerSchemeConf = {sch: (mod, sec) for sch, mod, sec in models}
-
+## Specialized SchemeEditor panel for ERPC 
 
 class ERPC_dialog(SchemeEditor):
     def __init__(self, scheme, *args, **kwargs):
-        # ID selector is enabled only on ERPC (secure)
-        self.model, self.EnableIDSelector = _PerSchemeConf[scheme]
+        self.model, self.EnableIDSelector, self.parser, self.builder = per_scheme_model[scheme]
 
         SchemeEditor.__init__(self, scheme, *args, **kwargs)
 
-    # pylint: disable=unused-variable
     def SetLoc(self, loc):
-        hostport, ID = list(islice(chain(loc.split("#"), repeat("")), 2))
-        host, port = list(islice(chain(hostport.split(":"), repeat("")), 2))
-        self.SetFields(locals())
+        self.SetFields(self.parser(loc))
 
     def GetLoc(self):
-        if self.model:
-            fields = self.GetFields()
-            template = "{host}"
-            if fields['port']:
-                template += ":{port}"
-            if self.EnableIDSelector:
-                if fields['ID']:
-                    template += "#{ID}"
-
-            return template.format(**fields)
-        return ''
+        return self.builder(self.GetFields())
--- a/connectors/__init__.py	Wed Nov 13 23:10:36 2024 +0100
+++ b/connectors/__init__.py	Mon Nov 18 13:37:08 2024 +0100
@@ -83,6 +83,8 @@
         scheme = _scheme
     elif _scheme[-1] == 'S' and _scheme[:-1] in connectors:
         scheme = _scheme[:-1]
+    elif _scheme.split("-")[0] in connectors:
+        scheme = _scheme.split("-")[0]
     else:
         return None