diff --git a/internal/cli/geoip/geoip.go b/internal/cli/geoip/geoip.go index d4fb28f..0de3620 100644 --- a/internal/cli/geoip/geoip.go +++ b/internal/cli/geoip/geoip.go @@ -1,9 +1,12 @@ package geoip import ( + "fmt" + "github.com/alecthomas/kingpin" "github.com/apex/log" "github.com/ooni/probe-cli/internal/cli/root" + "github.com/ooni/probe-cli/internal/output" "github.com/ooni/probe-cli/utils" ) @@ -13,7 +16,7 @@ func init() { shouldUpdate := cmd.Flag("update", "Update the geoip database").Bool() cmd.Action(func(_ *kingpin.ParseContext) error { - log.Info("geoip") + output.SectionTitle("GeoIP lookup") ctx, err := root.Init() if err != nil { return err @@ -35,7 +38,8 @@ func init() { } log.WithFields(log.Fields{ - "asn": loc.ASN, + "type": "table", + "asn": fmt.Sprintf("AS%d", loc.ASN), "network_name": loc.NetworkName, "country_code": loc.CountryCode, "ip": loc.IP, diff --git a/internal/log/handlers/cli/cli.go b/internal/log/handlers/cli/cli.go index 7985fec..07ca09b 100644 --- a/internal/log/handlers/cli/cli.go +++ b/internal/log/handlers/cli/cli.go @@ -73,6 +73,35 @@ func logSectionTitle(w io.Writer, f log.Fields) error { return nil } +func logTable(w io.Writer, f log.Fields) error { + color := color.New(color.FgBlue) + + names := f.Names() + + var lines []string + colWidth := 0 + for _, name := range names { + if name == "type" { + continue + } + line := fmt.Sprintf("%s: %s", color.Sprint(name), f.Get(name)) + lineLength := escapeAwareRuneCountInString(line) + lines = append(lines, line) + if colWidth < lineLength { + colWidth = lineLength + } + } + + fmt.Fprintf(w, "┏"+strings.Repeat("━", colWidth+2)+"┓\n") + for _, line := range lines { + fmt.Fprintf(w, "┃ %s ┃\n", + RightPad(line, colWidth), + ) + } + fmt.Fprintf(w, "┗"+strings.Repeat("━", colWidth+2)+"┛\n") + return nil +} + var bar *progress.Bar var lastBarChars int64 @@ -88,6 +117,8 @@ func (h *Handler) TypedLog(t string, e *log.Entry) error { bar.Text(e.Message) lastBarChars, err = bar.WriteTo(h.Writer) return err + case "table": + return logTable(h.Writer, e.Fields) case "result_item": return logResultItem(h.Writer, e.Fields) case "result_summary": diff --git a/internal/log/handlers/cli/util.go b/internal/log/handlers/cli/util.go index 41a42e2..07de510 100644 --- a/internal/log/handlers/cli/util.go +++ b/internal/log/handlers/cli/util.go @@ -1,10 +1,22 @@ package cli import ( + "regexp" "strings" "unicode/utf8" ) -func RightPad(str string, length int) string { - return str + strings.Repeat(" ", length-utf8.RuneCountInString(str)) +// Finds the control character sequences (like colors) +var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") + +func escapeAwareRuneCountInString(s string) int { + n := utf8.RuneCountInString(s) + for _, sm := range ctrlFinder.FindAllString(s, -1) { + n -= utf8.RuneCountInString(sm) + } + return n +} + +func RightPad(str string, length int) string { + return str + strings.Repeat(" ", length-escapeAwareRuneCountInString(str)) }