home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/env python
-
- ## Copyright (C) 2010 Red Hat, Inc.
- ## Authors:
- ## Tim Waugh <twaugh@redhat.com>
-
- ## This program is free software; you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation; either version 2 of the License, or
- ## (at your option) any later version.
-
- ## This program is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
-
- ## You should have received a copy of the GNU General Public License
- ## along with this program; if not, write to the Free Software
- ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- import dbus
- from debug import *
-
- class DNSSDHostNamesResolver:
- def __init__ (self, devices):
- self._devices = devices
- self._unresolved = len (devices)
- self._device_uri_by_name = {}
- debugprint ("+%s" % self)
-
- def __del__ (self):
- debugprint ("-%s" % self)
-
- def resolve (self, reply_handler):
- self._reply_handler = reply_handler
-
- bus = dbus.SystemBus ()
- if not bus:
- reply_handler ([])
- del self._devices
- del self._reply_handler
- return
-
- for uri, device in self._devices.iteritems ():
- if not uri.startswith ("dnssd://"):
- self._unresolved -= 1
- continue
-
- # We need to resolve the DNS-SD hostname in order to
- # compare with other network devices.
- p = uri[8:].find ("/")
- if p == -1:
- hostname = uri[8:]
- else:
- hostname = uri[8:8+p]
-
- elements = hostname.split (".")
- if len (elements) != 4:
- self._resolved ()
- continue
-
- name, stype, protocol, domain = elements
- stype += "." + protocol # e.g. _printer._tcp
-
- try:
- obj = bus.get_object ("org.freedesktop.Avahi", "/")
- server = dbus.Interface (obj,
- "org.freedesktop.Avahi.Server")
- self._device_uri_by_name[(name, stype, domain)] = uri
- debugprint ("Resolving address for %s" % hostname)
- server.ResolveService (-1, -1,
- name, stype, domain,
- -1, 0,
- reply_handler=self._reply,
- error_handler=lambda e:
- self._error (uri, e))
- except dbus.DBusException, e:
- debugprint ("Failed to resolve address: %s" % e)
- self._resolved ()
-
- def _resolved (self):
- self._unresolved -= 1
- if self._unresolved == 0:
- debugprint ("All addresses resolved")
- self._reply_handler (self._devices)
- del self._devices
- del self._reply_handler
-
- def _reply (self, interface, protocol, name, stype, domain,
- host, aprotocol, address, port, txt, flags):
- uri = self._device_uri_by_name[(name, stype, domain)]
- self._devices[uri].address = address
- debugprint ("%s is at %s" % (uri, address))
- self._resolved ()
-
- def _error (self, uri, error):
- debugprint ("Error resolving %s: %s" % (uri, error))
- self._resolved ()
-
- if __name__ == '__main__':
- class Device:
- def __repr__ (self):
- try:
- return "<Device @ %s>" % self.address
- except:
- return "<Device>"
-
- devices = {"dnssd://dlk-08E206-P1._printer._tcp.local/": Device(),
- "dnssd://foo._printer._tcp.local/": Device()}
- from dbus.glib import DBusGMainLoop
- DBusGMainLoop (set_as_default=True)
-
- class Test:
- def __init__ (self, loop, devices):
- self._loop = loop
- self._devices = devices
-
- def run (self):
- r = DNSSDHostNamesResolver (self._devices)
- r.resolve (reply_handler=self.reply)
- return False
-
- def reply (self, *args):
- print args
- self._loop.quit ()
-
- import gobject
- loop = gobject.MainLoop ()
- set_debugging (True)
- gobject.idle_add (Test (loop, devices).run)
- loop.run ()
-