##// END OF EJS Templates
config: abort on indented non-continuation lines (issue1829)...
config: abort on indented non-continuation lines (issue1829) Previously, as soon as a continuation would be met, "cont" would stay forever set to True, but "item" was set back to "None". This caused the continuation code bits to run every time, until the next "self.get(section, item) + '\n'" which would crash.

File last commit:

r9443:7805b27e merge default
r9469:7f0f882a default
Show More
__init__.py
162 lines | 5.3 KiB | text/x-python | PythonLexer
Matt Mackall
zeroconf: initial implementation...
r7071 # zeroconf.py - zeroconf support for Mercurial
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.
Matt Mackall
zeroconf: initial implementation...
r7071
Cédric Duval
extensions: improve the consistency of synopses...
r8894 '''discover and advertise repositories on the local network
David Soria Parra
zeroconf: add extension documentation
r7606
Martin Geisler
zeroconf: word-wrap help texts at 70 characters
r8003 Zeroconf enabled repositories will be announced in a network without
the need to configure a server or a service. They can be discovered
without knowing their actual IP address.
David Soria Parra
zeroconf: add extension documentation
r7606
Martin Geisler
zeroconf: word-wrap help texts at 70 characters
r8003 To allow other people to discover your repository using run "hg serve"
in your repository.
David Soria Parra
zeroconf: add extension documentation
r7606
$ cd test
$ hg serve
You can discover zeroconf enabled repositories by running "hg paths".
$ hg paths
zc-test = http://example.com:8000/test
'''
Matt Mackall
zeroconf: initial implementation...
r7071 import Zeroconf, socket, time, os
from mercurial import ui
Matt Mackall
extensions: use new wrapper functions
r7216 from mercurial import extensions
Matt Mackall
zeroconf: initial implementation...
r7071 from mercurial.hgweb import hgweb_mod
from mercurial.hgweb import hgwebdir_mod
# publish
server = None
localip = None
def getip():
# finds external-facing interface without sending any packets (Linux)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('1.0.0.1', 0))
ip = s.getsockname()[0]
return ip
except:
pass
# Generic method, sometimes gives useless results
Alexander Solovyov
zeroconf: guess ip for Zeroconf...
r8264 try:
dumbip = socket.gethostbyaddr(socket.gethostname())[2][0]
if not dumbip.startswith('127.') and ':' not in dumbip:
return dumbip
except socket.gaierror:
dumbip = '127.0.0.1'
Matt Mackall
zeroconf: initial implementation...
r7071
# works elsewhere, but actually sends a packet
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('1.0.0.1', 1))
ip = s.getsockname()[0]
return ip
except:
pass
return dumbip
def publish(name, desc, path, port):
global server, localip
if not server:
Alexander Solovyov
zeroconf: guess ip for Zeroconf...
r8264 ip = getip()
if ip.startswith('127.'):
Augie Fackler
zeroconf: Don't break serve if no internet connection is present.
r7295 # if we have no internet connection, this can happen.
return
Matt Mackall
zeroconf: initial implementation...
r7071 localip = socket.inet_aton(ip)
Alexander Solovyov
zeroconf: guess ip for Zeroconf...
r8264 server = Zeroconf.Zeroconf(ip)
Matt Mackall
zeroconf: initial implementation...
r7071
Alexander Solovyov
zeroconf: advertise repositories with hostname
r7845 hostname = socket.gethostname().split('.')[0]
host = hostname + ".local"
name = "%s-%s" % (hostname, name)
Matt Mackall
zeroconf: initial implementation...
r7071
# advertise to browsers
svc = Zeroconf.ServiceInfo('_http._tcp.local.',
name + '._http._tcp.local.',
server = host,
port = port,
properties = {'description': desc,
'path': "/" + path},
address = localip, weight = 0, priority = 0)
server.registerService(svc)
# advertise to Mercurial clients
svc = Zeroconf.ServiceInfo('_hg._tcp.local.',
name + '._hg._tcp.local.',
Matt Mackall
zeroconf: advertise a proper hostname for _hg services
r7088 server = host,
Matt Mackall
zeroconf: initial implementation...
r7071 port = port,
properties = {'description': desc,
'path': "/" + path},
address = localip, weight = 0, priority = 0)
server.registerService(svc)
class hgwebzc(hgweb_mod.hgweb):
def __init__(self, repo, name=None):
super(hgwebzc, self).__init__(repo, name)
name = self.reponame or os.path.basename(repo.root)
Patrick Mezard
zeroconf: fix hgweb published URLs (issue1819)
r9442 path = self.repo.ui.config("web", "prefix", "").strip('/')
Matt Mackall
zeroconf: initial implementation...
r7071 desc = self.repo.ui.config("web", "description", name)
Patrick Mezard
zeroconf: fix hgweb published URLs (issue1819)
r9442 publish(name, desc, path, int(repo.ui.config("web", "port", 8000)))
Matt Mackall
zeroconf: initial implementation...
r7071
class hgwebdirzc(hgwebdir_mod.hgwebdir):
Patrick Mezard
zeroconf: fix hgweb published URLs (issue1819)
r9442 def __init__(self, conf, baseui=None):
super(hgwebdirzc, self).__init__(conf, baseui)
prefix = self.ui.config("web", "prefix", "").strip('/') + '/'
Matt Mackall
zeroconf: initial implementation...
r7071 for r, p in self.repos:
Matt Mackall
hgweb: kill parentui references
r8191 u = self.ui.copy()
Benoit Boissinot
fix zeroconf handling for hgwebdir (error found by pychecker)
r7282 u.readconfig(os.path.join(p, '.hg', 'hgrc'))
Matt Mackall
zeroconf: initial implementation...
r7071 n = os.path.basename(r)
Patrick Mezard
zeroconf: fix hgweb published URLs (issue1819)
r9442 path = (prefix + r).strip('/')
publish(n, "hgweb", path, int(u.config("web", "port", 8000)))
Matt Mackall
zeroconf: initial implementation...
r7071
# listen
class listener(object):
def __init__(self):
self.found = {}
def removeService(self, server, type, name):
if repr(name) in self.found:
del self.found[repr(name)]
def addService(self, server, type, name):
self.found[repr(name)] = server.getServiceInfo(type, name)
def getzcpaths():
Alexander Solovyov
zeroconf: guess ip for Zeroconf...
r8264 ip = getip()
if ip.startswith('127.'):
return
server = Zeroconf.Zeroconf(ip)
Matt Mackall
zeroconf: initial implementation...
r7071 l = listener()
Peter Arrenbrecht
cleanup: drop variables for unused return values...
r7874 Zeroconf.ServiceBrowser(server, "_hg._tcp.local.", l)
Matt Mackall
zeroconf: initial implementation...
r7071 time.sleep(1)
server.close()
for v in l.found.values():
n = v.name[:v.name.index('.')]
n.replace(" ", "-")
u = "http://%s:%s%s" % (socket.inet_ntoa(v.address), v.port,
v.properties.get("path", "/"))
yield "zc-" + n, u
Matt Mackall
extensions: use new wrapper functions
r7216 def config(orig, self, section, key, default=None, untrusted=False):
Matt Mackall
zeroconf: initial implementation...
r7071 if section == "paths" and key.startswith("zc-"):
for n, p in getzcpaths():
if n == key:
return p
Matt Mackall
extensions: use new wrapper functions
r7216 return orig(self, section, key, default, untrusted)
Matt Mackall
zeroconf: initial implementation...
r7071
Matt Mackall
zeroconf: don't break on hg showconfig
r7238 def configitems(orig, self, section, untrusted=False):
r = orig(self, section, untrusted)
Matt Mackall
zeroconf: initial implementation...
r7071 if section == "paths":
r += getzcpaths()
return r
Matt Mackall
extensions: use new wrapper functions
r7216 extensions.wrapfunction(ui.ui, 'config', config)
extensions.wrapfunction(ui.ui, 'configitems', configitems)
Matt Mackall
zeroconf: initial implementation...
r7071 hgweb_mod.hgweb = hgwebzc
hgwebdir_mod.hgwebdir = hgwebdirzc