2019-05-05 23:36:49 +03:00
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
2019-05-11 18:49:56 +03:00
|
|
|
"database/sql/driver"
|
|
|
|
"errors"
|
2019-05-21 18:16:46 +03:00
|
|
|
"regexp"
|
2019-05-05 23:36:49 +03:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type HeartbeatReqTime time.Time
|
|
|
|
|
|
|
|
type Heartbeat struct {
|
2019-10-11 09:00:02 +03:00
|
|
|
ID uint `gorm:"primary_key"`
|
|
|
|
User *User `json:"-" gorm:"not null"`
|
|
|
|
UserID string `json:"-" gorm:"not null; index:idx_time_user"`
|
|
|
|
Entity string `json:"entity" gorm:"not null; index:idx_entity"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Category string `json:"category"`
|
|
|
|
Project string `json:"project"`
|
|
|
|
Branch string `json:"branch"`
|
|
|
|
Language string `json:"language" gorm:"index:idx_language"`
|
|
|
|
IsWrite bool `json:"is_write"`
|
|
|
|
Editor string `json:"editor"`
|
|
|
|
OperatingSystem string `json:"operating_system"`
|
|
|
|
Time HeartbeatReqTime `json:"time" gorm:"type:timestamp; default:now(); index:idx_time,idx_time_user"`
|
2019-05-21 18:16:46 +03:00
|
|
|
languageRegex *regexp.Regexp
|
2019-05-11 18:49:56 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Heartbeat) Valid() bool {
|
2019-10-11 09:00:02 +03:00
|
|
|
return h.User != nil && h.UserID != "" && h.Time != HeartbeatReqTime(time.Time{})
|
2019-05-05 23:36:49 +03:00
|
|
|
}
|
|
|
|
|
2019-05-21 18:16:46 +03:00
|
|
|
func (h *Heartbeat) Augment(customLangs map[string]string) {
|
|
|
|
if h.Language == "" {
|
|
|
|
if h.languageRegex == nil {
|
|
|
|
h.languageRegex = regexp.MustCompile(`^.+\.(.+)$`)
|
|
|
|
}
|
|
|
|
groups := h.languageRegex.FindAllStringSubmatch(h.Entity, -1)
|
|
|
|
if len(groups) == 0 || len(groups[0]) != 2 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
ending := groups[0][1]
|
|
|
|
if _, ok := customLangs[ending]; !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
h.Language, _ = customLangs[ending]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-05 23:36:49 +03:00
|
|
|
func (j *HeartbeatReqTime) UnmarshalJSON(b []byte) error {
|
|
|
|
s := strings.Split(strings.Trim(string(b), "\""), ".")[0]
|
|
|
|
i, err := strconv.ParseInt(s, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t := time.Unix(i, 0)
|
|
|
|
*j = HeartbeatReqTime(t)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-05-11 18:49:56 +03:00
|
|
|
func (j *HeartbeatReqTime) Scan(value interface{}) error {
|
|
|
|
switch value.(type) {
|
|
|
|
case int64:
|
|
|
|
*j = HeartbeatReqTime(time.Unix(123456, 0))
|
|
|
|
break
|
|
|
|
case time.Time:
|
|
|
|
*j = HeartbeatReqTime(value.(time.Time))
|
|
|
|
break
|
|
|
|
default:
|
2019-11-08 01:11:19 +03:00
|
|
|
return errors.New("unsupported type")
|
2019-05-11 18:49:56 +03:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j HeartbeatReqTime) Value() (driver.Value, error) {
|
|
|
|
return time.Time(j), nil
|
|
|
|
}
|
|
|
|
|
2019-05-05 23:36:49 +03:00
|
|
|
func (j HeartbeatReqTime) String() string {
|
|
|
|
t := time.Time(j)
|
|
|
|
return t.Format("2006-01-02 15:04:05")
|
|
|
|
}
|
2019-05-17 03:05:38 +03:00
|
|
|
|
|
|
|
func (j HeartbeatReqTime) Time() time.Time {
|
|
|
|
return time.Time(j)
|
|
|
|
}
|