Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: third_party/buildbot_7_12/buildbot/status/web/logs.py

Issue 12207158: Bye bye buildbot 0.7.12. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1
2 from zope.interface import implements
3 from twisted.python import components
4 from twisted.spread import pb
5 from twisted.web import html, server
6 from twisted.web.resource import Resource
7 from twisted.web.error import NoResource
8
9 from buildbot import interfaces
10 from buildbot.status import builder
11 from buildbot.status.web.base import IHTMLLog, HtmlResource
12 from buildbot.status.web.ansi2html import Ansi2HTML
13
14
15 textlog_stylesheet = """
16 <style type="text/css">
17 div.data {
18 font-family: "Courier New", courier, monotype;
19 }
20 span.stdout {
21 font-family: "Courier New", courier, monotype;
22 }
23 span.stderr {
24 font-family: "Courier New", courier, monotype;
25 color: red;
26 }
27 span.header {
28 font-family: "Courier New", courier, monotype;
29 color: blue;
30 }
31 </style>
32 """
33
34 class ChunkConsumer:
35 implements(interfaces.IStatusLogConsumer)
36
37 def __init__(self, original, textlog):
38 self.original = original
39 self.textlog = textlog
40 def registerProducer(self, producer, streaming):
41 self.producer = producer
42 self.original.registerProducer(producer, streaming)
43 def unregisterProducer(self):
44 self.original.unregisterProducer()
45 def writeChunk(self, chunk):
46 formatted = self.textlog.content([chunk])
47 try:
48 if isinstance(formatted, unicode):
49 formatted = formatted.encode('utf-8')
50 self.original.write(formatted)
51 except pb.DeadReferenceError:
52 self.producing.stopProducing()
53 def finish(self):
54 self.textlog.finished()
55
56
57 # /builders/$builder/builds/$buildnum/steps/$stepname/logs/$logname
58 class TextLog(Resource):
59 # a new instance of this Resource is created for each client who views
60 # it, so we can afford to track the request in the Resource.
61 implements(IHTMLLog)
62
63 printAs = "html"
64 subscribed = False
65
66 def __init__(self, original):
67 Resource.__init__(self)
68 self.original = original
69
70 def getChild(self, path, req):
71 if path == "ansi":
72 self.ansiParser = Ansi2HTML()
73
74 if path == "text" or path == "ansi":
75 self.printAs = path
76 return self
77
78 return HtmlResource.getChild(self, path, req)
79
80 def htmlHeader(self, request):
81 title = "Log File contents"
82 data = "<html>\n<head><title>" + title + "</title>\n"
83 data += textlog_stylesheet
84 data += "</head>\n"
85 data += "<body vlink=\"#800080\">\n"
86 texturl = request.childLink("text")
87 data += '<a href="%s">(view as text)</a><br />\n' % texturl
88 ansiurl = request.childLink("ansi")
89 data += '<a href="%s">(view as ansi)</a><br />\n' % ansiurl
90 data += "<pre>\n"
91 return data
92
93 def content(self, entries):
94 spanfmt = '<span class="%s">%s</span>'
95 data = ""
96 for type, entry in entries:
97 if type >= len(builder.ChunkTypes) or type < 0:
98 # non-std channel, don't display
99 continue
100 if self.printAs == "text":
101 if type != builder.HEADER:
102 data += entry
103 elif self.printAs == "ansi":
104 if type != builder.HEADER:
105 data += self.ansiParser.parseBlock(entry)
106 else:
107 data += spanfmt % (builder.ChunkTypes[type],
108 html.escape(entry))
109 return data
110
111 def htmlFooter(self):
112 data = "</pre>\n"
113 data += "</body></html>\n"
114 return data
115
116 def render_HEAD(self, request):
117 if self.printAs == "text":
118 request.setHeader("content-type", "text/plain")
119 else:
120 request.setHeader("content-type", "text/html")
121
122 # vague approximation, ignores markup
123 request.setHeader("content-length", self.original.length)
124 return ''
125
126 def render_GET(self, req):
127 self.req = req
128
129 if self.printAs == "text":
130 req.setHeader("content-type", "text/plain")
131 else:
132 req.setHeader("content-type", "text/html")
133
134 if self.printAs == "html":
135 req.write(self.htmlHeader(req))
136 if self.printAs == "ansi":
137 req.write(self.ansiParser.printHtmlHeader("Log File Contents"))
138 req.write(self.ansiParser.printHeader())
139
140 self.original.subscribeConsumer(ChunkConsumer(req, self))
141 return server.NOT_DONE_YET
142
143 def finished(self):
144 if not self.req:
145 return
146 try:
147 if self.printAs == "html":
148 self.req.write(self.htmlFooter())
149 if self.printAs == "ansi":
150 self.req.write(self.ansiParser.printFooter())
151 self.req.write(self.ansiParser.printHtmlFooter())
152 self.req.finish()
153 except pb.DeadReferenceError:
154 pass
155 # break the cycle, the Request's .notifications list includes the
156 # Deferred (from req.notifyFinish) that's pointing at us.
157 self.req = None
158
159 components.registerAdapter(TextLog, interfaces.IStatusLog, IHTMLLog)
160
161
162 class HTMLLog(Resource):
163 implements(IHTMLLog)
164
165 def __init__(self, original):
166 Resource.__init__(self)
167 self.original = original
168
169 def render(self, request):
170 request.setHeader("content-type", "text/html")
171 return self.original.html
172
173 components.registerAdapter(HTMLLog, builder.HTMLLogFile, IHTMLLog)
174
175
176 class LogsResource(HtmlResource):
177 addSlash = True
178
179 def __init__(self, step_status):
180 HtmlResource.__init__(self)
181 self.step_status = step_status
182
183 def getChild(self, path, req):
184 for log in self.step_status.getLogs():
185 if path == log.getName():
186 if log.hasContents():
187 return IHTMLLog(interfaces.IStatusLog(log))
188 return NoResource("Empty Log '%s'" % path)
189 return HtmlResource.getChild(self, path, req)
OLDNEW
« no previous file with comments | « third_party/buildbot_7_12/buildbot/status/web/index.html ('k') | third_party/buildbot_7_12/buildbot/status/web/robots.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698