Skip to content

Commit e6e59c0

Browse files
committed
cmd/get: add get command
For the moment, grabs c2 families.
1 parent be6a77b commit e6e59c0

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

cmd/get/get.go

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Package get implements the get command.
2+
package get
3+
4+
import (
5+
"flag"
6+
"fmt"
7+
"os"
8+
"strings"
9+
"text/tabwriter"
10+
"time"
11+
12+
"github.com/alphasoc/flightsim/wisdom"
13+
)
14+
15+
var Version string
16+
17+
var usage = `usage: flightsim get [flags] element:category
18+
19+
Available elements:
20+
21+
%s
22+
23+
Available categories:
24+
25+
%s
26+
27+
Available flags:
28+
`
29+
30+
// printWelcome prints a basic welcome banner.
31+
func printWelcome() {
32+
fmt.Printf(`
33+
AlphaSOC Network Flight Simulator™ %s (https://github.com/alphasoc/flightsim)
34+
The current time is %s
35+
`, Version, time.Now().Format("02-Jan-06 15:04:05"))
36+
}
37+
38+
// printGoodbye prints a parting message.
39+
func printGoodbye() {
40+
fmt.Printf("\nAll done!\n")
41+
}
42+
43+
// printMsg prints msg, decorated with an info string and the current date/time.
44+
func printMsg(info string, msg string) {
45+
if msg == "" {
46+
return
47+
}
48+
fmt.Printf("%s [%s] %s\n", time.Now().Format("15:04:05"), info, msg)
49+
}
50+
51+
// We only know how to get families for now.
52+
var supportedElementsMap = map[string]bool{
53+
"families": true,
54+
}
55+
56+
// supportedElements returns a slice of fetchable elements.
57+
func supportedElements() []string {
58+
var elements []string
59+
for e := range supportedElementsMap {
60+
elements = append(elements, e)
61+
}
62+
return elements
63+
}
64+
65+
// Taken from open-wisdom/server/entries/entries.go.
66+
// TODO: would be good to fetch these also.
67+
var supportedCategoriesMap = map[string]bool{
68+
"c2": true,
69+
}
70+
71+
// supportedCategories returns a slice of fetchable categories.
72+
func supportedCategories() []string {
73+
var categories []string
74+
for e := range supportedCategoriesMap {
75+
categories = append(categories, e)
76+
}
77+
return categories
78+
}
79+
80+
// computeFormatStr returns a format string to be used with column printing.
81+
func computeFormatStr(cols int) string {
82+
fmtStr := "\n"
83+
for i := 0; i < cols; i++ {
84+
fmtStr += "%v\t"
85+
}
86+
return fmtStr
87+
}
88+
89+
// printCol prints elements in cols columns.
90+
func printCol(elements []string, cols int) {
91+
w := new(tabwriter.Writer)
92+
// Min width, tab width, padding, pad char, flags.
93+
w.Init(os.Stdout, 8, 8, 1, '\t', 0)
94+
// Compute format string.
95+
fmtStr := computeFormatStr(cols)
96+
// Convert elements ([]string) to []interface{}.
97+
elementsToPrint := make([]interface{}, len(elements))
98+
for i, v := range elements {
99+
elementsToPrint[i] = v
100+
}
101+
// Print.
102+
i := 0
103+
lenElementsToPrint := len(elementsToPrint)
104+
for leftToPrint := lenElementsToPrint; leftToPrint > 0; {
105+
// We don't have enough elements left to print to satisfy the format string,
106+
// or the re-slice. Thus, reset *cols and recompute the format string.
107+
if leftToPrint < cols {
108+
cols = leftToPrint
109+
fmtStr = computeFormatStr(cols)
110+
}
111+
fmt.Fprintf(w, fmtStr, elementsToPrint[i:i+cols]...)
112+
// Move by number of columns.
113+
i += cols
114+
leftToPrint = lenElementsToPrint - i
115+
}
116+
// Append a blank line.
117+
fmt.Fprintf(w, "%v", "\n\n")
118+
w.Flush()
119+
}
120+
121+
// RunCmd runs the 'get' command and returns an error.
122+
func RunCmd(args []string) error {
123+
printWelcome()
124+
// Mirrors look of run command.
125+
fmt.Println("")
126+
cmdLine := flag.NewFlagSet("get", flag.ExitOnError)
127+
// TODO: replace cols with -format (issue #45).
128+
// cols := cmdLine.Int("cols", 0, "print elements in number of columns")
129+
cmdLine.Usage = func() {
130+
fmt.Fprintf(cmdLine.Output(), usage, strings.Join(supportedElements(), ", "), strings.Join(supportedCategories(), ", "))
131+
cmdLine.PrintDefaults()
132+
}
133+
cmdLine.Parse(args)
134+
// Next arg should be element:category (ie. families:c2)
135+
toGet := cmdLine.Arg(0)
136+
if len(toGet) == 0 {
137+
return fmt.Errorf("nothing to get")
138+
}
139+
toGetArr := strings.Split(cmdLine.Arg(0), ":")
140+
if len(toGetArr) != 2 {
141+
return fmt.Errorf("unable to get '%v': invalid format", toGet)
142+
}
143+
elem := toGetArr[0]
144+
cat := toGetArr[1]
145+
// infoTag == "element:category" (ie. families:c2). Mirrors the run command.
146+
infoTag := cmdLine.Arg(0)
147+
var elements []string
148+
var err error
149+
switch elem {
150+
case "families":
151+
printMsg(infoTag, fmt.Sprintf("Fetching %v %v", cat, elem))
152+
elements, err = wisdom.Families(cat)
153+
if err != nil {
154+
return err
155+
}
156+
default:
157+
return fmt.Errorf("unable to get '%v': unsupported element '%v'", toGet, elem)
158+
}
159+
// TODO: Leave quotes in for later cut/paste?
160+
for i := 0; i < len(elements); i++ {
161+
elements[i] = strings.Trim(elements[i], "\"")
162+
}
163+
// Default is to print in a single line. Otherwise, column print.
164+
// if *cols <= 0 {
165+
// printMsg(infoTag, strings.Join(elements, ", "))
166+
// } else {
167+
// printCol(elements, *cols)
168+
// }
169+
printMsg(infoTag, strings.Join(elements, ", "))
170+
171+
printMsg(infoTag, fmt.Sprintf("Fetched %v %v %v", len(elements), cat, elem))
172+
printGoodbye()
173+
return nil
174+
}

0 commit comments

Comments
 (0)