mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
screen archiving
This commit is contained in:
@@ -14,6 +14,7 @@ CREATE TABLE session (
|
||||
activescreenid varchar(36) NOT NULL,
|
||||
notifynum int NOT NULL,
|
||||
archived boolean NOT NULL,
|
||||
archivedts bigint NOT NULL,
|
||||
ownerid varchar(36) NOT NULL,
|
||||
sharemode varchar(12) NOT NULL,
|
||||
accesskey varchar(36) NOT NULL
|
||||
@@ -44,6 +45,7 @@ CREATE TABLE screen (
|
||||
sharemode varchar(12) NOT NULL,
|
||||
incognito boolean NOT NULL,
|
||||
archived boolean NOT NULL,
|
||||
archivedts bigint NOT NULL,
|
||||
PRIMARY KEY (sessionid, screenid)
|
||||
);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ CREATE TABLE session (
|
||||
activescreenid varchar(36) NOT NULL,
|
||||
notifynum int NOT NULL,
|
||||
archived boolean NOT NULL,
|
||||
archivedts bigint NOT NULL,
|
||||
ownerid varchar(36) NOT NULL,
|
||||
sharemode varchar(12) NOT NULL,
|
||||
accesskey varchar(36) NOT NULL
|
||||
@@ -43,6 +44,7 @@ CREATE TABLE screen (
|
||||
sharemode varchar(12) NOT NULL,
|
||||
incognito boolean NOT NULL,
|
||||
archived boolean NOT NULL,
|
||||
archivedts bigint NOT NULL,
|
||||
PRIMARY KEY (sessionid, screenid)
|
||||
);
|
||||
CREATE TABLE screen_window (
|
||||
|
||||
+18
-18
@@ -124,7 +124,7 @@ func init() {
|
||||
registerCmdFn("session:showall", SessionShowAllCommand)
|
||||
|
||||
registerCmdFn("screen", ScreenCommand)
|
||||
registerCmdFn("screen:close", ScreenCloseCommand)
|
||||
registerCmdFn("screen:archive", ScreenArchiveCommand)
|
||||
registerCmdFn("screen:purge", ScreenPurgeCommand)
|
||||
registerCmdFn("screen:open", ScreenOpenCommand)
|
||||
registerCmdAlias("screen:new", ScreenOpenCommand)
|
||||
@@ -381,42 +381,42 @@ func EvalCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.
|
||||
return update, rtnErr
|
||||
}
|
||||
|
||||
func ScreenCloseCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
func ScreenArchiveCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session) // don't force R_Screen
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot close screen: %w", err)
|
||||
return nil, fmt.Errorf("/screen:archive cannot archive screen: %w", err)
|
||||
}
|
||||
screenId := ids.ScreenId
|
||||
if len(pk.Args) > 0 {
|
||||
ri, err := resolveSessionScreen(ctx, ids.SessionId, pk.Args[0], ids.ScreenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot resolve screen arg: %v", err)
|
||||
return nil, fmt.Errorf("/screen:archive cannot resolve screen arg: %v", err)
|
||||
}
|
||||
screenId = ri.Id
|
||||
}
|
||||
if screenId == "" {
|
||||
return nil, fmt.Errorf("/screen:close no active screen or screen arg passed")
|
||||
return nil, fmt.Errorf("/screen:archive no active screen or screen arg passed")
|
||||
}
|
||||
closeVal := true
|
||||
archiveVal := true
|
||||
if len(pk.Args) > 1 {
|
||||
closeVal = resolveBool(pk.Args[1], true)
|
||||
archiveVal = resolveBool(pk.Args[1], true)
|
||||
}
|
||||
var update sstore.UpdatePacket
|
||||
if closeVal {
|
||||
update, err = sstore.CloseScreen(ctx, ids.SessionId, screenId)
|
||||
if archiveVal {
|
||||
update, err = sstore.ArchiveScreen(ctx, ids.SessionId, screenId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return update, nil
|
||||
} else {
|
||||
fmt.Printf("unclose screen %s\n", screenId)
|
||||
err = sstore.UnCloseScreen(ctx, ids.SessionId, screenId)
|
||||
fmt.Printf("unarchive screen %s\n", screenId)
|
||||
err = sstore.UnArchiveScreen(ctx, ids.SessionId, screenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot re-open screen: %v", err)
|
||||
return nil, fmt.Errorf("/screen:archive cannot re-open screen: %v", err)
|
||||
}
|
||||
screen, err := sstore.GetScreenById(ctx, ids.SessionId, screenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot get updated screen obj: %v", err)
|
||||
return nil, fmt.Errorf("/screen:archive cannot get updated screen obj: %v", err)
|
||||
}
|
||||
update, session := sstore.MakeSingleSessionUpdate(ids.SessionId)
|
||||
session.Screens = append(session.Screens, screen)
|
||||
@@ -427,7 +427,7 @@ func ScreenCloseCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (
|
||||
func ScreenPurgeCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:purge cannot close screen: %w", err)
|
||||
return nil, fmt.Errorf("/screen:purge cannot purge screen: %w", err)
|
||||
}
|
||||
update, err := sstore.DeleteScreen(ctx, ids.SessionId, ids.ScreenId)
|
||||
if err != nil {
|
||||
@@ -949,21 +949,21 @@ func RemoteShowAllCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
|
||||
func ScreenShowAllCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session)
|
||||
screenArr, err := sstore.GetAllSessionScreens(ctx, ids.SessionId)
|
||||
screenArr, err := sstore.GetSessionScreens(ctx, ids.SessionId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:showall error getting screen list: %v", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
for _, screen := range screenArr {
|
||||
var closedStr string
|
||||
var archivedStr string
|
||||
if screen.Archived {
|
||||
closedStr = " (closed)"
|
||||
archivedStr = " (archived)"
|
||||
}
|
||||
screenIdxStr := "-"
|
||||
if screen.ScreenIdx != 0 {
|
||||
screenIdxStr = strconv.Itoa(int(screen.ScreenIdx))
|
||||
}
|
||||
outStr := fmt.Sprintf("%-30s %s %s\n", screen.Name+closedStr, screen.ScreenId, screenIdxStr)
|
||||
outStr := fmt.Sprintf("%-30s %s %s\n", screen.Name+archivedStr, screen.ScreenId, screenIdxStr)
|
||||
buf.WriteString(outStr)
|
||||
}
|
||||
return sstore.ModelUpdate{
|
||||
|
||||
+16
-20
@@ -289,7 +289,7 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) {
|
||||
session.Full = true
|
||||
}
|
||||
var screens []*ScreenType
|
||||
query = `SELECT * FROM screen WHERE NOT archived ORDER BY screenidx`
|
||||
query = `SELECT * FROM screen ORDER BY archived, screenidx, archivedts`
|
||||
tx.SelectWrap(&screens, query)
|
||||
screenMap := make(map[string][]*ScreenType)
|
||||
for _, screen := range screens {
|
||||
@@ -358,17 +358,7 @@ func GetWindowById(ctx context.Context, sessionId string, windowId string) (*Win
|
||||
func GetSessionScreens(ctx context.Context, sessionId string) ([]*ScreenType, error) {
|
||||
var rtn []*ScreenType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT * FROM screen WHERE sessionid = ? ORDER BY screenidx`
|
||||
tx.SelectWrap(&rtn, query, sessionId)
|
||||
return nil
|
||||
})
|
||||
return rtn, txErr
|
||||
}
|
||||
|
||||
func GetAllSessionScreens(ctx context.Context, sessionId string) ([]*ScreenType, error) {
|
||||
var rtn []*ScreenType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT * FROM screen WHERE sessionid = ? ORDER BY archived, screenidx`
|
||||
query := `SELECT * FROM screen WHERE sessionid = ? ORDER BY archived, screenidx, archivedts`
|
||||
tx.SelectWrap(&rtn, query, sessionId)
|
||||
return nil
|
||||
})
|
||||
@@ -418,8 +408,8 @@ func InsertSessionWithName(ctx context.Context, sessionName string, activate boo
|
||||
names := tx.SelectStrings(`SELECT name FROM session`)
|
||||
sessionName = fmtUniqueName(sessionName, "session-%d", len(names)+1, names)
|
||||
maxSessionIdx := tx.GetInt(`SELECT COALESCE(max(sessionidx), 0) FROM session`)
|
||||
query := `INSERT INTO session (sessionid, name, activescreenid, sessionidx, notifynum, archived, ownerid, sharemode, accesskey)
|
||||
VALUES (?, ?, '', ?, ?, 0, '', 'local', '')`
|
||||
query := `INSERT INTO session (sessionid, name, activescreenid, sessionidx, notifynum, archived, archivedts, ownerid, sharemode, accesskey)
|
||||
VALUES (?, ?, '', ?, ?, 0, 0, '', 'local', '')`
|
||||
tx.ExecWrap(query, newSessionId, sessionName, maxSessionIdx+1, 0)
|
||||
_, err := InsertScreen(tx.Context(), newSessionId, "", true)
|
||||
if err != nil {
|
||||
@@ -528,7 +518,7 @@ func InsertScreen(ctx context.Context, sessionId string, origScreenName string,
|
||||
screenNames := tx.SelectStrings(`SELECT name FROM screen WHERE sessionid = ? AND NOT archived`, sessionId)
|
||||
screenName := fmtUniqueName(origScreenName, "s%d", maxScreenIdx+1, screenNames)
|
||||
newScreenId = scbase.GenPromptUUID()
|
||||
query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, ownerid, sharemode, incognito, archived) VALUES (?, ?, ?, ?, ?, ?, '', 'local', 0, 0)`
|
||||
query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, ownerid, sharemode, incognito, archived, archivedts) VALUES (?, ?, ?, ?, ?, ?, '', 'local', 0, 0, 0)`
|
||||
tx.ExecWrap(query, sessionId, newScreenId, screenName, newWindowId, maxScreenIdx+1, ScreenOptsType{})
|
||||
layout := LayoutType{Type: LayoutFull}
|
||||
query = `INSERT INTO screen_window (sessionid, screenid, windowid, name, layout, selectedline, anchor, focustype) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
@@ -858,14 +848,20 @@ func CleanWindows(sessionId string) {
|
||||
tx.ExecWrap(query, sessionId, windowId)
|
||||
query = `DELETE FROM history WHERE sessionid = ? AND windowid = ?`
|
||||
tx.ExecWrap(query, sessionId, windowId)
|
||||
query = `DELETE FROM line WHERE sessinid = ? AND windowid = ?`
|
||||
query = `DELETE FROM line WHERE sessionid = ? AND windowid = ?`
|
||||
tx.ExecWrap(query, sessionId, windowId)
|
||||
}
|
||||
query = `SELECT cmdid FROM cmd WHERE sessionid = ? AND cmdid NOT IN (SELECT cmdid FROM line WHERE sessionid = ?)`
|
||||
removedCmds := tx.SelectStrings(query, sessionId, sessionId)
|
||||
query = `DELETE FROM cmd WHERE sessionid = ? AND cmdid NOT IN (SELECT cmdid FROM line WHERE sessionid = ?)`
|
||||
tx.ExecWrap(query, sessionId, sessionId)
|
||||
if tx.Err != nil {
|
||||
return nil
|
||||
}
|
||||
fmt.Printf("removed cmds: %v\n", removedCmds)
|
||||
for _, cmdId := range removedCmds {
|
||||
DeletePtyOutFile(tx.Context(), sessionId, cmdId)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
@@ -873,7 +869,7 @@ func CleanWindows(sessionId string) {
|
||||
}
|
||||
}
|
||||
|
||||
func CloseScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
|
||||
func ArchiveScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
|
||||
var newActiveScreenId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?`
|
||||
@@ -890,8 +886,8 @@ func CloseScreen(ctx context.Context, sessionId string, screenId string) (Update
|
||||
if numScreens <= 1 {
|
||||
return fmt.Errorf("cannot close the last screen in a session")
|
||||
}
|
||||
query = `UPDATE screen SET archived = 1, screenidx = 0 WHERE sessionid = ? AND screenid = ?`
|
||||
tx.ExecWrap(query, sessionId, screenId)
|
||||
query = `UPDATE screen SET archived = 1, archivedts = ?, screenidx = 0 WHERE sessionid = ? AND screenid = ?`
|
||||
tx.ExecWrap(query, time.Now().UnixMilli(), sessionId, screenId)
|
||||
isActive := tx.Exists(`SELECT sessionid FROM session WHERE sessionid = ? AND activescreenid = ?`, sessionId, screenId)
|
||||
if isActive {
|
||||
screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT archived ORDER BY screenidx`, sessionId)
|
||||
@@ -910,7 +906,7 @@ func CloseScreen(ctx context.Context, sessionId string, screenId string) (Update
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func UnCloseScreen(ctx context.Context, sessionId string, screenId string) error {
|
||||
func UnArchiveScreen(ctx context.Context, sessionId string, screenId string) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ? AND archived`
|
||||
if !tx.Exists(query, sessionId, screenId) {
|
||||
|
||||
@@ -153,6 +153,7 @@ type SessionType struct {
|
||||
AccessKey string `json:"-"`
|
||||
NotifyNum int64 `json:"notifynum"`
|
||||
Archived bool `json:"archived,omitempty"`
|
||||
ArchivedTs int64 `json:"archivedts,omitempty"`
|
||||
Screens []*ScreenType `json:"screens"`
|
||||
Remotes []*RemoteInstance `json:"remotes"`
|
||||
|
||||
@@ -358,6 +359,7 @@ type ScreenType struct {
|
||||
ShareMode string `json:"sharemode"`
|
||||
Incognito bool `json:"incognito,omitempty"`
|
||||
Archived bool `json:"archived,omitempty"`
|
||||
ArchivedTs int64 `json:"archivedts,omitempty"`
|
||||
Windows []*ScreenWindowType `json:"windows"`
|
||||
|
||||
// only for updates
|
||||
|
||||
Reference in New Issue
Block a user