-
Notifications
You must be signed in to change notification settings - Fork 0
/
userhandler.go
137 lines (115 loc) · 3.53 KB
/
userhandler.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
134
135
136
137
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/bikedataproject/go-bike-data-lib/dbmodel"
log "github.com/sirupsen/logrus"
)
// HandleExpiringUsers : Handle users which are about to time out
func HandleExpiringUsers() {
for {
// Load expiring users
users, err := db.GetExpiringUsers()
if err != nil {
log.Warn(err)
}
// Handle expiring users
for _, user := range users {
newUser, err := out.RefreshUserSubscription(&user)
if err != nil {
log.Warnf("Could not refresh user subscription: %v", err)
}
if err = db.UpdateUser(&newUser); err != nil {
log.Warnf("Could not update user: %v", err)
}
}
// Loop every 10 minutes
time.Sleep(10 * time.Minute)
}
}
// HandleNewUsers : Handle the registration of a new user
func HandleNewUsers() {
for {
if users, err := db.FetchNewUsers(); err != nil {
log.Warnf("Could not fetch new users: %v", err)
} else {
// Check if there are any users to process
if len(users) > 0 {
log.Infof("Fetching Strava activities for %v new users", len(users))
// Iterate over new users
for _, user := range users {
if err := FetchNewUserActivities(&user); err != nil {
log.Errorf("Could not store new user activities: %v", err)
} else {
log.Infof("Fetching user activities for user %v was successfull", user.ID)
}
user.IsHistoryFetched = true
if err := db.UpdateUser(&user); err != nil {
log.Errorf("Something went wrong updating the user: %v", err)
}
}
}
}
// Loop every 10 minutes
time.Sleep(10 * time.Second)
}
}
// FetchNewUserActivities : Handle storing "old" activities of a new user
func FetchNewUserActivities(user *dbmodel.User) error {
// Fetch activities for user
var activities []*StravaActivity
client := &http.Client{}
// Allow 20000 activities max
for page := 1; page < 100; page++ {
req, err := http.NewRequest("GET", fmt.Sprintf("https://www.strava.com/api/v3/athlete/activities?per_page=%v&page=%v", MaxActivities, page), nil)
if err != nil {
return fmt.Errorf("Could not get user activities: %v", err)
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", user.AccessToken))
res, err := client.Do(req)
if err != nil {
return fmt.Errorf("Could not make request: %v", err)
}
// Except HTTP 429: too many requests
if res.StatusCode == 429 {
log.Warnf("Strava request limit has been reached - storing in database what we have")
break
}
defer res.Body.Close()
// Attempt to decode response
var tmpAct []*StravaActivity
err = json.NewDecoder(res.Body).Decode(&tmpAct)
if err != nil || len(tmpAct) < 1 {
return fmt.Errorf("Could not fetch user activities: %v", err)
}
// Add to global array
for _, act := range tmpAct {
activities = append(activities, act)
}
// Check if there's no more - should be if the len is 200
if len(tmpAct) < (200 * page) {
break
}
}
log.Infof("Fetching %v activities from strava user %v", len(activities), user.ProviderUser)
// Write activities to database
for _, act := range activities {
// Check for cycling type & convert activity to contribution
if act.Type == "Ride" && act.WorkoutType == 10 {
contrib, err := act.ConvertToContribution()
if err != nil {
log.Warnf("Could not convert activity to contribution: %v", err)
}
// Get contribution in database
err = db.AddContribution(&contrib, user)
if err != nil {
log.Warnf("Could not upload contribution to database: %v", err)
} else {
log.Infof("Added contribution to database")
}
}
}
return nil
}