screen archiving

This commit is contained in:
sawka
2022-12-25 13:21:48 -08:00
parent 5645a01482
commit f1a46dea82
5 changed files with 40 additions and 38 deletions
+2
View File
@@ -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)
);
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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) {
+2
View File
@@ -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