Steel/pkg/cmd/console.go

133 lines
2.4 KiB
Go
Raw Normal View History

package cmd
import (
"context"
"fmt"
2023-12-16 23:17:23 +01:00
"github.com/eiannone/keyboard"
"sync"
2023-12-16 20:52:05 +01:00
"time"
)
2023-12-16 20:52:05 +01:00
type Log struct {
2023-12-16 23:17:23 +01:00
Level string
2023-12-16 20:52:05 +01:00
Message string
2023-12-16 23:17:23 +01:00
Time string
Source string
2023-12-16 20:52:05 +01:00
}
type LoggerQueue struct {
2023-12-16 23:17:23 +01:00
queue chan Log
currentInput string
2023-12-16 20:52:05 +01:00
}
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(ctx context.Context) {
2023-12-18 21:06:17 +01:00
ticker := time.NewTicker(100 * time.Millisecond)
2023-12-16 23:17:23 +01:00
defer ticker.Stop()
for {
select {
case logEntry := <-l.queue:
displayLog(logEntry)
case <-ctx.Done():
2023-12-16 23:17:23 +01:00
fmt.Print("\033[2K\r")
return
case <-ticker.C:
refreshInputDisplay(l.currentInput)
}
2023-12-16 20:52:05 +01:00
}
}
2023-12-16 23:17:23 +01:00
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 Run(baseCtx context.Context) {
ctx, cancel := context.WithCancel(baseCtx)
defer cancel()
input := ""
event, err := keyboard.GetKeys(10)
if err != nil {
Logger.Error(fmt.Sprintf("Keyboard error: %v", err))
return
2023-12-16 23:17:23 +01:00
}
var wg sync.WaitGroup
2023-12-16 20:52:05 +01:00
wg.Add(1)
go func() {
defer wg.Done()
2023-12-16 23:17:23 +01:00
Logger.processLogs(ctx)
}()
loop:
for {
select {
case <-ctx.Done():
cancel()
break loop
case event := <-event:
if event.Rune != 0 {
input += string(event.Rune)
2023-12-16 23:17:23 +01:00
}
switch event.Key {
case keyboard.KeyEnter:
switch input {
case "":
// Do nothing
case "stop":
Logger.Info("Received stop command.")
cancel()
break loop
default:
Logger.Info(fmt.Sprintf("Unknown command: %s", input))
}
input = ""
2023-12-18 21:06:17 +01:00
case keyboard.KeyBackspace, keyboard.KeyBackspace2:
if len(input) > 0 {
input = input[:len(input)-1]
}
case keyboard.KeySpace:
input += " "
case keyboard.KeyCtrlC:
Logger.Info("Received stop command.")
cancel()
break loop
2023-12-16 23:17:23 +01:00
}
Logger.currentInput = input // Update stored user input
}
}
wg.Wait()
}