Merge branch 'release/v9.55'
This commit is contained in:
+7
-1
@@ -83,7 +83,7 @@ queuelow = django_rq.get_queue('low')
|
|||||||
queuehigh = django_rq.get_queue('default')
|
queuehigh = django_rq.get_queue('default')
|
||||||
|
|
||||||
from rowsandall_app.settings import SITE_URL
|
from rowsandall_app.settings import SITE_URL
|
||||||
from rowers.mytypes import otwtypes
|
from rowers.mytypes import otwtypes,otetypes
|
||||||
|
|
||||||
from rowers.database import *
|
from rowers.database import *
|
||||||
from rowers.opaque import encoder
|
from rowers.opaque import encoder
|
||||||
@@ -998,6 +998,8 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
|||||||
if dosummary:
|
if dosummary:
|
||||||
summary = row.allstats()
|
summary = row.allstats()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
timezone_str = 'UTC'
|
timezone_str = 'UTC'
|
||||||
try:
|
try:
|
||||||
workoutstartdatetime = timezone.make_aware(row.rowdatetime)
|
workoutstartdatetime = timezone.make_aware(row.rowdatetime)
|
||||||
@@ -1050,6 +1052,9 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
|||||||
maxhr = np.nan_to_num(maxhr)
|
maxhr = np.nan_to_num(maxhr)
|
||||||
averagehr = np.nan_to_num(averagehr)
|
averagehr = np.nan_to_num(averagehr)
|
||||||
|
|
||||||
|
dragfactor = 0
|
||||||
|
if workouttype in otetypes:
|
||||||
|
dragfactor = row.dragfactor
|
||||||
|
|
||||||
t = datetime.datetime.strptime(duration,"%H:%M:%S.%f")
|
t = datetime.datetime.strptime(duration,"%H:%M:%S.%f")
|
||||||
delta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
|
delta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
|
||||||
@@ -1079,6 +1084,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
|||||||
w = Workout(user=r, name=title, date=workoutdate,
|
w = Workout(user=r, name=title, date=workoutdate,
|
||||||
workouttype=workouttype,
|
workouttype=workouttype,
|
||||||
boattype=boattype,
|
boattype=boattype,
|
||||||
|
dragfactor=dragfactor,
|
||||||
duration=duration, distance=totaldist,
|
duration=duration, distance=totaldist,
|
||||||
weightcategory=weightcategory,
|
weightcategory=weightcategory,
|
||||||
adaptiveclass=adaptiveclass,
|
adaptiveclass=adaptiveclass,
|
||||||
|
|||||||
@@ -748,7 +748,8 @@ def fitnessmetric_chart(fitnessmetrics,user,workoutmode='rower',startdate=None,
|
|||||||
power2k = power2k,
|
power2k = power2k,
|
||||||
date = date,
|
date = date,
|
||||||
power1hr = power1hr,
|
power1hr = power1hr,
|
||||||
fdate=groups['dates'].map(lambda x: x.strftime('%d-%m-%Y')) )
|
fdate=groups['dates'].map(lambda x: x.strftime('%Y-%m-%d'))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -3146,7 +3147,7 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
|
|
||||||
|
|
||||||
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
||||||
tools=TOOLS,
|
tools=TOOLS,toolbar_location='above',
|
||||||
toolbar_sticky=False
|
toolbar_sticky=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2536,6 +2536,7 @@ class Workout(models.Model):
|
|||||||
max_length=100)
|
max_length=100)
|
||||||
distance = models.IntegerField(default=0,blank=True)
|
distance = models.IntegerField(default=0,blank=True)
|
||||||
duration = models.TimeField(default=1,blank=True)
|
duration = models.TimeField(default=1,blank=True)
|
||||||
|
dragfactor = models.IntegerField(default=0,blank=True)
|
||||||
trimp = models.IntegerField(default=-1,blank=True)
|
trimp = models.IntegerField(default=-1,blank=True)
|
||||||
rscore = models.IntegerField(default=-1,blank=True)
|
rscore = models.IntegerField(default=-1,blank=True)
|
||||||
hrtss = models.IntegerField(default=-1,blank=True)
|
hrtss = models.IntegerField(default=-1,blank=True)
|
||||||
@@ -2960,6 +2961,7 @@ class WorkoutForm(ModelForm):
|
|||||||
'distance',
|
'distance',
|
||||||
'workouttype',
|
'workouttype',
|
||||||
'boattype',
|
'boattype',
|
||||||
|
'dragfactor',
|
||||||
'weightcategory',
|
'weightcategory',
|
||||||
'adaptiveclass',
|
'adaptiveclass',
|
||||||
'notes',
|
'notes',
|
||||||
|
|||||||
+19
-19
@@ -265,10 +265,10 @@ def handle_check_race_course(self,
|
|||||||
row = rdata(csvfile=f1)
|
row = rdata(csvfile=f1)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
row = rdata(f1 + '.csv')
|
row = rdata(csvfile=f1 + '.csv')
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
row = rdata(f1 + '.gz')
|
row = rdata(csvfile=f1 + '.gz')
|
||||||
except IOError:
|
except IOError:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -526,13 +526,13 @@ def handle_update_empower(self,
|
|||||||
|
|
||||||
havedata = 1
|
havedata = 1
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(csvfile=f1)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.csv')
|
rowdata = rdata(csvfile=f1 + '.csv')
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.gz')
|
rowdata = rdata(csvfile=f1 + '.gz')
|
||||||
except IOError:
|
except IOError:
|
||||||
havedata = 0
|
havedata = 0
|
||||||
|
|
||||||
@@ -597,13 +597,13 @@ def handle_calctrimp(id,
|
|||||||
engine = create_engine(database_url, echo=False)
|
engine = create_engine(database_url, echo=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(csvfilename)
|
rowdata = rdata(csvfile=csvfilename)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(csvfilename + '.csv')
|
rowdata = rdata(csvfile=csvfilename + '.csv')
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(csvfilename + '.gz')
|
rowdata = rdata(csvfile=csvfilename + '.gz')
|
||||||
except IOError:
|
except IOError:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -719,13 +719,13 @@ def handle_updatedps(useremail, workoutids, debug=False,**kwargs):
|
|||||||
for wid, f1 in workoutids:
|
for wid, f1 in workoutids:
|
||||||
havedata = 1
|
havedata = 1
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(csvfile=f1)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.csv')
|
rowdata = rdata(csvfile=f1 + '.csv')
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.gz')
|
rowdata = rdata(csvfile=f1 + '.gz')
|
||||||
except IOError:
|
except IOError:
|
||||||
havedata = 0
|
havedata = 0
|
||||||
|
|
||||||
@@ -1384,12 +1384,12 @@ def handle_otwsetpower(self,f1, boattype, weightvalue,
|
|||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(csvfile=f1)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.csv')
|
rowdata = rdata(csvfile=f1 + '.csv')
|
||||||
except IOError:
|
except IOError:
|
||||||
rowdata = rdata(f1 + '.gz')
|
rowdata = rdata(csvfile=f1 + '.gz')
|
||||||
|
|
||||||
weightvalue = float(weightvalue)
|
weightvalue = float(weightvalue)
|
||||||
|
|
||||||
@@ -1490,13 +1490,13 @@ def handle_updateergcp(rower_id,workoutfilenames,debug=False,**kwargs):
|
|||||||
therows = []
|
therows = []
|
||||||
for f1 in workoutfilenames:
|
for f1 in workoutfilenames:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1)
|
rowdata = rdata(csvfile=f1)
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.csv')
|
rowdata = rdata(csvfile=f1 + '.csv')
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
try:
|
||||||
rowdata = rdata(f1 + '.gz')
|
rowdata = rdata(csvfile=f1 + '.gz')
|
||||||
except IOError:
|
except IOError:
|
||||||
rowdata = 0
|
rowdata = 0
|
||||||
if rowdata != 0:
|
if rowdata != 0:
|
||||||
@@ -1653,9 +1653,9 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename,
|
|||||||
ftp=ftp, powerperc=powerperc,
|
ftp=ftp, powerperc=powerperc,
|
||||||
powerzones=powerzones)
|
powerzones=powerzones)
|
||||||
try:
|
try:
|
||||||
row = rdata(f2, rower=rr)
|
row = rdata(csvfile=f2, rower=rr)
|
||||||
except IOError:
|
except IOError:
|
||||||
row = rdata(f2 + '.gz', rower=rr)
|
row = rdata(csvfile=f2 + '.gz', rower=rr)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
haspower = row.df[' Power (watts)'].mean() > 50
|
haspower = row.df[' Power (watts)'].mean() > 50
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ $( document ).ready(function() {
|
|||||||
$('#id_boattype').toggle(false);
|
$('#id_boattype').toggle(false);
|
||||||
$('#id_boattype').val('1x');
|
$('#id_boattype').val('1x');
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
$(this).val() == 'rower'
|
||||||
|
|| $(this).val() == 'dynamic'
|
||||||
|
|| $(this).val() == 'slides'
|
||||||
|
) {
|
||||||
|
$('#id_dragfactor').toggle(true);
|
||||||
|
} else {
|
||||||
|
$('#id_dragfactor').toggle(false);
|
||||||
|
$('#id_dragfactor').val('0');
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
$('#id_workouttype').change();
|
$('#id_workouttype').change();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from rowers.utils import calculate_age
|
|||||||
from rowers.models import (
|
from rowers.models import (
|
||||||
course_length,WorkoutComment,
|
course_length,WorkoutComment,
|
||||||
TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle,
|
TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle,
|
||||||
Rower,Workout
|
Rower,Workout,SiteAnnouncement
|
||||||
)
|
)
|
||||||
from rowers.plannedsessions import (
|
from rowers.plannedsessions import (
|
||||||
race_can_register, race_can_submit,race_rower_status
|
race_can_register, race_can_submit,race_rower_status
|
||||||
@@ -33,6 +33,12 @@ import arrow
|
|||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def nogoals(user):
|
||||||
|
targets = TrainingTarget.objects.filter(rowers=user.rower,
|
||||||
|
date__gte=datetime.date.today())
|
||||||
|
return len(targets)==0
|
||||||
|
|
||||||
def strfdelta(tdelta):
|
def strfdelta(tdelta):
|
||||||
minutes,seconds = divmod(tdelta.seconds,60)
|
minutes,seconds = divmod(tdelta.seconds,60)
|
||||||
tenths = int(tdelta.microseconds/1e5)
|
tenths = int(tdelta.microseconds/1e5)
|
||||||
@@ -333,6 +339,15 @@ def user_teams(user):
|
|||||||
|
|
||||||
return teams
|
return teams
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def announcements(request):
|
||||||
|
announcements = SiteAnnouncement.objects.filter(
|
||||||
|
expires__gte=datetime.date.today()).order_by(
|
||||||
|
"-created",
|
||||||
|
"-id"
|
||||||
|
)
|
||||||
|
|
||||||
|
return announcements[0:4]
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def has_teams(user):
|
def has_teams(user):
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ class ViewTest(TestCase):
|
|||||||
'adaptiveclass':'PR1',
|
'adaptiveclass':'PR1',
|
||||||
'workouttype':'rower',
|
'workouttype':'rower',
|
||||||
'boattype':'1x',
|
'boattype':'1x',
|
||||||
|
'dragfactor':'112',
|
||||||
'private':True,
|
'private':True,
|
||||||
'notes':'noot mies',
|
'notes':'noot mies',
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -147,6 +147,8 @@ urlpatterns = [
|
|||||||
name='workouts_view'),
|
name='workouts_view'),
|
||||||
# url(r'^(?P<rowerid>\d+)/list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
# url(r'^(?P<rowerid>\d+)/list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
||||||
# name='workouts_view'),
|
# name='workouts_view'),
|
||||||
|
url(r'^list-workouts/ranking/user/(?P<userid>\d+)/$',views.workouts_view,{'rankingonly':True},
|
||||||
|
name='workouts_view'),
|
||||||
url(r'^list-workouts/user/(?P<userid>\d+)/$',views.workouts_view,
|
url(r'^list-workouts/user/(?P<userid>\d+)/$',views.workouts_view,
|
||||||
name='workouts_view'),
|
name='workouts_view'),
|
||||||
# url(r'^list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.workouts_view,
|
# url(r'^list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.workouts_view,
|
||||||
|
|||||||
@@ -3328,6 +3328,18 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
if (checkworkoutuser(request.user,row)==False):
|
if (checkworkoutuser(request.user,row)==False):
|
||||||
raise PermissionDenied("Access denied")
|
raise PermissionDenied("Access denied")
|
||||||
|
|
||||||
|
if request.user.rower.rowerplan == 'basic' and 'speedcoach2' in row.workoutsource:
|
||||||
|
data = getsmallrowdata_db(['wash'],ids=[encoder.decode_hex(id)])
|
||||||
|
try:
|
||||||
|
if data['wash'].std() != 0:
|
||||||
|
url = reverse('paidplans')
|
||||||
|
messages.info(
|
||||||
|
request,
|
||||||
|
'Some Empower Oarlock data are only available to users with a <a href="{u}">paid plan</a>'.format(u=url)
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
form = WorkoutForm(instance=row)
|
form = WorkoutForm(instance=row)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@@ -3345,6 +3357,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
distance = form.cleaned_data['distance']
|
distance = form.cleaned_data['distance']
|
||||||
private = form.cleaned_data['private']
|
private = form.cleaned_data['private']
|
||||||
notes = form.cleaned_data['notes']
|
notes = form.cleaned_data['notes']
|
||||||
|
newdragfactor = form.cleaned_data['dragfactor']
|
||||||
thetimezone = form.cleaned_data['timezone']
|
thetimezone = form.cleaned_data['timezone']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -3416,6 +3429,11 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
row.timezone = thetimezone
|
row.timezone = thetimezone
|
||||||
row.plannedsession = ps
|
row.plannedsession = ps
|
||||||
|
|
||||||
|
dragchanged = False
|
||||||
|
if newdragfactor != row.dragfactor:
|
||||||
|
row.dragfactor = newdragfactor
|
||||||
|
dragchanged = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
row.save()
|
row.save()
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
@@ -3427,6 +3445,12 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
# change data in csv file
|
# change data in csv file
|
||||||
|
|
||||||
r = rdata(row.csvfilename)
|
r = rdata(row.csvfilename)
|
||||||
|
if dragchanged:
|
||||||
|
try:
|
||||||
|
r.change_drag(newdragfactor)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
if r == 0:
|
if r == 0:
|
||||||
return HttpResponse("Error: CSV Data File Not Found")
|
return HttpResponse("Error: CSV Data File Not Found")
|
||||||
r.rowdatetime = startdatetime
|
r.rowdatetime = startdatetime
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ th.rotate > div > span {
|
|||||||
padding: .2em .5em .2em 0em;
|
padding: .2em .5em .2em 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.site-announcement {
|
.site-announcement {
|
||||||
font: 1.0em/1.2em sans-serif;
|
font: 1.0em/1.2em sans-serif;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -253,6 +254,19 @@ th.rotate > div > span {
|
|||||||
border: solid 1px #333;
|
border: solid 1px #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.site-announcement-white {
|
||||||
|
font: 1.0em/1.2em sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
padding: .2em .5em .2em .5em;
|
||||||
|
zoom: 1;
|
||||||
|
/* border-radius: .5em; */
|
||||||
|
/* -moz-border-radius: .5em; */
|
||||||
|
/* -webkit-border-radius: .5em; */
|
||||||
|
text-align: left;
|
||||||
|
border: solid 1px #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.contentli {
|
.contentli {
|
||||||
|
|||||||
+11
-2
@@ -80,6 +80,15 @@
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ad h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 1.4em;
|
||||||
|
/* color: #dddddd; */
|
||||||
|
color: #f8f8ff;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
aside h1 a {
|
aside h1 a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@@ -647,8 +656,8 @@
|
|||||||
"side-nav nav nav"
|
"side-nav nav nav"
|
||||||
"sidebar content content"
|
"sidebar content content"
|
||||||
"sidebar content content"
|
"sidebar content content"
|
||||||
"sidebar content content"
|
"ad content content"
|
||||||
"sidebar footer footer"
|
"ad footer footer"
|
||||||
"ad footer footer"
|
"ad footer footer"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -309,6 +309,23 @@
|
|||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<ad class="ad">
|
<ad class="ad">
|
||||||
|
{% if request|announcements %}
|
||||||
|
<h1>What's New?</h1>
|
||||||
|
{% for a in request|announcements %}
|
||||||
|
<div class="site-announcement-box">
|
||||||
|
<div class="site-announcement-white">
|
||||||
|
<em>{{ a.created }}:</em>
|
||||||
|
{{ a.announcement|urlize }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if user.is_authenticated and user|nogoals %}
|
||||||
|
<p>
|
||||||
|
<a href="/rowers/createplan/">Create a Training Target!</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
{% block ad %}
|
{% block ad %}
|
||||||
<a href="https://pryglrowing.com">
|
<a href="https://pryglrowing.com">
|
||||||
<img src="/static/img/prygl.jpg">
|
<img src="/static/img/prygl.jpg">
|
||||||
|
|||||||
Reference in New Issue
Block a user