From 26ef93c1afb821572b57e43248e7d98550ac9be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Sun, 25 Apr 2021 09:21:21 +0200 Subject: [PATCH] chore: minor refactorings to custom time parsing logic --- README.md | 7 ++++--- models/shared.go | 27 ++++++++++++--------------- scripts/sample_data.py | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index fa65c04..5642ae6 100644 --- a/README.md +++ b/README.md @@ -117,13 +117,14 @@ $ ./wakapi #### Compile & Run ```bash -# Adapt config to your needs -$ cp config.default.yml config.yml -$ vi config.yml # Build the executable $ go build -o wakapi +# Adapt config to your needs +$ cp config.default.yml config.yml +$ vi config.yml + # Run it $ ./wakapi ``` diff --git a/models/shared.go b/models/shared.go index ecd6b94..ab75246 100644 --- a/models/shared.go +++ b/models/shared.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "gorm.io/gorm" - "math" "strconv" "strings" "time" @@ -30,24 +29,24 @@ type Interval struct { End time.Time } +// CustomTime is a wrapper type around time.Time, mainly used for the purpose of transparently unmarshalling Python timestamps in the format . (e.g. 1619335137.3324468) type CustomTime time.Time func (j *CustomTime) MarshalJSON() ([]byte, error) { - return json.Marshal(j.String()) + return json.Marshal(j.T()) } func (j *CustomTime) UnmarshalJSON(b []byte) error { - s := strings.Replace(strings.Trim(string(b), "\""), ".", "", 1) - i, err := strconv.ParseInt(s, 10, 64) + s := strings.Trim(string(b), "\"") + ts, err := strconv.ParseFloat(s, 64) if err != nil { return err } - t := time.Unix(0, i*int64(math.Pow10(19-len(s)))) + t := time.Unix(0, int64(ts*1e9)) // ms to ns *j = CustomTime(t) return nil } -// heartbeat timestamps arrive as strings for sqlite and as time.Time for postgres func (j *CustomTime) Scan(value interface{}) error { var ( t time.Time @@ -56,13 +55,12 @@ func (j *CustomTime) Scan(value interface{}) error { switch value.(type) { case string: + // with sqlite, some queries (like GetLastByUser()) return dates as strings, + // however, most of the time they are returned as time.Time t, err = time.Parse("2006-01-02 15:04:05-07:00", value.(string)) if err != nil { return errors.New(fmt.Sprintf("unsupported date time format: %s", value)) } - case int64: - t = time.Unix(0, value.(int64)) - break case time.Time: t = value.(time.Time) break @@ -76,18 +74,17 @@ func (j *CustomTime) Scan(value interface{}) error { return nil } -func (j *CustomTime) Hash() (uint64, error) { - return uint64((j.T().UnixNano() / 1000) / 1000), nil -} - func (j CustomTime) Value() (driver.Value, error) { t := time.Unix(0, j.T().UnixNano()/int64(time.Millisecond)*int64(time.Millisecond)) // round to millisecond precision return t, nil } +func (j *CustomTime) Hash() (uint64, error) { + return uint64((j.T().UnixNano() / 1000) / 1000), nil +} + func (j CustomTime) String() string { - t := time.Time(j) - return t.Format("2006-01-02 15:04:05.000") + return j.T().String() } func (j CustomTime) T() time.Time { diff --git a/scripts/sample_data.py b/scripts/sample_data.py index 64dd569..4ff9ef1 100644 --- a/scripts/sample_data.py +++ b/scripts/sample_data.py @@ -272,7 +272,7 @@ def run(params: ConfigParams, update_progress: Callable[[int], None]): else: for d in data: post_data_sync([d], f'{params.api_url}/heartbeats', params.api_key) - update_progress(len(d)) + update_progress(1) if __name__ == '__main__':