Merge branch 'feature/admintouser' into develop
This commit is contained in:
+4
-1
@@ -1225,7 +1225,10 @@ def handle_nonpainsled(f2, fileformat, summary=''):
|
|||||||
try:
|
try:
|
||||||
os.remove(f_to_be_deleted)
|
os.remove(f_to_be_deleted)
|
||||||
except:
|
except:
|
||||||
os.remove(f_to_be_deleted + '.gz')
|
try:
|
||||||
|
os.remove(f_to_be_deleted + '.gz')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
return (f2, summary, oarlength, inboard, fileformat)
|
return (f2, summary, oarlength, inboard, fileformat)
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from django_mailbox.models import Message, MessageAttachment,Mailbox
|
|||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
from django.utils import timezone
|
||||||
from rowers.models import Workout, Rower
|
from rowers.models import Workout, Rower
|
||||||
|
|
||||||
from rowingdata import rower as rrower
|
from rowingdata import rower as rrower
|
||||||
@@ -23,6 +24,8 @@ from rowers.mailprocessing import make_new_workout_from_email, send_confirm
|
|||||||
import rowers.polarstuff as polarstuff
|
import rowers.polarstuff as polarstuff
|
||||||
import rowers.c2stuff as c2stuff
|
import rowers.c2stuff as c2stuff
|
||||||
import rowers.stravastuff as stravastuff
|
import rowers.stravastuff as stravastuff
|
||||||
|
from rowers.models import User,VirtualRace,Workout
|
||||||
|
from rowers.plannedsessions import email_submit_race
|
||||||
|
|
||||||
workoutmailbox = Mailbox.objects.get(name='workouts')
|
workoutmailbox = Mailbox.objects.get(name='workouts')
|
||||||
failedmailbox = Mailbox.objects.get(name='Failed')
|
failedmailbox = Mailbox.objects.get(name='Failed')
|
||||||
@@ -65,17 +68,42 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
|
|||||||
|
|
||||||
if testing:
|
if testing:
|
||||||
print 'Creating workout from email'
|
print 'Creating workout from email'
|
||||||
|
|
||||||
|
# set user
|
||||||
|
if rower.user.is_staff and 'username' in uploadoptions:
|
||||||
|
users = User.objects.filter(username=uploadoptions['username'])
|
||||||
|
if len(users)==1:
|
||||||
|
therower = users[0].rower
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
therower = rower
|
||||||
|
|
||||||
|
|
||||||
workoutid = [
|
workoutid = [
|
||||||
make_new_workout_from_email(rower, filename, title,testing=testing)
|
make_new_workout_from_email(therower, filename, title,testing=testing)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
if 'raceid' in uploadoptions and workoutid[0] and rower.user.is_staff:
|
||||||
|
if testing and workoutid[0]:
|
||||||
|
w = Workout.objects.get(id = workoutid[0])
|
||||||
|
w.startdatetime = timezone.now()
|
||||||
|
w.date = timezone.now().date()
|
||||||
|
w.save()
|
||||||
|
try:
|
||||||
|
race = VirtualRace.objects.get(id=uploadoptions['raceid'])
|
||||||
|
if race.manager == rower.user:
|
||||||
|
result = email_submit_race(therower,race,workoutid[0])
|
||||||
|
except VirtualRace.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
if testing:
|
if testing:
|
||||||
print 'Workout id = {workoutid}'.format(workoutid=workoutid)
|
print 'Workout id = {workoutid}'.format(workoutid=workoutid)
|
||||||
|
|
||||||
if workoutid[0]:
|
if workoutid[0]:
|
||||||
link = settings.SITE_URL+reverse(
|
link = settings.SITE_URL+reverse(
|
||||||
rower.defaultlandingpage,
|
therower.defaultlandingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'id':workoutid[0],
|
'id':workoutid[0],
|
||||||
}
|
}
|
||||||
@@ -99,9 +127,9 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
if workoutid and not testing:
|
if workoutid and not testing:
|
||||||
if rower.getemailnotifications and not rower.emailbounced:
|
if therower.getemailnotifications and not therower.emailbounced:
|
||||||
email_sent = send_confirm(
|
email_sent = send_confirm(
|
||||||
rower.user, title, link,
|
therower.user, title, link,
|
||||||
uploadoptions
|
uploadoptions
|
||||||
)
|
)
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
@@ -109,9 +137,9 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
|
|||||||
try:
|
try:
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
if workoutid:
|
if workoutid:
|
||||||
if rower.getemailnotifications and not rower.emailbounced:
|
if therower.getemailnotifications and not therower.emailbounced:
|
||||||
email_sent = send_confirm(
|
email_sent = send_confirm(
|
||||||
rower.user, title, link,
|
therower.user, title, link,
|
||||||
uploadoptions
|
uploadoptions
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
|
|||||||
+128
-1
@@ -36,6 +36,10 @@ import courses
|
|||||||
import iso8601
|
import iso8601
|
||||||
from iso8601 import ParseError
|
from iso8601 import ParseError
|
||||||
from rowers.tasks import handle_check_race_course
|
from rowers.tasks import handle_check_race_course
|
||||||
|
from rowers.tasks import (
|
||||||
|
handle_sendemail_raceregistration,handle_sendemail_racesubmission
|
||||||
|
)
|
||||||
|
from rowers.utils import totaltime_sec_to_string
|
||||||
|
|
||||||
def get_indoorraces(workout):
|
def get_indoorraces(workout):
|
||||||
races1 = VirtualRace.objects.filter(
|
races1 = VirtualRace.objects.filter(
|
||||||
@@ -777,7 +781,6 @@ def race_can_submit(r,race):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print 'pop'
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def race_can_resubmit(r,race):
|
def race_can_resubmit(r,race):
|
||||||
@@ -877,6 +880,130 @@ def race_can_withdraw(r,race):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def email_submit_race(r,race,workoutid):
|
||||||
|
try:
|
||||||
|
w = Workout.objects.get(id=workoutid)
|
||||||
|
except Workout.DoesNotExist:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if race.sessionmode == 'time':
|
||||||
|
wduration = timefield_to_seconds_duration(w.duration)
|
||||||
|
delta = wduration - (60.*race.sessionvalue)
|
||||||
|
|
||||||
|
if delta > -2 and delta < 2:
|
||||||
|
w.duration = totaltime_sec_to_string(60.*race.sessionvalue)
|
||||||
|
w.save()
|
||||||
|
|
||||||
|
|
||||||
|
elif race.sessionmode == 'distance':
|
||||||
|
delta = w.distance - race.sessionvalue
|
||||||
|
|
||||||
|
if delta > -5 and delta < 5:
|
||||||
|
w.distance = race.sessionvalue
|
||||||
|
w.save()
|
||||||
|
|
||||||
|
|
||||||
|
if race_can_register(r,race):
|
||||||
|
teamname = ''
|
||||||
|
weightcategory = w.weightcategory
|
||||||
|
sex = r.sex
|
||||||
|
if sex == 'not specified':
|
||||||
|
sex = 'male'
|
||||||
|
|
||||||
|
if not r.birthdate:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
age = calculate_age(r.birthdate)
|
||||||
|
|
||||||
|
adaptiveclass = r.adaptiveclass
|
||||||
|
boatclass = w.workouttype
|
||||||
|
|
||||||
|
record = IndoorVirtualRaceResult(
|
||||||
|
userid = r.id,
|
||||||
|
teamname=teamname,
|
||||||
|
race=race,
|
||||||
|
username = u'{f} {l}'.format(
|
||||||
|
f = r.user.first_name,
|
||||||
|
l = r.user.last_name
|
||||||
|
),
|
||||||
|
weightcategory=weightcategory,
|
||||||
|
adaptiveclass=adaptiveclass,
|
||||||
|
duration=dt.time(0,0),
|
||||||
|
boatclass=boatclass,
|
||||||
|
coursecompleted=False,
|
||||||
|
sex=sex,
|
||||||
|
age=age
|
||||||
|
)
|
||||||
|
|
||||||
|
record.save()
|
||||||
|
|
||||||
|
result = add_rower_race(r,race)
|
||||||
|
|
||||||
|
otherrecords = IndoorVirtualRaceResult.objects.filter(
|
||||||
|
race = race)
|
||||||
|
|
||||||
|
|
||||||
|
for otherrecord in otherrecords:
|
||||||
|
otheruser = Rower.objects.get(id=otherrecord.userid)
|
||||||
|
othername = otheruser.user.first_name+' '+otheruser.user.last_name
|
||||||
|
registeredname = r.user.first_name+' '+r.user.last_name
|
||||||
|
if otherrecord.emailnotifications:
|
||||||
|
job = myqueue(
|
||||||
|
queue,
|
||||||
|
handle_sendemail_raceregistration,
|
||||||
|
otheruser.user.email, othername,
|
||||||
|
registeredname,
|
||||||
|
race.name,
|
||||||
|
race.id
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if race_can_submit(r,race):
|
||||||
|
records = IndoorVirtualRaceResult.objects.filter(
|
||||||
|
userid = r.id,
|
||||||
|
race=race
|
||||||
|
)
|
||||||
|
|
||||||
|
if not records:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
record = records[0]
|
||||||
|
|
||||||
|
workouts = Workout.objects.filter(id=w.id)
|
||||||
|
|
||||||
|
result,comments,errors,jobid = add_workout_indoorrace(
|
||||||
|
workouts,race,r,recordid=record.id
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if result:
|
||||||
|
otherrecords = IndoorVirtualRaceResult.objects.filter(
|
||||||
|
race = race)
|
||||||
|
|
||||||
|
for otherrecord in otherrecords:
|
||||||
|
otheruser = Rower.objects.get(id=otherrecord.userid)
|
||||||
|
othername = otheruser.user.first_name+' '+otheruser.user.last_name
|
||||||
|
registeredname = r.user.first_name+' '+r.user.last_name
|
||||||
|
if otherrecord.emailnotifications:
|
||||||
|
job = myqueue(
|
||||||
|
queue,
|
||||||
|
handle_sendemail_racesubmission,
|
||||||
|
otheruser.user.email, othername,
|
||||||
|
registeredname,
|
||||||
|
race.name,
|
||||||
|
race.id
|
||||||
|
)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def race_can_register(r,race):
|
def race_can_register(r,race):
|
||||||
if race.sessiontype == 'race':
|
if race.sessiontype == 'race':
|
||||||
recordobj = VirtualRaceResult
|
recordobj = VirtualRaceResult
|
||||||
|
|||||||
@@ -0,0 +1,503 @@
|
|||||||
|
{% extends "newbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}Rowsandall Virtual Race{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% include "monitorjobs.html" %}
|
||||||
|
<script>
|
||||||
|
setTimeout("location.reload(true);",60000);
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block og_title %}{{ race.name }}{% endblock %}
|
||||||
|
{% block description %}Virtual Rowing Race {{ race.name }}{% endblock %}
|
||||||
|
|
||||||
|
{% if racelogo %}
|
||||||
|
{% block og_image %}
|
||||||
|
<meta property="og:image" content="http://rowsandall.com/{{ racelogo.filename|spacetohtml }}" />
|
||||||
|
<meta property="og:image:secure_url" content="https://rowsandall.com/{{ racelogo.filename |spacetohtml }}" />
|
||||||
|
<meta property="og:image:width" content="{{ racelogo.width }}" />
|
||||||
|
<meta property="og:image:height" content="{{ racelogo.height }}" />
|
||||||
|
{% endblock %}
|
||||||
|
{% block image_src %}
|
||||||
|
<link rel="image_src" href="/{{ racelogo.filename |spacetohtml }}" />
|
||||||
|
{% endblock %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
|
||||||
|
<h1>{{ race.name }}</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="main-content">
|
||||||
|
<li class="grid_2">
|
||||||
|
<div id="results">
|
||||||
|
<p>
|
||||||
|
{% if race|is_final %}
|
||||||
|
<h2>Final Results</h2>
|
||||||
|
{% else %}
|
||||||
|
<h2>Results</h2>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
{% if results or dns %}
|
||||||
|
<p>
|
||||||
|
<table class="listtable shortpadded" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th> </th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Team Name</th>
|
||||||
|
<th> </th>
|
||||||
|
<th> </th>
|
||||||
|
<th> </th>
|
||||||
|
<th> </th>
|
||||||
|
<th>Class</th>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<th>Boat</th>
|
||||||
|
{% endif %}
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Distance</th>
|
||||||
|
<th>Details</th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for result in results %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ forloop.counter }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/workout/{{ result.workoutid }}">
|
||||||
|
{{ result.username }}</a></td>
|
||||||
|
<td>{{ result.teamname }}</td>
|
||||||
|
<td>{{ result.age }}</td>
|
||||||
|
<td>{{ result.sex }}</td>
|
||||||
|
<td>{{ result.weightcategory }}</td>
|
||||||
|
<td>
|
||||||
|
{% if result.adaptiveclass == 'None' %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{{ result.adaptiveclass }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ result.boatclass }}</td>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<td>{{ result.boattype }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>{{ result.duration |durationprint:"%H:%M:%S.%f" }}</td>
|
||||||
|
<td>{{ result.distance }} m</td>
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/workout/{{ result.workoutid }}">
|
||||||
|
Details</a></td>
|
||||||
|
<td>
|
||||||
|
{% if race.manager == request.user and not race|is_final %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/disqualify/{{ result.id }}/">
|
||||||
|
Disqualify
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% for result in dns %}
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td>{{ result.username }}</td>
|
||||||
|
<td>{{ result.teamname }}</td>
|
||||||
|
<td>{{ result.age }}</td>
|
||||||
|
<td>{{ result.sex }}</td>
|
||||||
|
<td>{{ result.weightcategory }}</td>
|
||||||
|
<td>
|
||||||
|
{% if result.adaptiveclass == 'None' %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{{ result.adaptiveclass }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ result.boatclass }}</td>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<td>{{ result.boattype }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>DNS</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/compare"
|
||||||
|
title="Compare the workouts of all competitors">Compare Results</a>
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
No results yet
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% if form %}
|
||||||
|
<li class="grid_2">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<h2>Filter Results</h2>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<form id="result_filter_form", method="post">
|
||||||
|
<table>
|
||||||
|
{{ form.as_table }}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if racelogo %}
|
||||||
|
<li class="grid_2">
|
||||||
|
<img src="/{{ racelogo.filename }}" alt="{{ racelogo.filename }}" height="100" width="120">
|
||||||
|
{% if race.manager == request.user %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/image">Edit Image</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<li class="grid_2">
|
||||||
|
<p>
|
||||||
|
<h2>Course</h2>
|
||||||
|
</p>
|
||||||
|
<div class="mapdiv">
|
||||||
|
{{ coursediv|safe }}
|
||||||
|
|
||||||
|
{{ coursescript|safe }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
<li class="grid_2">
|
||||||
|
<div id="raceinfo">
|
||||||
|
<p>
|
||||||
|
<h2>Race Information</h2>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<table class="listtable shortpadded" width="100%">
|
||||||
|
<tbody>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<tr>
|
||||||
|
<th>Course</th><td>{{ race.course }}</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<th>Indoor Race</th><td>To be rowed on a Concept2 ergometer</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Time Zone</th><td>{{ race.timezone }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ race.sessionmode }} challenge
|
||||||
|
</th><td>{{ race.sessionvalue }} {{ race.sessionunit }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Registration closure</th>
|
||||||
|
<td>{{ race.registration_closure }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th><td>{{ race.startdate }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Race Window</th><td>{{ race.startdate }} {{ race.start_time }} to {{ race.enddate }} {{ race.end_time }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Results Submission Deadline</th><td>{{ race.evaluation_closure }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Organizer</th><td>{{ race.manager.first_name }} {{ race.manager.last_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Contact Email</th><td>{{ race.contact_email }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Contact Phone</th><td>{{ race.contact_phone }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Comment</th><td>{{ race.comment|linebreaks }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="grid_2">
|
||||||
|
<div id="registerbuttons">
|
||||||
|
{% if request.user.is_anonymous %}
|
||||||
|
<p>
|
||||||
|
Registered users of rowsandall.com can participate in this event. Participation is free, unless specified differently in the race comment above.
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
See race rules below. Participation to this race is free,
|
||||||
|
unless specified differently in the race comment above.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{% for button in buttons %}
|
||||||
|
{% if button == 'registerbutton' %}
|
||||||
|
<p>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'submitbutton' %}
|
||||||
|
<table width=100% class="shortpadded">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/submit">Submit Workout</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Submit a workout that is already on the site as your race result
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/workout/upload">Upload your race result</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Upload a new workout to the site and submit it as a result. You
|
||||||
|
need a workout data file.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% if race.sessiontype == 'indoorrace' %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/workout/addmanual">Enter your race result manually</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
If you don't have a data file, enter the results
|
||||||
|
manually. If you have a photo of the monitor with the
|
||||||
|
result, it is recommended to add this to the workout.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'resubmitbutton' %}
|
||||||
|
<p>
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/submit">Submit New Result</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'withdrawbutton' %}
|
||||||
|
<p>
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/withdraw">Withdraw</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'adddisciplinebutton' %}
|
||||||
|
<p>
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/adddiscipline">
|
||||||
|
Register New Boat
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'editbutton' %}
|
||||||
|
<p>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/edit">Edit Race
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/editindoor">Edit Race
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="grid_2">
|
||||||
|
<div id="registered">
|
||||||
|
{% if records %}
|
||||||
|
<h2>Registered Competitors</h2>
|
||||||
|
<table class="listtable shortpadded" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Team Name</th>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<th>Class</th>
|
||||||
|
<th>Boat</th>
|
||||||
|
{% else %}
|
||||||
|
<th>Class</th>
|
||||||
|
{% endif %}
|
||||||
|
<th>Age</th>
|
||||||
|
<th>Gender</th>
|
||||||
|
<th>Weight Category</th>
|
||||||
|
<th>Adaptive</th>
|
||||||
|
</tr>
|
||||||
|
<tbody>
|
||||||
|
{% for record in records %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ record.username }}
|
||||||
|
<td>{{ record.teamname }}</td>
|
||||||
|
<td>{{ record.boatclass }}</td>
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
<td>{{ record.boattype }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>{{ record.age }}</td>
|
||||||
|
<td>{{ record.sex }}</td>
|
||||||
|
<td>{{ record.weightcategory }}</td>
|
||||||
|
<td>
|
||||||
|
{% if record.adaptiveclass == 'None' %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{{ record.adaptiveclass }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% if record.userid == rower.id and 'withdrawbutton' in buttons %}
|
||||||
|
<td>
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/withdraw/{{ record.id }}" >Withdraw</a>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% for record in records %}
|
||||||
|
{% if record.userid == request.user.rower.id %}
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
{% if record.emailnotifications %}
|
||||||
|
<a href="/rowers/raceregistration/togglenotification/{{ race.id }}">
|
||||||
|
Unsubscribe from race notifications by email
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/rowers/raceregistration/togglenotification/{{ race.id }}">
|
||||||
|
Subscribe to race notifications by email
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if record.emailnotifications %}
|
||||||
|
<a href="/rowers/indoorraceregistration/togglenotification/{{ race.id }}">
|
||||||
|
Unsubscribe from race notifications by email
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/rowers/indoorraceregistration/togglenotification/{{ race.id }}">
|
||||||
|
Subscribe to race notifications by email
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</li>
|
||||||
|
<li class="grid_4">
|
||||||
|
<div id="rules">
|
||||||
|
<p>
|
||||||
|
<h2>Rules</h2>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Virtual races are intended as an informal way to add a
|
||||||
|
competitive element to training and as a quick way to set
|
||||||
|
up and manage small regattas.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
On the water races are rowed on the course shown.
|
||||||
|
You cannot submit results rowed
|
||||||
|
on other bodies of water.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Indoor races are open for all, wherever you live.
|
||||||
|
However, be aware of the
|
||||||
|
time zone for the race window.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
As a rowsandall.com user, you can
|
||||||
|
register to take part in this event. Please note the registration
|
||||||
|
deadline. You must register before this deadline.
|
||||||
|
You can always withdraw from participating before the registration
|
||||||
|
deadline or the start of the race window, whichever is earlier.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
After the start of the race window and before the submission deadline,
|
||||||
|
you can submit results by linking the race to one of your uploaded
|
||||||
|
workouts. The workout start time must be within the race window
|
||||||
|
and your course must pass through the blue polygons on the course
|
||||||
|
map (in the right order), for your result to be valid.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The results table has a link to a page where details of your workout
|
||||||
|
are shown.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Race results are stored permanently and are not deleted when
|
||||||
|
you delete the respective workout or remove your account.
|
||||||
|
By registering, you agree with this and the race rules.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you use a manually added workout for your indoor race result,
|
||||||
|
please attach a screenshot of the ergometer display for verification.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Virtual Racing on rowsandall.com is honors based. Please be a good
|
||||||
|
sport, submit real results rowed by you, and make sure you set the
|
||||||
|
boat type correctly. For (future functionality) age and gender
|
||||||
|
corrected times, please be sure your gender and birth date are set
|
||||||
|
correctly in your user settings.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Virtual races are intended as an informal way to add a
|
||||||
|
competitive element to training. Virtual races are not
|
||||||
|
refereed or staffed to provide for participants safety.
|
||||||
|
Individual participants are entirely responsible for their
|
||||||
|
safety while participating in a virtual race.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Until the evaluation closure time, the race organizer can
|
||||||
|
review and reject entries. If you are disqualified in this
|
||||||
|
way, you will receive an email with the reason.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<div class="fb-share-button"
|
||||||
|
data-href="{{ request.build_absolute_uri }}"
|
||||||
|
data-layout="button" data-size="small" data-mobile-iframe="false">
|
||||||
|
<a class="fb-xfbml-parse-ignore" target="_blank"
|
||||||
|
href="https://www.facebook.com/sharer/sharer.php?u={{ request.build_absolute_uri }}">Share</a>
|
||||||
|
</div>
|
||||||
|
</p><p>
|
||||||
|
<a class="twitter-share-button"
|
||||||
|
href="https://twitter.com/intent/tweet"
|
||||||
|
data-url="{{ request.build_absolute_uri }}"
|
||||||
|
{% if race.sessiontype == 'race' %}
|
||||||
|
data-text="@rowsandall #rowingdata Participate in virtual race '{{ race.name }}'">Tweet</a>
|
||||||
|
{% else %}
|
||||||
|
data-text="@rowsandall #rowingdata Participate in Indoor Rowing virtual race '{{ race.name }}'">Tweet</a>
|
||||||
|
{% endif %}
|
||||||
|
</p><p>
|
||||||
|
<a href="https://www.pinterest.com/pin/create/button/"
|
||||||
|
data-pin-do="buttonBookmark">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
{% if not racelogo and race.manager == request.user %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/image">Add Race Logo</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block sidebar %}
|
||||||
|
{% include 'menu_racing.html' %}
|
||||||
|
{% endblock %}
|
||||||
@@ -127,6 +127,22 @@ class UserFactory(factory.DjangoModelFactory):
|
|||||||
|
|
||||||
first_name = faker.name().split(' ')[0]
|
first_name = faker.name().split(' ')[0]
|
||||||
last_name = faker.name().split(' ')[0]
|
last_name = faker.name().split(' ')[0]
|
||||||
|
|
||||||
|
class RaceFactory(factory.DjangoModelFactory):
|
||||||
|
class Meta:
|
||||||
|
model = VirtualRace
|
||||||
|
|
||||||
|
name = factory.LazyAttribute(lambda _: faker.word())
|
||||||
|
registration_closure = timezone.now()+datetime.timedelta(days=1)
|
||||||
|
evaluation_closure = timezone.now()+datetime.timedelta(days=2)
|
||||||
|
startdate = timezone.now().date()
|
||||||
|
start_time = datetime.time()
|
||||||
|
enddate = (timezone.now()+datetime.timedelta(days=1)).date()
|
||||||
|
end_time = datetime.time()
|
||||||
|
preferreddate = timezone.now().date()
|
||||||
|
sessiontype = 'indoorrace'
|
||||||
|
sessionvalue = 1
|
||||||
|
sessionmode = 'time'
|
||||||
|
|
||||||
class WorkoutFactory(factory.DjangoModelFactory):
|
class WorkoutFactory(factory.DjangoModelFactory):
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -150,3 +166,20 @@ class SessionFactory(factory.DjangoModelFactory):
|
|||||||
name = factory.LazyAttribute(lambda _: faker.word())
|
name = factory.LazyAttribute(lambda _: faker.word())
|
||||||
comment = faker.text()
|
comment = faker.text()
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
|
def cleanup(request):
|
||||||
|
def remove_test_files():
|
||||||
|
|
||||||
|
for filename in os.listdir('media/mailbox_attachments'):
|
||||||
|
path = os.path.join('media/mailbox_attachments/',filename)
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
os.remove(path)
|
||||||
|
|
||||||
|
for filename in os.listdir('rowers/tests/testdata/temp'):
|
||||||
|
path = os.path.join('rowers/tests/testdata/temp/',filename)
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
os.remove(path)
|
||||||
|
|
||||||
|
|
||||||
|
request.addfinalizer(remove_test_files)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,224 @@
|
|||||||
|
#from __future__ import print_function
|
||||||
|
from statements import *
|
||||||
|
|
||||||
|
class EmailUpload(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
redis_connection.publish('tasks','KILL')
|
||||||
|
u = User.objects.create_user('john',
|
||||||
|
'sander@ds.ds',
|
||||||
|
'koeinsloot')
|
||||||
|
r = Rower.objects.create(user=u,gdproptin=True,
|
||||||
|
gdproptindate=timezone.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
self.theadmin = UserFactory(is_staff=True)
|
||||||
|
self.rtheadmin = Rower.objects.create(user=self.theadmin,
|
||||||
|
birthdate = faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach')
|
||||||
|
|
||||||
|
nu = datetime.datetime.now()
|
||||||
|
workoutsbox = Mailbox.objects.create(name='workouts')
|
||||||
|
workoutsbox.save()
|
||||||
|
failbox = Mailbox.objects.create(name='Failed')
|
||||||
|
failbox.save()
|
||||||
|
|
||||||
|
m = Message(mailbox=workoutsbox,
|
||||||
|
from_header = u.email,
|
||||||
|
subject = "run",
|
||||||
|
body = """
|
||||||
|
workout run
|
||||||
|
""")
|
||||||
|
m.save()
|
||||||
|
a2 = 'media/mailbox_attachments/colin3.csv'
|
||||||
|
copyfile('rowers/tests/testdata/emails/colin.csv',a2)
|
||||||
|
a = MessageAttachment(message=m,document=a2[6:])
|
||||||
|
a.save()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
for filename in os.listdir('media/mailbox_attachments'):
|
||||||
|
path = os.path.join('media/mailbox_attachments/',filename)
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
try:
|
||||||
|
os.remove(path)
|
||||||
|
except (IOError,WindowsError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.polarstuff.get_polar_notifications')
|
||||||
|
@patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
|
||||||
|
def test_emailupload(
|
||||||
|
self, mocked_sqlalchemy,mocked_polar_notifications, mock_get, mock_post):
|
||||||
|
out = StringIO()
|
||||||
|
call_command('processemail', stdout=out,testing=True)
|
||||||
|
self.assertIn('Successfully processed email attachments',out.getvalue())
|
||||||
|
|
||||||
|
ws = Workout.objects.filter(name="run")
|
||||||
|
|
||||||
|
self.assertEqual(len(ws),1)
|
||||||
|
w = ws[0]
|
||||||
|
self.assertEqual(w.workouttype,'Run')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#@pytest.mark.django_db
|
||||||
|
class EmailTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
redis_connection.publish('tasks','KILL')
|
||||||
|
u = User.objects.create_user('john',
|
||||||
|
'sander@ds.ds',
|
||||||
|
'koeinsloot')
|
||||||
|
r = Rower.objects.create(user=u,gdproptin=True,
|
||||||
|
gdproptindate=timezone.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
self.theadmin = UserFactory(is_staff=True)
|
||||||
|
self.rtheadmin = Rower.objects.create(user=self.theadmin,
|
||||||
|
birthdate = faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach')
|
||||||
|
|
||||||
|
nu = datetime.datetime.now()
|
||||||
|
workoutsbox = Mailbox.objects.create(name='workouts')
|
||||||
|
workoutsbox.save()
|
||||||
|
failbox = Mailbox.objects.create(name='Failed')
|
||||||
|
failbox.save()
|
||||||
|
|
||||||
|
|
||||||
|
for filename in os.listdir(u'rowers/tests/testdata/emails'):
|
||||||
|
m = Message(mailbox=workoutsbox,
|
||||||
|
from_header = u.email,
|
||||||
|
subject = filename,
|
||||||
|
body="""
|
||||||
|
---
|
||||||
|
workouttype: water
|
||||||
|
boattype: 4x
|
||||||
|
...
|
||||||
|
""")
|
||||||
|
m.save()
|
||||||
|
a2 = 'media/mailbox_attachments/'+filename
|
||||||
|
copyfile(u'rowers/tests/testdata/emails/'+filename,a2)
|
||||||
|
a = MessageAttachment(message=m,document=a2[6:])
|
||||||
|
a.save()
|
||||||
|
|
||||||
|
m = Message(mailbox=workoutsbox,
|
||||||
|
from_header = u.email,
|
||||||
|
subject = "3x(5min/2min)/r2 \r2",
|
||||||
|
body = """
|
||||||
|
workout water
|
||||||
|
""")
|
||||||
|
m.save()
|
||||||
|
a2 = 'media/mailbox_attachments/colin2.csv'
|
||||||
|
copyfile('rowers/tests/testdata/emails/colin.csv',a2)
|
||||||
|
a = MessageAttachment(message=m,document=a2[6:])
|
||||||
|
a.save()
|
||||||
|
|
||||||
|
m = Message(mailbox=workoutsbox,
|
||||||
|
from_header = self.theadmin.email,
|
||||||
|
subject = "johnsworkout",
|
||||||
|
body = """
|
||||||
|
user john
|
||||||
|
race 1
|
||||||
|
""")
|
||||||
|
m.save()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
for filename in os.listdir('media/mailbox_attachments'):
|
||||||
|
path = os.path.join('media/mailbox_attachments/',filename)
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
try:
|
||||||
|
os.remove(path)
|
||||||
|
except (IOError,WindowsError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.polarstuff.get_polar_notifications')
|
||||||
|
@patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
|
||||||
|
def test_emailprocessing(
|
||||||
|
self, mocked_sqlalchemy,mocked_polar_notifications, mock_get, mock_post):
|
||||||
|
out = StringIO()
|
||||||
|
call_command('processemail', stdout=out,testing=True)
|
||||||
|
self.assertIn('Successfully processed email attachments',out.getvalue())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class EmailAdminUpload(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
redis_connection.publish('tasks','KILL')
|
||||||
|
u = User.objects.create_user('john',
|
||||||
|
'sander@ds.ds',
|
||||||
|
'koeinsloot')
|
||||||
|
r = Rower.objects.create(user=u,gdproptin=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
birthdate = faker.profile()['birthdate']
|
||||||
|
)
|
||||||
|
|
||||||
|
self.theadmin = UserFactory(is_staff=True)
|
||||||
|
self.rtheadmin = Rower.objects.create(user=self.theadmin,
|
||||||
|
birthdate = faker.profile()['birthdate'],
|
||||||
|
gdproptin=True,
|
||||||
|
gdproptindate=timezone.now(),
|
||||||
|
rowerplan='coach')
|
||||||
|
|
||||||
|
self.race = RaceFactory(manager = self.theadmin)
|
||||||
|
|
||||||
|
nu = datetime.datetime.now()
|
||||||
|
workoutsbox = Mailbox.objects.create(name='workouts')
|
||||||
|
workoutsbox.save()
|
||||||
|
failbox = Mailbox.objects.create(name='Failed')
|
||||||
|
failbox.save()
|
||||||
|
|
||||||
|
m = Message(mailbox=workoutsbox,
|
||||||
|
from_header = self.theadmin.email,
|
||||||
|
subject = "johnsworkout",
|
||||||
|
body = """
|
||||||
|
user john
|
||||||
|
race 1
|
||||||
|
""")
|
||||||
|
m.save()
|
||||||
|
a2 = 'media/mailbox_attachments/minute.csv'
|
||||||
|
copyfile('rowers/tests/testdata/minute.csv',a2)
|
||||||
|
a = MessageAttachment(message=m,document=a2[6:])
|
||||||
|
a.save()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
for filename in os.listdir('media/mailbox_attachments'):
|
||||||
|
path = os.path.join('media/mailbox_attachments/',filename)
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
try:
|
||||||
|
os.remove(path)
|
||||||
|
except (IOError,WindowsError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@patch('rowers.dataprep.create_engine')
|
||||||
|
@patch('rowers.polarstuff.get_polar_notifications')
|
||||||
|
@patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
|
||||||
|
def test_email_admin_upload(
|
||||||
|
self, mocked_sqlalchemy,mocked_polar_notifications, mock_get, mock_post):
|
||||||
|
out = StringIO()
|
||||||
|
call_command('processemail', stdout=out,testing=True)
|
||||||
|
self.assertIn('Successfully processed email attachments',out.getvalue())
|
||||||
|
|
||||||
|
ws = Workout.objects.filter(name="johnsworkout")
|
||||||
|
if not len(ws):
|
||||||
|
for w in Workout.objects.all():
|
||||||
|
print w
|
||||||
|
|
||||||
|
self.assertEqual(len(ws),1)
|
||||||
|
|
||||||
|
w = ws[0]
|
||||||
|
self.assertEqual(w.user.user.username,u'john')
|
||||||
|
|
||||||
|
results = IndoorVirtualRaceResult.objects.filter(
|
||||||
|
race=self.race)
|
||||||
|
|
||||||
|
self.assertEqual(len(results),1)
|
||||||
|
result = results[0]
|
||||||
|
|
||||||
|
self.assertTrue(result.coursecompleted)
|
||||||
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
#from __future__ import print_function
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
|
||||||
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
import re
|
|
||||||
from nose_parameterized import parameterized
|
|
||||||
from django.test import TestCase, Client,override_settings
|
|
||||||
from django.core.management import call_command
|
|
||||||
from django.utils.six import StringIO
|
|
||||||
from django.test.client import RequestFactory
|
|
||||||
from rowers.views import checkworkoutuser,c2_open
|
|
||||||
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
|
|
||||||
from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
|
|
||||||
import rowers.plots as plots
|
|
||||||
import rowers.interactiveplots as iplots
|
|
||||||
import datetime
|
|
||||||
from rowingdata import rowingdata as rdata
|
|
||||||
from rowingdata import rower as rrower
|
|
||||||
from django.utils import timezone
|
|
||||||
from rowers.rows import handle_uploaded_file
|
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
||||||
from time import strftime,strptime,mktime,time,daylight
|
|
||||||
import os
|
|
||||||
from rowers.tasks import handle_makeplot
|
|
||||||
from rowers.utils import serialize_list,deserialize_list
|
|
||||||
from rowers.utils import NoTokenError
|
|
||||||
from shutil import copyfile
|
|
||||||
from nose.tools import assert_true
|
|
||||||
from mock import Mock, patch
|
|
||||||
from minimocktest import MockTestCase
|
|
||||||
import pandas as pd
|
|
||||||
import rowers.c2stuff as c2stuff
|
|
||||||
|
|
||||||
import json
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from rowers import urls
|
|
||||||
from rowers.views import error500_view,error404_view,error400_view,error403_view
|
|
||||||
|
|
||||||
from rowers.dataprep import delete_strokedata
|
|
||||||
|
|
||||||
from redis import StrictRedis
|
|
||||||
redis_connection = StrictRedis()
|
|
||||||
|
|
||||||
from rowers.tests.test_imports import mocked_requests
|
|
||||||
|
|
||||||
|
|
||||||
from django_mailbox.models import Mailbox,MessageAttachment,Message
|
|
||||||
|
|
||||||
from rowers.tests.mocks import mocked_sqlalchemy
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
class UploadTests(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
redis_connection.publish('tasks','KILL')
|
|
||||||
u = User.objects.create_user('john',
|
|
||||||
'sander@ds.ds',
|
|
||||||
'koeinsloot')
|
|
||||||
r = Rower.objects.create(user=u,gdproptin=True,
|
|
||||||
gdproptindate=timezone.now(),
|
|
||||||
getemailnotifications = False,
|
|
||||||
)
|
|
||||||
|
|
||||||
nu = datetime.datetime.now()
|
|
||||||
workoutsbox = Mailbox.objects.create(name='workouts')
|
|
||||||
workoutsbox.save()
|
|
||||||
failbox = Mailbox.objects.create(name='Failed')
|
|
||||||
failbox.save()
|
|
||||||
m = Message(mailbox=workoutsbox,
|
|
||||||
from_header = u.email,
|
|
||||||
subject = "3x(5min/2min)/r2 \r2",
|
|
||||||
body = """
|
|
||||||
workout run
|
|
||||||
""")
|
|
||||||
m.save()
|
|
||||||
a2 = 'media/mailbox_attachments/colin2.csv'
|
|
||||||
copyfile('rowers/tests/testdata/emails/colin.csv',a2)
|
|
||||||
a = MessageAttachment(message=m,document=a2[6:])
|
|
||||||
a.save()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
for filename in os.listdir('media/mailbox_attachments'):
|
|
||||||
path = os.path.join('media/mailbox_attachments/',filename)
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
try:
|
|
||||||
os.remove(path)
|
|
||||||
except (IOError,WindowsError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@patch('requests.get', side_effect=mocked_requests)
|
|
||||||
def test_email_workouttype(self, mock_get):
|
|
||||||
out = StringIO()
|
|
||||||
call_command('processemail', stdout=out, testing=True)
|
|
||||||
w = Workout.objects.get(id=1)
|
|
||||||
self.assertEqual(w.workouttype,'Run')
|
|
||||||
|
|
||||||
#@pytest.mark.django_db
|
|
||||||
class EmailTests(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
redis_connection.publish('tasks','KILL')
|
|
||||||
u = User.objects.create_user('john',
|
|
||||||
'sander@ds.ds',
|
|
||||||
'koeinsloot')
|
|
||||||
r = Rower.objects.create(user=u,gdproptin=True,
|
|
||||||
gdproptindate=timezone.now()
|
|
||||||
)
|
|
||||||
|
|
||||||
nu = datetime.datetime.now()
|
|
||||||
workoutsbox = Mailbox.objects.create(name='workouts')
|
|
||||||
workoutsbox.save()
|
|
||||||
failbox = Mailbox.objects.create(name='Failed')
|
|
||||||
failbox.save()
|
|
||||||
|
|
||||||
for filename in os.listdir(u'rowers/tests/testdata/emails'):
|
|
||||||
m = Message(mailbox=workoutsbox,
|
|
||||||
from_header = u.email,
|
|
||||||
subject = filename,
|
|
||||||
body="""
|
|
||||||
---
|
|
||||||
workouttype: water
|
|
||||||
boattype: 4x
|
|
||||||
...
|
|
||||||
""")
|
|
||||||
m.save()
|
|
||||||
a2 = 'media/mailbox_attachments/'+filename
|
|
||||||
copyfile(u'rowers/tests/testdata/emails/'+filename,a2)
|
|
||||||
a = MessageAttachment(message=m,document=a2[6:])
|
|
||||||
a.save()
|
|
||||||
|
|
||||||
m = Message(mailbox=workoutsbox,
|
|
||||||
from_header = u.email,
|
|
||||||
subject = "3x(5min/2min)/r2 \r2",
|
|
||||||
body = """
|
|
||||||
workout water
|
|
||||||
""")
|
|
||||||
m.save()
|
|
||||||
a2 = 'media/mailbox_attachments/colin2.csv'
|
|
||||||
copyfile('rowers/tests/testdata/emails/colin.csv',a2)
|
|
||||||
a = MessageAttachment(message=m,document=a2[6:])
|
|
||||||
a.save()
|
|
||||||
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
for filename in os.listdir('media/mailbox_attachments'):
|
|
||||||
path = os.path.join('media/mailbox_attachments/',filename)
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
try:
|
|
||||||
os.remove(path)
|
|
||||||
except (IOError,WindowsError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@patch('rowers.dataprep.create_engine')
|
|
||||||
@patch('rowers.polarstuff.get_polar_notifications')
|
|
||||||
@patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
|
|
||||||
@patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
|
|
||||||
def test_emailprocessing(
|
|
||||||
self, mocked_sqlalchemy,mocked_polar_notifications, mock_get, mock_post):
|
|
||||||
out = StringIO()
|
|
||||||
call_command('processemail', stdout=out,testing=True)
|
|
||||||
self.assertIn('Successfully processed email attachments',out.getvalue())
|
|
||||||
|
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
index,TimeStamp (sec), activityIdx, lapIdx, pointIdx, ElapsedTime (sec), Horizontal (meters), Stroke500mPace (sec/500m), Cadence (strokes/min), HRCur (bpm), Power (watts), Calories (kCal), Speed (m/sec), StrokeCount, StrokeDistance (meters), DriveLength (meters), DriveTime (ms), StrokeRecoveryTime (ms), WorkPerStroke (joules), AverageDriveForce (lbs), PeakDriveForce (lbs), DragFactor, ElapsedTimeAtDrive (sec), HorizontalAtDrive (meters), WorkoutType, IntervalType, WorkoutState, RowingState, WorkoutDurationType, WorkoutIntervalCount, Cadence (stokes/min), AverageBoatSpeed (m/s), AverageDriveForce (N), PeakDriveForce (N), Stroke Number,cum_dist,originalvelo
|
||||||
|
0,1548096824.0,0,0,0,4.18,20.3,93.3506356168139,48,86,436.5048883104004,1,5.3820000000000014,4,6.79,1.36,500,560,0,142.4,222.0,115,0.0,0.0,5,0,1,1,0,0,48.0,5.353892279687333,633.4265280000002,987.50484,2,20.3,5.353892279687333
|
||||||
|
1,1548096826.7910905,0,0,1,6.94,35.9,89.62484388832563,45,87,496.4816892895996,2,5.6179999999999986,6,8.15,1.42,490,730,0,142.3,238.8,113,4.18,20.3,5,0,1,1,0,0,45.0,5.587840858292355,632.9817059999998,1062.2349359999996,4,35.9,5.587840858292355
|
||||||
|
2,1548096837.108201,0,0,2,17.27,94.5,88.81577825856567,41,96,504.2099300644,8,5.647,13,8.19,1.36,480,770,0,144.0,242.9,112,6.94,35.9,5,0,1,1,0,0,41.0,5.616084465910367,640.54368,1080.4726380000004,11,94.5,5.616084465910367
|
||||||
|
3,1548096839.086601,0,0,3,19.25,105.7,88.96490450858349,41,99,504.2099300644,8,5.647,14,8.19,1.39,480,750,0,142.0,244.6,112,17.27,94.5,5,0,1,1,0,0,41.0,5.616084465910367,631.64724,1088.034612,12,105.7,5.616084465910367
|
||||||
|
4,1548096842.8994308,0,0,4,23.07,127.2,89.27586762584984,41,104,501.8029914016,11,5.638,17,8.12,1.36,470,760,0,143.6,251.4,112,19.25,105.7,5,0,1,1,0,0,41.0,5.607267018055401,638.7643919999998,1118.282508,15,127.2,5.607267018055401
|
||||||
|
5,1548096847.161281,0,0,5,27.31,151.1,89.89298681607487,41,110,489.62041712640007,14,5.5920000000000005,20,8.11,1.36,490,760,0,133.6,231.0,111,23.07,127.2,5,0,1,1,0,0,41.0,5.561116672227786,594.282192,1027.53882,18,151.1,5.561116672227786
|
||||||
|
6,1548096850.1555116,0,0,6,30.31,167.8,90.29743877919012,41,112,480.4843223404,15,5.557,22,8.47,1.39,490,820,0,143.9,234.4,111,27.31,151.1,5,0,1,1,0,0,41.0,5.526693931690064,640.0988580000002,1042.662768,20,167.8,5.526693931690064
|
||||||
|
7,1548096853.1276512,0,0,7,33.28,184.3,90.39988760767656,40,113,484.1249963508004,17,5.5710000000000015,24,8.24,1.36,490,800,0,138.4,254.1,111,30.31,167.8,5,0,1,1,0,0,40.0,5.540780141843972,615.633648,1130.292702,22,184.3,5.540780141843972
|
||||||
|
8,1548096856.0643613,0,0,8,36.21,200.5,90.61884542605642,41,115,477.8950465044004,18,5.5470000000000015,26,8.1,1.36,480,770,0,135.5,227.6,111,33.28,184.3,5,0,1,1,0,0,41.0,5.516936996579499,602.7338100000002,1012.4148720000001,24,200.5,5.516936996579499
|
||||||
|
9,1548096859.0091813,0,0,9,39.17,216.8,91.12253138918642,41,116,468.9058576384001,20,5.5120000000000005,28,8.1,1.36,500,770,0,132.7,232.4,111,36.21,200.5,5,0,1,1,0,0,41.0,5.483057352779911,590.2787940000002,1033.766328,26,216.8,5.483057352779911
|
||||||
|
10,1548096862.008181,0,0,10,42.16,233.2,91.7159092344983,40,117,462.8074479616,21,5.488,30,8.24,1.33,470,810,0,130.6,218.9,111,39.17,216.8,5,0,1,1,0,0,40.0,5.459111256687411,580.937532,973.715358,28,233.2,5.459111256687411
|
||||||
|
11,1548096866.4157307,0,0,11,46.57,257.2,92.13100908526968,41,118,452.5120589444,24,5.447,33,7.89,1.33,470,760,0,133.0,227.5,111,42.16,233.2,5,0,1,1,0,0,41.0,5.417705060136527,591.61326,1011.97005,31,257.2,5.417705060136527
|
||||||
|
12,1548096869.206501,0,0,12,49.36,272.4,92.30771272248859,43,118,452.7613310976001,25,5.448,35,7.6,1.3,460,710,0,131.0,208.0,111,46.57,257.2,5,0,1,1,0,0,43.0,5.418879375745096,582.71682,925.2297599999999,33,272.4,5.418879375745096
|
||||||
|
13,1548096872.1160307,0,0,13,52.27,288.2,92.39395707918017,42,119,451.2670704864,26,5.442,37,7.96,1.33,480,770,0,132.8,222.3,111,49.36,272.4,5,0,1,1,0,0,42.0,5.413598960589,590.7236160000001,988.839306,35,288.2,5.413598960589
|
||||||
|
14,1548096875.085701,0,0,14,55.24,304.2,92.99397114111812,41,119,442.6160316004,28,5.407,39,8.02,1.3,480,790,0,128.7,230.0,111,52.27,288.2,5,0,1,1,0,0,41.0,5.378657487091222,572.485914,1023.0906,37,304.2,5.378657487091222
|
||||||
|
15,1548096878.0252109,0,0,15,58.2,319.9,94.06681282362852,41,119,426.8444927264001,29,5.3420000000000005,41,7.95,1.27,490,820,0,123.4,213.1,111,55.24,304.2,5,0,1,1,0,0,41.0,5.314061005420342,548.910348,947.9156820000001,39,319.9,5.314061005420342
|
||||||
|
16,1548096880.0612912,0,0,16,60.0,329.3,95.37595742617708,40,120,409.81691239999986,30,5.27,42,8.03,1.27,490,840,0,110.4,193.6,111,58.2,319.9,5,0,10,0,0,0,40.0,5.242738806752646,491.08348800000016,861.175392,40,329.3,5.242738806752646
|
||||||
|
BIN
Binary file not shown.
Vendored
+1
-1
@@ -2502,7 +2502,7 @@
|
|||||||
</Trackpoint>
|
</Trackpoint>
|
||||||
</Track>
|
</Track>
|
||||||
</Lap>
|
</Lap>
|
||||||
<Notes><Element 'Notes' at 0x13f67128></Notes>
|
<Notes><Element 'Notes' at 0x18ae8668></Notes>
|
||||||
</Activity>
|
</Activity>
|
||||||
</Activities>
|
</Activities>
|
||||||
<Creator>
|
<Creator>
|
||||||
|
|||||||
@@ -82,6 +82,27 @@ def matchchart(line):
|
|||||||
if tester3.match(line.lower()):
|
if tester3.match(line.lower()):
|
||||||
return 'pieplot'
|
return 'pieplot'
|
||||||
|
|
||||||
|
def matchuser(line):
|
||||||
|
testert = '^(user)'
|
||||||
|
tester = re.compile(testert)
|
||||||
|
if tester.match(line.lower()):
|
||||||
|
words = line.split()
|
||||||
|
return words[1]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def matchrace(line):
|
||||||
|
testert = '^(race)'
|
||||||
|
tester = re.compile(testert)
|
||||||
|
if tester.match(line.lower()):
|
||||||
|
words = line.split()
|
||||||
|
try:
|
||||||
|
return int(words[1])
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def matchsync(line):
|
def matchsync(line):
|
||||||
results = []
|
results = []
|
||||||
tester = '((sync)|(synchronization)|(export))'
|
tester = '((sync)|(synchronization)|(export))'
|
||||||
@@ -176,6 +197,22 @@ def getplotoptions_body2(uploadoptions,body):
|
|||||||
|
|
||||||
return uploadoptions
|
return uploadoptions
|
||||||
|
|
||||||
|
def getuseroptions_body2(uploadoptions,body):
|
||||||
|
for line in body.splitlines():
|
||||||
|
user = matchuser(line)
|
||||||
|
if user:
|
||||||
|
uploadoptions['username'] = user
|
||||||
|
|
||||||
|
return uploadoptions
|
||||||
|
|
||||||
|
def getraceoptions_body2(uploadoptions,body):
|
||||||
|
for line in body.splitlines():
|
||||||
|
raceid = matchrace(line)
|
||||||
|
if raceid:
|
||||||
|
uploadoptions['raceid'] = raceid
|
||||||
|
|
||||||
|
return uploadoptions
|
||||||
|
|
||||||
def getsyncoptions_body2(uploadoptions,body):
|
def getsyncoptions_body2(uploadoptions,body):
|
||||||
result = []
|
result = []
|
||||||
for line in body.splitlines():
|
for line in body.splitlines():
|
||||||
@@ -261,6 +298,20 @@ def getboattype(uploadoptions,value,key):
|
|||||||
|
|
||||||
return uploadoptions
|
return uploadoptions
|
||||||
|
|
||||||
|
def getuser(uploadoptions,value,key):
|
||||||
|
uploadoptions['username'] = value
|
||||||
|
|
||||||
|
return uploadoptions
|
||||||
|
|
||||||
|
def getrace(uploadoptions,value,key):
|
||||||
|
try:
|
||||||
|
raceid = int(value)
|
||||||
|
uploadoptions['raceid'] = raceid
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return uploadoptions
|
||||||
|
|
||||||
def getsource(uploadoptions,value,key):
|
def getsource(uploadoptions,value,key):
|
||||||
workoutsource = 'unknown'
|
workoutsource = 'unknown'
|
||||||
for type,verb in workoutsources:
|
for type,verb in workoutsources:
|
||||||
@@ -306,6 +357,10 @@ def upload_options(body):
|
|||||||
uploadoptions = getboattype(uploadoptions,value,'boattype')
|
uploadoptions = getboattype(uploadoptions,value,'boattype')
|
||||||
if 'source' in lowkey:
|
if 'source' in lowkey:
|
||||||
uploadoptions = getsource(uploadoptions,value,'workoutsource')
|
uploadoptions = getsource(uploadoptions,value,'workoutsource')
|
||||||
|
if 'username' in lowkey:
|
||||||
|
uploadoptions = getuser(uploadoptions,value,'username')
|
||||||
|
if 'raceid' in lowkey:
|
||||||
|
uploadoptions = getraceid(uploadoptions,value,'raceid')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
#pass
|
#pass
|
||||||
raise yaml.YAMLError
|
raise yaml.YAMLError
|
||||||
@@ -317,6 +372,8 @@ def upload_options(body):
|
|||||||
uploadoptions = gettypeoptions_body2(uploadoptions,body)
|
uploadoptions = gettypeoptions_body2(uploadoptions,body)
|
||||||
uploadoptions = getstravaid(uploadoptions,body)
|
uploadoptions = getstravaid(uploadoptions,body)
|
||||||
uploadoptions = getworkoutsources(uploadoptions,body)
|
uploadoptions = getworkoutsources(uploadoptions,body)
|
||||||
|
uploadoptions = getuseroptions_body2(uploadoptions,body)
|
||||||
|
uploadoptions = getraceoptions_body2(uploadoptions,body)
|
||||||
except IOError:
|
except IOError:
|
||||||
pm = exc.problem_mark
|
pm = exc.problem_mark
|
||||||
strpm = str(pm)
|
strpm = str(pm)
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ urlpatterns = [
|
|||||||
url(r'^indoorraceregistration/togglenotification/(?P<id>\d+)/$',
|
url(r'^indoorraceregistration/togglenotification/(?P<id>\d+)/$',
|
||||||
views.indoorvirtualevent_toggle_email_view),
|
views.indoorvirtualevent_toggle_email_view),
|
||||||
url(r'^virtualevent/(?P<id>\d+)/$',views.virtualevent_view),
|
url(r'^virtualevent/(?P<id>\d+)/$',views.virtualevent_view),
|
||||||
|
url(r'^virtualevent/(?P<id>\d+)/ranking$',views.virtualevent_ranking_view),
|
||||||
url(r'^virtualevent/(?P<id>\d+)/edit/$',views.virtualevent_edit_view),
|
url(r'^virtualevent/(?P<id>\d+)/edit/$',views.virtualevent_edit_view),
|
||||||
url(r'^virtualevent/(?P<id>\d+)/editindoor/$',views.indoorvirtualevent_edit_view),
|
url(r'^virtualevent/(?P<id>\d+)/editindoor/$',views.indoorvirtualevent_edit_view),
|
||||||
url(r'^virtualevent/(?P<id>\d+)/register/$',views.virtualevent_register_view),
|
url(r'^virtualevent/(?P<id>\d+)/register/$',views.virtualevent_register_view),
|
||||||
|
|||||||
+180
@@ -16128,6 +16128,186 @@ def virtualevent_view(request,id=0):
|
|||||||
'active':'nav-racing',
|
'active':'nav-racing',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def virtualevent_ranking_view(request,id=0):
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
if not request.user.is_anonymous():
|
||||||
|
r = getrower(request.user)
|
||||||
|
else:
|
||||||
|
r = None
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
race = VirtualRace.objects.get(id=id)
|
||||||
|
except VirtualRace.DoesNotExist:
|
||||||
|
raise Http404("Virtual Race does not exist")
|
||||||
|
|
||||||
|
if race.sessiontype == 'race':
|
||||||
|
script,div = course_map(race.course)
|
||||||
|
resultobj = VirtualRaceResult
|
||||||
|
else:
|
||||||
|
script = ''
|
||||||
|
div = ''
|
||||||
|
resultobj = IndoorVirtualRaceResult
|
||||||
|
|
||||||
|
records = resultobj.objects.filter(race=race)
|
||||||
|
|
||||||
|
|
||||||
|
buttons = []
|
||||||
|
|
||||||
|
# to-do - add DNS
|
||||||
|
dns = []
|
||||||
|
if timezone.now() > race.evaluation_closure:
|
||||||
|
dns = resultobj.objects.filter(
|
||||||
|
race=race,
|
||||||
|
workoutid__isnull=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if not request.user.is_anonymous():
|
||||||
|
if race_can_register(r,race):
|
||||||
|
buttons += ['registerbutton']
|
||||||
|
|
||||||
|
if race_can_adddiscipline(r,race):
|
||||||
|
buttons += ['adddisciplinebutton']
|
||||||
|
|
||||||
|
if race_can_submit(r,race):
|
||||||
|
buttons += ['submitbutton']
|
||||||
|
|
||||||
|
if race_can_resubmit(r,race):
|
||||||
|
buttons += ['resubmitbutton']
|
||||||
|
|
||||||
|
if race_can_withdraw(r,race):
|
||||||
|
buttons += ['withdrawbutton']
|
||||||
|
|
||||||
|
if race_can_edit(r,race):
|
||||||
|
buttons += ['editbutton']
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = RaceResultFilterForm(request.POST,records=records)
|
||||||
|
if form.is_valid():
|
||||||
|
cd = form.cleaned_data
|
||||||
|
try:
|
||||||
|
sex = cd['sex']
|
||||||
|
except KeyError:
|
||||||
|
sex = ['female','male','mixed']
|
||||||
|
|
||||||
|
try:
|
||||||
|
boattype = cd['boattype']
|
||||||
|
except KeyError:
|
||||||
|
boattype = mytypes.waterboattype
|
||||||
|
|
||||||
|
try:
|
||||||
|
boatclass = cd['boatclass']
|
||||||
|
except KeyError:
|
||||||
|
if race.sessiontype == 'race':
|
||||||
|
boatclass = [t for t in mytypes.otwtypes]
|
||||||
|
else:
|
||||||
|
boatclass = [t for t in mytypes.otetypes]
|
||||||
|
|
||||||
|
age_min = cd['age_min']
|
||||||
|
age_max = cd['age_max']
|
||||||
|
|
||||||
|
try:
|
||||||
|
weightcategory = cd['weightcategory']
|
||||||
|
except KeyError:
|
||||||
|
weightcategory = ['hwt','lwt']
|
||||||
|
|
||||||
|
try:
|
||||||
|
adaptiveclass = cd['adaptiveclass']
|
||||||
|
except KeyError:
|
||||||
|
adaptiveclass = ['None','PR1','PR2','PR3','FES']
|
||||||
|
|
||||||
|
if race.sessiontype == 'race':
|
||||||
|
results = resultobj.objects.filter(
|
||||||
|
race=race,
|
||||||
|
workoutid__isnull=False,
|
||||||
|
boatclass__in=boatclass,
|
||||||
|
boattype__in=boattype,
|
||||||
|
sex__in=sex,
|
||||||
|
weightcategory__in=weightcategory,
|
||||||
|
adaptiveclass__in=adaptiveclass,
|
||||||
|
age__gte=age_min,
|
||||||
|
age__lte=age_max
|
||||||
|
).order_by("duration")
|
||||||
|
else:
|
||||||
|
results = resultobj.objects.filter(
|
||||||
|
race=race,
|
||||||
|
workoutid__isnull=False,
|
||||||
|
boatclass__in=boatclass,
|
||||||
|
sex__in=sex,
|
||||||
|
weightcategory__in=weightcategory,
|
||||||
|
adaptiveclass__in=adaptiveclass,
|
||||||
|
age__gte=age_min,
|
||||||
|
age__lte=age_max
|
||||||
|
).order_by("duration","-distance")
|
||||||
|
|
||||||
|
|
||||||
|
# to-do - add DNS
|
||||||
|
dns = []
|
||||||
|
if timezone.now() > race.evaluation_closure:
|
||||||
|
dns = resultobj.objects.filter(
|
||||||
|
race=race,
|
||||||
|
workoutid__isnull=True,
|
||||||
|
boatclass__in=boatclass,
|
||||||
|
sex__in=sex,
|
||||||
|
weightcategory__in=weightcategory,
|
||||||
|
adaptiveclass__in=adaptiveclass,
|
||||||
|
age__gte=age_min,
|
||||||
|
age__lte=age_max
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
results = resultobj.objects.filter(
|
||||||
|
race=race,
|
||||||
|
workoutid__isnull=False,
|
||||||
|
coursecompleted=True,
|
||||||
|
).order_by("duration","-distance")
|
||||||
|
|
||||||
|
if results:
|
||||||
|
form = RaceResultFilterForm(records=records)
|
||||||
|
else:
|
||||||
|
form = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
breadcrumbs = [
|
||||||
|
{
|
||||||
|
'url':reverse(virtualevents_view),
|
||||||
|
'name': 'Racing'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url':reverse(virtualevent_view,
|
||||||
|
kwargs={'id':race.id}
|
||||||
|
),
|
||||||
|
'name': race.name
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
racelogos = race.logos.all()
|
||||||
|
|
||||||
|
if racelogos:
|
||||||
|
racelogo = racelogos[0]
|
||||||
|
else:
|
||||||
|
racelogo = None
|
||||||
|
|
||||||
|
return render(request,'virtualeventranking.html',
|
||||||
|
{
|
||||||
|
'coursescript':script,
|
||||||
|
'coursediv':div,
|
||||||
|
'breadcrumbs':breadcrumbs,
|
||||||
|
'race':race,
|
||||||
|
'rower':r,
|
||||||
|
'results':results,
|
||||||
|
'buttons':buttons,
|
||||||
|
'dns':dns,
|
||||||
|
'records':records,
|
||||||
|
'racelogo':racelogo,
|
||||||
|
'form':form,
|
||||||
|
'active':'nav-racing',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def virtualevent_withdraw_view(request,id=0,recordid=None):
|
def virtualevent_withdraw_view(request,id=0,recordid=None):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
|
|||||||
Reference in New Issue
Block a user