Alessio Caiazza is sharing code with you
Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.
Don't show this againavahiserve / avahiserve.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 | #!/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.verbose = False
self.serviceName = "Mercurial"
if name != '':
self.serviceName += ": " + 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):
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)
if self.verbose:
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):
if not group is None:
group.Reset()
def server_state_changed(self, state):
if state == avahi.SERVER_COLLISION:
if self.verbose:
print "WARNING: Server name collision"
remove_service()
elif state == avahi.SERVER_RUNNING:
self.add_service()
def entry_group_state_changed(self,state, error):
if self.verbose:
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)
if self.verbose:
print "WARNING: Service name collision, changing name to '%s' ..." % name
remove_service()
add_service()
else:
if self.verbose:
print "ERROR: No suitable service name found after %i retries, exiting." % n_rename
main_loop.quit()
elif state == avahi.ENTRY_GROUP_FAILURE:
if self.verbose:
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() )
def stop(self):
if self.verbose:
print "Stopping avahi-publish-service"
if not self.group is None:
self.group.Free()
# 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)
if ui.cdata.has_option('web', 'description'):
a.serviceTXT += ["description=" + ui.cdata.get('web','description')]
if ui.cdata.has_option('ui', 'username'):
#remove < and > cose make problems on Avahi Discovery
a.serviceTXT += ["owner=" +
ui.cdata.get('ui','username')
.replace('<','')
.replace('>','')]
a.verbose = ui.verbose
a.start()
try:
commands.serve(ui,repo, **opts)
except KeyboardInterrupt:
pass
a.stop()
cmdtable = {
# cmd name function call
"aserve": (avahi_serve,
commands.table['^serve'][1],
"hg aserve [OPTION]...")
}
|