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/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/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/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) 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) diff --git a/rowers/views.py b/rowers/views.py index a1454f3e..4dd98d9b 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 = [] @@ -5989,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'] @@ -6020,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) @@ -6070,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 @@ -6089,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) @@ -6107,6 +6104,7 @@ def multiflex_data(request,userid=0, 'groupsize':groupsize, }) + if yparam == 'pace': df['y'] = dataprep.paceformatsecs(df['y']/1.0e3) @@ -6138,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.]) @@ -12485,9 +12484,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) diff --git a/static/css/styles2.css b/static/css/styles2.css index 216ac4fc..f736e859 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: #144f80; +/* 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: #1c75bc; } @@ -146,7 +150,8 @@ aside .cd-accordion-menu { width: 100%; max-width: 600px; - background: #35383d; + /* background: #35383d; */ + background: #144f80; } 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: #1c75bc; + /* background: #144f80; */ } .side-nav { grid-area: side-nav; - background: #1c75bc; + background: #1c75bc; + /* background: #144f80; */ + /* background: #1c75bc; */ } .side { grid-area: sidebar; - background: #35383d; + /* background: #35383d; */ + background: #144f80; /* border-top: 1px solid #dddddd; */ padding: 0; } .sideheader { grid-area: side-header; - color: #dddddd; - background: #35383d; + color: #f8f8ff; + /* color: #dddddd; */ + background: #144f80; +/* 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: #144f80; + /* background: #35383d; */ color: #dddddd; padding: 1em 1em 1em 1em; } @@ -461,7 +479,8 @@ .main-footer { grid-area: footer; - background: #ededed; + /* background: #ededed; */ + background: #f8f8ff; padding: 1.2em 1.2em 1.2em 1.2em; } 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 @@
+ alt="Rowsandall logo" width="250px">