1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 from zope.interface import implements
18 from twisted.python import components
19 from twisted.spread import pb
20 from twisted.web import server
21 from twisted.web.resource import Resource
22 from twisted.web.error import NoResource
23
24 from buildbot import interfaces
25 from buildbot.status import logfile
26 from buildbot.status.web.base import IHTMLLog, HtmlResource, path_to_root
27
29 implements(interfaces.IStatusLogConsumer)
30
32 self.original = original
33 self.textlog = textlog
35 self.producer = producer
36 self.original.registerProducer(producer, streaming)
40 formatted = self.textlog.content([chunk])
41 try:
42 if isinstance(formatted, unicode):
43 formatted = formatted.encode('utf-8')
44 self.original.write(formatted)
45 except pb.DeadReferenceError:
46 self.producing.stopProducing()
49
50
51
52 -class TextLog(Resource):
53
54
55 implements(IHTMLLog)
56
57 asText = False
58 subscribed = False
59
60 - def __init__(self, original):
61 Resource.__init__(self)
62 self.original = original
63
64 - def getChild(self, path, req):
65 if path == "text":
66 self.asText = True
67 return self
68 return Resource.getChild(self, path, req)
69
70 - def content(self, entries):
71 html_entries = []
72 text_data = ''
73 for type, entry in entries:
74 if type >= len(logfile.ChunkTypes) or type < 0:
75
76 continue
77
78 is_header = type == logfile.HEADER
79
80 if not self.asText:
81
82 if not isinstance(entry, unicode):
83 entry = unicode(entry, 'utf-8', 'replace')
84 html_entries.append(dict(type = logfile.ChunkTypes[type],
85 text = entry,
86 is_header = is_header))
87 elif not is_header:
88 text_data += entry
89
90 if self.asText:
91 return text_data
92 else:
93 return self.template.module.chunks(html_entries)
94
95 - def render_HEAD(self, req):
96 self._setContentType(req)
97
98
99 req.setHeader("content-length", self.original.length)
100 return ''
101
102 - def render_GET(self, req):
103 self._setContentType(req)
104 self.req = req
105
106 if not self.asText:
107 self.template = req.site.buildbot_service.templates.get_template("logs.html")
108
109 data = self.template.module.page_header(
110 pageTitle = "Log File contents",
111 texturl = req.childLink("text"),
112 path_to_root = path_to_root(req))
113 data = data.encode('utf-8')
114 req.write(data)
115
116 self.original.subscribeConsumer(ChunkConsumer(req, self))
117 return server.NOT_DONE_YET
118
119 - def _setContentType(self, req):
120 if self.asText:
121 req.setHeader("content-type", "text/plain; charset=utf-8")
122 else:
123 req.setHeader("content-type", "text/html; charset=utf-8")
124
125 - def finished(self):
126 if not self.req:
127 return
128 try:
129 if not self.asText:
130 data = self.template.module.page_footer()
131 data = data.encode('utf-8')
132 self.req.write(data)
133 self.req.finish()
134 except pb.DeadReferenceError:
135 pass
136
137
138 self.req = None
139
140
141 self.template = None
142
143 components.registerAdapter(TextLog, interfaces.IStatusLog, IHTMLLog)
144
145
147 implements(IHTMLLog)
148
150 Resource.__init__(self)
151 self.original = original
152
154 request.setHeader("content-type", "text/html")
155 return self.original.html
156
157 components.registerAdapter(HTMLLog, logfile.HTMLLogFile, IHTMLLog)
158
159
174