Steel/pkg/cmd/console.go
2023-12-16 23:17:23 +01:00

124 lines
2.3 KiB
Go

package cmd
import (
"fmt"
"github.com/eiannone/keyboard"
"sync"
"time"
)
type Log struct {
Level string
Message string
Time string
Source string
}
type LoggerQueue struct {
queue chan Log
currentInput string
}
var Logger = &LoggerQueue{
queue: make(chan Log, 100),
}
func (l *LoggerQueue) log(level string, message string, source string) {
l.queue <- Log{
Level: level,
Message: message,
Time: time.Now().Format("2006/01/02 15:04:05"),
Source: source,
}
}
func (l *LoggerQueue) Info(message string) {
l.log("INFO", message, "")
}
func (l *LoggerQueue) Warning(message string) {
l.log("WARNING", message, "")
}
func (l *LoggerQueue) Error(message string) {
l.log("ERROR", message, "")
}
func (l *LoggerQueue) processLogs(stopChan chan struct{}) {
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
for {
select {
case logEntry := <-l.queue:
displayLog(logEntry)
case <-stopChan:
fmt.Print("\033[2K\r")
println("Stopping")
return
case <-ticker.C:
refreshInputDisplay(l.currentInput)
}
}
}
func displayLog(logEntry Log) {
fmt.Printf("\033[2K\r%s [%s]: %s\n", logEntry.Time, logEntry.Level, logEntry.Message)
fmt.Print("> ")
}
func refreshInputDisplay(input string) {
fmt.Print("\033[2K\r> " + input)
}
func Start(wg *sync.WaitGroup, stopChan chan struct{}) {
defer wg.Done()
if err := keyboard.Open(); err != nil {
panic(err)
}
defer func() {
go keyboard.Close()
}()
go Logger.processLogs(stopChan)
input := ""
for {
char, key, err := keyboard.GetKey()
if err != nil {
Logger.Error(fmt.Sprintf("Keyboard error: %v", err))
break
}
switch {
case key == keyboard.KeyEnter:
switch input {
case "":
// Do nothing
case "stop":
Logger.Info("Received stop command.")
close(stopChan)
return
default:
Logger.Info(fmt.Sprintf("Unknown command: %s", input))
}
input = ""
case key == keyboard.KeyBackspace || key == keyboard.KeyBackspace2:
if len(input) > 0 {
input = input[:len(input)-1]
}
case key == keyboard.KeySpace:
input += " "
case key == keyboard.KeyCtrlC:
Logger.Info("Received stop command.")
close(stopChan)
return
case char != 0:
input += string(char)
}
Logger.currentInput = input // Update stored user input
}
}