From ced0d86acf70f435ffdadb794db891be63a5b82a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Nov 2005 00:39:45 +0000 Subject: move python tools from avahi-utils to avahi-python git-svn-id: file:///home/lennart/svn/public/avahi/trunk@969 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-python/avahi-discover.in | 244 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100755 avahi-python/avahi-discover.in (limited to 'avahi-python/avahi-discover.in') diff --git a/avahi-python/avahi-discover.in b/avahi-python/avahi-discover.in new file mode 100755 index 0000000..00a5602 --- /dev/null +++ b/avahi-python/avahi-discover.in @@ -0,0 +1,244 @@ +#!@PYTHON@ +# -*-python-*- +# $Id$ + +# This file is part of avahi. +# +# avahi is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# avahi 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 Lesser General Public +# License along with avahi; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. + +import os, sys + +try: + import avahi, gtk, gobject, dbus, avahi.ServiceTypeDatabase + from avahi.SimpleGladeApp import SimpleGladeApp +except ImportError: + print "Sorry, to use this tool you need to install Avahi, pygtk and python-dbus." + sys.exit(1) + +try: + import dbus.glib +except ImportError, e: + pass + +service_type_browsers = {} +service_browsers = {} + +glade_dir = "@interfacesdir@" + +service_type_db = avahi.ServiceTypeDatabase.ServiceTypeDatabase() + +class Main_window(SimpleGladeApp): + def __init__(self, path="avahi-discover.glade", root="main_window", domain=None, **kwargs): + path = os.path.join(glade_dir, path) + SimpleGladeApp.__init__(self, path, root, domain, **kwargs) + + def on_tree_view_cursor_changed(self, widget, *args): + (model, iter) = widget.get_selection().get_selected() + (name,interface,protocol,stype,domain) = self.treemodel.get(iter,1,2,3,4,5) + if stype == None: + self.info_label.set_markup("No service currently selected.") + return + #Asynchronous resolving + self.server.ResolveService( int(interface), int(protocol), name, stype, domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), reply_handler=self.service_resolved, error_handler=self.print_error) + + + def protoname(self,protocol): + if protocol == avahi.PROTO_INET: + return "IPv4" + if protocol == avahi.PROTO_INET6: + return "IPv6" + + + def siocgifname(self, interface): + if interface <= 0: + return "any" + else: + return self.server.GetNetworkInterfaceNameByIndex(interface) + + def service_resolved(self, interface, protocol, name, stype, domain, host, aprotocol, address, port, txt, flags): + print "Service data for service '%s' of type '%s' in domain '%s' on %i.%i:" % (name, stype, domain, interface, protocol) + + print "\tHost %s (%s), port %i, TXT data: %s" % (host, address, port, str(avahi.txt_array_to_string_array(txt))) + + self.update_label(interface, protocol, name, stype, domain, host, aprotocol, address, port, avahi.txt_array_to_string_array(txt)) + + def print_error(self, err): + error_label = "Error: %s" % (err) + self.info_label.set_markup(error_label) + print "Error:", str(err) + + def lookup_type(self, stype): + global service_type_db + + try: + return service_type_db[stype] + except KeyError: + return stype + + def new_service(self, interface, protocol, name, stype, domain, flags): + print "Found service '%s' of type '%s' in domain '%s' on %i.%i." % (name, stype, domain, interface, protocol) + if self.zc_ifaces.has_key((interface,protocol)) == False: + self.zc_ifaces[(interface,protocol)] = self.insert_row(self.treemodel, None, str(self.siocgifname(interface))+" "+str(self.protoname(protocol)),None,interface,protocol,None,domain) + if self.zc_domains.has_key((interface,protocol,domain)) == False: + self.zc_domains[(interface,protocol,domain)] = self.insert_row(self.treemodel, self.zc_ifaces[(interface,protocol)], domain,None,interface,protocol,None,domain) + if self.zc_types.has_key((interface,protocol,stype,domain)) == False: + thisDomain = self.zc_domains[(interface,protocol,domain)] + self.zc_types[(interface,protocol,stype,domain)] = self.insert_row(self.treemodel, thisDomain, self.lookup_type(stype), name, interface,None,None,None) + treeiter = self.insert_row(self.treemodel,self.zc_types[(interface,protocol,stype,domain)], name, name, interface,protocol,stype,domain) + self.services_browsed[(interface, protocol, name, stype, domain)] = treeiter + # expand the tree of this path + self.tree_view.expand_to_path(self.treemodel.get_path(treeiter)) + + + 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) + self.info_label.set_markup("") + treeiter=self.services_browsed[(interface, protocol, name, stype, domain)] + parent = self.treemodel.iter_parent(treeiter) + self.treemodel.remove(treeiter) + del self.services_browsed[(interface, protocol, name, stype, domain)] + if self.treemodel.iter_has_child(parent) == False: + treeiter=self.zc_types[(interface,protocol,stype,domain)] + parent = self.treemodel.iter_parent(treeiter) + self.treemodel.remove(treeiter) + del self.zc_types[(interface,protocol,stype,domain)] + if self.treemodel.iter_has_child(parent) == False: + treeiter=self.zc_domains[(interface,protocol,domain)] + parent = self.treemodel.iter_parent(treeiter) + self.treemodel.remove(treeiter) + del self.zc_domains[(interface,protocol,domain)] + if self.treemodel.iter_has_child(parent) == False: + treeiter=self.zc_ifaces[(interface,protocol)] + parent = self.treemodel.iter_parent(treeiter) + self.treemodel.remove(treeiter) + del self.zc_ifaces[(interface,protocol)] + + + def new_service_type(self, interface, protocol, stype, domain, flags): + global service_browsers + + # Are we already browsing this domain for this type? + if 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) + + service_browsers[(interface, protocol, stype, domain)] = b + + def browse_domain(self, interface, protocol, domain): + global service_type_browsers + + # Are we already browsing this domain? + if service_type_browsers.has_key((interface, protocol, domain)): + return + + if self.stype is None: + print "Browsing domain '%s' on %i.%i ..." % (domain, interface, protocol) + + 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) + b.connect_to_signal('ItemNew', self.new_service_type) + + service_type_browsers[(interface, protocol, domain)] = b + else: + new_service_type(interface, protocol, stype, domain) + + def new_domain(self,interface, protocol, domain, flags): + if self.zc_ifaces.has_key((interface,protocol)) == False: + self.zc_ifaces[(interface,protocol)] = self.insert_row(self.treemodel, None, str(self.siocgifname(interface))+" "+str(self.protoname(protocol)),None,interface,protocol,None,domain) + if self.zc_domains.has_key((interface,protocol,domain)) == False: + self.zc_domains[(interface,protocol,domain)] = self.insert_row(self.treemodel, self.zc_ifaces[(interface,protocol)], domain,None,interface,protocol,None,domain) + if domain != "local": + self.browse_domain(interface, protocol, domain) + + def pair_to_dict(self, l): + res = dict() + for el in l: + if "=" not in el: + res[el]='' + else: + tmp = el.split('=',1) + if len(tmp[0]) > 0: + res[tmp[0]] = tmp[1] + return res + + + def update_label(self,interface, protocol, name, stype, domain, host, aprotocol, address, port, txt): + if len(txt) != 0: + txts = "" + txtd = self.pair_to_dict(txt) + for k,v in txtd.items(): + txts+="TXT %s = %s\n" % (k,v) + else: + txts = "TXT Data: empty" + + infos = "Service Type: %s\nService Name: %s\nDomain Name: %s\nInterface: %s %s\nAddress: %s/%s:%i\n%s" % (stype, name, domain, self.siocgifname(interface), self.protoname(protocol), host, address, port, txts.strip()) + self.info_label.set_markup(infos) + + def insert_row(self, model,parent, + content, name, interface,protocol,stype,domain): + myiter=model.insert_after(parent,None) + model.set(myiter,0,content,1,name,2,interface,3,protocol,4,stype,5,domain) + return myiter + + def new(self): + print "A new main_window has been created" + self.treemodel=gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) + self.tree_view.set_model(self.treemodel) + + #creating the columns headers + self.tree_view.set_headers_visible(False) + renderer=gtk.CellRendererText() + column=gtk.TreeViewColumn("",renderer, text=0) + column.set_resizable(True) + column.set_sizing("GTK_TREE_VIEW_COLUMN_GROW_ONLY"); + column.set_expand(True); + self.tree_view.append_column(column) + + self.domain = None + self.stype = None + self.zc_ifaces = {} + self.zc_domains = {} + self.zc_types = {} + self.services_browsed = {} + + self.bus = dbus.SystemBus() + self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) + + if self.domain is None: + # Explicitly browse .local + self.browse_domain(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "local") + + # Browse for other browsable domains + 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) + else: + # Just browse the domain the user wants us to browse + self.browse_domain(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, domain) + + +def main(): + main_window = Main_window() + + main_window.run() + +if __name__ == "__main__": + main() + + -- cgit