Private
Public Access
1
0

adding strava

This commit is contained in:
Sander Roosendaal
2023-02-11 17:20:02 +01:00
parent da9998eaf1
commit eaedf30369
20 changed files with 474 additions and 626 deletions

View File

@@ -7,7 +7,9 @@ from rowers.views.statements import *
from rowers.plannedsessions import get_dates_timeperiod
from rowers.tasks import fetch_strava_workout
from rowers.integrations.c2 import C2Integration
from rowers.integrations import C2Integration, StravaIntegration
import rowers.integrations.strava as strava
import numpy
@@ -82,8 +84,12 @@ def workout_strava_upload_view(request, id=0):
r = getrower(request.user)
w = get_workout_by_opaqueid(request, id)
result = -1
comment, result = stravastuff.workout_strava_upload(
r.user, w, asynchron=True)
strava_integration = StravaIntegration(request.user)
try:
stravaid = strava_integration.workout_export(w)
except NoTokenError:
return HttpResponseRedirect("/rowers/me/stravaauthorize")
messages.info(
request, 'Your workout will be synchronized to Strava in the background')
@@ -210,21 +216,12 @@ def rower_garmin_authorize(request): # pragma: no cover
@login_required()
def rower_strava_authorize(request): # pragma: no cover
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
# state = str(uuid4())
params = {"client_id": STRAVA_CLIENT_ID,
"response_type": "code",
"redirect_uri": STRAVA_REDIRECT_URI,
"scope": "activity:write,activity:read_all"}
url = "https://www.strava.com/oauth/authorize?" + \
urllib.parse.urlencode(params)
strava_integration = StravaIntegration(request.user)
url = strava_integration.make_authorization_url()
return HttpResponseRedirect(url)
# Polar Authorization
@@ -673,7 +670,7 @@ def workout_nkimport_view(request, userid=0, after=0, before=0):
if (res.status_code != 200): # pragma: no cover
if (res.status_code == 401):
r = getrower(request.user)
if (r.stravatoken == '') or (r.stravatoken is None):
if (r.nktoken == '') or (r.nktoken is None):
s = "Token doesn't exist. Need to authorize"
return HttpResponseRedirect("/rowers/me/nkauthorize/")
message = "Something went wrong in workout_nkimport_view"
@@ -786,6 +783,7 @@ def workout_nkimport_view(request, userid=0, after=0, before=0):
@login_required()
def rower_process_stravacallback(request):
strava_integration = StravaIntegration(request.user)
try:
code = request.GET['code']
_ = request.GET['scope']
@@ -800,7 +798,7 @@ def rower_process_stravacallback(request):
return HttpResponseRedirect(url)
res = stravastuff.get_token(code)
res = strava_integration.get_token(code)
if res[0]:
access_token = res[0]
@@ -815,7 +813,7 @@ def rower_process_stravacallback(request):
r.stravarefreshtoken = refresh_token
r.save()
_ = stravastuff.set_strava_athlete_id(r.user)
_ = strava_integration.set_strava_athlete_id()
successmessage = "Tokens stored. Good to go. Please check your import/export settings"
messages.info(request, successmessage)
@@ -1169,7 +1167,7 @@ def workout_rojaboimport_view(request, message="", userid=0):
},
{
'url': reverse('workout_rojaboimport_view'),
'name': 'Strava'
'name': 'Rojabo'
},
]
@@ -1197,130 +1195,69 @@ def workout_stravaimport_view(request, message="", userid=0):
url = reverse('workout_stravaimport_view',
kwargs={'userid': request.user.id})
return HttpResponseRedirect(url)
# if r.user != request.user:
# messages.info(request,"You cannot import other people's workouts from Strava")
strava_integration = StravaIntegration(request.user)
try:
_ = strava_open(request.user)
_ = strava_integration.open()
except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/stravaauthorize/")
res = stravastuff.get_strava_workout_list(request.user)
workouts = strava_integration.get_workout_list()
if (res.status_code != 200): # pragma: no cover
if (res.status_code == 401):
r = getrower(request.user)
if (r.stravatoken == '') or (r.stravatoken is None):
s = "Token doesn't exist. Need to authorize"
return HttpResponseRedirect("/rowers/me/stravaauthorize/")
message = "Something went wrong in workout_stravaimport_view"
messages.error(request, message)
url = reverse('workouts_view')
return HttpResponseRedirect(url)
else:
workouts = []
r = getrower(request.user)
rower = r
stravaids = [int(item['id']) for item in res.json()]
stravadata = [{
'id': int(item['id']),
'elapsed_time':item['elapsed_time'],
'start_date':item['start_date'],
} for item in res.json()]
if request.method == "POST":
try: # pragma: no cover
tdict = dict(request.POST.lists())
ids = tdict['workoutid']
stravaids = [int(id) for id in ids]
alldata = {}
wfailed = Workout.objects.filter(user=r, uploadedtostrava=-1)
for stravaid in stravaids:
csvfilename = 'media/{code}_{stravaid}.csv'.format(
code=uuid4().hex[:16], stravaid=stravaid)
_ = myqueue(
queue,
fetch_strava_workout,
r.stravatoken,
strava_integration.oauth_data,
stravaid,
csvfilename,
r.user.id
)
# done, redirect to workouts list
messages.info(request,
'Your Strava workouts will be imported in the background.'
' It may take a few minutes before they appear.')
url = reverse('workouts_view')
return HttpResponseRedirect(url)
except KeyError: # pragma: no cover
pass
for w in wfailed: # pragma: no cover
for item in stravadata:
elapsed_time = item['elapsed_time']
start_date = item['start_date']
stravaid = item['id']
if arrow.get(start_date) == arrow.get(w.startdatetime):
elapsed_td = datetime.timedelta(seconds=int(elapsed_time))
elapsed_time = datetime.datetime.strptime(
str(elapsed_td),
"%H:%M:%S"
)
if str(elapsed_time)[-7:] == str(w.duration)[-7:]:
w.uploadedtostrava = int(stravaid)
w.save()
breadcrumbs = [
{
'url': '/rowers/list-workouts/',
'name': 'Workouts'
},
{
'url': reverse('workout_stravaimport_view'),
'name': 'Strava'
},
]
knownstravaids = uniqify([
w.uploadedtostrava for w in Workout.objects.filter(user=r)
])
checknew = request.GET.get('selectallnew', False)
# 2022-10-24 sorting the results
workouts = sorted(workouts, key = lambda d:d['starttime'], reverse=True)
return render(request, 'list_import.html',
{'workouts': workouts,
'rower': r,
'active': 'nav-workouts',
'breadcrumbs': breadcrumbs,
'teams': get_my_teams(request.user),
'checknew': checknew,
'integration': 'Strava'
})
for item in res.json():
d = int(float(item['distance']))
i = item['id']
if i in knownstravaids: # pragma: no cover
nnn = ''
else:
nnn = 'NEW'
n = item['name']
ttot = str(datetime.timedelta(
seconds=int(float(item['elapsed_time']))))
s = item['start_date']
r = item['type']
keys = ['id', 'distance', 'duration',
'starttime', 'type', 'name', 'new']
values = [i, d, ttot, s, r, n, nnn]
res2 = dict(zip(keys, values))
workouts.append(res2)
if request.method == "POST":
try: # pragma: no cover
tdict = dict(request.POST.lists())
ids = tdict['workoutid']
stravaids = [int(id) for id in ids]
alldata = {}
for item in res.json():
alldata[item['id']] = item
for stravaid in stravaids:
csvfilename = 'media/{code}_{stravaid}.csv'.format(
code=uuid4().hex[:16], stravaid=stravaid)
_ = myqueue(
queue,
fetch_strava_workout,
rower.stravatoken,
stravastuff.oauth_data,
stravaid,
csvfilename,
rower.user.id
)
# done, redirect to workouts list
messages.info(request,
'Your Strava workouts will be imported in the background.'
' It may take a few minutes before they appear.')
url = reverse('workouts_view')
return HttpResponseRedirect(url)
except KeyError: # pragma: no cover
pass
breadcrumbs = [
{
'url': '/rowers/list-workouts/',
'name': 'Workouts'
},
{
'url': reverse('workout_stravaimport_view'),
'name': 'Strava'
},
]
checknew = request.GET.get('selectallnew', False)
# 2022-10-24 sorting the results
workouts = sorted(workouts, key = lambda d:d['starttime'], reverse=True)
return render(request, 'strava_list_import.html',
{'workouts': workouts,
'rower': rower,
'active': 'nav-workouts',
'breadcrumbs': breadcrumbs,
'teams': get_my_teams(request.user),
'checknew': checknew,
})
return HttpResponse(res) # pragma: no cover
# for Strava webhook request validation
@@ -1330,7 +1267,7 @@ def strava_webhook_view(request):
if request.method == 'GET':
challenge = request.GET.get('hub.challenge')
verificationtoken = request.GET.get('hub.verify_token')
if verificationtoken != stravastuff.webhookverification: # pragma: no cover
if verificationtoken != strava.webhookverification: # pragma: no cover
return HttpResponse(status=403)
data = {"hub.challenge": challenge}
return JSONResponse(data)
@@ -1374,8 +1311,9 @@ def strava_webhook_view(request):
ws = Workout.objects.filter(uploadedtostrava=stravaid)
if ws.count() == 0 and r.strava_auto_import:
job = stravastuff.async_get_workout(r.user, stravaid)
if job == 0: # pragma: no cover
strava_integration = StravaIntegration(r.user)
jobid = strava_integration.get_workout(stravaid)
if jobid == 0: # pragma: no cover
dologging('strava_webhooks.log',
'Strava strava_open yielded NoTokenError')
else: # pragma: no cover
@@ -1728,7 +1666,7 @@ def workout_c2import_view(request, page=1, userid=0, message=""):
workouts = c2_integration.get_workout_list(page=1)
if request.method == "POST":
try: # pragma: no cover
tdict = dict(request.POST.lists())
@@ -1801,7 +1739,7 @@ importauthorizeviews = {
importsources = {
'c2': C2Integration,
'strava': stravastuff,
'strava': StravaIntegration,
'polar': polarstuff,
'ownapi': ownapistuff,
'sporttracks': sporttracksstuff,
@@ -1960,24 +1898,3 @@ def workout_getsporttracksworkout_all(request):
url = reverse('workouts_view')
return HttpResponseRedirect(url)
# Imports all new workouts from SportTracks
@login_required()
def workout_getstravaworkout_next(request): # pragma: no cover
r = Rower.objects.get(user=request.user)
res = stravastuff.get_strava_workout_list(r.user)
if (res.status_code != 200):
return 0
else:
alldata = {}
for item in res.json():
alldata[item['id']] = item
_ = stravastuff.create_async_workout(
alldata, r.user, stravaid, debug=True)
url = reverse('workouts_view')
return HttpResponseRedirect(url)