X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=gfitsync.go;h=f913134e17863aea85b370974e05dba4e07cba76;hb=e694a51522759a7ed60ee8170b7541bd38fef764;hp=28c0685533854377b04ca6f2b1295a04cf53d823;hpb=059b0aebeffa117c539a98678950c10c0f69a73d;p=kraftakt.git diff --git a/gfitsync.go b/gfitsync.go index 28c0685..f913134 100644 --- a/gfitsync.go +++ b/gfitsync.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "net/http" + "sync" "time" "github.com/octo/gfitsync/app" @@ -125,8 +126,11 @@ func fitbitGrantHandler(ctx context.Context, w http.ResponseWriter, r *http.Requ return err } - if err := c.Subscribe(ctx, "activities"); err != nil { - return fmt.Errorf("c.Subscribe() = %v", err) + for _, collection := range []string{"activities", "sleep"} { + if err := c.Subscribe(ctx, collection); err != nil { + return fmt.Errorf("c.Subscribe(%q) = %v", collection, err) + } + log.Infof(ctx, "Successfully subscribed to %q", collection) } redirectURL := r.URL @@ -228,52 +232,126 @@ func handleNotification(ctx context.Context, s *fitbit.Subscription) error { return err } - profile, err := fitbitClient.Profile(ctx) - if err != nil { - return err + var ( + wg = &sync.WaitGroup{} + errs appengine.MultiError + summary *fitbit.ActivitySummary + profile *fitbit.Profile + ) + + wg.Add(1) + go func() { + var err error + summary, err = fitbitClient.ActivitySummary(ctx, s.Date) + if err != nil { + errs = append(errs, fmt.Errorf("fitbitClient.ActivitySummary(%q) = %v", s.Date, err)) + } + wg.Done() + }() + + wg.Add(1) + go func() { + var err error + profile, err = fitbitClient.Profile(ctx) + if err != nil { + errs = append(errs, fmt.Errorf("fitbitClient.Profile(%q) = %v", s.Date, err)) + } + wg.Done() + }() + + wg.Wait() + if len(errs) != 0 { + return errs } - log.Debugf(ctx, "profile = %+v", profile) tm, err := time.ParseInLocation("2006-01-02", s.Date, profile.Timezone) if err != nil { return err } - summary, err := fitbitClient.ActivitySummary(tm) - if err != nil { - return err - } log.Debugf(ctx, "%s (%s) took %d steps on %s", - profile.Name, u.Email, summary.Summary.Steps, s.Date) + profile.Name, u.Email, summary.Summary.Steps, tm) gfitClient, err := gfit.NewClient(ctx, u) if err != nil { return err } - if err := gfitClient.SetSteps(ctx, summary.Summary.Steps, tm); err != nil { - return fmt.Errorf("gfitClient.SetSteps(%d) = %v", summary.Summary.Steps, err) - } + wg.Add(1) + go func() { + if err := gfitClient.SetSteps(ctx, summary.Summary.Steps, tm); err != nil { + errs = append(errs, fmt.Errorf("gfitClient.SetSteps(%d) = %v", summary.Summary.Steps, err)) + } + wg.Done() + }() - if err := gfitClient.SetCalories(ctx, summary.Summary.CaloriesOut, tm); err != nil { - return fmt.Errorf("gfitClient.SetCalories(%d) = %v", summary.Summary.CaloriesOut, err) - } + wg.Add(1) + go func() { + if err := gfitClient.SetCalories(ctx, summary.Summary.CaloriesOut, tm); err != nil { + errs = append(errs, fmt.Errorf("gfitClient.SetCalories(%d) = %v", summary.Summary.CaloriesOut, err)) + } + wg.Done() + }() + + wg.Add(1) + go func() { + defer wg.Done() + + var distanceMeters float64 + for _, d := range summary.Summary.Distances { + if d.Activity != "total" { + continue + } + distanceMeters = 1000.0 * d.Distance + break + } + if err := gfitClient.SetDistance(ctx, distanceMeters, tm); err != nil { + errs = append(errs, fmt.Errorf("gfitClient.SetDistance(%d) = %v", distanceMeters, err)) + return + } + }() - var distanceMeters float64 - for _, d := range summary.Summary.Distances { - if d.Activity != "total" { - continue + wg.Add(1) + go func() { + if err := gfitClient.SetHeartRate(ctx, summary.Summary.HeartRateZones, summary.Summary.RestingHeartRate, tm); err != nil { + errs = append(errs, fmt.Errorf("gfitClient.SetHeartRate() = %v", err)) } - distanceMeters = 1000.0 * d.Distance - break - } - if err := gfitClient.SetDistance(ctx, distanceMeters, tm); err != nil { - return fmt.Errorf("gfitClient.SetDistance(%d) = %v", distanceMeters, err) - } + wg.Done() + }() + + wg.Add(1) + go func() { + defer wg.Done() + + var activities []gfit.Activity + for _, a := range summary.Activities { + if !a.HasStartTime { + continue + } + + startTime, err := time.ParseInLocation("2006-01-02T15:04:05", a.StartDate+"T"+a.StartTime, profile.Timezone) + if err != nil { + errs = append(errs, fmt.Errorf("gfitClient.SetActivities() = %v", err)) + return + } + endTime := startTime.Add(time.Duration(a.Duration) * time.Millisecond) + + activities = append(activities, gfit.Activity{ + Start: startTime, + End: endTime, + Type: gfit.ParseFitbitActivity(a.Name), + }) + } + if err := gfitClient.SetActivities(ctx, activities, tm); err != nil { + errs = append(errs, fmt.Errorf("gfitClient.SetActivities() = %v", err)) + return + } + }() - if err := gfitClient.SetHeartRate(ctx, summary.Summary.HeartRateZones, summary.Summary.RestingHeartRate, tm); err != nil { - return fmt.Errorf("gfitClient.SetHeartRate() = %v", err) - } + wg.Wait() + if len(errs) != 0 { + return errs + } return nil }