Merge branch 'develop' into feature/py38
This commit is contained in:
@@ -3,6 +3,7 @@ apipkg==1.5
|
|||||||
appdirs==1.4.3
|
appdirs==1.4.3
|
||||||
arcgis==1.6.0
|
arcgis==1.6.0
|
||||||
arrow==0.13.1
|
arrow==0.13.1
|
||||||
|
asgiref==3.2.7
|
||||||
asn1crypto==0.24.0
|
asn1crypto==0.24.0
|
||||||
atomicwrites==1.3.0
|
atomicwrites==1.3.0
|
||||||
attrs==19.1.0
|
attrs==19.1.0
|
||||||
@@ -12,6 +13,8 @@ billiard==3.6.0.0
|
|||||||
bleach==3.1.0
|
bleach==3.1.0
|
||||||
bokeh==1.0.4
|
bokeh==1.0.4
|
||||||
boto==2.49.0
|
boto==2.49.0
|
||||||
|
boto3==1.14.7
|
||||||
|
botocore==1.17.7
|
||||||
braintree==3.55.0
|
braintree==3.55.0
|
||||||
cairocffi==1.0.2
|
cairocffi==1.0.2
|
||||||
celery==4.3.0
|
celery==4.3.0
|
||||||
@@ -53,7 +56,7 @@ django-rest-framework==0.1.0
|
|||||||
django-rest-swagger==2.2.0
|
django-rest-swagger==2.2.0
|
||||||
django-rq==1.3.1
|
django-rq==1.3.1
|
||||||
django-rq-dashboard==0.3.3
|
django-rq-dashboard==0.3.3
|
||||||
django-ses==0.8.10
|
django-ses==1.0.0
|
||||||
django-shell-plus==1.1.7
|
django-shell-plus==1.1.7
|
||||||
django-social-share==1.3.2
|
django-social-share==1.3.2
|
||||||
django-suit==0.2.26
|
django-suit==0.2.26
|
||||||
@@ -96,6 +99,7 @@ itypes==1.1.0
|
|||||||
jedi==0.13.3
|
jedi==0.13.3
|
||||||
jeepney==0.4
|
jeepney==0.4
|
||||||
Jinja2==2.10
|
Jinja2==2.10
|
||||||
|
jmespath==0.10.0
|
||||||
json5==0.8.5
|
json5==0.8.5
|
||||||
jsonschema==3.0.1
|
jsonschema==3.0.1
|
||||||
jupyter==1.0.0
|
jupyter==1.0.0
|
||||||
@@ -107,7 +111,7 @@ jupyterlab-server==0.3.0
|
|||||||
keyring==18.0.0
|
keyring==18.0.0
|
||||||
kiwisolver==1.0.1
|
kiwisolver==1.0.1
|
||||||
kombu==4.5.0
|
kombu==4.5.0
|
||||||
llvmlite==0.33.0
|
llvmlite==0.30.0
|
||||||
lxml==4.3.2
|
lxml==4.3.2
|
||||||
Markdown==3.0.1
|
Markdown==3.0.1
|
||||||
MarkupSafe==1.1.1
|
MarkupSafe==1.1.1
|
||||||
@@ -148,7 +152,7 @@ protobuf==3.11.1
|
|||||||
psycopg2==2.8.1
|
psycopg2==2.8.1
|
||||||
ptyprocess==0.6.0
|
ptyprocess==0.6.0
|
||||||
py==1.8.0
|
py==1.8.0
|
||||||
pyarrow==0.17.1
|
pyarrow==0.15.0
|
||||||
pycairo==1.19.0
|
pycairo==1.19.0
|
||||||
pycparser==2.19
|
pycparser==2.19
|
||||||
Pygments==2.3.1
|
Pygments==2.3.1
|
||||||
@@ -179,6 +183,7 @@ rowingdata==2.9.1
|
|||||||
rowingphysics==0.5.0
|
rowingphysics==0.5.0
|
||||||
rq==0.13.0
|
rq==0.13.0
|
||||||
rules==2.1
|
rules==2.1
|
||||||
|
s3transfer==0.3.3
|
||||||
scipy==1.2.1
|
scipy==1.2.1
|
||||||
SecretStorage==3.1.1
|
SecretStorage==3.1.1
|
||||||
Send2Trash==1.5.0
|
Send2Trash==1.5.0
|
||||||
@@ -188,7 +193,7 @@ simplejson==3.16.0
|
|||||||
six==1.12.0
|
six==1.12.0
|
||||||
soupsieve==1.8
|
soupsieve==1.8
|
||||||
SQLAlchemy==1.3.1
|
SQLAlchemy==1.3.1
|
||||||
sqlparse==0.3.0
|
sqlparse==0.3.1
|
||||||
stravalib==0.10.2
|
stravalib==0.10.2
|
||||||
termcolor==1.1.0
|
termcolor==1.1.0
|
||||||
terminado==0.8.1
|
terminado==0.8.1
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from __future__ import absolute_import
|
|||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ class InvalidTrajectoryError(Exception):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
def time_in_path(df,p,maxmin='max',getall=False):
|
def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None):
|
||||||
|
|
||||||
if df.empty:
|
if df.empty:
|
||||||
return 0
|
return 0
|
||||||
@@ -38,25 +38,64 @@ def time_in_path(df,p,maxmin='max',getall=False):
|
|||||||
|
|
||||||
|
|
||||||
if len(df[b==2]):
|
if len(df[b==2]):
|
||||||
|
if logfile is not None:
|
||||||
|
t = time.localtime()
|
||||||
|
timestamp = time.strftime('%b-%d-%Y_%H%M', t)
|
||||||
|
with open(logfile,'a') as f:
|
||||||
|
f.write('\n')
|
||||||
|
f.write(timestamp)
|
||||||
|
f.write(' ')
|
||||||
|
f.write(name)
|
||||||
|
f.write(' ')
|
||||||
|
f.write(maxmin)
|
||||||
|
f.write(' ')
|
||||||
|
f.write(str(getall))
|
||||||
|
f.write(' ')
|
||||||
|
f.write(str(len(df[b==2])))
|
||||||
|
f.write(' ')
|
||||||
|
if len(df[b==2])>1:
|
||||||
|
f.write(' passes found')
|
||||||
|
else:
|
||||||
|
f.write(' pass found')
|
||||||
if getall:
|
if getall:
|
||||||
return df[b==2]['time'],df[b==2]['cum_dist']
|
return df[b==2]['time'],df[b==2]['cum_dist']
|
||||||
else:
|
else:
|
||||||
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
|
return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
|
||||||
|
|
||||||
|
if logfile is not None:
|
||||||
|
t = time.localtime()
|
||||||
|
timestamp = time.strftime('%b-%d-%Y_%H%M', t)
|
||||||
|
with open(logfile,'a') as f:
|
||||||
|
f.write('\n')
|
||||||
|
f.write(timestamp)
|
||||||
|
f.write(' ')
|
||||||
|
f.write(name)
|
||||||
|
f.write(' ')
|
||||||
|
f.write(maxmin)
|
||||||
|
f.write(' ')
|
||||||
|
f.write(str(getall))
|
||||||
|
f.write(' ')
|
||||||
|
f.write(str(len(df[b==2])))
|
||||||
|
f.write(' ')
|
||||||
|
f.write(' pass not found')
|
||||||
raise InvalidTrajectoryError("Trajectory doesn't go through path")
|
raise InvalidTrajectoryError("Trajectory doesn't go through path")
|
||||||
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def coursetime_first(data,paths):
|
def coursetime_first(data,paths,polygons=[],logfile=None):
|
||||||
|
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
entrydistance = data['cum_dist'].max()
|
entrydistance = data['cum_dist'].max()
|
||||||
coursecompleted = False
|
coursecompleted = False
|
||||||
|
|
||||||
|
if len(polygons) == 0:
|
||||||
|
polygons = [(0,str(i)) for i in range(len(paths))]
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max')
|
entrytime,entrydistance = time_in_path(data,paths[0],maxmin='max',name=polygons[0][1],logfile=logfile)
|
||||||
coursecompleted = True
|
coursecompleted = True
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError:
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
@@ -64,12 +103,15 @@ def coursetime_first(data,paths):
|
|||||||
coursecompleted = False
|
coursecompleted = False
|
||||||
return entrytime, entrydistance, coursecompleted
|
return entrytime, entrydistance, coursecompleted
|
||||||
|
|
||||||
def coursetime_paths(data,paths,finalmaxmin='min'):
|
def coursetime_paths(data,paths,finalmaxmin='min',polygons=[],logfile=None):
|
||||||
|
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
entrydistance = data['cum_dist'].max()
|
entrydistance = data['cum_dist'].max()
|
||||||
coursecompleted = False
|
coursecompleted = False
|
||||||
|
|
||||||
|
if len(polygons) == 0:
|
||||||
|
polygons = [(0,str(i)) for i in range(len(paths))]
|
||||||
|
|
||||||
# corner case - empty list of paths
|
# corner case - empty list of paths
|
||||||
if len(paths) == 0:
|
if len(paths) == 0:
|
||||||
return 0,True
|
return 0,True
|
||||||
@@ -80,7 +122,7 @@ def coursetime_paths(data,paths,finalmaxmin='min'):
|
|||||||
(
|
(
|
||||||
entrytime,
|
entrytime,
|
||||||
entrydistance
|
entrydistance
|
||||||
) = time_in_path(data,paths[0],maxmin=finalmaxmin)
|
) = time_in_path(data,paths[0],maxmin=finalmaxmin,name = polygons[0][1],logfile=logfile)
|
||||||
coursecompleted = True
|
coursecompleted = True
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError:
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
@@ -90,7 +132,7 @@ def coursetime_paths(data,paths,finalmaxmin='min'):
|
|||||||
|
|
||||||
if len(paths) > 1:
|
if len(paths) > 1:
|
||||||
try:
|
try:
|
||||||
time,dist = time_in_path(data, paths[0])
|
time,dist = time_in_path(data, paths[0],name=polygons[0][1],logfile=logfile)
|
||||||
data = data[data['time']>time]
|
data = data[data['time']>time]
|
||||||
data['time'] = data['time']-time
|
data['time'] = data['time']-time
|
||||||
data['cum_dist'] = data['cum_dist']-dist
|
data['cum_dist'] = data['cum_dist']-dist
|
||||||
@@ -98,7 +140,7 @@ def coursetime_paths(data,paths,finalmaxmin='min'):
|
|||||||
timenext,
|
timenext,
|
||||||
distnext,
|
distnext,
|
||||||
coursecompleted
|
coursecompleted
|
||||||
) = coursetime_paths(data,paths[1:])
|
) = coursetime_paths(data,paths[1:],polygons=polygons[1:],logfile=logfile)
|
||||||
return time+timenext, dist+distnext,coursecompleted
|
return time+timenext, dist+distnext,coursecompleted
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError:
|
||||||
entrytime = data['time'].max()
|
entrytime = data['time'].max()
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ from django.contrib.staticfiles import finders
|
|||||||
|
|
||||||
|
|
||||||
def textify(html):
|
def textify(html):
|
||||||
# Remove html tags and continuous whitespaces
|
# Remove html tags and continuous whitespaces
|
||||||
text_only = re.sub('[ \t]+', ' ', strip_tags(html))
|
text_only = re.sub('[ \t]+', ' ', strip_tags(html))
|
||||||
# Strip single spaces in the beginning of each line
|
# Strip single spaces in the beginning of each line
|
||||||
return text_only.replace('\n ', '\n').strip()
|
return text_only.replace('\n ', '\n').strip()
|
||||||
@@ -61,7 +61,7 @@ def textify(html):
|
|||||||
def htmlstripnobr(html):
|
def htmlstripnobr(html):
|
||||||
safe_html = re.sub('[ \t]+', ' ', strip_tags(html))
|
safe_html = re.sub('[ \t]+', ' ', strip_tags(html))
|
||||||
return safe_html
|
return safe_html
|
||||||
|
|
||||||
def htmlstrip(html):
|
def htmlstrip(html):
|
||||||
safe_html = re.sub('[ \t]+', ' ', strip_tags(html))
|
safe_html = re.sub('[ \t]+', ' ', strip_tags(html))
|
||||||
return newlinetobr(safe_html)
|
return newlinetobr(safe_html)
|
||||||
@@ -80,11 +80,17 @@ def send_template_email(from_email,to_email,subject,
|
|||||||
text_content = textify(html_content)
|
text_content = textify(html_content)
|
||||||
# html_content = newlinetobr(html_content)
|
# html_content = newlinetobr(html_content)
|
||||||
|
|
||||||
if 'cc' in kwargs:
|
|
||||||
|
if 'bcc' in kwargs and 'cc' in kwargs:
|
||||||
|
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email,cc=kwargs['cc'],
|
||||||
|
bcc=kwargs['bcc'])
|
||||||
|
elif 'bcc' in kwargs:
|
||||||
|
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email,bcc=kwargs['bcc'])
|
||||||
|
elif 'cc' in kwargs:
|
||||||
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email,cc=kwargs['cc'])
|
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email,cc=kwargs['cc'])
|
||||||
else:
|
else:
|
||||||
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email)
|
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email)
|
||||||
|
|
||||||
msg.attach_alternative(html_content, "text/html")
|
msg.attach_alternative(html_content, "text/html")
|
||||||
|
|
||||||
if 'attach_file' in kwargs:
|
if 'attach_file' in kwargs:
|
||||||
@@ -106,8 +112,8 @@ def send_template_email(from_email,to_email,subject,
|
|||||||
else:
|
else:
|
||||||
emailbounced = False
|
emailbounced = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not emailbounced:
|
if not emailbounced:
|
||||||
res = msg.send()
|
res = msg.send()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class EmailForm(forms.Form):
|
|||||||
subject = forms.CharField(max_length=255)
|
subject = forms.CharField(max_length=255)
|
||||||
message = forms.CharField(widget=forms.Textarea())
|
message = forms.CharField(widget=forms.Textarea())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
disqualificationreasons = (
|
disqualificationreasons = (
|
||||||
('noimage','No monitor screenshot or data evidence was included'),
|
('noimage','No monitor screenshot or data evidence was included'),
|
||||||
@@ -386,7 +386,7 @@ class UploadOptionsForm(forms.Form):
|
|||||||
makeprivate = forms.BooleanField(initial=False,required=False,
|
makeprivate = forms.BooleanField(initial=False,required=False,
|
||||||
label='Make Workout Private')
|
label='Make Workout Private')
|
||||||
|
|
||||||
submitrace = forms.ModelChoiceField(queryset=VirtualRace.objects.all(),
|
submitrace = forms.ChoiceField(
|
||||||
label='Submit as challenge Result',
|
label='Submit as challenge Result',
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
@@ -404,6 +404,7 @@ class UploadOptionsForm(forms.Form):
|
|||||||
r = Rower.objects.get(user=self.request.user)
|
r = Rower.objects.get(user=self.request.user)
|
||||||
races = VirtualRace.objects.filter(
|
races = VirtualRace.objects.filter(
|
||||||
registration_closure__gt=timezone.now())
|
registration_closure__gt=timezone.now())
|
||||||
|
|
||||||
registrations = IndoorVirtualRaceResult.objects.filter(
|
registrations = IndoorVirtualRaceResult.objects.filter(
|
||||||
race__in = races,
|
race__in = races,
|
||||||
userid = r.id)
|
userid = r.id)
|
||||||
@@ -413,25 +414,41 @@ class UploadOptionsForm(forms.Form):
|
|||||||
userid = r.id,
|
userid = r.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
raceids = [r.race.id for r in registrations]
|
choices1 = [(r.id,str(r)) for r in registrations]
|
||||||
raceids2 = [r.race.id for r in registrations2]
|
choices2 = [(r.id,str(r)) for r in registrations2]
|
||||||
|
choices3 = [(0,'---')]
|
||||||
|
|
||||||
raceids = raceids+raceids2
|
noregistrations = []
|
||||||
|
for ra in VirtualRace.objects.filter(registration_closure__gt=timezone.now(),sessiontype='race'):
|
||||||
|
rs = VirtualRaceResult.objects.filter(race = ra,userid=r.id)
|
||||||
|
if rs.count()==0:
|
||||||
|
noregistrations.append((-ra.id,ra.name))
|
||||||
|
for ra in VirtualRace.objects.filter(registration_closure__gt=timezone.now(),sessiontype='indoorrace'):
|
||||||
|
rs = IndoorVirtualRaceResult.objects.filter(race = ra,userid=r.id)
|
||||||
|
if rs.count()==0:
|
||||||
|
noregistrations.append((-ra.id,ra.name))
|
||||||
|
|
||||||
races = VirtualRace.objects.filter(
|
choices = choices3+choices1+choices2+noregistrations
|
||||||
id__in=raceids
|
|
||||||
)
|
|
||||||
|
|
||||||
|
if int(raceid) in [r.id for r in races]:
|
||||||
|
therace = VirtualRace.objects.get(id=raceid)
|
||||||
|
if therace.sessiontype == 'race':
|
||||||
|
registrations = VirtualRaceResult.objects.filter(race=therace,userid=r.id)
|
||||||
|
else:
|
||||||
|
registrations = IndoorVirtualRaceResult.objects.filter(race=therace,userid=r.id)
|
||||||
|
|
||||||
|
if registrations.count()==0:
|
||||||
|
race = VirtualRace.objects.get(id=raceid)
|
||||||
|
choices = [(-int(raceid),race.name)]
|
||||||
|
else:
|
||||||
|
choices = [(r.id,str(r)) for r in registrations]
|
||||||
|
choices = choices+[(0,'---')]
|
||||||
|
|
||||||
if races:
|
if races:
|
||||||
self.fields['submitrace'].queryset = races
|
self.fields['submitrace'].choices = choices
|
||||||
else:
|
else:
|
||||||
del self.fields['submitrace']
|
del self.fields['submitrace']
|
||||||
|
|
||||||
if int(raceid) in raceids:
|
|
||||||
self.fields['submitrace'].initial = VirtualRace.objects.get(id=raceid)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The form to indicate additional actions to be performed immediately
|
# The form to indicate additional actions to be performed immediately
|
||||||
# after a successful upload. This version allows the Team manager to select
|
# after a successful upload. This version allows the Team manager to select
|
||||||
|
|||||||
@@ -5481,8 +5481,11 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
|
|||||||
else:
|
else:
|
||||||
windowsize = 1
|
windowsize = 1
|
||||||
|
|
||||||
if windowsize >= 3 and windowsize < len(group['y']):
|
if windowsize > 3 and windowsize < len(group['y']):
|
||||||
group['y'] = savgol_filter(group['y'],windowsize,3)
|
try:
|
||||||
|
group['y'] = savgol_filter(group['y'],windowsize,3)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
ylabel = Label(x=100,y=60+nrworkouts*20-20*cntr,
|
ylabel = Label(x=100,y=60+nrworkouts*20-20*cntr,
|
||||||
x_units='screen',y_units='screen',
|
x_units='screen',y_units='screen',
|
||||||
|
|||||||
@@ -2643,7 +2643,11 @@ class VirtualRaceForm(ModelForm):
|
|||||||
enddatetime
|
enddatetime
|
||||||
)
|
)
|
||||||
|
|
||||||
registration_closure = cd['registration_closure']
|
try:
|
||||||
|
registration_closure = cd['registration_closure']
|
||||||
|
except KeyError:
|
||||||
|
registration_closure = enddatetime+datetime.timedelta(days=1)
|
||||||
|
cd['registration_closure'] = registration_closure
|
||||||
|
|
||||||
registration_form = cd['registration_form']
|
registration_form = cd['registration_form']
|
||||||
|
|
||||||
@@ -3120,6 +3124,8 @@ class CourseTestResult(models.Model):
|
|||||||
distance = models.IntegerField(default=0)
|
distance = models.IntegerField(default=0)
|
||||||
coursecompleted = models.BooleanField(default=False)
|
coursecompleted = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IndoorVirtualRaceResultForm(ModelForm):
|
class IndoorVirtualRaceResultForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IndoorVirtualRaceResult
|
model = IndoorVirtualRaceResult
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ from rowers.models import (
|
|||||||
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
|
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
|
||||||
TrainingPlan,PlannedSession,VirtualRaceResult,CourseTestResult,
|
TrainingPlan,PlannedSession,VirtualRaceResult,CourseTestResult,
|
||||||
get_course_timezone, IndoorVirtualRaceResult,VirtualRace,createmacrofillers,
|
get_course_timezone, IndoorVirtualRaceResult,VirtualRace,createmacrofillers,
|
||||||
createmesofillers,createmicrofillers,
|
createmesofillers,createmicrofillers,CourseStandard,
|
||||||
)
|
)
|
||||||
|
|
||||||
from rowers.courses import get_time_course
|
from rowers.courses import get_time_course
|
||||||
@@ -1026,7 +1026,13 @@ def race_can_edit(r,race):
|
|||||||
startdatetime = pytz.timezone(race.timezone).localize(
|
startdatetime = pytz.timezone(race.timezone).localize(
|
||||||
startdatetime
|
startdatetime
|
||||||
)
|
)
|
||||||
if timezone.now()<startdatetime:
|
end_time = race.end_time
|
||||||
|
end_date = race.enddate
|
||||||
|
enddatetime = datetime.combine(end_date,end_time)
|
||||||
|
enddatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
enddatetime
|
||||||
|
)
|
||||||
|
if timezone.now()<enddatetime:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -1035,8 +1041,8 @@ def race_can_edit(r,race):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def race_can_submit(r,race):
|
def race_can_submit(r,race):
|
||||||
if r not in race.rower.all():
|
#if r not in race.rower.all():
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
start_time = race.start_time
|
start_time = race.start_time
|
||||||
start_date = race.startdate
|
start_date = race.startdate
|
||||||
@@ -1335,8 +1341,83 @@ def remove_rower_race(r,race,recordid=None):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def default_class(r,w,race):
|
||||||
|
if r.birthdate:
|
||||||
|
age = calculate_age(r.birthdate)
|
||||||
|
else:
|
||||||
|
age = 25
|
||||||
|
|
||||||
|
sex = r.sex
|
||||||
|
if sex=='not specified':
|
||||||
|
sex='male'
|
||||||
|
|
||||||
|
if w is not None:
|
||||||
|
boatclass = w.workouttype
|
||||||
|
boattype = w.boattype
|
||||||
|
|
||||||
|
adaptiveclass = w.adaptiveclass
|
||||||
|
weightclass = w.weightcategory
|
||||||
|
else:
|
||||||
|
if race.sessiontype == 'race':
|
||||||
|
boatclass = 'water'
|
||||||
|
else:
|
||||||
|
boatclass = 'rower'
|
||||||
|
boattype = '1x'
|
||||||
|
adaptiveclass = 'None'
|
||||||
|
weightclass = 'hwt'
|
||||||
|
|
||||||
|
if race.coursestandards:
|
||||||
|
standards = CourseStandard.objects.filter(
|
||||||
|
agemin__lt=age,agemax__gt=age,
|
||||||
|
boatclass=boatclass,
|
||||||
|
adaptiveclass=adaptiveclass,
|
||||||
|
boattype=boattype,
|
||||||
|
weightclass=weightclass,
|
||||||
|
sex=sex,
|
||||||
|
).order_by("agemax","-agemin","boattype","sex")
|
||||||
|
|
||||||
|
|
||||||
|
if standards.count()==0:
|
||||||
|
# omit weight
|
||||||
|
standards = CourseStandard.objects.filter(
|
||||||
|
agemin__lt=age,agemax__gt=age,
|
||||||
|
boatclass=boatclass,
|
||||||
|
adaptiveclass=adaptiveclass,
|
||||||
|
boattype=boattype,
|
||||||
|
).order_by(
|
||||||
|
"agemax","-agemin","boattype","sex","weightcategory",
|
||||||
|
"referencespeed"
|
||||||
|
)
|
||||||
|
if standards.count()==0:
|
||||||
|
standards = CourseStandard.objects.filter(
|
||||||
|
agemin__lt=age,agemax__gt=age,
|
||||||
|
boattype=boattype
|
||||||
|
).order_by(
|
||||||
|
"agemax","-agemin","boattype","sex",
|
||||||
|
"weightcategory","referencespeed")
|
||||||
|
if standards.count()==0:
|
||||||
|
standards = CourseStandard.objects.filter(
|
||||||
|
agemin__lt=age,agemax__gt=age
|
||||||
|
).order_by(
|
||||||
|
"agemax","-agemin","boattype","sex",
|
||||||
|
"weightcategory","referencespeed")
|
||||||
|
|
||||||
|
if standards.count()==0:
|
||||||
|
# boolean, boattype, boatclass, adaptiveclass, weightclass, sex, coursestandard,
|
||||||
|
return False,'1x','water',None,'hwt','male',None
|
||||||
|
|
||||||
|
if standards.count()>0:
|
||||||
|
# find optimum standard
|
||||||
|
s = standards[0]
|
||||||
|
return True,s.boattype,s.boatclass,s.adaptiveclass,s.weightclass,s.sex,s
|
||||||
|
|
||||||
|
# No Course Standard
|
||||||
|
return True,boattype,boatclass,adaptiveclass,weightclass,sex,None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Low Level functions - to be called by higher level methods
|
# Low Level functions - to be called by higher level methods
|
||||||
def add_workout_indoorrace(ws,race,r,recordid=0):
|
def add_workout_indoorrace(ws,race,r,recordid=0,doregister=False):
|
||||||
result = 0
|
result = 0
|
||||||
comments = []
|
comments = []
|
||||||
errors = []
|
errors = []
|
||||||
@@ -1383,12 +1464,34 @@ def add_workout_indoorrace(ws,race,r,recordid=0):
|
|||||||
else:
|
else:
|
||||||
age = None
|
age = None
|
||||||
|
|
||||||
record = IndoorVirtualRaceResult.objects.get(
|
try:
|
||||||
userid=r.id,
|
record = IndoorVirtualRaceResult.objects.get(
|
||||||
race=race,
|
userid=r.id,
|
||||||
id=recordid
|
race=race,
|
||||||
)
|
id=recordid
|
||||||
|
)
|
||||||
|
except IndoorVirtualRaceResult.DoesNotExist:
|
||||||
|
if doregister:
|
||||||
|
hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,ws[0],race)
|
||||||
|
if hasinitial:
|
||||||
|
record = IndoorVirtualRaceResult(
|
||||||
|
userid = r.id,
|
||||||
|
username = r.user.first_name+' '+r.user.last_name,
|
||||||
|
weightcategory=weightclass,
|
||||||
|
adaptiveclass=adaptiveclass,
|
||||||
|
race=race,
|
||||||
|
boatclass=boatclass,
|
||||||
|
sex=sex,
|
||||||
|
age = age,
|
||||||
|
entrycategory=initialcategory,
|
||||||
|
)
|
||||||
|
record.save()
|
||||||
|
else:
|
||||||
|
errors.append("Unable to find a suitable start category")
|
||||||
|
return result,comments,errors,0
|
||||||
|
else:
|
||||||
|
errors.append("Couldn't find this entry")
|
||||||
|
return result,comments,errors,0
|
||||||
|
|
||||||
records = IndoorVirtualRaceResult.objects.filter(
|
records = IndoorVirtualRaceResult.objects.filter(
|
||||||
userid=r.id,
|
userid=r.id,
|
||||||
@@ -1396,9 +1499,11 @@ def add_workout_indoorrace(ws,race,r,recordid=0):
|
|||||||
workoutid = ws[0].id
|
workoutid = ws[0].id
|
||||||
)
|
)
|
||||||
|
|
||||||
if not record:
|
|
||||||
errors.append("Couldn't find this entry")
|
|
||||||
return result,comments,errors,0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if race.sessionmode == 'distance':
|
if race.sessionmode == 'distance':
|
||||||
if ws[0].distance != race.sessionvalue:
|
if ws[0].distance != race.sessionvalue:
|
||||||
@@ -1465,7 +1570,7 @@ def add_workout_indoorrace(ws,race,r,recordid=0):
|
|||||||
return result,comments,errors,0
|
return result,comments,errors,0
|
||||||
|
|
||||||
|
|
||||||
def add_workout_race(ws,race,r,splitsecond=0,recordid=0):
|
def add_workout_race(ws,race,r,splitsecond=0,recordid=0,doregister=False):
|
||||||
result = 0
|
result = 0
|
||||||
comments = []
|
comments = []
|
||||||
errors = []
|
errors = []
|
||||||
@@ -1511,11 +1616,35 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0):
|
|||||||
else:
|
else:
|
||||||
age = None
|
age = None
|
||||||
|
|
||||||
record = VirtualRaceResult.objects.get(
|
try:
|
||||||
userid=r.id,
|
record = VirtualRaceResult.objects.get(
|
||||||
race=race,
|
userid=r.id,
|
||||||
id=recordid
|
race=race,
|
||||||
)
|
id=recordid
|
||||||
|
)
|
||||||
|
except VirtualRaceResult.DoesNotExist:
|
||||||
|
if doregister:
|
||||||
|
hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,ws[0],race)
|
||||||
|
if hasinitial:
|
||||||
|
record = VirtualRaceResult(
|
||||||
|
userid = r.id,
|
||||||
|
username = r.user.first_name+' '+r.user.last_name,
|
||||||
|
weightcategory=weightclass,
|
||||||
|
adaptiveclass=adaptiveclass,
|
||||||
|
race=race,
|
||||||
|
boatclass=boatclass,
|
||||||
|
boattype=boattype,
|
||||||
|
sex=sex,
|
||||||
|
age = age,
|
||||||
|
entrycategory=initialcategory,
|
||||||
|
)
|
||||||
|
record.save()
|
||||||
|
else:
|
||||||
|
errors.append("Unable to find a suitable start category")
|
||||||
|
return result,comments,errors,0
|
||||||
|
else:
|
||||||
|
errors.append("Couldn't find this entry")
|
||||||
|
return result,comments,errors,0
|
||||||
|
|
||||||
records = VirtualRaceResult.objects.filter(
|
records = VirtualRaceResult.objects.filter(
|
||||||
userid=r.id,
|
userid=r.id,
|
||||||
@@ -1523,7 +1652,7 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0):
|
|||||||
workoutid = ws[0].id
|
workoutid = ws[0].id
|
||||||
)
|
)
|
||||||
|
|
||||||
if not record:
|
if not record and not doregister:
|
||||||
errors.append("Couldn't find this entry")
|
errors.append("Couldn't find this entry")
|
||||||
return result,comments,errors,0
|
return result,comments,errors,0
|
||||||
|
|
||||||
@@ -1583,6 +1712,8 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0):
|
|||||||
referencespeed=record.referencespeed,coursedistance=race.course.distance
|
referencespeed=record.referencespeed,coursedistance=race.course.distance
|
||||||
)
|
)
|
||||||
|
|
||||||
|
comments.append('We are now checking adherence to the race course. This may take a few minutes to complete')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_workouts_plannedsession(ws,race,r)
|
add_workouts_plannedsession(ws,race,r)
|
||||||
|
|||||||
@@ -349,6 +349,8 @@ def handle_check_race_course(self,
|
|||||||
recordid,useremail,userfirstname,
|
recordid,useremail,userfirstname,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
|
||||||
|
logfile = 'courselog_{workoutid}_{courseid}.log'.format(workoutid=workoutid,courseid=courseid)
|
||||||
|
|
||||||
if 'debug' in kwargs:
|
if 'debug' in kwargs:
|
||||||
debug = kwargs['debug']
|
debug = kwargs['debug']
|
||||||
else:
|
else:
|
||||||
@@ -420,10 +422,11 @@ def handle_check_race_course(self,
|
|||||||
engine = create_engine(database_url, echo=False)
|
engine = create_engine(database_url, echo=False)
|
||||||
|
|
||||||
# get polygons
|
# get polygons
|
||||||
query = "SELECT id FROM rowers_geopolygon WHERE course_id = {courseid} ORDER BY order_in_course ASC".format(
|
query = "SELECT id,name FROM rowers_geopolygon WHERE course_id = {courseid} ORDER BY order_in_course ASC".format(
|
||||||
courseid=courseid
|
courseid=courseid
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
with engine.connect() as conn, conn.begin():
|
with engine.connect() as conn, conn.begin():
|
||||||
result = conn.execute(query)
|
result = conn.execute(query)
|
||||||
polygons = result.fetchall()
|
polygons = result.fetchall()
|
||||||
@@ -441,7 +444,16 @@ def handle_check_race_course(self,
|
|||||||
|
|
||||||
# check how many times went through start polygon
|
# check how many times went through start polygon
|
||||||
try:
|
try:
|
||||||
entrytimes,entrydistances = time_in_path(rowdata,paths[0],maxmin='max',getall=True)
|
entrytimes,entrydistances = time_in_path(rowdata,paths[0],maxmin='max',getall=True,
|
||||||
|
name=polygons[0].name,logfile=logfile)
|
||||||
|
with open(logfile,'a') as f:
|
||||||
|
t = time.localtime()
|
||||||
|
timestamp = time.strftime('%b-%d-%Y_%H%M', t)
|
||||||
|
f.write('\n')
|
||||||
|
f.write(timestamp)
|
||||||
|
f.write(' ')
|
||||||
|
f.write('Found {n} entrytimes'.format(n=len(entrytimes)))
|
||||||
|
|
||||||
except InvalidTrajectoryError:
|
except InvalidTrajectoryError:
|
||||||
entrytimes = []
|
entrytimes = []
|
||||||
entrydistances = []
|
entrydistances = []
|
||||||
@@ -457,7 +469,13 @@ def handle_check_race_course(self,
|
|||||||
endseconds = []
|
endseconds = []
|
||||||
|
|
||||||
for startt in entrytimes:
|
for startt in entrytimes:
|
||||||
|
with open(logfile,'a') as f:
|
||||||
|
t = time.localtime()
|
||||||
|
timestamp = time.strftime('%b-%d-%Y_%H%M', t)
|
||||||
|
f.write('\n')
|
||||||
|
f.write(timestamp)
|
||||||
|
f.write(' ')
|
||||||
|
f.write('Path starting at {t}'.format(t=startt))
|
||||||
rowdata2 = rowdata[rowdata['time']>(startt-10.)]
|
rowdata2 = rowdata[rowdata['time']>(startt-10.)]
|
||||||
|
|
||||||
(
|
(
|
||||||
@@ -465,13 +483,13 @@ def handle_check_race_course(self,
|
|||||||
coursemeters,
|
coursemeters,
|
||||||
coursecompleted,
|
coursecompleted,
|
||||||
|
|
||||||
) = coursetime_paths(rowdata2,paths)
|
) = coursetime_paths(rowdata2,paths,polygons=polygons,logfile=logfile)
|
||||||
(
|
(
|
||||||
coursetimefirst,
|
coursetimefirst,
|
||||||
coursemetersfirst,
|
coursemetersfirst,
|
||||||
firstcompleted
|
firstcompleted
|
||||||
) = coursetime_first(
|
) = coursetime_first(
|
||||||
rowdata2,paths)
|
rowdata2,paths,polygons=polygons,logfile=logfile)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -541,6 +559,8 @@ def handle_check_race_course(self,
|
|||||||
conn.close()
|
conn.close()
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
|
|
||||||
|
os.remove(logfile)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -574,9 +594,11 @@ def handle_check_race_course(self,
|
|||||||
|
|
||||||
# send email
|
# send email
|
||||||
handle_sendemail_coursefail(
|
handle_sendemail_coursefail(
|
||||||
useremail,userfirstname,
|
useremail,userfirstname,logfile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
os.remove(logfile)
|
||||||
|
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -1168,7 +1190,7 @@ def handle_sendemail_raceregistration(
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def handle_sendemail_coursefail(
|
def handle_sendemail_coursefail(
|
||||||
useremail, username, **kwargs):
|
useremail, username, logfile, **kwargs):
|
||||||
|
|
||||||
if 'debug' in kwargs:
|
if 'debug' in kwargs:
|
||||||
debug = kwargs['debug']
|
debug = kwargs['debug']
|
||||||
@@ -1186,7 +1208,10 @@ def handle_sendemail_coursefail(
|
|||||||
res = send_template_email(from_email,[useremail],
|
res = send_template_email(from_email,[useremail],
|
||||||
subject,
|
subject,
|
||||||
'trajectoryfailemail.html',
|
'trajectoryfailemail.html',
|
||||||
d,**kwargs)
|
d,
|
||||||
|
cc=['info@rowsandall.com'],
|
||||||
|
attach_file=logfile,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -2421,8 +2446,8 @@ def handle_send_template_email(template,email,fromemail,rowername,
|
|||||||
}
|
}
|
||||||
|
|
||||||
res = send_template_email('Rowsandall <info@rowsandall.com>',
|
res = send_template_email('Rowsandall <info@rowsandall.com>',
|
||||||
fullemail,subject,
|
['info@rowsandall.com'],subject,
|
||||||
template,d,cc=[fromemail],**kwargs)
|
template,d,cc=[fromemail],bcc=fullemail,**kwargs)
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_sendemail_message(email,fromemail,rowername,message,teamname,managername,
|
def handle_sendemail_message(email,fromemail,rowername,message,teamname,managername,
|
||||||
|
|||||||
@@ -112,11 +112,11 @@
|
|||||||
<i class="fas fa-map fa-fw"></i> Map View
|
<i class="fas fa-map fa-fw"></i> Map View
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% if course.manager == rower %}
|
|
||||||
<li id="course-emailkml">
|
<li id="course-emailkml">
|
||||||
<a href="/rowers/courses/{{ course.id }}/downloadkml/">
|
<a href="/rowers/courses/{{ course.id }}/downloadkml/">
|
||||||
<i class="fas fa-globe-americas fa-fw"></i> Download as KML</a>
|
<i class="fas fa-globe-americas fa-fw"></i> Download as KML</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if course.manager == rower %}
|
||||||
<li id="course-editview">
|
<li id="course-editview">
|
||||||
<a href="/rowers/courses/{{ course.id }}/edit/">
|
<a href="/rowers/courses/{{ course.id }}/edit/">
|
||||||
<i class="fas fa-pencil-alt fa-fw"></i> Edit</a>
|
<i class="fas fa-pencil-alt fa-fw"></i> Edit</a>
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
contact me by reply to this email.
|
contact me by reply to this email.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The attachment contains debugging information for the site owners.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Best Regards, the Rowsandall Team
|
Best Regards, the Rowsandall Team
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
Registered users of rowsandall.com can participate in this challenge.
|
Registered users of rowsandall.com can participate in this challenge.
|
||||||
Participation is free, unless specified differently in the race comment above.
|
Participation is free, unless specified differently in the race comment above.
|
||||||
{% if race.sessiontype == 'race' %}
|
{% if race.sessiontype == 'race' %}
|
||||||
|
Register to let others know you plan to do this challenge:
|
||||||
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
|
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
|
<a href="/rowers/virtualevent/{{ race.id }}/registerindoor"><h3>Register</h3></a>
|
||||||
@@ -183,6 +184,8 @@
|
|||||||
{% for button in buttons %}
|
{% for button in buttons %}
|
||||||
{% if button == 'registerbutton' %}
|
{% if button == 'registerbutton' %}
|
||||||
<p>
|
<p>
|
||||||
|
Register to let others know you plan to do this challenge. This also give you the option to
|
||||||
|
select your entry category:
|
||||||
{% if race.sessiontype == 'race' %}
|
{% if race.sessiontype == 'race' %}
|
||||||
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
|
<a href="/rowers/virtualevent/{{ race.id }}/register"><h3>Register</h3></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -526,6 +526,11 @@ def statsdata(workouts, options):
|
|||||||
|
|
||||||
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
||||||
|
|
||||||
|
try:
|
||||||
|
datadf['pace'] = datadf['pace']/1000.
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Create stats
|
# Create stats
|
||||||
stats = {}
|
stats = {}
|
||||||
# fielddict.pop('workoutstate')
|
# fielddict.pop('workoutstate')
|
||||||
@@ -4169,6 +4174,10 @@ def cumstats(request,userid=0,
|
|||||||
datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist)
|
datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist)
|
||||||
|
|
||||||
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
||||||
|
try:
|
||||||
|
datadf['pace'] = datadf['pace']/1000.
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
request.session['rowerid'] = r.id
|
request.session['rowerid'] = r.id
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ def plannedsession_comment_view(request,id=0,userid=0):
|
|||||||
rowers = {r.user for r in ps.rower.all()}
|
rowers = {r.user for r in ps.rower.all()}
|
||||||
commenters = set(list(commenters)+list(rowers))
|
commenters = set(list(commenters)+list(rowers))
|
||||||
for u in commenters:
|
for u in commenters:
|
||||||
a_messages.info(u,message)
|
try:
|
||||||
|
a_messages.info(u,message)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
if u != request.user and u != r.user:
|
if u != request.user and u != r.user:
|
||||||
ocr = Rower.objects.get(user=u)
|
ocr = Rower.objects.get(user=u)
|
||||||
res = myqueue(queuelow,
|
res = myqueue(queuelow,
|
||||||
|
|||||||
@@ -746,6 +746,7 @@ def virtualevent_disqualify_view(request,id=0,recordid=0):
|
|||||||
|
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
race = get_object_or_404(VirtualRace,pk=id)
|
race = get_object_or_404(VirtualRace,pk=id)
|
||||||
|
raceid = race.id
|
||||||
|
|
||||||
|
|
||||||
if race.sessiontype == 'race':
|
if race.sessiontype == 'race':
|
||||||
@@ -1223,7 +1224,6 @@ def virtualevent_view(request,id=0):
|
|||||||
|
|
||||||
comments = PlannedSessionComment.objects.filter(plannedsession=race).order_by("created")
|
comments = PlannedSessionComment.objects.filter(plannedsession=race).order_by("created")
|
||||||
|
|
||||||
|
|
||||||
return render(request,'virtualevent.html',
|
return render(request,'virtualevent.html',
|
||||||
{
|
{
|
||||||
'coursescript':script,
|
'coursescript':script,
|
||||||
@@ -1500,6 +1500,7 @@ def virtualevent_addboat_view(request,id=0):
|
|||||||
raise Http404("Virtual Challenge does not exist")
|
raise Http404("Virtual Challenge does not exist")
|
||||||
|
|
||||||
categories = None
|
categories = None
|
||||||
|
hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,None,race)
|
||||||
if race.coursestandards is not None:
|
if race.coursestandards is not None:
|
||||||
categories = CourseStandard.objects.filter(
|
categories = CourseStandard.objects.filter(
|
||||||
standardcollection=race.coursestandards).order_by("name")
|
standardcollection=race.coursestandards).order_by("name")
|
||||||
@@ -1701,11 +1702,22 @@ def virtualevent_addboat_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
initial = {
|
if hasinitial:
|
||||||
'age': calculate_age(r.birthdate),
|
initial = {
|
||||||
'weightcategory': r.weightcategory,
|
'age': calculate_age(r.birthdate),
|
||||||
'adaptiveclass': r.adaptiveclass,
|
'boattype':boattype,
|
||||||
|
'boatclass':boatclass,
|
||||||
|
'adaptiveclass':adaptiveclass,
|
||||||
|
'weightclass':weightclass,
|
||||||
|
'sex':sex,
|
||||||
|
'entrycategory':initialcategory,
|
||||||
}
|
}
|
||||||
|
else:
|
||||||
|
initial = {
|
||||||
|
'age': calculate_age(r.birthdate),
|
||||||
|
'weightcategory': r.weightcategory,
|
||||||
|
'adaptiveclass': r.adaptiveclass,
|
||||||
|
}
|
||||||
|
|
||||||
categories = None
|
categories = None
|
||||||
if race.coursestandards is not None:
|
if race.coursestandards is not None:
|
||||||
@@ -1775,6 +1787,7 @@ def virtualevent_register_view(request,id=0):
|
|||||||
raise Http404("Virtual Challenge does not exist")
|
raise Http404("Virtual Challenge does not exist")
|
||||||
|
|
||||||
categories = None
|
categories = None
|
||||||
|
hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,None,race)
|
||||||
if race.coursestandards is not None:
|
if race.coursestandards is not None:
|
||||||
categories = CourseStandard.objects.filter(
|
categories = CourseStandard.objects.filter(
|
||||||
standardcollection=race.coursestandards).order_by("name")
|
standardcollection=race.coursestandards).order_by("name")
|
||||||
@@ -1938,11 +1951,22 @@ def virtualevent_register_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
initial = {
|
if hasinitial:
|
||||||
'age': calculate_age(r.birthdate),
|
initial = {
|
||||||
'weightcategory': r.weightcategory,
|
'age': calculate_age(r.birthdate),
|
||||||
'adaptiveclass': r.adaptiveclass,
|
'boattype':boattype,
|
||||||
|
'boatclass':boatclass,
|
||||||
|
'adaptiveclass':adaptiveclass,
|
||||||
|
'weightclass':weightclass,
|
||||||
|
'sex':sex,
|
||||||
|
'entrycategory':initialcategory,
|
||||||
}
|
}
|
||||||
|
else:
|
||||||
|
initial = {
|
||||||
|
'age': calculate_age(r.birthdate),
|
||||||
|
'weightcategory': r.weightcategory,
|
||||||
|
'adaptiveclass': r.adaptiveclass,
|
||||||
|
}
|
||||||
|
|
||||||
categories = None
|
categories = None
|
||||||
if race.coursestandards is not None:
|
if race.coursestandards is not None:
|
||||||
@@ -2565,8 +2589,15 @@ def virtualevent_edit_view(request,id=0):
|
|||||||
startdatetime
|
startdatetime
|
||||||
)
|
)
|
||||||
|
|
||||||
if timezone.now() > startdatetime:
|
end_time = race.end_time
|
||||||
messages.error(request,"You cannot edit a race after the start of the race window")
|
end_date = race.enddate
|
||||||
|
enddatetime = datetime.datetime.combine(end_date,end_time)
|
||||||
|
enddatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
enddatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
if timezone.now() > enddatetime:
|
||||||
|
messages.error(request,"You cannot edit a race after the end of the race window")
|
||||||
url = reverse('virtualevent_view',
|
url = reverse('virtualevent_view',
|
||||||
kwargs={
|
kwargs={
|
||||||
'id':race.id,
|
'id':race.id,
|
||||||
@@ -2658,8 +2689,15 @@ def indoorvirtualevent_edit_view(request,id=0):
|
|||||||
startdatetime
|
startdatetime
|
||||||
)
|
)
|
||||||
|
|
||||||
if timezone.now() > startdatetime:
|
end_time = race.end_time
|
||||||
messages.error(request,"You cannot edit a race after the start of the race window")
|
end_date = race.enddate
|
||||||
|
enddatetime = datetime.datetime.combine(end_date,end_time)
|
||||||
|
enddatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
enddatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
if timezone.now() > enddatetime:
|
||||||
|
messages.error(request,"You cannot edit a race after the end of the race window")
|
||||||
url = reverse('virtualevent_view',
|
url = reverse('virtualevent_view',
|
||||||
kwargs={
|
kwargs={
|
||||||
'id':race.id,
|
'id':race.id,
|
||||||
@@ -2773,6 +2811,29 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0):
|
|||||||
race=race
|
race=race
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if records.count() == 0:
|
||||||
|
hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,None,race)
|
||||||
|
if not hasinitial:
|
||||||
|
messages.error(request,"Sorry, you have to register first")
|
||||||
|
url = reverse('virtualevent_view',
|
||||||
|
kwargs = {
|
||||||
|
'id':id,
|
||||||
|
})
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
record = resultobj(
|
||||||
|
userid = r.id,
|
||||||
|
username = r.user.first_name+' '+r.user.last_name,
|
||||||
|
weightcategory=weightclass,
|
||||||
|
adaptiveclass=adaptiveclass,
|
||||||
|
race=race,
|
||||||
|
boatclass=boatclass,
|
||||||
|
sex=sex,
|
||||||
|
age=calculate_age(r.birthdate),
|
||||||
|
entrycategory=initialcategory,
|
||||||
|
)
|
||||||
|
record.save()
|
||||||
|
records = [record]
|
||||||
|
|
||||||
|
|
||||||
entrychoices = []
|
entrychoices = []
|
||||||
|
|
||||||
|
|||||||
@@ -4909,7 +4909,7 @@ def workout_upload_view(request,
|
|||||||
notes = form.cleaned_data['notes']
|
notes = form.cleaned_data['notes']
|
||||||
offline = form.cleaned_data['offline']
|
offline = form.cleaned_data['offline']
|
||||||
|
|
||||||
race = None
|
registrationid = 0
|
||||||
if optionsform.is_valid():
|
if optionsform.is_valid():
|
||||||
make_plot = optionsform.cleaned_data['make_plot']
|
make_plot = optionsform.cleaned_data['make_plot']
|
||||||
plottype = optionsform.cleaned_data['plottype']
|
plottype = optionsform.cleaned_data['plottype']
|
||||||
@@ -4923,9 +4923,9 @@ def workout_upload_view(request,
|
|||||||
landingpage = optionsform.cleaned_data['landingpage']
|
landingpage = optionsform.cleaned_data['landingpage']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
race = optionsform.cleaned_data['submitrace']
|
registrationid = optionsform.cleaned_data['submitrace']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
race = None
|
registrationid = 0
|
||||||
|
|
||||||
uploadoptions = {
|
uploadoptions = {
|
||||||
'makeprivate':makeprivate,
|
'makeprivate':makeprivate,
|
||||||
@@ -5113,17 +5113,58 @@ def workout_upload_view(request,
|
|||||||
else:
|
else:
|
||||||
messages.error(request,message)
|
messages.error(request,message)
|
||||||
|
|
||||||
if race and race_can_submit(r,race):
|
if int(registrationid) < 0:
|
||||||
if race.sessiontype == 'indoorrace':
|
race = VirtualRace.objects.get(id=-int(registrationid))
|
||||||
records = IndoorVirtualRaceResult.objects.filter(
|
if race.sessiontype == 'race':
|
||||||
race=race,
|
result,comments,errors,jobid = add_workout_race(
|
||||||
userid=r.id
|
[w], race,r,doregister=True,
|
||||||
|
)
|
||||||
|
if result:
|
||||||
|
messages.info(
|
||||||
|
request,
|
||||||
|
"We have submitted your workout to the race")
|
||||||
|
|
||||||
|
for c in comments:
|
||||||
|
messages.info(request,c)
|
||||||
|
for er in errors:
|
||||||
|
messages.error(request,er)
|
||||||
|
elif race.sessiontype == 'indoorrace':
|
||||||
|
result,comments,errors,jobid = add_workout_indoorrace(
|
||||||
|
[w],race,r,doregister=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if records:
|
if result:
|
||||||
|
messages.info(
|
||||||
|
request,
|
||||||
|
"We have submitted your workout to the race")
|
||||||
|
|
||||||
|
for c in comments:
|
||||||
|
messages.info(request,c)
|
||||||
|
for er in errors:
|
||||||
|
messages.error(request,er)
|
||||||
|
|
||||||
|
if int(registrationid)>0:
|
||||||
|
races = VirtualRace.objects.filter(
|
||||||
|
registration_closure__gt=timezone.now()
|
||||||
|
)
|
||||||
|
registrations = IndoorVirtualRaceResult.objects.filter(
|
||||||
|
race__in = races,
|
||||||
|
id=registrationid,
|
||||||
|
userid = r.id,
|
||||||
|
)
|
||||||
|
registrations2 = VirtualRaceResult.objects.filter(
|
||||||
|
race__in = races,
|
||||||
|
id=registrationid,
|
||||||
|
userid=r.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
if int(registrationid) in [r.id for r in registrations]:
|
||||||
|
# indoor race
|
||||||
|
registrations = registrations.filter(id=registrationid)
|
||||||
|
if registrations:
|
||||||
|
race = registrations[0].race
|
||||||
result,comments,errors,jobid = add_workout_indoorrace(
|
result,comments,errors,jobid = add_workout_indoorrace(
|
||||||
[w],race,r,recordid=records[0].id
|
[w],race,r,recordid=registrations[0].id
|
||||||
)
|
)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
@@ -5135,15 +5176,15 @@ def workout_upload_view(request,
|
|||||||
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 race.sessiontype == 'race':
|
|
||||||
records = VirtualRaceResult.objects.filter(
|
|
||||||
race=race,userid=r.id
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if records:
|
if int(registrationid) in [r.id for r in registrations2]:
|
||||||
|
# race
|
||||||
|
registrations = registrations2.filter(id=registrationid)
|
||||||
|
if registrations:
|
||||||
|
race = registrations[0].race
|
||||||
result,comments,errors,jobid = add_workout_race(
|
result,comments,errors,jobid = add_workout_race(
|
||||||
[w], race,r,recordid=records[0].id
|
[w], race,r,recordid=registrations[0].id
|
||||||
)
|
)
|
||||||
if result:
|
if result:
|
||||||
messages.info(
|
messages.info(
|
||||||
@@ -5156,11 +5197,18 @@ def workout_upload_view(request,
|
|||||||
messages.error(request,er)
|
messages.error(request,er)
|
||||||
|
|
||||||
|
|
||||||
if landingpage != 'workout_upload_view':
|
|
||||||
|
if registrationid != 0:
|
||||||
|
url = reverse('virtualevent_view',
|
||||||
|
kwargs = {
|
||||||
|
'id':race.id,
|
||||||
|
})
|
||||||
|
elif landingpage != 'workout_upload_view':
|
||||||
url = reverse(landingpage,
|
url = reverse(landingpage,
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'id':encoder.encode_hex(w.id),
|
'id':encoder.encode_hex(w.id),
|
||||||
})
|
})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
url = reverse(landingpage)
|
url = reverse(landingpage)
|
||||||
|
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ CACHE_MIDDLEWARE_SECONDS = 900
|
|||||||
|
|
||||||
EMAIL_BACKEND = 'django_ses.SESBackend'
|
EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||||
|
|
||||||
AWS_SES_REGION_NAME = CFG['aws_smtp']
|
AWS_SES_REGION_NAME = CFG['aws_region']
|
||||||
AWS_SES_REGION_ENDPOINT = CFG['aws_smtp']
|
AWS_SES_REGION_ENDPOINT = CFG['aws_smtp']
|
||||||
|
|
||||||
AWS_SES_ACCESS_KEY_ID = CFG['aws_access_key_id']
|
AWS_SES_ACCESS_KEY_ID = CFG['aws_access_key_id']
|
||||||
|
|||||||
Reference in New Issue
Block a user