This repository has been archived by the owner on Oct 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
133 lines (109 loc) · 3.59 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
//go:generate oapi-codegen --package=main -generate=types -o ./oura.gen.go https://cloud.ouraring.com/v2/static/json/openapi.json
import (
"context"
"flag"
"fmt"
"net/http"
"os"
"time"
// Autoloads .env file to supply environment variables
_ "github.com/joho/godotenv/autoload"
"github.com/lildude/oura"
"github.com/lildude/runalyze"
"golang.org/x/oauth2"
)
var (
version = "dev"
commit, start, end string
yesterday bool
)
func main() {
flag.StringVar(&start, "start", "", "Start date in the format: YYYY-MM-DD. If not provided, defaults to Oura's default of one week ago.")
flag.StringVar(&end, "end", "", "End date in the form: YYYY-MM-DD. If not provided, defaults to Oura's default of today.")
flag.BoolVar(&yesterday, "yesterday", false, "Use yesterday's date as the start date.")
ver := flag.Bool("version", false, "Print the version and exit.")
flag.Parse()
if *ver {
fmt.Printf("oura-to-runalyze %s (commit: %s)", version, commit)
os.Exit(0)
}
if _, ok := os.LookupEnv("OURA_ACCESS_TOKEN"); !ok {
fmt.Printf("%s not set\n", "OURA_ACCESS_TOKEN")
os.Exit(1)
}
if _, ok := os.LookupEnv("RUNALYZE_ACCESS_TOKEN"); !ok {
fmt.Printf("%s not set\n", "RUNALYZE_ACCESS_TOKEN")
os.Exit(1)
}
if yesterday {
start = time.Now().AddDate(0, 0, -1).Format("2006-01-02")
}
ouraClient := newOuraClient()
sleeps, err := getOuraSleep(ouraClient, start, end)
if err != nil {
fmt.Fprintf(os.Stderr, "Problem getting sleep data from Oura: %v\n", err)
os.Exit(1)
}
metrics := createMetrics(*sleeps)
runalyzeClient := newRunalyzeClient()
if err := upLoadMetricsToRunAlyze(runalyzeClient, metrics); err != nil {
fmt.Fprintf(os.Stderr, "Problem uploading metrics to Runalyze: %v\n", err)
os.Exit(1)
}
fmt.Println("Successfully sync'd to Runalyze")
}
func createMetrics(sleeps []oura.Sleep) runalyze.Metrics {
var sleep []runalyze.Sleep
var hrRest []runalyze.HeartRateRest
for _, s := range sleeps {
sleep = append(sleep, runalyze.Sleep{
DateTime: s.BedtimeStart,
Duration: secToMin(s.Total),
RemDuration: secToMin(s.Rem),
LightSleepDuration: secToMin(s.Light),
DeepSleepDuration: secToMin(s.Deep),
AwakeDuration: secToMin(s.Awake),
HrAverage: int(s.HrAverage),
HrLowest: int(s.HrLowest),
Quality: int(s.Score / 10),
})
hrRest = append(hrRest, runalyze.HeartRateRest{
DateTime: s.BedtimeEnd,
HeartRate: int(s.HrLowest),
})
}
metrics := runalyze.Metrics{
HeartRateRest: hrRest,
Sleep: sleep,
}
return metrics
}
type ouraClient interface {
GetSleep(ctx context.Context, start, end string) (*oura.Sleeps, *http.Response, error)
}
func newOuraClient() *oura.Client {
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: os.Getenv("OURA_ACCESS_TOKEN")})
tc := oauth2.NewClient(context.Background(), ts)
cl := *oura.NewClient(tc)
return &cl
}
func getOuraSleep(client ouraClient, start string, end string) (*[]oura.Sleep, error) {
sleep, _, err := client.GetSleep(context.Background(), start, end)
return &sleep.Sleeps, err
}
type runalyzeClient interface {
CreateMetrics(ctx context.Context, metrics runalyze.Metrics) (*http.Response, error)
}
func newRunalyzeClient() *runalyze.Client {
cl := *runalyze.NewClient(os.Getenv("RUNALYZE_ACCESS_TOKEN"))
return &cl
}
func upLoadMetricsToRunAlyze(client runalyzeClient, metrics runalyze.Metrics) error {
_, err := client.CreateMetrics(context.Background(), metrics)
return err
}
func secToMin(sec int) int {
min, _ := time.ParseDuration(fmt.Sprintf("%ds", sec))
return int(min.Minutes() + 0.5)
}