16bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport BaseHTTPServer 26bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport SimpleHTTPServer 36bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport os 46bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport sys 56bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport urllib, urlparse 66bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport posixpath 76bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport StringIO 86bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport re 96bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport shutil 106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport threading 116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport time 126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport socket 136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport itertools 146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport Reporter 166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerimport ConfigParser 176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker### 196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Various patterns matched or replaced by server. 206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportFileRE = re.compile('(.*/)?report-(.*)\\.html') 226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->') 246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" --> 266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->') 286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"') 296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportReplacements = [] 316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Add custom javascript. 336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\ 346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<script language="javascript" type="text/javascript"> 356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerfunction load(url) { 366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (window.XMLHttpRequest) { 376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker req = new XMLHttpRequest(); 386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } else if (window.ActiveXObject) { 396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker req = new ActiveXObject("Microsoft.XMLHTTP"); 406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (req != undefined) { 426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker req.open("GET", url, true); 436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker req.send(""); 446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</script>""")) 476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Insert additional columns. 496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'), 506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker '<td></td><td></td>')) 516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Insert report bug and open file links. 536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'), 546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' + 556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>'))) 566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportReplacements.append((re.compile('<!-- REPORTHEADER -->'), 586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker '<h3><a href="/">Summary</a> > Report %(report)s</h3>')) 596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'), 616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>')) 626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Insert report crashes link. 646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Disabled for the time being until we decide exactly when this should 666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# be enabled. Also the radar reporter needs to be fixed to report 676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# multiple files. 686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'), 706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# '<br>These files will automatically be attached to ' + 716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# 'reports filed here: <a href="report_crashes">Report Crashes</a>.')) 726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker### 746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Other simple parameters 756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkShare = posixpath.join(posixpath.dirname(__file__), '../share/scan-view') 776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerkConfigPath = os.path.expanduser('~/.scanview.cfg') 786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker### 806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker__version__ = "0.1" 826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker__all__ = ["create_server"] 846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerclass ReporterThread(threading.Thread): 866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def __init__(self, report, reporter, parameters, server): 876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker threading.Thread.__init__(self) 886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.report = report 896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.server = server 906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.reporter = reporter 916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.parameters = parameters 926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.success = False 936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.status = None 946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def run(self): 966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker result = None 976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.server.options.debug: 996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],) 1006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.status = self.reporter.fileReport(self.report, self.parameters) 1016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.success = True 1026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker time.sleep(3) 1036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.server.options.debug: 1046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],) 1056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except Reporter.ReportFailure,e: 1066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.status = e.value 1076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except Exception,e: 1086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker s = StringIO.StringIO() 1096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker import traceback 1106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>s,'<b>Unhandled Exception</b><br><pre>' 1116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker traceback.print_exc(e,file=s) 1126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>s,'</pre>' 1136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.status = s.getvalue() 1146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerclass ScanViewServer(BaseHTTPServer.HTTPServer): 1166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def __init__(self, address, handler, root, reporters, options): 1176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker BaseHTTPServer.HTTPServer.__init__(self, address, handler) 1186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.root = root 1196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.reporters = reporters 1206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.options = options 1216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.halted = False 1226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config = None 1236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.load_config() 1246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def load_config(self): 1266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config = ConfigParser.RawConfigParser() 1276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Add defaults 1296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config.add_section('ScanView') 1306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for r in self.reporters: 1316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config.add_section(r.getName()) 1326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for p in r.getParameters(): 1336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if p.saveConfigValue(): 1346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config.set(r.getName(), p.getName(), '') 1356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Ignore parse errors 1376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 1386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config.read([kConfigPath]) 1396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except: 1406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker pass 1416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Save on exit 1436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker import atexit 1446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker atexit.register(lambda: self.save_config()) 1456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def save_config(self): 1476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Ignore errors (only called on exit). 1486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 1496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f = open(kConfigPath,'w') 1506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.config.write(f) 1516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f.close() 1526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except: 1536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker pass 1546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def halt(self): 1566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.halted = True 1576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.options.debug: 1586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],) 1596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def serve_forever(self): 1616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while not self.halted: 1626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.options.debug > 1: 1636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],) 1646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 1656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.handle_request() 1666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except OSError,e: 1676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print 'OSError',e.errno 1686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def finish_request(self, request, client_address): 1706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.options.autoReload: 1716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker import ScanView 1726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler 1736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker BaseHTTPServer.HTTPServer.finish_request(self, request, client_address) 1746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def handle_error(self, request, client_address): 1766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Ignore socket errors 1776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker info = sys.exc_info() 1786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if info and isinstance(info[1], socket.error): 1796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.options.debug > 1: 1806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],) 1816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return 1826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker BaseHTTPServer.HTTPServer.handle_error(self, request, client_address) 1836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Borrowed from Quixote, with simplifications. 1856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerdef parse_query(qs, fields=None): 1866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if fields is None: 1876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fields = {} 1886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for chunk in filter(None, qs.split('&')): 1896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if '=' not in chunk: 1906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker name = chunk 1916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker value = '' 1926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 1936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker name, value = chunk.split('=', 1) 1946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker name = urllib.unquote(name.replace('+', ' ')) 1956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker value = urllib.unquote(value.replace('+', ' ')) 1966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker item = fields.get(name) 1976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if item is None: 1986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fields[name] = [value] 1996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 2006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker item.append(value) 2016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return fields 2026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerclass ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): 2046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker server_version = "ScanViewServer/" + __version__ 2056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker dynamic_mtime = time.time() 2066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def do_HEAD(self): 2086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 2096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self) 2106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except Exception,e: 2116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.handle_exception(e) 2126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def do_GET(self): 2146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 2156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) 2166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except Exception,e: 2176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.handle_exception(e) 2186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def do_POST(self): 2206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker """Serve a POST request.""" 2216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 2226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker length = self.headers.getheader('content-length') or "0" 2236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 2246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker length = int(length) 2256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except: 2266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker length = 0 2276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker content = self.rfile.read(length) 2286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fields = parse_query(content) 2296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f = self.send_head(fields) 2306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if f: 2316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.copyfile(f, self.wfile) 2326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f.close() 2336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except Exception,e: 2346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.handle_exception(e) 2356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def log_message(self, format, *args): 2376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.server.options.debug: 2386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" % 2396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker (sys.argv[0], 2406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.address_string(), 2416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.log_date_time_string(), 2426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker format%args)) 2436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def load_report(self, report): 2456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path = os.path.join(self.server.root, 'report-%s.html'%report) 2466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker data = open(path).read() 2476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker keys = {} 2486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for item in kBugKeyValueRE.finditer(data): 2496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker k,v = item.groups() 2506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker keys[k] = v 2516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return keys 2526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def load_crashes(self): 2546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path = posixpath.join(self.server.root, 'index.html') 2556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker data = open(path).read() 2566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker problems = [] 2576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for item in kReportCrashEntryRE.finditer(data): 2586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fieldData = item.group(1) 2596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fields = dict([i.groups() for i in 2606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker kReportCrashEntryKeyValueRE.finditer(fieldData)]) 2616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker problems.append(fields) 2626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return problems 2636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def handle_exception(self, exc): 2656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker import traceback 2666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker s = StringIO.StringIO() 2676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>s, "INTERNAL ERROR\n" 2686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker traceback.print_exc(exc, s) 2696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f = self.send_string(s.getvalue(), 'text/plain') 2706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if f: 2716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.copyfile(f, self.wfile) 2726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f.close() 2736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def get_scalar_field(self, name): 2756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if name in self.fields: 2766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.fields[name][0] 2776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 2786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return None 2796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def submit_bug(self, c): 2816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker title = self.get_scalar_field('title') 2826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker description = self.get_scalar_field('description') 2836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker report = self.get_scalar_field('report') 2846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterIndex = self.get_scalar_field('reporter') 2856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker files = [] 2866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for fileID in self.fields.get('files',[]): 2876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 2886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker i = int(fileID) 2896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except: 2906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker i = None 2916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if i is None or i<0 or i>=len(c.files): 2926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (False, 'Invalid file ID') 2936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker files.append(c.files[i]) 2946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if not title: 2966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (False, "Missing title.") 2976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if not description: 2986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (False, "Missing description.") 2996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 3006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterIndex = int(reporterIndex) 3016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except: 3026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (False, "Invalid report method.") 3036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Get the reporter and parameters. 3056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporter = self.server.reporters[reporterIndex] 3066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker parameters = {} 3076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for o in reporter.getParameters(): 3086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker name = '%s_%s'%(reporter.getName(),o.getName()) 3096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if name not in self.fields: 3106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (False, 3116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'Missing field "%s" for %s report method.'%(name, 3126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporter.getName())) 3136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker parameters[o.getName()] = self.get_scalar_field(name) 3146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Update config defaults. 3166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if report != 'None': 3176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.server.config.set('ScanView', 'reporter', reporterIndex) 3186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for o in reporter.getParameters(): 3196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if o.saveConfigValue(): 3206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker name = o.getName() 3216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.server.config.set(reporter.getName(), name, parameters[name]) 3226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Create the report. 3246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker bug = Reporter.BugReport(title, description, files) 3256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Kick off a reporting thread. 3276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker t = ReporterThread(bug, reporter, parameters, self.server) 3286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker t.start() 3296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Wait for thread to die... 3316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while t.isAlive(): 3326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker time.sleep(.25) 3336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker submitStatus = t.status 3346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (t.success, t.status) 3366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_report_submit(self): 3386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker report = self.get_scalar_field('report') 3396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c = self.get_report_context(report) 3406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if c.reportSource is None: 3416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reportingFor = "Report Crashes > " 3426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fileBug = """\ 3436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<a href="/report_crashes">File Bug</a> > """%locals() 3446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 3456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource, 3466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker report) 3476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fileBug = '<a href="/report/%s">File Bug</a> > ' % report 3486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker title = self.get_scalar_field('title') 3496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker description = self.get_scalar_field('description') 3506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker res,message = self.submit_bug(c) 3526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if res: 3546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker statusClass = 'SubmitOk' 3556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker statusName = 'Succeeded' 3566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 3576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker statusClass = 'SubmitFail' 3586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker statusName = 'Failed' 3596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker result = """ 3616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<head> 3626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <title>Bug Submission</title> 3636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <link rel="stylesheet" type="text/css" href="/scanview.css" /> 3646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</head> 3656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<body> 3666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<h3> 3676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<a href="/">Summary</a> > 3686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(reportingFor)s 3696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(fileBug)s 3706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerSubmit</h3> 3716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<form name="form" action=""> 3726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table class="form"> 3736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><td> 3746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table class="form_group"> 3756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr> 3766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_clabel">Title:</td> 3776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 3786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <input type="text" name="title" size="50" value="%(title)s" disabled> 3796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 3806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr> 3816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr> 3826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_label">Description:</td> 3836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 3846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<textarea rows="10" cols="80" name="description" disabled> 3856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(description)s 3866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</textarea> 3876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 3886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 3896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</td></tr> 3906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 3916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</form> 3926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<h1 class="%(statusClass)s">Submission %(statusName)s</h1> 3936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(message)s 3946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<p> 3956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<hr> 3966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<a href="/">Return to Summary</a> 3976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</body> 3986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</html>"""%locals() 3996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_string(result) 4006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_open_report(self, report): 4026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 4036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker keys = self.load_report(report) 4046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except IOError: 4056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_error(400, 'Invalid report.') 4066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker file = keys.get('FILE') 4086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if not file or not posixpath.exists(file): 4096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_error(400, 'File does not exist: "%s"' % file) 4106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker import startfile 4126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.server.options.debug: 4136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0], 4146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker file) 4156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker status = startfile.open(file) 4176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if status: 4186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker res = 'Opened: "%s"' % file 4196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 4206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker res = 'Open failed: "%s"' % file 4216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_string(res, 'text/plain') 4236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def get_report_context(self, report): 4256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker class Context: 4266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker pass 4276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if report is None or report == 'None': 4286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker data = self.load_crashes() 4296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Don't allow empty reports. 4306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if not data: 4316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker raise ValueError, 'No crashes detected!' 4326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c = Context() 4336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.title = 'clang static analyzer failures' 4346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker stderrSummary = "" 4366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for item in data: 4376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if 'stderr' in item: 4386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path = posixpath.join(self.server.root, item['stderr']) 4396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if os.path.exists(path): 4406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker lns = itertools.islice(open(path), 0, 10) 4416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker stderrSummary += '%s\n--\n%s' % (item.get('src', 4426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker '<unknown>'), 4436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ''.join(lns)) 4446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.description = """\ 4466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerThe clang static analyzer failed on these inputs: 4476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%s 4486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerSTDERR Summary 4506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker-------------- 4516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%s 4526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker""" % ('\n'.join([item.get('src','<unknown>') for item in data]), 4536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker stderrSummary) 4546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.reportSource = None 4556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.navMarkup = "Report Crashes > " 4566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files = [] 4576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for item in data: 4586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files.append(item.get('src','')) 4596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files.append(posixpath.join(self.server.root, 4606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker item.get('file',''))) 4616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files.append(posixpath.join(self.server.root, 4626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker item.get('clangfile',''))) 4636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files.append(posixpath.join(self.server.root, 4646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker item.get('stderr',''))) 4656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files.append(posixpath.join(self.server.root, 4666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker item.get('info',''))) 4676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Just in case something failed, ignore files which don't 4686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # exist. 4696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files = [f for f in c.files 4706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if os.path.exists(f) and os.path.isfile(f)] 4716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 4726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Check that this is a valid report. 4736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path = posixpath.join(self.server.root, 'report-%s.html' % report) 4746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if not posixpath.exists(path): 4756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker raise ValueError, 'Invalid report ID' 4766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker keys = self.load_report(report) 4776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c = Context() 4786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.title = keys.get('DESC','clang error (unrecognized') 4796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.description = """\ 4806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerBug reported by the clang static analyzer. 4816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerDescription: %s 4836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerFile: %s 4846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerLine: %s 4856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>')) 4866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.reportSource = 'report-%s.html' % report 4876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource, 4886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker report) 4896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c.files = [path] 4916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return c 4926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_report(self, report, configOverrides=None): 4946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def getConfigOption(section, field): 4956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (configOverrides is not None and 4966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker section in configOverrides and 4976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker field in configOverrides[section]): 4986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return configOverrides[section][field] 4996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.server.config.get(section, field) 5006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # report is None is used for crashes 5026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 5036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker c = self.get_report_context(report) 5046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except ValueError, e: 5056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_error(400, e.message) 5066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker title = c.title 5086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker description= c.description 5096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reportingFor = c.navMarkup 5106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if c.reportSource is None: 5116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker extraIFrame = "" 5126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 5136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker extraIFrame = """\ 5146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<iframe src="/%s" width="100%%" height="40%%" 5156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker scrolling="auto" frameborder="1"> 5166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <a href="/%s">View Bug Report</a> 5176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</iframe>""" % (c.reportSource, c.reportSource) 5186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterSelections = [] 5206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterOptions = [] 5216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 5236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker active = int(getConfigOption('ScanView','reporter')) 5246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except: 5256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker active = 0 5266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for i,r in enumerate(self.server.reporters): 5276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker selected = (i == active) 5286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if selected: 5296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker selectedStr = ' selected' 5306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 5316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker selectedStr = '' 5326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName())) 5336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()]) 5346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker display = ('none','')[selected] 5356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterOptions.append("""\ 5366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr id="%sReporterOptions" style="display:%s"> 5376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_label">%s Options</td> 5386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 5396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <table class="form_inner_group"> 5406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%s 5416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </table> 5426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 5436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr> 5446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker"""%(r.getName(),display,r.getName(),options)) 5456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterSelections = '\n'.join(reporterSelections) 5466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporterOptionsDivs = '\n'.join(reporterOptions) 5476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters])) 5486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if c.files: 5506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fieldSize = min(5, len(c.files)) 5516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker attachFileOptions = '\n'.join(["""\ 5526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)]) 5536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker attachFileRow = """\ 5546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr> 5556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_label">Attach:</td> 5566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 5576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<select style="width:100%%" name="files" multiple size=%d> 5586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%s 5596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</select> 5606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 5616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr> 5626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker""" % (min(5, len(c.files)), attachFileOptions) 5636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 5646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker attachFileRow = "" 5656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker result = """<html> 5676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<head> 5686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <title>File Bug</title> 5696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <link rel="stylesheet" type="text/css" href="/scanview.css" /> 5706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</head> 5716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<script language="javascript" type="text/javascript"> 5726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickervar reporters = %(reportersArray)s; 5736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerfunction updateReporterOptions() { 5746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker index = document.getElementById('reporter').selectedIndex; 5756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for (var i=0; i < reporters.length; ++i) { 5766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker o = document.getElementById(reporters[i] + "ReporterOptions"); 5776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (i == index) { 5786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker o.style.display = ""; 5796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } else { 5806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker o.style.display = "none"; 5816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 5846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</script> 5856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<body onLoad="updateReporterOptions()"> 5866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<h3> 5876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<a href="/">Summary</a> > 5886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(reportingFor)s 5896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerFile Bug</h3> 5906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<form name="form" action="/report_submit" method="post"> 5916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<input type="hidden" name="report" value="%(report)s"> 5926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table class="form"> 5946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><td> 5956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table class="form_group"> 5966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr> 5976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_clabel">Title:</td> 5986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 5996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <input type="text" name="title" size="50" value="%(title)s"> 6006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 6016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr> 6026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr> 6036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_label">Description:</td> 6046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 6056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<textarea rows="10" cols="80" name="description"> 6066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(description)s 6076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</textarea> 6086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 6096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr> 6106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(attachFileRow)s 6126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 6146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<br> 6156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table class="form_group"> 6166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr> 6176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_clabel">Method:</td> 6186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="form_value"> 6196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <select id="reporter" name="reporter" onChange="updateReporterOptions()"> 6206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker %(reporterSelections)s 6216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </select> 6226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker </td> 6236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr> 6246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(reporterOptionsDivs)s 6256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 6266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<br> 6276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</td></tr> 6286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><td class="form_submit"> 6296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <input align="right" type="submit" name="Submit" value="Submit"> 6306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</td></tr> 6316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 6326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</form> 6336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker%(extraIFrame)s 6356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</body> 6376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</html>"""%locals() 6386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_string(result) 6406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_head(self, fields=None): 6426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (self.server.options.onlyServeLocal and 6436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.client_address[0] != '127.0.0.1'): 6446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_error(401, 'Unauthorized host.') 6456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if fields is None: 6476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fields = {} 6486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.fields = fields 6496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker o = urlparse.urlparse(self.path) 6516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.fields = parse_query(o.query, fields) 6526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path = posixpath.normpath(urllib.unquote(o.path)) 6536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Split the components and strip the root prefix. 6556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker components = path.split('/')[1:] 6566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Special case some top-level entries. 6586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if components: 6596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker name = components[0] 6606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if len(components)==2: 6616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if name=='report': 6626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_report(components[1]) 6636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elif name=='open': 6646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_open_report(components[1]) 6656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elif len(components)==1: 6666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if name=='quit': 6676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.server.halt() 6686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_string('Goodbye.', 'text/plain') 6696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elif name=='report_submit': 6706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_report_submit() 6716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elif name=='report_crashes': 6726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker overrides = { 'ScanView' : {}, 6736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'Radar' : {}, 6746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'Email' : {} } 6756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for i,r in enumerate(self.server.reporters): 6766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if r.getName() == 'Radar': 6776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker overrides['ScanView']['reporter'] = i 6786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker break 6796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker overrides['Radar']['Component'] = 'llvm - checker' 6806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker overrides['Radar']['Component Version'] = 'X' 6816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_report(None, overrides) 6826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elif name=='favicon.ico': 6836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_path(posixpath.join(kShare,'bugcatcher.ico')) 6846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Match directory entries. 6866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if components[-1] == '': 6876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker components[-1] = 'index.html' 6886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker relpath = '/'.join(components) 6906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path = posixpath.join(self.server.root, relpath) 6916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if self.server.options.debug > 1: 6936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0], 6946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker path) 6956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_path(path) 6966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_404(self): 6986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_error(404, "File not found") 6996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return None 7006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_path(self, path): 7026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # If the requested path is outside the root directory, do not open it 7036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker rel = os.path.abspath(path) 7046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if not rel.startswith(os.path.abspath(self.server.root)): 7056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_404() 7066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ctype = self.guess_type(path) 7086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ctype.startswith('text/'): 7096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Patch file instead 7106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_patched_file(path, ctype) 7116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else: 7126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker mode = 'rb' 7136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 7146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f = open(path, mode) 7156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except IOError: 7166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_404() 7176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_file(f, ctype) 7186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_file(self, f, ctype): 7206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Patch files to add links, but skip binary files. 7216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_response(200) 7226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_header("Content-type", ctype) 7236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fs = os.fstat(f.fileno()) 7246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_header("Content-Length", str(fs[6])) 7256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) 7266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.end_headers() 7276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return f 7286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_string(self, s, ctype='text/html', headers=True, mtime=None): 7306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if headers: 7316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_response(200) 7326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_header("Content-type", ctype) 7336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_header("Content-Length", str(len(s))) 7346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if mtime is None: 7356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker mtime = self.dynamic_mtime 7366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.send_header("Last-Modified", self.date_time_string(mtime)) 7376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker self.end_headers() 7386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return StringIO.StringIO(s) 7396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker def send_patched_file(self, path, ctype): 7416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Allow a very limited set of variables. This is pretty gross. 7426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker variables = {} 7436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker variables['report'] = '' 7446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker m = kReportFileRE.match(path) 7456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if m: 7466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker variables['report'] = m.group(2) 7476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker try: 7496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker f = open(path,'r') 7506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker except IOError: 7516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_404() 7526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker fs = os.fstat(f.fileno()) 7536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker data = f.read() 7546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for a,b in kReportReplacements: 7556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker data = a.sub(b % variables, data) 7566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return self.send_string(data, ctype, mtime=fs.st_mtime) 7576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerdef create_server(address, options, root): 7606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker import Reporter 7616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporters = Reporter.getReporters() 7636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return ScanViewServer(address, ScanViewRequestHandler, 7656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker root, 7666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker reporters, 7676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker options) 768