source file: /home/buildslave/tahoe/edgy/build/src/allmydata/web/introweb.py
file stats: 127 lines, 123 executed: 96.9% covered
1.
2. import time
3. from nevow import rend, inevow
4. from foolscap.referenceable import SturdyRef
5. from twisted.internet import address
6. import allmydata
7. import simplejson
8. from allmydata import get_package_versions_string
9. from allmydata.util import idlib
10. from common import getxmlfile, get_arg, IClient
11.
12. class IntroducerRoot(rend.Page):
13.
14. addSlash = True
15. docFactory = getxmlfile("introducer.xhtml")
16.
17. def renderHTTP(self, ctx):
18. t = get_arg(inevow.IRequest(ctx), "t")
19. if t == "json":
20. return self.render_JSON(ctx)
21. return rend.Page.renderHTTP(self, ctx)
22.
23. def render_JSON(self, ctx):
24. i = IClient(ctx).getServiceNamed("introducer")
25. res = {}
26. clients = i.get_subscribers()
27. subscription_summary = dict([ (name, len(clients[name]))
28. for name in clients ])
29. res["subscription_summary"] = subscription_summary
30.
31. announcement_summary = {}
32. for (ann,when) in i.get_announcements().values():
33. (furl, service_name, ri_name, nickname, ver, oldest) = ann
34. if service_name not in announcement_summary:
35. announcement_summary[service_name] = 0
36. announcement_summary[service_name] += 1
37. res["announcement_summary"] = announcement_summary
38.
39. return simplejson.dumps(res, indent=1)
40.
41. def data_version(self, ctx, data):
42. return get_package_versions_string()
43. def data_import_path(self, ctx, data):
44. return str(allmydata)
45. def data_my_nodeid(self, ctx, data):
46. return idlib.nodeid_b2a(IClient(ctx).nodeid)
47.
48. def render_announcement_summary(self, ctx, data):
49. i = IClient(ctx).getServiceNamed("introducer")
50. services = {}
51. for (ann,when) in i.get_announcements().values():
52. (furl, service_name, ri_name, nickname, ver, oldest) = ann
53. if service_name not in services:
54. services[service_name] = 0
55. services[service_name] += 1
56. service_names = services.keys()
57. service_names.sort()
58. return ", ".join(["%s: %d" % (service_name, services[service_name])
59. for service_name in service_names])
60.
61. def render_client_summary(self, ctx, data):
62. i = IClient(ctx).getServiceNamed("introducer")
63. clients = i.get_subscribers()
64. service_names = clients.keys()
65. service_names.sort()
66. return ", ".join(["%s: %d" % (service_name, len(clients[service_name]))
67. for service_name in service_names])
68.
69. def data_services(self, ctx, data):
70. i = IClient(ctx).getServiceNamed("introducer")
71. ann = [(since,a)
72. for (a,since) in i.get_announcements().values()
73. if a[1] != "stub_client"]
74. ann.sort(lambda a,b: cmp( (a[1][1], a), (b[1][1], b) ) )
75. return ann
76.
77. def render_service_row(self, ctx, (since,announcement)):
78. (furl, service_name, ri_name, nickname, ver, oldest) = announcement
79. sr = SturdyRef(furl)
80. nodeid = sr.tubID
81. advertised = self.show_location_hints(sr)
82. ctx.fillSlots("peerid", "%s %s" % (nodeid, nickname))
83. ctx.fillSlots("advertised", " ".join(advertised))
84. ctx.fillSlots("connected", "?")
85. TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
86. ctx.fillSlots("announced",
87. time.strftime(TIME_FORMAT, time.localtime(since)))
88. ctx.fillSlots("version", ver)
89. ctx.fillSlots("service_name", service_name)
90. return ctx.tag
91.
92. def data_subscribers(self, ctx, data):
93. i = IClient(ctx).getServiceNamed("introducer")
94. # use the "stub_client" announcements to get information per nodeid
95. clients = {}
96. for (ann,when) in i.get_announcements().values():
97. if ann[1] != "stub_client":
98. continue
99. (furl, service_name, ri_name, nickname, ver, oldest) = ann
100. sr = SturdyRef(furl)
101. nodeid = sr.tubID
102. clients[nodeid] = ann
103.
104. # then we actually provide information per subscriber
105. s = []
106. for service_name, subscribers in i.get_subscribers().items():
107. for (rref, timestamp) in subscribers.items():
108. sr = rref.getSturdyRef()
109. nodeid = sr.tubID
110. ann = clients.get(nodeid)
111. s.append( (service_name, rref, timestamp, ann) )
112. s.sort()
113. return s
114.
115. def render_subscriber_row(self, ctx, s):
116. (service_name, rref, since, ann) = s
117. nickname = "?"
118. version = "?"
119. if ann:
120. (furl, service_name_2, ri_name, nickname, version, oldest) = ann
121.
122. sr = rref.getSturdyRef()
123. # if the subscriber didn't do Tub.setLocation, nodeid will be None
124. nodeid = sr.tubID or "?"
125. ctx.fillSlots("peerid", "%s %s" % (nodeid, nickname))
126. advertised = self.show_location_hints(sr)
127. ctx.fillSlots("advertised", " ".join(advertised))
128. remote_host = rref.tracker.broker.transport.getPeer()
129. if isinstance(remote_host, address.IPv4Address):
130. remote_host_s = "%s:%d" % (remote_host.host, remote_host.port)
131. else:
132. # loopback is a non-IPv4Address
133. remote_host_s = str(remote_host)
134. ctx.fillSlots("connected", remote_host_s)
135. TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
136. ctx.fillSlots("since",
137. time.strftime(TIME_FORMAT, time.localtime(since)))
138. ctx.fillSlots("version", version)
139. ctx.fillSlots("service_name", service_name)
140. return ctx.tag
141.
142. def show_location_hints(self, sr, ignore_localhost=True):
143. advertised = []
144. for hint in sr.locationHints:
145. if isinstance(hint, str):
146. # Foolscap-0.2.5 and earlier used strings in .locationHints
147. if ignore_localhost and hint.startswith("127.0.0.1"):
148. continue
149. advertised.append(hint.split(":")[0])
150. else:
151. # Foolscap-0.2.6 and later use tuples of ("ipv4", host, port)
152. if hint[0] == "ipv4":
153. host = hint[1]
154. if ignore_localhost and host == "127.0.0.1":
155. continue
156. advertised.append(hint[1])
157. return advertised
158.
159.