mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-03-02 04:02:13 +01:00
new API for client to log activity
This commit is contained in:
parent
db727b232f
commit
64ec186fa0
@ -46,6 +46,12 @@ var GlobalLock = &sync.Mutex{}
|
||||
var WSStateMap = make(map[string]*scws.WSState) // clientid -> WsState
|
||||
var GlobalAuthKey string
|
||||
|
||||
type ClientActiveState struct {
|
||||
Fg bool `json:"fg"`
|
||||
Active bool `json:"active"`
|
||||
Open bool `json:"open"`
|
||||
}
|
||||
|
||||
func setWSState(state *scws.WSState) {
|
||||
GlobalLock.Lock()
|
||||
defer GlobalLock.Unlock()
|
||||
@ -150,6 +156,34 @@ func HandleSetWinSize(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// params: fg, active, open
|
||||
func HandleLogActiveState(w http.ResponseWriter, r *http.Request) {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
var activeState ClientActiveState
|
||||
err := decoder.Decode(&activeState)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("error decoding json: %w", err))
|
||||
return
|
||||
}
|
||||
activity := sstore.ActivityUpdate{}
|
||||
if activeState.Fg {
|
||||
activity.FgMinutes = 1
|
||||
}
|
||||
if activeState.Active {
|
||||
activity.ActiveMinutes = 1
|
||||
}
|
||||
if activeState.Open {
|
||||
activity.OpenMinutes = 1
|
||||
}
|
||||
err = sstore.UpdateCurrentActivity(r.Context(), activity)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("error updating activity: %w", err))
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, true)
|
||||
return
|
||||
}
|
||||
|
||||
// params: sessionid, windowid
|
||||
func HandleGetWindow(w http.ResponseWriter, r *http.Request) {
|
||||
qvals := r.URL.Query()
|
||||
@ -461,6 +495,7 @@ func main() {
|
||||
gr.HandleFunc("/api/run-command", AuthKeyWrap(HandleRunCommand)).Methods("POST")
|
||||
gr.HandleFunc("/api/get-client-data", AuthKeyWrap(HandleGetClientData))
|
||||
gr.HandleFunc("/api/set-winsize", AuthKeyWrap(HandleSetWinSize))
|
||||
gr.HandleFunc("/api/log-active-state", AuthKeyWrap(HandleLogActiveState))
|
||||
serverAddr := MainServerAddr
|
||||
if scbase.IsDevMode() {
|
||||
serverAddr = MainServerDevAddr
|
||||
|
1
db/migrations/000002_activity.down.sql
Normal file
1
db/migrations/000002_activity.down.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE activity;
|
12
db/migrations/000002_activity.up.sql
Normal file
12
db/migrations/000002_activity.up.sql
Normal file
@ -0,0 +1,12 @@
|
||||
CREATE TABLE activity (
|
||||
day varchar(20) PRIMARY KEY,
|
||||
uploaded boolean NOT NULL,
|
||||
numlines int NOT NULL,
|
||||
activeminutes int NOT NULL,
|
||||
fgminutes int NOT NULL,
|
||||
openminutes int NOT NULL,
|
||||
tzname varchar(50) NOT NULL,
|
||||
tzoffset int NOT NULL,
|
||||
clientversion varchar(20) NOT NULL,
|
||||
clientarch varchar(20) NOT NULL
|
||||
);
|
@ -318,3 +318,7 @@ func NumFormatB2(num int64) string {
|
||||
return signStr + strconv.FormatFloat(gVal, 'f', 2, 64) + "G"
|
||||
}
|
||||
}
|
||||
|
||||
func ClientArch() string {
|
||||
return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
@ -1837,3 +1837,51 @@ func GetRIsForWindow(ctx context.Context, sessionId string, windowId string) ([]
|
||||
}
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error {
|
||||
now := time.Now()
|
||||
dayStr := now.Format("2006-01-02")
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT day FROM activity WHERE day = ?`
|
||||
if !tx.Exists(query, dayStr) {
|
||||
query = `INSERT INTO activity (day, uploaded, numlines, fgminutes, activeminutes, openminutes, tzname, tzoffset, clientversion, clientarch)
|
||||
VALUES (?, 0, 0, 0, 0, 0, ?, ?, ?, ?)`
|
||||
tzName, tzOffset := now.Zone()
|
||||
if len(tzName) > MaxTzNameLen {
|
||||
tzName = tzName[0:MaxTzNameLen]
|
||||
}
|
||||
tx.ExecWrap(query, dayStr, tzName, tzOffset, scbase.PromptVersion, scbase.ClientArch())
|
||||
}
|
||||
query = `UPDATE activity SET numlines = numlines + ?, fgminutes = fgminutes + ?, activeminutes = activeminutes + ?, openminutes = openminutes + ? WHERE day = ?`
|
||||
tx.ExecWrap(query, update.NumLines, update.FgMinutes, update.ActiveMinutes, update.OpenMinutes, dayStr)
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
return txErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetNonUploadedActivity(ctx context.Context) ([]*ActivityType, error) {
|
||||
var rtn []*ActivityType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT * FROM activity WHERE uploaded = 0 ORDER BY day DESC LIMIT 30`
|
||||
tx.SelectWrap(&rtn, query)
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
return nil, txErr
|
||||
}
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
func MarkActivityAsUploaded(ctx context.Context, activityArr []*ActivityType) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `UPDATE activity SET uploaded = 1 WHERE day = ?`
|
||||
for _, activity := range activityArr {
|
||||
tx.ExecWrap(query, activity.Day)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ const (
|
||||
SWFocusCmdFg = "cmd-fg"
|
||||
)
|
||||
|
||||
const MaxTzNameLen = 50
|
||||
|
||||
var globalDBLock = &sync.Mutex{}
|
||||
var globalDB *sqlx.DB
|
||||
var globalDBErr error
|
||||
@ -110,6 +112,26 @@ type ClientWinSizeType struct {
|
||||
FullScreen bool `json:"fullscreen,omitempty"`
|
||||
}
|
||||
|
||||
type ActivityUpdate struct {
|
||||
FgMinutes int
|
||||
ActiveMinutes int
|
||||
OpenMinutes int
|
||||
NumLines int
|
||||
}
|
||||
|
||||
type ActivityType struct {
|
||||
Day string `json:"day"`
|
||||
Uploaded bool `json:"-"`
|
||||
NumLines int `json:"numlines"`
|
||||
ActiveMinutes int `json:"activeminutes"`
|
||||
FgMinutes int `json:"fgminutes"`
|
||||
OpenMinutes int `json:"openminutes"`
|
||||
TzName string `json:"tzname"`
|
||||
TzOffset int `json:"tzoffset"`
|
||||
ClientVersion string `json:"clientversion"`
|
||||
ClientArch string `json:"clientarch"`
|
||||
}
|
||||
|
||||
type ClientData struct {
|
||||
ClientId string `json:"clientid"`
|
||||
UserId string `json:"userid"`
|
||||
|
Loading…
Reference in New Issue
Block a user