nolith / avahiserve

Avahi mercurial extension. Works only on Linux.

Clone this repository (size: 23.4 KB): HTTPS / SSH
$ hg clone http://code.l0g.in/avahiserve

Changed (Δ508 bytes):

raw changeset »

avahiserve.py (41 lines added, 17 lines removed)

Up to file-list avahiserve.py:

@@ -11,7 +11,10 @@ from dbus.mainloop.glib import DBusGMain
11
11
class AvahiReg:
12
12
13
13
	def __init__(self, name, port):
14
		self.serviceName = "Mercurial: " + name
14
		self.verbose = False
15
		self.serviceName = "Mercurial"
16
		if name != '':
17
			self.serviceName += ": " + name
15
18
		self.serviceType = "_http._tcp" # See http://www.dns-sd.org/ServiceTypes.html
16
19
		self.servicePort = port
17
20
		self.serviceTXT = ["extension's author=Alessio Caiazza"] #TXT record for the service
@@ -23,13 +26,13 @@ class AvahiReg:
23
26
		self.rename_count = 12 # Counter so we only rename after collisions a sensible number of times
24
27
25
28
	def add_service(self):
26
	#global group, serviceName, serviceType, servicePort, serviceTXT, domain, host
27
29
		if self.group is None:
28
30
			self.group = dbus.Interface(
29
31
				self.bus.get_object( avahi.DBUS_NAME, self.server.EntryGroupNew()),
30
32
				avahi.DBUS_INTERFACE_ENTRY_GROUP)
31
33
			self.group.connect_to_signal('StateChanged', self.entry_group_state_changed)
32
		print "Adding service '%s' of type '%s' ..." % (self.serviceName, self.serviceType)
34
		if self.verbose:
35
			print "Adding service '%s' of type '%s' ..." % (self.serviceName, self.serviceType)
33
36
		self.group.AddService(
34
37
			avahi.IF_UNSPEC,    #interface
35
38
			avahi.PROTO_UNSPEC, #protocol
@@ -41,21 +44,21 @@ class AvahiReg:
41
44
		self.group.Commit()
42
45
43
46
	def remove_service(self):
44
	   #global group
45
	   if not group is None:
46
		   group.Reset()
47
		if not group is None:
48
			group.Reset()
47
49
48
50
	def server_state_changed(self, state):
49
51
		if state == avahi.SERVER_COLLISION:
50
			print "WARNING: Server name collision"
52
			if self.verbose:
53
				print "WARNING: Server name collision"
51
54
			remove_service()
52
55
		elif state == avahi.SERVER_RUNNING:
53
56
			self.add_service()
54
57
55
58
	def entry_group_state_changed(self,state, error):
56
		#global serviceName, server, rename_count
57
59
58
		print "state change: %i" % state
60
		if self.verbose:
61
			print "state change: %i" % state
59
62
60
63
		if state == avahi.ENTRY_GROUP_ESTABLISHED:
61
64
			print "Service established."
@@ -64,18 +67,21 @@ class AvahiReg:
64
67
			rename_count = rename_count - 1
65
68
			if rename_count > 0:
66
69
				name = server.GetAlternativeServiceName(name)
67
				print "WARNING: Service name collision, changing name to '%s' ..." % name
70
				if self.verbose:
71
					print "WARNING: Service name collision, changing name to '%s' ..." % name
68
72
				remove_service()
69
73
				add_service()
70
74
71
75
			else:
72
				print "ERROR: No suitable service name found after %i retries, exiting." % n_rename
76
				if self.verbose:
77
					print "ERROR: No suitable service name found after %i retries, exiting." % n_rename
73
78
				main_loop.quit()
74
79
		elif state == avahi.ENTRY_GROUP_FAILURE:
75
			print "Error in group state changed", error
80
			if self.verbose:
81
				print "Error in group state changed", error
76
82
			main_loop.quit()
77
83
			return
78
    
84
79
85
	def start(self):
80
86
		DBusGMainLoop( set_as_default=True )
81
87
		self.bus = dbus.SystemBus()
@@ -86,6 +92,12 @@ class AvahiReg:
86
92
87
93
		self.server.connect_to_signal( "StateChanged", self.server_state_changed )
88
94
		self.server_state_changed( self.server.GetState() )
95
	
96
	def stop(self):
97
		if self.verbose:
98
			print "Stopping avahi-publish-service"
99
		if not self.group is None:
100
			self.group.Free()
89
101
90
102
# every command must take a ui and and repo as arguments.
91
103
# opts is a dict where you can find other command line flags
@@ -103,12 +115,24 @@ def avahi_serve(ui, repo, **opts):
103
115
	else:
104
116
		port = 8000
105
117
	a = AvahiReg(opts['name'], port)
118
119
	if ui.cdata.has_option('web', 'description'):
120
		a.serviceTXT += ["description=" + ui.cdata.get('web','description')]
121
	if ui.cdata.has_option('ui', 'username'):
122
		#remove < and > cose make problems on Avahi Discovery
123
		a.serviceTXT += ["owner=" + 
124
				ui.cdata.get('ui','username')
125
				.replace('<','')
126
				.replace('>','')]
127
128
	a.verbose = ui.verbose
106
129
	a.start()
107
	commands.serve(ui,repo, **opts)
130
	try:
131
		commands.serve(ui,repo, **opts)
132
	except KeyboardInterrupt:
133
		pass
108
134
	
109
	#never reached, I think...
110
	if not group is None:
111
		group.Free()
135
	a.stop()
112
136
113
137
cmdtable = {
114
138
	# cmd name        function call