util/discovery.py
changeset 763 c1104099c151
parent 726 ae63ccc29444
equal deleted inserted replaced
762:aaacc83aa86b 763:c1104099c151
    25 import wx
    25 import wx
    26 import  wx.lib.mixins.listctrl  as  listmix
    26 import  wx.lib.mixins.listctrl  as  listmix
    27 from util.Zeroconf import *
    27 from util.Zeroconf import *
    28 
    28 
    29 import connectors
    29 import connectors
       
    30 
       
    31 service_type = '_PYRO._tcp.local.'
    30 
    32 
    31 class AutoWidthListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
    33 class AutoWidthListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
    32     def __init__(self, parent, id, name, pos=wx.DefaultPosition,
    34     def __init__(self, parent, id, name, pos=wx.DefaultPosition,
    33                  size=wx.DefaultSize, style=0):
    35                  size=wx.DefaultSize, style=0):
    34         wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name)
    36         wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name)
    35         listmix.ListCtrlAutoWidthMixin.__init__(self)
    37         listmix.ListCtrlAutoWidthMixin.__init__(self)
    36 
    38 
    37 [ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1, 
    39 [ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1, 
    38  ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON, 
    40  ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON, 
    39  ID_DISCOVERYDIALOGLOCALBUTTON, 
    41  ID_DISCOVERYDIALOGLOCALBUTTON, ID_DISCOVERYDIALOGIPBUTTON, 
    40 ] = [wx.NewId() for _init_ctrls in range(5)]
    42 ] = [wx.NewId() for _init_ctrls in range(6)]
    41 
    43 
    42 class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin):
    44 class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin):
    43     
    45     
    44     def _init_coll_MainSizer_Items(self, parent):
    46     def _init_coll_MainSizer_Items(self, parent):
    45         parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
    47         parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
    51         parent.AddGrowableRow(1)
    53         parent.AddGrowableRow(1)
    52     
    54     
    53     def _init_coll_ButtonGridSizer_Items(self, parent):
    55     def _init_coll_ButtonGridSizer_Items(self, parent):
    54         parent.AddWindow(self.RefreshButton, 0, border=0, flag=0)
    56         parent.AddWindow(self.RefreshButton, 0, border=0, flag=0)
    55         parent.AddWindow(self.LocalButton, 0, border=0, flag=0)
    57         parent.AddWindow(self.LocalButton, 0, border=0, flag=0)
       
    58         parent.AddWindow(self.IpButton, 0, border=0, flag=0)
    56         parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0)
    59         parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0)
    57         
    60         
    58     def _init_coll_ButtonGridSizer_Growables(self, parent):
    61     def _init_coll_ButtonGridSizer_Growables(self, parent):
    59         parent.AddGrowableCol(0)
    62         parent.AddGrowableCol(0)
    60         parent.AddGrowableCol(1)
    63         parent.AddGrowableCol(1)
    61         parent.AddGrowableRow(1)
    64         parent.AddGrowableRow(1)
    62     
    65     
    63     def _init_sizers(self):
    66     def _init_sizers(self):
    64         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
    67         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
    65         self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=5, rows=1, vgap=0)
    68         self.ButtonGridSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=1, vgap=0)
    66         
    69         
    67         self._init_coll_MainSizer_Items(self.MainSizer)
    70         self._init_coll_MainSizer_Items(self.MainSizer)
    68         self._init_coll_MainSizer_Growables(self.MainSizer)
    71         self._init_coll_MainSizer_Growables(self.MainSizer)
    69         self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer)
    72         self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer)
    70         self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer)
    73         self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer)
   105         
   108         
   106         self.LocalButton = wx.Button(id=ID_DISCOVERYDIALOGLOCALBUTTON,
   109         self.LocalButton = wx.Button(id=ID_DISCOVERYDIALOGLOCALBUTTON,
   107               label=_('Local'), name='LocalButton', parent=self,
   110               label=_('Local'), name='LocalButton', parent=self,
   108               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   111               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
   109         self.Bind(wx.EVT_BUTTON, self.OnLocalButton, id=ID_DISCOVERYDIALOGLOCALBUTTON)
   112         self.Bind(wx.EVT_BUTTON, self.OnLocalButton, id=ID_DISCOVERYDIALOGLOCALBUTTON)
       
   113 
       
   114         self.IpButton = wx.Button(id=ID_DISCOVERYDIALOGIPBUTTON,
       
   115               label=_('Add IP'), name='IpButton', parent=self,
       
   116               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   117         self.Bind(wx.EVT_BUTTON, self.OnIpButton, id=ID_DISCOVERYDIALOGIPBUTTON)
   110         
   118         
   111         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTER)
   119         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTER)
   112         
   120         
   113         self._init_sizers()
   121         self._init_sizers()
   114         
   122         
   117         
   125         
   118         self.itemDataMap = {}
   126         self.itemDataMap = {}
   119         self.nextItemId = 0
   127         self.nextItemId = 0
   120         
   128         
   121         self.URI = None
   129         self.URI = None
   122         self.Browsers = []
   130         self.Browser = None
   123         
   131         
   124         self.ZeroConfInstance = Zeroconf()
   132         self.ZeroConfInstance = Zeroconf()
   125         self.RefreshList()
   133         self.RefreshList()
       
   134         self.LatestSelection=None
   126         
   135         
   127     def __del__(self):
   136     def __del__(self):
   128         for browser in self.Browsers:
   137         if self.Browser is not None : self.Browser.cancel()
   129             browser.cancel()
       
   130         self.ZeroConfInstance.close()
   138         self.ZeroConfInstance.close()
   131         
   139         
   132     def RefreshList(self):
   140     def RefreshList(self):
   133         for browser in self.Browsers:
   141         if self.Browser is not None : self.Browser.cancel()
   134             browser.cancel()
   142         self.Browser = ServiceBrowser(self.ZeroConfInstance, service_type, self)
   135         
       
   136         self.Browsers = []
       
   137         for t in connectors.dnssd_connectors.keys():
       
   138             self.Browsers.append(ServiceBrowser(self.ZeroConfInstance, t, self))
       
   139 
   143 
   140     def OnRefreshButton(self, event):
   144     def OnRefreshButton(self, event):
   141         self.ServicesList.DeleteAllItems()
   145         self.ServicesList.DeleteAllItems()
   142         self.RefreshList()
   146         self.RefreshList()
   143 
   147 
   144     def OnLocalButton(self, event):
   148     def OnLocalButton(self, event):
   145         self.URI = "LOCAL://"
   149         self.URI = "LOCAL://"
   146         self.EndModal(wx.ID_OK)
   150         self.EndModal(wx.ID_OK)
   147         event.Skip()
   151         event.Skip()
   148 
   152 
       
   153     def OnIpButton(self, event):
       
   154         if self.LatestSelection is not None:
       
   155             l = lambda col : self.getColumnText(self.LatestSelection,col)
       
   156             self.URI = "%s://%s:%s"%tuple(map(l,(1,2,3)))
       
   157             self.EndModal(wx.ID_OK)
       
   158         event.Skip()
       
   159 
   149     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
   160     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
   150     def GetListCtrl(self):
   161     def GetListCtrl(self):
   151         return self.ServicesList
   162         return self.ServicesList
   152 
   163 
   153     def getColumnText(self, index, col):
   164     def getColumnText(self, index, col):
   161     def OnItemActivated(self, event):
   172     def OnItemActivated(self, event):
   162         self.SetURI(event.m_itemIndex)
   173         self.SetURI(event.m_itemIndex)
   163         self.EndModal(wx.ID_OK)
   174         self.EndModal(wx.ID_OK)
   164         event.Skip()
   175         event.Skip()
   165 
   176 
       
   177 #    def SetURI(self, idx):
       
   178 #        connect_type = self.getColumnText(idx, 1)
       
   179 #        connect_address = self.getColumnText(idx, 2)
       
   180 #        connect_port = self.getColumnText(idx, 3)
       
   181 #        
       
   182 #        self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port)
       
   183 
   166     def SetURI(self, idx):
   184     def SetURI(self, idx):
       
   185         self.LatestSelection = idx
       
   186         svcname = self.getColumnText(idx, 0) 
   167         connect_type = self.getColumnText(idx, 1)
   187         connect_type = self.getColumnText(idx, 1)
   168         connect_address = self.getColumnText(idx, 2)
   188         self.URI = "%s://%s"%(connect_type, svcname + '.' + service_type)
   169         connect_port = self.getColumnText(idx, 3)
   189         
   170         
       
   171         self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port)
       
   172 
       
   173     def GetURI(self):
   190     def GetURI(self):
   174         return self.URI
   191         return self.URI
   175         
   192         
   176     def removeService(self, zeroconf, type, name):
   193     def removeService(self, zeroconf, _type, name):
   177         wx.CallAfter(self._removeService, name)
   194         wx.CallAfter(self._removeService, name)
   178 
   195 
   179 
   196 
   180     def _removeService(self, name):
   197     def _removeService(self, name):
   181         '''
   198         '''
   192 
   209 
   193             if item_name == name:
   210             if item_name == name:
   194                 self.ServicesList.DeleteItem(idx)
   211                 self.ServicesList.DeleteItem(idx)
   195                 break
   212                 break
   196         
   213         
   197     def addService(self, zeroconf, type, name):
   214     def addService(self, zeroconf, _type, name):
   198         wx.CallAfter(self._addService, type, name)
   215         wx.CallAfter(self._addService, _type, name)
   199 
   216 
   200     def _addService(self, type, name):
   217     def _addService(self, _type, name):
   201         '''
   218         '''
   202         called when a service with the desired type is discovered.
   219         called when a service with the desired type is discovered.
   203         '''
   220         '''
   204         info = self.ZeroConfInstance.getServiceInfo(type, name)
   221         info = self.ZeroConfInstance.getServiceInfo(_type, name)
   205 
   222 
   206         svcname  = name.split(".")[0]
   223         svcname  = name.split(".")[0]
   207         typename = type.split(".")[0][1:]
   224         typename = _type.split(".")[0][1:]
   208         ip       = str(socket.inet_ntoa(info.getAddress()))
   225         ip       = str(socket.inet_ntoa(info.getAddress()))
   209         port     = info.getPort()
   226         port     = info.getPort()
   210 
   227 
   211         num_items = self.ServicesList.GetItemCount()
   228         num_items = self.ServicesList.GetItemCount()
   212 
   229