adding strava
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user