378 STRIPPATHS.append(os.path.abspath(os.getcwd()) +
"/")
380 import SimpleHTTPServer
384 conn = sqlite3.connect(OUTFILE_TREE)
389 def formatsource(source, formatstr = '<em class="%s">%s</em>'):
390 processings = [
"ALCA",
"RECO",
"HARVEST",
"online"]
391 info = source.split(
" ")
392 processing =
" ".
join(
filter(
lambda x: x
in processings, info))
393 source =
" ".
join(
filter(
lambda x: x
not in processings, info))
394 return formatstr % (processing,
escape(source))
396 def formatplace(filename, line):
398 shortname = filename[ :(MAXLEN-3)/2] +
"..." + filename[-(MAXLEN-3)/2: ]
if len(filename) > MAXLEN
else filename
399 return '<a href="/%s#%s" target="_blank">%s:%s</a>' % (
escape(filename), line,
escape(shortname), line)
402 out = [
escape(
'goto to /<filename> for info about a file')]
404 wfs = defaultdict(list)
405 for source, wf
in conn.execute(
""" -- some SQL hackery here to parse "source" 406 SELECT DISTINCT source, substr(source, instr(source, "wf ")+3)*1 FROM relation ORDER BY 2, 1;"""):
407 wfs[wf].
append(
'<a href="/workflow/%s">%s</a>' % (urllib.quote(source), formatsource(source)))
410 out.append(
'<li>' +
" ".
join(wfs[wf]) +
"</li>")
414 for f
in conn.execute(
"SELECT name FROM file ORDER BY name;"):
416 out.append(
'<li><a href="/%s">%s</a></li>' % (name, name))
419 return "\n".
join(out)
421 def showworkflow(source):
422 source = urllib.unquote(source)
423 cur = conn.execute(
""" 424 SELECT DISTINCT file.name FROM relation 425 INNER JOIN trace ON place = trace.id 426 INNER JOIN file ON file.id = trace.file 427 WHERE relation.source = ? 430 out = [
"Files used by workflow %s: <ul>" % formatsource(source)]
433 out.append(
'<li><a href="/%s">%s</a></li>' % (name, name))
435 return "\n".
join(out)
437 def showfile(filename):
439 out.append(
'<script src="https://rawgit.com/google/code-prettify/master/src/prettify.js"></script>')
440 out.append(
'<link rel="stylesheet" href="https://rawgit.com/google/code-prettify/master/src/prettify.css"></link>')
445 with open(d + filename)
as f:
446 lines = f.readlines()
447 out.append(
"Read %s" % f.name)
453 cur = conn.execute(
""" 454 SELECT DISTINCT trace.line, source FROM relation 455 INNER JOIN trace on relation.place = trace.id 456 INNER JOIN file ON trace.file == file.id 457 WHERE file.name == ? ORDER BY line, source;""", (filename,))
458 sourceinfo = defaultdict(list)
459 for line, source
in cur:
460 sourceinfo[line].
append(source)
462 out.append(
'<pre class="prettyprint linenums">')
463 for i, l
in enumerate(lines):
465 tags = [formatsource(source,
'<em class="%%s" data-tag="%%s" data-line="%d"></em>' % (i+1))
for source
in sourceinfo[i+1]]
466 out.append(
escape(l).rstrip() +
"".
join(tags))
469 out.append(
"""<script type="text/javascript"> 471 clickfunc = function(evt) { 472 document.querySelectorAll("li > iframe, li > br").forEach(function(e) {e.remove()}); 473 dest = "/info" + window.location.pathname + ":" + this.getAttribute("data-line"); 474 this.parentElement.insertAdjacentHTML("beforeend", '<br><iframe width="90%" height="500px" frameborder="0" src="' + dest + '"></iframe><br>'); 476 document.querySelectorAll("li > em").forEach(function(e) { 477 e.innerText = e.getAttribute("data-tag"); 478 e.onclick = clickfunc; 481 n = 1*window.location.hash.replace("#", ""); 483 li = document.querySelectorAll("li")[n-1]; 484 li.style = "background: #ee7"; 490 out.append(
"Could not find %s" % filename)
492 return "\n".
join(out)
495 def showinfo(filename, line):
498 def queryandoutput(startfrom, to, directiontext):
500 cur = conn.execute(
""" 501 SELECT place_type, -- why did we trace this line? 502 <to>file.name, <to>trace.line, -- where was it used? 503 usedby, usedby_type, relation, -- what was it used for? 504 place, source -- why did this code run? 506 INNER JOIN trace AS placetrace ON placetrace.id = relation.place 507 INNER JOIN trace AS usedbytrace ON usedbytrace.id = relation.usedby 508 INNER JOIN file AS placefile ON placefile.id = placetrace.file 509 INNER JOIN file AS usedbyfile ON usedbyfile.id = usedbytrace.file 510 WHERE <from>file.name = ? AND <from>trace.line = ? 512 .
replace(
"<from>", startfrom).
replace(
"<to>", to), (filename, line))
513 out.append(
"<p>%s %s <ul>" % (formatplace(filename, line), directiontext))
514 for place_type, pname, pline, usedby, usedby_type, relation, place, source
in cur:
516 '<li><tt>%s</tt> at %s by <tt>%s</tt> as <a href="/why/%d">%s</a> <a href="/why/%d">in</a> %s</li>' 517 % (
escape(place_type), formatplace(pname, pline),
escape(usedby_type), usedby,
escape(relation), place, formatsource(source)))
518 out.append(
"</ul></p>")
520 queryandoutput(
"place",
"usedby",
"is used as")
521 queryandoutput(
"usedby",
"place",
"uses")
523 return "\n".
join(out)
528 cur = conn.execute(
""" 529 WITH RECURSIVE fulltrace(level, baseid, parent, file, name, line) AS ( 530 SELECT 1 AS level, trace.id, parent, trace.file, file.name, line FROM trace 531 INNER JOIN file ON file.id = trace.file 533 UNION SELECT level+1, baseid, trace.parent, trace.file, file.name, trace.line FROM fulltrace 534 INNER JOIN trace ON trace.id = fulltrace.parent 535 INNER JOIN file ON file.id = trace.file) 536 SELECT name, line FROM fulltrace ORDER BY level;""", (id,))
538 out.append(
"Full stack trace:<ul>")
539 for name, line
in cur:
540 out.append(
'<li>%s</li>' % formatplace(name, line))
542 return "\n".
join(out)
545 (re.compile(
'/workflow/(.*)$'), showworkflow),
546 (re.compile(
'/info/(.*):(\d+)$'), showinfo),
547 (re.compile(
'/why/(\d+)$'), showwhy),
548 (re.compile(
'/(.+)$'), showfile),
549 (re.compile(
'/$'), index),
555 for pattern, func
in ROUTES:
556 m = pattern.match(self.path)
558 res =
func(*m.groups())
562 self.send_response(200,
"Here you go")
563 self.send_header(
"Content-Type",
"text/html; charset=utf-8")
565 self.wfile.write(
"""<html><style> 575 em.ALCA {background: #ee9; } 576 em.RECO {background: #9e9; } 577 em.HARVEST {background: #99e; } 578 em.online {background: #e99; } 580 self.wfile.write(res)
581 self.wfile.write(
"</body></html>")
584 self.send_response(400,
"Something went wrong")
586 trace = traceback.format_exc()
587 self.send_response(500,
"Things went very wrong")
588 self.send_header(
"Content-Type",
"text/plain; charset=utf-8")
590 self.wfile.write(trace)
593 Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
594 Handler.do_GET = do_GET
595 httpd = SocketServer.TCPServer((
"",SERVE_PORT), Handler)
596 print(
"serving at port", SERVE_PORT)
597 httpd.serve_forever()
def replace(string, replacements)
S & print(S &os, JobReport::InputFile const &f)
static std::string join(char **cmd)