diff --git a/requirements.txt b/requirements.txt
index d08e1fed..8aba5f9a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -164,7 +164,7 @@ pytest-xdist==1.27.0
python-dateutil==2.8.0
python-memcached==1.59
python-twitter==3.5
-pytz==2018.9
+pytz==2020.1
pyviz-comms==0.7.1
pywin32-ctypes==0.2.0
pywinpty==0.5.5
@@ -173,9 +173,9 @@ pyzmq==18.0.1
qtconsole==4.4.3
ratelim==0.1.6
redis==3.2.1
-requests==2.21.0
+requests==2.23.0
requests-oauthlib==1.2.0
-rowingdata==2.8.4
+rowingdata==2.9.1
rowingphysics==0.5.0
rq==0.13.0
rules==2.1
diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index 02df37f3..d8936ca3 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -381,6 +381,7 @@ def add_workouts_plannedsession(ws,ps,r):
record.save()
job = myqueue(queue,handle_check_race_course,w.csvfilename,
w.id,ps.course.id,record.id,
+ w.user.user.email,w.user.user.first_name,
mode='coursetest')
else:
errors.append('Workout %i did not match session dates' % w.id)
@@ -659,6 +660,7 @@ def is_session_complete_ws(ws,ps):
record.save()
job = myqueue(queue,handle_check_race_course,ws[0].csvfilename,
ws[0].id,ps.course.id,record.id,
+ ws[0].user.user.email,ws[0].user.user.first_name,
mode='coursetest')
return (0,'not done',None)
@@ -1575,7 +1577,9 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0):
comments.append('Workouts submitted to virtual events have to be public. We have changed the workout to a public workout.')
job = myqueue(queue,handle_check_race_course,ws[0].csvfilename,
- ws[0].id,race.course.id,record.id,splitsecond=splitsecond,
+ ws[0].id,race.course.id,record.id,
+ ws[0].user.user.email,ws[0].user.user.first_name,
+ splitsecond=splitsecond,
referencespeed=record.referencespeed,coursedistance=race.course.distance
)
diff --git a/rowers/tasks.py b/rowers/tasks.py
index fcd7bc62..2a5365fc 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -119,7 +119,11 @@ siteurl = SITE_URL
# testing task
from rowers.emails import send_template_email
-from rowers.courseutils import coursetime_paths, coursetime_first, time_in_path
+from rowers.courseutils import (
+ coursetime_paths, coursetime_first, time_in_path,
+ InvalidTrajectoryError
+ )
+
@app.task
def add(x, y):
@@ -342,7 +346,8 @@ def polygon_to_path(polygon,debug=True):
@app.task(bind=True)
def handle_check_race_course(self,
f1,workoutid,courseid,
- recordid,**kwargs):
+ recordid,useremail,userfirstname,
+ **kwargs):
if 'debug' in kwargs:
debug = kwargs['debug']
@@ -431,8 +436,19 @@ def handle_check_race_course(self,
path = polygon_to_path(polygon,debug=debug)
paths.append(path)
+ startsecond = 0
+ endsecond = rowdata['time'].max()
+
# check how many times went through start polygon
- entrytimes,entrydistances = time_in_path(rowdata,paths[0],maxmin='max',getall=True)
+ try:
+ entrytimes,entrydistances = time_in_path(rowdata,paths[0],maxmin='max',getall=True)
+ except InvalidTrajectoryError:
+ entrytimes = []
+ entrydistances = []
+ coursecompleted = False
+ coursemeters = 0
+ coursetimeseconds = 0
+
cseconds = []
cmeters = []
@@ -528,6 +544,39 @@ def handle_check_race_course(self,
return 1
else:
+ query = 'UPDATE rowers_virtualraceresult SET coursecompleted = 0, duration = "{duration}", distance = {distance}, workoutid = {workoutid}, startsecond = {startsecond}, endsecond = {endsecond}, points={points} WHERE id={recordid}'.format(
+ recordid=recordid,
+ duration=totaltime_sec_to_string(0),
+ distance=0,
+ points=0.0,
+ workoutid=workoutid,
+ startsecond=startsecond,
+ endsecond=endsecond,
+ )
+
+ if mode == 'coursetest':
+ query = 'UPDATE rowers_coursetestresult SET coursecompleted = 0, duration = "{duration}", distance = {distance}, workoutid = {workoutid}, startsecond = {startsecond}, endsecond = {endsecond}, points={points} WHERE id={recordid}'.format(
+ recordid=recordid,
+ duration=totaltime_sec_to_string(0),
+ distance=0,
+ points=0,
+ workoutid=workoutid,
+ startsecond=startsecond,
+ endsecond=endsecond,
+ )
+
+
+ with engine.connect() as conn, conn.begin():
+ result = conn.execute(query)
+
+ conn.close()
+ engine.dispose()
+
+ # send email
+ handle_sendemail_coursefail(
+ useremail,userfirstname,
+ )
+
return 2
return 0
@@ -1118,6 +1167,29 @@ def handle_sendemail_raceregistration(
return 1
+def handle_sendemail_coursefail(
+ useremail, username, **kwargs):
+
+ if 'debug' in kwargs:
+ debug = kwargs['debug']
+ else:
+ debug = True
+
+ subject = "The validation of your course has failed"
+
+ from_email = 'Rowsandall Dear {{ username }},
+ Unfortunately, the course you took did not go through all gates for
+ the virtual challenge.
+ You can check your course versus the gates by clicking on Details
+ in your challenge result.
+ Of course, you can always submit a new row!
+
+ If you feel that your course should have been valid, or in case
+ you have questions, please
+ contact me by reply to this email.
+
+ Best Regards, the Rowsandall Team
+Results
{% endif %}
| Time▼ | -Distance▼ | +Distance▼▲ | {% if race.coursestandards %}Points▼ | {% endif %} @@ -349,11 +349,16 @@ {% endfor %} - {% for result in dns %} + {% for result in dnf %}|||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{ result.username }} | {{ result.teamname }} | + {% if race.coursestandards %} +{{ result.entrycategory }} | +DNF | +DNF | + {% else %}{{ result.age }} | {{ result.sex }} | {{ result.weightcategory }} | @@ -368,6 +373,39 @@ {% if race.sessiontype == 'race' %}{{ result.boattype }} | {% endif %} + {% endif %} +DNF | ++ + Details + | +||
| + | {{ result.username }} | +{{ result.teamname }} | + {% if race.coursestandards %} +{{ result.entrycategory }} | +DNS | +DNS | + {% else %} +{{ result.age }} | +{{ result.sex }} | +{{ result.weightcategory }} | ++ {% if result.adaptiveclass == 'None' %} + + {% else %} + {{ result.adaptiveclass }} + {% endif %} + | +{{ result.boatclass }} | + {% if race.sessiontype == 'race' %} +{{ result.boattype }} | + {% endif %} + {% endif %}DNS |
| + | {{ result.username }} | +{{ result.teamname }} | +{{ result.age }} | +{{ result.sex }} | +{{ result.weightcategory }} | ++ {% if result.adaptiveclass == 'None' %} + + {% else %} + {{ result.adaptiveclass }} + {% endif %} + | +{{ result.boatclass }} | + {% if race.sessiontype == 'race' %} +{{ result.boattype }} | + {% endif %} ++ + Details + | +DNF | +
| diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index f596d83a..f30b51b9 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -1956,7 +1956,9 @@ def plannedsession_view(request,id=0,userid=0): record.save() job = myqueue(queue,handle_check_race_course, w.csvfilename,w.id,ps.course.id, - record.id,mode='coursetest') + record.id, + w.user.user.email,w.user.user.first_name, + mode='coursetest') intsecs = 0 microsecs = 0 diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index 1f6f4a33..7d2e2dcf 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -1072,6 +1072,12 @@ def virtualevent_view(request,id=0): workoutid__isnull=True, ) + dnf = resultobj.objects.filter( + race=race, + workoutid__isnull=False, + coursecompleted=False, + ) + if not request.user.is_anonymous: if race_can_register(r,race): @@ -1143,6 +1149,7 @@ def virtualevent_view(request,id=0): adaptiveclass__in=adaptiveclass, age__gte=age_min, age__lte=age_max, + coursecompleted=True, ).order_by("duration") else: results = resultobj.objects.filter( @@ -1154,6 +1161,7 @@ def virtualevent_view(request,id=0): adaptiveclass__in=adaptiveclass, age__gte=age_min, age__lte=age_max, + coursecompleted=True, ).order_by("duration","-distance") if entrycategory is not None: @@ -1179,6 +1187,8 @@ def virtualevent_view(request,id=0): coursecompleted=True, ).order_by("duration","-distance") + + if results: form = RaceResultFilterForm(records=records) else: @@ -1221,6 +1231,7 @@ def virtualevent_view(request,id=0): 'results':results, 'buttons':buttons, 'dns':dns, + 'dnf':dnf, 'records':records, 'racelogo':racelogo, 'form':form, @@ -1304,6 +1315,12 @@ def virtualevent_ranking_view(request,id=0): workoutid__isnull=True, ) + dnf = resultobj.objects.filter( + race=race, + workoutid__isnull=False, + coursecompleted=False, + ) + if not request.user.is_anonymous: if race_can_register(r,race): diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index a407d0e2..43bea2b4 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -1511,7 +1511,6 @@ def virtualevent_mapcompare_view(request,id=0): results = VirtualRaceResult.objects.filter( race=race, workoutid__isnull=False, - coursecompleted=True, ).order_by("distance","duration") workoutids = [result.workoutid for result in results] |