Private
Public Access
1
0

Merge branch 'feature/python3' into develop

This commit is contained in:
Sander Roosendaal
2019-02-28 22:53:16 +01:00
51 changed files with 114 additions and 1514 deletions
+14 -3
View File
@@ -16,6 +16,8 @@ import rowers.mytypes as mytypes
from rowers.mytypes import otwtypes from rowers.mytypes import otwtypes
from iso8601 import ParseError from iso8601 import ParseError
import numpy
from rowsandall_app.settings import ( from rowsandall_app.settings import (
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET
) )
@@ -424,7 +426,11 @@ def createc2workoutdata(w):
hr = 0*d hr = 0*d
stroke_data = [] stroke_data = []
for i in range(len(t)): for i in range(len(t)):
thisrecord = {"t":t[i],"d":d[i],"p":p[i],"spm":spm[i],"hr":hr[i]} thisrecord = {"t":t[i].astype(int),
"d":d[i].astype(int),
"p":p[i].astype(int),
"spm":spm[i].astype(int),
"hr":hr[i].astype(int)}
stroke_data.append(thisrecord) stroke_data.append(thisrecord)
try: try:
@@ -551,7 +557,7 @@ def make_authorization_url(request):
params = {"client_id": C2_CLIENT_ID, params = {"client_id": C2_CLIENT_ID,
"response_type": "code", "response_type": "code",
"redirect_uri": C2_REDIRECT_URI} "redirect_uri": C2_REDIRECT_URI}
url = "https://log.concept2.com/oauth/authorize?"+ urllib.urlencode(params) url = "https://log.concept2.com/oauth/authorize?"+ urllib.parse.urlencode(params)
url += "&scope="+scope url += "&scope="+scope
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
@@ -697,6 +703,10 @@ def process_callback(request):
return HttpResponse("got a user name: %s" % username) return HttpResponse("got a user name: %s" % username)
def default(o):
if isinstance(o, numpy.int64): return int(o)
raise TypeError
# Uploading workout # Uploading workout
def workout_c2_upload(user,w): def workout_c2_upload(user,w):
message = 'trying C2 upload' message = 'trying C2 upload'
@@ -717,6 +727,7 @@ def workout_c2_upload(user,w):
raise NoTokenError raise NoTokenError
data = createc2workoutdata(w) data = createc2workoutdata(w)
if data == 0: if data == 0:
return "Error: No data file. Contact info@rowsandall.com if the problem persists",0 return "Error: No data file. Contact info@rowsandall.com if the problem persists",0
@@ -726,7 +737,7 @@ def workout_c2_upload(user,w):
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
import urllib import urllib
url = "https://log.concept2.com/api/users/%s/results" % (c2userid) url = "https://log.concept2.com/api/users/%s/results" % (c2userid)
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
if (response.status_code == 409 ): if (response.status_code == 409 ):
message = "Concept2 Duplicate error" message = "Concept2 Duplicate error"
+1 -1
View File
@@ -280,7 +280,7 @@ def imports_make_authorization_url(oauth_data):
import urllib import urllib
url = oauth_data['authorizaton_uri']+urllib.urlencode(params) url = oauth_data['authorizaton_uri']+urllib.parse.urlencode(params)
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
+10 -1
View File
@@ -1,13 +1,17 @@
#!/srv/venv/bin/python #!/srv/venv/bin/python
""" Process emails """ """ Process emails """
import sys import sys
import os import os
PY3K = sys.version_info >= (3, 0)
import zipfile import zipfile
import re import re
import time import time
from time import strftime from time import strftime
import io
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django_mailbox.models import Message, MessageAttachment,Mailbox from django_mailbox.models import Message, MessageAttachment,Mailbox
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
@@ -62,7 +66,7 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
# test if file exists and is not empty # test if file exists and is not empty
try: try:
with open('media/'+filename,'r') as fop: with io.open('media/'+filename,'rb') as fop:
line = fop.readline() line = fop.readline()
except (IOError, UnicodeEncodeError): except (IOError, UnicodeEncodeError):
if testing: if testing:
@@ -164,6 +168,11 @@ def get_from_address(message):
except IndexError: except IndexError:
first_line = '' first_line = ''
try:
first_line = first_line.decode('utf-8')
except AttributeError:
pass
if "quiske" in first_line: if "quiske" in first_line:
match = re.search(r'[\w\.-]+@[\w\.-]+', first_line) match = re.search(r'[\w\.-]+@[\w\.-]+', first_line)
return match.group(0) return match.group(0)
+1 -1
View File
@@ -128,7 +128,7 @@ def make_authorization_url(request):
import urllib import urllib
url = "http://localhost:8000/rowers/o/authorize" +urllib.urlencode(params) url = "http://localhost:8000/rowers/o/authorize" +urllib.parse.urlencode(params)
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
+1 -1
View File
@@ -106,7 +106,7 @@ def make_authorization_url():
"redirect_uri": POLAR_REDIRECT_URI, "redirect_uri": POLAR_REDIRECT_URI,
"scope":"write"} "scope":"write"}
import urllib import urllib
url = "https://flow.polar.com/oauth2/authorization" +urllib.urlencode(params) url = "https://flow.polar.com/oauth2/authorization" +urllib.parse.urlencode(params)
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
+7 -1
View File
@@ -29,6 +29,8 @@ oauth_data = {
} }
import numpy
def splitrunkeeperlatlongdata(lijst,tname,latname,lonname): def splitrunkeeperlatlongdata(lijst,tname,latname,lonname):
t = [] t = []
lat = [] lat = []
@@ -262,6 +264,10 @@ def get_userid(access_token):
return str(res) return str(res)
def default(o):
if isinstance(o, numpy.int64): return int(o)
raise TypeError
def workout_runkeeper_upload(user,w): def workout_runkeeper_upload(user,w):
message = "Uploading to Runkeeper" message = "Uploading to Runkeeper"
rkid = 0 rkid = 0
@@ -287,7 +293,7 @@ def workout_runkeeper_upload(user,w):
'Content-Length':'nnn'} 'Content-Length':'nnn'}
url = "https://api.runkeeper.com/fitnessActivities" url = "https://api.runkeeper.com/fitnessActivities"
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ):
+8 -1
View File
@@ -6,6 +6,8 @@ from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
# All the functionality to connect to SportTracks # All the functionality to connect to SportTracks
import numpy
from rowers.imports import * from rowers.imports import *
import re import re
from rowsandall_app.settings import ( from rowsandall_app.settings import (
@@ -235,6 +237,11 @@ def getidfromresponse(response):
return int(id) return int(id)
def default(o):
if isinstance(o, numpy.int64): return int(o)
raise TypeError
def workout_sporttracks_upload(user,w): def workout_sporttracks_upload(user,w):
message = "Uploading to SportTracks" message = "Uploading to SportTracks"
@@ -257,7 +264,7 @@ def workout_sporttracks_upload(user,w):
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json" url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json"
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ):
-227
View File
@@ -1,227 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}{{ workout.name }} Advanced {% endblock %}
{% block content %}
<div id="workouts" class="grid_6 alpha">
<div class="grid_6 alpha">
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<h1>{{ workout.name }} - Advanced</h1>
{% if user.rower.rowerplan == 'basic' %}
<p>Functionality marked with an asterisk (*) is limited to the paid plans. See
<a href="/rowers/paidplans">the page about Pro membership</a>
for more information and to sign up for Pro Membership</a></p>
{% endif %}
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/workflow">Workflow View</a>
</p>
</div>
<div class="grid_2 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/export">Export</a>
</p>
</div>
</div>
<div class="grid_6 alpha">
<table width=100%>
<tr>
<th>Date:</th><td>{{ workout.date }}</td>
</tr><tr>
<th>Time:</th><td>{{ workout.starttime }}</td>
</tr><tr>
<th>Distance:</th><td>{{ workout.distance }}m</td>
</tr><tr>
<th>Duration:</th><td>{{ workout.duration |durationprint:"%H:%M:%S.%f" }}</td>
</tr>
<th>Public link to this workout</th>
<td>
<a href="/rowers/workout/{{ workout.id|encode }}">https://rowsandall.com/rowers/workout/{{ workout.id|encode }}</a>
<td>
</table>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ workout.id|encode }}">Compare Workouts</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans/">Compare Workouts*</a>
{% endif %}
<p>
Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts.
</p>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/flexchart">
Flexible Interactive Plot
</a>
<p>
Flexible Interactive plot. Pick your own X and Y axis parameters.
</p>
</div>
<div class="grid_2 omega tooltip">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/editintervals">Edit Intervals</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Edit Intervals*</a>
{% endif %}
</p>
<span class="tooltiptext">Enter or change the interval and summary data for your workout</span>
<p>
Enter or change the interval and summary data for your workout
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/adddistanceplot2">Dist Metrics Plot</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Dist Metrics Plot*</a>
{% endif %}
</p>
<p>
Various advanced stroke metrics plotted versus distance.
</p>
</div>
<div class="grid_2">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/addtimeplot2">Time Metrics Plot</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Time Metrics Plot*</a>
{% endif %}
</p>
<p>
Various advanced stroke metrics plotted versus time.
</p>
</div>
<div class="grid_2 omega">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/histo">Power Histogram</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Power Histogram*</a>
{% endif %}
</p>
<p>
Plot the Power Histogram of this workout
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workouts-join-select">Glue</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Glue*</a>
{% endif %}
</p>
<p>
Glue multiple workouts together (into one workout). For example, to combine separately recorded intervals.
</p>
</div>
<div class="grid_2">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/fusion/{{ workout.id|encode }}/">Sensor Fusion</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Sensor Fusion*</a>
{% endif %}
</p>
<p>
Merge data from another source into this workout
</p>
</div>
<div class="grid_2 omega">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/split">Split Workout</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Split Workout*</a>
{% endif %}
</p>
<p>
Split workout into two seperate workouts
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/interactiveplot">Big Interactive Plot</a>
</p>
<p>
See (and save) the big interactive plot
</p>
</div>
<div class="grid_2">
<p>
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/instroke">In-Stroke Metrics</a></p>
<p>
If your workout has in-stroke metrics (like a stroke power curve or boat acceleration curve), you will find it here.
</p>
</div>
</div>
</div>
<div id="advancedplots" class="grid_6 omega">
<div class="grid_6 alpha">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, true);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="interactiveplot" class="grid_6 omega">
{{ the_div |safe }}
</div>
</div>
</div>
{% endblock %}
-284
View File
@@ -1,284 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}{{ workout.name }} Advanced {% endblock %}
{% block content %}
<div id="workouts" class="grid_6 alpha">
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<h1>{{ workout.name }} - Advanced OTW</h1>
{% if user.rower.rowerplan == 'basic' %}
<p>Functionality marked with an asterisk (*) is limited to the paid plans. See
<a href="/rowers/paidplans">the page about Pro membership</a>
for more information and to sign up for Pro Membership</a></p>
{% endif %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/workflow">Workflow View</a>
</p>
</div>
<div class="grid_2 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/export">Export</a>
</p>
</div>
<div class="grid_6 alpha">
<table width=100%>
<tr>
<th>Date:</th><td>{{ workout.date }}</td>
</tr><tr>
<th>Time:</th><td>{{ workout.starttime }}</td>
</tr><tr>
<th>Distance:</th><td>{{ workout.distance }}m</td>
</tr><tr>
<th>Duration:</th><td>{{ workout.duration |durationprint:"%H:%M:%S.%f" }}</td>
</tr>
<th>Public link to this workout</th>
<td>
<a href="/rowers/workout/{{ workout.id|encode }}">https://rowsandall.com/rowers/workout/{{ workout.id|encode }}</a>
<td>
</table>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ workout.id|encode }}">Compare Workouts</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Compare Workouts*</a>
{% endif %}
</p>
<p>
Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts.
</p>
</div>
<div class="grid_2">
<p>
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/flexchart">Flexible Interactive Plot</a>
</p>
<p>
Flexible Interactive plot. Pick your own X and Y axis parameters.
</p>
</div>
<div class="grid_2 omega tooltip">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/editintervals">Edit Intervals</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Edit Intervals*</a>
{% endif %}
</p>
<span class="tooltiptext">Enter or change the interval and summary data for your workout</span>
<p>
Enter or change the interval and summary data for your workout
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id|encode }}/crewnerdsummary">CrewNerd Summary</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">CrewNerd Summary*</a>
{% endif %}
</p>
<p>
Upload a CrewNerd Summary (CSV file) to this workout.
</p>
</div>
<div class="grid_2 tooltip">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/forcecurve">Stroke Profile (Empower)</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Stroke Profile (Empower)*</a>
{% endif %}
</p>
<span class="tooltiptext">Analyze your stroke force profile (need Empower Oarlock data)</span> <p>
Interactive plot of Stroke Profile (with Empower Oarlock)
</p>
</div>
<div class="grid_2 omega tooltip">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/addotwpowerplot">OTW Power Plot</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">OTW Power Plot*</a>
{% endif %}
</p>
<span class="tooltiptext">Note: You must run the OTW calculations under Geeky Stuff first. Otherwise the plot will be empty</span>
<p>
Pace, wind corrected pace, power, equivalent erg power in a static plot
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/geeky">Geeky Stuff</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Geeky Stuff*</a>
{% endif %}
</p>
<p>
Add weather and current data and OTW power calculations.
</p>
</div>
<div class="grid_2 tooltip">
<p>
{% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id|encode }}/smoothenpace">Smooth out Pace Data</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Smooth out Pace Data*</a>
{% endif %}
</p>
<span class="tooltiptext">This will reduce noise on your pace data. The smoothing is irreversible but you can use the reset smoothing button.</span>
<p>
Pace data too noisy? Press this button!
</p>
</div>
<div class="grid_2 omega">
<p>
{% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id|encode }}/undosmoothenpace">Raw Data</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Reset Smoothing*</a>
{% endif %}
</p>
<p>
Reset pace data to values before smoothing
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workouts-join-select">Glue</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Glue*</a>
{% endif %}
</p>
<p>
Glue multiple workouts together (into one workout). For example, to combine separately recorded intervals.
</p>
</div>
<div class="grid_2">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/fusion/{{ workout.id|encode }}/">Sensor Fusion</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Sensor Fusion*</a>
{% endif %}
</p>
<p>
Merge data from another source into this workout
</p>
</div>
<div class="grid_2 omega">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/split">Split Workout</a>
{% else %}
<a class="button blue small" href="/rowers/paidplans">Split Workout*</a>
{% endif %}
</p>
<p>
Split workout into two seperate workouts
</p>
</div>
</div>
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/interactiveplot">Big Interactive Plot</a>
</p>
<p>
See (and save) the big interactive plot
</p>
</div>
<div class="grid_2">
<p>
<a class="button blue small" href="/rowers/workout/{{ workout.id|encode }}/instroke">In-Stroke Metrics</a></p>
<p>
If your workout has in-stroke metrics (like a stroke power curve or boat acceleration curve), you will find it here.
</p>
</div>
</div>
</div>
<div id="advancedplots" class="grid_6 omega">
<div class="grid_6 alpha">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, true);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="interactiveplot" class="grid_6 omega">
{{ the_div |safe }}
</div>
</div>
</div>
{% endblock %}
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
-232
View File
@@ -1,232 +0,0 @@
{% load cookielaw_tags %}
{% load leaflet_tags %}
{% load tz_detect %}
{% tz_detect %}
{% load analytical %}
{% block filters %}
{% endblock %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
{% block headtext %}{% endblock %}
<script src="/static/cookielaw/js/cookielaw.js"></script>
{% analytical_head_top %}
{% if GOOGLE_ANALYTICS_PROPERTY_ID %}
{% include "ga.html" %}
{% endif %}
<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="stylesheet" href="https://webapiv2.navionics.com/dist/webapi/webapi.min.css" >
<script type="text/javascript" src="https://webapiv2.navionics.com/dist/webapi/webapi.min.no-dep.js"></script>
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
<link rel="icon" sizes="32x32" href="/static/img/favicon-32x32.png" type="image/png"/>
<link rel="icon" sizes="64x64" href="/static/img/favicon-64x64.png" type="image/png"/>
<link rel="icon" sizes="192x192" href="/static/img/favicon-192x192.png" type="image/png"/>
<link rel="icon" sizes="16x16" href="/static/img/favicon-16x16.png" type="image/png"/>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=0.67">
<title>{% block title %}Rowsandall{% endblock %}</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" />
<link rel="stylesheet" href="/static/css/leaflet.css" />
<script src="/static/css/leaflet.js" ></script>
{% block meta %} {% endblock %}
{% analytical_head_bottom %}
</head>
<body>
{% analytical_body_top %}
{% block body_top %}{% endblock %}
<div class="container_12">
<div class="grid_12">
&nbsp;
</div>
<div class="grid_12">
<div id="logo" class="grid_6 alpha">
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
<p><a href="/"><img src="/static/img/logo7.png"
alt="Rowsandall logo" height="80"></a></p>
{% else %}
<p><a href="/"><img src="/static/img/logo7.png"
alt="Rowsandall logo" height="80"></a></p>
{% endif %}
</div>
<div class="grid_6 omega">
<div class="grid_4 alpha">
<div class="grid_1 alpha">
<p id="header">
<a class="button gray small" href="/rowers/videos">Videos</a></p>
</div>
<div class="grid_2">
<p id="header">
<a class="button gray small" href="http://analytics.rowsandall.com/">Rowing Analytics BLOG</a></p>
</div>
<div class="grid_1 omega">
<p id="header">
<a class="button gray small" href="/rowers/email">Contact</a>
</p>
</div>
<div class="grid_4 alpha">
<p>Free Data and Analysis. For Rowers. By Rowers.</p>
</div>
</div>
<div class="grid_1">
<div class="grid_1 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 account, e.g. heart rate zones, power zones, email, teams</span>
{% else %}
<p><a class="button gray small" href="{% url 'login' %}">login</a> </p>
{% endif %}
</div>
<div class="grid_1">
{% 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_1 omega">
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
<h6 class="graytext">Pro Member</h6>
{% else %}
<div class="grid_1"><a class="button green small" href="/rowers/paidplans">Upgrade to Pro</a></div>
{% endif %}
</div>
</div>
</div>
<div class="grid_12">
<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_1 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 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 tooltip">
{% block teams %}
{% endblock %}
</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_1">
<p id="footer">
<a href="/rowers/brochure">Brochure</a></p>
</div>
<div class="grid_1">
<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/partners">Partners</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="http://analytics.rowsandall.com/">Rowing Analytics BLOG</a></p>
</div>
<div class="grid_2 omega">
<p id="footer">
<a href="https://www.facebook.com/groups/rowsandall/">Facebook group</a></p>
</div>
{% endblock %}
</div>
{% cookielaw_banner %}
</div>
<!-- end container -->
{% analytical_body_bottom %}
{% block body_bottom %}{% endblock %}
</body>
</html>
-194
View File
@@ -1,194 +0,0 @@
{% load rowerfilters %}
<!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|is_promember %}
<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|is_promember %}
<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_1">
<p id="footer">
<a href="/rowers/brochure">Brochure</a></p>
</div>
<div class="grid_1">
<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>
-60
View File
@@ -1,60 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Rowsandall {% endblock %}
{% block content %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="workouts" class="grid_12 alpha">
<h1>Interactive Plot</h1>
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_2 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id|encode }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
{{ the_div|safe }}
</div>
{% endblock %}
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
-77
View File
@@ -1,77 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Compare Workouts {% endblock %}
{% block content %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="other" class="grid_12 alpha">
<div class="grid_2 alpha suffix_10">
<a class="button blue small"
href="/rowers/workout/compare/{{ id2 }}/{{ id1 }}/{{ xparam }}/{{ yparam }}">Swap Workouts</a>
</div>
</div>
<p>&nbsp;</p>
<div id="plotbuttons" class="grid_12 alpha">
<div id="x-axis" class="grid_6 alpha">
<div class="grid_2 alpha">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/time/{{ yparam }}">Time</a>
</div>
<div class="grid_2 suffix_2 omega">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/distance/{{ yparam }}">Distance</a>
</div>
</div>
<div id="y-axis" class="grid_6 omega">
<div class="grid_2 alpha">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/pace">Pace</a>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/hr">Heart Rate</a>
</div>
<div class="grid_2 omega">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/spm">SPM</a>
</div>
</div>
</div>
<div id="theplot" class="grid_12 alpha">
{{ the_div|safe }}
</div>
{% endblock %}
-131
View File
@@ -1,131 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %} Comparison Plot {% endblock %}
{% block content %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_8 omega">
<p>
<a class="button gray small" href="/rowers/workout/compare/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
<div id="plotbuttons" class="grid_12 alpha">
<div id="x-axis" class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
<a class="button blue small"
href="/rowers/workout/compare/{{ id2 }}/{{ id1 }}/{{ xparam }}/{{ yparam }}/{{ plottype }}">Swap Workouts</a>
</p>
</div>
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key != 'None' %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1}}/{{ id2 }}/{{ key }}/{{ yparam }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ key }}/{{ yparam }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
<a class="button rosy small" href="/rowers/paidplans">{{ value }}</a>
{% endfor %}
{% endif %}
</div>
</div>
<div class="grid_2 omega dropdown">
<button class="grid_2 alpha button blue small dropbtn">Y-axis</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist and key != 'None' %}
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/paidplans">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
<div id="y-axis" class="grid_6 omega">
<div class="grid_2 prefix_2 alpha">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/line">Line Plot</a>
</div>
<div class="grid_2 omega">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/scatter">Scatter Plot</a>
</div>
</div>
</div>
<div id="theplot" class="grid_12 alpha flexplot">
{{ the_div|safe }}
</div>
{% endblock %}
+4 -9
View File
@@ -58,18 +58,13 @@
</script> </script>
<div id="id_css_res"> <div id="id_css_res">
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css" type="text/css" />
</div> </div>
<div id="id_js_res"> <div id="id_js_res">
<script <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"> <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js"></script>
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
</div> </div>
+4 -8
View File
@@ -60,16 +60,12 @@
<div id="id_css_res"> <div id="id_css_res">
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css" type="text/css" />
</div> </div>
<div id="id_js_res"> <div id="id_js_res">
<script <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"> <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js"></script>
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
</div> </div>
+1 -1
View File
@@ -98,7 +98,7 @@
</li> </li>
{% endif %} {% endif %}
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -48,7 +48,7 @@
}); });
</script> </script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
-182
View File
@@ -1,182 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% load tz %}
{% block title %} Flexible Plot {% endblock %}
{% localtime on %}
{% block content %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
{{ widgetscript | safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_8 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
<p>&nbsp;</p>
<div id="plotbuttons" class="grid_12 alpha">
<div id="x-axis" class="grid_6 alpha">
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/time/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Time</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/distance/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Distance</a>
{% if promember %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/power/{{ yparam1 }}/{{ yparam2 }}/scatter">Power</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/hr/{{ yparam1 }}/{{ yparam2 }}/scatter">HR</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/spm/{{ yparam1 }}/{{ yparam2 }}/scatter">SPM</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/peakforce/{{ yparam1 }}/{{ yparam2 }}/scatter">Peak Force</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/averageforce/{{ yparam1 }}/{{ yparam2 }}/scatter">Average Force</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/drivelength/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Length</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/driveenergy/{{ yparam1 }}/{{ yparam2 }}/scatter">Work per Stroke</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/drivespeed/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Speed</a>
{% else %}
<a class="button rosy small" href="/rowers/paidplans">Power (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">HR (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">SPM (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Drive Speed (Pro)</a>
{% endif %}
</div>
</div>
<div class="grid_2 dropdown">
<button class="grid_2 alpha button blue small dropbtn">Left</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/pace/{{ yparam2 }}/{{ plottype }}">Pace</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/hr/{{ yparam2 }}/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/spm/{{ yparam2 }}/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/power/{{ yparam2 }}/{{ plottype }}">Power</a>
{% if promember %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/peakforce/{{ yparam2 }}/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/averageforce/{{ yparam2 }}/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/drivelength/{{ yparam2 }}/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/driveenergy/{{ yparam2 }}/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/drivespeed/{{ yparam2 }}/{{ plottype }}">Drive Speed</a>
{% else %}
<a class="button rosy small" href="/rowers/paidplans">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Drive Speed (Pro)</a>
{% endif %}
</div>
</div>
<div class="grid_2 dropdown omega">
<button class="grid_2 alpha button blue small dropbtn">Right</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/hr/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/spm/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/power/{{ plottype }}">Power</a>
{% if promember %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/peakforce/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/averageforce/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/drivelength/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/driveenergy/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/drivespeed/{{ plottype }}">Drive Speed</a>
{% else %}
<a class="button rosy small" href="/rowers/paidplans">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/paidplans">Drive Speed (Pro)</a>
{% endif %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/None/{{ plottype }}">None</a>
</div>
</div>
</div>
<div id="y-axis" class="grid_6 omega">
<div class="grid_2 alpha tooltip">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
{% if workstrokesonly %}
<input type="hidden" name="workstrokesonly" value="True">
{% else %}
<input class="grid_2 alpha button blue small" type="hidden" name="workstrokesonly" value="False">
{% endif %}
<input class="grid_2 alpha button blue small" value="Toggle Work Strokes" type="Submit">
</form>
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/line">Line Plot</a>
</div>
<div class="grid_2 omega">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/scatter">Scatter Plot</a>
</div>
</div>
</div>
<div id="theplot" class="grid_12 alpha flexplot">
{{ the_div|safe }}
</div>
<div id="thewidgets" class="grid_12 alpha">
{{ widgetdiv1|safe }}
{{ widgetdiv2|safe }}
</div>
{% endblock %}
{% endlocaltime %}
+2 -2
View File
@@ -11,8 +11,8 @@
{{ js_res | safe }} {{ js_res | safe }}
{{ css_res| safe }} {{ css_res| safe }}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+4 -9
View File
@@ -60,17 +60,12 @@
<div id="id_css_res"> <div id="id_css_res">
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css" type="text/css" />
</div> </div>
<div id="id_js_res"> <div id="id_js_res">
<script <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"> <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js"></script>
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
</div> </div>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -10,7 +10,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -138,7 +138,7 @@
<div id="advancedplots" class="grid_6 omega"> <div id="advancedplots" class="grid_6 omega">
<div class="grid_6 alpha"> <div class="grid_6 alpha">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -6,7 +6,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -10,7 +10,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -13,7 +13,7 @@
{% block main %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -23,7 +23,7 @@
</li> </li>
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -31,7 +31,7 @@
<img src="/static/img/rivercurrent.jpg" width="400"> <img src="/static/img/rivercurrent.jpg" width="400">
</li> </li>
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -62,7 +62,7 @@
</form> </form>
</li> </li>
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
-54
View File
@@ -1,54 +0,0 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %} Flexible Plot {% endblock %}
{% block content %}
{{ js_res | safe }}
{{ css_res| safe }}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ the_script |safe }}
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_8 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
<p>&nbsp;</p>
<div id="theplot" class="grid_12 alpha">
{{ the_div|safe }}
</div>
{% endblock %}
+1 -1
View File
@@ -53,7 +53,7 @@
</li> </li>
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -13,7 +13,7 @@
{{ workout.date }} - {{ workout.distance }}m - {{ workout.duration |durationprint:"%H:%M:%S.%f" }}{% endblock %} {{ workout.date }} - {{ workout.distance }}m - {{ workout.duration |durationprint:"%H:%M:%S.%f" }}{% endblock %}
{% block meta %} {% block meta %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -86,7 +86,7 @@
</li> </li>
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -130,7 +130,7 @@ $('#id_workouttype').change();
{% endif %} {% endif %}
{% if mapdiv %} {% if mapdiv %}
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+1 -1
View File
@@ -121,7 +121,7 @@
</li> </li>
{% endif %} {% endif %}
<li class="grid_2"> <li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
+3 -2
View File
@@ -16,11 +16,12 @@ class TestErrorPages(TestCase):
factory = RequestFactory() factory = RequestFactory()
request = factory.get('/') request = factory.get('/')
response = error404_view(request) response = error404_view(request)
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
self.assertIn('404 Page not found', unicode(response)) self.assertIn('404 Page not found', str(response.content))
response = error500_view(request) response = error500_view(request)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
self.assertIn('500 Internal Server Error', unicode(response)) self.assertIn('500 Internal Server Error', str(response.content))
response = error400_view(request) response = error400_view(request)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
Binary file not shown.
+8 -1
View File
@@ -5,6 +5,8 @@ from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from rowers.imports import * from rowers.imports import *
import numpy
import rowers.mytypes as mytypes import rowers.mytypes as mytypes
from rowers.mytypes import otwtypes from rowers.mytypes import otwtypes
@@ -305,6 +307,11 @@ def get_userid(access_token):
return res return res
def default(o):
if isinstance(o, numpy.int64): return int(o)
raise TypeError
def workout_ua_upload(user,w): def workout_ua_upload(user,w):
message = "Uploading to MapMyFitness" message = "Uploading to MapMyFitness"
uaid = 0 uaid = 0
@@ -331,7 +338,7 @@ def workout_ua_upload(user,w):
} }
url = "https://api.ua.com/v7.1/workout/" url = "https://api.ua.com/v7.1/workout/"
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ):
+5
View File
@@ -44,6 +44,11 @@ from rowers.utils import (
) )
def cleanbody(body): def cleanbody(body):
try:
body = body.decode('utf-8')
except AttributeError:
pass
regex = r".*---\n([\s\S]*?)\.\.\..*" regex = r".*---\n([\s\S]*?)\.\.\..*"
matches = re.finditer(regex,body) matches = re.finditer(regex,body)
+9 -3
View File
@@ -5,6 +5,12 @@ from __future__ import unicode_literals
from rowers.views.statements import * from rowers.views.statements import *
import numpy
def default(o):
if isinstance(o, numpy.int64): return int(o)
raise TypeError
# Send workout to TP # Send workout to TP
@login_required() @login_required()
@@ -228,7 +234,7 @@ def workout_runkeeper_upload_view(request,id=0):
'Content-Length':'nnn'} 'Content-Length':'nnn'}
url = "https://api.runkeeper.com/fitnessActivities" url = "https://api.runkeeper.com/fitnessActivities"
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ):
@@ -293,7 +299,7 @@ def workout_underarmour_upload_view(request,id=0):
} }
url = "https://api.ua.com/v7.1/workout/" url = "https://api.ua.com/v7.1/workout/"
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
@@ -356,7 +362,7 @@ def workout_sporttracks_upload_view(request,id=0):
'Content-Type': 'application/json'} 'Content-Type': 'application/json'}
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json" url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json"
response = requests.post(url,headers=headers,data=json.dumps(data)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
+7 -4
View File
@@ -28,6 +28,9 @@ import isodate
import re import re
import cgi import cgi
from icalendar import Calendar, Event from icalendar import Calendar, Event
from functools import reduce
import rowers.braintreestuff as braintreestuff import rowers.braintreestuff as braintreestuff
import rowers.payments as payments import rowers.payments as payments
from rowers.opaque import encoder from rowers.opaque import encoder
@@ -502,7 +505,7 @@ def remove_asynctask(request,id):
def get_job_result(jobid): def get_job_result(jobid):
if settings.TESTING: if settings.TESTING:
return None return None
elif settings.DEBUG: elif settings.CELERY:
result = celery_result.AsyncResult(jobid).result result = celery_result.AsyncResult(jobid).result
else: else:
running_job_ids = rq_registry.get_job_ids() running_job_ids = rq_registry.get_job_ids()
@@ -541,7 +544,7 @@ def get_job_status(jobid):
'started_at':None, 'started_at':None,
} }
return summary return summary
elif settings.DEBUG: elif settings.CELERY:
job = celery_result.AsyncResult(jobid) job = celery_result.AsyncResult(jobid)
jobresult = job.result jobresult = job.result
@@ -592,7 +595,7 @@ def get_job_status(jobid):
return summary return summary
def kill_async_job(request,id='aap'): def kill_async_job(request,id='aap'):
if settings.DEBUG: if settings.CELERY:
job = celery_result.AsyncResult(id) job = celery_result.AsyncResult(id)
job.revoke() job.revoke()
else: else:
@@ -734,7 +737,7 @@ def get_stored_tasks_status(request):
if finished: if finished:
cache.set(id,100) cache.set(id,100)
progress = 100 progress = 100
elif cached_progress>0: elif cached_progress is not None and cached_progress>0:
progress = cached_progress progress = cached_progress
else: else:
progress = 0 progress = 0
+1 -1
View File
@@ -4595,7 +4595,7 @@ def workout_split_view(request,id=0):
pass pass
qdict = {'q':rowname} qdict = {'q':rowname}
url+='?'+urllib.urlencode(qdict) url+='?'+urllib.parse.urlencode(qdict)
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
+1 -1
View File
@@ -58,7 +58,7 @@
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/> <link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/>
<link rel="stylesheet" href="/static/css/resetnew.css" /> <link rel="stylesheet" href="/static/css/resetnew.css" />
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-9ralMzdK1QYsk4yBY680hmsb4/hJ98xK3w0TIaJ3ll4POWpWUYaA2bRjGGujGT8w" crossorigin="anonymous"> <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-6jHF7Z3XI3fF4XZixAuSu0gGKrXwoX/w3uFPxC56OtjChio7wtTGJWRW53Nhx6Ev" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/styles2.css"> <link rel="stylesheet" href="/static/css/styles2.css">
<link rel="stylesheet" href="/static/css/text2.css" /> <link rel="stylesheet" href="/static/css/text2.css" />
<link rel="stylesheet" href="/static/css/rowsandall2.css" /> <link rel="stylesheet" href="/static/css/rowsandall2.css" />
+1 -1
View File
@@ -56,7 +56,7 @@
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/> <link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/>
<link rel="stylesheet" href="/static/css/resetnew.css" /> <link rel="stylesheet" href="/static/css/resetnew.css" />
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-9ralMzdK1QYsk4yBY680hmsb4/hJ98xK3w0TIaJ3ll4POWpWUYaA2bRjGGujGT8w" crossorigin="anonymous"> <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-6jHF7Z3XI3fF4XZixAuSu0gGKrXwoX/w3uFPxC56OtjChio7wtTGJWRW53Nhx6Ev" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/frontstyles.css"> <link rel="stylesheet" href="/static/css/frontstyles.css">
<link rel="stylesheet" href="/static/css/text2.css" /> <link rel="stylesheet" href="/static/css/text2.css" />
<link rel="stylesheet" href="/static/css/rowsandall2.css" /> <link rel="stylesheet" href="/static/css/rowsandall2.css" />