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/xtaci/gaio v1.2.9
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/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-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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0=

87
main.go
View File

@ -1,6 +1,7 @@
package main
import (
"bytes"
"context"
"errors"
"flag"
@ -12,6 +13,7 @@ import (
"strconv"
"strings"
"sync"
"text/template"
"time"
"github.com/creack/pty"
@ -102,7 +104,11 @@ func main() {
log.Printf("new context for client %v: %v\n", conn.RemoteAddr(), ctx)
// 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 {
log.Printf("err sending welcomeHandler: %v\n", err)
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]))) {
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)
}
@ -199,22 +209,18 @@ func menuHandler(ctx context.Context, conn net.Conn, w *gaio.Watcher) {
}
case "exit":
if err := w.Write(ctx, conn, exitHandler()); err != nil {
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 {
log.Printf("err closing connection: %v\n", err)
}
MenuControl <- "stop"
break ControlLoop
exitStr, err := screenHandler("exit")
if err != nil {
log.Printf("err loading exit screen: %v\n", err)
}
default:
if err := w.Write(ctx, conn, exitStr); err != nil {
log.Printf("error sending exitHandler from cmd `exit`: %v", err)
}
// 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> "))
if err != nil {
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")
}
func welcomeHandler() []byte {
const bannerText = "\x1b[2J\x1b[H\x1b[31m\x1b[J\r\n" + `
func screenHandler(screenName string) (screen []byte, err error) {
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 {
const exitMessage = "\x1b[2J\x1b[H\x1b[31m\x1b[J\r\n" + `
___| | |
\___ \ _ \ _ \ | | _ \ | | __| __ \ _' | __| _ \ __| _ \\ \ \ / __ \ _ \ | | |
| __/ __/ | | ( | | | \__ \ | | ( | ( __/ ( ( |\ \ \ / | | ( | | |_|
_____/ \___|\___| \__, |\___/ \__,_| ) ____/ .__/ \__,_|\___|\___| \___|\___/ \_/\_/ _.__/ \___/ \__, |_)
____/ / _| ____/
`
return []byte(exitMessage)
return screenBuf.Bytes(), err
}
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
>