"encoding/json"
"fmt"
"io/ioutil"
+ "sort"
"time"
"google.golang.org/appengine/log"
Stages []SleepStage
}
+type byTime []SleepStage
+
+func (t byTime) Len() int { return len(t) }
+func (t byTime) Less(i, j int) bool { return t[i].StartTime.Before(t[j].StartTime) }
+func (t byTime) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
+
func parseSleep(ctx context.Context, data []byte, loc *time.Location) (*Sleep, error) {
type rawData struct {
DateTime string
Level string
Seconds int64
}
- var jsonSleep struct {
- Levels struct {
- Data []rawData
- ShortData []rawData
+ var parsed struct {
+ Sleep []struct {
+ Levels struct {
+ Data []rawData
+ ShortData []rawData
+ }
}
}
- if err := json.Unmarshal(data, &jsonSleep); err != nil {
+ if err := json.Unmarshal(data, &parsed); err != nil {
return nil, err
}
- rawStages := jsonSleep.Levels.Data
- if len(jsonSleep.Levels.ShortData) != 0 {
- rawStages = append(rawStages, jsonSleep.Levels.ShortData...)
+ var allStages []rawData
+ for _, s := range parsed.Sleep {
+ if len(s.Levels.Data) != 0 {
+ allStages = append(allStages, s.Levels.Data...)
+ }
+ if len(s.Levels.ShortData) != 0 {
+ allStages = append(allStages, s.Levels.ShortData...)
+ }
}
var ret Sleep
- for _, stg := range rawStages {
+ for _, stg := range allStages {
tm, err := time.ParseInLocation("2006-01-02T15:04:05.999", stg.DateTime, loc)
if err != nil {
log.Warningf(ctx, "unable to parse time: %q", stg.DateTime)
})
}
- if len(ret.Stages) == 0 && len(jsonSleep.Levels.Data) != 0 {
+ if len(ret.Stages) == 0 && len(allStages) != 0 {
return nil, fmt.Errorf("parsing sleep stages failed")
}
+ sort.Sort(byTime(ret.Stages))
+
return &ret, nil
}