From 5b1eb383e3f7f0309e79f2c7e09fab0d1e799f97 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 15 Jul 2022 01:57:45 -0700 Subject: [PATCH] screen deletion working, bug fixes --- cmd/main-server.go | 24 ++++++++++--- pkg/scws/scws.go | 4 +++ pkg/sstore/dbops.go | 78 ++++++++++++++++++++++++++++++++++++----- pkg/sstore/updatebus.go | 13 ++++++- 4 files changed, 106 insertions(+), 13 deletions(-) diff --git a/cmd/main-server.go b/cmd/main-server.go index 3a9a8dfc..ca27f8f3 100644 --- a/cmd/main-server.go +++ b/cmd/main-server.go @@ -9,6 +9,7 @@ import ( "io/fs" "net/http" "os" + "runtime/debug" "strconv" "strings" "sync" @@ -334,6 +335,15 @@ type runCommandResponse struct { } func HandleRunCommand(w http.ResponseWriter, r *http.Request) { + defer func() { + r := recover() + if r == nil { + return + } + fmt.Printf("[error] in run-command: %v\n", r) + debug.PrintStack() + return + }() w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") @@ -385,8 +395,7 @@ func ProcessFeCommandPacket(ctx context.Context, pk *scpacket.FeCommandPacketTyp } colonIdx := strings.Index(metaCmd, ":") if colonIdx != -1 { - metaCmd = metaCmd[0:colonIdx] - metaSubCmd = metaCmd[colonIdx+1:] + metaCmd, metaSubCmd = metaCmd[0:colonIdx], metaCmd[colonIdx+1:] } if metaCmd == "" { return nil, fmt.Errorf("invalid command, got bare '/', with no command") @@ -440,6 +449,13 @@ func ProcessFeCommandPacket(ctx context.Context, pk *scpacket.FeCommandPacketTyp } func RunScreenCmd(ctx context.Context, sessionId string, screenId string, subCmd string, commandStr string) error { + if subCmd == "close" { + err := sstore.DeleteScreen(ctx, sessionId, screenId) + if err != nil { + return err + } + return nil + } if subCmd != "" { return fmt.Errorf("invalid /screen subcommand '%s'", subCmd) } @@ -458,11 +474,11 @@ func RunScreenCmd(ctx context.Context, sessionId string, screenId string, subCmd return sstore.SwitchScreenById(ctx, sessionId, screens[screenNum-1].ScreenId) } for _, screen := range screens { - if screen.Name == commandStr { + if screen.ScreenId == commandStr || screen.Name == commandStr { return sstore.SwitchScreenById(ctx, sessionId, screen.ScreenId) } } - return fmt.Errorf("could not switch to screen '%s' (name not found)", commandStr) + return fmt.Errorf("could not switch to screen '%s' (name/id not found)", commandStr) } // /api/start-session diff --git a/pkg/scws/scws.go b/pkg/scws/scws.go index 6ad4cd98..759e8747 100644 --- a/pkg/scws/scws.go +++ b/pkg/scws/scws.go @@ -143,6 +143,10 @@ func (ws *WSState) RunWSRead() { fmt.Printf("[error] invalid watchscreen sessionid: %v\n", err) continue } + if wsPk.ScreenId == "" { + ws.UnWatchScreen() + continue + } if _, err := uuid.Parse(wsPk.ScreenId); err != nil { fmt.Printf("[error] invalid watchscreen screenid: %v\n", err) continue diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index a9e173f9..d18350c2 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -167,6 +167,7 @@ func GetSessionById(ctx context.Context, id string) (*SessionType, error) { tx.SelectWrap(&session.Screens, query, session.SessionId) query = `SELECT * FROM remote_instance WHERE sessionid = ?` tx.SelectWrap(&session.Remotes, query, session.SessionId) + session.Full = true return nil }) if err != nil { @@ -270,6 +271,16 @@ func InsertScreen(ctx context.Context, sessionId string, screenName string, acti } return nil }) + newScreen, err := GetScreenById(ctx, sessionId, newScreenId) + if err != nil { + return "", err + } + update, session := MakeSingleSessionUpdate(sessionId) + if activate { + session.ActiveScreenId = newScreenId + } + session.Screens = append(session.Screens, newScreen) + MainBus.SendUpdate("", update) return newScreenId, txErr } @@ -285,6 +296,7 @@ func GetScreenById(ctx context.Context, sessionId string, screenId string) (*Scr rtnScreen = &screen query = `SELECT * FROM screen_window WHERE sessionid = ? AND screenid = ?` tx.SelectWrap(&screen.Windows, query, sessionId, screenId) + screen.Full = true return nil }) if txErr != nil { @@ -385,6 +397,31 @@ func HangupRunningCmdsByRemoteId(ctx context.Context, remoteId string) error { }) } +func getNextId(ids []string, delId string) string { + fmt.Printf("getnextid %v | %v\n", ids, delId) + if len(ids) == 0 { + return "" + } + if len(ids) == 1 { + if ids[0] == delId { + return "" + } + return ids[0] + } + for idx := 0; idx < len(ids); idx++ { + if ids[idx] == delId { + var rtnIdx int + if idx == len(ids)-1 { + rtnIdx = idx - 1 + } else { + rtnIdx = idx + 1 + } + return ids[rtnIdx] + } + } + return ids[0] +} + func SwitchScreenById(ctx context.Context, sessionId string, screenId string) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?` @@ -395,14 +432,39 @@ func SwitchScreenById(ctx context.Context, sessionId string, screenId string) er tx.ExecWrap(query, screenId, sessionId) return nil }) - sessionUpdate := SessionType{ - SessionId: sessionId, - ActiveScreenId: screenId, - NotifyNum: -1, - } - update := &SessionUpdate{ - Sessions: []SessionType{sessionUpdate}, - } + update, session := MakeSingleSessionUpdate(sessionId) + session.ActiveScreenId = screenId MainBus.SendUpdate("", update) return txErr } + +func CleanWindows() { +} + +func DeleteScreen(ctx context.Context, sessionId string, screenId string) error { + var newActiveScreenId string + txErr := WithTx(ctx, func(tx *TxWrap) error { + isActive := tx.Exists(`SELECT sessionid FROM session WHERE sessionid = ? AND activescreenid = ?`, sessionId, screenId) + fmt.Printf("delete-screen %s %s | %v\n", sessionId, screenId, isActive) + if isActive { + screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? ORDER BY screenidx`, sessionId) + nextId := getNextId(screenIds, screenId) + tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) + newActiveScreenId = nextId + } + query := `DELETE FROM screen_window WHERE sessionid = ? AND screenid = ?` + tx.ExecWrap(query, sessionId, screenId) + query = `DELETE FROM screen WHERE sessionid = ? AND screenid = ?` + tx.ExecWrap(query, sessionId, screenId) + return nil + }) + if txErr != nil { + return txErr + } + go CleanWindows() + update, session := MakeSingleSessionUpdate(sessionId) + session.ActiveScreenId = newActiveScreenId + session.Screens = append(session.Screens, &ScreenType{SessionId: sessionId, ScreenId: screenId, Remove: true}) + MainBus.SendUpdate("", update) + return nil +} diff --git a/pkg/sstore/updatebus.go b/pkg/sstore/updatebus.go index 1540149d..b9e94298 100644 --- a/pkg/sstore/updatebus.go +++ b/pkg/sstore/updatebus.go @@ -23,7 +23,18 @@ type WindowUpdate struct { } type SessionUpdate struct { - Sessions []SessionType `json:"sessions"` + Sessions []*SessionType `json:"sessions"` +} + +func MakeSingleSessionUpdate(sessionId string) (*SessionUpdate, *SessionType) { + session := &SessionType{ + SessionId: sessionId, + NotifyNum: -1, + } + update := &SessionUpdate{ + Sessions: []*SessionType{session}, + } + return update, session } type CmdUpdate struct {