Package conduit :: Package modules :: Package NetworkModule :: Module Server
[hide private]

Source Code for Module conduit.modules.NetworkModule.Server

  1  """ 
  2  Contains classes for transmitting and receiving python objects over the network. 
  3   
  4  Copyright: John Stowers, 2006 
  5  License: GPLv2 
  6  """ 
  7  import logging 
  8  log = logging.getLogger("modules.Network") 
  9   
 10  import Peers 
 11  import XMLRPCUtils 
 12   
 13  import conduit 
 14  import conduit.dataproviders.DataProvider as DataProvider 
 15   
 16  from gettext import gettext as _ 
 17   
 18  SERVER_PORT = 3400 
 19   
20 -class NetworkServerFactory(DataProvider.DataProviderFactory):
21 """ 22 Controlls all network related communication aspects. This involves 23 1) Advertising dataprovider presence on local network using avahi 24 2) Discovering remote conduit capabilities (i.e. what dataproviders it has advertised) 25 3) Data transmission to/from remote conduit instances 26 """
27 - def __init__(self, **kwargs):
28 DataProvider.DataProviderFactory.__init__(self) 29 30 self.shared = {} 31 self.DP_PORT = 3401 32 33 # Initiate Avahi stuff & announce our presence 34 try: 35 log.debug("Starting AvahiAdvertiser server") 36 self.advertiser = Peers.AvahiAdvertiser("_conduit.tcp", SERVER_PORT) 37 self.advertiser.announce() 38 39 #Start the server which anounces other shared servers 40 self.peerAnnouncer = XMLRPCUtils.StoppableXMLRPCServer('',SERVER_PORT) 41 self.peerAnnouncer.register_function(self.list_shared_dataproviders) 42 self.peerAnnouncer.start() 43 44 #FIXME: Only show the endpoint if the server was started. 45 #self.emit_added( 46 # klass=NetworkEndpoint, 47 # initargs=(), 48 # category=conduit.dataproviders.CATEGORY_MISC 49 # ) 50 except Exception, e: 51 self.peerAnnouncer = None 52 log.warn("Error starting AvahiAdvertiser server: %s" % e) 53 54 #watch the modulemanager for added conduits and syncsets 55 if conduit.GLOBALS.moduleManager != None: 56 conduit.GLOBALS.moduleManager.connect('syncset-added', self._syncset_added) 57 else: 58 log.warn("Could not start AvahiAdvertiser server, moduleManager not created yet")
59
60 - def _syncset_added(self, mgr, syncset):
61 syncset.connect("conduit-added", self._conduit_added) 62 syncset.connect("conduit-removed", self._conduit_removed)
63
64 - def _conduit_added(self, syncset, cond):
65 cond.connect("dataprovider-added", self._dataprovider_added) 66 cond.connect("dataprovider-removed", self._dataprovider_removed)
67
68 - def _conduit_removed(self, syncset, cond):
69 for dpw in cond.get_all_dataproviders(): 70 self._dataprovider_removed(cond, dpw)
71
72 - def _get_shared_dps(self, cond):
73 """ 74 This is a cludgy evil function to determine if a conduit is shared or not 75 If it is, the dp to share is returned 76 If it is not, None is returned 77 """ 78 dps = cond.get_all_dataproviders() 79 ne = None 80 tg = None 81 if len(dps) == 2: 82 for dp in dps: 83 if type(dp.module) == NetworkEndpoint: 84 ne = dp 85 else: 86 tg = dp 87 if tg and ne: 88 return tg,ne 89 else: 90 return None,None 91 return None,None
92
93 - def _dataprovider_added(self, cond, dpw):
94 sharedDpw,networkEndpoint = self._get_shared_dps(cond) 95 if sharedDpw != None: 96 if sharedDpw.get_UID() not in self.shared and sharedDpw.module != None: 97 #Update the network enpoint to have the same input and output 98 #types as the shared DP. 99 networkEndpoint.module.input_type = sharedDpw.module.get_input_type() 100 networkEndpoint.module.output_type = sharedDpw.module.get_output_type() 101 cond._parameters_changed() 102 self.share_dataprovider(sharedDpw)
103
104 - def _dataprovider_removed(self, cond, dpw):
105 if dpw.get_UID() in self.shared: 106 self.unshare_dataprovider(dpw) 107 cond._parameters_changed()
108
110 info = [] 111 for key, dp in self.shared.iteritems(): 112 info.append(dp.get_info()) 113 return info
114
115 - def quit(self):
116 #stop all the xmlrpc servers 117 for server in self.shared.values(): 118 server.stop() 119 120 if self.peerAnnouncer != None: 121 self.peerAnnouncer.stop()
122
123 - def share_dataprovider(self, dpw):
124 """ 125 Shares a conduit/dp on the network 126 """ 127 server = XMLRPCUtils.DataproviderServer(dpw, self.DP_PORT) 128 server.start() 129 self.shared[dpw.get_UID()] = server 130 self.DP_PORT += 1 131 return server
132
133 - def unshare_dataprovider(self, dpw):
134 """ 135 Stop sharing a conduit 136 """ 137 uid = dpw.get_UID() 138 server = self.shared[uid] 139 server.stop() 140 del self.shared[uid]
141
142 -class NetworkEndpoint(DataProvider.TwoWay):
143 """ 144 Simple class used for detecting when a user connects 145 another dataprovider to this one, symbolising a network sync 146 """ 147 _name_ = _("Network") 148 _description_ = _("Enable synchronization via network") 149 _category_ = conduit.dataproviders.CATEGORY_MISC 150 _module_type_ = "twoway" 151 _icon_ = "network-idle" 152 _configurable_ = False 153
154 - def __init__(self):
155 DataProvider.TwoWay.__init__(self) 156 self.input_type = "" 157 self.output_type = ""
158
159 - def is_busy(self):
160 #Stop right click menu 161 return True
162
163 - def is_configured(self, isSource, isTwoWay):
164 #Prevent initiating a sync on the server end by pretending we are 165 #not configured 166 return False
167
168 - def get_status(self):
169 #Always show status as ready 170 return DataProvider.STATUS_NONE
171
172 - def get_input_type(self):
173 return self.input_type
174
175 - def get_output_type(self):
176 return self.output_type
177
178 - def get_UID(self):
179 return "NetworkEndpoint"
180