OLD | NEW |
| (Empty) |
1 | |
2 import sys, re | |
3 | |
4 from twisted.spread import pb | |
5 from twisted.cred import credentials, error | |
6 from twisted.internet import reactor | |
7 | |
8 class StatusClient(pb.Referenceable): | |
9 """To use this, call my .connected method with a RemoteReference to the | |
10 buildmaster's StatusClientPerspective object. | |
11 """ | |
12 | |
13 def __init__(self, events): | |
14 self.builders = {} | |
15 self.events = events | |
16 | |
17 def connected(self, remote): | |
18 print "connected" | |
19 self.remote = remote | |
20 remote.callRemote("subscribe", self.events, 5, self) | |
21 | |
22 def remote_builderAdded(self, buildername, builder): | |
23 print "builderAdded", buildername | |
24 | |
25 def remote_builderRemoved(self, buildername): | |
26 print "builderRemoved", buildername | |
27 | |
28 def remote_builderChangedState(self, buildername, state, eta): | |
29 print "builderChangedState", buildername, state, eta | |
30 | |
31 def remote_buildStarted(self, buildername, build): | |
32 print "buildStarted", buildername | |
33 | |
34 def remote_buildFinished(self, buildername, build, results): | |
35 print "buildFinished", results | |
36 | |
37 def remote_buildETAUpdate(self, buildername, build, eta): | |
38 print "ETA", buildername, eta | |
39 | |
40 def remote_stepStarted(self, buildername, build, stepname, step): | |
41 print "stepStarted", buildername, stepname | |
42 | |
43 def remote_stepFinished(self, buildername, build, stepname, step, results): | |
44 print "stepFinished", buildername, stepname, results | |
45 | |
46 def remote_stepETAUpdate(self, buildername, build, stepname, step, | |
47 eta, expectations): | |
48 print "stepETA", buildername, stepname, eta | |
49 | |
50 def remote_logStarted(self, buildername, build, stepname, step, | |
51 logname, log): | |
52 print "logStarted", buildername, stepname | |
53 | |
54 def remote_logFinished(self, buildername, build, stepname, step, | |
55 logname, log): | |
56 print "logFinished", buildername, stepname | |
57 | |
58 def remote_logChunk(self, buildername, build, stepname, step, logname, log, | |
59 channel, text): | |
60 ChunkTypes = ["STDOUT", "STDERR", "HEADER"] | |
61 print "logChunk[%s]: %s" % (ChunkTypes[channel], text) | |
62 | |
63 class TextClient: | |
64 def __init__(self, master, events="steps"): | |
65 """ | |
66 @type events: string, one of builders, builds, steps, logs, full | |
67 @param events: specify what level of detail should be reported. | |
68 - 'builders': only announce new/removed Builders | |
69 - 'builds': also announce builderChangedState, buildStarted, and | |
70 buildFinished | |
71 - 'steps': also announce buildETAUpdate, stepStarted, stepFinished | |
72 - 'logs': also announce stepETAUpdate, logStarted, logFinished | |
73 - 'full': also announce log contents | |
74 """ | |
75 self.master = master | |
76 self.listener = StatusClient(events) | |
77 | |
78 def run(self): | |
79 """Start the TextClient.""" | |
80 self.startConnecting() | |
81 reactor.run() | |
82 | |
83 def startConnecting(self): | |
84 try: | |
85 host, port = re.search(r'(.+):(\d+)', self.master).groups() | |
86 port = int(port) | |
87 except: | |
88 print "unparseable master location '%s'" % self.master | |
89 print " expecting something more like localhost:8007" | |
90 raise | |
91 cf = pb.PBClientFactory() | |
92 creds = credentials.UsernamePassword("statusClient", "clientpw") | |
93 d = cf.login(creds) | |
94 reactor.connectTCP(host, port, cf) | |
95 d.addCallbacks(self.connected, self.not_connected) | |
96 return d | |
97 def connected(self, ref): | |
98 ref.notifyOnDisconnect(self.disconnected) | |
99 self.listener.connected(ref) | |
100 def not_connected(self, why): | |
101 if why.check(error.UnauthorizedLogin): | |
102 print """ | |
103 Unable to login.. are you sure we are connecting to a | |
104 buildbot.status.client.PBListener port and not to the slaveport? | |
105 """ | |
106 reactor.stop() | |
107 return why | |
108 def disconnected(self, ref): | |
109 print "lost connection" | |
110 # we can get here in one of two ways: the buildmaster has | |
111 # disconnected us (probably because it shut itself down), or because | |
112 # we've been SIGINT'ed. In the latter case, our reactor is already | |
113 # shut down, but we have no easy way of detecting that. So protect | |
114 # our attempt to shut down the reactor. | |
115 try: | |
116 reactor.stop() | |
117 except RuntimeError: | |
118 pass | |
119 | |
120 if __name__ == '__main__': | |
121 master = "localhost:8007" | |
122 if len(sys.argv) > 1: | |
123 master = sys.argv[1] | |
124 c = TextClient() | |
125 c.run() | |
OLD | NEW |