mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-08 19:38:51 +01:00
starting on screen:webshare feature. simplify bookmarks (removed bookmarked from line)
This commit is contained in:
parent
8299d3ff54
commit
bfe8ee1c02
9
db/migrations/000014_simplifybookmarks.down.sql
Normal file
9
db/migrations/000014_simplifybookmarks.down.sql
Normal file
@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS "bookmark_cmd" (
|
||||
bookmarkid varchar(36) NOT NULL,
|
||||
screenid varchar(36) NOT NULL,
|
||||
cmdid varchar(36) NOT NULL,
|
||||
PRIMARY KEY (bookmarkid, screenid, cmdid)
|
||||
);
|
||||
|
||||
ALTER TABLE line ADD COLUMN bookmarked boolean NOT NULL DEFAULT 0;
|
||||
|
3
db/migrations/000014_simplifybookmarks.up.sql
Normal file
3
db/migrations/000014_simplifybookmarks.up.sql
Normal file
@ -0,0 +1,3 @@
|
||||
DROP TABLE bookmark_cmd;
|
||||
ALTER TABLE line DROP COLUMN bookmarked;
|
||||
|
4
db/migrations/000015_lineupdates.down.sql
Normal file
4
db/migrations/000015_lineupdates.down.sql
Normal file
@ -0,0 +1,4 @@
|
||||
DROP TABLE screenupdates;
|
||||
|
||||
ALTER TABLE screen DROP COLUMN webshareopts;
|
||||
|
10
db/migrations/000015_lineupdates.up.sql
Normal file
10
db/migrations/000015_lineupdates.up.sql
Normal file
@ -0,0 +1,10 @@
|
||||
CREATE TABLE screenupdates (
|
||||
updateid integer PRIMARY KEY,
|
||||
screenid varchar(36) NOT NULL,
|
||||
lineid varchar(36) NOT NULL,
|
||||
updatetype varchar(50) NOT NULL,
|
||||
updatets bigint NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE screen ADD COLUMN webshareopts json NOT NULL DEFAULT 'null';
|
||||
|
@ -128,12 +128,6 @@ CREATE TABLE cloud_update (
|
||||
updatetype varchar(50) NOT NULL,
|
||||
updatekeys json NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "bookmark_cmd" (
|
||||
bookmarkid varchar(36) NOT NULL,
|
||||
screenid varchar(36) NOT NULL,
|
||||
cmdid varchar(36) NOT NULL,
|
||||
PRIMARY KEY (bookmarkid, screenid, cmdid)
|
||||
);
|
||||
CREATE TABLE cmd_migrate (
|
||||
sessionid varchar(36) NOT NULL,
|
||||
screenid varchar(36) NOT NULL,
|
||||
@ -155,7 +149,7 @@ CREATE TABLE IF NOT EXISTS "screen" (
|
||||
anchor json NOT NULL,
|
||||
focustype varchar(12) NOT NULL,
|
||||
archived boolean NOT NULL,
|
||||
archivedts bigint NOT NULL,
|
||||
archivedts bigint NOT NULL, webshareopts json NOT NULL DEFAULT 'null',
|
||||
PRIMARY KEY (screenid)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "line" (
|
||||
@ -174,7 +168,6 @@ CREATE TABLE IF NOT EXISTS "line" (
|
||||
star int NOT NULL,
|
||||
archived boolean NOT NULL,
|
||||
renderer varchar(50) NOT NULL,
|
||||
bookmarked boolean NOT NULL,
|
||||
PRIMARY KEY (screenid, lineid)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "cmd" (
|
||||
@ -199,3 +192,10 @@ CREATE TABLE IF NOT EXISTS "cmd" (
|
||||
rtndiffhasharr json NOT NULL,
|
||||
PRIMARY KEY (screenid, cmdid)
|
||||
);
|
||||
CREATE TABLE screenupdates (
|
||||
updateid integer PRIMARY KEY,
|
||||
screenid varchar(36) NOT NULL,
|
||||
lineid varchar(36) NOT NULL,
|
||||
updatetype varchar(50) NOT NULL,
|
||||
updatets bigint NOT NULL
|
||||
);
|
||||
|
@ -3,6 +3,8 @@ package cmdrunner
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
@ -12,6 +14,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/alessio/shellescape"
|
||||
"github.com/google/uuid"
|
||||
@ -40,6 +43,7 @@ func init() {
|
||||
|
||||
const DefaultUserId = "sawka"
|
||||
const MaxNameLen = 50
|
||||
const MaxShareNameLen = 150
|
||||
const MaxRendererLen = 50
|
||||
const MaxRemoteAliasLen = 50
|
||||
const PasswordUnchangedSentinel = "--unchanged--"
|
||||
@ -131,7 +135,6 @@ func init() {
|
||||
registerCmdFn("session:showall", SessionShowAllCommand)
|
||||
registerCmdFn("session:show", SessionShowCommand)
|
||||
registerCmdFn("session:openshared", SessionOpenSharedCommand)
|
||||
registerCmdFn("session:opencloud", SessionOpenCloudCommand)
|
||||
|
||||
registerCmdFn("screen", ScreenCommand)
|
||||
registerCmdFn("screen:archive", ScreenArchiveCommand)
|
||||
@ -141,6 +144,7 @@ func init() {
|
||||
registerCmdFn("screen:set", ScreenSetCommand)
|
||||
registerCmdFn("screen:showall", ScreenShowAllCommand)
|
||||
registerCmdFn("screen:reset", ScreenResetCommand)
|
||||
registerCmdFn("screen:webshare", ScreenWebShareCommand)
|
||||
|
||||
registerCmdAlias("remote", RemoteCommand)
|
||||
registerCmdFn("remote:show", RemoteShowCommand)
|
||||
@ -1561,6 +1565,18 @@ func validateName(name string, typeStr string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateShareName(name string) error {
|
||||
if len(name) > MaxShareNameLen {
|
||||
return fmt.Errorf("share name too long, max length is %d", MaxShareNameLen)
|
||||
}
|
||||
for _, ch := range name {
|
||||
if !unicode.IsPrint(ch) {
|
||||
return fmt.Errorf("invalid character %q in share name", string(ch))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRenderer(renderer string) error {
|
||||
if renderer == "" {
|
||||
return nil
|
||||
@ -1601,22 +1617,6 @@ func SessionOpenSharedCommand(ctx context.Context, pk *scpacket.FeCommandPacketT
|
||||
return nil, fmt.Errorf("shared sessions are not available in this version of prompt (stay tuned)")
|
||||
}
|
||||
|
||||
func SessionOpenCloudCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
activate := resolveBool(pk.Kwargs["activate"], true)
|
||||
newName := pk.Kwargs["name"]
|
||||
if newName != "" {
|
||||
err := validateName(newName, "session")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
update, err := sstore.InsertSessionWithName(ctx, newName, sstore.ShareModeShared, activate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func SessionOpenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
activate := resolveBool(pk.Kwargs["activate"], true)
|
||||
newName := pk.Kwargs["name"]
|
||||
@ -1633,6 +1633,53 @@ func SessionOpenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func ScreenWebShareCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Screen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shouldShare := true
|
||||
if len(pk.Args) > 0 {
|
||||
shouldShare = resolveBool(pk.Args[0], true)
|
||||
}
|
||||
shareName := pk.Kwargs["sharename"]
|
||||
if err := validateShareName(shareName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var infoMsg string
|
||||
if shouldShare {
|
||||
viewKeyBytes := make([]byte, 9)
|
||||
_, err = rand.Read(viewKeyBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create viewkey: %v", err)
|
||||
}
|
||||
webShareOpts := sstore.ScreenWebShareOpts{ShareName: shareName, ViewKey: base64.RawURLEncoding.EncodeToString(viewKeyBytes)}
|
||||
err = sstore.ScreenWebShareStart(ctx, ids.ScreenId, webShareOpts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot web-share screen: %v", err)
|
||||
}
|
||||
pcloud.NotifyUpdateWriter()
|
||||
infoMsg = fmt.Sprintf("screen is now shared to the web at %s", "[screen-share-url]")
|
||||
} else {
|
||||
err = sstore.ScreenWebShareStop(ctx, ids.ScreenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot stop web-sharing screen: %v", err)
|
||||
}
|
||||
infoMsg = fmt.Sprintf("screen is no longer web shared")
|
||||
}
|
||||
screen, err := sstore.GetScreenById(ctx, ids.ScreenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get updated screen: %v", err)
|
||||
}
|
||||
update := sstore.ModelUpdate{
|
||||
Screens: []*sstore.ScreenType{screen},
|
||||
Info: &sstore.InfoMsgType{
|
||||
InfoMsg: infoMsg,
|
||||
},
|
||||
}
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func SessionDeleteCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session)
|
||||
if err != nil {
|
||||
@ -2339,36 +2386,42 @@ func LineBookmarkCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
if lineId == "" {
|
||||
return nil, fmt.Errorf("line %q not found", lineArg)
|
||||
}
|
||||
lineObj, cmdObj, err := sstore.GetLineCmdByLineId(ctx, ids.ScreenId, lineId)
|
||||
_, cmdObj, err := sstore.GetLineCmdByLineId(ctx, ids.ScreenId, lineId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:bookmark error getting line: %v", err)
|
||||
}
|
||||
if cmdObj == nil {
|
||||
return nil, fmt.Errorf("cannot bookmark non-cmd line")
|
||||
}
|
||||
ck := base.MakeCommandKey(lineObj.ScreenId, cmdObj.CmdId)
|
||||
bm := &sstore.BookmarkType{
|
||||
BookmarkId: uuid.New().String(),
|
||||
CreatedTs: time.Now().UnixMilli(),
|
||||
CmdStr: cmdObj.CmdStr,
|
||||
Alias: "",
|
||||
Tags: nil,
|
||||
Description: "",
|
||||
Cmds: []base.CommandKey{ck},
|
||||
}
|
||||
err = sstore.InsertBookmark(ctx, bm)
|
||||
existingBmIds, err := sstore.GetBookmarkIdsByCmdStr(ctx, cmdObj.CmdStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot insert bookmark: %v", err)
|
||||
return nil, fmt.Errorf("error trying to retrieve current boookmarks: %v", err)
|
||||
}
|
||||
newLineObj, err := sstore.GetLineById(ctx, ids.ScreenId, lineId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:bookmark error getting line: %v", err)
|
||||
var newBmId string
|
||||
if len(existingBmIds) > 0 {
|
||||
newBmId = existingBmIds[0]
|
||||
} else {
|
||||
newBm := &sstore.BookmarkType{
|
||||
BookmarkId: uuid.New().String(),
|
||||
CreatedTs: time.Now().UnixMilli(),
|
||||
CmdStr: cmdObj.CmdStr,
|
||||
Alias: "",
|
||||
Tags: nil,
|
||||
Description: "",
|
||||
}
|
||||
err = sstore.InsertBookmark(ctx, newBm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot insert bookmark: %v", err)
|
||||
}
|
||||
newBmId = newBm.BookmarkId
|
||||
}
|
||||
if newLineObj == nil {
|
||||
// no line (which is strange given we checked for it above). just return a nop.
|
||||
return nil, nil
|
||||
bms, err := sstore.GetBookmarks(ctx, "")
|
||||
update := sstore.ModelUpdate{
|
||||
MainView: sstore.MainViewBookmarks,
|
||||
Bookmarks: bms,
|
||||
SelectedBookmark: newBmId,
|
||||
}
|
||||
return sstore.ModelUpdate{Line: newLineObj}, nil
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func LinePinCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
|
@ -209,3 +209,6 @@ func CreateCloudSession(ctx context.Context) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NotifyUpdateWriter() {
|
||||
}
|
||||
|
@ -663,7 +663,8 @@ func InsertScreen(ctx context.Context, sessionId string, origScreenName string,
|
||||
Archived: false,
|
||||
ArchivedTs: 0,
|
||||
}
|
||||
query = `INSERT INTO screen (sessionid, screenid, name, screenidx, screenopts, ownerid, sharemode, curremoteownerid, curremoteid, curremotename, nextlinenum, selectedline, anchor, focustype, archived, archivedts) VALUES (:sessionid,:screenid,:name,:screenidx,:screenopts,:ownerid,:sharemode,:curremoteownerid,:curremoteid,:curremotename,:nextlinenum,:selectedline,:anchor,:focustype,:archived,:archivedts)`
|
||||
query = `INSERT INTO screen ( sessionid, screenid, name, screenidx, screenopts, ownerid, sharemode, webshareopts, curremoteownerid, curremoteid, curremotename, nextlinenum, selectedline, anchor, focustype, archived, archivedts)
|
||||
VALUES (:sessionid,:screenid,:name,:screenidx,:screenopts,:ownerid,:sharemode,:webshareopts,:curremoteownerid,:curremoteid,:curremotename,:nextlinenum,:selectedline,:anchor,:focustype,:archived,:archivedts)`
|
||||
tx.NamedExec(query, screen.ToMap())
|
||||
if activate {
|
||||
query = `UPDATE session SET activescreenid = ? WHERE sessionid = ?`
|
||||
@ -775,8 +776,8 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error {
|
||||
query = `SELECT nextlinenum FROM screen WHERE screenid = ?`
|
||||
nextLineNum := tx.GetInt(query, line.ScreenId)
|
||||
line.LineNum = int64(nextLineNum)
|
||||
query = `INSERT INTO line ( screenid, userid, lineid, ts, linenum, linenumtemp, linelocal, linetype, text, cmdid, renderer, ephemeral, contentheight, star, archived, bookmarked)
|
||||
VALUES (:screenid,:userid,:lineid,:ts,:linenum,:linenumtemp,:linelocal,:linetype,:text,:cmdid,:renderer,:ephemeral,:contentheight,:star,:archived,:bookmarked)`
|
||||
query = `INSERT INTO line ( screenid, userid, lineid, ts, linenum, linenumtemp, linelocal, linetype, text, cmdid, renderer, ephemeral, contentheight, star, archived)
|
||||
VALUES (:screenid,:userid,:lineid,:ts,:linenum,:linenumtemp,:linelocal,:linetype,:text,:cmdid,:renderer,:ephemeral,:contentheight,:star,:archived)`
|
||||
tx.NamedExec(query, line)
|
||||
query = `UPDATE screen SET nextlinenum = ? WHERE screenid = ?`
|
||||
tx.Exec(query, nextLineNum+1, line.ScreenId)
|
||||
@ -943,8 +944,6 @@ func cleanScreenCmds(ctx context.Context, screenId string) error {
|
||||
removedCmds = tx.SelectStrings(query, screenId, screenId)
|
||||
query = `DELETE FROM cmd WHERE screenid = ? AND cmdid NOT IN (SELECT cmdid FROM line WHERE screenid = ?)`
|
||||
tx.Exec(query, screenId, screenId)
|
||||
query = `DELETE FROM bookmark_cmd WHERE screenid = ? AND cmdid NOT IN (SELECT cmdid FROM cmd WHERE screenid = ?)`
|
||||
tx.Exec(query, screenId, screenId)
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
@ -2039,12 +2038,6 @@ type bookmarkOrderType struct {
|
||||
OrderIdx int64
|
||||
}
|
||||
|
||||
type bookmarkCmdType struct {
|
||||
BookmarkId string
|
||||
ScreenId string
|
||||
CmdId string
|
||||
}
|
||||
|
||||
func GetBookmarks(ctx context.Context, tag string) ([]*BookmarkType, error) {
|
||||
var bms []*BookmarkType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
@ -2066,15 +2059,6 @@ func GetBookmarks(ctx context.Context, tag string) ([]*BookmarkType, error) {
|
||||
bm.OrderIdx = bmOrder.OrderIdx
|
||||
}
|
||||
}
|
||||
var cmds []bookmarkCmdType
|
||||
query = `SELECT bookmarkid, screenid, cmdid FROM bookmark_cmd`
|
||||
tx.Select(&cmds, query)
|
||||
for _, cmd := range cmds {
|
||||
bm := bmMap[cmd.BookmarkId]
|
||||
if bm != nil {
|
||||
bm.Cmds = append(bm.Cmds, base.MakeCommandKey(cmd.ScreenId, cmd.CmdId))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
@ -2094,12 +2078,6 @@ func GetBookmarkById(ctx context.Context, bookmarkId string, tag string) (*Bookm
|
||||
query = `SELECT orderidx FROM bookmark_order WHERE bookmarkid = ? AND tag = ?`
|
||||
orderIdx := tx.GetInt(query, bookmarkId, tag)
|
||||
rtn.OrderIdx = int64(orderIdx)
|
||||
query = `SELECT bookmarkid, screenid, cmdid FROM bookmark_cmd WHERE bookmarkid = ?`
|
||||
var cmds []bookmarkCmdType
|
||||
tx.Select(&cmds, query, bookmarkId)
|
||||
for _, cmd := range cmds {
|
||||
rtn.Cmds = append(rtn.Cmds, base.MakeCommandKey(cmd.ScreenId, cmd.CmdId))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
@ -2126,6 +2104,14 @@ func GetBookmarkIdByArg(ctx context.Context, bookmarkArg string) (string, error)
|
||||
return rtnId, nil
|
||||
}
|
||||
|
||||
func GetBookmarkIdsByCmdStr(ctx context.Context, cmdStr string) ([]string, error) {
|
||||
return WithTxRtn(ctx, func(tx *TxWrap) ([]string, error) {
|
||||
query := `SELECT bookmarkid FROM bookmark WHERE cmdstr = ?`
|
||||
bmIds := tx.SelectStrings(query, cmdStr)
|
||||
return bmIds, nil
|
||||
})
|
||||
}
|
||||
|
||||
// ignores OrderIdx field
|
||||
func InsertBookmark(ctx context.Context, bm *BookmarkType) error {
|
||||
if bm == nil || bm.BookmarkId == "" {
|
||||
@ -2145,14 +2131,6 @@ func InsertBookmark(ctx context.Context, bm *BookmarkType) error {
|
||||
query = `INSERT INTO bookmark_order (tag, bookmarkid, orderidx) VALUES (?, ?, ?)`
|
||||
tx.Exec(query, tag, bm.BookmarkId, maxOrder+1)
|
||||
}
|
||||
query = `INSERT INTO bookmark_cmd (bookmarkid, screenid, cmdid) VALUES (?, ?, ?)`
|
||||
for _, ck := range bm.Cmds {
|
||||
tx.Exec(query, bm.BookmarkId, ck.GetGroupId(), ck.GetCmdId())
|
||||
}
|
||||
query = `UPDATE line SET bookmarked = 1 WHERE screenid = ? AND cmdid = ?`
|
||||
for _, ck := range bm.Cmds {
|
||||
tx.Exec(query, ck.GetGroupId(), ck.GetCmdId())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
@ -2205,10 +2183,6 @@ func DeleteBookmark(ctx context.Context, bookmarkId string) error {
|
||||
tx.Exec(query, bookmarkId)
|
||||
query = `DELETE FROM bookmark_order WHERE bookmarkid = ?`
|
||||
tx.Exec(query, bookmarkId)
|
||||
query = `UPDATE line SET bookmarked = 0 WHERE bookmarked AND cmdid <> '' AND (screenid||cmdid) IN (SELECT screenid||cmdid FROM bookmark_cmd WHERE bookmarkid = ?) `
|
||||
tx.Exec(query, bookmarkId)
|
||||
query = `DELETE FROM bookmark_cmd WHERE bookmarkid = ?`
|
||||
tx.Exec(query, bookmarkId)
|
||||
fixupBookmarkOrder(tx)
|
||||
return nil
|
||||
})
|
||||
@ -2343,3 +2317,47 @@ func PurgeHistoryByIds(ctx context.Context, historyIds []string) ([]*HistoryItem
|
||||
return rtn, nil
|
||||
})
|
||||
}
|
||||
|
||||
func ScreenWebShareStart(ctx context.Context, screenId string, shareOpts ScreenWebShareOpts) error {
|
||||
return WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE screenid = ?`
|
||||
if !tx.Exists(query, screenId) {
|
||||
return fmt.Errorf("screen does not exist")
|
||||
}
|
||||
shareMode := tx.GetString(`SELECT sharemode FROM screen WHERE screenid = ?`, screenId)
|
||||
if shareMode == ShareModeWeb {
|
||||
return fmt.Errorf("screen is already shared to web")
|
||||
}
|
||||
if shareMode != ShareModeLocal {
|
||||
return fmt.Errorf("screen cannot be shared, invalid current share mode %q (must be local)", shareMode)
|
||||
}
|
||||
query = `UPDATE screen SET sharemode = ?, webshareopts = ? WHERE screenid = ?`
|
||||
tx.Exec(query, ShareModeWeb, quickJson(shareOpts), screenId)
|
||||
query = `INSERT INTO screenupdates (screenid, lineid, updatetype, updatets)
|
||||
SELECT screenid, lineid, ?, ? FROM line WHERE screenid = ? ORDER BY linenum`
|
||||
tx.Exec(query, UpdateType_LineNew, time.Now().UnixMilli(), screenId)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ScreenWebShareStop(ctx context.Context, screenId string) error {
|
||||
return WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE screenid = ?`
|
||||
if !tx.Exists(query, screenId) {
|
||||
return fmt.Errorf("screen does not exist")
|
||||
}
|
||||
shareMode := tx.GetString(`SELECT sharemode FROM screen WHERE screenid = ?`, screenId)
|
||||
if shareMode != ShareModeWeb {
|
||||
return fmt.Errorf("screen is not currently shared to the web")
|
||||
}
|
||||
query = `UPDATE screen SET sharemode = ?, webshareopts = ? WHERE screenid = ?`
|
||||
tx.Exec(query, ShareModeLocal, "null", screenId)
|
||||
query = `DELETE FROM screenupdates WHERE screenid = ?`
|
||||
tx.Exec(query, screenId)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func isWebShare(tx *TxWrap, screenId string) bool {
|
||||
return tx.Exists(`SELECT screenid FROM screen WHERE screenid = ? AND sharemode = ?`, screenId, ShareModeWeb)
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
)
|
||||
|
||||
const MaxMigration = 13
|
||||
const MaxMigration = 15
|
||||
const MigratePrimaryScreenVersion = 9
|
||||
|
||||
func MakeMigrate() (*migrate.Migrate, error) {
|
||||
|
@ -80,6 +80,21 @@ func quickSetJson(ptr interface{}, m map[string]interface{}, name string) {
|
||||
json.Unmarshal([]byte(str), ptr)
|
||||
}
|
||||
|
||||
func quickSetNullableJson(ptr interface{}, m map[string]interface{}, name string) {
|
||||
v, ok := m[name]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if str == "" {
|
||||
str = "null"
|
||||
}
|
||||
json.Unmarshal([]byte(str), ptr)
|
||||
}
|
||||
|
||||
func quickSetJsonArr(ptr interface{}, m map[string]interface{}, name string) {
|
||||
v, ok := m[name]
|
||||
if !ok {
|
||||
@ -95,6 +110,14 @@ func quickSetJsonArr(ptr interface{}, m map[string]interface{}, name string) {
|
||||
json.Unmarshal([]byte(str), ptr)
|
||||
}
|
||||
|
||||
func quickNullableJson(v interface{}) string {
|
||||
if v == nil {
|
||||
return "null"
|
||||
}
|
||||
barr, _ := json.Marshal(v)
|
||||
return string(barr)
|
||||
}
|
||||
|
||||
func quickJson(v interface{}) string {
|
||||
if v == nil {
|
||||
return "{}"
|
||||
|
@ -54,10 +54,8 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
ShareModeLocal = "local"
|
||||
ShareModePrivate = "private"
|
||||
ShareModeView = "view"
|
||||
ShareModeShared = "shared"
|
||||
ShareModeLocal = "local"
|
||||
ShareModeWeb = "web"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -81,6 +79,19 @@ const (
|
||||
CmdStoreTypeScreen = "screen"
|
||||
)
|
||||
|
||||
const (
|
||||
UpdateType_ScreenName = "screen:sharename"
|
||||
UpdateType_ScreenCurRemote = "screen:curremote"
|
||||
UpdateType_LineNew = "line:new"
|
||||
UpdateType_LineDel = "line:del"
|
||||
UpdateType_LineArchived = "line:archived"
|
||||
UpdateType_LineRenderer = "line:renderer"
|
||||
UpdateType_CmdStatus = "cmd:status"
|
||||
UpdateType_CmdDoneInfo = "cmd:doneinfo"
|
||||
UpdateType_CmdRunOut = "cmd:runout"
|
||||
UpdateType_CmdRtnState = "cmd:rtnstate"
|
||||
)
|
||||
|
||||
const MaxTzNameLen = 50
|
||||
|
||||
var globalDBLock = &sync.Mutex{}
|
||||
@ -212,6 +223,7 @@ type ClientData struct {
|
||||
FeOpts FeOptsType `json:"feopts"`
|
||||
CmdStoreType string `json:"cmdstoretype"`
|
||||
Migration *ClientMigrationData `json:"migration,omitempty" dbmap:"-"`
|
||||
DBVersion int `json:"dbversion" dbmap:"-"`
|
||||
}
|
||||
|
||||
func (ClientData) UseDBMap() {}
|
||||
@ -401,21 +413,27 @@ type ScreenLinesType struct {
|
||||
|
||||
func (ScreenLinesType) UseDBMap() {}
|
||||
|
||||
type ScreenWebShareOpts struct {
|
||||
ShareName string `json:"sharename"`
|
||||
ViewKey string `json:"viewkey"`
|
||||
}
|
||||
|
||||
type ScreenType struct {
|
||||
SessionId string `json:"sessionid"`
|
||||
ScreenId string `json:"screenid"`
|
||||
Name string `json:"name"`
|
||||
ScreenIdx int64 `json:"screenidx"`
|
||||
ScreenOpts ScreenOptsType `json:"screenopts"`
|
||||
OwnerId string `json:"ownerid"`
|
||||
ShareMode string `json:"sharemode"`
|
||||
CurRemote RemotePtrType `json:"curremote"`
|
||||
NextLineNum int64 `json:"nextlinenum"`
|
||||
SelectedLine int64 `json:"selectedline"`
|
||||
Anchor ScreenAnchorType `json:"anchor"`
|
||||
FocusType string `json:"focustype"`
|
||||
Archived bool `json:"archived,omitempty"`
|
||||
ArchivedTs int64 `json:"archivedts,omitempty"`
|
||||
SessionId string `json:"sessionid"`
|
||||
ScreenId string `json:"screenid"`
|
||||
Name string `json:"name"`
|
||||
ScreenIdx int64 `json:"screenidx"`
|
||||
ScreenOpts ScreenOptsType `json:"screenopts"`
|
||||
OwnerId string `json:"ownerid"`
|
||||
ShareMode string `json:"sharemode"`
|
||||
WebShareOpts *ScreenWebShareOpts `json:"webshareopts,omitempty"`
|
||||
CurRemote RemotePtrType `json:"curremote"`
|
||||
NextLineNum int64 `json:"nextlinenum"`
|
||||
SelectedLine int64 `json:"selectedline"`
|
||||
Anchor ScreenAnchorType `json:"anchor"`
|
||||
FocusType string `json:"focustype"`
|
||||
Archived bool `json:"archived,omitempty"`
|
||||
ArchivedTs int64 `json:"archivedts,omitempty"`
|
||||
|
||||
// only for updates
|
||||
Full bool `json:"full,omitempty"`
|
||||
@ -431,6 +449,7 @@ func (s *ScreenType) ToMap() map[string]interface{} {
|
||||
rtn["screenopts"] = quickJson(s.ScreenOpts)
|
||||
rtn["ownerid"] = s.OwnerId
|
||||
rtn["sharemode"] = s.ShareMode
|
||||
rtn["webshareopts"] = quickNullableJson(s.WebShareOpts)
|
||||
rtn["curremoteownerid"] = s.CurRemote.OwnerId
|
||||
rtn["curremoteid"] = s.CurRemote.RemoteId
|
||||
rtn["curremotename"] = s.CurRemote.Name
|
||||
@ -451,6 +470,7 @@ func (s *ScreenType) FromMap(m map[string]interface{}) bool {
|
||||
quickSetJson(&s.ScreenOpts, m, "screenopts")
|
||||
quickSetStr(&s.OwnerId, m, "ownerid")
|
||||
quickSetStr(&s.ShareMode, m, "sharemode")
|
||||
quickSetNullableJson(&s.WebShareOpts, m, "webshareopts")
|
||||
quickSetStr(&s.CurRemote.OwnerId, m, "curremoteownerid")
|
||||
quickSetStr(&s.CurRemote.RemoteId, m, "curremoteid")
|
||||
quickSetStr(&s.CurRemote.Name, m, "curremotename")
|
||||
@ -654,6 +674,16 @@ func (ri *RemoteInstance) ToMap() map[string]interface{} {
|
||||
return rtn
|
||||
}
|
||||
|
||||
type ScreenUpdateType struct {
|
||||
UpdateId int64 `json:"updateid"`
|
||||
ScreenId string `json:"screenid"`
|
||||
LineId string `json:"lineid"`
|
||||
UpdateType string `json:"updatetype"`
|
||||
UpdateTs int64 `json:"updatets"`
|
||||
}
|
||||
|
||||
func (ScreenUpdateType) UseDBMap() {}
|
||||
|
||||
type LineType struct {
|
||||
ScreenId string `json:"screenid"`
|
||||
UserId string `json:"userid"`
|
||||
@ -669,7 +699,6 @@ type LineType struct {
|
||||
Ephemeral bool `json:"ephemeral,omitempty"`
|
||||
ContentHeight int64 `json:"contentheight,omitempty"`
|
||||
Star bool `json:"star,omitempty"`
|
||||
Bookmarked bool `json:"bookmarked,omitempty"`
|
||||
Archived bool `json:"archived,omitempty"`
|
||||
Remove bool `json:"remove,omitempty"`
|
||||
}
|
||||
@ -747,15 +776,14 @@ type PlaybookEntry struct {
|
||||
}
|
||||
|
||||
type BookmarkType struct {
|
||||
BookmarkId string `json:"bookmarkid"`
|
||||
CreatedTs int64 `json:"createdts"`
|
||||
CmdStr string `json:"cmdstr"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
Description string `json:"description"`
|
||||
Cmds []base.CommandKey `json:"cmds"`
|
||||
OrderIdx int64 `json:"orderidx"`
|
||||
Remove bool `json:"remove,omitempty"`
|
||||
BookmarkId string `json:"bookmarkid"`
|
||||
CreatedTs int64 `json:"createdts"`
|
||||
CmdStr string `json:"cmdstr"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
Description string `json:"description"`
|
||||
OrderIdx int64 `json:"orderidx"`
|
||||
Remove bool `json:"remove,omitempty"`
|
||||
}
|
||||
|
||||
func (bm *BookmarkType) GetSimpleKey() string {
|
||||
@ -1127,6 +1155,8 @@ func EnsureClientData(ctx context.Context) (*ClientData, error) {
|
||||
if cdata == nil {
|
||||
return nil, fmt.Errorf("no client data found")
|
||||
}
|
||||
dbVersion := tx.GetInt(`SELECT version FROM schema_migrations`)
|
||||
cdata.DBVersion = dbVersion
|
||||
return cdata, nil
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -30,24 +30,25 @@ func (PtyDataUpdate) UpdateType() string {
|
||||
}
|
||||
|
||||
type ModelUpdate struct {
|
||||
Sessions []*SessionType `json:"sessions,omitempty"`
|
||||
ActiveSessionId string `json:"activesessionid,omitempty"`
|
||||
Screens []*ScreenType `json:"screens,omitempty"`
|
||||
ScreenLines *ScreenLinesType `json:"screenlines,omitempty"`
|
||||
Line *LineType `json:"line,omitempty"`
|
||||
Lines []*LineType `json:"lines,omitempty"`
|
||||
Cmd *CmdType `json:"cmd,omitempty"`
|
||||
CmdLine *CmdLineType `json:"cmdline,omitempty"`
|
||||
Info *InfoMsgType `json:"info,omitempty"`
|
||||
ClearInfo bool `json:"clearinfo,omitempty"`
|
||||
Remotes []interface{} `json:"remotes,omitempty"` // []*remote.RemoteState
|
||||
History *HistoryInfoType `json:"history,omitempty"`
|
||||
Interactive bool `json:"interactive"`
|
||||
Connect bool `json:"connect,omitempty"`
|
||||
MainView string `json:"mainview,omitempty"`
|
||||
Bookmarks []*BookmarkType `json:"bookmarks,omitempty"`
|
||||
HistoryViewData *HistoryViewData `json:"historyviewdata,omitempty"`
|
||||
ClientData *ClientData `json:"clientdata,omitempty"`
|
||||
Sessions []*SessionType `json:"sessions,omitempty"`
|
||||
ActiveSessionId string `json:"activesessionid,omitempty"`
|
||||
Screens []*ScreenType `json:"screens,omitempty"`
|
||||
ScreenLines *ScreenLinesType `json:"screenlines,omitempty"`
|
||||
Line *LineType `json:"line,omitempty"`
|
||||
Lines []*LineType `json:"lines,omitempty"`
|
||||
Cmd *CmdType `json:"cmd,omitempty"`
|
||||
CmdLine *CmdLineType `json:"cmdline,omitempty"`
|
||||
Info *InfoMsgType `json:"info,omitempty"`
|
||||
ClearInfo bool `json:"clearinfo,omitempty"`
|
||||
Remotes []interface{} `json:"remotes,omitempty"` // []*remote.RemoteState
|
||||
History *HistoryInfoType `json:"history,omitempty"`
|
||||
Interactive bool `json:"interactive"`
|
||||
Connect bool `json:"connect,omitempty"`
|
||||
MainView string `json:"mainview,omitempty"`
|
||||
Bookmarks []*BookmarkType `json:"bookmarks,omitempty"`
|
||||
SelectedBookmark string `json:"selectedbookmark,omitempty"`
|
||||
HistoryViewData *HistoryViewData `json:"historyviewdata,omitempty"`
|
||||
ClientData *ClientData `json:"clientdata,omitempty"`
|
||||
}
|
||||
|
||||
func (ModelUpdate) UpdateType() string {
|
||||
|
Loading…
Reference in New Issue
Block a user