syzkaller/pkg/html/html.go
Dmitry Vyukov 13ab4beeef syz-manager: modernize web UI
1. Use dashboard style.
2. Allow sorting of tables.
3. Show old crashes in grey.
4. Use tables instead of text output for more pages.
5. Show corpus inputs on a separate page to allow copy-pasting.
6. Use standard JS sorting instead of custom bubble sort (much faster).
7. Fix off-by one in table sorting.

Fixes #694
2018-11-22 14:36:32 +01:00

111 lines
2.6 KiB
Go

// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
//go:generate bash -c "echo '// AUTOGENERATED FILE' > generated.go"
//go:generate bash -c "echo 'package html' > generated.go"
//go:generate bash -c "echo 'const style = `' >> generated.go"
//go:generate bash -c "cat ../../dashboard/app/static/style.css >> generated.go"
//go:generate bash -c "echo '`' >> generated.go"
//go:generate bash -c "echo 'const js = `' >> generated.go"
//go:generate bash -c "cat ../../dashboard/app/static/common.js >> generated.go"
//go:generate bash -c "echo '`' >> generated.go"
package html
import (
"fmt"
"html/template"
"strings"
"time"
"github.com/google/syzkaller/dashboard/dashapi"
)
func CreatePage(page string) *template.Template {
const headTempl = `<style type="text/css" media="screen">%v</style><script>%v</script>`
page = strings.Replace(page, "{{HEAD}}", fmt.Sprintf(headTempl, style, js), 1)
return template.Must(template.New("").Funcs(funcs).Parse(page))
}
func CreateGlob(glob string) *template.Template {
return template.Must(template.New("").Funcs(funcs).ParseGlob(glob))
}
var funcs = template.FuncMap{
"formatTime": FormatTime,
"formatClock": formatClock,
"formatDuration": formatDuration,
"formatLateness": formatLateness,
"formatReproLevel": formatReproLevel,
"formatStat": formatStat,
"formatShortHash": formatShortHash,
}
func FormatTime(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("2006/01/02 15:04")
}
func formatClock(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("15:04")
}
func formatDuration(d time.Duration) string {
if d == 0 {
return ""
}
days := int(d / (24 * time.Hour))
hours := int(d / time.Hour % 24)
mins := int(d / time.Minute % 60)
if days >= 10 {
return fmt.Sprintf("%vd", days)
} else if days != 0 {
return fmt.Sprintf("%vd%02vh", days, hours)
} else if hours != 0 {
return fmt.Sprintf("%vh%02vm", hours, mins)
}
return fmt.Sprintf("%vm", mins)
}
func formatLateness(now, t time.Time) string {
if t.IsZero() {
return "never"
}
d := now.Sub(t)
if d < 5*time.Minute {
return "now"
}
return formatDuration(d)
}
func formatReproLevel(l dashapi.ReproLevel) string {
switch l {
case dashapi.ReproLevelSyz:
return "syz"
case dashapi.ReproLevelC:
return "C"
default:
return ""
}
}
func formatStat(v int64) string {
if v == 0 {
return ""
}
return fmt.Sprint(v)
}
func formatShortHash(v string) string {
const hashLen = 8
if len(v) <= hashLen {
return v
}
return v[:hashLen]
}