Merge branch 'release/v8.27'
This commit is contained in:
@@ -846,7 +846,8 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
pass
|
||||
return new_workout_from_df(r, newdf,
|
||||
title=title,boattype=boattype,
|
||||
workouttype=workouttype)
|
||||
workouttype=workouttype,
|
||||
workoutsource=workoutsource)
|
||||
try:
|
||||
checks = row.check_consistency()
|
||||
allchecks = 1
|
||||
@@ -1178,6 +1179,7 @@ def handle_nonpainsled(f2, fileformat, summary=''):
|
||||
|
||||
def new_workout_from_file(r, f2,
|
||||
workouttype='rower',
|
||||
workoutsource=None,
|
||||
title='Workout',
|
||||
boattype='1x',
|
||||
makeprivate=False,
|
||||
@@ -1272,13 +1274,16 @@ def new_workout_from_file(r, f2,
|
||||
dosummary = (fileformat != 'fit' and 'speedcoach2' not in fileformat)
|
||||
dosummary = dosummary or summary == ''
|
||||
|
||||
if workoutsource is None:
|
||||
workoutsource = fileformat
|
||||
|
||||
id, message = save_workout_database(
|
||||
f2, r,
|
||||
workouttype=workouttype,
|
||||
boattype=boattype,
|
||||
makeprivate=makeprivate,
|
||||
dosummary=dosummary,
|
||||
workoutsource=fileformat,
|
||||
workoutsource=workoutsource,
|
||||
summary=summary,
|
||||
inboard=inboard, oarlength=oarlength,
|
||||
title=title
|
||||
@@ -1389,6 +1394,7 @@ def split_workout(r, parent, splitsecond, splitmode):
|
||||
|
||||
def new_workout_from_df(r, df,
|
||||
title='New Workout',
|
||||
workoutsource='unknown',
|
||||
boattype='1x',
|
||||
workouttype='rower',
|
||||
parent=None,
|
||||
@@ -1403,7 +1409,7 @@ def new_workout_from_df(r, df,
|
||||
oarlength = parent.oarlength
|
||||
inboard = parent.inboard
|
||||
|
||||
|
||||
workoutsource = parent.workoutsource
|
||||
workouttype = parent.workouttype
|
||||
boattype = parent.boattype
|
||||
notes = parent.notes
|
||||
@@ -1451,6 +1457,7 @@ def new_workout_from_df(r, df,
|
||||
workouttype=workouttype,
|
||||
boattype=boattype,
|
||||
title=title,
|
||||
workoutsource=workoutsource,
|
||||
notes=notes,
|
||||
oarlength=oarlength,
|
||||
inboard=inboard,
|
||||
|
||||
@@ -298,6 +298,7 @@ def add_c2_stroke_data_db(strokedata,workoutid,starttimeunix,csvfilename,
|
||||
def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
||||
dosummary=True,title='Workout',
|
||||
notes='',totaldist=0,totaltime=0,
|
||||
workoutsource='unknown',
|
||||
summary='',
|
||||
makeprivate=False,
|
||||
oarlength=2.89,inboard=0.88):
|
||||
@@ -430,15 +431,16 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
||||
|
||||
|
||||
w = Workout(user=r,name=title,date=workoutdate,
|
||||
workouttype=workouttype,
|
||||
duration=duration,distance=totaldist,
|
||||
weightcategory=r.weightcategory,
|
||||
starttime=workoutstarttime,
|
||||
csvfilename=f2,notes=notes,summary=summary,
|
||||
maxhr=maxhr,averagehr=averagehr,
|
||||
startdatetime=workoutstartdatetime,
|
||||
inboard=inboard,oarlength=oarlength,
|
||||
privacy=privacy)
|
||||
workouttype=workouttype,
|
||||
workoutsource=workoutsource,
|
||||
duration=duration,distance=totaldist,
|
||||
weightcategory=r.weightcategory,
|
||||
starttime=workoutstarttime,
|
||||
csvfilename=f2,notes=notes,summary=summary,
|
||||
maxhr=maxhr,averagehr=averagehr,
|
||||
startdatetime=workoutstartdatetime,
|
||||
inboard=inboard,oarlength=oarlength,
|
||||
privacy=privacy)
|
||||
|
||||
|
||||
w.save()
|
||||
|
||||
@@ -751,11 +751,14 @@ parchoicesx = list(sorted(favchartlabelsx.items(), key = lambda x:x[1]))
|
||||
|
||||
# Saving a chart as a favorite chart
|
||||
class FavoriteChart(models.Model):
|
||||
workouttypechoices = (
|
||||
workouttypechoices = [
|
||||
('ote','Erg/SkiErg'),
|
||||
('otw','On The Water'),
|
||||
('both','both')
|
||||
)
|
||||
('all','All')
|
||||
]
|
||||
|
||||
for workoutsource in mytypes.workoutsources:
|
||||
workouttypechoices.append(workoutsource)
|
||||
|
||||
plottypes = (
|
||||
('line','Line Chart'),
|
||||
@@ -771,6 +774,7 @@ class FavoriteChart(models.Model):
|
||||
workouttype = models.CharField(max_length=50,choices=workouttypechoices,
|
||||
default='both',
|
||||
verbose_name='Workout Type')
|
||||
|
||||
reststrokes = models.BooleanField(default=True,verbose_name="Incl. Rest")
|
||||
notes = models.CharField(max_length=300,verbose_name='Chart Notes',
|
||||
default='Flex Chart Notes',blank=True)
|
||||
@@ -930,7 +934,8 @@ def a_week_from_now():
|
||||
# models related to training planning - draft
|
||||
# Do we need a separate class TestTarget?
|
||||
class TrainingTarget(models.Model):
|
||||
rower = models.ForeignKey(Rower)
|
||||
rower = models.ForeignKey(Rower,related_name='targetathlete')
|
||||
manager = models.ForeignKey(Rower,related_name='targetmanager',null=True)
|
||||
name = models.CharField(max_length=150,blank=True)
|
||||
date = models.DateField(
|
||||
default=half_year_from_now)
|
||||
@@ -978,7 +983,8 @@ class TrainingTargetForm(ModelForm):
|
||||
|
||||
|
||||
class TrainingPlan(models.Model):
|
||||
rower = models.ForeignKey(Rower)
|
||||
rower = models.ForeignKey(Rower,related_name='planathlete')
|
||||
manager = models.ForeignKey(Rower,related_name='planmanager',null=True)
|
||||
name = models.CharField(max_length=150,blank=True)
|
||||
target = models.ForeignKey(TrainingTarget,blank=True,null=True)
|
||||
startdate = models.DateField(default=timezone.now)
|
||||
|
||||
@@ -30,14 +30,14 @@ workoutsources = (
|
||||
('mapmyfitness','mapmyfitness'),
|
||||
('csv','painsled'),
|
||||
('tcx','tcx'),
|
||||
('rp','rp'),
|
||||
('rp','rowperfect'),
|
||||
('mystery','mystery'),
|
||||
('tcxnohr','tcx (no HR)'),
|
||||
# ('tcxnohr','tcx (no HR)'),
|
||||
('rowperfect3','rowperfect3'),
|
||||
('ergdata','ergdata'),
|
||||
('boatcoach','boatcoach'),
|
||||
('boatcoachotw','boatcoachotw'),
|
||||
('bcmike','boatcoach (develop)'),
|
||||
# ('bcmike','boatcoach (develop)'),
|
||||
('painsleddesktop','painsleddesktop'),
|
||||
('speedcoach','speedcoach'),
|
||||
('speedcoach2','speedcoach2'),
|
||||
@@ -52,6 +52,7 @@ boattypes = (
|
||||
('2-', '2- (pair)'),
|
||||
('2+', '2+ (coxed pair)'),
|
||||
('3x+','3x+ (coxed triple)'),
|
||||
('3x-','3x- (triple)'),
|
||||
('4x', '4x (quad)'),
|
||||
('4x+', '4x+ (coxed quad)'),
|
||||
('4-', '4- (four)'),
|
||||
|
||||
@@ -41,13 +41,11 @@
|
||||
<i class="fal fa-table fa-fw"></i> Statistics
|
||||
</a>
|
||||
</li>
|
||||
<!--
|
||||
<li id="compare">
|
||||
<a href="/rowers/multi-compare">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare
|
||||
<li id="compare">
|
||||
<a href="/rowers/multi-compare/workout/{{ workout.id }}">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
</li>
|
||||
{% if user.is_authenticated and workout|may_edit:request %}
|
||||
<li id="chart-image">
|
||||
<a href="/rowers/workout/{{ workout.id }}/image">
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
<td> {{ actualvalue|lookup:ps.id }}</td>
|
||||
<td> {{ ps.sessionunit }} </td>
|
||||
{% if completeness|lookup:ps.id == 'partial' %}
|
||||
<td style="color:darkgray"><i> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</i></td>
|
||||
<td style="color:darkgray"><em> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</em></td>
|
||||
{% else %}
|
||||
<td> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</td>
|
||||
{% endif %}
|
||||
|
||||
@@ -83,6 +83,31 @@
|
||||
your workouts. That makes it easy to search.
|
||||
</p>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<form enctype="multipart/form-data"
|
||||
action="/rowers/team-compare-select/team/{{ team.id }}"
|
||||
method="post">
|
||||
<table>
|
||||
{{ dateform.as_table }}
|
||||
</table>
|
||||
<table>
|
||||
{{ modalityform.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<input name='modalityform' class="button green" type="submit" value="Filter">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<form id="searchform" action=""
|
||||
method="get" accept-charset="utf-8">
|
||||
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
|
||||
<button class="button blue small" type="submit">
|
||||
Search
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2 maxheight">
|
||||
{% if workouts %}
|
||||
<form enctype="multipart/form-data" action="/rowers/multi-compare" method="post">
|
||||
@@ -109,42 +134,6 @@
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
{% if team %}
|
||||
<form enctype="multipart/form-data"
|
||||
action="/rowers/team-compare-select/team/{{ team.id }}"
|
||||
method="post">
|
||||
{% else %}
|
||||
<form enctype="multipart/form-data"
|
||||
action="/rowers/team-compare-select/"
|
||||
method="post">
|
||||
{% endif %}
|
||||
<table>
|
||||
{{ dateform.as_table }}
|
||||
</table>
|
||||
<table>
|
||||
{{ modalityform.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<input name='modalityform' class="button green" type="submit" value="Submit">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
{% if team %}
|
||||
<form id="searchform" action=""
|
||||
method="get" accept-charset="utf-8">
|
||||
{% else %}
|
||||
<form id="searchform" action="/rowers/team-compare-select/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}"
|
||||
method="get" accept-charset="utf-8">
|
||||
{% endif %}
|
||||
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
|
||||
<button class="button blue small" type="submit">
|
||||
Search
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
The training plan target is: {{ plan.target.name }} on {{ plan.target.date }}.
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if plan|mayeditplan:request %}
|
||||
<p><a href="/rowers/editplan/{{ plan.id }}">Edit the plan</a></p>
|
||||
{% endif %}
|
||||
|
||||
<h2>Plan Macro, Meso and Micro Cycles</h2>
|
||||
|
||||
<ul class="cd-accordion-menu animated">
|
||||
<!-- Start Macrocycle For Loop -->
|
||||
{% for key, macrocycle in cycles.items %}
|
||||
<li class="has-children" id="macros">
|
||||
<li class="has-kids" id="macros">
|
||||
<input type="checkbox" name="macro-selector" id="macro-selector-{{ macrocycle.0.id }}">
|
||||
<label for="macro-selector-{{ macrocycle.0.id }}">Macro Cycle {{ macrocycle.0.name }} ({{ macrocycle.0.startdate }} - {{ macrocycle.0.enddate }})</label>
|
||||
<ul>
|
||||
@@ -39,10 +41,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
{% if macrocycle.0|mayeditplan:request %}
|
||||
<a href="/rowers/macrocycle/{{ macrocycle.0.id }}/">edit</a>
|
||||
/
|
||||
<a href="/rowers/deletemacrocycle/{{ macrocycle.0.id }}/">delete</a>
|
||||
/
|
||||
{% endif %}
|
||||
<a href='/rowers/sessions/{{ macrocycle.0.startdate|date:"Y-m-d" }}/{{ macrocycle.0.enddate|date:"Y-m-d" }}/user/{{ rower.user.id }}'>sessions</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -95,10 +99,16 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
{% if macrocycle.0|mayeditplan:request %}
|
||||
<a href="/rowers/macrocycle/{{ macrocycle.0.id }}/">edit</a>
|
||||
/
|
||||
<a href="/rowers/deletemacrocycle/{{ macrocycle.0.id }}/">delete</a>
|
||||
/
|
||||
<a href="/rowers/macrocycle/{{ macrocycle.0.id }}/planbymonths/user/{{ rower.user.id }}">
|
||||
Replan by Months
|
||||
</a>
|
||||
/
|
||||
{% endif %}
|
||||
<a href='/rowers/sessions/{{ macrocycle.0.startdate|date:"Y-m-d" }}/{{ macrocycle.0.enddate|date:"Y-m-d" }}/user/{{ rower.user.id }}'>sessions</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -117,7 +127,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="has-children" id="mesos">
|
||||
<li class="has-kids" id="mesos">
|
||||
<input type="checkbox" name="meso-selector" id="meso-selector-{{ macrocycle.0.id }}">
|
||||
<label for="meso-selector-{{ macrocycle.0.id }}">Meso Cycles</label>
|
||||
<ul>
|
||||
@@ -140,10 +150,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
{% if mesocycle.0|mayeditplan:request %}
|
||||
<a href="/rowers/mesocycle/{{ mesocycle.0.id }}/">edit</a>
|
||||
/
|
||||
<a href="/rowers/deletemesocycle/{{ mesocycle.0.id }}/">delete</a>
|
||||
/
|
||||
{% endif %}
|
||||
<a href='/rowers/sessions/{{ mesocycle.0.startdate|date:"Y-m-d" }}/{{ mesocycle.0.enddate|date:"Y-m-d" }}/user/{{ rower.user.id }}'>sessions</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -197,10 +209,16 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
{% if mesocycle.0|mayeditplan:request %}
|
||||
<a href="/rowers/mesocycle/{{ mesocycle.0.id }}/">edit</a>
|
||||
/
|
||||
<a href="/rowers/deletemesocycle/{{ mesocycle.0.id }}/">delete</a>
|
||||
/
|
||||
<a href="/rowers/mesocycle/{{ mesocycle.0.id }}/planbyweeks/user/{{ rower.user.id }}">
|
||||
Replan by Weeks
|
||||
</a>
|
||||
/
|
||||
{% endif %}
|
||||
<a href='/rowers/sessions/{{ mesocycle.0.startdate|date:"Y-m-d" }}/{{ mesocycle.0.enddate|date:"Y-m-d" }}/user/{{ rower.user.id }}'>sessions</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -219,7 +237,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="has-children" id="micros">
|
||||
<li class="has-kids" id="micros">
|
||||
<input type="checkbox" name="micro-selector"
|
||||
id="micro-selector-{{ macrocycle.0.id }}-{{ mesocycle.0.id }}">
|
||||
<label
|
||||
@@ -247,10 +265,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
{% if microcycle|mayeditplan:request %}
|
||||
<a href="/rowers/microcycle/{{ microcycle.id }}/">edit</a>
|
||||
/
|
||||
<a href="/rowers/deletemicrocycle/{{ microcycle.id }}/">delete</a>
|
||||
/
|
||||
{% endif %}
|
||||
<a href='/rowers/sessions/{{ microcycle.startdate|date:"Y-m-d" }}/{{ microcycle.enddate|date:"Y-m-d" }}/user/{{ rower.user.id }}'>sessions</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -306,10 +326,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
{% if microcycle|mayeditplan:request %}
|
||||
<a href="/rowers/microcycle/{{ microcycle.id }}">edit</a>
|
||||
/
|
||||
<a href="/rowers/deletemicrocycle/{{ microcycle.id }}">delete</a>
|
||||
/
|
||||
{% endif %}
|
||||
<a href='/rowers/sessions/{{ microcycle.startdate|date:"Y-m-d" }}/{{ microcycle.enddate|date:"Y-m-d" }}/user/{{ rower.user.id }}'>sessions</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -74,7 +74,9 @@ $('#id_workouttype').change();
|
||||
</tr><tr>
|
||||
<th>Duration:</th><td>{{ workout.duration |durationprint:"%H:%M:%S.%f" }}</td>
|
||||
</tr><tr>
|
||||
<th>Public link to this workout</th>
|
||||
<th>Source:</th><td>{{ workout.workoutsource }}</td>
|
||||
</tr><tr>
|
||||
<th>Public link to this workout:</th>
|
||||
<td>
|
||||
<a href="/rowers/workout/{{ workout.id }}">https://rowsandall.com/rowers/workout/{{ workout.id }}</a>
|
||||
</td>
|
||||
|
||||
@@ -10,7 +10,8 @@ register = template.Library()
|
||||
from rowers.utils import calculate_age
|
||||
from rowers.models import (
|
||||
course_length,WorkoutComment,
|
||||
TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle
|
||||
TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle,
|
||||
Rower
|
||||
)
|
||||
from rowers.plannedsessions import (
|
||||
race_can_register, race_can_submit,race_rower_status
|
||||
@@ -19,7 +20,7 @@ from rowers.plannedsessions import (
|
||||
from rowers import c2stuff, runkeeperstuff
|
||||
from rowers.c2stuff import c2_open
|
||||
from rowers.runkeeperstuff import runkeeper_open
|
||||
|
||||
from rowers.models import checkaccessuser
|
||||
from rowers.mytypes import otwtypes
|
||||
from rowers.utils import NoTokenError
|
||||
|
||||
@@ -182,6 +183,29 @@ def may_edit(workout,request):
|
||||
|
||||
return mayedit
|
||||
|
||||
|
||||
|
||||
@register.filter
|
||||
def mayeditplan(obj,request):
|
||||
|
||||
if obj is None:
|
||||
return False
|
||||
|
||||
if hasattr(obj,'plan'):
|
||||
return mayeditplan(obj.plan,request)
|
||||
|
||||
if hasattr(obj,'manager'):
|
||||
if obj.manager is not None:
|
||||
return request.user == obj.manager.user
|
||||
|
||||
rr = Rower.objects.get(user=request.user)
|
||||
if checkaccessuser(request.user,obj.rower) and rr.rowerplan not in ['basic','pro']:
|
||||
mayedit = True
|
||||
|
||||
|
||||
return mayedit
|
||||
|
||||
|
||||
@register.filter(name='times')
|
||||
def times(number):
|
||||
return range(number)
|
||||
|
||||
@@ -1046,6 +1046,7 @@ boattype: 4x
|
||||
a = MessageAttachment(message=m,document=a2[6:])
|
||||
a.save()
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
for filename in os.listdir('media/mailbox_attachments'):
|
||||
path = os.path.join('media/mailbox_attachments/',filename)
|
||||
@@ -2137,6 +2138,7 @@ class URLTests(TestCase):
|
||||
'/rowers/sessions/teamcreate/',
|
||||
'/rowers/sessions/user/1',
|
||||
'/rowers/team-compare-select/',
|
||||
'/rowers/team-compare-select/workout/1',
|
||||
'/rowers/team-compare-select/2016-01-01/2016-12-31',
|
||||
'/rowers/test-job/2',
|
||||
'/rowers/test-job2/2',
|
||||
|
||||
@@ -26,7 +26,7 @@ queue = django_rq.get_queue('default')
|
||||
queuelow = django_rq.get_queue('low')
|
||||
queuehigh = django_rq.get_queue('low')
|
||||
|
||||
from mytypes import workouttypes,boattypes,otwtypes
|
||||
from mytypes import workouttypes,boattypes,otwtypes,workoutsources
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
@@ -49,6 +49,18 @@ def cleanbody(body):
|
||||
|
||||
return body
|
||||
|
||||
|
||||
sources = [s for s,name in workoutsources]
|
||||
|
||||
def matchsource(line):
|
||||
results = []
|
||||
for s in sources:
|
||||
testert = '^source.*(%s)' % s
|
||||
tester = re.compile(testert)
|
||||
|
||||
if tester.match(line.lower()):
|
||||
return group(1)
|
||||
|
||||
# currently only matches one chart
|
||||
def matchchart(line):
|
||||
results = []
|
||||
@@ -147,6 +159,14 @@ def getprivateoptions_body2(uploadoptions,body):
|
||||
|
||||
return uploadoptions
|
||||
|
||||
def getworkoutsources(uploadoptions,body):
|
||||
for line in body.splitlines():
|
||||
workoutsource = matchsource(line)
|
||||
if workoutsource:
|
||||
uploadoptions['workoutsource'] = workoutsource
|
||||
|
||||
return uploadoptions
|
||||
|
||||
def getplotoptions_body2(uploadoptions,body):
|
||||
for line in body.splitlines():
|
||||
chart = matchchart(line)
|
||||
@@ -241,6 +261,17 @@ def getboattype(uploadoptions,value,key):
|
||||
|
||||
return uploadoptions
|
||||
|
||||
def getsource(uploadoptions,value,key):
|
||||
workoutsource = 'unknown'
|
||||
for type,verb in workoutsources:
|
||||
if value == type:
|
||||
workoutsource = type
|
||||
if value == verb:
|
||||
workoutsource = type
|
||||
|
||||
uploadoptions[key] = workoutsource
|
||||
|
||||
return uploadoptions
|
||||
|
||||
def getboolean(uploadoptions,value,key):
|
||||
b = True
|
||||
@@ -273,6 +304,8 @@ def upload_options(body):
|
||||
uploadoptions = gettype(uploadoptions,value,'workouttype')
|
||||
if 'boat' in lowkey:
|
||||
uploadoptions = getboattype(uploadoptions,value,'boattype')
|
||||
if 'source' in lowkey:
|
||||
uploadoptions = getsource(uploadoptions,value,'workoutsource')
|
||||
except AttributeError:
|
||||
#pass
|
||||
raise yaml.YAMLError
|
||||
@@ -283,6 +316,7 @@ def upload_options(body):
|
||||
uploadoptions = getprivateoptions_body2(uploadoptions,body)
|
||||
typeoptions = gettypeoptions_body2(uploadoptions,body)
|
||||
uploadoptions = getstravaid(uploadoptions,body)
|
||||
uploadoptions = getworkoutsources(uploadoptions,body)
|
||||
except IOError:
|
||||
pm = exc.problem_mark
|
||||
strpm = str(pm)
|
||||
@@ -377,6 +411,13 @@ def set_workouttype(w,options):
|
||||
|
||||
return 1
|
||||
|
||||
def set_workoutsource(w,options):
|
||||
try:
|
||||
w.workoutsource = options['workoutsource']
|
||||
w.save()
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def make_private(w,options):
|
||||
if 'makeprivate' in options and options['makeprivate']:
|
||||
w.privacy = 'hidden'
|
||||
|
||||
@@ -156,8 +156,13 @@ urlpatterns = [
|
||||
url(r'^courses/upload$',views.course_upload_view),
|
||||
url(r'^addmanual/$',views.addmanual_view),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/$',views.team_comparison_select),
|
||||
url(r'^workouts-join-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)$',views.workouts_join_select),
|
||||
url(r'^workouts-join$',views.workouts_join_view),
|
||||
@@ -328,6 +333,7 @@ urlpatterns = [
|
||||
url(r'^workout/(?P<id>\d+)/runkeeperuploadw/$',views.workout_runkeeper_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/underarmouruploadw/$',views.workout_underarmour_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/tpuploadw/$',views.workout_tp_upload_view),
|
||||
url(r'^multi-compare/workout/(?P<id>\d+)$',views.multi_compare_view),
|
||||
url(r'^multi-compare$',views.multi_compare_view),
|
||||
url(r'^user-boxplot/user/(?P<userid>\d+)$',views.boxplot_view),
|
||||
url(r'^user-boxplot$',views.boxplot_view),
|
||||
@@ -435,6 +441,10 @@ urlpatterns = [
|
||||
name='macrocycle_update_view'),
|
||||
url(r'^mesocycle/(?P<pk>\d+)/$',views.TrainingMesoCycleUpdate.as_view(),
|
||||
name='mesocycle_update_view'),
|
||||
url(r'^macrocycle/(?P<id>\d+)/planbymonths/$',views.planmacrocyclebymonth),
|
||||
url(r'^macrocycle/(?P<id>\d+)/planbymonths/user/(?P<userid>\d+)/$',views.planmacrocyclebymonth),
|
||||
url(r'^mesocycle/(?P<id>\d+)/planbyweeks/$',views.planmesocyclebyweek),
|
||||
url(r'^mesocycle/(?P<id>\d+)/planbyweeks/user/(?P<userid>\d+)/$',views.planmesocyclebyweek),
|
||||
url(r'^microcycle/(?P<pk>\d+)/$',views.TrainingMicroCycleUpdate.as_view(),
|
||||
name='microcycle_update_view'),
|
||||
url(r'^deletetarget/(?P<id>\d+)/$',views.rower_delete_trainingtarget),
|
||||
|
||||
331
rowers/views.py
331
rowers/views.py
@@ -3019,7 +3019,7 @@ def workout_forcecurve_view(request,id=0,workstrokesonly=False):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_forcecurve_view,kwargs={'id':id}),
|
||||
@@ -3089,7 +3089,7 @@ def workout_histo_view(request,id=0):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_histo_view,kwargs={'id':id}),
|
||||
@@ -5250,6 +5250,7 @@ def team_comparison_select(request,
|
||||
successmessage='',
|
||||
startdate=timezone.now()-datetime.timedelta(days=30),
|
||||
enddate=timezone.now(),
|
||||
id=0,
|
||||
teamid=0):
|
||||
|
||||
try:
|
||||
@@ -5371,7 +5372,7 @@ def team_comparison_select(request,
|
||||
|
||||
if rankingonly:
|
||||
workouts = [w for w in workouts if w.rankingpiece]
|
||||
|
||||
|
||||
query = request.GET.get('q')
|
||||
if query:
|
||||
query_list = query.split()
|
||||
@@ -5382,8 +5383,22 @@ def team_comparison_select(request,
|
||||
(Q(notes__icontains=q) for q in query_list))
|
||||
)
|
||||
|
||||
if id:
|
||||
firstworkout = get_workout(id)
|
||||
if not checkworkoutuser(request.user,firstworkout):
|
||||
raise PermissionDenied("You are not allowed to sue this workout")
|
||||
|
||||
firstworkoutquery = Workout.objects.filter(id=id)
|
||||
workouts = firstworkoutquery | workouts
|
||||
else:
|
||||
firstworkout = None
|
||||
|
||||
form = WorkoutMultipleCompareForm()
|
||||
form.fields["workouts"].queryset = workouts
|
||||
if id:
|
||||
form.fields["workouts"].initial = [firstworkout]
|
||||
|
||||
|
||||
|
||||
if theteam:
|
||||
theid = theteam.id
|
||||
@@ -5396,20 +5411,38 @@ def team_comparison_select(request,
|
||||
messages.error(request,message)
|
||||
|
||||
r = getrower(request.user)
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_comparison_select,kwargs={'teamid':teamid}),
|
||||
'name': 'Compare Select'
|
||||
},
|
||||
|
||||
if id:
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(id)
|
||||
},
|
||||
{
|
||||
'url':reverse(team_comparison_select,kwargs={'id':id,'teamid':teamid}),
|
||||
'name':'Compare Select'
|
||||
},
|
||||
]
|
||||
else:
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_comparison_select,kwargs={'teamid':teamid}),
|
||||
'name': 'Compare Select'
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
return render(request, 'team_compare_select.html',
|
||||
{'workouts': workouts,
|
||||
'workout':firstworkout,
|
||||
'dateform':dateform,
|
||||
'startdate':startdate,
|
||||
'enddate':enddate,
|
||||
@@ -5426,7 +5459,7 @@ def team_comparison_select(request,
|
||||
|
||||
# Team comparison
|
||||
@login_required()
|
||||
def multi_compare_view(request):
|
||||
def multi_compare_view(request,id=0):
|
||||
promember=0
|
||||
if not request.user.is_anonymous():
|
||||
r = getrower(request.user)
|
||||
@@ -5542,7 +5575,10 @@ def multi_compare_view(request):
|
||||
})
|
||||
|
||||
else:
|
||||
url = reverse(workouts_view)
|
||||
url = reverse(team_comparison_select,
|
||||
kwargs={
|
||||
'id':id,
|
||||
'teamid':0})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# Multi Flex Chart with Grouping
|
||||
@@ -6908,7 +6944,7 @@ def workout_fusion_list(request,id=0,message='',successmessage='',
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,row.id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_fusion_list,kwargs={'id':id}),
|
||||
@@ -7131,7 +7167,7 @@ def workout_crewnerd_summary_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_crewnerd_summary_view,kwargs={'id':id}),
|
||||
@@ -7341,7 +7377,7 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_wind_view,kwargs={'id':id}),
|
||||
@@ -7529,7 +7565,7 @@ def workout_stream_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_stream_view,kwargs={'id':id}),
|
||||
@@ -7661,7 +7697,7 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_otwsetpower_view,kwargs={'id':id}),
|
||||
@@ -7701,7 +7737,7 @@ def instroke_view(request,id=0):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(instroke_view,kwargs={'id':id}),
|
||||
@@ -8179,7 +8215,7 @@ def workout_data_view(request, id=0):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_data_view,kwargs={'id':id}),
|
||||
@@ -8275,7 +8311,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_stats_view,kwargs={'id':id}),
|
||||
@@ -8719,6 +8755,34 @@ def workout_workflow_config2_view(request,userid=0):
|
||||
})
|
||||
|
||||
|
||||
def getfavorites(r,row):
|
||||
workouttype = 'ote'
|
||||
if row.workouttype in mytypes.otwtypes:
|
||||
workouttype = 'otw'
|
||||
|
||||
matchworkouttypes = [workouttype,'all']
|
||||
|
||||
workoutsource = row.workoutsource
|
||||
if 'speedcoach2' in row.workoutsource:
|
||||
workoutsource = 'speedcoach2'
|
||||
|
||||
try:
|
||||
favorites = FavoriteChart.objects.filter(user=r,
|
||||
workouttype__in=matchworkouttypes).order_by("id")
|
||||
favorites2 = FavoriteChart.objects.filter(user=r,
|
||||
workouttype__in=[workoutsource]).order_by("id")
|
||||
|
||||
favorites = favorites | favorites2
|
||||
|
||||
|
||||
maxfav = len(favorites)-1
|
||||
except:
|
||||
favorites = None
|
||||
maxfav = 0
|
||||
|
||||
return favorites,maxfav
|
||||
|
||||
|
||||
# Workflow View
|
||||
@login_required()
|
||||
def workout_workflow_view(request,id):
|
||||
@@ -8738,17 +8802,8 @@ def workout_workflow_view(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 = get_call()
|
||||
|
||||
@@ -8791,7 +8846,7 @@ def workout_workflow_view(request,id):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_workflow_view,kwargs={'id':id}),
|
||||
@@ -8853,13 +8908,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
||||
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)
|
||||
|
||||
# check if favoritenr is not out of range
|
||||
if favorites:
|
||||
@@ -8968,7 +9017,6 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
||||
else:
|
||||
print flexaxesform.errors
|
||||
|
||||
print xparam,yparam1,yparam2
|
||||
|
||||
if not promember:
|
||||
for name,d in rowingmetrics:
|
||||
@@ -9086,7 +9134,7 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_flexchart3_view,kwargs=kwargs),
|
||||
@@ -9180,7 +9228,7 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_otwpowerplot_view,kwargs={'id':id}),
|
||||
@@ -9407,7 +9455,7 @@ def workout_comment_view(request,id=0):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_comment_view,kwargs={'id':id}),
|
||||
@@ -9827,7 +9875,7 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_edit_view,kwargs={'id':id}),
|
||||
@@ -9869,7 +9917,7 @@ def workout_map_view(request,id=0):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_map_view,kwargs={'id':id}),
|
||||
@@ -9943,7 +9991,7 @@ def workout_uploadimage_view(request,id):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_uploadimage_view,kwargs={'id':id}),
|
||||
@@ -10926,6 +10974,11 @@ def workout_upload_view(request,
|
||||
except KeyError:
|
||||
boattype = '1x'
|
||||
|
||||
try:
|
||||
workoutsource = uploadoptions['workoutsource']
|
||||
except KeyError:
|
||||
workoutsource = None
|
||||
|
||||
try:
|
||||
plottype = uploadoptions['plottype']
|
||||
except KeyError:
|
||||
@@ -11039,6 +11092,7 @@ def workout_upload_view(request,
|
||||
id,message,f2 = dataprep.new_workout_from_file(
|
||||
r,f2,
|
||||
workouttype=workouttype,
|
||||
workoutsource=workoutsource,
|
||||
boattype=boattype,
|
||||
makeprivate=makeprivate,
|
||||
title = t,
|
||||
@@ -11583,7 +11637,7 @@ def graph_show_view(request,id):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,w.id),
|
||||
'name': str(w.id)
|
||||
'name': w.name
|
||||
},
|
||||
{
|
||||
'url':reverse(graph_show_view,kwargs={'id':id}),
|
||||
@@ -11675,7 +11729,7 @@ def workout_split_view(request,id=id):
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,row.id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(graph_show_view,kwargs={'id':id}),
|
||||
@@ -11846,7 +11900,7 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,row.id),
|
||||
'name': str(row.id)
|
||||
'name': row.name
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_summary_edit_view,kwargs={'id':id}),
|
||||
@@ -16040,6 +16094,7 @@ def rower_create_trainingplan(request,userid=0):
|
||||
|
||||
therower = getrequestrower(request,userid=userid)
|
||||
theuser = therower.user
|
||||
themanager = getrower(request.user)
|
||||
|
||||
if request.method == 'POST' and 'date' in request.POST:
|
||||
targetform = TrainingTargetForm(request.POST)
|
||||
@@ -16051,6 +16106,7 @@ def rower_create_trainingplan(request,userid=0):
|
||||
t = TrainingTarget(rower=therower,
|
||||
name=name,
|
||||
date=date,
|
||||
manager=themanager,
|
||||
notes=notes)
|
||||
|
||||
t.save()
|
||||
@@ -16067,6 +16123,7 @@ def rower_create_trainingplan(request,userid=0):
|
||||
name=name,
|
||||
rower=therower,
|
||||
target=target,
|
||||
manager=themanager,
|
||||
startdate=startdate,
|
||||
enddate=enddate,
|
||||
)
|
||||
@@ -16115,7 +16172,7 @@ def rower_delete_trainingtarget(request,id=0):
|
||||
except TrainingPlan.DoesNotExist:
|
||||
raise Http404("Training Plan Does Not Exist")
|
||||
|
||||
if checkaccessuser(request.user,target.rower):
|
||||
if checkaccessuser(request.user,target.manager):
|
||||
target.delete()
|
||||
messages.info(request,"We have deleted the training target")
|
||||
else:
|
||||
@@ -16135,7 +16192,7 @@ def rower_delete_trainingplan(request,id=0):
|
||||
except TrainingPlan.DoesNotExist:
|
||||
raise Http404("Training Plan Does Not Exist")
|
||||
|
||||
if checkaccessuser(request.user,plan.rower):
|
||||
if checkaccessuser(request.user,plan.manager):
|
||||
plan.delete()
|
||||
messages.info(request,"We have deleted the training plan")
|
||||
else:
|
||||
@@ -16152,7 +16209,7 @@ class TrainingPlanDelete(DeleteView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
|
||||
if not checkaccessuser(self.request.user,obj.rower):
|
||||
if not checkaccessuser(self.request.user,obj.manager):
|
||||
raise PermissionDenied('You are not allowed to delete this training plan')
|
||||
|
||||
return obj
|
||||
@@ -16218,7 +16275,7 @@ class MicroCycleDelete(DeleteView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(MicroCycleDelete, self).get_object(*args, **kwargs)
|
||||
if not checkaccessuser(self.request.user,obj.plan.plan.plan.rower):
|
||||
if not checkaccessuser(self.request.user,obj.plan.plan.plan.manager):
|
||||
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
||||
return obj
|
||||
|
||||
@@ -16279,7 +16336,8 @@ class MesoCycleDelete(DeleteView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(MesoCycleDelete, self).get_object(*args, **kwargs)
|
||||
if not checkaccessuser(self.request.user,obj.plan.plan.rower):
|
||||
|
||||
if not checkaccessuser(self.request.user,obj.plan.plan.manager):
|
||||
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
||||
|
||||
return obj
|
||||
@@ -16432,15 +16490,12 @@ class MacroCycleDelete(DeleteView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(MacroCycleDelete, self).get_object(*args, **kwargs)
|
||||
if not checkaccessuser(self.request.user,obj.plan.rower):
|
||||
if not checkaccessuser(self.request.user,obj.plan.manager):
|
||||
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
|
||||
message="This functionality requires a Coach or Self-Coach plan",
|
||||
redirect_field_name=None)
|
||||
def rower_trainingplan_view(request,
|
||||
id=0,
|
||||
userid=0,
|
||||
@@ -16676,6 +16731,9 @@ class TrainingMacroCycleUpdate(UpdateView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs)
|
||||
if obj.plan.manager is not None and self.request.user.rower != obj.plan.manager:
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
|
||||
if not checkaccessuser(self.request.user,obj.plan.rower):
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
else:
|
||||
@@ -16748,6 +16806,9 @@ class TrainingMesoCycleUpdate(UpdateView):
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs)
|
||||
r = obj.plan.plan.rower
|
||||
if obj.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.manager:
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
|
||||
if not checkaccessuser(self.request.user,r):
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
else:
|
||||
@@ -16826,6 +16887,9 @@ class TrainingMicroCycleUpdate(UpdateView):
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs)
|
||||
r = obj.plan.plan.plan.rower
|
||||
if obj.plan.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.plan.manager:
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
|
||||
if not checkaccessuser(self.request.user,r):
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
else:
|
||||
@@ -16840,6 +16904,41 @@ class TrainingPlanUpdate(UpdateView):
|
||||
template_name = 'trainingplan_edit.html'
|
||||
form_class = TrainingPlanForm
|
||||
|
||||
# extra parameters
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(TrainingPlanUpdate, self).get_context_data(**kwargs)
|
||||
|
||||
if 'userid' in kwargs:
|
||||
userid = kwargs['userid']
|
||||
else:
|
||||
userid=0
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(plannedsessions_view,
|
||||
kwargs={'userid':userid}),
|
||||
'name': 'Plan'
|
||||
},
|
||||
{
|
||||
'url':reverse(rower_trainingplan_view,
|
||||
kwargs={'userid':userid,
|
||||
'id':self.object.id}),
|
||||
'name': self.object.name
|
||||
},
|
||||
{
|
||||
'url':reverse('trainingplan_update_view',
|
||||
kwargs={'pk':self.object.pk}),
|
||||
'name': 'Edit'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
context['active'] = 'nav-plan'
|
||||
context['breadcrumbs'] = breadcrumbs
|
||||
context['rower'] = getrequestrower(self.request,userid=userid)
|
||||
|
||||
return context
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse(rower_create_trainingplan)
|
||||
|
||||
@@ -16847,11 +16946,16 @@ class TrainingPlanUpdate(UpdateView):
|
||||
form.instance.user = self.request.user
|
||||
form.instance.post_date = datetime.datetime.now()
|
||||
plan = form.save()
|
||||
plan.manager = self.request.user.rower
|
||||
plan.save()
|
||||
macrocyclecheckdates(plan)
|
||||
return super(TrainingPlanUpdate, self).form_valid(form)
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs)
|
||||
if obj.manager is not None and self.request.user.rower != obj.manager.user:
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
|
||||
if not checkaccessuser(self.request.user,obj.rower):
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
return obj
|
||||
@@ -16872,7 +16976,114 @@ class TrainingTargetUpdate(UpdateView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs)
|
||||
if obj.manager is not None and self.request.user.rower != obj.manager.user:
|
||||
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
||||
|
||||
if not checkaccessuser(self.request.user,obj.rower):
|
||||
raise PermissionDenied('You are not allowed to edit this training plan target')
|
||||
return obj
|
||||
|
||||
def allsundays(startdate,enddate):
|
||||
d = startdate
|
||||
d += timedelta(days = 6 - d.weekday()) # first Sunday
|
||||
while d<enddate:
|
||||
yield d
|
||||
d += timedelta(days=7)
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
|
||||
message="This functionality requires a Coach or Self-Coach plan",
|
||||
redirect_field_name=None)
|
||||
def planmesocyclebyweek(request,id=0,userid=0):
|
||||
try:
|
||||
cycle = TrainingMesoCycle.objects.get(id=id)
|
||||
except TrainingMesoCycle.DoesNotExist:
|
||||
raise Http404("Training Cycle does not exist")
|
||||
|
||||
if not checkaccessuser(request.user,cycle.plan.plan.manager):
|
||||
raise PermissionDenied("You are not allowed to do this")
|
||||
|
||||
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
||||
for m in micros:
|
||||
m.delete()
|
||||
|
||||
cycle.type = 'userdefined'
|
||||
cycle.save()
|
||||
|
||||
#we're still here. We have permission
|
||||
sundays = [s for s in allsundays(cycle.startdate,cycle.enddate)]
|
||||
for i in range(len(sundays)-1):
|
||||
monday = sundays[i]+timedelta(days=1)
|
||||
nextsunday = sundays[i+1]
|
||||
if i == 0 and monday > cycle.startdate:
|
||||
monday = cycle.startdate
|
||||
if nextsunday < cycle.enddate and i == len(sundays)-2:
|
||||
nextsunday = cycle.enddate
|
||||
micro = TrainingMicroCycle(startdate = monday,
|
||||
enddate = nextsunday,
|
||||
plan = cycle,
|
||||
name = 'Week %s' % sundays[i+1].isocalendar()[1],
|
||||
type = 'userdefined')
|
||||
micro.save()
|
||||
|
||||
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
||||
|
||||
url = reverse(rower_trainingplan_view,
|
||||
kwargs = {'userid':str(userid),
|
||||
'id':str(cycle.plan.plan.id),
|
||||
'thismicroid':str(micros[0].id)})
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
def allmonths(startdate,enddate):
|
||||
d = startdate
|
||||
while d<enddate:
|
||||
yield d
|
||||
d = datetime.date(d.year+(d.month / 12),((d.month % 12) + 1),1)
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
|
||||
message="This functionality requires a Coach or Self-Coach plan",
|
||||
redirect_field_name=None)
|
||||
def planmacrocyclebymonth(request,id=0,userid=0):
|
||||
try:
|
||||
cycle = TrainingMacroCycle.objects.get(id=id)
|
||||
except TrainingMacroCycle.DoesNotExist:
|
||||
raise Http404("Training Cycle does not exist")
|
||||
|
||||
if not checkaccessuser(request.user,cycle.plan.manager):
|
||||
raise PermissionDenied("You are not allowed to do this")
|
||||
|
||||
mesos = TrainingMesoCycle.objects.filter(plan=cycle)
|
||||
for m in mesos:
|
||||
m.delete()
|
||||
|
||||
cycle.type = 'userdefined'
|
||||
cycle.save()
|
||||
|
||||
#we're still here. We have permission
|
||||
monthstarts = [d for d in allmonths(cycle.startdate,cycle.enddate)]
|
||||
monthstarts.append(cycle.enddate)
|
||||
for i in range(len(monthstarts)-1):
|
||||
firstday = monthstarts[i]
|
||||
lastday = monthstarts[i+1]-timedelta(days=1)
|
||||
if lastday < cycle.enddate and i == len(monthstarts)-2:
|
||||
lastday = cycle.enddate
|
||||
|
||||
|
||||
meso = TrainingMesoCycle(startdate = firstday,
|
||||
enddate = lastday,
|
||||
plan = cycle,
|
||||
name = '%s' % firstday.strftime("%B"),
|
||||
type = 'userdefined')
|
||||
meso.save()
|
||||
|
||||
mesos = TrainingMesoCycle.objects.filter(plan=cycle)
|
||||
|
||||
url = reverse(rower_trainingplan_view,
|
||||
kwargs = {'userid':str(userid),
|
||||
'id':str(cycle.plan.id),
|
||||
'thismesoid':str(mesos[0].id)})
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
</li>
|
||||
{% if user.is_authenticated %}
|
||||
<li>
|
||||
<a href="/rowers/me/edit" title="Profile">
|
||||
<a href="/rowers/me/preferences" title="Profile">
|
||||
{% if user.rower.rowerplan == 'pro' %}
|
||||
<i class="fas fa-user-ninja "></i>
|
||||
{% elif user.rower.rowerplan == 'coach' %}
|
||||
|
||||
Reference in New Issue
Block a user