# HG changeset patch # User Alessio Caiazza # Date 1204290735 -3600 # Node ID 2de4c35d30c8838f8750a07a85e946d4dc36cbc6 # Parent 0000000000000000000000000000000000000000 start diff -r 0000000000000000000000000000000000000000 -r 2de4c35d30c8838f8750a07a85e946d4dc36cbc6 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Feb 29 14:12:15 2008 +0100 @@ -0,0 +1,4 @@ +syntax: glob +*.pyc +*~ +*.swp diff -r 0000000000000000000000000000000000000000 -r 2de4c35d30c8838f8750a07a85e946d4dc36cbc6 avahiserve.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/avahiserve.py Fri Feb 29 14:12:15 2008 +0100 @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +from mercurial import hg +from mercurial import commands + +import dbus +import gobject +import avahi +from dbus.mainloop.glib import DBusGMainLoop + +class AvahiReg: + + def __init__(self, name, port): + self.serviceName = "Mercurial: " + name + self.serviceType = "_http._tcp" # See http://www.dns-sd.org/ServiceTypes.html + self.servicePort = port + self.serviceTXT = ["extension's author=Alessio Caiazza"] #TXT record for the service + + self.domain = "" # Domain to publish on, default to .local + self.host = "" # Host to publish records for, default to localhost + + self.group = None #our entry group + self.rename_count = 12 # Counter so we only rename after collisions a sensible number of times + + def add_service(self): + #global group, serviceName, serviceType, servicePort, serviceTXT, domain, host + if self.group is None: + self.group = dbus.Interface( + self.bus.get_object( avahi.DBUS_NAME, self.server.EntryGroupNew()), + avahi.DBUS_INTERFACE_ENTRY_GROUP) + self.group.connect_to_signal('StateChanged', self.entry_group_state_changed) + print "Adding service '%s' of type '%s' ..." % (self.serviceName, self.serviceType) + self.group.AddService( + avahi.IF_UNSPEC, #interface + avahi.PROTO_UNSPEC, #protocol + 0, #flags + self.serviceName, self.serviceType, + self.domain, self.host, + dbus.UInt16(self.servicePort), + avahi.string_array_to_txt_array(self.serviceTXT)) + self.group.Commit() + + def remove_service(self): + #global group + if not group is None: + group.Reset() + + def server_state_changed(self, state): + if state == avahi.SERVER_COLLISION: + print "WARNING: Server name collision" + remove_service() + elif state == avahi.SERVER_RUNNING: + self.add_service() + + def entry_group_state_changed(self,state, error): + #global serviceName, server, rename_count + + print "state change: %i" % state + + if state == avahi.ENTRY_GROUP_ESTABLISHED: + print "Service established." + elif state == avahi.ENTRY_GROUP_COLLISION: + + rename_count = rename_count - 1 + if rename_count > 0: + name = server.GetAlternativeServiceName(name) + print "WARNING: Service name collision, changing name to '%s' ..." % name + remove_service() + add_service() + + else: + print "ERROR: No suitable service name found after %i retries, exiting." % n_rename + main_loop.quit() + elif state == avahi.ENTRY_GROUP_FAILURE: + print "Error in group state changed", error + main_loop.quit() + return + + def start(self): + DBusGMainLoop( set_as_default=True ) + self.bus = dbus.SystemBus() + + self.server = dbus.Interface( + self.bus.get_object( avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER ), + avahi.DBUS_INTERFACE_SERVER ) + + self.server.connect_to_signal( "StateChanged", self.server_state_changed ) + self.server_state_changed( self.server.GetState() ) + +# every command must take a ui and and repo as arguments. +# opts is a dict where you can find other command line flags +# +# Other parameters are taken in order from items on the command line that +# don't start with a dash. If no default value is given in the parameter list, +# they are required. +def avahi_serve(ui, repo, **opts): + # The doc string below will show up in hg help + """Serve and publish on avahi zeroconf""" + + #print opts + if opts['port'] != 0: + port = int(opts['port']) + else: + port = 8000 + a = AvahiReg(opts['name'], port) + a.start() + commands.serve(ui,repo, **opts) + + #never reached, I think... + if not group is None: + group.Free() + +cmdtable = { + # cmd name function call + "aserve": (avahi_serve, + commands.table['^serve'][1], + "hg aserve [OPTION]...") +} + +