crude version of results submit
This commit is contained in:
@@ -809,34 +809,7 @@ def create_row_df(r,distance,duration,startdatetime,
|
||||
|
||||
return (id, message)
|
||||
|
||||
|
||||
def totaltime_sec_to_string(totaltime):
|
||||
hours = int(totaltime / 3600.)
|
||||
if hours > 23:
|
||||
message = 'Warning: The workout duration was longer than 23 hours. '
|
||||
hours = 23
|
||||
|
||||
minutes = int((totaltime - 3600. * hours) / 60.)
|
||||
if minutes > 59:
|
||||
minutes = 59
|
||||
if not message:
|
||||
message = 'Warning: there is something wrong with the workout duration'
|
||||
|
||||
seconds = int(totaltime - 3600. * hours - 60. * minutes)
|
||||
if seconds > 59:
|
||||
seconds = 59
|
||||
if not message:
|
||||
message = 'Warning: there is something wrong with the workout duration'
|
||||
|
||||
tenths = int(10 * (totaltime - 3600. * hours - 60. * minutes - seconds))
|
||||
if tenths > 9:
|
||||
tenths = 9
|
||||
if not message:
|
||||
message = 'Warning: there is something wrong with the workout duration'
|
||||
|
||||
duration = "%s:%s:%s.%s" % (hours, minutes, seconds, tenths)
|
||||
|
||||
return duration
|
||||
from utils import totaltime_sec_to_string
|
||||
|
||||
# Processes painsled CSV file to database
|
||||
def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
|
||||
@@ -695,6 +695,19 @@ class WorkoutSessionSelectForm(forms.Form):
|
||||
widget = forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
class WorkoutRaceSelectForm(forms.Form):
|
||||
|
||||
def __init__(self, workoutdata, *args, **kwargs):
|
||||
|
||||
super(WorkoutRaceSelectForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields['workouts'] = forms.ChoiceField(
|
||||
label='Workouts',
|
||||
choices = workoutdata['choices'],
|
||||
initial=workoutdata['initial'],
|
||||
widget=forms.RadioSelect,
|
||||
)
|
||||
|
||||
class PlannedSessionTeamForm(forms.Form):
|
||||
team = forms.ModelMultipleChoiceField(
|
||||
queryset=Team.objects.all(),
|
||||
|
||||
@@ -1335,12 +1335,14 @@ class VirtualRaceResult(models.Model):
|
||||
default='1x',
|
||||
verbose_name = 'Boat Type'
|
||||
)
|
||||
|
||||
coursecompleted = models.BooleanField(default=False)
|
||||
sex = models.CharField(default="not specified",
|
||||
max_length=30,
|
||||
choices=sexcategories,
|
||||
verbose_name='Gender')
|
||||
|
||||
age = models.IntegerField(null=True)
|
||||
|
||||
|
||||
from rowers.metrics import rowingmetrics
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from django.db import IntegrityError
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
import pytz
|
||||
from utils import myqueue
|
||||
from utils import myqueue,calculate_age,totaltime_sec_to_string
|
||||
|
||||
import django_rq
|
||||
queue = django_rq.get_queue('default')
|
||||
@@ -18,7 +18,7 @@ queuehigh = django_rq.get_queue('low')
|
||||
from rowers.models import (
|
||||
Rower, Workout,Team,
|
||||
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
|
||||
TrainingPlan,PlannedSession,
|
||||
TrainingPlan,PlannedSession,VirtualRaceResult
|
||||
)
|
||||
|
||||
import metrics
|
||||
@@ -596,3 +596,95 @@ def remove_rower_race(r,race):
|
||||
race.rower.remove(r)
|
||||
|
||||
return 1
|
||||
|
||||
# Low Level functions - to be called by higher level methods
|
||||
def add_workout_race(ws,race,r):
|
||||
result = 0
|
||||
comments = []
|
||||
errors = []
|
||||
|
||||
start_time = race.start_time
|
||||
start_date = race.startdate
|
||||
startdatetime = datetime.combine(start_date,start_time)
|
||||
startdatetime = pytz.timezone(race.timezone).localize(
|
||||
startdatetime
|
||||
)
|
||||
|
||||
end_time = race.end_time
|
||||
end_date = race.enddate
|
||||
enddatetime = datetime.combine(end_date,end_time)
|
||||
enddatetime = pytz.timezone(race.timezone).localize(
|
||||
enddatetime
|
||||
)
|
||||
|
||||
# check if all sessions have same date
|
||||
dates = [w.date for w in ws]
|
||||
if (not all(d == dates[0] for d in dates)) and race.sessiontype not in ['challenge','cycletarget']:
|
||||
errors.append('For tests and training sessions, selected workouts must all be done on the same date')
|
||||
return result,comments,errors
|
||||
|
||||
if len(ws)>1 and race.sessiontype == 'test':
|
||||
errors.append('For tests, you can only attach one workout')
|
||||
return result,comments,errors
|
||||
|
||||
|
||||
|
||||
wold = Workout.objects.filter(plannedsession=race,user=r)
|
||||
ids = [w.id for w in wold] + [w.id for w in ws]
|
||||
ids = list(set(ids))
|
||||
|
||||
if len(ids)>1 and race.sessiontype in ['test','coursetest']:
|
||||
errors.append('For tests, you can only attach one workout')
|
||||
return result,comments,errors
|
||||
|
||||
# start adding sessions
|
||||
for w in ws:
|
||||
if w.startdatetime>=startdatetime and w.startdatetime<=enddatetime:
|
||||
w.plannedsession = race
|
||||
w.save()
|
||||
result += 1
|
||||
|
||||
comments.append('Your result has been submitted')
|
||||
else:
|
||||
errors.append('Workout %i did not match the race window' % w.id)
|
||||
|
||||
if result>0:
|
||||
username = r.user.first_name+' '+r.user.last_name
|
||||
if r.birthdate:
|
||||
age = calculate_age(r.birthdate)
|
||||
else:
|
||||
age = None
|
||||
(
|
||||
coursetime,
|
||||
coursemeters,
|
||||
coursecompleted
|
||||
) = courses.get_time_course(ws,race.course)
|
||||
if not coursecompleted:
|
||||
errors.append('Your trajectory did not match the race course')
|
||||
|
||||
duration = totaltime_sec_to_string(coursetime)
|
||||
|
||||
record = VirtualRaceResult(
|
||||
user=r,
|
||||
username=username,
|
||||
workout = ws[0],
|
||||
race = race,
|
||||
coursecompleted=coursecompleted,
|
||||
duration = duration,
|
||||
boattype = ws[0].boattype,
|
||||
sex = r.sex,
|
||||
age = age,
|
||||
)
|
||||
|
||||
record.save()
|
||||
|
||||
|
||||
|
||||
return result,comments,errors
|
||||
|
||||
def delete_race_result(workout,race):
|
||||
results = VirtualRaceResult.objects.filter(workout=workout,race=race)
|
||||
for r in results:
|
||||
r.delete()
|
||||
|
||||
|
||||
|
||||
59
rowers/templates/race_submit.html
Normal file
59
rowers/templates/race_submit.html
Normal file
@@ -0,0 +1,59 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Submit Race Result{% endblock %}
|
||||
|
||||
{% block meta %}
|
||||
<script type='text/javascript'
|
||||
src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'>
|
||||
</script>
|
||||
<script type='text/javascript'
|
||||
src='https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js'>
|
||||
</script>
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="grid_12 alpha">
|
||||
<div class="grid_6 alpha">
|
||||
<h1>Submit Your Result for {{ race.name }}</h1>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<form id="race_submit_form"
|
||||
method="post">
|
||||
<div class="grid_12 alpha">
|
||||
<div class="grid_6 alpha">
|
||||
<p> </p>
|
||||
</div>
|
||||
<div class="grid_6 omega">
|
||||
<p>Workouts</p>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
{% for field in w_form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
{% for field in w_form.visible_fields %}
|
||||
<td>
|
||||
{{ field }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid_2 prefix_2 suffix_8">
|
||||
{% csrf_token %}
|
||||
<input class="button green" type="submit" value="Submit">
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
@@ -149,6 +149,8 @@ urlpatterns = [
|
||||
url(r'^virtualevent/(?P<id>\d+)/edit$',views.virtualevent_edit_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/register$',views.virtualevent_register_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/withdraw$',views.virtualevent_withdraw_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/submit$',
|
||||
views.virtualevent_submit_result_view),
|
||||
url(r'^list-workouts/$',views.workouts_view),
|
||||
url(r'^list-courses/$',views.courses_view),
|
||||
url(r'^courses/upload$',views.course_upload_view),
|
||||
|
||||
@@ -337,3 +337,31 @@ def wavg(group, avg_name, weight_name):
|
||||
return (d * w).sum() / w.sum()
|
||||
except ZeroDivisionError:
|
||||
return d.mean()
|
||||
|
||||
def totaltime_sec_to_string(totaltime):
|
||||
hours = int(totaltime / 3600.)
|
||||
if hours > 23:
|
||||
message = 'Warning: The workout duration was longer than 23 hours. '
|
||||
hours = 23
|
||||
|
||||
minutes = int((totaltime - 3600. * hours) / 60.)
|
||||
if minutes > 59:
|
||||
minutes = 59
|
||||
if not message:
|
||||
message = 'Warning: there is something wrong with the workout duration'
|
||||
|
||||
seconds = int(totaltime - 3600. * hours - 60. * minutes)
|
||||
if seconds > 59:
|
||||
seconds = 59
|
||||
if not message:
|
||||
message = 'Warning: there is something wrong with the workout duration'
|
||||
|
||||
tenths = int(10 * (totaltime - 3600. * hours - 60. * minutes - seconds))
|
||||
if tenths > 9:
|
||||
tenths = 9
|
||||
if not message:
|
||||
message = 'Warning: there is something wrong with the workout duration'
|
||||
|
||||
duration = "%s:%s:%s.%s" % (hours, minutes, seconds, tenths)
|
||||
|
||||
return duration
|
||||
|
||||
100
rowers/views.py
100
rowers/views.py
@@ -34,7 +34,7 @@ from rowers.forms import (
|
||||
WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement,
|
||||
LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm,
|
||||
PlannedSessionTeamForm,PlannedSessionTeamMemberForm,
|
||||
VirtualRaceSelectForm
|
||||
VirtualRaceSelectForm,WorkoutRaceSelectForm,
|
||||
)
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.exceptions import PermissionDenied
|
||||
@@ -13581,3 +13581,101 @@ def virtualevent_edit_view(request,id=0):
|
||||
'race':race,
|
||||
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def virtualevent_submit_result_view(request,id=0):
|
||||
|
||||
r = getrower(request.user)
|
||||
|
||||
try:
|
||||
race = VirtualRace.objects.get(id=id)
|
||||
except VirtualRace.DoesNotExist:
|
||||
raise Http404("Virtual Race does not exist")
|
||||
|
||||
start_time = race.start_time
|
||||
start_date = race.startdate
|
||||
startdatetime = datetime.datetime.combine(start_date, start_time)
|
||||
startdatetime = pytz.timezone(race.timezone).localize(startdatetime)
|
||||
|
||||
end_time = race.end_time
|
||||
end_date = race.enddate
|
||||
enddatetime = datetime.datetime.combine(end_date, end_time)
|
||||
enddatetime = pytz.timezone(race.timezone).localize(enddatetime)
|
||||
|
||||
can_submit = race_can_submit(r,race) or race_can_resubmit(r,race)
|
||||
|
||||
if not can_submit:
|
||||
messages.error(request,'You cannot submit a result to this race')
|
||||
url = reverse(virtualevent_view,
|
||||
kwargs = {
|
||||
'id':id
|
||||
}
|
||||
)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
ws = Workout.objects.filter(
|
||||
user=r,
|
||||
startdatetime__gte=startdatetime,
|
||||
startdatetime__lte=enddatetime,
|
||||
).order_by("date","startdatetime","id")
|
||||
|
||||
initialworkouts = [w.id for w in Workout.objects.filter(
|
||||
user=r,plannedsession=race
|
||||
)]
|
||||
|
||||
workoutdata = {}
|
||||
workoutdata['initial'] = []
|
||||
|
||||
choices = []
|
||||
|
||||
for w in ws:
|
||||
wtpl = (w.id, w.__unicode__())
|
||||
choices.append(wtpl)
|
||||
if w.id in initialworkouts:
|
||||
workoutdata['initial'].append(w.id)
|
||||
|
||||
workoutdata['choices'] = tuple(choices)
|
||||
|
||||
if request.method == 'POST':
|
||||
w_form = WorkoutRaceSelectForm(workoutdata,request.POST)
|
||||
|
||||
if w_form.is_valid():
|
||||
selectedworkouts = [w_form.cleaned_data['workouts']]
|
||||
else:
|
||||
selectedworkouts = []
|
||||
|
||||
if len(selectedworkouts) == 0:
|
||||
for w in ws:
|
||||
remove_workout_plannedsession(w,race)
|
||||
|
||||
if selectedworkouts:
|
||||
workouts = Workout.objects.filter(user=r,
|
||||
id__in=selectedworkouts)
|
||||
|
||||
for w in ws:
|
||||
if w.id not in selectedworkouts:
|
||||
remove_workout_plannedsession(w,race)
|
||||
delete_race_result(w,race)
|
||||
|
||||
result,comments,errors = add_workout_race(workouts,race,r)
|
||||
|
||||
for c in comments:
|
||||
messages.info(request,c)
|
||||
for er in errors:
|
||||
messages.error(request,er)
|
||||
|
||||
|
||||
# redirect to race page
|
||||
else:
|
||||
w_form = WorkoutRaceSelectForm(workoutdata=workoutdata)
|
||||
|
||||
return render(request,'race_submit.html',
|
||||
{
|
||||
'race':race,
|
||||
'workouts':ws,
|
||||
'rower':r,
|
||||
'w_form':w_form,
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user