summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSebastien Estienne <sebastien.estienne@gmail.com>2005-08-28 22:09:02 +0000
committerSebastien Estienne <sebastien.estienne@gmail.com>2005-08-28 22:09:02 +0000
commit67b0d605554cc5d1836c6e112eb465d53e213330 (patch)
tree8c839fb24d71be729ed595af6374aa14b07d10b3 /src
parentf4b0f0626e54347eb9b56e19e69b9e8a451f0721 (diff)
* initial import
git-svn-id: file:///home/lennart/svn/public/service-discovery-applet/trunk@3 3be567f1-68ff-0310-b24a-ad7cc433fd2f
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am17
-rwxr-xr-xsrc/service-discovery-applet.in219
2 files changed, 236 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..3e6695a
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,17 @@
+pythonscripts = \
+ service-discovery-applet
+
+EXTRA_DIST = \
+ service-discovery-applet.in
+
+bin_SCRIPTS = $(pythonscripts)
+
+service-discovery-applet: service-discovery-applet.in
+ sed \
+ -e 's,@PYTHON\@,$(PYTHON),g' \
+ -e 's,@iconsdir\@,$(ICONSDIR),g' \
+ -e 's,@scriptsdir\@,$(SCRIPTSDIR),g' \
+ $< > $@
+ chmod +x $@
+
+CLEANFILES = $(pythonscripts)
diff --git a/src/service-discovery-applet.in b/src/service-discovery-applet.in
new file mode 100755
index 0000000..171f8c0
--- /dev/null
+++ b/src/service-discovery-applet.in
@@ -0,0 +1,219 @@
+#!@PYTHON@
+
+# This file is part of service-discovery-applet (sd-applet).
+#
+# sd-applet 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.
+#
+# sd-applet 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 sd-applet; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+
+# todo
+# * memleaks ?
+# * dict([el.split('=',1) for el in l ])
+
+import os
+import sys
+import pygtk
+pygtk.require('2.0')
+
+try:
+ import avahi, gobject, dbus
+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
+
+import gtk
+import gnomeapplet
+import gnome
+
+domain = None
+
+type_browsed = ('_ssh._tcp', '_http._tcp','_ftp._tcp')
+
+service_browsers = {}
+service_menu = gtk.Menu()
+zc_types = {}
+zc_services = {}
+zc_pretty_name = {'_ssh._tcp' : 'SSH Servers',
+ '_http._tcp' : 'Web Servers',
+ '_ftp._tcp' : 'Ftp Servers',
+ '_workstation._tcp': 'Workstations'
+ }
+
+
+
+def siocgifname(interface):
+ global server
+
+ if interface <= 0:
+ return "any"
+ else:
+ return server.GetNetworkInterfaceNameByIndex(interface)
+
+def service_resolved(interface, protocol, name, type, domain, host, aprotocol, address, port, txt):
+ print "Service data for service '%s' of type '%s' in domain '%s' on %s.%i:" % (name, type, domain, siocgifname(interface), protocol)
+ print "\tHost %s (%s), port %i, TXT data: %s" % (host, address, port, avahi.txt_array_to_string_array(txt))
+ cmd = '@scriptsdir@/%s.sh "%s" %s %s %i "%s"' % (type, name, host, address, port," ".join(avahi.txt_array_to_string_array(txt)))
+ os.system(cmd)
+# if type == "_http._tcp":
+#
+# url = "http://%s:%i" % (address,port)
+# gnome.url_show(url)
+# else:
+# os.system(cmd)
+ # FIXME: text if the script exist
+
+def print_error(err):
+ print "Error:", str(err)
+
+def menuitem_response(widget, interface, protocol, name, type, domain):
+ server.ResolveService(interface, protocol, name, type, domain, avahi.PROTO_UNSPEC, reply_handler=service_resolved, error_handler=print_error)
+
+def new_service(interface, protocol, name, type, domain):
+ global server, service_menu, zc_types, zc_pretty_name, zc_services
+
+ print "Found service '%s' of type '%s' in domain '%s' on %s.%i." % (name, type, domain, siocgifname(interface), protocol)
+
+ if zc_types.has_key(type) == False:
+ menuitem = gtk.ImageMenuItem()
+ if zc_pretty_name.has_key(type):
+ menuitem.add(gtk.Label(zc_pretty_name[type]))
+ img = gtk.Image()
+ iconfile = "@iconsdir@/%s.png" % (type)
+ img.set_from_file(iconfile)
+ menuitem.set_image(img)
+ else:
+ menuitem.add(gtk.Label(type))
+
+ service_menu.add(menuitem)
+ zc_types[type] = gtk.Menu()
+ menuitem.set_submenu(zc_types[type])
+ menuitem.show_all()
+
+ menuitem = gtk.MenuItem(name)
+ zc_types[type].add(menuitem)
+ zc_services[(interface, protocol, name, type, domain)] = menuitem
+ menuitem.connect("activate", menuitem_response,interface, protocol, name, type, domain)
+ menuitem.show_all()
+
+ # Asynchronous resolving
+ #server.ResolveService(interface, protocol, name, type, domain, avahi.PROTO_UNSPEC, reply_handler=service_resolved, error_handler=print_error)
+
+def remove_service(interface, protocol, name, type, domain):
+ global zc_services
+
+ print "Service '%s' of type '%s' in domain '%s' on %s.%i disappeared." % (name, type, domain, siocgifname(interface), protocol)
+
+ zc_types[type].remove(zc_services[(interface, protocol, name, type, domain)])
+
+ if zc_types[type].get_children() == []:
+ service_menu.remove(zc_types[type].get_attach_widget())
+ del zc_types[type]
+
+def new_service_type(interface, protocol, type, domain):
+ global server, service_browsers
+
+ # Are we already browsing this domain for this type?
+ if service_browsers.has_key((interface, protocol, type, domain)):
+ return
+
+ print "Browsing for services of type '%s' in domain '%s' on %s.%i ..." % (type, domain, siocgifname(interface), protocol)
+
+ b = dbus.Interface(bus.get_object(avahi.DBUS_NAME, server.ServiceBrowserNew(interface, protocol, type, domain)), avahi.DBUS_INTERFACE_SERVICE_BROWSER)
+ b.connect_to_signal('ItemNew', new_service)
+ b.connect_to_signal('ItemRemove', remove_service)
+
+ service_browsers[(interface, protocol, type, domain)] = b
+
+def browse_domain(interface, protocol, domain):
+ global server
+
+ # Are we already browsing this domain?
+ for type in type_browsed:
+ new_service_type(interface, protocol, type, domain)
+
+def new_domain(interface, protocol, domain):
+ # We browse for .local anyway...
+ if domain != "local":
+ browse_domain(interface, protocol, domain)
+
+
+bus = dbus.SystemBus()
+server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
+
+if domain is None:
+ # Explicitly browse .local
+ browse_domain(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "local")
+
+ # Browse for other browsable domains
+ db = dbus.Interface(bus.get_object(avahi.DBUS_NAME, server.DomainBrowserNew(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, "", avahi.DOMAIN_BROWSER_BROWSE)), avahi.DBUS_INTERFACE_DOMAIN_BROWSER)
+ db.connect_to_signal('ItemNew', new_domain)
+
+else:
+ # Just browse the domain the user wants us to browse
+ browse_domain(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, domain)
+
+def on_menubar_click(widget, event):
+ # allow Middle- and Right-Mouse-Button to go through to the applet window
+ if event.button != 1:
+ widget.emit_stop_by_name("button-press-event")
+
+ return False
+
+
+def ServiceDiscoveryApplet_factory(applet, iid):
+ global menuZC
+ print "Creating new applet instance"
+ menubar = gtk.MenuBar()
+ menubar.connect("button-press-event", on_menubar_click)
+
+ menuZC = gtk.ImageMenuItem()
+ menuZC.add(gtk.Label('ZeroConf'))
+ img = gtk.Image()
+ img.set_from_file("@iconsdir@/service-discovery-applet-mini.png")
+ menuZC.set_image(img)
+ menuZC.set_right_justified(True)
+ menubar.add(menuZC)
+ menuZC.set_submenu(service_menu);
+ menuZC.show_all()
+
+
+ applet.add(menubar)
+ applet.show_all()
+ return True
+
+
+
+print "Starting factory"
+if __name__ == '__main__':
+ if len(sys.argv) == 2 and sys.argv[1] == "-window":
+ main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ main_window.set_title("Service discovery applet")
+ main_window.connect("destroy", gtk.main_quit)
+ app = gnomeapplet.Applet()
+ ServiceDiscoveryApplet_factory(app, None)
+ app.reparent(main_window)
+ main_window.show_all()
+ gtk.main()
+ sys.exit()
+ else:
+ gnomeapplet.bonobo_factory("OAFIID:GNOME_ServiceDiscoveryApplet_Factory",
+ gnomeapplet.Applet.__gtype__,
+ "Service discovery applet", "0", ServiceDiscoveryApplet_factory)
+
+print "Factory ended"