URI editor : Rewrote most of it, cleaner.
authorEdouard Tisserant
Thu, 08 Nov 2018 09:39:06 +0100
changeset 2329 e5703dc8848e
parent 2328 7eb6cb70bf5b
child 2330 8c18b1a3e2bf
URI editor : Rewrote most of it, cleaner.
connectors/PYRO/dialog.py
connectors/PYRO_dialog.py
connectors/SchemeEditor.py
connectors/WAMP/dialog.py
connectors/WAMP_dialog.py
connectors/__init__.py
controls/UriLocationEditor.py
--- a/connectors/PYRO/dialog.py	Tue Oct 30 14:08:28 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2018: Smarteh
-#
-# See COPYING file for copyrights details.
-
-
-from __future__ import absolute_import
-from __future__ import print_function
-
-import wx
-from zope.interface import implementer
-
-from controls.UriLocationEditor import IConnectorPanel
-
-URITypes = ["LOCAL", "PYRO", "PYROS"]
-
-
-def PYRO_connector_dialog(confnodesroot):
-    [ID_IPTEXT, ID_PORTTEXT] = [wx.NewId() for _init_ctrls in range(2)]
-
-    @implementer(IConnectorPanel)
-    class PYROConnectorPanel(wx.Panel):
-        def __init__(self, typeConnector, parrent, *args, **kwargs):
-            self.type = typeConnector
-            self.parrent = parrent
-            wx.Panel.__init__(self, parrent, *args, **kwargs)
-            self._init_ctrls()
-            self._init_sizers()
-            self.uri = None
-
-        def _init_ctrls(self):
-            self.IpText = wx.TextCtrl(parent=self, id=ID_IPTEXT, size=wx.Size(200, -1))
-            self.PortText = wx.TextCtrl(parent=self, id=ID_PORTTEXT, size=wx.Size(200, -1))
-
-        def _init_sizers(self):
-            self.mainSizer = wx.FlexGridSizer(cols=2, hgap=10, rows=5, vgap=10)
-            self.mainSizer.AddWindow(wx.StaticText(self, label=_("URI host:")),
-                                     flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.IpText, flag=wx.GROW)
-
-            self.mainSizer.AddWindow(wx.StaticText(self, label=_("URI port:")),
-                                     flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.PortText, flag=wx.GROW)
-            self.SetSizer(self.mainSizer)
-
-        def SetURI(self, uri):
-            self.uri = uri
-            uri_list = uri.strip().split(":")
-            length = len(uri_list)
-            if length == 3:
-                self.IpText.SetValue(uri_list[1].strip("/"))
-                self.PortText.SetValue(uri_list[2])
-            elif length == 2:
-                self.IpText.SetValue(uri_list[1].strip("/"))
-
-        def GetURI(self):
-            self.uri = self.type+"://"+self.IpText.GetValue()+":"+self.PortText.GetValue()
-            return self.uri
-
-    return PYROConnectorPanel("PYRO", confnodesroot)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectors/PYRO_dialog.py	Thu Nov 08 09:39:06 2018 +0100
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# See COPYING file for copyrights details.
+
+from __future__ import absolute_import
+
+from itertools import repeat, islice, chain
+import wx
+
+from connectors.SchemeEditor import SchemeEditor
+
+
+model = [('host',_("Host:")),
+         ('port',_("Port:"))]
+
+secure_model = model + [('ID',_("ID:"))]
+
+models = [("LOCAL", []), ("PYRO",model), ("PYROS",secure_model)]
+
+Schemes = list(zip(*models)[0])
+
+ModelsDict = dict(models)
+
+class PYRO_dialog(SchemeEditor):
+    def __init__(self, scheme, *args, **kwargs):
+        self.model = ModelsDict[scheme]
+        SchemeEditor.__init__(self, scheme, *args, **kwargs)
+
+    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())
+
+    def GetLoc(self):
+        if self.model:
+            fields = self.GetFields()
+            template = "{host}"
+            if fields['port']:
+                template += ":{port}" 
+
+            return template.format(**fields)
+        return ''
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectors/SchemeEditor.py	Thu Nov 08 09:39:06 2018 +0100
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# See COPYING file for copyrights details.
+
+from __future__ import absolute_import
+
+from itertools import repeat, izip_longest
+import wx
+
+class SchemeEditor(wx.Panel):
+    def __init__(self, scheme, parent, *args, **kwargs):
+        self.txtctrls = {} 
+        wx.Panel.__init__(self, parent, *args, **kwargs)
+
+        self.mainSizer = wx.FlexGridSizer(cols=2, hgap=10, rows=5, vgap=10)
+
+        for tag, label in self.model:
+            txtctrl = wx.TextCtrl(parent=self, size=wx.Size(200, -1))
+            self.txtctrls[tag] = txtctrl
+            for win, flag in [
+                (wx.StaticText(self, label=label), wx.ALIGN_CENTER_VERTICAL),
+                (txtctrl, wx.GROW)]:
+                self.mainSizer.AddWindow(win, flag=flag)
+
+        self.mainSizer.AddSpacer(20)
+
+        self.SetSizer(self.mainSizer)
+
+    def SetFields(self, fields):
+        for tag, label in self.model:
+            self.txtctrls[tag].SetValue(fields[tag])
+
+    def GetFields(self):
+        return {tag: self.txtctrls[tag].GetValue() for tag,label in self.model}
+
--- a/connectors/WAMP/dialog.py	Tue Oct 30 14:08:28 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2018: Smarteh
-#
-# See COPYING file for copyrights details.
-
-
-from __future__ import absolute_import
-from __future__ import print_function
-
-import wx
-from zope.interface import implementer
-
-from controls.UriLocationEditor import IConnectorPanel
-
-URITypes = ["WAMP", "WAMPS"]
-
-
-def WAMP_connector_dialog(confnodesroot):
-    [ID_IPTEXT, ID_PORTTEXT, ID_REALMTEXT, ID_WAMPIDTEXT, ID_SECURECHECKBOX] = [wx.NewId() for _init_ctrls in range(5)]
-
-    @implementer(IConnectorPanel)
-    class WAMPConnectorPanel(wx.Panel):
-        def __init__(self, typeConnector, parrent, *args, **kwargs):
-            self.type = typeConnector
-            self.parrent = parrent
-            wx.Panel.__init__(self, parrent, *args, **kwargs)
-            self._init_ctrls()
-            self._init_sizers()
-            self.uri = None
-
-        def _init_ctrls(self):
-            self.IpText = wx.TextCtrl(parent=self, id=ID_IPTEXT, size=wx.Size(200, -1))
-            self.PortText = wx.TextCtrl(parent=self, id=ID_PORTTEXT, size=wx.Size(200, -1))
-            self.RealmText = wx.TextCtrl(parent=self, id=ID_REALMTEXT, size=wx.Size(200, -1))
-            self.WAMPIDText = wx.TextCtrl(parent=self, id=ID_WAMPIDTEXT, size=wx.Size(200, -1))
-            self.SecureCheckbox = wx.CheckBox(self, ID_SECURECHECKBOX, _("Is connection secure?"))
-
-        def _init_sizers(self):
-            self.mainSizer = wx.FlexGridSizer(cols=2, hgap=10, rows=5, vgap=10)
-            self.mainSizer.AddWindow(wx.StaticText(self, label=_("URI host:")),
-                                     flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.IpText, flag=wx.GROW)
-
-            self.mainSizer.AddWindow(wx.StaticText(self, label=_("URI port:")),
-                                     flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.PortText, flag=wx.GROW)
-
-            self.mainSizer.AddWindow(wx.StaticText(self, label=_("Realm:")),
-                                     flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.RealmText, flag=wx.GROW)
-
-            self.mainSizer.AddWindow(wx.StaticText(self, label=_("WAMP ID:")),
-                                     flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.WAMPIDText, flag=wx.GROW)
-
-            self.mainSizer.AddWindow(wx.StaticText(self, label=""), flag=wx.ALIGN_CENTER_VERTICAL)
-            self.mainSizer.AddWindow(self.SecureCheckbox, flag=wx.GROW)
-
-            self.SetSizer(self.mainSizer)
-
-        def SetURI(self, uri):
-            self.uri = uri
-            uri_list = uri.strip().split(":")
-            length = len(uri_list)
-
-            if length > 0:
-                if uri_list[0] == URITypes[1]:
-                    self.SecureCheckbox.SetValue(True)
-
-                if length > 2:
-                    self.IpText.SetValue(uri_list[1].strip("/"))
-                    wampSett = uri_list[2].split("#")
-                    length2 = len(wampSett)
-                    if length2 > 0:
-                        self.PortText.SetValue(wampSett[0])
-                        if length2 > 1:
-                            self.RealmText.SetValue(wampSett[1])
-                            if length2 > 2:
-                                self.WAMPIDText.SetValue(wampSett[2])
-
-        def GetURI(self):
-            if self.IpText.Validate():
-                typeForURI = self.type + "S" if self.SecureCheckbox.GetValue() else self.type
-                self.uri = typeForURI + "://" + self.IpText.GetValue() + ":" + self.PortText.GetValue() + "#" + self.RealmText.GetValue() + "#" + self.WAMPIDText.GetValue()
-                return self.uri
-            else:
-                return ""
-
-    return WAMPConnectorPanel("WAMP", confnodesroot)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectors/WAMP_dialog.py	Thu Nov 08 09:39:06 2018 +0100
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# See COPYING file for copyrights details.
+
+from __future__ import absolute_import
+
+from itertools import repeat, islice, chain
+import wx
+
+from connectors.SchemeEditor import SchemeEditor
+
+Schemes = ["WAMP", "WAMPS"]
+
+model = [('host',_("Host:")),
+         ('port',_("Port:")),
+         ('realm',_("Realm:")),
+         ('ID',_("ID:"))]
+
+class WAMP_dialog(SchemeEditor):
+    def __init__(self, *args, **kwargs):
+        self.model = model
+        SchemeEditor.__init__(self, *args, **kwargs)
+
+    def SetLoc(self, loc):
+        hostport, realm, ID = list(islice(chain(loc.split("#"), repeat("")),3))
+        host, port = list(islice(chain(hostport.split(":"), repeat("")),2))
+        self.SetFields(locals())
+
+    def GetLoc(self):
+        fields = self.GetFields()
+
+        #TODO : input validation test
+
+        template = "{host}" + \
+                   (":{port}" if fields['port'] else '') +\
+                   "#{realm}#{ID}"
+
+        return template.format(**fields)
+
--- a/connectors/__init__.py	Tue Oct 30 14:08:28 2018 +0100
+++ b/connectors/__init__.py	Thu Nov 08 09:39:06 2018 +0100
@@ -30,31 +30,33 @@
 from os import listdir, path
 import util.paths as paths
 
-_base_path = paths.AbsDir(__file__)
+connectors_packages = ["PYRO","WAMP"]
+
 
 def _GetLocalConnectorClassFactory(name):
     return lambda: getattr(__import__(name, globals(), locals()), name + "_connector_factory")
 
 
-def _GetLocalConnectorClassDialog(name):
-    return lambda: getattr(__import__(name + '.dialog', globals(), locals(), fromlist=['dialog']), name + "_connector_dialog")
+connectors = {name: _GetLocalConnectorClassFactory(name)
+              for name in connectors_packages}
 
+_dialogs_imported = False
+per_URI_connectors = None
+schemes = None 
 
-def _GetLocalConnectorURITypes(name):
-    return lambda: getattr(__import__(name + '.dialog', globals(), locals(), fromlist=['dialog']), "URITypes", None)
+# lazy import of connectors dialogs, only if used
+def _Import_Dialogs():
+    global per_URI_connectors, schemes, _dialogs_imported
+    if not _dialogs_imported: 
+        _dialogs_imported = True
+        per_URI_connectors = {}
+        schemes = []
+        for con_name in connectors_packages:
+            module =  __import__(con_name + '_dialog', globals(), locals())
 
-
-connectors = {name:
-              _GetLocalConnectorClassFactory(name)
-              for name in listdir(_base_path)
-              if (path.isdir(path.join(_base_path, name)) and
-                  not name.startswith("__"))}
-
-connectors_dialog = {name:
-                     {"function": _GetLocalConnectorClassDialog(name), "URITypes": _GetLocalConnectorURITypes(name)}
-                     for name in listdir(_base_path)
-                     if (path.isdir(path.join(_base_path, name)) and
-                         not name.startswith("__"))}
+            for scheme in module.Schemes:
+                per_URI_connectors[scheme] = getattr(module, con_name + '_dialog')
+                schemes += [scheme]
 
 
 def ConnectorFactory(uri, confnodesroot):
@@ -83,20 +85,10 @@
     return connectorclass(uri, confnodesroot)
 
 
-def ConnectorDialog(conn_type, confnodesroot):
-    if conn_type not in connectors_dialog:
-        return None
+def EditorClassFromScheme(scheme):
+    _Import_Dialogs()
+    return per_URI_connectors.get(scheme, None) 
 
-    connectorclass = connectors_dialog[conn_type]["function"]()
-    return connectorclass(confnodesroot)
-
-
-def GetConnectorFromURI(uri):
-    typeOfConnector = None
-    for conn_type in connectors_dialog:
-        connectorTypes = connectors_dialog[conn_type]["URITypes"]()
-        if connectorTypes and uri in connectorTypes:
-            typeOfConnector = conn_type
-            break
-
-    return typeOfConnector
+def ConnectorSchemes():
+    _Import_Dialogs()
+    return schemes
--- a/controls/UriLocationEditor.py	Tue Oct 30 14:08:28 2018 +0100
+++ b/controls/UriLocationEditor.py	Thu Nov 08 09:39:06 2018 +0100
@@ -1,42 +1,27 @@
 from __future__ import absolute_import
 
 import wx
-from zope.interface import Interface, Attribute
-from zope.interface.verify import verifyObject
-from connectors import connectors_dialog, ConnectorDialog, GetConnectorFromURI
+from connectors import ConnectorSchemes, EditorClassFromScheme
 
 
 [ID_URIWIZARDDIALOG, ID_URITYPECHOICE] = [wx.NewId() for _init_ctrls in range(2)]
 
-
-class IConnectorPanel(Interface):
-    """This is interface for panel of seperate connector type"""
-    uri = Attribute("""uri of connections""")
-    type = Attribute("""type of connector""")
-
-    def SetURI(uri):     # pylint: disable=no-self-argument
-        """methode for set uri"""
-
-    def GetURI():        # pylint: disable=no-self-argument
-        """metohde for get uri"""
-
-
 class UriLocationEditor(wx.Dialog):
     def _init_ctrls(self, parent):
         self.UriTypeChoice = wx.Choice(parent=self, id=ID_URIWIZARDDIALOG, choices=self.URITYPES)
         self.UriTypeChoice.SetSelection(0)
         self.Bind(wx.EVT_CHOICE, self.OnTypeChoice, self.UriTypeChoice)
-        self.PanelSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.editor_sizer = wx.BoxSizer(wx.HORIZONTAL)
         self.ButtonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)
 
     def _init_sizers(self):
         self.mainSizer = wx.BoxSizer(wx.VERTICAL)
         typeSizer = wx.BoxSizer(wx.HORIZONTAL)
-        typeSizer.Add(wx.StaticText(self, wx.ID_ANY, _("URI type:")), border=5, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
+        typeSizer.Add(wx.StaticText(self, wx.ID_ANY, _("Scheme :")), border=5, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL)
         typeSizer.Add(self.UriTypeChoice, border=5, flag=wx.ALL)
         self.mainSizer.Add(typeSizer)
 
-        self.mainSizer.Add(self.PanelSizer, border=5, flag=wx.ALL)
+        self.mainSizer.Add(self.editor_sizer, border=5, flag=wx.ALL)
         self.mainSizer.Add(self.ButtonSizer, border=5, flag=wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL)
         self.SetSizer(self.mainSizer)
         self.Layout()
@@ -45,71 +30,50 @@
     def __init__(self, parent, uri):
         wx.Dialog.__init__(self, id=ID_URIWIZARDDIALOG,
                            name='UriLocationEditor', parent=parent,
-                           title='Uri location')
-        self.URITYPES = [_("- Select URI type -")]
-        for connector_type, connector_function in connectors_dialog.iteritems():
-            try:
-                connector_function['function']()
-                self.URITYPES.append(connector_type)
-            except Exception:
-                pass
-
-        self.selected = None
-        self.parrent = parent
-        self.logger = self.parrent.CTR.logger
+                           title=_('URI Editor'))
+        self.URITYPES = [_("- Select URI Scheme -")] + ConnectorSchemes()
         self._init_ctrls(parent)
         self._init_sizers()
+        self.scheme = None
+        self.scheme_editor = None
         self.SetURI(uri)
         self.CenterOnParent()
 
     def OnTypeChoice(self, event):
-        self._removePanelType()
         index = event.GetSelection()
-        if index > 0:
-            self.selected = event.GetString()
-            self.panelType = self._getConnectorDialog(self.selected)
-            if self.panelType:
-                self.PanelSizer.Add(self.panelType)
-                self.mainSizer.Layout()
-                self.Fit()
-                self.panelType.Refresh()
+        self._replaceSchemeEditor(event.GetString() if index > 0 else None)
 
     def SetURI(self, uri):
-        self._removePanelType()
-        uri_list = uri.strip().split(":")
-        if uri_list:
-            uri_type = uri_list[0].upper()
-            type = GetConnectorFromURI(uri_type)
-            if type:
-                self.selected = type
-                self.UriTypeChoice.SetStringSelection(self.selected)
-                self.panelType = self._getConnectorDialog(self.selected)
-                if self.panelType:
-                    self.panelType.SetURI(uri)
-                    self.PanelSizer.Add(self.panelType)
-                    self.PanelSizer.Layout()
-                    self.mainSizer.Layout()
-                    self.Fit()
-                    self.panelType.Refresh()
+        try:
+            scheme, loc = uri.strip().split("://",1)
+        except:
+            return None
+        scheme = scheme.upper()
+        if scheme in ConnectorSchemes():
+            self.UriTypeChoice.SetStringSelection(scheme)
+            self._replaceSchemeEditor(scheme)
+            self.scheme_editor.SetLoc(loc)
 
     def GetURI(self):
-        if not self.selected or not self.panelType:
-            return ""
+        if self.scheme_editor is None:
+            return None
         else:
-            return self.panelType.GetURI()
+            return self.scheme+"://"+self.scheme_editor.GetLoc()
 
-    def _removePanelType(self):
-        for i in range(self.PanelSizer.GetItemCount()):
-            item = self.PanelSizer.GetItem(i)
-            item.DeleteWindows()
-            self.PanelSizer.Remove(i)
-            self.Fit()
-        self.PanelSizer.Layout()
+    def _replaceSchemeEditor(self, scheme):
+        self.scheme = scheme
+       
+        if self.scheme_editor is not None:
+            self.editor_sizer.Detach(self.scheme_editor)
+            self.scheme_editor.Destroy()
+            self.scheme_editor = None
 
-    def _getConnectorDialog(self, connectorType):
-        connector = ConnectorDialog(connectorType, self)
-        if connector and IConnectorPanel.providedBy(connector):
-            if verifyObject(IConnectorPanel, connector):
-                return connector
-        else:
-            return None
+        EditorClass = EditorClassFromScheme(scheme)
+        if EditorClass is not None:
+            self.scheme_editor = EditorClass(scheme,self)
+            self.editor_sizer.Add(self.scheme_editor)
+            self.scheme_editor.Refresh()
+        self.editor_sizer.Layout()
+        self.mainSizer.Layout()
+        self.Fit()
+