Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar/p2p
diff options
context:
space:
mode:
authorDan Williams <dcbw@localhost.localdomain>2006-07-25 21:38:48 (GMT)
committer Dan Williams <dcbw@localhost.localdomain>2006-07-25 21:38:48 (GMT)
commitea133a9c6dd7bc64e9d375ec1d050385bd726eb4 (patch)
tree57009c03d84ecc58d3a7a9d4eeacaf55e01921dd /sugar/p2p
parentc1e0bd39b211aed599b5a2cece670f96ef5aeb30 (diff)
merge
Diffstat (limited to 'sugar/p2p')
-rw-r--r--sugar/p2p/presence.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/sugar/p2p/presence.py b/sugar/p2p/presence.py
new file mode 100644
index 0000000..9cb297e
--- /dev/null
+++ b/sugar/p2p/presence.py
@@ -0,0 +1,106 @@
+# -*- tab-width: 4; indent-tabs-mode: t -*-
+
+import avahi, dbus, dbus.glib, dbus.dbus_bindings
+
+ACTION_SERVICE_NEW = 'new'
+ACTION_SERVICE_REMOVED = 'removed'
+
+class PresenceDiscovery(object):
+ def __init__(self):
+ self.bus = dbus.SystemBus()
+ self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
+ self._service_browsers = {}
+ self._service_type_browsers = {}
+ self._service_listeners = []
+
+ def add_service_listener(self, listener):
+ self._service_listeners.append(listener)
+
+ def start(self):
+ # Always browse .local
+ self.browse_domain(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "local")
+ db = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.DomainBrowserNew(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "", avahi.DOMAIN_BROWSER_BROWSE, dbus.UInt32(0))), avahi.DBUS_INTERFACE_DOMAIN_BROWSER)
+ db.connect_to_signal('ItemNew', self.new_domain)
+
+ def _error_handler(self, err):
+ print "Error resolving: %s" % err
+
+ def resolve_service(self, interface, protocol, name, stype, domain, reply_handler, error_handler=None):
+ if not error_handler:
+ error_handler = self._error_handler
+ self.server.ResolveService(int(interface), int(protocol), name, stype, domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), reply_handler=reply_handler, error_handler=error_handler)
+
+ def new_service(self, interface, protocol, name, stype, domain, flags):
+# print "Found service '%s' (%d) of type '%s' in domain '%s' on %i.%i." % (name, flags, stype, domain, interface, protocol)
+ for listener in self._service_listeners:
+ listener(ACTION_SERVICE_NEW, interface, protocol, name, stype, domain, flags)
+
+ def remove_service(self, interface, protocol, name, stype, domain, flags):
+# print "Service '%s' of type '%s' in domain '%s' on %i.%i disappeared." % (name, stype, domain, interface, protocol)
+ for listener in self._service_listeners:
+ listener(ACTION_SERVICE_REMOVED, interface, protocol, name, stype, domain, flags)
+
+ def new_service_type(self, interface, protocol, stype, domain, flags):
+ # Are we already browsing this domain for this type?
+ if self._service_browsers.has_key((interface, protocol, stype, domain)):
+ return
+
+# print "Browsing for services of type '%s' in domain '%s' on %i.%i ..." % (stype, domain, interface, protocol)
+
+ b = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.ServiceBrowserNew(interface, protocol, stype, domain, dbus.UInt32(0))), avahi.DBUS_INTERFACE_SERVICE_BROWSER)
+ b.connect_to_signal('ItemNew', self.new_service)
+ b.connect_to_signal('ItemRemove', self.remove_service)
+
+ self._service_browsers[(interface, protocol, stype, domain)] = b
+
+ def browse_domain(self, interface, protocol, domain):
+ # Are we already browsing this domain?
+ if self._service_type_browsers.has_key((interface, protocol, domain)):
+ return
+
+# print "Browsing domain '%s' on %i.%i ..." % (domain, interface, protocol)
+
+ try:
+ b = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.ServiceTypeBrowserNew(interface, protocol, domain, dbus.UInt32(0))), avahi.DBUS_INTERFACE_SERVICE_TYPE_BROWSER)
+ except dbus.DBusException, exc:
+ str_exc = str(exc)
+ if str_exc.find("The name org.freedesktop.Avahi was not provided by any .service files") >= 0:
+ raise Exception("Avahi does not appear to be running. '%s'" % str_exc)
+ else:
+ raise exc
+ b.connect_to_signal('ItemNew', self.new_service_type)
+
+ self._service_type_browsers[(interface, protocol, domain)] = b
+
+ def new_domain(self, interface, protocol, domain, flags):
+ if domain != "local":
+ return
+ self.browse_domain(interface, protocol, domain)
+
+
+class PresenceAnnounce(object):
+ def __init__(self):
+ self.bus = dbus.SystemBus()
+ self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
+ self._hostname = None
+
+ def register_service(self, rs_name, rs_port, rs_service, **kwargs):
+ g = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.EntryGroupNew()), avahi.DBUS_INTERFACE_ENTRY_GROUP)
+ if rs_name is None:
+ if self._hostname is None:
+ self._hostname = "%s:%s" % (self.server.GetHostName(), rs_port)
+ rs_name = self._hostname
+
+ info = ["%s=%s" % (k, v) for k, v in kwargs.items()]
+ try:
+ g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, 0, rs_name, rs_service,
+ "", "", # domain, host (let the system figure it out)
+ dbus.UInt16(rs_port), info,)
+ g.Commit()
+ except dbus.dbus_bindings.DBusException, exc:
+ # FIXME: ignore local name collisions, since that means
+ # the zeroconf service is already registered. Ideally we
+ # should un-register it an re-register with the correct info
+ if str(exc) == "Local name collision":
+ pass
+ return g