Private
Public Access
1
0

Merge branch 'develop' into feature/c2splits

This commit is contained in:
Sander Roosendaal
2017-01-06 19:45:45 +01:00
16 changed files with 291 additions and 54 deletions

View File

@@ -63,12 +63,16 @@ class Command(BaseCommand):
wid = [make_new_workout_from_email(rr,a.document,name)]
res += wid
link = 'http://rowsandall.com/rowers/workout/'+str(wid[0])+'/edit'
dd = send_confirm(u,name,link)
except:
# replace with code to process error
res += ['fail: '+name]
donotdelete = 1
try:
dd = send_confirm(u,name,link)
except:
pass
except Rower.DoesNotExist:
pass

View File

@@ -181,8 +181,10 @@ def createsporttracksworkoutdata(w):
maxhr = int(row.df[' HRCur (bpm)'].max())
# adding diff, trying to see if this is valid
t = row.df.ix[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)']
#t = row.df.ix[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)']
t = row.df.ix[:,'TimeStamp (sec)'].values-row.df.ix[0,'TimeStamp (sec)']
t[0] = t[1]
d = row.df.ix[:,'cum_dist'].values
d[0] = d[1]
t = t.astype(int)
@@ -196,9 +198,12 @@ def createsporttracksworkoutdata(w):
try:
lat = row.df[' latitude'].values
lon = row.df[' longitude'].values
if not lat.std() and not lon.std():
haslatlon = 0
except KeyError:
haslatlon = 0
haspower = 1
try:
power = row.df[' Power (watts)'].values

View File

@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "bases.html" %}
{% load staticfiles %}
{% load rowerfilters %}
@@ -13,4 +13,4 @@ HTTP Error 400 Bad Request.
</p>
</div>
{% endblock %}
{% endblock %}

View File

@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "bases.html" %}
{% load staticfiles %}
{% load rowerfilters %}
@@ -13,4 +13,4 @@ Access forbidden
</p>
</div>
{% endblock %}
{% endblock %}

View File

@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "bases.html" %}
{% load staticfiles %}
{% load rowerfilters %}
@@ -13,4 +13,4 @@ We could not find the page on our server.
</p>
</div>
{% endblock %}
{% endblock %}

View File

@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "bases.html" %}
{% load staticfiles %}
{% load rowerfilters %}
@@ -13,4 +13,4 @@ The site reported an internal server error. If this behavior repeats, please inf
</p>
</div>
{% endblock %}
{% endblock %}

189
rowers/templates/bases.html Normal file
View File

@@ -0,0 +1,189 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<script src="/static/cookielaw/js/cookielaw.js"></script>
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
<link rel="shortcut icon" href="/static/img/myicon.png" />
<link rel="shortcut icon" href="/static/img/favicon.ico" />
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=0.67">
<title>Rowsandall</title>
<link rel="stylesheet" href="/static/css/reset.css" />
<link rel="stylesheet" href="/static/css/text.css" />
<link rel="stylesheet" href="/static/css/960_12_col.css" />
<link rel="stylesheet" href="/static/css/rowsandall.css" />
{% block meta %} {% endblock %}
</head>
<body>
<div class="container_12">
<div id="logo" class="grid_2">
{% if user.rower.rowerplan == 'pro' %}
<p><a href="/"><img src="/static/img/logocroppedpro.gif"
alt="Rowsandall logo" width="110" heigt="110"></a></p>
{% else %}
<p><a href="/"><img src="/static/img/logocropped.gif"
alt="Rowsandall logo" width="110" heigt="110"></a></p>
{% endif %}
</div>
<div class="grid_10 omega">
<div class="grid_8 alpha"><p>&nbsp</p></div>
<div class="grid_2 omega">
{% if user.is_authenticated %}
<p><a class="button gray small" href="/password_change/">Password Change</a></p>
{% else %}
<p><a class="button gray small" href="/password_reset/">Forgotten Password?</a></p>
{% endif %}
</div>
</div>
<div class="grid_10 omega">
<div class="grid_4 suffix_2 alpha">
<p>Free Data and Analysis. For Rowers. By Rowers.</p>
</div>
<div class="grid_3">
{% if user.rower.rowerplan == 'pro' %}
<h6>Pro Member</h6>
{% else %}
<p>&nbsp;</p>
{% endif %}
</div>
<div class="grid_1 omega">
{% if user.is_authenticated %}
<p><a class="button gray small" href="{% url 'logout' %}">logout</a></p>
{% else %}
<p>&nbsp</p>
{% endif %}
</div>
</div>
<div class="grid_10" omega>
<div class="grid_1 alpha tooltip">
{% if user.is_authenticated %}
<p><a class="button gray small" href="/rowers/workout/upload/">Upload</a></p>
<span class="tooltiptext">Upload CSV, TCX, FIT data files to rowsandall.com</span>
{% else %}
<p><a class="button green small" href="/rowers/register">Register (free)</a></p>
{% endif %}
</div>
<div class="grid_1 tooltip">
{% if user.is_authenticated %}
<p>
<a class="button gray small" href="/rowers/imports/">Import</a>
</p>
<span class="tooltiptext">Import workouts from Strava, SportTracks, and C2 logbook</span>
{% else %}
<p>&nbsp;</p>
{% endif %}
</div>
<div class="grid_2 tooltip">
{% if user.is_authenticated %}
<p>
<a class="button gray small" href="/rowers/list-workouts/">Workouts</a>
</p>
<span class="tooltiptext">See your list of workouts</span>
{% else %}
<p>&nbsp;</p>
{% endif %}
</div>
<div class="grid_2 tooltip">
{% if user.is_authenticated %}
<p>
<a class="button gray small" href="/rowers/list-graphs/">Graphs</a>
</p>
<span class="tooltiptext">See your most recent charts</span>
{% else %}
<p>&nbsp;</p>
{% endif %}
</div>
<div class="grid_2 suffix_1 tooltip">
{% if user.is_authenticated %}
<p>
<a class="button gray small" href="/rowers/analysis">Analysis</a>
</p>
<span class="tooltiptext">Analysis of workouts over a period of time</span>
{% else %}
<p>&nbsp;</p>
{% endif %}
</div>
<div class="grid_1 omega tooltip">
{% if user.is_authenticated %}
<p>
<a class="button gray small" href="/rowers/me/edit">{{ user.first_name }}</a>
</p>
<span class="tooltiptext">Edit user data, e.g. heart rate zones</span>
{% else %}
<p><a class="button gray small" href="{% url 'login' %}">login</a> </p>
{% endif %}
</div>
</div>
<div class="clear"></div>
<div class="grid_12">
{% block message %}
{% if message %}
<p class="message">
{{ message }}
</p>
{% endif %}
{% if successmessage %}
<p class="successmessage">
{{ successmessage }}
</p>
{% endif %}
{% endblock %}
</div>
<div class="grid_12">
{% load tz %}
{% block content %}{% endblock %}
</div>
<div class="clear"></div>
<div class="grid_12 omega" >
{% block footer %}
<p id="footer"
>{{ versionstring }}</p>
<div class="grid_2 alpha">
<p id="footer"><a href="/rowers/email/">&copy; Sander Roosendaal</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/about">About</a></p>
</div>
<div class="grid_2">
<p id="footer">
<a href="/rowers/developers">Developers</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/legal">Legal</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/physics">Physics</a></p>
</div>
<div class="grid_2">
<p id="footer">
<a href="/rowers/videos">Videos</a></p>
</div>
<div class="grid_2">
<p id="footer">
<a href="http://analytics.rowsandall.com/">Rowing Analytics BLOG</a></p>
</div>
<div class="grid_1 omega">
<p id="footer">
<a href="/rowers/email">Contact</a></p>
</div>
{% endblock %}
</div>
</div>
<!-- end container -->
</body>
</html>

View File

@@ -16,13 +16,14 @@
<li> CrewNerd (TCX)</li>
<li> Rowing In Motion (TCX)</li>
<li> Speedcoach XL (CSV)</li>
<li> Speedcoach GPS (FIT)</li></ul></p>
<li> Speedcoach GPS (FIT and CSV)</li></ul></p>
<p>Erg
<ul>
<li> Painsled (CSV)</li>
<li> ErgData (CSV export from Concept2 logbook)</li>
<li> RowPro (CSV)</li>
<li> BoatCoach (CSV)</li>
<li> ErgStick (CSV)</li></ul></p>
@@ -35,7 +36,7 @@
<h2>Export Compatibility</h2>
<ul>
<li> Concept2 Logbook: Exports stroke by stroke data for erg and OTW rowing</li>
<li> Strava: </li>
<li> Strava </li>
<li> SportTracks</li>
<li> email (TCX or CSV format)</li></ul></p>
</div>

View File

@@ -22,8 +22,9 @@
<img src="/static/img/rimsquare.png" alt="RiM icon" width="30" height="30">
<img src="/static/img/rpsquare.png" alt="RowPro icon" width="30" height="30">
<img src="/static/img/essquare.png" alt="ErgStick icon" width="30" height="30">
<img src="/static/img/bcsquare.png" alt="BoatCoach icon" width="30" height="30">
<img src="/static/img/pssquare.png" alt="PainSled icon" width="30" height="30">
</p>
</div>
{% endblock %}
{% endblock %}

View File

@@ -59,10 +59,23 @@ class RowerViewSet(viewsets.ModelViewSet):
IsOwnerOrNot,
)
http_method_names = ['get','patch']
class FavoriteChartViewSet(viewsets.ModelViewSet):
model = FavoriteChart
serializer_class = FavoriteChartSerializer
queryset = FavoriteChart.objects.all()
#queryset = FavoriteChart.objects.all()
def get_queryset(self):
r = Rower.objects.filter(user=self.request.user)
return FavoriteChart.objects.filter(user=r)
permission_classes = (
IsOwnerOrNot,
)
http_method_names = ['get','put','patch','delete']
class StrokeDataViewSet(viewsets.ModelViewSet):
serializer_class = StrokeDataSerializer

View File

@@ -266,7 +266,7 @@ def rower_register_view(request):
message += "Happy rowing!\n\n\n"
message += "Oh, one more thing. The site is currently in beta and is developing fast. Bear with us. Don't hesitate to contact me if anything is broken or doesn't seem to work as advertised."
send_mail(subject, message,
'Sander Roosendaal <info@rowsandall,com>',
'Sander Roosendaal <info@rowsandall.com>',
[fullemail])
subject2 = "New User"
@@ -275,7 +275,7 @@ def rower_register_view(request):
message2 += "User name: "+username
send_mail(subject2, message2,
'Rowsandall Server <info@rowsandall,com>',
'Rowsandall Server <info@rowsandall.com>',
['roosendaalsander@gmail.com'])
return HttpResponseRedirect('/rowers/register/thankyou/')
@@ -343,17 +343,6 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
rowdatetime = iso8601.parse_date(data['start_date'])
except ParseError:
rowdatetime = iso8601.parse_date(data['date'])
# try:
# rowdatetime = datetime.datetime.strptime(data['date_utc'],"%Y-%m-%d %H:%M:%S")
# rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
# except KeyError:
# try:
# rowdatetime = dateutil.parser.parse(data['start_date'])
# rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
# except:
# rowdatetime = datetime.datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S")
# rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc)
try:
@@ -860,7 +849,7 @@ def workout_tcxemail_view(request,id=0):
})
except:
successmessage = ""
message = "Something went wrong (strava export) "+str(sys.exc_info()[0])
message = "Something went wrong (TCX export) "+str(sys.exc_info()[0])
with open("media/c2errors.log","a") as errorlog:
errorstring = str(sys.exc_info()[0])
timestr = strftime("%Y%m%d-%H%M%S")
@@ -925,6 +914,7 @@ def workout_csvemail_view(request,id=0):
def workout_strava_upload_view(request,id=0):
message = ""
r = Rower.objects.get(user=request.user)
res = -1
if (r.stravatoken == '') or (r.stravatoken is None):
s = "Token doesn't exist. Need to authorize"
return HttpResponseRedirect("/rowers/me/stravaauthorize/")
@@ -932,28 +922,29 @@ def workout_strava_upload_view(request,id=0):
# ready to upload. Hurray
w = Workout.objects.get(id=id)
if (checkworkoutuser(request.user,w)):
tcxfile = stravastuff.createstravaworkoutdata(w)
try:
tcxfile = stravastuff.createstravaworkoutdata(w)
try:
with open(tcxfile,'rb') as f:
try:
res = stravastuff.handle_stravaexport(f,w.name,
r.stravatoken,
description=w.notes)
except:
w.uploadedtostrava = res
w.save()
os.remove(tcxfile)
url = "/rowers/workout/"+str(w.id)+"/edit"
successmessage = 'Workout sent to Strava.'
except:
with open("media/stravaerrors.log","a") as errorlog:
errorstring = str(sys.exc_info()[0])
timestr = time.strftime("%Y%m%d-%H%M%S")
timestr = strftime("%Y%m%d-%H%M%S")
errorlog.write(timestr+errorstring+"\r\n")
errorlog.write("views.py line 946\r\n")
message = 'Error: '+errorstring
w.uploadedtostrava = res
w.save()
os.remove(tcxfile)
url = "/rowers/workout/"+str(w.id)+"/edit"
successmessage = 'Workout sent to Strava.'
url = reverse(workout_export_view,
kwargs = {
'id':str(w.id),
@@ -968,7 +959,6 @@ def workout_strava_upload_view(request,id=0):
url = reverse(workout_export_view,
kwargs = {
'id':str(w.id),
'message':message,
})
response = HttpResponseRedirect(url)
# except TimeoutExceeded as e:
@@ -1009,7 +999,7 @@ def workout_c2_upload_view(request,id=0):
message = "Unexpected Error: "+str(sys.exc_info()[0])
with open("media/c2errors.log","a") as errorlog:
errorstring = str(sys.exc_info()[0])
timestr = time.strftime("%Y%m%d-%H%M%S")
timestr = strftime("%Y%m%d-%H%M%S")
errorlog.write(timestr+errorstring+"\r\n")
# check for duplicate error first
@@ -1029,7 +1019,7 @@ def workout_c2_upload_view(request,id=0):
message = "Something went wrong in workout_c2_upload_view. Response code 200/201 but C2 sync failed: "+response.text
with open("media/c2errors.log","a") as errorlog:
errorstring = str(sys.exc_info()[0])
timestr = time.strftime("%Y%m%d-%H%M%S")
timestr = strftime("%Y%m%d-%H%M%S")
errorlog.write(timestr+errorstring+"\r\n")
@@ -1038,7 +1028,7 @@ def workout_c2_upload_view(request,id=0):
message = "Something went wrong in workout_c2_upload_view. C2 sync failed."
with open("media/c2errors.log","a") as errorlog:
errorstring = str(sys.exc_info()[0])
timestr = time.strftime("%Y%m%d-%H%M%S")
timestr = strftime("%Y%m%d-%H%M%S")
errorlog.write(timestr+errorstring+"\r\n")
else:
@@ -1073,7 +1063,6 @@ def workout_sporttracks_upload_view(request,id=0):
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json"
response = requests.post(url,headers=headers,data=json.dumps(data))
# check for duplicate error first
if (response.status_code == 409 ):
message = "Duplicate error"
@@ -1088,7 +1077,7 @@ def workout_sporttracks_upload_view(request,id=0):
return HttpResponseRedirect(url)
else:
s = response
message = "Something went wrong in workout_sporttracks_upload_view %s" % s
message = "Something went wrong in workout_sporttracks_upload_view: %s" % s.reason
else:
message = "You are not authorized to upload this workout"
@@ -2338,6 +2327,9 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
except KeyError:
hascoordinates = 0
if not latitude.std():
hascoordinates = 0
try:
bearing = rowdata.df.ix[:,'bearing'].values
except KeyError:
@@ -3150,10 +3142,14 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
if rowdata != 0:
try:
latitude = rowdata.df[' latitude']
if not latitude.std():
hascoordinates = 0
except KeyError,AttributeError:
hascoordinates = 0
else:
hascoordinates = 0
if hascoordinates:
res = googlemap_chart(rowdata.df[' latitude'],
@@ -3692,6 +3688,7 @@ def workout_getc2workout_view(request,c2id):
res = c2stuff.get_c2_workout(request.user,c2id)
if (res.status_code == 200):
data = res.json()['data']
<<<<<<< HEAD
splitdata = None
if 'splits' in data:
splitdata = data['splits']
@@ -3719,16 +3716,41 @@ def workout_getc2workout_view(request,c2id):
'message':message,
})
return HttpResponseRedirect(url)
=======
if data['stroke_data']:
res2 = c2stuff.get_c2_workout_strokes(request.user,c2id)
else:
message = "This workout does not have any stroke data associated with it"
url = reverse(workout_c2import_view,
kwargs={
'message':message,
})
return HttpResponseRedirect(url)
if res2.status_code == 200:
strokedata = pd.DataFrame.from_dict(res2.json()['data'])
id = add_workout_from_strokedata(request.user,c2id,data,strokedata,
source='c2')
w = Workout.objects.get(id=id)
w.uploadedtoc2=c2id
w.save()
url = "/rowers/workout/"+str(id)+"/edit"
return HttpResponseRedirect(url)
>>>>>>> develop
else:
message = "This workout doesn't contain stroke data"
if settings.DEBUG:
return HttpResponse(res)
else:
url = reverse(workout_c2import_view,
kwargs={
'message':message,
})
return HttpResponseRedirect(url)
# message = json.loads(s.text)['message']
message = json.loads(res2.text)['message']
url = reverse(workout_c2import_view,
kwargs={
'message':message,
})
return HttpResponseRedirect(url)
url = reverse(workout_c2import_view,
kwargs={
'message':message,
})
return HttpResponseRedirect(url)
else:
message = "Received error code from Concept2"