diff --git a/rowers/courseutils.py b/rowers/courseutils.py index d864e372..32b38eb1 100644 --- a/rowers/courseutils.py +++ b/rowers/courseutils.py @@ -40,23 +40,23 @@ 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') + timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8') + with open(logfile,'ab') as f: + f.write(b'\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(b' ') + f.write(bytes(name,'utf-8')) + f.write(b' ') + f.write(bytes(maxmin,'utf-8')) + f.write(b' ') + f.write(bytes(str(getall),'utf-8')) + f.write(b' ') + f.write(bytes(str(len(df[b==2])),'utf-8')) + f.write(b' ') if len(df[b==2])>1: - f.write(' passes found') + f.write(b' passes found') else: - f.write(' pass found') + f.write(b' pass found') if getall: return df[b==2]['time'],df[b==2]['cum_dist'] else: @@ -64,20 +64,20 @@ def time_in_path(df,p,maxmin='max',getall=False,name='unknown',logfile=None): 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') + timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8') + with open(logfile,'ab') as f: + f.write(b'\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') + f.write(b' ') + f.write(bytes(name,'utf-8')) + f.write(b' ') + f.write(bytes(maxmin,'utf-8')) + f.write(b' ') + f.write(bytes(str(getall),'utf-8')) + f.write(b' ') + f.write(bytes(str(len(df[b==2])),'utf-8')) + f.write(b' ') + f.write(b' pass not found') raise InvalidTrajectoryError("Trajectory doesn't go through path") diff --git a/rowers/garmin_stuff.py b/rowers/garmin_stuff.py index 9e9502a1..3ce43ebf 100644 --- a/rowers/garmin_stuff.py +++ b/rowers/garmin_stuff.py @@ -135,7 +135,6 @@ def garmin_getworkout(garminid,r,activity): offset = activity['startTimeOffsetInSeconds'] except KeyError: offset = 0 - print(offset) durationseconds = activity['durationInSeconds'] duration = dataprep.totaltime_sec_to_string(durationseconds) activitytype = activity['activityType'] diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 0ea08a8b..be22200f 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -193,6 +193,7 @@ def interactive_hr_piechart(df,rower,title,totalseconds=0): qry = 'hr < {ut2}'.format(ut2=rower.ut2) frac_lut2 = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr + qry = '{ut2} <= hr < {ut1}'.format(ut1=rower.ut1,ut2=rower.ut2) frac_ut2 = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 709ccf1d..326b02d3 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -1385,7 +1385,7 @@ def default_class(r,w,race): adaptiveclass=adaptiveclass, boattype=boattype, ).order_by( - "agemax","-agemin","boattype","sex","weightcategory", + "agemax","-agemin","boattype","sex","weightclass", "referencespeed" ) if standards.count()==0: @@ -1394,7 +1394,7 @@ def default_class(r,w,race): boattype=boattype ).order_by( "agemax","-agemin","boattype","sex", - "weightcategory","referencespeed") + "weightclass","referencespeed") if standards.count()==0: standards = CourseStandard.objects.filter( agemin__lt=age,agemax__gt=age @@ -1404,15 +1404,15 @@ def default_class(r,w,race): if standards.count()==0: # boolean, boattype, boatclass, adaptiveclass, weightclass, sex, coursestandard, - return False,'1x','water',None,'hwt','male',None + return False,'1x','water',None,'hwt','male',5.0,None if standards.count()>0: # find optimum standard s = standards[0] - return True,s.boattype,s.boatclass,s.adaptiveclass,s.weightclass,s.sex,s + return True,s.boattype,s.boatclass,s.adaptiveclass,s.weightclass,s.sex,s.referencespeed,s # No Course Standard - return True,boattype,boatclass,adaptiveclass,weightclass,sex,None + return True,boattype,boatclass,adaptiveclass,weightclass,sex,5.0,None @@ -1472,7 +1472,7 @@ def add_workout_indoorrace(ws,race,r,recordid=0,doregister=False): ) except IndoorVirtualRaceResult.DoesNotExist: if doregister: - hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,ws[0],race) + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,referencespeed,initialcategory = default_class(r,ws[0],race) if hasinitial: record = IndoorVirtualRaceResult( userid = r.id, @@ -1483,6 +1483,7 @@ def add_workout_indoorrace(ws,race,r,recordid=0,doregister=False): boatclass=boatclass, sex=sex, age = age, + referencespeed=referencespeed, entrycategory=initialcategory, ) record.save() @@ -1624,7 +1625,7 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0,doregister=False): ) except VirtualRaceResult.DoesNotExist: if doregister: - hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,ws[0],race) + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,referencespeed,initialcategory = default_class(r,ws[0],race) if hasinitial: record = VirtualRaceResult( userid = r.id, @@ -1637,8 +1638,10 @@ def add_workout_race(ws,race,r,splitsecond=0,recordid=0,doregister=False): sex=sex, age = age, entrycategory=initialcategory, + referencespeed=referencespeed, ) record.save() + add_rower_race(r,race) else: errors.append("Unable to find a suitable start category") return result,comments,errors,0 diff --git a/rowers/tasks.py b/rowers/tasks.py index 26ef86e3..e83d08c3 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -197,9 +197,9 @@ def handle_strava_sync(stravatoken,workoutid,filename,name,activity_type,descrip except: e = sys.exc_info()[0] t = time.localtime() - timestamp = time.strftime('%b-%d-%Y_%H%M', t) - with open('stravalog.log','a') as f: - f.write('\n') + timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8') + with open('stravalog.log','ab') as f: + f.write(b'\n') f.write(timestamp) f.write(str(e)) @@ -446,15 +446,15 @@ def handle_check_race_course(self, try: entrytimes,entrydistances = time_in_path(rowdata,paths[0],maxmin='max',getall=True, name=polygons[0].name,logfile=logfile) - with open(logfile,'a') as f: + with open(logfile,'ab') as f: t = time.localtime() - timestamp = time.strftime('%b-%d-%Y_%H%M', t) - f.write('\n') - f.write('Course id {n}, Record id {m}'.format(n=courseid,m=recordid)) - f.write('\n') + timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8') + f.write(b'\n') + f.write(bytes('Course id {n}, Record id {m}'.format(n=courseid,m=recordid),'utf-8')) + f.write(b'\n') f.write(timestamp) - f.write(' ') - f.write('Found {n} entrytimes'.format(n=len(entrytimes))) + f.write(b' ') + f.write(bytes('Found {n} entrytimes'.format(n=len(entrytimes)),'utf-8')) except InvalidTrajectoryError: entrytimes = [] @@ -471,13 +471,13 @@ def handle_check_race_course(self, endseconds = [] for startt in entrytimes: - with open(logfile,'a') as f: + with open(logfile,'ab') as f: t = time.localtime() - timestamp = time.strftime('%b-%d-%Y_%H%M', t) - f.write('\n') + timestamp = bytes('{t}'.format(t=time.strftime('%b-%d-%Y_%H%M', t)),'utf-8') + f.write(b'\n') f.write(timestamp) - f.write(' ') - f.write('Path starting at {t}'.format(t=startt)) + f.write(b' ') + f.write(bytes('Path starting at {t}'.format(t=startt),'utf-8')) rowdata2 = rowdata[rowdata['time']>(startt-10.)] ( @@ -587,13 +587,26 @@ def handle_check_race_course(self, endsecond=endsecond, ) - with engine.connect() as conn, conn.begin(): result = conn.execute(query) conn.close() engine.dispose() + # add times for all gates to log file + with open(logfile,'ab') as f: + t = time.localtime() + f.write(b'\n') + f.write(b' ') + f.write(b'--- LOG of all gate times---') + + for path,polygon in zip(paths,polygons): + ( secs,meters,completed) = coursetime_paths(rowdata2, + [path],polygons=[polygon],logfile=logfile) + with open(logfile,'ab') as f: + line = " time: {t} seconds, distance: {m} meters".format(t=secs,m=meters) + f.write(bytes(line,'utf-8')) + # send email handle_sendemail_coursefail( useremail,userfirstname,logfile diff --git a/rowers/templates/rower_exportsettings.html b/rowers/templates/rower_exportsettings.html index 8e7f66d2..69a6bc40 100644 --- a/rowers/templates/rower_exportsettings.html +++ b/rowers/templates/rower_exportsettings.html @@ -34,10 +34,11 @@ alt="connect with Polar" width="130">
+ {% endblock %} diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py index 3abb8944..ef9e3935 100644 --- a/rowers/tests/test_imports.py +++ b/rowers/tests/test_imports.py @@ -109,7 +109,7 @@ class GarminObjects(DjangoTestCase): self.assertEqual(len(data),2) def test_garmin_deregistration(self): - data = {"userAccessToken":"dfdzf"} + data = {"deregistrations":[{"userAccessToken":"dfdzf"}]} response = self.c.post('/rowers/garmin/deregistration/',json.dumps(data), content_type='application/json') diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index b02a7cb9..15de14d7 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -4721,7 +4721,6 @@ def history_view(request,userid=0): totalmeters,totalhours, totalminutes, totalseconds = get_totals(g_workouts) - # meters, duration per workout type wtypes = list(set([w.workouttype for w in g_workouts])) @@ -4860,14 +4859,13 @@ def history_view_data(request,userid=0): df = getsmallrowdata_db(columns,ids=ids) try: - df['deltat'] = df['time'].diff() + df['deltat'] = df['time'].diff().clip(lower=0) except KeyError: pass df = dataprep.clean_df_stats(df,workstrokesonly=True, ignoreadvanced=True,ignorehr=False) totalmeters,totalhours, totalminutes,totalseconds = get_totals(g_workouts) - # meters, duration per workout type wtypes = list(set([w.workouttype for w in g_workouts])) @@ -4895,7 +4893,7 @@ def history_view_data(request,userid=0): ) ddf = getsmallrowdata_db(columns,ids=[w.id for w in a_workouts]) try: - ddf['deltat'] = ddf['time'].diff() + ddf['deltat'] = ddf['time'].diff().clip(lower=0) except KeyError: pass ddf = dataprep.clean_df_stats(ddf,workstrokesonly=True, @@ -4944,7 +4942,7 @@ def history_view_data(request,userid=0): totalseconds = 3600*hours+60*minutes+seconds ddf = getsmallrowdata_db(columns,ids=[w.id for w in a_workouts]) try: - ddf['deltat'] = ddf['time'].diff() + ddf['deltat'] = ddf['time'].diff().clip(lower=0) except KeyError: pass ddf = dataprep.clean_df_stats(ddf,workstrokesonly=True, diff --git a/rowers/views/importviews.py b/rowers/views/importviews.py index 10573f7f..a512eca1 100644 --- a/rowers/views/importviews.py +++ b/rowers/views/importviews.py @@ -1036,26 +1036,19 @@ def garmin_deregistration_view(request): if request.method != 'POST': return HttpResponse(status=200) - t = time.localtime() - timestamp = time.strftime('%b-%d-%Y_%H%M', t) - with open('garminlog.log','a') as f: - f.write('\n') - f.write(timestamp) - f.write(' ') - f.write(str(request.body)) - data = json.loads(request.body) - try: - garmintoken = data['userAccessToken'] - except KeyError: - print(data) - return HttpResponse(status=200) - try: - r = Rower.objects.get(garmintoken=garmintoken) - r.garmintoken = '' - r.save() - except Rower.DoesNotExist: - return HttpResponse(status=200) + deregistrations = data['deregistrations'] + for deregistration in deregistrations: + try: + garmintoken = deregistration['userAccessToken'] + try: + r = Rower.objects.get(garmintoken=garmintoken) + r.garmintoken = '' + r.save() + except Rower.DoesNotExist: + pass + except KeyError: + pass return HttpResponse(status=200) diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index 7db2babe..2de4b7a6 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -1967,7 +1967,11 @@ def plannedsession_view(request,id=0,userid=0): microsecs = 0 # taking workout duration plus 1 minute penalty - wdict['time'] = w.duration + wdict['time'] = datetime.timedelta( + hours=w.duration.hour, + minutes=w.duration.minute, + seconds=w.duration.second, + ) wdict['distance'] = ps.course.distance wdict['coursecompleted'] = False diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index a68ef3ba..8fd04b04 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -1631,7 +1631,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) + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,referencespeed,initialcategory = default_class(r,None,race) if race.coursestandards is not None: categories = CourseStandard.objects.filter( standardcollection=race.coursestandards).order_by("name") @@ -1918,7 +1918,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) + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,referencespeed,initialcategory = default_class(r,None,race) if race.coursestandards is not None: categories = CourseStandard.objects.filter( standardcollection=race.coursestandards).order_by("name") @@ -2943,7 +2943,7 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0): ) if records.count() == 0: - hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,initialcategory = default_class(r,None,race) + hasinitial,boattype,boatclass,adaptiveclass,weightclass,sex,referencespeed,initialcategory = default_class(r,None,race) if not hasinitial: messages.error(request,"Sorry, you have to register first") url = reverse('virtualevent_view', @@ -2961,6 +2961,7 @@ def virtualevent_submit_result_view(request,id=0,workoutid=0): sex=sex, age=calculate_age(r.birthdate), entrycategory=initialcategory, + referencespeed=referencespeed, ) record.save() records = [record] @@ -3277,6 +3278,7 @@ def virtualevent_entry_edit_view(request,id=0,entryid=0): if form.is_valid(): cd = form.cleaned_data + teamname = cd['teamname'] try: boattype = cd['boattype'] @@ -3293,12 +3295,12 @@ def virtualevent_entry_edit_view(request,id=0,entryid=0): acceptsocialmedia = cd['acceptsocialmedia'] sex = r.sex + if mix: sex = 'mixed' if boattype == '1x' and r.birthdate: age = calculate_age(r.birthdate) - sex = r.sex if sex == 'not specified': sex = 'male' @@ -3328,6 +3330,7 @@ def virtualevent_entry_edit_view(request,id=0,entryid=0): messages.error(request,'You are older than the maximum age for this group') return HttpResponseRedirect(returnurl) + print(sex,coursestandard.sex) if sex == 'male' and coursestandard.sex != 'male': messages.error(request,'Men are not allowed to enter this category') return HttpResponseRedirect(returnurl)