Package sparked :: Package internet :: Module zeroconf
[hide private]
[frames] | no frames]

Source Code for Module sparked.internet.zeroconf

  1  # Copyright (c) 2010 Arjan Scherpenisse 
  2  # See LICENSE for details. 
  3   
  4  """ 
  5  A mixin object for Service instances that announce the service over Zeroconf. 
  6  """ 
  7   
  8  import avahi 
  9  import dbus 
 10   
 11  from twisted.python import log 
 12  from sparked import events 
 13   
 14   
15 -class _ZeroconfService (object):
16 """ 17 A globally defined object which interfaces with avahi. 18 """ 19
20 - def __init__(self):
21 self.published = {} 22 self.server = None 23 self.bus = None 24 self.subscribed = []
25 26
27 - def publishService(self, name, stype, port, domain="", host=""):
28 """ 29 Publish a named service on the local zeroconf network. 30 """ 31 if name in self.published: 32 return 33 34 if not self.bus: 35 self.bus = dbus.SystemBus() 36 37 server = dbus.Interface( 38 self.bus.get_object( 39 avahi.DBUS_NAME, 40 avahi.DBUS_PATH_SERVER), 41 avahi.DBUS_INTERFACE_SERVER) 42 43 g = dbus.Interface( 44 self.bus.get_object(avahi.DBUS_NAME, 45 server.EntryGroupNew()), 46 avahi.DBUS_INTERFACE_ENTRY_GROUP) 47 48 g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC,dbus.UInt32(0), 49 name, stype, domain, host, 50 dbus.UInt16(port), "") 51 52 g.Commit() 53 self.published[name] = g
54 55
56 - def unpublishService(self, name):
57 """ 58 Revoke a previously published service. 59 """ 60 self.published[name].Reset() 61 del self.published[name]
62 63
64 - def unpublishAllServices(self):
65 """ 66 Revoke all published services. 67 """ 68 for k in self.published.keys(): 69 self.unpublishService(k)
70 71 72
73 - def subscribeTo(self, serviceType):
74 """ 75 Subscribe to a specific service. 76 """ 77 if serviceType in self.subscribed: 78 return 79 80 if not self.bus: 81 self.bus = dbus.SystemBus() 82 if not self.server: 83 self.server = dbus.Interface( self.bus.get_object(avahi.DBUS_NAME, '/'), 'org.freedesktop.Avahi.Server') 84 85 sbrowser = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, 86 self.server.ServiceBrowserNew(avahi.IF_UNSPEC, 87 avahi.PROTO_UNSPEC, serviceType, 'local', dbus.UInt32(0))), 88 avahi.DBUS_INTERFACE_SERVICE_BROWSER) 89 sbrowser.connect_to_signal("ItemNew", self._itemNew) 90 sbrowser.connect_to_signal("ItemRemove", self._itemRemove) 91 self.subscribed.append(serviceType)
92 93 94 # Avahi handler functions 95
96 - def _itemNew(self, iface, protocol, name, stype, domain, flags):
97 98 def resolveError(*a): 99 log.msg("RESOLVE ERROR:") 100 log.err(a)
101 102 def resolveSuccess(*args): 103 name = args[2] 104 hostname = args[5] 105 address = args[7] 106 port = args[8] 107 log.msg("** New service: %s (%s@%s)" % (name, hostname, port)) 108 zeroconfEvents.dispatch("service-found", name, hostname=hostname, address=address, port=port, type=stype)
109 110 self.server.ResolveService(iface, protocol, name, stype, 111 domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), 112 reply_handler=resolveSuccess, error_handler=resolveError) 113 114 115
116 - def _itemRemove(self, iface, protocol, name, stype, domain, flags):
117 log.msg("** Service lost: %s" % name) 118 zeroconfEvents.dispatch("service-lost", name, type=stype)
119 120 121 try: 122 zeroconfService 123 except NameError: 124 zeroconfService = _ZeroconfService() 125 zeroconfEvents = events.EventDispatcher() 126 127 128 __all__ = ['zeroconfService', 'zeroconfEvents'] 129