adding rpe editing
This commit is contained in:
@@ -28,6 +28,7 @@ from rowers.utils import landingpages
|
||||
from rowers.metrics import axes, metricsgroups, rowingmetrics
|
||||
from rowers.metrics import axlabels
|
||||
from rowers.rower_rules import user_is_not_basic
|
||||
from rowers import models
|
||||
|
||||
formaxlabels = axlabels.copy()
|
||||
formaxlabels.pop('None')
|
||||
@@ -401,7 +402,7 @@ class StandardsForm(forms.Form):
|
||||
|
||||
|
||||
class DocumentsForm(forms.Form):
|
||||
rpechoices = Workout.rpechoices
|
||||
rpechoices = models.rpechoices
|
||||
rpechoices = tuple([(-1, '---')]+list(rpechoices))
|
||||
title = forms.CharField(required=False)
|
||||
file = forms.FileField(required=False,
|
||||
|
||||
@@ -3421,14 +3421,6 @@ class PlannedSessionFormSmall(ModelForm):
|
||||
boattypes = mytypes.boattypes
|
||||
|
||||
# Workout
|
||||
|
||||
|
||||
class Workout(models.Model):
|
||||
workouttypes = mytypes.workouttypes
|
||||
workoutsources = mytypes.workoutsources
|
||||
privacychoices = mytypes.privacychoices
|
||||
adaptivetypes = mytypes.adaptivetypes
|
||||
boatbrands = mytypes.boatbrands
|
||||
rpechoices = (
|
||||
(0, 'Not Specified'),
|
||||
(1, '1 Very Easy (a walk in the park)'), # 20 TSS / hour
|
||||
@@ -3446,6 +3438,14 @@ class Workout(models.Model):
|
||||
(10, '10 Max Effort (You can barely remember your name, you would rather rip out your toenails than go through this)')
|
||||
)
|
||||
|
||||
class Workout(models.Model):
|
||||
workouttypes = mytypes.workouttypes
|
||||
workoutsources = mytypes.workoutsources
|
||||
privacychoices = mytypes.privacychoices
|
||||
adaptivetypes = mytypes.adaptivetypes
|
||||
boatbrands = mytypes.boatbrands
|
||||
|
||||
|
||||
user = models.ForeignKey(Rower, on_delete=models.CASCADE)
|
||||
team = models.ManyToManyField(Team, blank=True)
|
||||
plannedsession = models.ForeignKey(PlannedSession, blank=True, null=True,
|
||||
@@ -3586,6 +3586,10 @@ class Workout(models.Model):
|
||||
|
||||
return stri
|
||||
|
||||
class WorkoutRPEForm(ModelForm):
|
||||
class Meta:
|
||||
model = Workout
|
||||
fields = ['rpe']
|
||||
|
||||
class TombStone(models.Model):
|
||||
user = models.ForeignKey(Rower, on_delete=models.CASCADE)
|
||||
|
||||
@@ -3187,7 +3187,8 @@ def df_from_summary(data):
|
||||
|
||||
|
||||
@app.task
|
||||
def handle_c2_async_workout(alldata, userid, c2token, c2id, delaysec, defaulttimezone, debug=False, **kwargs):
|
||||
def handle_c2_async_workout(alldata, userid, c2token, c2id, delaysec,
|
||||
defaulttimezone, debug=False, **kwargs):
|
||||
time.sleep(delaysec)
|
||||
dologging('c2_import.log',str(c2id)+' for userid '+str(userid))
|
||||
data = alldata[c2id]
|
||||
|
||||
@@ -92,6 +92,11 @@
|
||||
{% if workout.rankingpiece %}
|
||||
<span style="font-size: smaller"><i class="fal fa-asterisk"></i></span>
|
||||
{% endif %}
|
||||
{% if workout.rpe == 0 %}
|
||||
<span style="font-size: smaller">
|
||||
<a href="/rowers/workout/{{ workout.id|encode }}/edit/">No RPE</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% if workout.name != '' %}
|
||||
<h3>
|
||||
|
||||
209
rowers/templates/workouts_rpe.html
Normal file
209
rowers/templates/workouts_rpe.html
Normal file
@@ -0,0 +1,209 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% load static %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Rowsandall Workouts List{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
setTimeout("location.reload(true);",180000);
|
||||
</script>
|
||||
<script
|
||||
type='text/javascript'
|
||||
src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'>
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<style>
|
||||
#mypointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
div.columns { width: 100%; }
|
||||
div.columns div { width: 20%; padding: 10px; float: left; }
|
||||
div.icondiv svg { height: 35px; }
|
||||
</style>
|
||||
|
||||
|
||||
<h1>
|
||||
Workouts of {{ rower.user.first_name }} {{ rower.user.last_name }}
|
||||
</h1>
|
||||
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<span>
|
||||
{% if workouts.has_previous %}
|
||||
{% if request.GET.q %}
|
||||
<a href="?page=1&q={{ request.GET.q }}">
|
||||
<i class="fas fa-arrow-alt-to-left"></i>
|
||||
</a>
|
||||
<a
|
||||
href="?page={{ workouts.previous_page_number }}&q={{ request.GET.q }}&when={{ timeperiod }}">
|
||||
<i class="fas fa-arrow-alt-left"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="?page=1&when={{ timeperiod }}">
|
||||
<i class="fas fa-arrow-alt-to-left"></i>
|
||||
</a>
|
||||
<a href="?page={{ workouts.previous_page_number }}&when={{ timeperiod }}">
|
||||
<i class="fas fa-arrow-alt-left"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</span>
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
<form method="post" target="">
|
||||
{% csrf_token %}
|
||||
{{ rpe_formset.management_form }}
|
||||
<table width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
{% for field in rpe_formset.0.visible_fields %}
|
||||
<td>{{ field.label_tag }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in rpe_formset %}
|
||||
<tr class="session_form_row">
|
||||
<td>
|
||||
{{ form.id }}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% if form.instance.pk %}{{ form.instance.startdatetime }}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if form.instance.pk %}{{ form.instance.name }}{% endif %}
|
||||
</td>
|
||||
{% if form.instance.pk %}
|
||||
{% for field in form.visible_fields %}
|
||||
<td>
|
||||
{{ field }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
|
||||
{% if workouts %}
|
||||
{% for workout in workouts %}
|
||||
<li class="grid_4 divlines">
|
||||
{{ workout.date|date:"Y-m-d" }} {{ workout.starttime|date:"H:i" }}
|
||||
{% if workout.duplicate %}
|
||||
<span style="font-size: smaller"><i class="fal fa-angle-double-up"></i></span>
|
||||
{% endif %}
|
||||
{% if workout.rankingpiece %}
|
||||
<span style="font-size: smaller"><i class="fal fa-asterisk"></i></span>
|
||||
{% endif %}
|
||||
{% if workout.rpe == 0 %}
|
||||
<span style="font-size: smaller">
|
||||
<a href="/rowers/workout/{{ workout.id|encode }}/edit/">No RPE</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% if workout.name != '' %}
|
||||
<h3>
|
||||
{% if team %}
|
||||
<a
|
||||
href={% url rower.defaultlandingpage3 id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage3|verbose }}">
|
||||
{{ workout.name }} ({{ workout.user.user.first_name }} {{ workout.user.user.last_name}})
|
||||
</a>
|
||||
{% else %}
|
||||
<a
|
||||
href={% url rower.defaultlandingpage3 id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage3|verbose }}">
|
||||
{{ workout.name }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% else %}
|
||||
<h3>
|
||||
{% if team %}
|
||||
<a
|
||||
href={% url rower.defaultlandingpage id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage|verbose }}">
|
||||
No Name ({{ workout.user.user.first_name }} {{ workout.user.user.last_name}})
|
||||
</a>
|
||||
{% else %}
|
||||
<a
|
||||
href={% url rower.defaultlandingpage id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage|verbose }}">
|
||||
No Name
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="workoutcontainer">
|
||||
<div class="icondiv">
|
||||
{% with workout.workouttype|icon|safe as templateName %}
|
||||
{% include templateName %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div class="workoutelement">
|
||||
<span style="color:#555">Distance</span><br>
|
||||
{{ workout.distance|distanceprint }}
|
||||
</div>
|
||||
<div class="workoutelement">
|
||||
<span style="color:#555">Time</span><br>
|
||||
{{ workout.duration |durationprint:"%H:%M:%S.%f" }}
|
||||
</div>
|
||||
<div class="workoutelement">
|
||||
{% if workout|may_edit:request %}
|
||||
<a class="small"
|
||||
href={% url rower.defaultlandingpage id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage|verbose }}">
|
||||
<i class="{{ rower.defaultlandingpage|landingicon }}"></i></a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="workoutelement">
|
||||
{% if workout|may_edit:request %}
|
||||
{% if rower.defaultlandingpage2 != 'workout_delete' %}
|
||||
<a class="small"
|
||||
href={% url rower.defaultlandingpage2 id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage2|verbose }}">
|
||||
<i class="{{ rower.defaultlandingpage2|landingicon }}"></i></a>
|
||||
{% else %}
|
||||
<a class="small"
|
||||
href={% url rower.defaultlandingpage2 id=workout.id|encode %}
|
||||
title="{{ rower.defaultlandingpage2|verbose }}">
|
||||
<i class="{{ rower.defaultlandingpage2|landingicon }}"></i></a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
<li> No workouts found </li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_workouts.html' %}
|
||||
{% endblock %}
|
||||
@@ -286,6 +286,8 @@ urlpatterns = [
|
||||
views.agegrouprecordview, name='agegrouprecordview'),
|
||||
re_path(r'^agegrouprecords/$',
|
||||
views.agegrouprecordview, name='agegrouprecordview'),
|
||||
re_path(r'^workouts/setrpe/$', views.workouts_setrpe_view,
|
||||
name='workouts_setrpe_view'),
|
||||
re_path(r'^list-workouts/team/(?P<teamid>\d+)/$', views.workouts_view,
|
||||
name='workouts_view'),
|
||||
re_path(r'^(?P<rowerid>\d+)/list-workouts/$', views.workouts_view,
|
||||
|
||||
@@ -159,22 +159,20 @@ from rowers.models import (
|
||||
VirtualRaceFollower, TombStone, InstantPlan,
|
||||
PlannedSessionStep,InStrokeAnalysis, ForceCurveAnalysis
|
||||
)
|
||||
from rowers.models import (
|
||||
RowerPowerForm, RowerHRZonesForm, RowerForm, RowerCPForm, GraphImage, AdvancedWorkoutForm,
|
||||
RowerPowerZonesForm, AccountRowerForm, UserForm,
|
||||
Team, TeamForm, TeamInviteForm, TeamInvite, TeamRequest,
|
||||
WorkoutComment, WorkoutCommentForm, RowerExportForm,
|
||||
CalcAgePerformance,
|
||||
PowerTimeFitnessMetric, BlogPost,
|
||||
PlannedSessionForm, PlannedSessionTemplateForm,
|
||||
PlannedSessionFormSmall, GeoCourseEditForm, VirtualRace,
|
||||
VirtualRaceForm, VirtualRaceResultForm, RowerImportExportForm,
|
||||
from rowers.models import ( RowerPowerForm, RowerHRZonesForm,
|
||||
RowerForm, RowerCPForm, GraphImage, AdvancedWorkoutForm,
|
||||
RowerPowerZonesForm, AccountRowerForm, UserForm, Team, TeamForm,
|
||||
TeamInviteForm, TeamInvite, TeamRequest, WorkoutComment,
|
||||
WorkoutCommentForm, RowerExportForm, CalcAgePerformance,
|
||||
PowerTimeFitnessMetric, BlogPost, PlannedSessionForm,
|
||||
PlannedSessionTemplateForm, PlannedSessionFormSmall,
|
||||
GeoCourseEditForm, VirtualRace, VirtualRaceForm,
|
||||
VirtualRaceResultForm, RowerImportExportForm, WorkoutRPEForm,
|
||||
IndoorVirtualRaceResultForm, IndoorVirtualRaceResult,
|
||||
IndoorVirtualRaceForm, PlannedSessionCommentForm,
|
||||
Alert, Condition, StaticChartRowerForm,
|
||||
FollowerForm, VirtualRaceAthleteForm, InstantPlanForm, DataRowerForm,
|
||||
StepEditorForm,
|
||||
)
|
||||
IndoorVirtualRaceForm, PlannedSessionCommentForm, Alert,
|
||||
Condition, StaticChartRowerForm, FollowerForm,
|
||||
VirtualRaceAthleteForm, InstantPlanForm, DataRowerForm,
|
||||
StepEditorForm, )
|
||||
from rowers.models import (
|
||||
FavoriteForm, BaseFavoriteFormSet, SiteAnnouncement, BasePlannedSessionFormSet,
|
||||
get_course_timezone, BaseConditionFormSet,
|
||||
|
||||
@@ -1921,6 +1921,99 @@ def plannedsession_compare_view(request, id=0, userid=0):
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# set RPE for list of workouts
|
||||
@login_required()
|
||||
def workouts_setrpe_view(request):
|
||||
startdate, enddate = get_dates_timeperiod(
|
||||
request, defaulttimeperiod='lastyear')
|
||||
r = getrequestrower(request)
|
||||
|
||||
startdate = datetime.datetime.combine(startdate, datetime.time())
|
||||
enddate = datetime.datetime.combine(enddate, datetime.time(23, 59, 59))
|
||||
|
||||
|
||||
workouts = Workout.objects.filter(
|
||||
user=r,rpe=0,
|
||||
startdatetime__gte=startdate,
|
||||
startdatetime__lte=enddate
|
||||
).order_by("-date", "-starttime")
|
||||
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
})
|
||||
WorkoutsRPEFormSet = modelformset_factory(
|
||||
Workout,
|
||||
form=WorkoutRPEForm,
|
||||
)
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
dateform = DateRangeForm(request.POST)
|
||||
rpe_formset = WorkoutsRPEFormSet(request.POST)
|
||||
if dateform.is_valid(): # pragma: no cover
|
||||
startdate = dateform.cleaned_data['startdate']
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
if rpe_formset.is_valid():
|
||||
for item in rpe_formset.cleaned_data:
|
||||
rpe = item['rpe']
|
||||
workout = item['id']
|
||||
if workout:
|
||||
workout.rpe = rpe
|
||||
workout.save()
|
||||
workouts = Workout.objects.filter(
|
||||
user=r,rpe=0,
|
||||
startdatetime__gte=startdate,
|
||||
startdatetime__lte=enddate
|
||||
).order_by("-date", "-starttime")
|
||||
|
||||
rpe_formset = WorkoutsRPEFormSet(queryset=workouts)
|
||||
|
||||
usertimezone = pytz.timezone(r.defaulttimezone)
|
||||
startdate = datetime.datetime.combine(
|
||||
startdate, datetime.time()).astimezone(usertimezone)
|
||||
enddate = datetime.datetime.combine(
|
||||
enddate, datetime.time(23, 59, 59)).astimezone(usertimezone)
|
||||
|
||||
if enddate < startdate: # pragma: no cover
|
||||
s = enddate
|
||||
enddate = startdate
|
||||
startdate = s
|
||||
|
||||
|
||||
|
||||
today = timezone.now()
|
||||
announcements = SiteAnnouncement.objects.filter(
|
||||
expires__gte=today
|
||||
).order_by(
|
||||
"-created",
|
||||
"-id"
|
||||
)
|
||||
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url': '/rowers/list-workouts/',
|
||||
'name': 'Workouts'
|
||||
},
|
||||
{
|
||||
'url': '/rowers/workouts/setrpe/',
|
||||
'name': 'Set RPE'
|
||||
}
|
||||
]
|
||||
|
||||
return render(request,'workouts_rpe.html',
|
||||
{
|
||||
'workouts': workouts,
|
||||
'active': 'nav-workouts',
|
||||
'rower': r,
|
||||
'breadcrumbs': breadcrumbs,
|
||||
'dateform': dateform,
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
'rpe_formset': rpe_formset,
|
||||
})
|
||||
|
||||
|
||||
# List Workouts
|
||||
@login_required()
|
||||
@@ -2111,6 +2204,12 @@ def workouts_view(request, message='', successmessage='',
|
||||
]
|
||||
timeperiod = startdate.strftime(
|
||||
'%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
||||
|
||||
norpecount = len([w for w in workouts if w.rpe==0])
|
||||
if norpecount:
|
||||
messages.info(request,'You have workouts with no RPE value set. \
|
||||
Click <a href="/rowers/workouts/setrpe">here</a> to update them.')
|
||||
|
||||
return render(request, 'list_workouts.html',
|
||||
{'workouts': workouts,
|
||||
'active': 'nav-workouts',
|
||||
|
||||
Reference in New Issue
Block a user