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 HtmlResource.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