Private
Public Access
1
0

import list rp3 working

This commit is contained in:
Sander Roosendaal
2021-01-27 08:39:33 +01:00
parent 3ef8d4ba57
commit 2d7d07a914
5 changed files with 139 additions and 123 deletions

View File

@@ -21,7 +21,6 @@ from rowsandall_app.settings import (
RP3_CLIENT_ID, RP3_CLIENT_KEY, RP3_REDIRECT_URI, RP3_CLIENT_SECRET
)
tpapilocation = "https://api.trainingpeaks.com"
from celery import Celery,app
from django_rq import job
@@ -45,6 +44,8 @@ oauth_data = {
from rowers.rower_rules import is_workout_user
graphql_url = "https://rp3rowing-app.com/graphql"
# Checks if user has UnderArmour token, renews them if they are expired
def rp3_open(user):
@@ -73,8 +74,6 @@ def get_token(code):
data=post_data,verify=False,
)
print(response.json())
try:
token_json = response.json()
@@ -93,124 +92,23 @@ def make_authorization_url(request):
return imports_make_authorization_url(oauth_data)
def getidfromresponse(response):
t = json.loads(response.text)
def get_rp3_workout_list(user):
r = Rower.objects.get(user=user)
links = t["_links"]
auth_token = rp3_open(user)
id = links["self"][0]["id"]
headers = {'Authorization': 'Bearer ' + auth_token }
return int(id)
def createtpworkoutdata(w):
filename = w.csvfilename
row = rowingdata(csvfile=filename)
tcxfilename = filename[:-4]+'.tcx'
try:
newnotes = w.notes+'\n from '+w.workoutsource+' via rowsandall.com'
except TypeError:
newnotes = 'from '+w.workoutsource+' via rowsandall.com'
row.exporttotcx(tcxfilename,notes=newnotes)
return tcxfilename
def rp3_check(access_token):
headers = {
"Content-Type": "application/json",
'Accept': 'application/json',
'authorization': 'Bearer %s' % access_token
}
resp = requests.post(tpapilocation+"/v1/info/version",
headers=headers,verify=False)
return resp
def uploadactivity(access_token,filename,description='',
name='Rowsandall.com workout'):
data_gz = BytesIO()
with open(filename,'rb') as inF:
s = inF.read()
with gzip.GzipFile(fileobj=data_gz,mode="w") as gzf:
gzf.write(s)
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer %s' % access_token
}
data = {
"UploadClient": "rowsandall",
"Filename": filename,
"SetWorkoutPublic": True,
"Title":name,
"Type": "rowing",
"Comment": description,
"Data": base64.b64encode(data_gz.getvalue()).decode("ascii")
get_workouts_list = """{
workouts{
id
executed_at
}
}"""
response = requests.post(
url=graphql_url,
headers=headers,
json={'query': get_workouts_list}
)
resp = requests.post(tpapilocation+"/v1/file",
data = json.dumps(data),
headers=headers,verify=False)
if resp.status_code != 200:
return 0,resp.reason,resp.status_code,headers
else:
return resp.json()[0]["Id"],"ok",200,""
return 0,0,0,0
def workout_rp3_upload(user,w):
message = "Uploading to TrainingPeaks"
tpid = 0
r = w.user
thetoken = rp3_open(r.user)
# need some code if token doesn't refresh
if (is_workout_user(user,w)):
tcxfile = createtpworkoutdata(w)
if tcxfile:
res,reason,status_code,headers = uploadactivity(
thetoken,tcxfile,
name=w.name
)
if res == 0:
message = "Upload to TrainingPeaks failed with status code "+str(status_code)+": "+reason
w.tpid = -1
try:
os.remove(tcxfile)
except WindowsError:
pass
return message,tpid
else: # res != 0
w.uploadedtotp = res
tpid = res
w.save()
os.remove(tcxfile)
return 'Successfully synchronized to TrainingPeaks',tpid
else: # no tcxfile
message = "Upload to TrainingPeaks failed"
w.uploadedtotp = -1
tpid = -1
w.save()
return message,tpid
else: # not allowed to upload
message = "You are not allowed to export this workout to TP"
tpid = 0
return message,tpid
return message,tpid
return response

View File

@@ -16,7 +16,7 @@
<a href="/rowers/team-compare-select/team/0/">
<i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare</a>
{% endif %}
</li>
</li>
<li>
<a href="/rowers/workout/upload/"><i class="fas fa-file-upload fa-fw"></i>&nbsp;Upload</a>
</li>
@@ -35,7 +35,7 @@
<li class="has-children" id="imports">
<input type="checkbox" name ="group-1" id="group-1">
<label for="group-1"><i class="fas fa-cloud-download fa-fw"></i>&nbsp;Import</label>
<ul>
<li id="concept2"><a href="/rowers/workout/c2list/">Concept2</a></li>
<li id="strava"><a href="/rowers/workout/stravaimport/">Strava</a></li>
@@ -43,6 +43,7 @@
<li id="sporttracks"><a href="/rowers/workout/sporttracksimport/">SportTracks</a></li>
<li id="mapmyfitness"><a href="/rowers/workout/underarmourimport/">MapMyFitness</a></li>
<li id="polar"><a href="/rowers/workout/polarimport/">Polar</a></li>
<li id="rp3"><a href="/rowers/workout/rp3import/">RP3</a></li>
</ul>
</li>
</ul> <!-- cd-accordion-menu -->
@@ -64,7 +65,7 @@
{% if member == rower %}
&bull;
{% else %}
&nbsp;
&nbsp;
{% endif %}
{{ member.user.first_name }} {{ member.user.last_name }}
</a>
@@ -85,7 +86,7 @@
{% for tteam in teams %}
<li>
<a href={{ request.path|teamurl:tteam }}>
<i class="fas fa-users fa-fw"></i>
<i class="fas fa-users fa-fw"></i>
{% if tteam == team %}
&bull;
{% else %}

View File

@@ -0,0 +1,43 @@
{% extends "newbase.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Workouts{% endblock %}
{% block main %}
<h1>Available on RP3</h1>
{% if workouts %}
<ul class="main-content">
<li class="grid_4">
<table width="70%" class="listtable">
<thead>
<tr>
<th> Import </th>
<th> Date</th>
<th> New</th>
</tr>
</thead>
<tbody>
{% for workout in workouts %}
<tr>
<td>
<a href="/rowers/workout/rp3import/{{ workout|lookup:'id' }}/">Import</a></td>
<td>{{ workout|lookup:'starttime' }}</td>
<td>{{ workout|lookup:'new' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</li>
</ul>
{% else %}
<p>
No workouts found
</p>
{% endif %}
{% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %}

View File

@@ -537,6 +537,8 @@ urlpatterns = [
re_path(r'^workout/c2list/(?P<page>\d+)/$',views.workout_c2import_view,name='workout_c2import_view'),
re_path(r'^workout/c2list/user/(?P<userid>\d+)/$',views.workout_c2import_view,name='workout_c2import_view'),
re_path(r'^workout/c2list/(?P<page>\d+)/user/(?P<userid>\d+)/$',views.workout_c2import_view,name='workout_c2import_view'),
re_path(r'^workout/rp3import/$',views.workout_rp3import_view,name='workout_rp3import_view'),
re_path(r'^workout/rp3import/user/(?P<userid>\d+)/$',views.workout_rp3import_view,name='workout_rp3import_view'),
re_path(r'^workout/stravaimport/$',views.workout_stravaimport_view,name='workout_stravaimport_view'),
re_path(r'^workout/stravaimport/user/(?P<userid>\d+)/$',views.workout_stravaimport_view,name='workout_stravaimport_view'),
re_path(r'^workout/c2import/all/$',views.workout_getc2workout_all,name='workout_getc2workout_all'),

View File

@@ -964,6 +964,78 @@ def rower_process_testcallback(request):
return HttpResponse(text)
@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def workout_rp3import_view(request,userid=0):
r = getrequestrower(request,userid=userid)
try:
thetoken = rp3stuff.rp3_open(request.user)
except NoTokenError:
url = reverse('rower_rp3_authorize')
return HttpResponseRedirect(url)
res = rp3stuff.get_rp3_workout_list(request.user)
if (res.status_code != 200):
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)
workouts_list = pd.json_normalize(res.json()['data']['workouts'])
rp3ids = workouts_list['id'].values
knownrp3ids = uniqify([
w.uploadedtorp3 for w in Workout.objects.filter(user=r)
])
newids = [rp3id for rp3id in rp3ids if not rp3id in knownrp3ids]
workouts = []
for key,data in workouts_list.iterrows():
i = data['id']
if i in knownrp3ids:
nnn = ''
else:
nnn = 'NEW'
s = data['executed_at']
keys = ['id','starttime','new']
values = [i,s,nnn]
res = dict(zip(keys,values))
workouts.append(res)
breadcrumbs = [
{
'url':'/rowers/list-workouts/',
'name':'Workouts'
},
{
'url':reverse('workout_stravaimport_view'),
'name':'Strava'
},
]
return render(request,'rp3_list_import.html',
{
'workouts':workouts,
'rower':r,
'active':'nav-workouts',
'breadcrumbs':breadcrumbs,
'teams':get_my_teams(request.user)
})
# The page where you select which Strava workout to import