5 # This file is part of avahi.
7 # avahi is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU Lesser General Public License as
9 # published by the Free Software Foundation; either version 2 of the
10 # License, or (at your option) any later version.
12 # avahi is distributed in the hope that it will be useful, but WITHOUT
13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 # License for more details.
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with avahi; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 import avahi, gobject, dbus
27 print "Sorry, to use this tool you need to install Avahi, pygtk and python-dbus."
36 from twisted.internet import gtk2reactor
38 from twisted.internet import reactor
39 from twisted.web import server, resource
41 print "Sorry, to use this tool you need to install twisted and twisted.web."
44 urlproto = { "_http._tcp" : "http", "_https._tcp" : "https", "_ftp._tcp" : "ftp" }
48 use_host_names = False
51 class AvahiBookmarks(resource.Resource):
57 resource.Resource.__init__(self)
59 self.bus = dbus.SystemBus()
60 self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
62 self.version_string = self.server.GetVersionString()
64 self.browse_service_type("_http._tcp")
66 # Hurrah! if I enable one of the following lines, python segfaults.
67 #self.browse_service_type("_https._tcp")
68 #self.browse_service_type("_ftp._tcp")
70 def browse_service_type(self, stype):
74 browser = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.ServiceBrowserNew(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, stype, domain, 0)), avahi.DBUS_INTERFACE_SERVICE_BROWSER)
75 browser.connect_to_signal('ItemNew', self.new_service)
76 browser.connect_to_signal('ItemRemove', self.remove_service)
78 def find_path(self, txt):
80 l = avahi.txt_array_to_string_array(txt)
84 if k[5:].startswith("/"):
91 def render_GET(self, request):
93 t = '<html><head><title>Zeroconf Bookmarks</title></head><body><h1>Zeroconf Bookmarks</h1>'
95 if len(self.services) == 0:
96 t += '<p>Sorry, no web services have been registered on the local LAN.</p>'
98 t += '<ul style="padding: 0px; margin: 20px; list-style-type: none">'
100 for k, v in self.services.iteritems():
107 path = self.find_path(v[4])
108 t += '<li><a href="%s://%s%s%s">%s</a></li>' % (urlproto[k[3]], v[2], port, path, k[2])
112 t += '<hr noshade/><p style="font-size: 8; font-family: sans-serif">Served by %s</p></body></html>' % self.version_string
117 def new_service(self, interface, protocol, name, type, domain, flags):
119 interface, protocol, name, type, domain, host, aprotocol, address, port, txt, flags = self.server.ResolveService(interface, protocol, name, type, domain, avahi.PROTO_UNSPEC, 0)
124 if aprotocol == avahi.PROTO_INET6:
125 h = "[" + address + "]"
129 self.services[(interface, protocol, name, type, domain)] = (host, aprotocol, h, port, txt)
131 def remove_service(self, interface, protocol, name, type, domain):
132 del self.services[(interface, protocol, name, type, domain)]
135 def usage(retval = 0):
136 print "%s [options]\n" % sys.argv[0]
137 print " -h --help Show this help"
138 print " -p --port PORT Specify the port to use (default %u)" % port
139 print " -a --address ADDRESS Specify the address to bind to (default %s)" % address
140 print " -H --host-names Show all services, regardless of the type"
141 print " -d --domain DOMAIN Specify the domain to browse"
145 opts, args = getopt.getopt(sys.argv[1:], "hp:a:Hd:", ["help", "port=", "address=", "host-names", "domain="])
146 except getopt.GetoptError:
150 if o in ("-h", "--help"):
153 if o in ("-p", "--port"):
156 if o in ("-a", "--address"):
159 if o in ("-H", "--host-names"):
160 use_host_names = True
162 if o in ("-d", "--domain"):
165 site = server.Site(AvahiBookmarks())
166 reactor.listenTCP(port, site, interface=address)
168 print "Now point your web browser to http://%s:%u/!" % (address, port)
172 except KeyboardInterrupt, k: