From 0d031833145eb7e231558b0e2289fc4a67f5c789 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 09:06:33 +0200 Subject: [PATCH 01/18] bug fix savgol filter --- rowers/interactiveplots.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index be7360b5..6ad25d6a 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -5481,8 +5481,11 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line', else: windowsize = 1 - if windowsize >= 3 and windowsize < len(group['y']): - group['y'] = savgol_filter(group['y'],windowsize,3) + if windowsize > 3 and windowsize < len(group['y']): + try: + group['y'] = savgol_filter(group['y'],windowsize,3) + except ValueError: + pass ylabel = Label(x=100,y=60+nrworkouts*20-20*cntr, x_units='screen',y_units='screen', From db29971fa6fc4ca7296cd953cb740a51295df41d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 09:38:34 +0200 Subject: [PATCH 02/18] small bug fixed --- rowers/views/planviews.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index f30b51b9..7db2babe 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -81,7 +81,10 @@ def plannedsession_comment_view(request,id=0,userid=0): rowers = {r.user for r in ps.rower.all()} commenters = set(list(commenters)+list(rowers)) 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: ocr = Rower.objects.get(user=u) res = myqueue(queuelow, From f89ddd57b8ce1537792686168dbc4033abd09311 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 09:42:46 +0200 Subject: [PATCH 03/18] download for logged in --- rowers/templates/menu_racing.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowers/templates/menu_racing.html b/rowers/templates/menu_racing.html index 67e72c77..9d115550 100644 --- a/rowers/templates/menu_racing.html +++ b/rowers/templates/menu_racing.html @@ -112,11 +112,11 @@  Map View - {% if course.manager == rower %}
  •  Download as KML
  • + {% if course.manager == rower %}
  •  Edit From 49a2a552067a7d959d929902a1baafbde1ba1049 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 11:05:02 +0200 Subject: [PATCH 04/18] logging of validaitons --- rowers/courseutils.py | 37 +++++++++++++++----- rowers/tasks.py | 41 ++++++++++++++++++----- rowers/templates/trajectoryfailemail.html | 4 +++ 3 files changed, 66 insertions(+), 16 deletions(-) diff --git a/rowers/courseutils.py b/rowers/courseutils.py index 6ff83fc7..3bdeefd8 100644 --- a/rowers/courseutils.py +++ b/rowers/courseutils.py @@ -2,7 +2,7 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals - +import time @@ -19,7 +19,7 @@ class InvalidTrajectoryError(Exception): def __str__(self): 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: return 0 @@ -43,20 +43,38 @@ def time_in_path(df,p,maxmin='max',getall=False): else: 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]))) raise InvalidTrajectoryError("Trajectory doesn't go through path") return 0 -def coursetime_first(data,paths): +def coursetime_first(data,paths,polygons=[],logfile=None): entrytime = data['time'].max() entrydistance = data['cum_dist'].max() coursecompleted = False + if len(polygons) == 0: + polygons = [(0,str(i)) for i in range(len(paths))] + + 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 except InvalidTrajectoryError: entrytime = data['time'].max() @@ -64,12 +82,15 @@ def coursetime_first(data,paths): coursecompleted = False 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() entrydistance = data['cum_dist'].max() coursecompleted = False + if len(polygons) == 0: + polygons = [(0,str(i)) for i in range(len(paths))] + # corner case - empty list of paths if len(paths) == 0: return 0,True @@ -80,7 +101,7 @@ def coursetime_paths(data,paths,finalmaxmin='min'): ( entrytime, 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 except InvalidTrajectoryError: entrytime = data['time'].max() @@ -90,7 +111,7 @@ def coursetime_paths(data,paths,finalmaxmin='min'): if len(paths) > 1: 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['time'] = data['time']-time data['cum_dist'] = data['cum_dist']-dist @@ -98,7 +119,7 @@ def coursetime_paths(data,paths,finalmaxmin='min'): timenext, distnext, coursecompleted - ) = coursetime_paths(data,paths[1:]) + ) = coursetime_paths(data,paths[1:],polygons=polygons[1:],logfile=logfile) return time+timenext, dist+distnext,coursecompleted except InvalidTrajectoryError: entrytime = data['time'].max() diff --git a/rowers/tasks.py b/rowers/tasks.py index 2a5365fc..d0d5844b 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -349,6 +349,8 @@ def handle_check_race_course(self, recordid,useremail,userfirstname, **kwargs): + logfile = 'courselog_{workoutid}_{courseid}.log'.format(workoutid=workoutid,courseid=courseid) + if 'debug' in kwargs: debug = kwargs['debug'] else: @@ -420,10 +422,11 @@ def handle_check_race_course(self, engine = create_engine(database_url, echo=False) # 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 ) + with engine.connect() as conn, conn.begin(): result = conn.execute(query) polygons = result.fetchall() @@ -441,7 +444,16 @@ def handle_check_race_course(self, # check how many times went through start polygon 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: entrytimes = [] entrydistances = [] @@ -457,7 +469,13 @@ def handle_check_race_course(self, endseconds = [] 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.)] ( @@ -465,13 +483,13 @@ def handle_check_race_course(self, coursemeters, coursecompleted, - ) = coursetime_paths(rowdata2,paths) + ) = coursetime_paths(rowdata2,paths,polygons=polygons,logfile=logfile) ( coursetimefirst, coursemetersfirst, firstcompleted ) = coursetime_first( - rowdata2,paths) + rowdata2,paths,polygons=polygons,logfile=logfile) @@ -541,6 +559,8 @@ def handle_check_race_course(self, conn.close() engine.dispose() + os.remove(logfile) + return 1 else: @@ -574,9 +594,11 @@ def handle_check_race_course(self, # send email handle_sendemail_coursefail( - useremail,userfirstname, + useremail,userfirstname,logfile ) + os.remove(logfile) + return 2 return 0 @@ -1168,7 +1190,7 @@ def handle_sendemail_raceregistration( return 1 def handle_sendemail_coursefail( - useremail, username, **kwargs): + useremail, username, logfile, **kwargs): if 'debug' in kwargs: debug = kwargs['debug'] @@ -1186,7 +1208,10 @@ def handle_sendemail_coursefail( res = send_template_email(from_email,[useremail], subject, 'trajectoryfailemail.html', - d,**kwargs) + d, + cc=['info@rowsandall.com'], + attach_file=logfile, + **kwargs) return 1 diff --git a/rowers/templates/trajectoryfailemail.html b/rowers/templates/trajectoryfailemail.html index 3022682b..10593994 100644 --- a/rowers/templates/trajectoryfailemail.html +++ b/rowers/templates/trajectoryfailemail.html @@ -16,6 +16,10 @@ contact me by reply to this email.

    +

    + The attachment contains debugging information for the site owners. +

    +

    Best Regards, the Rowsandall Team

    From 467e59ff3b321644ee0aa2e60955f6e08d3c3c5a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 11:50:26 +0200 Subject: [PATCH 05/18] formproce --- rowers/models.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index e28fef26..4a8adafb 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2643,8 +2643,12 @@ class VirtualRaceForm(ModelForm): 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'] try: From cbed58e0ca2b741ee371e80bf5a23c22c63f001d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 12:09:43 +0200 Subject: [PATCH 06/18] adding bcc --- rowers/emails.py | 19 +++++++++++++------ rowers/tasks.py | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/rowers/emails.py b/rowers/emails.py index b232ee09..d3d76ff6 100644 --- a/rowers/emails.py +++ b/rowers/emails.py @@ -53,7 +53,7 @@ from django.contrib.staticfiles import finders def textify(html): - # Remove html tags and continuous whitespaces + # Remove html tags and continuous whitespaces text_only = re.sub('[ \t]+', ' ', strip_tags(html)) # Strip single spaces in the beginning of each line return text_only.replace('\n ', '\n').strip() @@ -61,7 +61,7 @@ def textify(html): def htmlstripnobr(html): safe_html = re.sub('[ \t]+', ' ', strip_tags(html)) return safe_html - + def htmlstrip(html): safe_html = re.sub('[ \t]+', ' ', strip_tags(html)) return newlinetobr(safe_html) @@ -80,11 +80,18 @@ def send_template_email(from_email,to_email,subject, text_content = textify(html_content) # html_content = newlinetobr(html_content) - if 'cc' in kwargs: + print(kwargs['bcc']) + + 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']) else: msg = EmailMultiAlternatives(subject, text_content, from_email, to_email) - + msg.attach_alternative(html_content, "text/html") if 'attach_file' in kwargs: @@ -106,8 +113,8 @@ def send_template_email(from_email,to_email,subject, else: emailbounced = False - - + + if not emailbounced: res = msg.send() else: diff --git a/rowers/tasks.py b/rowers/tasks.py index d0d5844b..f573ec44 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -2446,8 +2446,8 @@ def handle_send_template_email(template,email,fromemail,rowername, } res = send_template_email('Rowsandall ', - fullemail,subject, - template,d,cc=[fromemail],**kwargs) + ['info@rowsandall.com'],subject, + template,d,cc=[fromemail],bcc=fullemail,**kwargs) @app.task def handle_sendemail_message(email,fromemail,rowername,message,teamname,managername, From da9a226cc60de3d6ececd301d668e63c1eda3585 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 12:22:38 +0200 Subject: [PATCH 07/18] allowing race edit during race window --- rowers/plannedsessions.py | 8 +++++++- rowers/views/racesviews.py | 23 ++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index d8936ca3..a9be6a3e 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1026,7 +1026,13 @@ def race_can_edit(r,race): startdatetime = pytz.timezone(race.timezone).localize( startdatetime ) - if timezone.now() startdatetime: - messages.error(request,"You cannot edit a race after the start of the race window") + end_time = race.end_time + 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', kwargs={ 'id':race.id, @@ -2658,8 +2664,15 @@ def indoorvirtualevent_edit_view(request,id=0): startdatetime ) - if timezone.now() > startdatetime: - messages.error(request,"You cannot edit a race after the start of the race window") + end_time = race.end_time + 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', kwargs={ 'id':race.id, From 1914b855deee1a9c7c4ccdfaa74f0593e4af7111 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 20 Jun 2020 12:23:52 +0200 Subject: [PATCH 08/18] c --- rowers/emails.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rowers/emails.py b/rowers/emails.py index d3d76ff6..59f3e0ec 100644 --- a/rowers/emails.py +++ b/rowers/emails.py @@ -80,7 +80,6 @@ def send_template_email(from_email,to_email,subject, text_content = textify(html_content) # html_content = newlinetobr(html_content) - print(kwargs['bcc']) if 'bcc' in kwargs and 'cc' in kwargs: msg = EmailMultiAlternatives(subject, text_content, from_email, to_email,cc=kwargs['cc'], From de6fdd9378f5b2fc5b972388c4ed71b0648f8000 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 10:29:54 +0200 Subject: [PATCH 09/18] more verbose logging --- rowers/courseutils.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/rowers/courseutils.py b/rowers/courseutils.py index 3bdeefd8..d864e372 100644 --- a/rowers/courseutils.py +++ b/rowers/courseutils.py @@ -38,6 +38,25 @@ def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None): 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: return df[b==2]['time'],df[b==2]['cum_dist'] else: @@ -57,6 +76,8 @@ def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None): 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") From 36f54783f72eb0d7555803a0e0101e340ef05a3d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 10:41:08 +0200 Subject: [PATCH 10/18] bug fixed --- rowers/views/analysisviews.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index a8c58849..b02a7cb9 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -526,6 +526,11 @@ def statsdata(workouts, options): datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) + try: + datadf['pace'] = datadf['pace']/1000. + except KeyError: + pass + # Create stats stats = {} # fielddict.pop('workoutstate') @@ -4169,6 +4174,10 @@ def cumstats(request,userid=0, datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist) datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) + try: + datadf['pace'] = datadf['pace']/1000. + except KeyError: + pass request.session['rowerid'] = r.id From ba0b351130f876ee8662b312d7fa7ef25e16d251 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 12:48:24 +0200 Subject: [PATCH 11/18] working submission --- requirements.txt | 8 +++- rowers/forms.py | 29 ++++++++------ rowers/plannedsessions.py | 5 ++- rowers/views/workoutviews.py | 76 ++++++++++++++++++++++++++++-------- 4 files changed, 86 insertions(+), 32 deletions(-) diff --git a/requirements.txt b/requirements.txt index a237c95a..25b00df6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,8 @@ billiard==3.6.0.0 bleach==3.1.0 bokeh==1.0.4 boto==2.49.0 +boto3==1.14.7 +botocore==1.17.7 braintree==3.55.0 cairocffi==1.0.2 celery==4.3.0 @@ -53,7 +55,7 @@ django-rest-framework==0.1.0 django-rest-swagger==2.2.0 django-rq==1.3.1 django-rq-dashboard==0.3.3 -django-ses==0.8.10 +django-ses==1.0.0 django-shell-plus==1.1.7 django-social-share==1.3.2 django-suit==0.2.26 @@ -96,6 +98,7 @@ itypes==1.1.0 jedi==0.13.3 jeepney==0.4 Jinja2==2.10 +jmespath==0.10.0 json5==0.8.5 jsonschema==3.0.1 jupyter==1.0.0 @@ -125,7 +128,7 @@ newrelic==5.2.1.129 nose==1.3.7 nose-parameterized==0.6.0 notebook==5.7.6 -numba==0.46.0 +numba==0.50.0 numpy==1.18.5 oauth2==1.9.0.post1 oauthlib==3.0.1 @@ -179,6 +182,7 @@ rowingdata==2.9.1 rowingphysics==0.5.0 rq==0.13.0 rules==2.1 +s3transfer==0.3.3 scipy==1.2.1 SecretStorage==3.1.1 Send2Trash==1.5.0 diff --git a/rowers/forms.py b/rowers/forms.py index 3dc3a222..42987cb4 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -124,7 +124,7 @@ class EmailForm(forms.Form): subject = forms.CharField(max_length=255) message = forms.CharField(widget=forms.Textarea()) - + disqualificationreasons = ( ('noimage','No monitor screenshot or data evidence was included'), @@ -386,7 +386,7 @@ class UploadOptionsForm(forms.Form): makeprivate = forms.BooleanField(initial=False,required=False, label='Make Workout Private') - submitrace = forms.ModelChoiceField(queryset=VirtualRace.objects.all(), + submitrace = forms.ChoiceField( label='Submit as challenge Result', required=False) @@ -404,6 +404,7 @@ class UploadOptionsForm(forms.Form): r = Rower.objects.get(user=self.request.user) races = VirtualRace.objects.filter( registration_closure__gt=timezone.now()) + registrations = IndoorVirtualRaceResult.objects.filter( race__in = races, userid = r.id) @@ -413,25 +414,27 @@ class UploadOptionsForm(forms.Form): userid = r.id, ) - raceids = [r.race.id for r in registrations] - raceids2 = [r.race.id for r in registrations2] + choices1 = [(r.id,str(r)) for r in registrations] + choices2 = [(r.id,str(r)) for r in registrations2] + choices3 = [(0,'---')] - raceids = raceids+raceids2 + choices = choices3+choices1+choices2 - races = VirtualRace.objects.filter( - 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) + choices = [(r.id,str(r)) for r in registrations] + choices = [(0,'---')]+choices if races: - self.fields['submitrace'].queryset = races + self.fields['submitrace'].choices = choices else: 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 # after a successful upload. This version allows the Team manager to select diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index a9be6a3e..674b5fe8 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1343,6 +1343,7 @@ def remove_rower_race(r,race,recordid=None): # Low Level functions - to be called by higher level methods def add_workout_indoorrace(ws,race,r,recordid=0): + print('aap') result = 0 comments = [] errors = [] @@ -1402,6 +1403,8 @@ def add_workout_indoorrace(ws,race,r,recordid=0): workoutid = ws[0].id ) + print(record,records) + if not record: errors.append("Couldn't find this entry") return result,comments,errors,0 @@ -1471,7 +1474,7 @@ def add_workout_indoorrace(ws,race,r,recordid=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 comments = [] errors = [] diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 43bea2b4..79b8f1ea 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -4909,7 +4909,7 @@ def workout_upload_view(request, notes = form.cleaned_data['notes'] offline = form.cleaned_data['offline'] - race = None + registrationid = 0 if optionsform.is_valid(): make_plot = optionsform.cleaned_data['make_plot'] plottype = optionsform.cleaned_data['plottype'] @@ -4923,9 +4923,9 @@ def workout_upload_view(request, landingpage = optionsform.cleaned_data['landingpage'] try: - race = optionsform.cleaned_data['submitrace'] + registrationid = optionsform.cleaned_data['submitrace'] except KeyError: - race = None + registrationid = 0 uploadoptions = { 'makeprivate':makeprivate, @@ -5113,17 +5113,60 @@ def workout_upload_view(request, else: messages.error(request,message) - if race and race_can_submit(r,race): - if race.sessiontype == 'indoorrace': - records = IndoorVirtualRaceResult.objects.filter( - race=race, - userid=r.id + if int(registrationid) < 0: + race = VirtualRace.Objects.get(id=-int(registrationid)) + if race.sessiontype == 'race': + race = registrations[0].race + result,comments,errors,jobid = add_workout_race( + [w], race,r, + ) + 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': + race = registrations[0].race + result,comments,errors,jobid = add_workout_indoorrace( + [w],race,r, ) - 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( - [w],race,r,recordid=records[0].id + [w],race,r,recordid=registrations[0].id ) if result: @@ -5135,15 +5178,15 @@ def workout_upload_view(request, messages.info(request,c) for er in errors: 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( - [w], race,r,recordid=records[0].id + [w], race,r,recordid=registrations[0].id ) if result: messages.info( @@ -5156,6 +5199,7 @@ def workout_upload_view(request, messages.error(request,er) + if landingpage != 'workout_upload_view': url = reverse(landingpage, kwargs = { From add55993ba33350ebc37b3fe75a624cf8b5f2bfb Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 14:49:09 +0200 Subject: [PATCH 12/18] form initial now has better default initial --- rowers/forms.py | 12 +++++- rowers/models.py | 4 +- rowers/plannedsessions.py | 76 +++++++++++++++++++++++++++++++++++--- rowers/views/racesviews.py | 40 ++++++++++++++++---- 4 files changed, 116 insertions(+), 16 deletions(-) diff --git a/rowers/forms.py b/rowers/forms.py index 42987cb4..694962b5 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -418,7 +418,17 @@ class UploadOptionsForm(forms.Form): choices2 = [(r.id,str(r)) for r in registrations2] choices3 = [(0,'---')] - choices = choices3+choices1+choices2 + 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)) + + choices = choices3+choices1+choices2+noregistrations if int(raceid) in [r.id for r in races]: therace = VirtualRace.objects.get(id=raceid) diff --git a/rowers/models.py b/rowers/models.py index 4a8adafb..8e9ed3f8 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2648,7 +2648,7 @@ class VirtualRaceForm(ModelForm): except KeyError: registration_closure = enddatetime+datetime.timedelta(days=1) cd['registration_closure'] = registration_closure - + registration_form = cd['registration_form'] try: @@ -3124,6 +3124,8 @@ class CourseTestResult(models.Model): distance = models.IntegerField(default=0) coursecompleted = models.BooleanField(default=False) + + class IndoorVirtualRaceResultForm(ModelForm): class Meta: model = IndoorVirtualRaceResult diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 674b5fe8..93206cbe 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -45,7 +45,7 @@ from rowers.models import ( GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle, TrainingPlan,PlannedSession,VirtualRaceResult,CourseTestResult, get_course_timezone, IndoorVirtualRaceResult,VirtualRace,createmacrofillers, - createmesofillers,createmicrofillers, + createmesofillers,createmicrofillers,CourseStandard, ) from rowers.courses import get_time_course @@ -1341,9 +1341,70 @@ def remove_rower_race(r,race,recordid=None): 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 + ).order_by("agemax","-agemin","boattype") + + + if standards.count()==0: + # omit weight + standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age, + boatclass=boatclass, + adaptiveclass=adaptiveclass, + boattype=boattype, + ) + if standards.count()==0: + standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age, + boattype=boattype) + if standards.count()==0: + standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age) + + 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 -def add_workout_indoorrace(ws,race,r,recordid=0): - print('aap') +def add_workout_indoorrace(ws,race,r,recordid=0,doregister=False): result = 0 comments = [] errors = [] @@ -1403,11 +1464,14 @@ def add_workout_indoorrace(ws,race,r,recordid=0): workoutid = ws[0].id ) - print(record,records) - if not record: + + if not record and not doregister: errors.append("Couldn't find this entry") return result,comments,errors,0 + elif not record: + pass + if race.sessionmode == 'distance': if ws[0].distance != race.sessionvalue: @@ -1532,7 +1596,7 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0,doregister=False): workoutid = ws[0].id ) - if not record: + if not record and not doregister: errors.append("Couldn't find this entry") return result,comments,errors,0 diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index c0369e00..c2148ac0 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -1499,6 +1499,7 @@ def virtualevent_addboat_view(request,id=0): raise Http404("Virtual Challenge does not exist") categories = None + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,None,race) if race.coursestandards is not None: categories = CourseStandard.objects.filter( standardcollection=race.coursestandards).order_by("name") @@ -1700,11 +1701,22 @@ def virtualevent_addboat_view(request,id=0): return HttpResponseRedirect(url) else: - initial = { - 'age': calculate_age(r.birthdate), - 'weightcategory': r.weightcategory, - 'adaptiveclass': r.adaptiveclass, + if hasinitial: + initial = { + 'age': calculate_age(r.birthdate), + '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 if race.coursestandards is not None: @@ -1774,6 +1786,7 @@ def virtualevent_register_view(request,id=0): raise Http404("Virtual Challenge does not exist") categories = None + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,None,race) if race.coursestandards is not None: categories = CourseStandard.objects.filter( standardcollection=race.coursestandards).order_by("name") @@ -1937,11 +1950,22 @@ def virtualevent_register_view(request,id=0): return HttpResponseRedirect(url) else: - initial = { - 'age': calculate_age(r.birthdate), - 'weightcategory': r.weightcategory, - 'adaptiveclass': r.adaptiveclass, + if hasinitial: + initial = { + 'age': calculate_age(r.birthdate), + '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 if race.coursestandards is not None: From 37f977a187fffb5a1adfa2ad27d31f1b6baef7dc Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 16:27:41 +0200 Subject: [PATCH 13/18] seems to be complete now --- rowers/forms.py | 8 ++- rowers/plannedsessions.py | 81 +++++++++++++++++++++++------- rowers/templates/virtualevent.html | 3 ++ rowers/views/racesviews.py | 24 +++++++++ rowers/views/workoutviews.py | 16 +++--- 5 files changed, 106 insertions(+), 26 deletions(-) diff --git a/rowers/forms.py b/rowers/forms.py index 694962b5..d3b23329 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -437,8 +437,12 @@ class UploadOptionsForm(forms.Form): else: registrations = IndoorVirtualRaceResult.objects.filter(race=therace,userid=r.id) - choices = [(r.id,str(r)) for r in registrations] - choices = [(0,'---')]+choices + 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: self.fields['submitrace'].choices = choices diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 93206cbe..92166a78 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1041,8 +1041,8 @@ def race_can_edit(r,race): return False def race_can_submit(r,race): - if r not in race.rower.all(): - return False + #if r not in race.rower.all(): + # return False start_time = race.start_time start_date = race.startdate @@ -1451,12 +1451,34 @@ def add_workout_indoorrace(ws,race,r,recordid=0,doregister=False): else: age = None - record = IndoorVirtualRaceResult.objects.get( - userid=r.id, - race=race, - id=recordid - ) - + try: + record = IndoorVirtualRaceResult.objects.get( + userid=r.id, + 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( userid=r.id, @@ -1466,11 +1488,8 @@ def add_workout_indoorrace(ws,race,r,recordid=0,doregister=False): - if not record and not doregister: - errors.append("Couldn't find this entry") - return result,comments,errors,0 - elif not record: - pass + + if race.sessionmode == 'distance': @@ -1584,11 +1603,35 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0,doregister=False): else: age = None - record = VirtualRaceResult.objects.get( - userid=r.id, - race=race, - id=recordid - ) + try: + record = VirtualRaceResult.objects.get( + userid=r.id, + 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( userid=r.id, @@ -1656,6 +1699,8 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0,doregister=False): 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) diff --git a/rowers/templates/virtualevent.html b/rowers/templates/virtualevent.html index 26d16084..6decfc0c 100644 --- a/rowers/templates/virtualevent.html +++ b/rowers/templates/virtualevent.html @@ -163,6 +163,7 @@ Registered users of rowsandall.com can participate in this challenge. Participation is free, unless specified differently in the race comment above. {% if race.sessiontype == 'race' %} + Register to let others know you plan to do this challenge:

    Register

    {% else %}

    Register

    @@ -183,6 +184,8 @@ {% for button in buttons %} {% if button == 'registerbutton' %}

    + 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' %}

    Register

    {% else %} diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index c2148ac0..93df6047 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -746,6 +746,7 @@ def virtualevent_disqualify_view(request,id=0,recordid=0): r = getrower(request.user) race = get_object_or_404(VirtualRace,pk=id) + raceid = race.id if race.sessiontype == 'race': @@ -2810,6 +2811,29 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0): 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 = [] diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 79b8f1ea..914064b0 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -5114,11 +5114,10 @@ def workout_upload_view(request, messages.error(request,message) if int(registrationid) < 0: - race = VirtualRace.Objects.get(id=-int(registrationid)) + race = VirtualRace.objects.get(id=-int(registrationid)) if race.sessiontype == 'race': - race = registrations[0].race result,comments,errors,jobid = add_workout_race( - [w], race,r, + [w], race,r,doregister=True, ) if result: messages.info( @@ -5130,9 +5129,8 @@ def workout_upload_view(request, for er in errors: messages.error(request,er) elif race.sessiontype == 'indoorrace': - race = registrations[0].race result,comments,errors,jobid = add_workout_indoorrace( - [w],race,r, + [w],race,r,doregister=True, ) if result: @@ -5200,11 +5198,17 @@ def workout_upload_view(request, - if landingpage != 'workout_upload_view': + if registrationid != 0: + url = reverse('virtualevent_view', + kwargs = { + 'id':race.id, + }) + elif landingpage != 'workout_upload_view': url = reverse(landingpage, kwargs = { 'id':encoder.encode_hex(w.id), }) + else: url = reverse(landingpage) From 14bc64b3db26c8c3cc3bae1a3c839b2df6c9d875 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 18:05:04 +0200 Subject: [PATCH 14/18] fix gender bug --- rowers/plannedsessions.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 92166a78..de3698ac 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1372,8 +1372,9 @@ def default_class(r,w,race): boatclass=boatclass, adaptiveclass=adaptiveclass, boattype=boattype, - weightclass=weightclass - ).order_by("agemax","-agemin","boattype") + weightclass=weightclass, + sex=sex, + ).order_by("agemax","-agemin","boattype","sex") if standards.count()==0: @@ -1382,12 +1383,12 @@ def default_class(r,w,race): boatclass=boatclass, adaptiveclass=adaptiveclass, boattype=boattype, - ) + ).order_by("agemax","-agemin","boattype","sex") if standards.count()==0: standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age, - boattype=boattype) + boattype=boattype).order_by("agemax","-agemin","boattype","sex") if standards.count()==0: - standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age) + standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age).order_by("agemax","-agemin","boattype","sex") if standards.count()==0: # boolean, boattype, boatclass, adaptiveclass, weightclass, sex, coursestandard, From a128bdd530bdfcabaf8fbf9e1dea6a50778f0050 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 18:16:35 +0200 Subject: [PATCH 15/18] lw --- rowers/plannedsessions.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index de3698ac..2c649a6b 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1379,16 +1379,25 @@ def default_class(r,w,race): 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") + standards = CourseStandard.objects.filter( + agemin__lt=age,agemax__gt=age, + boatclass=boatclass, + adaptiveclass=adaptiveclass, + boattype=boattype, + ).order_by( + "agemax","-agemin","boattype","sex","weightcategory" + ) if standards.count()==0: - standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age, - boattype=boattype).order_by("agemax","-agemin","boattype","sex") + standards = CourseStandard.objects.filter( + agemin__lt=age,agemax__gt=age, + boattype=boattype + ).order_by( + "agemax","-agemin","boattype","sex") if standards.count()==0: - standards = CourseStandard.objects.filter(agemin__lt=age,agemax__gt=age).order_by("agemax","-agemin","boattype","sex") + standards = CourseStandard.objects.filter( + agemin__lt=age,agemax__gt=age + ).order_by( + "agemax","-agemin","boattype","sex") if standards.count()==0: # boolean, boattype, boatclass, adaptiveclass, weightclass, sex, coursestandard, From c04954daed6467a45e9b6843c2ae73ba7221fd3f Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 21 Jun 2020 18:19:17 +0200 Subject: [PATCH 16/18] filter by ref speed --- rowers/plannedsessions.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 2c649a6b..7f4d23c0 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1385,19 +1385,22 @@ def default_class(r,w,race): adaptiveclass=adaptiveclass, boattype=boattype, ).order_by( - "agemax","-agemin","boattype","sex","weightcategory" + "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") + "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") + "agemax","-agemin","boattype","sex", + "weightcategory","referencespeed") if standards.count()==0: # boolean, boattype, boatclass, adaptiveclass, weightclass, sex, coursestandard, From 745358a2c7f9d9ffb85054e81b57b21ee718c8df Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 22 Jun 2020 18:36:41 +0200 Subject: [PATCH 17/18] adding aws_region --- rowsandall_app/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index 04a621a1..aea004aa 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -379,7 +379,7 @@ CACHE_MIDDLEWARE_SECONDS = 900 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_ACCESS_KEY_ID = CFG['aws_access_key_id'] From 7beaec99e999f94a9d68f1a458ea94b9c69a5eb8 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 22 Jun 2020 18:46:18 +0200 Subject: [PATCH 18/18] updated reqs.txt --- requirements.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 25b00df6..8da2a8d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ apipkg==1.5 appdirs==1.4.3 arcgis==1.6.0 arrow==0.13.1 +asgiref==3.2.7 asn1crypto==0.24.0 atomicwrites==1.3.0 attrs==19.1.0 @@ -110,7 +111,7 @@ jupyterlab-server==0.3.0 keyring==18.0.0 kiwisolver==1.0.1 kombu==4.5.0 -llvmlite==0.33.0 +llvmlite==0.30.0 lxml==4.3.2 Markdown==3.0.1 MarkupSafe==1.1.1 @@ -128,7 +129,7 @@ newrelic==5.2.1.129 nose==1.3.7 nose-parameterized==0.6.0 notebook==5.7.6 -numba==0.50.0 +numba==0.46.0 numpy==1.18.5 oauth2==1.9.0.post1 oauthlib==3.0.1 @@ -151,7 +152,7 @@ protobuf==3.11.1 psycopg2==2.8.1 ptyprocess==0.6.0 py==1.8.0 -pyarrow==0.17.1 +pyarrow==0.15.0 pycairo==1.19.0 pycparser==2.19 Pygments==2.3.1 @@ -192,7 +193,7 @@ simplejson==3.16.0 six==1.12.0 soupsieve==1.8 SQLAlchemy==1.3.1 -sqlparse==0.3.0 +sqlparse==0.3.1 stravalib==0.10.2 termcolor==1.1.0 terminado==0.8.1