Merge branch 'develop' into feature/workoutslist
This commit is contained in:
@@ -1286,6 +1286,15 @@ class AnalysisChoiceForm(forms.Form):
|
||||
label='Include Rest Strokes')
|
||||
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AnalysisChoiceForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if 'initial' in kwargs and kwargs['initial']['function'] == 'compare':
|
||||
self.fields['xaxis'].initial = 'time'
|
||||
self.fields['yaxis1'].initial = 'hr'
|
||||
self.fields['plottype'].initial = 'line'
|
||||
|
||||
|
||||
|
||||
class BoxPlotChoiceForm(forms.Form):
|
||||
yparam = forms.ChoiceField(choices=parchoices,initial='spm',
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
on behalf of {{ name }}.
|
||||
</p>
|
||||
<p>
|
||||
By accepting the invite, you are agreeing with the sharing
|
||||
By accepting the invite, you are agreeing with the sharing
|
||||
of personal data according to our privacy policy.
|
||||
</p>
|
||||
<p>
|
||||
To accept the login to the
|
||||
site and you will find the invitation here on the Teams page:
|
||||
<a href="{{ siteurl }}/rowers/me/teams">{{ siteurl }}/rowers/me/teams</a>
|
||||
<a href="{{ siteurl }}/rowers/me/teams">{{ siteurl }}/rowers/me/teams</a>,
|
||||
including the email address of {{ name }}, if you need a contact.
|
||||
</p>
|
||||
<p>
|
||||
You can also click the direct link:
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
</li>
|
||||
<li id="compare">
|
||||
{% if team %}
|
||||
<a href="/rowers/team-compare-select/team/{{ team.id }}/"><i class="fas fa-balance-scale fa-fw"></i> Compare</a>
|
||||
<a href="/rowers/user-analysis-select/compare/team/{{ team.id }}/">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare</a>
|
||||
{% else %}
|
||||
<a href="/rowers/team-compare-select/team/0/"><i class="fas fa-balance-scale fa-fw"></i> Compare</a>
|
||||
<a href="/rowers/user-analysis-select/compare/team/0/">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li id="compare">
|
||||
<a href="/rowers/team-compare-select/workout/{{ workout.id|encode }}/">
|
||||
<a href="/rowers/user-analysis-select/compare/workout/{{ workout.id|encode }}/">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
</li>
|
||||
<li id="compare">
|
||||
{% if team %}
|
||||
<a href="/rowers/team-compare-select/team/{{ team.id }}/">
|
||||
<a href="/rowers/user-analysis-select/compare/team/{{ team.id }}/">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare</a>
|
||||
{% else %}
|
||||
<a href="/rowers/team-compare-select/team/0/">
|
||||
<a href="/rowers/user-analysis-select/compare/team/0/">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% load static %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Workouts{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
||||
<script>
|
||||
function toggle(source) {
|
||||
checkboxes = document.querySelectorAll("input[name='workouts']");
|
||||
for(var i=0, n=checkboxes.length;i<n;i++) {
|
||||
checkboxes[i].checked = source.checked;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
|
||||
// Get the form fields and hidden div
|
||||
var modality = $("#id_modality");
|
||||
var hidden = $("#id_waterboattype");
|
||||
|
||||
|
||||
// Hide the fields.
|
||||
// Use JS to do this in case the user doesn't have JS
|
||||
// enabled.
|
||||
|
||||
hidden.hide();
|
||||
|
||||
if (modality.val() == 'water') {
|
||||
hidden.show();
|
||||
}
|
||||
|
||||
// Setup an event listener for when the state of the
|
||||
// checkbox changes.
|
||||
modality.change(function() {
|
||||
// Check to see if the checkbox is checked.
|
||||
// If it is, show the fields and populate the input.
|
||||
// If not, hide the fields.
|
||||
var Value = modality.val();
|
||||
if (Value=='water') {
|
||||
// Show the hidden fields.
|
||||
hidden.show();
|
||||
} else {
|
||||
// Make sure that the hidden fields are indeed
|
||||
// hidden.
|
||||
hidden.hide();
|
||||
|
||||
// You may also want to clear the value of the
|
||||
// hidden fields here. Just in case somebody
|
||||
// shows the fields, enters data to them and then
|
||||
// unticks the checkbox.
|
||||
//
|
||||
// This would do the job:
|
||||
//
|
||||
// $("#hidden_field").val("");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<h1>{{ team.name }} Compare Workouts</h1>
|
||||
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<p>Select two or more workouts on the left, set your plot settings,
|
||||
and press submit</p>
|
||||
<p>
|
||||
You can use the date and search forms to search through all
|
||||
workouts from this team.
|
||||
</p>
|
||||
<p>
|
||||
TIP: Agree with your team members to put tags (e.g. '8x500m')
|
||||
in the notes section of
|
||||
your workouts. That makes it easy to search.
|
||||
</p>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<form enctype="multipart/form-data"
|
||||
action=""
|
||||
method="post">
|
||||
<table>
|
||||
{{ dateform.as_table }}
|
||||
</table>
|
||||
<table>
|
||||
{{ modalityform.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<input name='modalityform' class="button green" type="submit" value="Filter">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<form id="searchform"
|
||||
action=""
|
||||
method="get" accept-charset="utf-8">
|
||||
{{ searchform }}
|
||||
<input type="submit" value="GO"></input>
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2 maxheight">
|
||||
{% if workouts %}
|
||||
<form enctype="multipart/form-data"
|
||||
action="/rowers/multi-compare/"
|
||||
method="post">
|
||||
|
||||
<input type="checkbox" onClick="toggle(this)" /> Toggle All<br/>
|
||||
|
||||
<table width="100%" class="listtable">
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
|
||||
{% else %}
|
||||
<p> No workouts found </p>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<p>
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{ chartform.as_table }}
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
<input name="chartform" type="submit" value="Compare">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_workouts.html' %}
|
||||
{% endblock %}
|
||||
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
<p>
|
||||
<a class="button gray small" href="/rowers/team-compare-select/team/{{ teamid }}/">Multi Compare</a>
|
||||
<a class="button gray small" href="/rowers/user-analysis-select/compare/{{ teamid }}/">Multi Compare</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<a href="/rowers/team/{{ team.id }}/">{{ team.name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/team/{{ team.id }}/leaveconfirm/">Leave</a>
|
||||
<a href="/rowers/team/{{ team.id }}/leaveconfirm/">Leave</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -29,7 +29,7 @@
|
||||
</table>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if otherteams %}
|
||||
<li class="grid_2">
|
||||
<h2>Open Groups</h2>
|
||||
@@ -73,7 +73,7 @@
|
||||
<a href="/rowers/team/{{ team.id }}/">{{ team.name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/team/{{ team.id }}/deleteconfirm/">Delete</a>
|
||||
<a href="/rowers/team/{{ team.id }}/deleteconfirm/">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -98,7 +98,7 @@
|
||||
{{ coach.user.first_name }} {{ coach.user.last_name }}
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red"
|
||||
<a
|
||||
href="/rowers/coaches/{{ coach.id }}/dropcoachconfirm/">Remove
|
||||
</a>
|
||||
</td>
|
||||
@@ -124,7 +124,7 @@
|
||||
{{ coachee.user.first_name }} {{ coachee.user.last_name }}
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red"
|
||||
<a
|
||||
href="/rowers/coaches/{{ coachee.id }}/dropconfirm/">Remove
|
||||
</a>
|
||||
</td>
|
||||
@@ -138,11 +138,11 @@
|
||||
<li class="grid_2">
|
||||
<h2>Group Invitations and Requests</h2>
|
||||
<p>This section lists open invites to join a group. By accepting
|
||||
a group invite, you are agreeing with the sharing
|
||||
a group invite, you are agreeing with the sharing
|
||||
of personal data between group members and coaches according to
|
||||
our <a href="/rowers/legal/">privacy policy</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<p>As a group manager, by accepting a group invite, you are agreeing
|
||||
with our <a href="/rowers/legal/">privacy policy</a> regarding groups and
|
||||
personal data owned by group members.</p>
|
||||
@@ -163,10 +163,10 @@
|
||||
<td><a href="/rowers/team/{{ i.team.id }}/">{{ i.team.name }}</a></td>
|
||||
<td>{{ i.team.manager.first_name }} {{ i.team.manager.last_name }}</td>
|
||||
<td>{{ user.first_name }} {{ user.last_name }}</td>
|
||||
<td><a class="button small green" href="/rowers/me/invitation/{{ i.code }}/">Accept</a>
|
||||
<td><a href="/rowers/me/invitation/{{ i.code }}/">Accept</a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/me/invitation/{{ i.id }}/reject/">Reject</a>
|
||||
<a href="/rowers/me/invitation/{{ i.id }}/reject/">Reject</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -184,9 +184,9 @@
|
||||
<td><a href="/rowers/team/{{ i.team.id }}/">{{ i.team.name }}</a></td>
|
||||
<td>{{ i.team.manager.first_name }} {{ i.team.manager.last_name }}</td>
|
||||
<td>{{ i.user.first_name }} {{ i.user.last_name }}</td>
|
||||
<td><a class="button small green" href="/rowers/me/request/{{ i.code }}/">Accept</a>
|
||||
<td><a href="/rowers/me/request/{{ i.code }}/">Accept</a>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/me/request/{{ i.id }}/reject/">Reject</a>
|
||||
<a href="/rowers/me/request/{{ i.id }}/reject/">Reject</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -201,7 +201,7 @@
|
||||
{% endif %}
|
||||
<td>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/me/invitation/{{ i.id }}/revoke/">Revoke</a>
|
||||
<a href="/rowers/me/invitation/{{ i.id }}/revoke/">Revoke</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -218,7 +218,7 @@
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<input class="button green" type="submit" value="Submit">
|
||||
<input class="button" type="submit" value="Submit">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if mycoachrequests or mycoachoffers or coachoffers or coachrequests %}
|
||||
@@ -226,16 +226,17 @@
|
||||
<h2>Coaching Offers and Requests</h2>
|
||||
<p>This section lists open offers and requests related to coaching.
|
||||
By accepting a coaching offer, the coach can run
|
||||
analysis, add workouts and edit settings on behalf of the athlete.
|
||||
analysis, add workouts and edit settings on behalf of the athlete.
|
||||
You agree to the sharing
|
||||
of personal data between athletes and coaches according to
|
||||
our <a href="/rowers/legal/">privacy policy</a>.
|
||||
</p>
|
||||
</p>
|
||||
<table width="90%" class="listtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Coach</th>
|
||||
<th>User</th>
|
||||
<th>E-mail</th>
|
||||
<th>Action</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
@@ -245,12 +246,13 @@
|
||||
<tr>
|
||||
<td>{{ i.coach.user.first_name }} {{ i.coach.user.last_name }}</td>
|
||||
<td>{{ i.user.first_name }} {{ i.user.last_name }}</td>
|
||||
<td>{{ i.user.email }}</td>
|
||||
<td><a
|
||||
class="button small green"
|
||||
|
||||
href="/rowers/me/coachrequest/{{ i.code }}/accept">Accept</a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/me/coachrequest/{{ i.id }}/reject/">Reject</a>
|
||||
<a href="/rowers/me/coachrequest/{{ i.id }}/reject/">Reject</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -261,7 +263,7 @@
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<a class="button small red" href="/rowers/me/coachoffer/{{ i.id }}/revoke/">Revoke</a>
|
||||
<a href="/rowers/me/coachoffer/{{ i.id }}/revoke/">Revoke</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -272,7 +274,7 @@
|
||||
<td> </td>
|
||||
<td>
|
||||
<a
|
||||
class="button small red"
|
||||
|
||||
href="/rowers/me/coachrequest/{{ i.id }}/revoke/">Revoke</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -282,12 +284,12 @@
|
||||
<td>{{ i.coach.user.first_name }} {{ i.coach.user.last_name }}</td>
|
||||
<td>{{ i.user.first_name }} {{ i.user.last_name }}</td>
|
||||
<td><a
|
||||
class="button small green"
|
||||
|
||||
href="/rowers/me/coachoffer/{{ i.code }}/accept/">Accept</a>
|
||||
</td>
|
||||
<td>
|
||||
<a
|
||||
class="button small red"
|
||||
|
||||
href="/rowers/me/coachoffer/{{ i.id }}/revoke/">Reject</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -312,14 +314,14 @@
|
||||
<td>{{ a.user.first_name }} {{ a.user.last_name }}</td>
|
||||
<td>
|
||||
<a
|
||||
class="button small green"
|
||||
|
||||
href="/rowers/me/coachoffer/{{ a.user.id }}/">Offer Coaching</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if potentialcoaches %}
|
||||
<li class="grid_2">
|
||||
@@ -337,7 +339,7 @@
|
||||
<td>{{ c.first_name }} {{ c.last_name }}</td>
|
||||
<td>
|
||||
<a
|
||||
class="button small green"
|
||||
|
||||
href="/rowers/me/coachrequest/{{ c.id }}/">Request Coaching</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -36,7 +36,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from io import StringIO
|
||||
|
||||
from django.test.client import RequestFactory
|
||||
from rowers.views import c2_open, multi_compare_view
|
||||
from rowers.views import c2_open
|
||||
|
||||
|
||||
from rowers.forms import (
|
||||
|
||||
@@ -11,70 +11,6 @@ nu = datetime.datetime.now()
|
||||
from rowers.views import *
|
||||
from rowers.views.analysisviews import histodata
|
||||
|
||||
class WorkoutCompareTest(TestCase):
|
||||
def setUp(self):
|
||||
self.u = UserFactory()
|
||||
|
||||
self.r = Rower.objects.create(user=self.u,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,surveydone=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='coach')
|
||||
|
||||
self.c = Client()
|
||||
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
|
||||
self.factory = RequestFactory()
|
||||
self.password = faker.word()
|
||||
self.u.set_password(self.password)
|
||||
self.u.save()
|
||||
|
||||
def tearDown(self):
|
||||
for workout in self.user_workouts:
|
||||
try:
|
||||
os.remove(workout.csvfilename)
|
||||
except (IOError, FileNotFoundError, OSError):
|
||||
pass
|
||||
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
def test_workouts_compare(self, mocked_sqlalchemy,
|
||||
mocked_getsmallrowdata_db):
|
||||
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/team-compare-select/workout/'+encoded1+'/team/0/user/1/'
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
|
||||
def test_workouts_compare_submit(self, mocked_sqlalchemy,
|
||||
mocked_getsmallrowdata_db):
|
||||
|
||||
login = self.c.login(username=self.u.username,password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
form_data = {
|
||||
'chartform':'Compare',
|
||||
'plottype':'scatter',
|
||||
'teamid':0,
|
||||
'workouts':['1','2','3'],
|
||||
'xparam':'distance',
|
||||
'yparam':'hr',
|
||||
}
|
||||
|
||||
form = WorkoutMultipleCompareForm(form_data)
|
||||
chartform = ChartParamChoiceForm(form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
self.assertTrue(chartform.is_valid())
|
||||
|
||||
response = self.c.post('/rowers/multi-compare/',form_data)
|
||||
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
|
||||
|
||||
class ListWorkoutTest(TestCase):
|
||||
|
||||
@@ -214,70 +214,6 @@ class WorkoutViewTest(TestCase):
|
||||
expected_url=expected_url,
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
@patch('rowers.middleware.myqueue')
|
||||
def test_compares(self, mocked_sqlalchemy, mocked_getsmallrowdata_db,
|
||||
mocked_myqueue):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
|
||||
session = self.c.session
|
||||
session['ids'] = [self.werg1.id,self.werg2.id]
|
||||
session.save()
|
||||
|
||||
response = self.c.get('/')
|
||||
|
||||
url = reverse('team_comparison_select')
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
d1 = self.werg1.date-datetime.timedelta(days=2)
|
||||
d2 = self.werg2.date+datetime.timedelta(days=2)
|
||||
|
||||
form_data = {
|
||||
'startdate': d1.strftime('%Y-%m-%d'),
|
||||
'enddate': d2.strftime('%Y-%m-%d'),
|
||||
'modality':'water',
|
||||
'waterboattype':['1x'],
|
||||
}
|
||||
|
||||
form = DateRangeForm(form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
form = TrendFlexModalForm(form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post(url,form_data)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
url = reverse('multi_compare_view',kwargs={
|
||||
'userid':self.u.id,
|
||||
'id':encoder.encode_hex(self.werg1.id),
|
||||
})
|
||||
|
||||
form_data = {
|
||||
'xparam':'time',
|
||||
'yparam':'power',
|
||||
'plottype':'line',
|
||||
'teamid': '',
|
||||
}
|
||||
|
||||
|
||||
response = self.c.post(url,form_data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
session['plottype'] = 'scatter'
|
||||
session['xparam'] = 'time'
|
||||
session['yparam'] = 'hr'
|
||||
|
||||
session.save()
|
||||
|
||||
response = self.c.get('/')
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
|
||||
@@ -16,6 +16,7 @@ from django.db import transaction
|
||||
import json
|
||||
|
||||
from rowers.views.workoutviews import plannedsession_compare_view
|
||||
from rowers.views.analysisviews import analysis_new
|
||||
from rowers.views.otherviews import download_fit
|
||||
from rowers.opaque import encoder
|
||||
from django.utils.crypto import get_random_string
|
||||
@@ -443,7 +444,11 @@ class SessionLinkTest(TestCase):
|
||||
|
||||
url = reverse(plannedsession_compare_view,kwargs={'id':ps.id,'userid':self.u.id})
|
||||
response = self.c.get(url,follow=True)
|
||||
expected_url = reverse('multi_compare_view',kwargs={'userid':self.u.id,'id':encoder.encode_hex(w.id)})
|
||||
expected_url = reverse('analysis_new',
|
||||
kwargs={'function':'compare',
|
||||
'id':encoder.encode_hex(w.id),
|
||||
'session':ps.id,
|
||||
})
|
||||
self.assertRedirects(response,expected_url=expected_url,
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
@@ -473,7 +478,7 @@ class SessionLinkTest(TestCase):
|
||||
session.save()
|
||||
|
||||
request.user = self.u
|
||||
response = multi_compare_view(request,id=str(w.id))
|
||||
response = analysis_new(request,id=encoder.encode_hex(w.id))
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
# and adding a get
|
||||
@@ -491,7 +496,7 @@ class SessionLinkTest(TestCase):
|
||||
session.save()
|
||||
|
||||
request.user = self.u
|
||||
response = multi_compare_view(request,id=str(w.id))
|
||||
response = analysis_new(request,id=encoder.encode_hex(w.id))
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
|
||||
@@ -169,70 +169,6 @@ class TeamTest(TestCase):
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
@patch('rowers.middleware.myqueue')
|
||||
def test_compares(self, mocked_sqlalchemy, mocked_getsmallrowdata_db,
|
||||
mocked_myqueue):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
|
||||
session = self.c.session
|
||||
session['ids'] = [self.werg1.id,self.werg2.id]
|
||||
session.save()
|
||||
|
||||
response = self.c.get('/')
|
||||
|
||||
url = reverse('team_comparison_select',kwargs={'teamid':self.t.id})
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
d1 = self.werg1.date-timedelta(days=2)
|
||||
d2 = self.werg2.date+timedelta(days=2)
|
||||
|
||||
form_data = {
|
||||
'startdate': d1.strftime('%Y-%m-%d'),
|
||||
'enddate': d2.strftime('%Y-%m-%d'),
|
||||
'modality':'water',
|
||||
'waterboattype':['1x'],
|
||||
}
|
||||
|
||||
form = DateRangeForm(form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
form = TrendFlexModalForm(form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post(url,form_data)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
url = reverse('multi_compare_view',kwargs={
|
||||
'userid':self.u.id,
|
||||
'id':encoder.encode_hex(self.werg1.id),
|
||||
})
|
||||
|
||||
form_data = {
|
||||
'xparam':'time',
|
||||
'yparam':'power',
|
||||
'plottype':'line',
|
||||
'teamid': '',
|
||||
}
|
||||
|
||||
|
||||
response = self.c.post(url,form_data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
session['plottype'] = 'scatter'
|
||||
session['xparam'] = 'time'
|
||||
session['yparam'] = 'hr'
|
||||
|
||||
session.save()
|
||||
|
||||
response = self.c.get('/')
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_teamsview(self):
|
||||
|
||||
|
||||
@@ -124,8 +124,6 @@ class URLTests(TestCase):
|
||||
'/rowers/sessions/multicreate/',
|
||||
'/rowers/sessions/print/',
|
||||
'/rowers/sessions/teamcreate/',
|
||||
'/rowers/team-compare-select/',
|
||||
'/rowers/team-compare-select/workout/'+encoded1+'/',
|
||||
'/rowers/workout/'+encoded1+'/',
|
||||
'/rowers/workout/'+encoded1+'/adddistanceplot/',
|
||||
'/rowers/workout/'+encoded1+'/adddistanceplot2/',
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
22,24,courses_view,see race courses,TRUE,200,FALSE,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||
23,25,course_upload_view,upload a new course,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||
24,26,addmanual_view,upload a manual workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
|
||||
25,27,team_comparison_select,compare with a team member workout,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,TRUE,TRUE,TRUE,TRUE,
|
||||
26,28,workouts_join_view,join workouts,TRUE,302,pro,302,302,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||
27,29,workouts_join_select,select workouts to join,TRUE,404,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||
29,31,analysis_new,analysis front page,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||
@@ -97,7 +96,6 @@
|
||||
111,137,workout_recalcsummary_view,recalculates workout summary,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||
112,138,workout_sporttracks_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||
115,141,workout_tp_upload_view,uploads workout to C2,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE,
|
||||
116,142,multi_compare_view,compare workouts ,TRUE,302,basic,302,403,basic,302,403,coach,302,302,FALSE,FALSE,TRUE,TRUE,TRUE,
|
||||
117,145,alerts_view,view alerts,TRUE,302,basic,200,403,basic,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE,
|
||||
118,147,AlertDelete,delete alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||
119,148,alert_edit_view,edit alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
|
||||
|
||||
|
@@ -308,24 +308,16 @@ urlpatterns = [
|
||||
re_path(r'^standards/upload/(?P<id>\d+)/$',views.standards_upload_view,name='standards_upload_view'),
|
||||
re_path(r'^workout/addmanual/(?P<raceid>\d+)/$',views.addmanual_view,name='addmanual_view'),
|
||||
re_path(r'^workout/addmanual/$',views.addmanual_view,name='addmanual_view'),
|
||||
re_path(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/workout/(?P<id>\b[0-9A-Fa-f]+\b)/team/(?P<teamid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/workout/(?P<id>\b[0-9A-Fa-f]+\b)/team/(?P<teamid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/workout/(?P<id>\b[0-9A-Fa-f]+\b)/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/workout/(?P<id>\b[0-9A-Fa-f]+\b)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/team/(?P<teamid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^team-compare-select/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
re_path(r'^workouts-join/$',views.workouts_join_view,name='workouts_join_view'),
|
||||
re_path(r'^workouts-join/user/(?P<userid>\d+)$',views.workouts_join_view,name='workouts_join_view'),
|
||||
re_path(r'^workouts-join-select/$',views.workouts_join_select,name='workouts_join_select'),
|
||||
re_path(r'^workouts-join-select/user/(?P<userid>\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/session/(?P<session>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/user/(?P<userid>\d+)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/user/(?P<userid>\d+)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/team/(?P<teamid>\d+)/$',views.analysis_new,name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/$',views.analysis_new,name='analysis_new'),
|
||||
@@ -518,10 +510,6 @@ urlpatterns = [
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/recalcsummary/$',views.workout_recalcsummary_view,name='workout_recalcsummary_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/sporttracksuploadw/$',views.workout_sporttracks_upload_view,name='workout_sporttracks_upload_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/tpuploadw/$',views.workout_tp_upload_view,name='workout_tp_upload_view'),
|
||||
re_path(r'^multi-compare/workout/(?P<id>\b[0-9A-Fa-f]+\b)/user/(?P<userid>\d+)/$',views.multi_compare_view,
|
||||
name='multi_compare_view'),
|
||||
re_path(r'^multi-compare/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',views.multi_compare_view,name='multi_compare_view'),
|
||||
re_path(r'^multi-compare/$',views.multi_compare_view,name='multi_compare_view'),
|
||||
re_path(r'^alerts/user/(?P<userid>\d+)/$',views.alerts_view,name='alerts_view'),
|
||||
re_path(r'^alerts/$',views.alerts_view,name='alerts_view'),
|
||||
re_path(r'^alerts/(?P<pk>\d+)/delete/$',views.AlertDelete.as_view(),name='alert_delete_view'),
|
||||
|
||||
@@ -8,6 +8,7 @@ from rowers.views.statements import *
|
||||
import collections
|
||||
import simplejson
|
||||
from jinja2 import Template,Environment,FileSystemLoader
|
||||
from rowers.rower_rules import can_view_session
|
||||
|
||||
def floatformat(x,prec=2): # pragma: no cover
|
||||
return '{x}'.format(x=round(x,prec))
|
||||
@@ -34,7 +35,7 @@ defaultoptions = {
|
||||
message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",
|
||||
redirect_field_name=None)
|
||||
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
|
||||
def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''):
|
||||
def analysis_new(request,userid=0,function='boxplot',teamid=0,id='',session=0):
|
||||
r = getrequestrower(request, userid=userid)
|
||||
user = r.user
|
||||
userid = user.id
|
||||
@@ -52,6 +53,13 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''):
|
||||
except Team.DoesNotExist:
|
||||
theteam = None
|
||||
|
||||
try:
|
||||
thesession = PlannedSession.objects.get(id=session)
|
||||
if not can_view_session(user,thesession):
|
||||
raise PermissionDenied("you cannot view this session")
|
||||
except PlannedSession.DoesNotExist:
|
||||
thesession = None
|
||||
|
||||
|
||||
if 'options' in request.session:
|
||||
options = request.session['options']
|
||||
@@ -199,6 +207,8 @@ def analysis_new(request,userid=0,function='boxplot',teamid=0,id=''):
|
||||
startdatetime__lte=enddate,
|
||||
workouttype__in=modalities,
|
||||
)
|
||||
elif thesession is not None:
|
||||
workouts = get_workouts_session(r,thesession)
|
||||
else:
|
||||
workouts = Workout.objects.filter(user=r,
|
||||
startdatetime__gte=startdate,
|
||||
|
||||
@@ -2024,163 +2024,19 @@ def plannedsession_compare_view(request,id=0,userid=0):
|
||||
request.session['plottype'] = plottype
|
||||
request.session['ps'] = ps.id
|
||||
|
||||
teams = ps.team.all()
|
||||
|
||||
if ids:
|
||||
url = reverse('multi_compare_view',
|
||||
kwargs={'userid':userid,'id':encoder.encode_hex(ids[0])})
|
||||
url = reverse('analysis_new',
|
||||
kwargs={
|
||||
'session':ps.id,
|
||||
'id':encoder.encode_hex(ids[0]),
|
||||
'function':'compare'})
|
||||
else:
|
||||
url = reverse('plannedsession_view',kwargs={'id':ps.id})
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# Team comparison
|
||||
@login_required()
|
||||
def multi_compare_view(request,id=0,userid=0):
|
||||
promember=0
|
||||
if not request.user.is_anonymous:
|
||||
r = getrower(request.user)
|
||||
result = request.user.is_authenticated and ispromember(request.user)
|
||||
if result:
|
||||
promember=1
|
||||
|
||||
if request.method == 'POST' and 'workouts' in request.POST:
|
||||
form = WorkoutMultipleCompareForm(request.POST)
|
||||
chartform = ChartParamChoiceForm(request.POST)
|
||||
if form.is_valid() and chartform.is_valid():
|
||||
cd = form.cleaned_data
|
||||
workouts = cd['workouts']
|
||||
xparam = chartform.cleaned_data['xparam']
|
||||
yparam = chartform.cleaned_data['yparam']
|
||||
plottype = chartform.cleaned_data['plottype']
|
||||
teamid = chartform.cleaned_data['teamid']
|
||||
ids = [int(w.id) for w in workouts]
|
||||
request.session['ids'] = ids
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__str__() for w in workouts
|
||||
}
|
||||
|
||||
else: # pragma: no cover
|
||||
return HttpResponse("Form is not valid")
|
||||
elif request.method == 'POST' and 'ids' in request.session:
|
||||
chartform = ChartParamChoiceForm(request.POST)
|
||||
if chartform.is_valid():
|
||||
xparam = chartform.cleaned_data['xparam']
|
||||
yparam = chartform.cleaned_data['yparam']
|
||||
plottype = chartform.cleaned_data['plottype']
|
||||
teamid = chartform.cleaned_data['teamid']
|
||||
ids = request.session['ids']
|
||||
request.session['ids'] = ids
|
||||
workouts = []
|
||||
for id in ids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist: # pragma: no cover
|
||||
pass
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__str__() for w in workouts
|
||||
}
|
||||
elif 'ids' in request.session and 'plottype' in request.session:
|
||||
xparam = request.session['xparam']
|
||||
yparam = request.session['yparam']
|
||||
plottype = request.session['plottype']
|
||||
teamid = 0
|
||||
ids = request.session['ids']
|
||||
workouts = []
|
||||
for id in ids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist: # pragma: no cover
|
||||
pass
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__str__() for w in workouts
|
||||
}
|
||||
chartform = ChartParamChoiceForm(
|
||||
initial = {
|
||||
'xparam':xparam,
|
||||
'yparam':yparam,
|
||||
'plottype':plottype,
|
||||
'teamid':teamid
|
||||
}
|
||||
)
|
||||
|
||||
else:
|
||||
url = reverse('team_comparison_select',
|
||||
kwargs={
|
||||
'id':id,
|
||||
'teamid':0})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
res = interactive_multiple_compare_chart(ids,xparam,yparam,
|
||||
promember=promember,
|
||||
plottype=plottype,
|
||||
labeldict=labeldict)
|
||||
script = res[0]
|
||||
div = res[1]
|
||||
errormessage = res[3]
|
||||
if errormessage != '': # pragma: no cover
|
||||
messages.error(request,errormessage)
|
||||
|
||||
r = getrower(request.user)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts/',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':reverse('team_comparison_select',kwargs={'teamid':teamid}),
|
||||
'name': 'Compare Select'
|
||||
},
|
||||
{
|
||||
'url':reverse('multi_compare_view'),
|
||||
'name': 'Comparison Chart'
|
||||
}
|
||||
]
|
||||
|
||||
if 'ps' in request.session: # pragma: no cover
|
||||
ps = PlannedSession.objects.get(id=int(request.session['ps']))
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url': reverse('plannedsessions_view',
|
||||
kwargs={'userid':userid}),
|
||||
'name': 'Sessions'
|
||||
},
|
||||
{
|
||||
'url':reverse('plannedsession_view',
|
||||
kwargs={
|
||||
'userid':userid,
|
||||
'id':ps.id,
|
||||
}
|
||||
),
|
||||
'name': ps.id
|
||||
},
|
||||
{
|
||||
'url':reverse('plannedsession_compare_view',
|
||||
kwargs={
|
||||
'userid':userid,
|
||||
'id':ps.id,
|
||||
}
|
||||
),
|
||||
'name': 'Compare'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
return render(request,'multicompare.html',
|
||||
{'interactiveplot':script,
|
||||
'the_div':div,
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'rower':r,
|
||||
'active':'nav-workouts',
|
||||
'promember':promember,
|
||||
'teamid':teamid,
|
||||
'chartform':chartform,
|
||||
'teams':get_my_teams(request.user),
|
||||
})
|
||||
|
||||
|
||||
# List Workouts
|
||||
@login_required()
|
||||
|
||||
Reference in New Issue
Block a user