X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=gfit%2Fgfit.go;h=9a1c6f42fd33d1dd18eceddf56116e40a9c144a3;hb=0a346a38e86f8c40df7ab4e871b3a416e0783b39;hp=ec88b1984e1900a2175e9ba9fdb200be2eda93de;hpb=5b245cc42860c980c321c1c1829cdc373d53ac53;p=kraftakt.git diff --git a/gfit/gfit.go b/gfit/gfit.go index ec88b19..9a1c6f4 100644 --- a/gfit/gfit.go +++ b/gfit/gfit.go @@ -9,7 +9,6 @@ import ( "github.com/octo/kraftakt/app" "github.com/octo/kraftakt/fitbit" - "github.com/octo/retry" "golang.org/x/oauth2" oauth2google "golang.org/x/oauth2/google" fitness "google.golang.org/api/fitness/v1" @@ -119,28 +118,8 @@ func DataStreamID(dataSource *fitness.DataSource) string { return strings.Join(fields, ":") } -func wrapGoogleError(err error) error { - if err == nil { - return nil - } - - if gerr, ok := err.(*googleapi.Error); ok && gerr.Code >= 400 && gerr.Code < 500 { - return retry.Abort(err) - } - - return err -} - func (c *Client) DataSourceCreate(ctx context.Context, dataSource *fitness.DataSource) (string, error) { - var dataStreamID string - err := retry.Do(ctx, func(ctx context.Context) error { - res, err := c.Service.Users.DataSources.Create(userID, dataSource).Context(ctx).Do() - if err != nil { - return wrapGoogleError(err) - } - dataStreamID = res.DataStreamId - return nil - }) + res, err := c.Service.Users.DataSources.Create(userID, dataSource).Context(ctx).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == http.StatusConflict { if dataSource.DataStreamId != "" { @@ -148,29 +127,20 @@ func (c *Client) DataSourceCreate(ctx context.Context, dataSource *fitness.DataS } return DataStreamID(dataSource), nil } - log.Errorf(ctx, "c.Service.Users.DataSources.Create(%q) = %v", DataStreamID(dataSource), err) - return "", err + return "", fmt.Errorf("DataSources.Create(%q) = %v", DataStreamID(dataSource), err) } - return dataStreamID, nil + + return res.DataStreamId, nil } -func (c *Client) DatasetGet(ctx context.Context, dataStreamID string, startTime, endTime time.Time) (*fitness.Dataset, error) { +func (c *Client) DatasetGet(ctx context.Context, dataSourceID string, startTime, endTime time.Time) (*fitness.Dataset, error) { datasetID := fmt.Sprintf("%d-%d", startTime.UnixNano(), endTime.UnixNano()) - var dataset *fitness.Dataset - err := retry.Do(ctx, func(ctx context.Context) error { - res, err := c.Service.Users.DataSources.Datasets.Get(userID, dataStreamID, datasetID).Context(ctx).Do() - if err != nil { - return wrapGoogleError(err) - } - dataset = res - return nil - }) + res, err := c.Service.Users.DataSources.Datasets.Get(userID, dataSourceID, datasetID).Context(ctx).Do() if err != nil { - log.Errorf(ctx, "c.Service.Users.DataSources.Datasets.Get(%q, %q) = %v", dataStreamID, datasetID, err) - return nil, err + return nil, fmt.Errorf("DataSources.Datasets.Get(%q, %q) = %v", dataSourceID, datasetID, err) } - return dataset, nil + return res, nil } func (c *Client) DatasetPatch(ctx context.Context, dataSourceID string, points []*fitness.DataPoint) error { @@ -192,19 +162,16 @@ func (c *Client) DatasetPatch(ctx context.Context, dataSourceID string, points [ Point: points, } - err := retry.Do(ctx, func(ctx context.Context) error { - _, err := c.Service.Users.DataSources.Datasets.Patch(userID, dataSourceID, datasetID, dataset).Context(ctx).Do() - return wrapGoogleError(err) - }) + _, err := c.Service.Users.DataSources.Datasets.Patch(userID, dataSourceID, datasetID, dataset).Context(ctx).Do() if err != nil { - log.Errorf(ctx, "c.Service.Users.DataSources.Datasets.Patch() = %v", err) + log.Errorf(ctx, "DataSources.Datasets.Patch(%q, %q) = %v", dataSourceID, datasetID, err) return err } return nil } func (c *Client) SetDistance(ctx context.Context, meters float64, startOfDay time.Time) error { - return c.updateCumulative(ctx, + return c.updateIncremental(ctx, &fitness.DataSource{ Application: Application(ctx), DataType: &fitness.DataType{ @@ -226,7 +193,7 @@ func (c *Client) SetDistance(ctx context.Context, meters float64, startOfDay tim } func (c *Client) SetSteps(ctx context.Context, totalSteps int, startOfDay time.Time) error { - return c.updateCumulative(ctx, + return c.updateIncremental(ctx, &fitness.DataSource{ Application: Application(ctx), DataType: &fitness.DataType{ @@ -248,7 +215,7 @@ func (c *Client) SetSteps(ctx context.Context, totalSteps int, startOfDay time.T } func (c *Client) SetCalories(ctx context.Context, totalCalories float64, startOfDay time.Time) error { - return c.updateCumulative(ctx, + return c.updateIncremental(ctx, &fitness.DataSource{ Application: Application(ctx), DataType: &fitness.DataType{ @@ -272,11 +239,11 @@ func (c *Client) SetCalories(ctx context.Context, totalCalories float64, startOf type Activity struct { Start time.Time End time.Time - Type int64 + Type string } func (a Activity) String() string { - return fmt.Sprintf("%s-%s %d", a.Start.Format("15:04:05"), a.End.Format("15:04:05"), a.Type) + return fmt.Sprintf("%s-%s %q", a.Start.Format("15:04:05"), a.End.Format("15:04:05"), a.Type) } func (c *Client) SetActivities(ctx context.Context, activities []Activity, startOfDay time.Time) error { @@ -313,9 +280,10 @@ Next: for _, a := range activities { startTimeNanos := a.Start.UnixNano() endTimeNanos := a.End.UnixNano() + activityType := ParseFitbitActivity(a.Type) for _, p := range dataset.Point { - if p.StartTimeNanos == startTimeNanos && p.EndTimeNanos == endTimeNanos && p.Value[0].IntVal == a.Type { + if p.StartTimeNanos == startTimeNanos && p.EndTimeNanos == endTimeNanos && p.Value[0].IntVal == activityType { log.Debugf(ctx, "activity %s already stored in Google Fit", a) continue Next } @@ -327,7 +295,7 @@ Next: StartTimeNanos: startTimeNanos, EndTimeNanos: endTimeNanos, Value: []*fitness.Value{ - &fitness.Value{IntVal: a.Type}, + &fitness.Value{IntVal: activityType}, }, }) } @@ -339,7 +307,7 @@ Next: return c.DatasetPatch(ctx, dataStreamID, dataPoints) } -func (c *Client) updateCumulative(ctx context.Context, dataSource *fitness.DataSource, rawValue *fitness.Value, startOfDay time.Time) error { +func (c *Client) updateIncremental(ctx context.Context, dataSource *fitness.DataSource, rawValue *fitness.Value, startOfDay time.Time) error { switch f := dataSource.DataType.Field[0].Format; f { case "integer": if rawValue.IntVal == 0 { @@ -360,30 +328,30 @@ func (c *Client) updateCumulative(ctx context.Context, dataSource *fitness.DataS dataSource.DataStreamId = dataSourceID endOfDay := startOfDay.Add(24 * time.Hour).Add(-1 * time.Nanosecond) - currValue, startTime, err := c.readCumulative(ctx, dataSource, startOfDay, endOfDay) + storedValue, startTime, err := c.readIncremental(ctx, dataSource, startOfDay, endOfDay) if err != nil { return err } var diffValue fitness.Value if dataSource.DataType.Field[0].Format == "integer" { - if rawValue.IntVal == currValue.IntVal { + if storedValue.IntVal > rawValue.IntVal { + log.Warningf(ctx, "stored value (%d) is larger than new value (%d)", storedValue.IntVal, rawValue.IntVal) return nil } - diffValue.IntVal = rawValue.IntVal - currValue.IntVal - if diffValue.IntVal < 0 { - log.Warningf(ctx, "stored value (%d) is larger than new value (%d); assuming count was reset", currValue.IntVal, rawValue.IntVal) - diffValue.IntVal = rawValue.IntVal + if rawValue.IntVal == storedValue.IntVal { + return nil } + diffValue.IntVal = rawValue.IntVal - storedValue.IntVal } else { // if dataSource.DataType.Field[0].Format == "floatPoint" - if rawValue.FpVal == currValue.FpVal { + if storedValue.FpVal > rawValue.FpVal { + log.Warningf(ctx, "stored value (%g) is larger than new value (%g)", storedValue.FpVal, rawValue.FpVal) return nil } - diffValue.FpVal = rawValue.FpVal - currValue.FpVal - if diffValue.FpVal < 0 { - log.Warningf(ctx, "stored value (%g) is larger than new value (%g); assuming count was reset", currValue.FpVal, rawValue.FpVal) - diffValue.FpVal = rawValue.FpVal + if rawValue.FpVal == storedValue.FpVal { + return nil } + diffValue.FpVal = rawValue.FpVal - storedValue.FpVal } endTime := endOfDay @@ -402,7 +370,7 @@ func (c *Client) updateCumulative(ctx context.Context, dataSource *fitness.DataS }) } -func (c *Client) readCumulative(ctx context.Context, dataSource *fitness.DataSource, startTime, endTime time.Time) (*fitness.Value, time.Time, error) { +func (c *Client) readIncremental(ctx context.Context, dataSource *fitness.DataSource, startTime, endTime time.Time) (*fitness.Value, time.Time, error) { dataset, err := c.DatasetGet(ctx, dataSource.DataStreamId, startTime, endTime) if err != nil { return nil, time.Time{}, err