new API for client to log activity

This commit is contained in:
sawka 2023-01-16 23:36:52 -08:00
parent db727b232f
commit 64ec186fa0
6 changed files with 122 additions and 0 deletions

View File

@ -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

View File

@ -0,0 +1 @@
DROP TABLE activity;

View 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
);

View File

@ -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)
}

View File

@ -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
}

View File

@ -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"`