2023-12-12 20:59:54 +01:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
|
|
import (
|
2023-12-17 00:43:24 +01:00
|
|
|
"context"
|
2023-12-12 20:59:54 +01:00
|
|
|
"fmt"
|
2023-12-16 23:17:23 +01:00
|
|
|
"github.com/eiannone/keyboard"
|
2023-12-12 20:59:54 +01:00
|
|
|
"sync"
|
2023-12-16 20:52:05 +01:00
|
|
|
"time"
|
2023-12-12 20:59:54 +01:00
|
|
|
)
|
|
|
|
|
|
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, "")
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-17 00:43:24 +01:00
|
|
|
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)
|
2023-12-17 00:43:24 +01:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-17 00:43:24 +01:00
|
|
|
func Run(baseCtx context.Context) {
|
|
|
|
|
ctx, cancel := context.WithCancel(baseCtx)
|
|
|
|
|
defer cancel()
|
2023-12-12 20:59:54 +01:00
|
|
|
|
2023-12-17 00:43:24 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2023-12-17 00:43:24 +01:00
|
|
|
var wg sync.WaitGroup
|
2023-12-16 20:52:05 +01:00
|
|
|
|
2023-12-17 00:43:24 +01:00
|
|
|
wg.Add(1)
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
2023-12-16 23:17:23 +01:00
|
|
|
|
2023-12-17 00:43:24 +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
|
|
|
}
|
2023-12-17 00:43:24 +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:
|
2023-12-17 00:43:24 +01:00
|
|
|
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
|
|
|
}
|
2023-12-17 00:43:24 +01:00
|
|
|
Logger.currentInput = input // Update stored user input
|
2023-12-12 20:59:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-12-17 00:43:24 +01:00
|
|
|
|
|
|
|
|
wg.Wait()
|
2023-12-12 20:59:54 +01:00
|
|
|
}
|