From 9d303c36dd2fdc3a54a44a3a704a445324b734d4 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 15 Nov 2018 13:40:57 +0100 Subject: [PATCH 1/8] blue side bar, top nav bar light blue, larger logo --- rowers/mytypes.py | 30 ++++++++++++------------- static/css/styles2.css | 50 ++++++++++++++++++++++++++++-------------- templates/newbase.html | 2 +- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/rowers/mytypes.py b/rowers/mytypes.py index 7eb07b6a..884f8013 100644 --- a/rowers/mytypes.py +++ b/rowers/mytypes.py @@ -11,33 +11,33 @@ workouttypes = ( ('c-boat','Dutch C boat'), ('churchboat','Finnish Church boat'), ('Ride','Ride'), - ('Kitesurf','Kitesurf'), +# ('Kitesurf','Kitesurf'), ('Run','Run'), ('NordicSki','NordicSki'), ('Swim','Swim'), - ('RockClimbing','RockClimbing'), +# ('RockClimbing','RockClimbing'), ('Hike','Hike'), - ('RollerSki','RollerSki'), - ('Walk','Walk'), - ('AlpineSki','AlpineSki'), - ('Snowboard','Snowboard'), - ('BackcountrySki','BackcountrySki'), - ('Snowshoe','Snowshoe'), +# ('RollerSki','RollerSki'), +# ('Walk','Walk'), +# ('AlpineSki','AlpineSki'), +# ('Snowboard','Snowboard'), +# ('BackcountrySki','BackcountrySki'), +# ('Snowshoe','Snowshoe'), ('Canoeing','Canoeing'), - ('StairStepper','StairStepper'), +# ('StairStepper','StairStepper'), ('Crossfit','Crossfit'), ('StandUpPaddling','StandUpPaddling'), - ('EBikeRide','EBikeRide'), - ('Surfing','Surfing'), - ('Elliptical','Elliptical'), - ('VirtualRide','VirtualRide'), +# ('EBikeRide','EBikeRide'), +# ('Surfing','Surfing'), +# ('Elliptical','Elliptical'), +# ('VirtualRide','VirtualRide'), ('IceSkate','IceSkate'), ('WeightTraining','WeightTraining'), ('InlineSkate','InlineSkate'), - ('Windsurf','Windsurf'), +# ('Windsurf','Windsurf'), ('Kayaking','Kayaking'), ('Workout','Workout'), - ('Yoga','Yoga'), +# ('Yoga','Yoga'), ('other','Other'), ) diff --git a/static/css/styles2.css b/static/css/styles2.css index 216ac4fc..3d68d2cd 100644 --- a/static/css/styles2.css +++ b/static/css/styles2.css @@ -75,7 +75,8 @@ font-weight: bold; text-align: left; font-size: 1.4em; - color: #dddddd; + /* color: #dddddd; */ + color: #f8f8ff; padding: 15px; } @@ -83,7 +84,8 @@ font-weight: bold; text-align: left; font-size: 1.0em; - color: #dddddd; + color: #f8f8ff; +/* color: #dddddd; */ } @@ -120,7 +122,8 @@ aside ul ul ul a { list-style: none; margin: 0; - background: #35383d; + background: #1c75bc; +/* background: #35383d; */ } @@ -130,7 +133,8 @@ aside ul ul a:hover, aside ul ul ul label:hover, aside ul ul ul a:hover { - background: #4d5158; + /* background: #4d5158; */ + background: #144f80; } @@ -146,7 +150,8 @@ aside .cd-accordion-menu { width: 100%; max-width: 600px; - background: #35383d; + /* background: #35383d; */ + background: #1c75bc; } aside .cd-accordion-menu ul { @@ -171,7 +176,8 @@ aside .cd-accordion-menu a { position: relative; display: block; - color: #dddddd; + color: #f8f8ff; + /* color: #dddddd; */ font-size: 1.0em; } @@ -359,14 +365,16 @@ .main-head { grid-area: header; - background: #ededed; + /* background: #ededed; */ + background: #f8f8ff; } .main-user { grid-area: user; - background: #ededed; +/* background: #ededed; */ + background: #f8f8ff; } .content { @@ -396,30 +404,38 @@ .main-nav { grid-area: nav; - background: #1c75bc; + /* background: #1c75bc; */ + background: #27aae1; + /* background: #144f80; */ } .side-nav { grid-area: side-nav; - background: #1c75bc; + background: #27aae1; + /* background: #144f80; */ + /* background: #1c75bc; */ } .side { grid-area: sidebar; - background: #35383d; + /* background: #35383d; */ + background: #1c75bc; /* border-top: 1px solid #dddddd; */ padding: 0; } .sideheader { grid-area: side-header; - color: #dddddd; - background: #35383d; + color: #f8f8ff; + /* color: #dddddd; */ + background: #1c75bc; +/* background: #35383d; */ padding: 0; } .side h2 { - color: #dddddd; + color: #f8f8ff; + /* color: #dddddd; */ font-weight: bold; text-align: left; font-size: 1.0em; @@ -433,7 +449,8 @@ font-weight: bold; text-align: left; font-size: 1.4em; - color: #dddddd; + color: #f8f8ff; + /* color: #dddddd; */ padding: 5px; margin: 0; margin-left: 30px; @@ -442,7 +459,8 @@ .ad { grid-area: ad; - background: #35383d; + background: #1c75bc; + /* background: #35383d; */ color: #dddddd; padding: 1em 1em 1em 1em; } diff --git a/templates/newbase.html b/templates/newbase.html index 11a5ece0..e62b0448 100644 --- a/templates/newbase.html +++ b/templates/newbase.html @@ -131,7 +131,7 @@
  • Rowsandall logo + alt="Rowsandall logo" width="250px">
  • From 70310b60b1e84fa863061560814283e7ca3f3c7e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 15 Nov 2018 13:52:55 +0100 Subject: [PATCH 2/8] lightening up footer --- static/css/styles2.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/css/styles2.css b/static/css/styles2.css index 3d68d2cd..14fd978e 100644 --- a/static/css/styles2.css +++ b/static/css/styles2.css @@ -479,7 +479,8 @@ .main-footer { grid-area: footer; - background: #ededed; + /* background: #ededed; */ + background: #f8f8ff; padding: 1.2em 1.2em 1.2em 1.2em; } From 6be0ed8667a837b5c2383f1229c1c4d73a71e147 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 15 Nov 2018 14:16:15 +0100 Subject: [PATCH 3/8] darker variation --- static/css/styles2.css | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/static/css/styles2.css b/static/css/styles2.css index 14fd978e..f736e859 100644 --- a/static/css/styles2.css +++ b/static/css/styles2.css @@ -122,7 +122,7 @@ aside ul ul ul a { list-style: none; margin: 0; - background: #1c75bc; + background: #144f80; /* background: #35383d; */ } @@ -134,7 +134,7 @@ aside ul ul ul label:hover, aside ul ul ul a:hover { /* background: #4d5158; */ - background: #144f80; + background: #1c75bc; } @@ -151,7 +151,7 @@ width: 100%; max-width: 600px; /* background: #35383d; */ - background: #1c75bc; + background: #144f80; } aside .cd-accordion-menu ul { @@ -405,13 +405,13 @@ .main-nav { grid-area: nav; /* background: #1c75bc; */ - background: #27aae1; + background: #1c75bc; /* background: #144f80; */ } .side-nav { grid-area: side-nav; - background: #27aae1; + background: #1c75bc; /* background: #144f80; */ /* background: #1c75bc; */ } @@ -419,7 +419,7 @@ .side { grid-area: sidebar; /* background: #35383d; */ - background: #1c75bc; + background: #144f80; /* border-top: 1px solid #dddddd; */ padding: 0; } @@ -428,7 +428,7 @@ grid-area: side-header; color: #f8f8ff; /* color: #dddddd; */ - background: #1c75bc; + background: #144f80; /* background: #35383d; */ padding: 0; } @@ -459,7 +459,7 @@ .ad { grid-area: ad; - background: #1c75bc; + background: #144f80; /* background: #35383d; */ color: #dddddd; padding: 1em 1em 1em 1em; From bd2c6a21b93d2ed272a97a34f8e6caa9996c63a4 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 18 Nov 2018 11:04:07 +0100 Subject: [PATCH 4/8] small bug fix --- rowers/views.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rowers/views.py b/rowers/views.py index a1454f3e..3c62bafd 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -12485,9 +12485,12 @@ def workout_summary_edit_view(request,id,message="",successmessage="" initial = {} for i in xrange(nrintervals): - initial['intervald_%s' % i] = idist[i] - initial['intervalt_%s' % i] = get_time(itime[i]) - initial['type_%s' % i] = itype[i] + try: + initial['intervald_%s' % i] = idist[i] + initial['intervalt_%s' % i] = get_time(itime[i]) + initial['type_%s' % i] = itype[i] + except IndexError: + pass detailform = IntervalUpdateForm(aantal=nrintervals,initial=initial) From 886b05fe8a73f46498a52606581ca1ce76410585 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 19 Nov 2018 11:29:10 +0100 Subject: [PATCH 5/8] bug fixes --- rowers/models.py | 20 ++++++++++++++++---- rowers/tasks.py | 28 +++++++++++++++------------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index dfa1726a..a07bbc68 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.db import models +from django.db import models,IntegrityError from django.contrib.auth.models import User from django.core.validators import validate_email from django.core.exceptions import ValidationError @@ -201,9 +201,11 @@ def update_records(url=c2url): name = name, ) try: - record.save() - except: print record + record.save() + except IntegrityError: + print(record,'*') + class CalcAgePerformance(models.Model): @@ -281,7 +283,17 @@ class C2WorldClassAgePerformance(models.Model): unique_together = ('age','sex','weightcategory','distance') def __unicode__(self): - return self.sex+' '+self.weightcategory+' '+self.name+':'+str(self.age)+' ('+str(self.season)+')' + thestring = '{s} {w} {n} age {a} ({season}) {distance}m {duration} seconds'.format( + s = self.sex, + w = self.weightcategory, + n = self.name, + a = self.age, + season = self.season, + distance = self.distance, + duration = self.duration, + ) + + return thestring # For future Team functionality class Team(models.Model): diff --git a/rowers/tasks.py b/rowers/tasks.py index 51e86064..c7219c3d 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -405,12 +405,13 @@ def handle_getagegrouprecords(self, weightcategory=weightcategory,indf=df, ) velo = (worldclasspower/2.8)**(1./3.) - try: - duration = distance/velo - wcdurations.append(duration) - wcpower.append(worldclasspower) - except ZeroDivisionError: - pass + if not np.isinf(worldclasspower) and not np.isnan(worldclasspower): + try: + duration = distance/velo + wcdurations.append(duration) + wcpower.append(worldclasspower) + except ZeroDivisionError: + pass @@ -421,13 +422,14 @@ def handle_getagegrouprecords(self, duration=duration, weightcategory=weightcategory,indf=df ) - try: - velo = (worldclasspower/2.8)**(1./3.) - distance = int(60*duration*velo) - wcdurations.append(60.*duration) - wcpower.append(worldclasspower) - except ValueError: - pass + if not np.isinf(worldclasspower) and not np.isnan(worldclasspower): + try: + velo = (worldclasspower/2.8)**(1./3.) + distance = int(60*duration*velo) + wcdurations.append(60.*duration) + wcpower.append(worldclasspower) + except ValueError: + pass update_agegroup_db(age,sex,weightcategory,wcdurations,wcpower, debug=debug) From f155e9800c1e271858f2e5827825c8d9678ed01b Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 19 Nov 2018 21:09:42 +0100 Subject: [PATCH 6/8] small strava sync correction --- rowers/stravastuff.py | 5 +++++ rowers/uploads.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rowers/stravastuff.py b/rowers/stravastuff.py index fdad80f4..30835e14 100644 --- a/rowers/stravastuff.py +++ b/rowers/stravastuff.py @@ -590,6 +590,11 @@ def add_workout_from_data(user,importid,data,strokedata, return id,message def workout_strava_upload(user,w): + try: + thetoken = strava_open(user) + except NoTokenError: + return "Please connect to Strava first",0 + message = "Uploading to Strava" stravaid=-1 r = Rower.objects.get(user=user) diff --git a/rowers/uploads.py b/rowers/uploads.py index 6aeca4d7..ac60340c 100644 --- a/rowers/uploads.py +++ b/rowers/uploads.py @@ -294,7 +294,7 @@ def upload_options(body): try: for key, value in yml.iteritems(): lowkey = key.lower() - if lowkey == 'sync' or lowkey == 'synchronization': + if lowkey == 'sync' or lowkey == 'synchronization' or lowkey == 'export': uploadoptions = getsyncoptions(uploadoptions,value) if lowkey == 'chart' or lowkey == 'static' or lowkey == 'plot': uploadoptions = getplotoptions(uploadoptions,value) From 3a16d9b7863655444a40802d8ab79ba9b639724c Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 19 Nov 2018 21:28:09 +0100 Subject: [PATCH 7/8] fixed thumbnail fav charts bug --- rowers/views.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/rowers/views.py b/rowers/views.py index 3c62bafd..790209f4 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -643,17 +643,7 @@ def get_thumbnails(request,id): aantalcomments = len(comments) - workouttype = 'ote' - if row.workouttype in mytypes.otwtypes: - workouttype = 'otw' - - try: - favorites = FavoriteChart.objects.filter(user=r, - workouttype__in=[workouttype,'both']).order_by("id") - maxfav = len(favorites)-1 - except: - favorites = None - maxfav = 0 + favorites,maxfav = getfavorites(r,row) charts = [] From a02ef7233e66dd373a5cabc30bfb5eec1e92070e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 20 Nov 2018 20:51:33 +0100 Subject: [PATCH 8/8] bug fix (dataframe index same as x axis name in multi flex) --- rowers/interactiveplots.py | 4 ++++ rowers/views.py | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index c08ef90d..316f7fe5 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -94,6 +94,7 @@ def errorbar(fig, x, y, source=ColumnDataSource(), xvalues = source.data[x] yvalues = source.data[y] + xerrvalues = source.data['xerror'] yerrvalues = source.data['yerror'] try: @@ -2362,10 +2363,13 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', if yparam == 'pace': y_axis_type = 'datetime' + datadf.index.names = ['index'] + source = ColumnDataSource( datadf, ) + TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,resize' if groupby != 'date': diff --git a/rowers/views.py b/rowers/views.py index 790209f4..4dd98d9b 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -5979,6 +5979,7 @@ def multiflex_data(request,userid=0, if userid==0: userid = request.user.id + palette = options['palette'] groupby = options['groupby'] binsize = options['binsize'] @@ -6010,6 +6011,9 @@ def multiflex_data(request,userid=0, # prepare data frame datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist) + if xparam == groupby: + datadf['groupby'] = datadf[xparam] + groupy = 'groupby' datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) @@ -6060,14 +6064,18 @@ def multiflex_data(request,userid=0, labels=False)) - xvalues = groups.mean()[xparam] + xvalues = groups.mean()[xparam] yvalues = groups.mean()[yparam] xerror = groups.std()[xparam] yerror = groups.std()[yparam] groupsize = groups.count()[xparam] + print groupsize.sum(),groupsize.mean() + mask = groupsize <= min([0.01*groupsize.sum(),0.2*groupsize.mean()]) + print '--------------------------' xvalues.loc[mask] = np.nan + yvalues.loc[mask] = np.nan xerror.loc[mask] = np.nan yerror.loc[mask] = np.nan @@ -6079,7 +6087,6 @@ def multiflex_data(request,userid=0, yerror.dropna(inplace=True) groupsize.dropna(inplace=True) - if len(groupsize) == 0: messages.error(request,'No data in selection') url = reverse(user_multiflex_select) @@ -6097,6 +6104,7 @@ def multiflex_data(request,userid=0, 'groupsize':groupsize, }) + if yparam == 'pace': df['y'] = dataprep.paceformatsecs(df['y']/1.0e3) @@ -6128,8 +6136,9 @@ def multiflex_data(request,userid=0, df['groupval'] = groups.mean()['days ago'].fillna(value=0) groupcols = 100.*np.arange(aantal)/float(aantal) - + groupcols = (groupcols-groupcols.min())/(groupcols.max()-groupcols.min()) + if aantal == 1: groupcols = np.array([1.])