From 54e8351a0abac8a1969927fd7ca2db1899b3bb34 Mon Sep 17 00:00:00 2001 From: hanemile Date: Thu, 10 Jan 2019 22:25:16 +0100 Subject: created some kind of command line utility --- shell/shell.go | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 shell/shell.go (limited to 'shell/shell.go') diff --git a/shell/shell.go b/shell/shell.go new file mode 100644 index 0000000..1b629df --- /dev/null +++ b/shell/shell.go @@ -0,0 +1,334 @@ +package main + +import ( + "bytes" + "encoding/csv" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "strconv" + "strings" + + "github.com/marcusolsson/tui-go" + + "git.darknebu.la/GalaxySimulator/db-container/shell/structs" +) + +func main() { + parameters := structs.NewEnv("localhost:8042", "data.csv", 10, 0) + boundary := structs.NewBoundary(0, 0, 4000) + + // define the history box displayed in the top part of the window + history := tui.NewVBox() + historyScroll := tui.NewScrollArea(history) + historyScroll.SetAutoscrollToBottom(true) + historyBox := tui.NewVBox(historyScroll) + historyBox.SetBorder(true) + + // define the input bar displayed on the bottom window edge + input := tui.NewEntry() + input.SetFocused(true) + input.SetSizePolicy(tui.Expanding, tui.Maximum) + inputBox := tui.NewHBox(input) + inputBox.SetBorder(true) + inputBox.SetSizePolicy(tui.Expanding, tui.Maximum) + + // define a root container containing all the containers and maximizing them in the given space + root := tui.NewVBox(historyBox, inputBox) + root.SetSizePolicy(tui.Expanding, tui.Expanding) + + // on submission of the input box, add the text to the history box + input.OnSubmit(func(e *tui.Entry) { + + // add the input to the history + history.Append(tui.NewHBox(tui.NewLabel(e.Text()))) + handleInput(history, e.Text(), parameters, boundary) + input.SetText("") + }) + + ui, err := tui.New(root) + if err != nil { + panic(err) + } + + ui.SetKeybinding("Esc", func() { ui.Quit() }) + + if err := ui.Run(); err != nil { + panic(err) + } +} + +func faultyInput(history *tui.Box) { + // print an error message if the input cannot be assigned to an action + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "", "Faulty Input!")), + ), + ) +} + +func printEnvironment(history *tui.Box, parameters *structs.Env) { + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30s", "", "url", parameters.Url())), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30s", "", "data", parameters.Data())), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30d", "", "amount", parameters.Amount())), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30d", "", "treeindex", parameters.Treeindex())), + ), + ) +} + +func printBoundary(history *tui.Box, boundary *structs.Boundary) { + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30d", "", "x", boundary.X())), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30d", "", "y", boundary.Y())), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-15s%-30d", "", "width", boundary.Width())), + ), + ) +} + +func setEnvironment(history *tui.Box, parameters *structs.Env, key string, value string) { + switch key { + case "url": + parameters.SetUrl(value) + break + case "data": + parameters.SetData(value) + break + case "amount": + valueInt, _ := strconv.ParseInt(value, 10, 64) + parameters.SetAmount(valueInt) + break + case "treeindex": + valueInt, _ := strconv.ParseInt(value, 10, 64) + parameters.SetTreeindex(valueInt) + break + default: + faultyInput(history) + } +} + +func setBoundary(history *tui.Box, boundary *structs.Boundary, key string, value string) { + switch key { + case "x": + valueInt, _ := strconv.ParseInt(value, 10, 64) + boundary.SetX(valueInt) + break + case "y": + valueInt, _ := strconv.ParseInt(value, 10, 64) + boundary.SetY(valueInt) + break + case "width": + valueInt, _ := strconv.ParseInt(value, 10, 64) + boundary.SetWidth(valueInt) + break + default: + faultyInput(history) + } +} + +func handleInput(history *tui.Box, input string, parameters *structs.Env, boundary *structs.Boundary) { + if input == "help" { + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-35s%-30s", "", "print ", "print the according local values")), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-35s%-30s", "", "set [KEY] [VALUE]", "set the local values")), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-35s%-30s", "", "new", "Create a new tree using the values defined in env and boundary")), + ), + ) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-35s%-30s", "", "", "quit")), + ), + ) + return + } + + if strings.HasPrefix(input, "print") { + key := "" + + if len(input) > 6 { + key = strings.Split(input[6:], " ")[0] + } else { + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-35s", "", "[env|bounadry|all]")), + ), + ) + return + } + + switch key { + case "env": + printEnvironment(history, parameters) + break + case "boundary": + printBoundary(history, boundary) + break + case "all": + printEnvironment(history, parameters) + printBoundary(history, boundary) + break + default: + } + return + } + + // test if the input string starts with 'set' + if strings.HasPrefix(input, "set") { + // trim of the "set" off the string + parameter := strings.Split(input[4:], " ")[0] + key := strings.Split(input[4:], " ")[1] + value := strings.Split(input[4:], " ")[2] + + switch parameter { + case "env": + setEnvironment(history, parameters, key, value) + break + case "boundary": + setBoundary(history, boundary, key, value) + break + } + + return + } + + if input == "new" { + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "", "Creating a new tree")), + ), + ) + + // Generate the request url + requestUrl := fmt.Sprintf("http://%s/new", parameters.Url()) + + // Bundle the post request data + data := []byte(fmt.Sprintf("x=%d&y=%d&w=%d", boundary.X(), boundary.Y(), boundary.Width())) + + // make the new request the the endpoint defined above using the data bundled above + req, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(data)) + if err != nil { + log.Fatal("Error reading request.", err) + } + + // Send the request + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Fatal("Error reading response.", err) + } + + // return the http response code + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "", resp.Status)), + ), + ) + return + } + + if input == "insert" { + infoMessage := fmt.Sprintf("Inserting %d stars from %s into tree Nr. %d defined in %s.", parameters.Amount(), parameters.Data(), parameters.Treeindex(), parameters.Url()) + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "", infoMessage)), + ), + ) + + // open parameters.Data() + dat, err := ioutil.ReadFile(parameters.Data()) + if err != nil { + log.Fatal("Error reading file") + } + + // parse the data using a csv reader + csvData := csv.NewReader(strings.NewReader(string(dat))) + + for i := 0; i < int(parameters.Amount()); i++ { + record, err := csvData.Read() + if err == io.EOF { + break + } + if err != nil { + log.Fatal("Error Reading the csv data: ", err) + } + + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "", record)), + ), + ) + + // Generate the request url + requestUrl := fmt.Sprintf("http://%s/insert/%d", parameters.Url(), parameters.Treeindex()) + + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "requesturl: ", requestUrl)), + ), + ) + + x, _ := strconv.ParseFloat(record[0], 64) + y, _ := strconv.ParseFloat(record[0], 64) + + // Bundle the post request data + data := []byte(fmt.Sprintf("x=%f&y=%f&vx=0&vy=0&m=10", x, y)) + + // make the new request the the endpoint defined above using the data bundled above + req, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(data)) + if err != nil { + log.Fatal("Error reading request.", err) + } + + // Send the request + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Fatal("Error reading response.", err) + } + + // return the http response code + history.Append( + tui.NewHBox( + tui.NewLabel(fmt.Sprintf("%10s%-30s", "", resp.Status)), + ), + ) + } + + return + } + + faultyInput(history) +} -- cgit 1.4.1