ipn/ipnstate: improve HTML output

Signed-off-by: Sylvain Rabot <sylvain@abstraction.fr>
pull/364/head
Sylvain Rabot 5 years ago committed by Dave Anderson
parent 0c69b4e00d
commit 74d6ab995d

@ -186,15 +186,33 @@ type StatusUpdater interface {
func (st *Status) WriteHTML(w io.Writer) { func (st *Status) WriteHTML(w io.Writer) {
f := func(format string, args ...interface{}) { fmt.Fprintf(w, format, args...) } f := func(format string, args ...interface{}) { fmt.Fprintf(w, format, args...) }
f(`<html><head><style> f(`<!DOCTYPE html>
.owner { font-size: 80%%; color: #444; } <html lang="en">
.tailaddr { font-size: 80%%; font-family: monospace: } <head>
</style></head>`) <title>Tailscale State</title>
f("<body><h1>Tailscale State</h1>") <style>
body { font-family: monospace; }
.owner { text-decoration: underline; }
.tailaddr { font-style: italic; }
.acenter { text-align: center; }
.aright { text-align: right; }
table, th, td { border: 1px solid black; border-spacing : 0; border-collapse : collapse; }
thead { background-color: #FFA500; }
th, td { padding: 5px; }
td { vertical-align: top; }
table tbody tr:nth-child(even) td { background-color: #f5f5f5; }
</style>
</head>
<body>
<h1>Tailscale State</h1>
`)
//f("<p><b>logid:</b> %s</p>\n", logid) //f("<p><b>logid:</b> %s</p>\n", logid)
//f("<p><b>opts:</b> <code>%s</code></p>\n", html.EscapeString(fmt.Sprintf("%+v", opts))) //f("<p><b>opts:</b> <code>%s</code></p>\n", html.EscapeString(fmt.Sprintf("%+v", opts)))
f("<table border=1 cellpadding=5><tr><th>Peer</th><th>Node</th><th>Rx</th><th>Tx</th><th>Handshake</th><th>Endpoints</th></tr>") f("<table>\n<thead>\n")
f("<tr><th>Peer</th><th>Node</th><th>Owner</th><th>Rx</th><th>Tx</th><th>Handshake</th><th>Endpoints</th></tr>\n")
f("</thead>\n<tbody>\n")
now := time.Now() now := time.Now()
@ -224,33 +242,35 @@ func (st *Status) WriteHTML(w io.Writer) {
owner = owner[:i] owner = owner[:i]
} }
} }
f("<tr><td>%s</td><td>%s<div class=owner>%s</div><div class=tailaddr>%s</div></td><td>%v</td><td>%v</td><td>%v</td>", f("<tr><td>%s</td><td>%s %s<br><span class=\"tailaddr\">%s</span></td><td class=\"acenter owner\">%s</td><td class=\"aright\">%v</td><td class=\"aright\">%v</td><td class=\"aright\">%v</td>",
peer.ShortString(), peer.ShortString(),
osEmoji(ps.OS)+" "+html.EscapeString(ps.SimpleHostName()), html.EscapeString(ps.SimpleHostName()),
html.EscapeString(owner), osEmoji(ps.OS),
ps.TailAddr, ps.TailAddr,
html.EscapeString(owner),
ps.RxBytes, ps.RxBytes,
ps.TxBytes, ps.TxBytes,
hsAgo, hsAgo,
) )
f("<td>") f("<td class=\"aright\">")
match := false match := false
for _, addr := range ps.Addrs { for _, addr := range ps.Addrs {
if addr == ps.CurAddr { if addr == ps.CurAddr {
match = true match = true
f("<b>%s</b> 🔗<br>\n", addr) f("🔗 <b>%s</b><br>", addr)
} else { } else {
f("%s<br>\n", addr) f("%s<br>", addr)
} }
} }
if ps.CurAddr != "" && !match { if ps.CurAddr != "" && !match {
f("<b>%s</b> \xf0\x9f\xa7\xb3<br>\n", ps.CurAddr) f("<b>%s</b> \xf0\x9f\xa7\xb3<br>", ps.CurAddr)
} }
f("</tr>") // end Addrs f("</td>") // end Addrs
f("</tr>\n") f("</tr>\n")
} }
f("</table>") f("</tbody>\n</table>\n")
f("</body>\n</html>\n")
} }
func osEmoji(os string) string { func osEmoji(os string) string {

Loading…
Cancel
Save