Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sundowndev
GitHub Repository: sundowndev/phoneinfoga
Path: blob/master/lib/output/console.go
994 views
1
package output
2
3
import (
4
"fmt"
5
"github.com/fatih/color"
6
"github.com/sirupsen/logrus"
7
"io"
8
"reflect"
9
"sort"
10
"strings"
11
)
12
13
type ConsoleOutput struct {
14
w io.Writer
15
}
16
17
func NewConsoleOutput(w io.Writer) *ConsoleOutput {
18
return &ConsoleOutput{w: w}
19
}
20
21
func (o *ConsoleOutput) Write(result map[string]interface{}, errs map[string]error) error {
22
succeeded := 0
23
for _, name := range getSortedResultKeys(result) {
24
res := result[name]
25
if res == nil {
26
logrus.WithField("name", name).Debug("Scanner returned result <nil>")
27
continue
28
}
29
_, _ = fmt.Fprintf(o.w, color.WhiteString("Results for %s\n"), name)
30
o.displayResult(res, "")
31
_, _ = fmt.Fprintf(o.w, "\n")
32
succeeded++
33
}
34
35
if len(errs) > 0 {
36
_, _ = fmt.Fprintln(o.w, "The following scanners returned errors:")
37
for _, name := range getSortedErrorKeys(errs) {
38
_, _ = fmt.Fprintf(o.w, "%s: %s\n", name, errs[name])
39
}
40
_, _ = fmt.Fprintf(o.w, "\n")
41
}
42
43
_, _ = fmt.Fprintf(o.w, "%d scanner(s) succeeded\n", succeeded)
44
45
return nil
46
}
47
48
func (o *ConsoleOutput) displayResult(val interface{}, prefix string) {
49
reflectType := reflect.TypeOf(val)
50
reflectValue := reflect.ValueOf(val)
51
52
if reflectValue.Kind() == reflect.Slice {
53
for i := 0; i < reflectValue.Len(); i++ {
54
item := reflectValue.Index(i)
55
if item.Kind() == reflect.Ptr {
56
item = reflectValue.Index(i).Elem()
57
}
58
o.displayResult(item.Interface(), prefix)
59
60
// If it's the latest element, add a newline
61
if i < reflectValue.Len()-1 {
62
_, _ = fmt.Fprintf(o.w, "\n")
63
}
64
}
65
return
66
}
67
68
for i := 0; i < reflectType.NumField(); i++ {
69
valueValue := reflectValue.Field(i).Interface()
70
71
field, ok := reflectType.Field(i).Tag.Lookup("console")
72
if !ok || field == "-" {
73
continue
74
}
75
76
if strings.Contains(field, "omitempty") && reflectValue.Field(i).IsZero() {
77
continue
78
}
79
fieldTitle := strings.Split(field, ",")[0]
80
81
switch reflectValue.Field(i).Kind() {
82
case reflect.String:
83
_, _ = fmt.Fprintf(o.w, "%s%s: ", prefix, fieldTitle)
84
_, _ = fmt.Fprintf(o.w, color.YellowString("%s\n"), valueValue)
85
case reflect.Bool:
86
_, _ = fmt.Fprintf(o.w, "%s%s: ", prefix, fieldTitle)
87
_, _ = fmt.Fprintf(o.w, color.YellowString("%v\n"), valueValue)
88
case reflect.Int:
89
_, _ = fmt.Fprintf(o.w, "%s%s: ", prefix, fieldTitle)
90
_, _ = fmt.Fprintf(o.w, color.YellowString("%d\n"), valueValue)
91
case reflect.Struct:
92
_, _ = fmt.Fprintf(o.w, "%s%s:\n", prefix, fieldTitle)
93
o.displayResult(valueValue, prefix+"\t")
94
case reflect.Slice:
95
_, _ = fmt.Fprintf(o.w, color.WhiteString("%s:\n"), fieldTitle)
96
o.displayResult(valueValue, prefix+"\t")
97
}
98
}
99
}
100
101
func getSortedResultKeys(m map[string]interface{}) []string {
102
keys := make([]string, 0, len(m))
103
for k := range m {
104
keys = append(keys, k)
105
}
106
sort.Strings(keys)
107
return keys
108
}
109
110
func getSortedErrorKeys(m map[string]error) []string {
111
keys := make([]string, 0, len(m))
112
for k := range m {
113
keys = append(keys, k)
114
}
115
sort.Strings(keys)
116
return keys
117
}
118
119