refactor simple screen output into screenHandler function to parse ANSI files (with optional go template fields)

This commit is contained in:
Sundog Jones 2021-04-16 14:41:35 -07:00
parent 10a3c0a4e9
commit f371c01596
7 changed files with 69 additions and 59 deletions

2
go.mod
View File

@ -6,5 +6,5 @@ require (
github.com/creack/pty v1.1.11 github.com/creack/pty v1.1.11
github.com/xtaci/gaio v1.2.9 github.com/xtaci/gaio v1.2.9
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c // indirect golang.org/x/sys v0.0.0-20210415045647-66c3f260301c // indirect
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 // indirect golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72
) )

2
go.sum
View File

@ -3,8 +3,6 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ
github.com/xtaci/gaio v1.2.9 h1:EuVc7Q2JDzIY2mk5mjtq4K5BgTuO+kj5LXzCwjOK+mo= github.com/xtaci/gaio v1.2.9 h1:EuVc7Q2JDzIY2mk5mjtq4K5BgTuO+kj5LXzCwjOK+mo=
github.com/xtaci/gaio v1.2.9/go.mod h1:rJMerwiLCLnKa14YTM/sRggTPrnBZrlCg9U3DnV5VBE= github.com/xtaci/gaio v1.2.9/go.mod h1:rJMerwiLCLnKa14YTM/sRggTPrnBZrlCg9U3DnV5VBE=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0 h1:g9s1Ppvvun/fI+BptTMj909BBIcGrzQ32k9FNlcevOE=
golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c h1:6L+uOeS3OQt/f4eFHXZcTxeZrGCuz+CLElgEBjbcTA4= golang.org/x/sys v0.0.0-20210415045647-66c3f260301c h1:6L+uOeS3OQt/f4eFHXZcTxeZrGCuz+CLElgEBjbcTA4=
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0= golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0=

81
main.go
View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"flag" "flag"
@ -12,6 +13,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"text/template"
"time" "time"
"github.com/creack/pty" "github.com/creack/pty"
@ -102,7 +104,11 @@ func main() {
log.Printf("new context for client %v: %v\n", conn.RemoteAddr(), ctx) log.Printf("new context for client %v: %v\n", conn.RemoteAddr(), ctx)
// submit the first async write IO request // submit the first async write IO request
err = w.Write(ctx, conn, welcomeHandler()) welcomeScreen, err := screenHandler("welcome")
if err != nil {
log.Printf("err loading initial welcome screen: %v\n", err)
}
err = w.Write(ctx, conn, welcomeScreen)
if err != nil { if err != nil {
log.Printf("err sending welcomeHandler: %v\n", err) log.Printf("err sending welcomeHandler: %v\n", err)
return return
@ -179,7 +185,11 @@ func menuHandler(ctx context.Context, conn net.Conn, w *gaio.Watcher) {
switch string(strings.TrimSpace(string(res.Buffer[:res.Size-2]))) { switch string(strings.TrimSpace(string(res.Buffer[:res.Size-2]))) {
case "welcome": case "welcome":
if err := w.Write(ctx, conn, welcomeHandler()); err != nil { welcomeStr, err := screenHandler("welcome")
if err != nil {
log.Printf("err loading welcome screen: %v\n", err)
}
if err := w.Write(ctx, conn, welcomeStr); err != nil {
log.Printf("error sending welcomeHandler from cmd `welcome`: %v", err) log.Printf("error sending welcomeHandler from cmd `welcome`: %v", err)
} }
@ -199,22 +209,18 @@ func menuHandler(ctx context.Context, conn net.Conn, w *gaio.Watcher) {
} }
case "exit": case "exit":
if err := w.Write(ctx, conn, exitHandler()); err != nil { exitStr, err := screenHandler("exit")
log.Printf("error sending exitHandler from cmd `exit`: %v\n", err)
} else {
// let's wait before we actually close the connection to try and ensure the write gets through
time.Sleep(time.Second)
log.Println("exiting...")
log.Printf("Goodbye %s!\n", conn.RemoteAddr())
err := w.Free(conn)
if err != nil { if err != nil {
log.Printf("err closing connection: %v\n", err) log.Printf("err loading exit screen: %v\n", err)
} }
MenuControl <- "stop" if err := w.Write(ctx, conn, exitStr); err != nil {
break ControlLoop log.Printf("error sending exitHandler from cmd `exit`: %v", err)
} }
default: // wait a second before really closing the connection
time.Sleep(time.Second)
w.Free(conn)
default:
err := w.Write(ctx, conn, []byte("huh?\n\n> ")) err := w.Write(ctx, conn, []byte("huh?\n\n> "))
if err != nil { if err != nil {
log.Printf("error writing to connection: %v", err) log.Printf("error writing to connection: %v", err)
@ -244,47 +250,16 @@ func menuHandler(ctx context.Context, conn net.Conn, w *gaio.Watcher) {
log.Println("terminating menucontrol for client") log.Println("terminating menucontrol for client")
} }
func welcomeHandler() []byte { func screenHandler(screenName string) (screen []byte, err error) {
const bannerText = "\x1b[2J\x1b[H\x1b[31m\x1b[J\r\n" + ` var screenBuf *bytes.Buffer
if tmpl, err := template.ParseFiles("screens/" + screenName + ".ans"); err != nil {
_ __ _ ` + "" + ` log.Printf("err loading welcome template: %v\n", err)
| | / /__ / /________ ____ ___ ___` + "" + ` } else {
| | /| / / _ \/ / ___/ __ \/ __ '__ \/ _ \` + "" + ` screenBuf = new(bytes.Buffer)
| |/ |/ / __/ / /__/ /_/ / / / / / / __/` + "" + ` tmpl.Execute(screenBuf, nil)
|__/|__/\___/_/\___/\____/_/ /_/ /_/\___/` + "\r\n\x1b[33m" + `
__` + "" + `
/ /_____ ` + "" + `
/ __/ __ \` + "" + `
/ /_/ /_/ /` + "" + `
\__/\____/` + "\x1b[35m\r\n" + `
_ __` + "" + `
| | / /__ _____________` + "" + `
| | / / _ \/ ___/ ___/ _ \` + "" + `
| |/ / __/ / (__ ) __/` + "" + `
|___/\___/_/ /____/\___/` + "\x1b[37m\r\n" + `
_____ __ ___` + "" + `
/ ___// /___ ______/ (_)___ _____` + "" + `
\__ \/ __/ / / / __ / / __ \/ ___/` + "" + `
___/ / /_/ /_/ / /_/ / / /_/ (__ ) ` + "" + `
/____/\__/\__,_/\__,_/_/\____/____/ ` + "\x1b[32m\r\n\r\n\r\n" + `
Help is available: type help` + "\r\n\r\n> "
return []byte(bannerText)
} }
func exitHandler() []byte { return screenBuf.Bytes(), err
const exitMessage = "\x1b[2J\x1b[H\x1b[31m\x1b[J\r\n" + `
___| | |
\___ \ _ \ _ \ | | _ \ | | __| __ \ _' | __| _ \ __| _ \\ \ \ / __ \ _ \ | | |
| __/ __/ | | ( | | | \__ \ | | ( | ( __/ ( ( |\ \ \ / | | ( | | |_|
_____/ \___|\___| \__, |\___/ \__,_| ) ____/ .__/ \__,_|\___|\___| \___|\___/ \_/\_/ _.__/ \___/ \__, |_)
____/ / _| ____/
`
return []byte(exitMessage)
} }
func doorHandler(ctx context.Context, c net.Conn, w *gaio.Watcher, menuwg *sync.WaitGroup) error { func doorHandler(ctx context.Context, c net.Conn, w *gaio.Watcher, menuwg *sync.WaitGroup) error {

8
screens/exit.ans Normal file
View File

@ -0,0 +1,8 @@

___| | |
\___ \ _ \ _ \ | | _ \ | | __| __ \ _' | __| _ \ __| _ \\ \ \ / __ \ _ \ | | |
| __/ __/ | | ( | | | \__ \ | | ( | ( __/ ( ( |\ \ \ / | | ( | | |_|
_____/ \___|\___| \__, |\___/ \__,_| ) ____/ .__/ \__,_|\___|\___| \___|\___/ \_/\_/ _.__/ \___/ \__, |_)
____/ / _| ____/

0
screens/info.ans Normal file
View File

0
screens/operator.ans Normal file
View File

29
screens/welcome.ans Normal file
View File

@ -0,0 +1,29 @@

_ __ _
| | / /__ / /________ ____ ___ ___
| | /| / / _ \/ / ___/ __ \/ __ `__ \/ _ \
| |/ |/ / __/ / /__/ /_/ / / / / / / __/
|__/|__/\___/_/\___/\____/_/ /_/ /_/\___/
__
/ /_____
/ __/ __ \
/ /_/ /_/ /
\__/\____/
_ __
| | / /__ _____________
| | / / _ \/ ___/ ___/ _ \
| |/ / __/ / (__ ) __/
|___/\___/_/ /____/\___/
_____ __ ___
/ ___// /___ ______/ (_)___ _____
\__ \/ __/ / / / __ / / __ \/ ___/
___/ / /_/ /_/ / /_/ / / /_/ (__ )
/____/\__/\__,_/\__,_/_/\____/____/ 
Help is available: type help
>