Private
Public Access
1
0

Merge branch 'release/v6.68'

This commit is contained in:
Sander Roosendaal
2018-05-17 18:52:44 +02:00
8 changed files with 398 additions and 134 deletions

View File

@@ -33,14 +33,8 @@ from rowers.models import (
) )
from utils import geo_distance from utils import geo_distance
from rowers.courseutils import coursetime_paths, coursetime_first
# low level methods
class InvalidTrajectoryError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
return repr(self.value)
def get_course_timezone(course): def get_course_timezone(course):
@@ -65,31 +59,6 @@ def get_course_timezone(course):
def time_in_path(df,p,maxmin='max'):
if df.empty:
return 0
latitude = df.latitude
longitude = df.longitude
f = lambda x: coordinate_in_path(x['latitude'],x['longitude'],p)
df['inpolygon'] = df.apply(f,axis=1)
if maxmin=='max':
b = (~df['inpolygon']).shift(-1)+df['inpolygon']
else:
b = (~df['inpolygon']).shift(1)+df['inpolygon']
if len(df[b==2]):
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
raise InvalidTrajectoryError("Trajectory doesn't go through path")
return 0
def crewnerdcourse(doc): def crewnerdcourse(doc):
courses = [] courses = []
@@ -198,63 +167,6 @@ def createcourse(
return c return c
def coursetime_first(data,paths):
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
try:
entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max')
coursecompleted = True
except InvalidTrajectoryError:
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
return entrytime, entrydistance, coursecompleted
def coursetime_paths(data,paths,finalmaxmin='min'):
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
# corner case - empty list of paths
if len(paths) == 0:
return 0,True
# end - just the Finish polygon
if len(paths) == 1:
try:
(
entrytime,
entrydistance
) = time_in_path(data,paths[0],maxmin=finalmaxmin)
coursecompleted = True
except InvalidTrajectoryError:
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
return entrytime,entrydistance,coursecompleted
if len(paths) > 1:
try:
time,dist = time_in_path(data, paths[0])
data = data[data['time']>time]
data['time'] = data['time']-time
data['cum_dist'] = data['cum_dist']-dist
(
timenext,
distnext,
coursecompleted
) = coursetime_paths(data,paths[1:])
return time+timenext, dist+distnext,coursecompleted
except InvalidTrajectoryError:
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
return entrytime, entrydistance, coursecompleted
def get_time_course(ws,course): def get_time_course(ws,course):
coursetimeseconds = 0.0 coursetimeseconds = 0.0

96
rowers/courseutils.py Normal file
View File

@@ -0,0 +1,96 @@
# low level methods
def coordinate_in_path(latitude,longitude, p):
return p.contains_points([(latitude,longitude)])[0]
class InvalidTrajectoryError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
return repr(self.value)
def time_in_path(df,p,maxmin='max'):
if df.empty:
return 0
latitude = df.latitude
longitude = df.longitude
f = lambda x: coordinate_in_path(x['latitude'],x['longitude'],p)
df['inpolygon'] = df.apply(f,axis=1)
if maxmin=='max':
b = (~df['inpolygon']).shift(-1)+df['inpolygon']
else:
b = (~df['inpolygon']).shift(1)+df['inpolygon']
if len(df[b==2]):
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
raise InvalidTrajectoryError("Trajectory doesn't go through path")
return 0
def coursetime_first(data,paths):
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
try:
entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max')
coursecompleted = True
except InvalidTrajectoryError:
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
return entrytime, entrydistance, coursecompleted
def coursetime_paths(data,paths,finalmaxmin='min'):
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
# corner case - empty list of paths
if len(paths) == 0:
return 0,True
# end - just the Finish polygon
if len(paths) == 1:
try:
(
entrytime,
entrydistance
) = time_in_path(data,paths[0],maxmin=finalmaxmin)
coursecompleted = True
except InvalidTrajectoryError:
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
return entrytime,entrydistance,coursecompleted
if len(paths) > 1:
try:
time,dist = time_in_path(data, paths[0])
data = data[data['time']>time]
data['time'] = data['time']-time
data['cum_dist'] = data['cum_dist']-dist
(
timenext,
distnext,
coursecompleted
) = coursetime_paths(data,paths[1:])
return time+timenext, dist+distnext,coursecompleted
except InvalidTrajectoryError:
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
return entrytime, entrydistance, coursecompleted

View File

@@ -376,9 +376,7 @@ def polygon_to_path(polygon):
return p return p
def coordinate_in_path(latitude,longitude, p): from rowers.courseutils import coordinate_in_path
return p.contains_points([(latitude,longitude)])[0]
def course_spline(coordinates): def course_spline(coordinates):
latitudes = coordinates['latitude'].values latitudes = coordinates['latitude'].values
@@ -1577,6 +1575,14 @@ class VirtualRaceResult(models.Model):
age = models.IntegerField(null=True) age = models.IntegerField(null=True)
class CourseTestResult(models.Model):
userid = models.IntegerField(default=0)
workoutid = models.IntegerField(null=True)
plannedsession = models.ForeignKey(PlannedSession)
duration = models.TimeField(default=datetime.time(1,0))
distance = models.IntegerField(default=0)
coursecompleted = models.BooleanField(default=False)
class VirtualRaceResultForm(ModelForm): class VirtualRaceResultForm(ModelForm):
class Meta: class Meta:
model = VirtualRaceResult model = VirtualRaceResult

View File

@@ -1,6 +1,7 @@
# Python # Python
from django.utils import timezone from django.utils import timezone
from datetime import datetime from datetime import datetime
import datetime as dt
from datetime import timedelta from datetime import timedelta
from datetime import date from datetime import date
import time import time
@@ -18,7 +19,7 @@ queuehigh = django_rq.get_queue('low')
from rowers.models import ( from rowers.models import (
Rower, Workout,Team, Rower, Workout,Team,
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle, GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
TrainingPlan,PlannedSession,VirtualRaceResult TrainingPlan,PlannedSession,VirtualRaceResult,CourseTestResult
) )
import metrics import metrics
@@ -26,6 +27,8 @@ import numpy as np
import dataprep import dataprep
import courses import courses
from rowers.tasks import handle_check_race_course
# Low Level functions - to be called by higher level methods # Low Level functions - to be called by higher level methods
def add_workouts_plannedsession(ws,ps,r): def add_workouts_plannedsession(ws,ps,r):
result = 0 result = 0
@@ -59,6 +62,17 @@ def add_workouts_plannedsession(ws,ps,r):
w.save() w.save()
result += 1 result += 1
comments.append('Attached workout %i to session' % w.id) comments.append('Attached workout %i to session' % w.id)
if ps.sessiontype == 'coursetest':
record = CourseTestResult(
userid=w.user.id,
plannedsession=ps,
duration=dt.time(0,0),
coursecompleted=False,
)
record.save()
job = myqueue(queue,handle_check_race_course,w.csvfilename,
w.id,ps.course.id,record.id,
mode='coursetest')
else: else:
errors.append('Workout %i did not match session dates' % w.id) errors.append('Workout %i did not match session dates' % w.id)
@@ -271,7 +285,68 @@ def is_session_complete_ws(ws,ps):
if not completiondate: if not completiondate:
completiondate = ws.reverse()[0].date completiondate = ws.reverse()[0].date
return ratio,'partial',completiondate return ratio,'partial',completiondate
elif ps.sessiontype in ['coursetest','race']: elif ps.sessiontype == 'race':
vs = VirtualRaceResult.objects.filter(race=ps)
wids = [w.id for w in ws]
for record in vs:
if record.workoutid in wids:
if record.coursecompleted:
ratio = record.distance/ps.sessionvalue
return ratio,'completed',completiondate
if ps.course:
(
coursetime,
coursemeters,
coursecompleted
) = courses.get_time_course(ws,ps.course)
if coursecompleted:
return 1.0,'completed',completiondate
else:
return ratio,'partial',completiondate
else:
if ps.criterium == 'exact':
if ratio == 1.0:
return ratio,'completed',completiondate
else:
if not completiondate:
completiondate = ws.reverse()[0].date
return ratio,'partial',completiondate
elif ps.criterium == 'minimum':
if ratio >= 1.0:
return ratio,'completed',completiondate
else:
if not completiondate:
completiondate = ws.reverse()[0].date
return ratio,'partial',completiondate
else:
if ratio>cratiomin and ratio<cratiomax:
return ratio,'completed',completiondate
else:
return ratio,'partial',completiondate
elif ps.sessiontype == 'coursetest':
vs = CourseTestResult.objects.filter(plannedsession=ps)
wids = [w.id for w in ws]
for record in vs:
if record.workoutid in wids:
if record.coursecompleted:
ratio = record.distance/ps.sessionvalue
return ratio,'completed',completiondate
# we're still here - no record, need to create one
if ws:
record = CourseTestResult(
userid=ws[0].user.id,
plannedsession=ps,
duration=dt.time(0,0),
coursecompleted=False,
)
record.save()
job = myqueue(queue,handle_check_race_course,ws[0].csvfilename,
ws[0].id,ps.course.id,record.id,
mode='coursetest')
if ps.course: if ps.course:
( (
coursetime, coursetime,
@@ -660,11 +735,11 @@ def add_workout_race(ws,race,r):
dates = [w.date for w in ws] dates = [w.date for w in ws]
if (not all(d == dates[0] for d in dates)) and race.sessiontype not in ['challenge','cycletarget']: 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') errors.append('For tests and training sessions, selected workouts must all be done on the same date')
return result,comments,errors return result,comments,errors,0
if len(ws)>1 and race.sessiontype == 'test': if len(ws)>1 and race.sessiontype == 'test':
errors.append('For tests, you can only attach one workout') errors.append('For tests, you can only attach one workout')
return result,comments,errors return result,comments,errors,0
@@ -673,7 +748,7 @@ def add_workout_race(ws,race,r):
if len(ids)>1 and race.sessiontype in ['test','coursetest','race']: if len(ids)>1 and race.sessiontype in ['test','coursetest','race']:
errors.append('For tests, you can only attach one workout') errors.append('For tests, you can only attach one workout')
return result,comments,errors return result,comments,errors,0
# start adding sessions # start adding sessions
for w in ws: for w in ws:
@@ -682,10 +757,9 @@ def add_workout_race(ws,race,r):
w.save() w.save()
result += 1 result += 1
comments.append('Your result has been submitted')
else: else:
errors.append('Workout %i did not match the race window' % w.id) errors.append('Workout %i did not match the race window' % w.id)
return result,comments,errors return result,comments,errors,0
if result>0: if result>0:
username = r.user.first_name+' '+r.user.last_name username = r.user.first_name+' '+r.user.last_name
@@ -693,16 +767,6 @@ def add_workout_race(ws,race,r):
age = calculate_age(r.birthdate) age = calculate_age(r.birthdate)
else: else:
age = None 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')
return result,comments,errors
duration = totaltime_sec_to_string(coursetime)
records = VirtualRaceResult.objects.filter( records = VirtualRaceResult.objects.filter(
userid=r.id, userid=r.id,
@@ -713,22 +777,20 @@ def add_workout_race(ws,race,r):
if ws[0].boattype != record.boattype: if ws[0].boattype != record.boattype:
errors.append('Your workout boat type did not match the boat type you registered') errors.append('Your workout boat type did not match the boat type you registered')
return result,comments,errors return result,comments,errors,0
if ws[0].weightcategory != record.weightcategory: if ws[0].weightcategory != record.weightcategory:
errors.append('Your workout weight category did not match the weight category you registered') errors.append('Your workout weight category did not match the weight category you registered')
return result,comments, errors return result,comments, errors,0
record.coursecompleted=coursecompleted
record.distance = int(coursemeters) job = myqueue(queue,handle_check_race_course,ws[0].csvfilename,
record.workoutid=ws[0].id ws[0].id,race.course.id,record.id)
record.duration = duration
record.save()
add_workouts_plannedsession(ws,race,r) add_workouts_plannedsession(ws,race,r)
return result,comments,errors return result,comments,errors,job.id
def delete_race_result(workout,race): def delete_race_result(workout,race):
results = VirtualRaceResult.objects.filter(workoutid=workout.id,race=race) results = VirtualRaceResult.objects.filter(workoutid=workout.id,race=race)

View File

@@ -12,6 +12,8 @@ from scipy import optimize
import rowingdata import rowingdata
from rowingdata import rowingdata as rdata from rowingdata import rowingdata as rdata
from datetime import timedelta
from sqlalchemy import create_engine
from celery import app from celery import app
import datetime import datetime
@@ -21,6 +23,7 @@ import iso8601
from matplotlib.backends.backend_agg import FigureCanvas from matplotlib.backends.backend_agg import FigureCanvas
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas #from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib import path
from rowsandall_app.settings import SITE_URL from rowsandall_app.settings import SITE_URL
from rowsandall_app.settings_dev import SITE_URL as SITE_URL_DEV from rowsandall_app.settings_dev import SITE_URL as SITE_URL_DEV
@@ -41,7 +44,8 @@ from rowers.dataprepnodjango import (
getsmallrowdata_db, updatecpdata_sql, getsmallrowdata_db, updatecpdata_sql,
update_agegroup_db,fitnessmetric_to_sql, update_agegroup_db,fitnessmetric_to_sql,
add_c2_stroke_data_db,totaltime_sec_to_string, add_c2_stroke_data_db,totaltime_sec_to_string,
create_c2_stroke_data_db,update_empower create_c2_stroke_data_db,update_empower,
database_url_debug,database_url,
) )
@@ -66,6 +70,7 @@ siteurl = SITE_URL
# testing task # testing task
from rowers.emails import send_template_email from rowers.emails import send_template_email
from rowers.courseutils import coursetime_paths, coursetime_first
@app.task @app.task
def add(x, y): def add(x, y):
@@ -171,6 +176,149 @@ def getagegrouprecord(age,sex='male',weightcategory='hwt',
return power return power
def polygon_to_path(polygon,debug=True):
pid = polygon[0]
query = 'SELECT "rowers_geopoint"."id", "rowers_geopoint"."latitude", "rowers_geopoint"."longitude" FROM "rowers_geopoint" WHERE "rowers_geopoint"."polygon_id" = {pid} ORDER BY "rowers_geopoint"."order_in_poly" ASC'.format(
pid=pid
)
if debug:
engine = create_engine(database_url_debug, echo=False)
else:
engine = create_engine(database_url, echo=False)
with engine.connect() as conn, conn.begin():
result = conn.execute(query)
points = result.fetchall()
conn.close()
engine.dispose()
s = []
for point in points:
s.append([point[1],point[2]])
p = path.Path(s[:-1])
return p
@app.task(bind=True)
def handle_check_race_course(self,
f1,workoutid,courseid,
recordid,**kwargs):
if 'debug' in kwargs:
debug = kwargs['debug']
else:
debug = False
mode = 'race'
if 'mode' in kwargs:
mode = kwargs['mode']
columns = ['time',' latitude',' longitude','cum_dist']
try:
row = rdata(csvfile=f1)
except IOError:
try:
row = rdata(f1 + '.csv')
except IOError:
try:
row = rdata(f1 + '.gz')
except IOError:
return 0
rowdata = row.df
rowdata.rename(columns = {
' latitude':'latitude',
' longitude':'longitude',
' ElapsedTime (sec)': 'time',
}, inplace=True)
rowdata.fillna(method='backfill',inplace=True)
rowdata['time'] = rowdata['time']-rowdata.ix[0,'time']
# we may want to expand the time (interpolate)
rowdata['dt'] = rowdata['time'].apply(
lambda x: timedelta(seconds=x)
)
rowdata = rowdata.resample('100ms',on='dt').mean()
rowdata = rowdata.interpolate()
# initiate database engine
if debug:
engine = create_engine(database_url_debug, echo=False)
else:
engine = create_engine(database_url, echo=False)
# get polygons
query = 'SELECT "rowers_geopolygon"."id" FROM "rowers_geopolygon" WHERE "rowers_geopolygon"."course_id" = {courseid} ORDER BY "rowers_geopolygon"."order_in_course" ASC'.format(
courseid=courseid
)
with engine.connect() as conn, conn.begin():
try:
result = conn.execute(query)
polygons = result.fetchall()
except:
print "Database locked"
conn.close()
engine.dispose()
paths = []
for polygon in polygons:
path = polygon_to_path(polygon,debug=debug)
paths.append(path)
(
coursetimeseconds,
coursemeters,
coursecompleted,
) = coursetime_paths(rowdata,paths)
(
coursetimefirst,
coursemetersfirst,
firstcompleted
) = coursetime_first(
rowdata,paths)
coursetimeseconds = coursetimeseconds-coursetimefirst
coursemeters = coursemeters-coursemetersfirst
if coursecompleted:
query = 'UPDATE "rowers_virtualraceresult" SET "coursecompleted" = 1, "duration" = "{duration}", "distance" = {distance}, "workoutid" = {workoutid} WHERE "id"="{recordid}"'.format(
recordid=recordid,
duration=totaltime_sec_to_string(coursetimeseconds),
distance=int(coursemeters),
workoutid=workoutid,
)
if mode == 'coursetest':
query = 'UPDATE "rowers_coursetestresult" SET "coursecompleted" = 1, "duration" = "{duration}", "distance" = {distance}, "workoutid" = {workoutid} WHERE "id"="{recordid}"'.format(
recordid=recordid,
duration=totaltime_sec_to_string(coursetimeseconds),
distance=int(coursemeters),
workoutid=workoutid,
)
with engine.connect() as conn, conn.begin():
result = conn.execute(query)
conn.close()
engine.dispose()
return 1
else:
return 2
return 0
@app.task(bind=True) @app.task(bind=True)
def handle_getagegrouprecords(self, def handle_getagegrouprecords(self,
@@ -287,8 +435,6 @@ def handle_update_empower(self,
boattype = workoutdict['boattype'] boattype = workoutdict['boattype']
f1 = workoutdict['filename'] f1 = workoutdict['filename']
print wid
# oarlength consistency checks will be done in view # oarlength consistency checks will be done in view
havedata = 1 havedata = 1

View File

@@ -115,6 +115,7 @@
<td> {{ ps.startdate|date:"Y-m-d" }} </td> <td> {{ ps.startdate|date:"Y-m-d" }} </td>
<td> {{ ps.enddate|date:"Y-m-d" }} </td> <td> {{ ps.enddate|date:"Y-m-d" }} </td>
<td> <td>
{% if ps.sessiontype != 'race' %}
{% if ps.name != '' %} {% if ps.name != '' %}
<a class="small" <a class="small"
href="/rowers/sessions/{{ ps.id }}/{{ timeperiod }}/rower/{{ rower.id }}">{{ ps.name }}</a> href="/rowers/sessions/{{ ps.id }}/{{ timeperiod }}/rower/{{ rower.id }}">{{ ps.name }}</a>
@@ -122,6 +123,15 @@
<a class="small" <a class="small"
href="/rowers/sessions/{{ ps.id }}/{{ timeperiod }}/rower/{{ rower.id }}">Unnamed Session</a> href="/rowers/sessions/{{ ps.id }}/{{ timeperiod }}/rower/{{ rower.id }}">Unnamed Session</a>
{% endif %} {% endif %}
{% else %}
{% if ps.name != '' %}
<a class="small"
href="/rowers/virtualevent/{{ ps.id }}">{{ ps.name }}</a>
{% else %}
<a class="small"
href="/rowers/virtualevent/{{ ps.id }}">Unnamed Race</a>
{% endif %}
{% endif %}
</td> </td>
<td> {{ ps.get_sessiontype_display }} </td> <td> {{ ps.get_sessiontype_display }} </td>
<td> {{ ps.get_sessionmode_display }} </td> <td> {{ ps.get_sessionmode_display }} </td>

View File

@@ -4,6 +4,10 @@
{% block title %}Rowsandall Virtual Race{% endblock %} {% block title %}Rowsandall Virtual Race{% endblock %}
{% block scripts %}
{% include "monitorjobs.html" %}
{% endblock %}
{% block content %} {% block content %}
<div class="grid_12 alpha"> <div class="grid_12 alpha">

View File

@@ -1,3 +1,4 @@
import time import time
import colorsys import colorsys
import timestring import timestring
@@ -371,6 +372,7 @@ verbose_job_status = {
'long_test_task': 'Long Test Task', 'long_test_task': 'Long Test Task',
'long_test_task2': 'Long Test Task 2', 'long_test_task2': 'Long Test Task 2',
'update_empower': 'Correct Empower Inflated Power Bug', 'update_empower': 'Correct Empower Inflated Power Bug',
'submit_race': 'Checking Race Course Result',
} }
def get_job_status(jobid): def get_job_status(jobid):
@@ -12855,6 +12857,9 @@ def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
sps = get_sessions(r,startdate=startdate,enddate=enddate) sps = get_sessions(r,startdate=startdate,enddate=enddate)
for ps in sps:
print ps.name,ps.sessiontype
completeness = {} completeness = {}
actualvalue = {} actualvalue = {}
completiondate = {} completiondate = {}
@@ -13185,7 +13190,7 @@ def plannedsession_view(request,id=0,rowerid=0,
ws = get_workouts_session(r,ps) ws = get_workouts_session(r,ps)
ratio,status,completiondate = is_session_complete(r,ps) ratio,status,completiondate = is_session_complete(r,ps)
ratio = int(100.*ratio) ratio = int(100.*ratio)
# ranking for test # ranking for test
@@ -13212,19 +13217,34 @@ def plannedsession_view(request,id=0,rowerid=0,
'type': w.workouttype, 'type': w.workouttype,
} }
if ps.sessiontype == 'coursetest': if ps.sessiontype == 'coursetest':
( vs = CourseTestResult.objects.filter(plannedsession=ps)
coursetimeseconds, if vs:
coursemeters, for record in vs:
coursecompleted if record.workoutid == w.id:
) = courses.get_time_course([w],ps.course) coursemeters = record.distance
intsecs = int(coursetimeseconds) coursecompleted = record.coursecompleted
microsecs = int(1.e6*(coursetimeseconds-intsecs)) t = record.duration
wdict['time'] = datetime.timedelta(
hours=t.hour,
seconds=t.second,
minutes=t.minute,
microseconds=t.microsecond
)
wdict['distance'] = int(round(coursemeters))
else:
(
coursetimeseconds,
coursemeters,
coursecompleted
) = courses.get_time_course([w],ps.course)
intsecs = int(coursetimeseconds)
microsecs = int(1.e6*(coursetimeseconds-intsecs))
wdict['time'] = datetime.timedelta( wdict['time'] = datetime.timedelta(
seconds=intsecs, seconds=intsecs,
microseconds=microsecs microseconds=microsecs
) )
wdict['distance'] = int(round(coursemeters)) wdict['distance'] = int(round(coursemeters))
ranking.append(wdict) ranking.append(wdict)
@@ -13629,7 +13649,7 @@ def virtualevent_create_view(request):
end_time=end_time, end_time=end_time,
course=geocourse, course=geocourse,
comment=comment, comment=comment,
sessiontype = 'coursetest', sessiontype = 'race',
timezone=timezone_str, timezone=timezone_str,
evaluation_closure=evaluation_closure, evaluation_closure=evaluation_closure,
registration_closure=registration_closure, registration_closure=registration_closure,
@@ -13788,13 +13808,21 @@ def virtualevent_submit_result_view(request,id=0):
workouts = Workout.objects.filter(id=selectedworkout) workouts = Workout.objects.filter(id=selectedworkout)
result,comments,errors = add_workout_race(workouts,race,r) result,comments,errors,jobid = add_workout_race(workouts,race,r)
for c in comments: for c in comments:
messages.info(request,c) messages.info(request,c)
for er in errors: for er in errors:
messages.error(request,er) messages.error(request,er)
if jobid:
try:
request.session['async_tasks'] += [(jobid,'submit_race')]
except KeyError:
request.session['async_tasks'] = [(jobid,'submit_race')]
messages.info(request,"We are evaluating your result. The page will reload when we're done. Your result will show up if you adhered to the course")
# redirect to race page # redirect to race page
url = reverse(virtualevent_view, url = reverse(virtualevent_view,
kwargs = { kwargs = {