1# Copyright 2016 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4"""Text templates used by various parts of results_report.""" 5from __future__ import print_function 6 7import cgi 8from string import Template 9 10_TabMenuTemplate = Template(""" 11<div class='tab-menu'> 12 <a href="javascript:switchTab('$table_name', 'html')">HTML</a> 13 <a href="javascript:switchTab('$table_name', 'text')">Text</a> 14 <a href="javascript:switchTab('$table_name', 'tsv')">TSV</a> 15</div>""") 16 17def _GetTabMenuHTML(table_name): 18 # N.B. cgi.escape does some very basic HTML escaping. Nothing more. 19 escaped = cgi.escape(table_name, quote=True) 20 return _TabMenuTemplate.substitute(table_name=escaped) 21 22 23_ExperimentFileHTML = """ 24<div class='results-section'> 25 <div class='results-section-title'>Experiment File</div> 26 <div class='results-section-content'> 27 <pre>%s</pre> 28</div> 29""" 30 31def _GetExperimentFileHTML(experiment_file_text): 32 if not experiment_file_text: 33 return '' 34 return _ExperimentFileHTML % (cgi.escape(experiment_file_text), ) 35 36 37_ResultsSectionHTML = Template(""" 38<div class='results-section'> 39 <div class='results-section-title'>$sect_name</div> 40 <div class='results-section-content'> 41 <div id='${short_name}-html'>$html_table</div> 42 <div id='${short_name}-text'><pre>$text_table</pre></div> 43 <div id='${short_name}-tsv'><pre>$tsv_table</pre></div> 44 </div> 45 $tab_menu 46</div> 47""") 48 49def _GetResultsSectionHTML(print_table, table_name, data): 50 first_word = table_name.strip().split()[0] 51 short_name = first_word.lower() 52 return _ResultsSectionHTML.substitute(sect_name=table_name, 53 html_table=print_table(data, 'HTML'), 54 text_table=print_table(data, 'PLAIN'), 55 tsv_table=print_table(data, 'TSV'), 56 tab_menu=_GetTabMenuHTML(short_name), 57 short_name=short_name) 58 59 60 61_MainHTML = Template(""" 62<html> 63<head> 64 <style type="text/css"> 65 body { 66 font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif; 67 font-size: 12px; 68 } 69 70 pre { 71 margin: 10px; 72 color: #039; 73 font-size: 14px; 74 } 75 76 .chart { 77 display: inline; 78 } 79 80 .hidden { 81 visibility: hidden; 82 } 83 84 .results-section { 85 border: 1px solid #b9c9fe; 86 margin: 10px; 87 } 88 89 .results-section-title { 90 background-color: #b9c9fe; 91 color: #039; 92 padding: 7px; 93 font-size: 14px; 94 width: 200px; 95 } 96 97 .results-section-content { 98 margin: 10px; 99 padding: 10px; 100 overflow:auto; 101 } 102 103 #box-table-a { 104 font-size: 12px; 105 width: 480px; 106 text-align: left; 107 border-collapse: collapse; 108 } 109 110 #box-table-a th { 111 padding: 6px; 112 background: #b9c9fe; 113 border-right: 1px solid #fff; 114 border-bottom: 1px solid #fff; 115 color: #039; 116 text-align: center; 117 } 118 119 #box-table-a td { 120 padding: 4px; 121 background: #e8edff; 122 border-bottom: 1px solid #fff; 123 border-right: 1px solid #fff; 124 color: #669; 125 border-top: 1px solid transparent; 126 } 127 128 #box-table-a tr:hover td { 129 background: #d0dafd; 130 color: #339; 131 } 132 133 </style> 134 <script type='text/javascript' src='https://www.google.com/jsapi'></script> 135 <script type='text/javascript'> 136 google.load('visualization', '1', {packages:['corechart']}); 137 google.setOnLoadCallback(init); 138 function init() { 139 switchTab('summary', 'html'); 140 ${perf_init}; 141 switchTab('full', 'html'); 142 drawTable(); 143 } 144 function drawTable() { 145 ${chart_js}; 146 } 147 function switchTab(table, tab) { 148 document.getElementById(table + '-html').style.display = 'none'; 149 document.getElementById(table + '-text').style.display = 'none'; 150 document.getElementById(table + '-tsv').style.display = 'none'; 151 document.getElementById(table + '-' + tab).style.display = 'block'; 152 } 153 </script> 154</head> 155 156<body> 157 $summary_table 158 $perf_html 159 <div class='results-section'> 160 <div class='results-section-title'>Charts</div> 161 <div class='results-section-content'>$chart_divs</div> 162 </div> 163 $full_table 164 $experiment_file 165</body> 166</html> 167""") 168 169# It's a bit ugly that we take some HTML things, and some non-HTML things, but I 170# need to balance prettiness with time spent making things pretty. 171def GenerateHTMLPage(perf_table, chart_js, summary_table, print_table, 172 chart_divs, full_table, experiment_file): 173 """Generates a crosperf HTML page from the given arguments. 174 175 print_table is a two-arg function called like: print_table(t, f) 176 t is one of [summary_table, print_table, full_table]; it's the table we want 177 to format. 178 f is one of ['TSV', 'HTML', 'PLAIN']; it's the type of format we want. 179 """ 180 summary_table_html = _GetResultsSectionHTML(print_table, 'Summary Table', 181 summary_table) 182 if perf_table: 183 perf_html = _GetResultsSectionHTML(print_table, 'Perf Table', perf_table) 184 perf_init = "switchTab('perf', 'html')" 185 else: 186 perf_html = '' 187 perf_init = '' 188 189 full_table_html = _GetResultsSectionHTML(print_table, 'Full Table', 190 full_table) 191 experiment_file_html = _GetExperimentFileHTML(experiment_file) 192 return _MainHTML.substitute(perf_init=perf_init, chart_js=chart_js, 193 summary_table=summary_table_html, 194 perf_html=perf_html, chart_divs=chart_divs, 195 full_table=full_table_html, 196 experiment_file=experiment_file_html) 197