-
Notifications
You must be signed in to change notification settings - Fork 3
/
python_avahi_browse.py
173 lines (137 loc) · 5.87 KB
/
python_avahi_browse.py
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
166
167
168
169
170
171
172
173
#!/usr/bin/python
import sys
try:
import gobject
import avahi
import dbus
import gtk
import avahi.ServiceTypeDatabase
except ImportError, e:
print "A required python module is missing!\n%s" % (e)
sys.exit()
# try:
# import dbus.glib
# except ImportError, e:
# pass
from dbus.mainloop.glib import DBusGMainLoop
class ServiceTypeDatabase:
def __init__(self):
self.pretty_name = avahi.ServiceTypeDatabase.ServiceTypeDatabase()
def get_human_type(self, type):
if self.pretty_name.has_key(type):
return self.pretty_name[type]
else:
return type
class ServiceDiscovery():
def __init__(self):
#Start Service Discovery
self.domain = ""
try:
loop = DBusGMainLoop(set_as_default=True)
self.system_bus = dbus.SystemBus(mainloop=loop)
# self.system_bus = dbus.SystemBus()
self.system_bus.add_signal_receiver(self.avahi_dbus_connect_cb, "NameOwnerChanged", "org.freedesktop.DBus", arg0="org.freedesktop.Avahi")
except dbus.DBusException, e:
pprint.pprint(e)
sys.exit(1)
self.service_browsers = {}
self.start_service_discovery(None, None, None)
def avahi_dbus_connect_cb(self, a, connect, disconnect):
if connect != "":
print "We are disconnected from avahi-daemon"
self.stop_service_discovery(None, None, None)
else:
print "We are connected to avahi-daemon"
self.start_service_discovery(None, None, None)
def siocgifname(self, interface):
if interface <= 0:
return "any"
else:
return self.server.GetNetworkInterfaceNameByIndex(interface)
def service_resolved(self, interface, protocol, name, type, domain, host, aprotocol, address, port, txt, flags):
stdb = ServiceTypeDatabase()
h_type = stdb.get_human_type(type)
print "Service data for service '%s' of type '%s' (%s) in domain '%s' on %s.%i:" % (name, h_type, type, domain, self.siocgifname(interface), protocol)
print "\tHost %s (%s), port %i, TXT data: %s" % (host, address, port, avahi.txt_array_to_string_array(txt))
# txts = avahi.txt_array_to_string_array(txt)
def print_error(self, err):
# FIXME we should use notifications
print "Error:", str(err)
def new_service(self, interface, protocol, name, type, domain, flags):
print "Found service '%s' of type '%s' in domain '%s' on %s.%i." % (name, type, domain, self.siocgifname(interface), protocol)
# this check is for local services
# try:
# if flags & avahi.LOOKUP_RESULT_LOCAL:
# return
# except dbus.DBusException:
# pass
self.server.ResolveService(interface, protocol, name, type, domain, avahi.PROTO_INET, dbus.UInt32(0), reply_handler=self.service_resolved, error_handler=self.print_error)
def remove_service(self, interface, protocol, name, type, domain, flags):
print "Service '%s' of type '%s' in domain '%s' on %s.%i disappeared." % (name, type, domain, self.siocgifname(interface), protocol)
def all_for_now(self):
print "that's all for now"
#self.mainloop.quit()
gtk.main_quit()
def cache_exhausted(self):
print "cache exhausted"
def add_service_type(self, interface, protocol, type, domain):
# Are we already browsing this domain for this type?
if self.service_browsers.has_key((interface, protocol, type, domain)):
return
print "Browsing for services of type '%s' in domain '%s' on %s.%i ..." % (type, domain, self.siocgifname(interface), protocol)
b = dbus.Interface(self.system_bus.get_object(avahi.DBUS_NAME,
self.server.ServiceBrowserNew(interface, protocol, type, 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)
b.connect_to_signal("AllForNow", self.all_for_now)
b.connect_to_signal("CacheExhausted", self.cache_exhausted)
self.service_browsers[(interface, protocol, type, domain)] = b
def del_service_type(self, interface, protocol, type, domain):
service = (interface, protocol, type, domain)
if not self.service_browsers.has_key(service):
return
sb = self.service_browsers[service]
try:
sb.Free()
except dbus.DBusException:
pass
del self.service_browsers[service]
# delete the sub menu of service_type
if self.zc_types.has_key(type):
self.service_menu.remove(self.zc_types[type].get_attach_widget())
del self.zc_types[type]
if len(self.zc_types) == 0:
self.add_no_services_menuitem()
def start_service_discovery(self, component, verb, applet):
if len(self.domain) != 0:
print "domain not null %s" % (self.domain)
self.display_notification(_("Already Discovering"),"")
return
try:
self.server = dbus.Interface(self.system_bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER),
avahi.DBUS_INTERFACE_SERVER)
self.domain = self.server.GetDomainName()
except:
print "Check that the Avahi daemon is running!"
return
try:
self.use_host_names = self.server.IsNSSSupportAvailable()
except:
self.use_host_names = False
print "Starting discovery"
self.interface = avahi.IF_UNSPEC
self.protocol = avahi.PROTO_INET
#service_type = "_ssh._tcp"
service_type = "_universal._sub._ipp._tcp"
self.add_service_type(self.interface, self.protocol, service_type, self.domain)
def stop_service_discovery(self, component, verb, applet):
if len(self.domain) == 0:
print "Discovery already stopped"
return
print "Discovery stopped"
def main():
sda = ServiceDiscovery()
gtk.main()
if __name__ == "__main__":
main()