summaryrefslogtreecommitdiffstats
path: root/avahi-utils/avahi-discover.in
blob: 9734ae65617fdd42505b671aa8ea0645c55cd105 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/env @PYTHON@
# -*-python-*-
# $Id$

import os
import gtk
import gobject

import avahi, dbus, gobject, sys
from avahi.SimpleGladeApp import SimpleGladeApp

try:
    import dbus.glib
except ImportError, e:
    pass

service_type_browsers = {}
service_browsers = {}


glade_dir = "@prefix@/share/@PACKAGE@/interfaces"

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,type,domain) = self.treemodel.get(iter,0,1,2,3,4)
        if type == None:
            self.info_label.set_markup("<i>No service currently selected.</i>")
            return
        #Asynchronous resolving
        self.server.ResolveService( int(interface), int(protocol), name, type, domain, avahi.PROTO_UNSPEC, reply_handler=self.service_resolved, error_handler=self.print_error)


    def service_resolved(self, interface, protocol, name, type, domain, host, aprotocol, address, port, txt):
        print "Service data for service '%s' of type '%s' in domain '%s' on %i.%i:" % (name, type, domain, interface, protocol)
        print "\tHost %s (%s), port %i, TXT data: %s" % (host, address, port, str(txt))
        self.update_label(interface, protocol, name, type, domain, host, aprotocol, address, port, str(txt))
        
    def print_error(err):
        print "Error:", str(err)
            
    def new_service(self, interface, protocol, name, type, domain):
        print "Found service '%s' of type '%s' in domain '%s' on %i.%i." % (name, type, domain, interface, protocol)
        if self.service_type.has_key(type) == False:
            self.service_type[type] = self.insert_row(self.treemodel,None,type, interface,None,None,None)
        treeiter = self.insert_row(self.treemodel,self.service_type[type],name, interface,protocol,type,domain)
        self.services_browsed[(interface, protocol, name, type, domain)] = treeiter


    def remove_service(self, interface, protocol, name, type, domain):
        print "Service '%s' of type '%s' in domain '%s' on %i.%i disappeared." % (name, type, domain, interface, protocol)
        treeiter=self.services_browsed[(interface, protocol, name, type, domain)]
        parent = self.treemodel.iter_parent(treeiter)
        self.treemodel.remove(treeiter)
        del self.services_browsed[(interface, protocol, name, type, domain)]
        if self.treemodel.iter_has_child(parent) == False:
            self.treemodel.remove(parent)
            del self.service_type[type]
 
    def new_service_type(self, interface, protocol, type, domain):
        global 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 %i.%i ..." % (type, domain, interface, protocol)
        
        b = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, self.server.ServiceBrowserNew(interface, protocol, type, domain)),  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, type, 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
            
        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)),  avahi.DBUS_INTERFACE_SERVICE_TYPE_BROWSER)
        b.connect_to_signal('ItemNew', self.new_service_type)

        service_type_browsers[(interface, protocol, domain)] = b

    def new_domain(self,interface, protocol, domain):

        # We browse for .local anyway...
        if domain != "local":
            browse_domain(interface, protocol, domain)

    def update_label(self,interface, protocol, name, type, domain, host, aprotocol, address, port, txt):
        if protocol == avahi.PROTO_INET:
            protocol = "IPv4"
        if protocol == avahi.PROTO_INET6:
            protocol = "IPv6"
        infos = "<b>Service Type:</b> %s\n<b>Service Name:</b> %s\n<b>Domain Name:</b> %s\n<b>Interface:</b>#%i %s\n<b>Address:</b> %s/%s:%i\n<b>TXT Data:</b> %s" % (type, name, domain, interface, protocol, host, address, port, str(txt))
        self.info_label.set_markup(infos)

    def insert_row(self, model,parent,
                   name, interface,protocol,type,domain):
        myiter=model.insert_after(parent,None)
        model.set(myiter,0,name,1,interface,2,protocol,3,type,4,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)
        self.tree_view.set_model(self.treemodel)

        #creating the columns headers
        self.tree_view.set_headers_visible(True)
        renderer=gtk.CellRendererText()
        column=gtk.TreeViewColumn("Name",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)
        renderer=gtk.CellRendererText()
        column=gtk.TreeViewColumn("Interface",renderer,
                                  text=1)
        column.set_resizable(True)
        self.tree_view.append_column(column)
        
        # testing with fake data
        self.service_type = {}
        self.services_browsed = {}
        
        model=self.treemodel

        domain = None

        self.bus = dbus.SystemBus()
        self.server = dbus.Interface(self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)

        if 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)), 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()