Signed-off-by: Timothy Gu <timothyg...@gmail.com> --- FATE.pm | 130 ++++++++++++++++++++++++++++++++++++++++---------- fate.css | 154 ++++++++++++++---------------------------------------------- history.cgi | 32 +++---------- index.cgi | 117 ++++++++++++++++++++++++--------------------- report.cgi | 46 ++++++------------ 5 files changed, 226 insertions(+), 253 deletions(-)
diff --git a/FATE.pm b/FATE.pm index 806168d..544e80f 100644 --- a/FATE.pm +++ b/FATE.pm @@ -27,7 +27,8 @@ BEGIN { @ISA = qw/Exporter/; @EXPORT = qw/split_header split_config split_rec parse_date agestr split_stats load_summary load_report load_lastpass - doctype start end tag h1 span trow trowa trowh th td anchor navbar + start end tag h1 span trow trowa trowh th td anchor + head1 head2 head3 footer fail $fatedir $recent_age $ancient_age $hidden_age href $gitweb/; } @@ -199,10 +200,6 @@ $block_tags{$_} = 1 for @block_tags; my @tags; -sub doctype { - print q{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">}, "\n"; -} - sub opentag { my ($tag, %attrs) = @_; print qq{<$tag}; @@ -301,35 +298,116 @@ sub href { } } -sub navbar { +sub head1 { + print <<EOF; +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> +EOF +} + +sub head2 { # Copied from ffmpeg-web print <<EOF; -<div id="banner"> -<a href="//ffmpeg.org/index.html"> -<img src="//ffmpeg.org/ffmpeg-logo.png" alt="FFmpeg" /> -</a> -</div> -<div id="navbar"> -<a href="//ffmpeg.org/index.html">News</a> | -<a href="//ffmpeg.org/about.html">About</a> | -<a href="//ffmpeg.org/download.html">Download</a> | -<a href="//ffmpeg.org/documentation.html">Documentation</a> | -<a href="//ffmpeg.org/bugreports.html">Bug Reports</a> | -<a href="//ffmpeg.org/contact.html">Contact</a> | -<a href="//ffmpeg.org/donations.html">Donations</a> | -<a href="//ffmpeg.org/consulting.html">Consulting</a> | -<a href="//ffmpeg.org/projects.html">Projects</a> | -<a href="//ffmpeg.org/legal.html">Legal</a> | -<a href="//ffmpeg.org/security.html">Security</a> | -<a href="http://fate.ffmpeg.org">FATE</a> -</div> + <link rel="stylesheet" href="https://ffmpeg.org/css/font-awesome.min.css" /> + <link rel="stylesheet" href="https://ffmpeg.org/css/bootstrap.min.css" /> + <link rel="stylesheet" href="https://ffmpeg.org/css/simple-sidebar.css" /> + <link rel="stylesheet" href="https://ffmpeg.org/css/style.min.css" /> + <link rel="stylesheet" href="/fate.css" /> + <meta name="viewport" content="width=device-width,initial-scale=1.0"> + <!--[if lt IE 9]> + <script src="https://ffmpeg.org/js/html5shiv.min.js"></script> + <script src="https://ffmpeg.org/js/respond.min.js"></script> + <![endif]--> + + <link rel="shortcut icon" href="https://ffmpeg.org/favicon.ico" /> + </head> + <body> + + <div id="wrapper"> + + <nav id="sidebar-wrapper"> + <ul class="sidebar-nav"> + <li class="sidebar-brand"><a href="."> + <img src="https://ffmpeg.org/img/ffmpeg3d_white_20.png" alt="FFmpeg" /> + FFmpeg</a> + </li> + <li><a href="https://ffmpeg.org/about.html">About</a></li> + <li><a href="https://ffmpeg.org/index.html#news">News</a></li> + <li><a href="https://ffmpeg.org/download.html">Download</a></li> + <li><a href="https://ffmpeg.org/documentation.html">Documentation</a></li> + <li><a href="https://ffmpeg.org/contact.html#MailingLists">Community</a> + <ul> + <li><a href="https://ffmpeg.org/contact.html#MailingLists">Mailing Lists</a></li> + <li><a href="https://ffmpeg.org/contact.html#IRCChannels">IRC</a></li> + <li><a href="https://ffmpeg.org/contact.html#Forums">Forums</a></li> + <li><a href="https://ffmpeg.org/bugreports.html">Bug Reports</a></li> + <li><a href="http://trac.ffmpeg.org">Wiki</a></li> + </ul> + </li> + <li><a href="#">Developers</a> + <ul> + <li><a href="https://ffmpeg.org/download.html#get-sources">Source Code</a> + <li><a href="/">FATE</a></li> + <li><a href="http://coverage.ffmpeg.org">Code Coverage</a></li> + </ul> + </li> + <li><a href="#">More</a> + <ul> + <li><a href="https://ffmpeg.org/donations.html"> + Donate<span style="color: #e55; font-size: 0.8em; margin-left: -10px"><i class="fa fa-heart"></i></span></a></li> + <li><a href="https://ffmpeg.org/consulting.html">Hire Developers</a></li> + <li><a href="https://ffmpeg.org/contact.html">Contact</a></li> + <li><a href="https://ffmpeg.org/security.html">Security</a></li> + <li><a href="https://ffmpeg.org/legal.html">Legal</a></li> + </ul> + </li> + </ul> + </nav> + + <div id="page-content-wrapper"> + <header class="content-header"> + <h1> + <a id="menu-toggle" href="#" class="btn btn-success"><i class="fa fa-reorder"></i></a> +EOF +} + +sub head3 { + print <<EOF; + </h1> + </header> + <div class="page-content inset"> +EOF +} + +sub footer { + print <<EOF + </div> <!-- page-content-inset --> + </div> <!-- page-content-wrapper --> + </div> <!-- wrapper --> + + <script src="https://ffmpeg.org/js/jquery.min.js"></script> + <script src="https://ffmpeg.org/js/bootstrap.min.js"></script> + + <!-- Custom JavaScript for the Menu Toggle --> + <script> + \$("#menu-toggle").click(function(e) { + e.preventDefault(); + \$("#wrapper").toggleClass("active"); + }); + </script> + + </body> +</html> + EOF } sub fail { my ($msg) = @_; print "Content-type: text/html\r\n\r\n"; - doctype; + print "<!DOCTYPE html>\n"; start 'html', xmlns => "http://www.w3.org/1999/xhtml"; start 'head'; tag 'meta', 'http-equiv' => "Content-Type", diff --git a/fate.css b/fate.css index 3a83511..cd73f6b 100644 --- a/fate.css +++ b/fate.css @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Mans Rullgard <m...@mansr.com> + * Copyright (c) 2014 Tiancheng "Timothy" Gu <timothyg...@gmail.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,41 +15,38 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -table { - border-collapse: collapse; -} - -th { - background: #ccc; - padding: 0.5em; -} - .recent { font-weight: bold; } .ancient { color: #888; } -.fail { background: #e44; } -.pass { background: #5e5; } -.warn { background: #ff3; } +.fail { + background: #d9534f !important; + color: white; +} +.pass { + background: #5cb85c !important; + color: white; +} +.warn { + background: #ecd046 !important; + color: black; +} -.alert { color: #911; } +.fate-alert { color: #911; } .rejoice { color: #191; } #failometer { padding: 0; } -#failometer span { - display: inline-block; +#failometer .progress { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + margin-bottom: inherit; } /* index and history listings */ -#index > tbody > tr > td, #history > tbody > tr > td { - height: 1.7em; -} - .replist { - border: solid 1px #eee; width: 100%; } @@ -57,54 +55,8 @@ th { text-decoration: none; } -.replist tr { - border-left: solid 1px #eee; - border-right: solid 1px #eee; -} - -.replist th { - border: solid 1px #eee; -} - -.replist td { - border: solid 1px #eee; - padding: 0 0.5em; -} - -.replist tr.alt:nth-child(odd) { - background: white; -} - -.replist tr.alt:nth-child(even) { - background: #eee; -} - -.replist tr.alt:nth-child(odd) td { - border-color: #eee; -} - -.replist tr.alt:nth-child(even) td { - border-color: white; -} - -.replist tr.alt:nth-child(even) td:first-child { - border-left: solid 1px #eee; -} - -.replist tr:nth-child(n) td:last-child { - border-right: solid 1px #eee; -} - -.replist tr.hilight:hover { - background: #ddf; -} - -.replist tr.hilight:hover td { - border-color: white; -} - th a:link, th a:visited { - color: black; + color: inherit; text-decoration: none; } @@ -114,35 +66,14 @@ th a:hover { #index .comment { max-width: 13em; } -#index .warnleft { border-right: none; } -#index .warnright { border-left: none; } -#index .warnright a { text-decoration: none; } - -#index .resleft { - border-left: solid 1px white; - border-right: none; -} - -#index .resright { - border-left: none; - border-right: solid 1px #eee; - width: 1em; -} - #index .toggle { cursor: pointer; - text-align: center; - color: black; } tr.slotfail { display: none; } -tr.slotfail > td { - padding: 0.5em; -} - table.minirep { width: 100%; } @@ -152,12 +83,6 @@ table.minirep { text-align: left; } -.minilog { - border: solid 1px #eee; - padding: 0.5em; - margin: 0; -} - /* config summary */ #config td:first-child { @@ -169,17 +94,19 @@ table.minirep { /* test listing */ #tests { - border: solid 1px #eee; margin-top: 2em; width: 100%; } -#tests th { - text-align: left; +#tests .fail th { + background: #d9534f; + border-bottom: 2px solid #fcc; } -#tests .fail th { - background: #e44; +#tests .pass th { + background: #5cb85c; + border-bottom: 2px solid #9f9; + border-top: 0; } #tests .toggle { @@ -197,35 +124,26 @@ table.minirep { width: 12em; } -#tests tr:only-child th { - border: solid 1px #eee; -} - .diff { - font-family: monospace; - white-space: pre-wrap; display: none; } -.diff-new { +.diff-new, .diff-old, .diff-hnk { font-weight: bold; - color: #262; } -.diff-old { - font-weight: bold; - color: #622; +.diff-new, .diff-add { + color: #4cae4c; } -.diff-hnk { - font-weight: bold; - color: #226; +.diff-old, .diff-del { + color: #d9534f; } -.diff-add { - color: #262; +.diff-hnk { + color: #226; } -.diff-del { - color: #622; -} +code, pre { + white-space: pre-wrap; +} \ No newline at end of file diff --git a/history.cgi b/history.cgi index b2ed52f..cb6f71c 100755 --- a/history.cgi +++ b/history.cgi @@ -35,30 +35,14 @@ close D; print "Content-type: text/html\r\n\r\n"; -doctype; -start 'html', xmlns => "http://www.w3.org/1999/xhtml"; -start 'head'; -tag 'meta', 'http-equiv' => "Content-Type", - 'content' => "text/html; charset=utf-8"; -tag 'link', rel => 'stylesheet', - type => 'text/css', - href => '//ffmpeg.org/default.css'; -tag 'link', rel => 'stylesheet', - type => 'text/css', - href => '/fate.css'; +head1; print "<title>FATE: $slot</title>\n"; -end 'head'; +head2; +print "Report history for $slot"; +head3; -start 'body'; -start 'div', id => 'container'; - -navbar; - -start 'div', id => 'body'; - -h1 "Report history for $slot"; - -start 'table', id => 'history', class => 'replist'; +start 'div', class => 'table-responsive'; +start 'table', id => 'history', class => 'replist table'; start 'thead'; trowh 'Time', 'Rev', 'Arch', 'OS', 'Compiler', 'Warnings', 'Tests'; end 'thead'; @@ -104,6 +88,4 @@ for my $date ((sort { $b cmp $a } @reps)[0..49]) { end 'tbody'; end 'table'; end 'div'; -end 'div'; -end 'body'; -end 'html'; +footer; diff --git a/index.cgi b/index.cgi index 7204591..105cb86 100755 --- a/index.cgi +++ b/index.cgi @@ -1,6 +1,7 @@ #! /usr/bin/perl # # Copyright (c) 2011 Mans Rullgard <m...@mansr.com> +# Copyright (c) 2014 Tiancheng "Timothy" Gu <timothyg...@gmail.com> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -164,6 +165,7 @@ sub category { } print "Content-type: text/html\r\n"; +print "Access-Control-Allow-Origin: https://ffmpeg.org\r\n"; if ($ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/) { print "Content-Encoding: gzip\r\n\r\n"; @@ -172,17 +174,7 @@ if ($ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/) { print "\r\n"; } -doctype; -start 'html', xmlns => "http://www.w3.org/1999/xhtml"; -start 'head'; -tag 'meta', 'http-equiv' => "Content-Type", - 'content' => "text/html; charset=utf-8"; -tag 'link', rel => 'stylesheet', - type => 'text/css', - href => '//ffmpeg.org/default.css'; -tag 'link', rel => 'stylesheet', - type => 'text/css', - href => '/fate.css'; +head1; print "<title>FATE</title>\n"; print <<EOF; <script type="text/javascript"> @@ -190,24 +182,19 @@ print <<EOF; var e = document.getElementById(id); if (e.style.display == 'table-row') { e.style.display = 'none'; - arr.textContent = '\\u25b6' + arr.classList.remove("fa-caret-up"); + arr.classList.add("fa-caret-down"); } else { e.style.display = 'table-row'; - arr.textContent = '\\u25bc' + arr.classList.add("fa-caret-up"); + arr.classList.remove("fa-caret-down"); } } </script> EOF -end 'head'; - -start 'body'; -start 'div', id => 'container'; - -navbar; - -start 'div', id => 'body'; - -h1 'FATE'; +head2; +print "FATE\n"; +head3; if (@queries) { start 'p'; @@ -220,13 +207,34 @@ if (@queries) { end 'p'; } -start 'table', id => 'index', class => 'replist'; +start 'div', class => 'table-responsive'; +start 'table', id => 'index', class => 'replist table'; start 'thead'; start 'tr'; -start 'td', colspan => 10, id => 'failometer'; -span ' ', class => 'pass', style => "width: ${allpass}%" if $allpass; -span ' ', class => 'warn', style => "width: ${warn}%" if $warn; -span ' ', class => 'fail', style => "width: ${allfail}%" if $allfail; +start 'td', colspan => 8, id => 'failometer'; +start 'div', class => 'progress'; +if ($allpass) { + print <<EOF; +<div class="progress-bar pass" role="progressbar" title="${allpass}% tests passed" aria-valuenow="${allpass}" aria-valuemin="0" aria-valuemax="100" style="width: ${allpass}%"> + <span class="sr-only">${allpass}%}</span> +</div> +EOF +} +if ($warn) { + print <<EOF; +<div class="progress-bar warn" role="progressbar" title="${warn}% tests failed" aria-valuenow="${warn}" aria-valuemin="0" aria-valuemax="100" style="width: ${warn}%"> + <span class="sr-only">${warn}%</span> +</div> +EOF +} +if ($allfail) { + print <<EOF; +<div class="progress-bar fail" role="progressbar" title="${allfail}% build failed" aria-valuenow="${allfail}" aria-valuemin="0" aria-valuemax="100" style="width: ${allfail}%"> + <span class="sr-only">${allfail}%</span> +</div> +EOF +} +end 'div'; end 'td'; end 'tr'; start 'tr'; @@ -236,8 +244,8 @@ start 'th'; lsort 'Arch', 'arch'; end 'th'; start 'th'; lsort 'OS', 'os'; end 'th'; start 'th'; lsort 'Compiler', 'cc'; end 'th'; start 'th'; lsort 'Comment', 'comment'; end 'th'; -start 'th', colspan => 2; lsort 'Warnings', 'nwarn'; end 'th'; -start 'th', colspan => 2; lsort 'Tests', 'npass'; end 'th'; +start 'th'; lsort 'Warnings', 'nwarn'; end 'th'; +start 'th'; lsort 'Tests', 'npass'; end 'th'; end 'tr'; end 'thead'; start 'tbody'; @@ -251,8 +259,8 @@ for my $rep (sort repcmp @reps) { my $rtext; my $rclass; my $log; - my $alert = ('rejoice', '', 'alert')[$$rep{alert} + 1]; - my $walert = ('rejoice', '', 'alert')[$$rep{dwarn} + 1]; + my $alert = ('pass', '', 'warn')[$$rep{alert} + 1]; + my $walert = ('pass', '', 'warn')[$$rep{dwarn} + 1]; (my $slotid = $$rep{slot}) =~ s/[^a-z0-9_-]/_/ig; if ($age < $recent_age) { @@ -262,7 +270,7 @@ for my $rep (sort repcmp @reps) { $alert = ''; } - start 'tr', class => "$ageclass $alert alt hilight"; + start 'tr', class => "$ageclass $alert"; start 'td'; anchor $agestr, href => href slot => $$rep{slot}; end 'td'; @@ -295,32 +303,38 @@ for my $rep (sort repcmp @reps) { } } } - start 'td', class => 'warnleft'; - anchor $$rep{nwarn}, class => $walert, - href => href slot => $$rep{slot}, time => $$rep{date}, log => 'compile'; + start 'td', class => "$walert"; + start 'div', class => 'pull-left'; + anchor $$rep{nwarn}, + href => href slot => $$rep{slot}, time => $$rep{date}, log => 'compile'; end; - start 'td', class => 'warnright'; - anchor '±', class => $walert, - href => href slot => $$rep{slot}, time => $$rep{date}, + start 'div', class => 'pull-right'; + anchor '±', + href => href slot => $$rep{slot}, time => $$rep{date}, log => "compile/$$rep{pdate}"; end; - start 'td', class => "$rclass resleft"; + end; + start 'td', class => "$rclass"; + start 'div', class => 'pull-left'; anchor $rtext, href => href slot => $$rep{slot}, time => $$rep{date}; - end 'td'; - start 'td', class => "$rclass resright"; + end; if ($npass < $ntest or $log) { - span '▶', class => 'toggle', onclick => "toggle('$slotid', this)"; + start 'div', class => 'pull-right'; + span '', class => 'toggle fa fa-caret-down', onclick => "toggle('$slotid', this)"; + end; } - end 'td'; + end; end 'tr'; print "\n"; if ($npass < $ntest && $ntest - $npass < 100) { + trowa { style => 'display: none' }, ''; + print "\n"; my $report = load_report $$rep{slot}, $$rep{date}; my @fail = grep $$_{status} ne '0', @{$$report{recs}}; my $lastpass = load_lastpass $$rep{slot}; start 'tr', id => $slotid, class => 'slotfail'; - start 'td', colspan => 10; + start 'td', colspan => 8; start 'table', class => 'minirep'; start 'thead'; start 'tr'; @@ -335,8 +349,8 @@ for my $rep (sort repcmp @reps) { start 'tbody'; for (sort { $$a{name} cmp $$b{name} } @fail) { my $falert = $$rep{pdate} eq $$lastpass{$$_{name}}{date} ? - 'alert' : ''; - start 'tr', class => "alt hilight $falert"; + 'warn' : ''; + start 'tr', class => "$falert"; td $$_{name}; td $$_{status}, class => 'errcode'; end 'tr'; @@ -346,21 +360,18 @@ for my $rep (sort repcmp @reps) { end 'td'; end 'tr'; print "\n"; - trowa { style => 'display: none' }, ''; } elsif ($log) { + trowa { style => 'display: none' }, ''; start 'tr', id => $slotid, class => 'slotfail'; - start 'td', colspan => 10; + start 'td', colspan => 8; start 'pre', class => 'minilog'; print encode_entities($log, '<>&"'); end 'pre'; end 'td'; end 'tr'; - trowa { style => 'display: none' }, ''; } } end 'tbody'; end 'table'; end 'div'; -end 'div'; -end 'body'; -end 'html'; +footer; diff --git a/report.cgi b/report.cgi index 2176dde..92e9fba 100755 --- a/report.cgi +++ b/report.cgi @@ -70,17 +70,7 @@ if ($ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/) { print "\r\n"; } -doctype; -start 'html', xmlns => "http://www.w3.org/1999/xhtml"; -start 'head'; -tag 'meta', 'http-equiv' => "Content-Type", - 'content' => "text/html; charset=utf-8"; -tag 'link', rel => 'stylesheet', - type => 'text/css', - href => '//ffmpeg.org/default.css'; -tag 'link', rel => 'stylesheet', - type => 'text/css', - href => '/fate.css'; +head1; print "<title>FATE: $$hdr{slot} $$hdr{rev}</title>\n"; print <<EOF; <script type="text/javascript"> @@ -102,16 +92,9 @@ print <<EOF; } </script> EOF -end 'head'; - -start 'body'; -start 'div', id => 'container'; - -navbar; - -start 'div', id => 'body'; - -h1 "$$hdr{slot} $$hdr{rev}", id => 'title'; +head2; +print "$$hdr{slot} $$hdr{rev}"; +head3; start 'table', id => 'config'; trow 'Architecture', $$conf{arch}; @@ -120,7 +103,7 @@ trow 'CPU', $$conf{cpu}; trow 'OS', $$conf{os}; trow 'Owner', $owner if $owner; trow 'Compiler', $$conf{cc}; -trow 'Configuration', $$conf{config}; +trow 'Configuration', '<code>' . $$conf{config} . '</code>'; trow 'Comment', $$hdr{comment}; start 'tr'; td 'Revision'; @@ -147,7 +130,8 @@ end 'td'; end 'tr'; end; -start 'table', id => 'tests', class => 'replist'; +start 'div', class => 'table-responsive'; +start 'table', id => 'tests', class => 'table'; if ($nfail) { start 'thead'; start 'tr', class => 'fail'; @@ -197,23 +181,23 @@ if ($nfail) { td $$lastpass{$n}? $$lastpass{$n}{rev} : 'n / a'; } end 'tr'; + trowa { style => 'display: none' }, ''; # nee start 'tr', id => "$test-diff", class => 'diff'; - td $diff, colspan => 5; + td "<pre>$diff</pre>", colspan => 5; end 'tr'; + trowa { style => 'display: none' }, ''; start 'tr', id => "$test-err", class => 'diff'; - td $err, colspan => 5; + td "<pre>$err</pre>", colspan => 5; end 'tr'; } end 'tbody'; } elsif ($ntest) { - start 'tr'; th 'All tests successful', colspan => 3, class => 'pass'; end; + start 'tr', class => 'pass'; th 'All tests successful', colspan => 3; end; } else { my $class = $$hdr{status}? 'fail' : 'pass'; - start 'tr'; th 'No tests were run', colspan => 3, class => $class; end; + start 'tr', class => $class; th 'No tests were run', colspan => 3; end; } end 'table'; - -end 'div'; end 'div'; -end 'body'; -end 'html'; + +footer; -- 1.9.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel