##// END OF EJS Templates
zeroconf: use only first part of hostname for building local name
Matt Mackall -
r7087:62c71741 default
parent child Browse files
Show More
@@ -1,133 +1,134 b''
1 # zeroconf.py - zeroconf support for Mercurial
1 # zeroconf.py - zeroconf support for Mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of
5 # This software may be used and distributed according to the terms of
6 # the GNU General Public License (version 2), incorporated herein by
6 # the GNU General Public License (version 2), incorporated herein by
7 # reference.
7 # reference.
8
8
9 import Zeroconf, socket, time, os
9 import Zeroconf, socket, time, os
10 from mercurial import ui
10 from mercurial import ui
11 from mercurial.hgweb import hgweb_mod
11 from mercurial.hgweb import hgweb_mod
12 from mercurial.hgweb import hgwebdir_mod
12 from mercurial.hgweb import hgwebdir_mod
13
13
14 # publish
14 # publish
15
15
16 server = None
16 server = None
17 localip = None
17 localip = None
18
18
19 def getip():
19 def getip():
20 # finds external-facing interface without sending any packets (Linux)
20 # finds external-facing interface without sending any packets (Linux)
21 try:
21 try:
22 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
22 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
23 s.connect(('1.0.0.1', 0))
23 s.connect(('1.0.0.1', 0))
24 ip = s.getsockname()[0]
24 ip = s.getsockname()[0]
25 return ip
25 return ip
26 except:
26 except:
27 pass
27 pass
28
28
29 # Generic method, sometimes gives useless results
29 # Generic method, sometimes gives useless results
30 dumbip = socket.gethostbyaddr(socket.gethostname())[2][0]
30 dumbip = socket.gethostbyaddr(socket.gethostname())[2][0]
31 if not dumbip.startswith('127.'):
31 if not dumbip.startswith('127.'):
32 return dumbip
32 return dumbip
33
33
34 # works elsewhere, but actually sends a packet
34 # works elsewhere, but actually sends a packet
35 try:
35 try:
36 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
36 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
37 s.connect(('1.0.0.1', 1))
37 s.connect(('1.0.0.1', 1))
38 ip = s.getsockname()[0]
38 ip = s.getsockname()[0]
39 return ip
39 return ip
40 except:
40 except:
41 pass
41 pass
42
42
43 return dumbip
43 return dumbip
44
44
45 def publish(name, desc, path, port):
45 def publish(name, desc, path, port):
46 global server, localip
46 global server, localip
47 if not server:
47 if not server:
48 server = Zeroconf.Zeroconf()
48 server = Zeroconf.Zeroconf()
49 ip = getip()
49 ip = getip()
50 localip = socket.inet_aton(ip)
50 localip = socket.inet_aton(ip)
51
51
52 host = socket.gethostname() + ".local"
52 parts = socket.gethostname().split('.')
53 host = parts[0] + ".local"
53
54
54 # advertise to browsers
55 # advertise to browsers
55 svc = Zeroconf.ServiceInfo('_http._tcp.local.',
56 svc = Zeroconf.ServiceInfo('_http._tcp.local.',
56 name + '._http._tcp.local.',
57 name + '._http._tcp.local.',
57 server = host,
58 server = host,
58 port = port,
59 port = port,
59 properties = {'description': desc,
60 properties = {'description': desc,
60 'path': "/" + path},
61 'path': "/" + path},
61 address = localip, weight = 0, priority = 0)
62 address = localip, weight = 0, priority = 0)
62 server.registerService(svc)
63 server.registerService(svc)
63
64
64 # advertise to Mercurial clients
65 # advertise to Mercurial clients
65 svc = Zeroconf.ServiceInfo('_hg._tcp.local.',
66 svc = Zeroconf.ServiceInfo('_hg._tcp.local.',
66 name + '._hg._tcp.local.',
67 name + '._hg._tcp.local.',
67 port = port,
68 port = port,
68 properties = {'description': desc,
69 properties = {'description': desc,
69 'path': "/" + path},
70 'path': "/" + path},
70 address = localip, weight = 0, priority = 0)
71 address = localip, weight = 0, priority = 0)
71 server.registerService(svc)
72 server.registerService(svc)
72
73
73 class hgwebzc(hgweb_mod.hgweb):
74 class hgwebzc(hgweb_mod.hgweb):
74 def __init__(self, repo, name=None):
75 def __init__(self, repo, name=None):
75 super(hgwebzc, self).__init__(repo, name)
76 super(hgwebzc, self).__init__(repo, name)
76 name = self.reponame or os.path.basename(repo.root)
77 name = self.reponame or os.path.basename(repo.root)
77 desc = self.repo.ui.config("web", "description", name)
78 desc = self.repo.ui.config("web", "description", name)
78 publish(name, desc, name, int(repo.ui.config("web", "port", 8000)))
79 publish(name, desc, name, int(repo.ui.config("web", "port", 8000)))
79
80
80 class hgwebdirzc(hgwebdir_mod.hgwebdir):
81 class hgwebdirzc(hgwebdir_mod.hgwebdir):
81 def run(self):
82 def run(self):
82 print os.environ
83 print os.environ
83 for r, p in self.repos:
84 for r, p in self.repos:
84 u = ui.ui(parentui=self.parentui)
85 u = ui.ui(parentui=self.parentui)
85 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
86 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
86 n = os.path.basename(r)
87 n = os.path.basename(r)
87 desc = u.config("web", "description", n)
88 desc = u.config("web", "description", n)
88 publish(n, "hgweb", p, int(repo.ui.config("web", "port", 8000)))
89 publish(n, "hgweb", p, int(repo.ui.config("web", "port", 8000)))
89 return super(hgwebdirzc, self).run()
90 return super(hgwebdirzc, self).run()
90
91
91 # listen
92 # listen
92
93
93 class listener(object):
94 class listener(object):
94 def __init__(self):
95 def __init__(self):
95 self.found = {}
96 self.found = {}
96 def removeService(self, server, type, name):
97 def removeService(self, server, type, name):
97 if repr(name) in self.found:
98 if repr(name) in self.found:
98 del self.found[repr(name)]
99 del self.found[repr(name)]
99 def addService(self, server, type, name):
100 def addService(self, server, type, name):
100 self.found[repr(name)] = server.getServiceInfo(type, name)
101 self.found[repr(name)] = server.getServiceInfo(type, name)
101
102
102 def getzcpaths():
103 def getzcpaths():
103 server = Zeroconf.Zeroconf()
104 server = Zeroconf.Zeroconf()
104 l = listener()
105 l = listener()
105 browser = Zeroconf.ServiceBrowser(server, "_hg._tcp.local.", l)
106 browser = Zeroconf.ServiceBrowser(server, "_hg._tcp.local.", l)
106 time.sleep(1)
107 time.sleep(1)
107 server.close()
108 server.close()
108 for v in l.found.values():
109 for v in l.found.values():
109 n = v.name[:v.name.index('.')]
110 n = v.name[:v.name.index('.')]
110 n.replace(" ", "-")
111 n.replace(" ", "-")
111 u = "http://%s:%s%s" % (socket.inet_ntoa(v.address), v.port,
112 u = "http://%s:%s%s" % (socket.inet_ntoa(v.address), v.port,
112 v.properties.get("path", "/"))
113 v.properties.get("path", "/"))
113 yield "zc-" + n, u
114 yield "zc-" + n, u
114
115
115 def config(self, section, key, default=None, untrusted=False):
116 def config(self, section, key, default=None, untrusted=False):
116 if section == "paths" and key.startswith("zc-"):
117 if section == "paths" and key.startswith("zc-"):
117 for n, p in getzcpaths():
118 for n, p in getzcpaths():
118 if n == key:
119 if n == key:
119 return p
120 return p
120 return oldconfig(self, section, key, default, untrusted)
121 return oldconfig(self, section, key, default, untrusted)
121
122
122 def configitems(self, section):
123 def configitems(self, section):
123 r = oldconfigitems(self, section, untrusted=False)
124 r = oldconfigitems(self, section, untrusted=False)
124 if section == "paths":
125 if section == "paths":
125 r += getzcpaths()
126 r += getzcpaths()
126 return r
127 return r
127
128
128 oldconfig = ui.ui.config
129 oldconfig = ui.ui.config
129 oldconfigitems = ui.ui.configitems
130 oldconfigitems = ui.ui.configitems
130 ui.ui.config = config
131 ui.ui.config = config
131 ui.ui.configitems = configitems
132 ui.ui.configitems = configitems
132 hgweb_mod.hgweb = hgwebzc
133 hgweb_mod.hgweb = hgwebzc
133 hgwebdir_mod.hgwebdir = hgwebdirzc
134 hgwebdir_mod.hgwebdir = hgwebdirzc
General Comments 0
You need to be logged in to leave comments. Login now