234 lines
6.2 KiB
Python
234 lines
6.2 KiB
Python
# Python
|
|
from django.utils import timezone
|
|
from datetime import datetime
|
|
from datetime import timedelta
|
|
from datetime import date
|
|
import time
|
|
from django.db import IntegrityError
|
|
import uuid
|
|
from django.conf import settings
|
|
|
|
from utils import myqueue
|
|
|
|
import django_rq
|
|
queue = django_rq.get_queue('default')
|
|
queuelow = django_rq.get_queue('low')
|
|
queuehigh = django_rq.get_queue('low')
|
|
|
|
from rowers.models import (
|
|
Rower, Workout,
|
|
GeoCourse, TrainingMicroCycle,TrainingMesoCycle,TrainingMacroCycle,
|
|
TrainingPlan,PlannedSession,
|
|
)
|
|
|
|
import metrics
|
|
import numpy as np
|
|
import dataprep
|
|
|
|
# Low Level functions - to be called by higher level methods
|
|
def add_workouts_plannedsession(ws,ps):
|
|
result = 0
|
|
comments = []
|
|
errors = []
|
|
|
|
# check if all sessions have same date
|
|
dates = [w.date for w in ws]
|
|
if (not all(d == dates[0] for d in dates)) and ps.sessiontype != 'challenge':
|
|
errors.append('For tests and training sessions, selected workouts must all be done on the same date')
|
|
return result,comments,errors
|
|
|
|
# start adding sessions
|
|
for w in ws:
|
|
if w.date>=ps.startdate and w.date<=ps.enddate:
|
|
w.plannedsession = ps
|
|
w.save()
|
|
result += 1
|
|
comments.append('Attached workout %i to session' % w.id)
|
|
else:
|
|
errors.append('Workout %i did not match session dates' % w.id)
|
|
|
|
return result,comments,errors
|
|
|
|
|
|
def remove_workout_plannedsession(w,ps):
|
|
if w.plannedsession == ps:
|
|
w.plannedsession = None
|
|
w.save()
|
|
return 1
|
|
|
|
return 0
|
|
|
|
def clone_planned_session(ps):
|
|
ps.save()
|
|
ps.pk = None # creates new instance
|
|
ps.save()
|
|
|
|
def timefield_to_seconds_duration(t):
|
|
duration = t.hour*3600.
|
|
duration += t.minute * 60.
|
|
duration += t.second
|
|
duration += t.microsecond/1.e6
|
|
|
|
return duration
|
|
|
|
def is_session_complete(r,ps):
|
|
status = 'not done'
|
|
|
|
ws = Workout.objects.filter(user=r,plannedsession=ps)
|
|
|
|
if len(ws)==0:
|
|
today = date.today()
|
|
if today > ps.enddate:
|
|
status = 'missed'
|
|
ratio = 0
|
|
return ratio,status
|
|
else:
|
|
return 0,'not done'
|
|
|
|
score = 0
|
|
for w in ws:
|
|
if ps.sessionmode == 'distance':
|
|
score += w.distance
|
|
elif ps.sessionmode == 'time':
|
|
durationseconds = timefield_to_seconds_duration(w.duration)
|
|
score += durationseconds
|
|
elif ps.sessionmode == 'TRIMP':
|
|
trimp = dataprep.workout_trimp(w)
|
|
score += trimp
|
|
elif ps.sessionmode == 'rScore':
|
|
rscore = dataprep.workout_rscore(w)
|
|
score += rscore
|
|
|
|
value = ps.sessionvalue
|
|
if ps.sessionunit == 'min':
|
|
value *= 60.
|
|
elif ps.sessionunit == 'km':
|
|
value *= 1000.
|
|
|
|
ratio = score/float(value)
|
|
|
|
status = 'partial'
|
|
|
|
if ps.sessiontype == 'session':
|
|
if ps.criterium == 'exact':
|
|
if ratio == 1.0:
|
|
return ratio,'completed'
|
|
else:
|
|
return ratio,'partial'
|
|
elif ps.criterium == 'minimum':
|
|
if ratio > 1.0:
|
|
return ratio,'completed'
|
|
else:
|
|
return ratio,'partial'
|
|
else:
|
|
if ratio>0.8 and ratio<1.2:
|
|
return ratio,'completed'
|
|
else:
|
|
return ratio,'partial'
|
|
elif ps.sessiontype == 'test':
|
|
if ratio==1.0:
|
|
return ratio,'completed'
|
|
else:
|
|
return ratio,'partial'
|
|
elif ps.sessiontype == 'challenge':
|
|
if ps.criterium == 'exact':
|
|
if ratio == 1.0:
|
|
return ratio,'completed'
|
|
else:
|
|
return ratio,'partial'
|
|
elif ps.criterium == 'minimum':
|
|
if ratio > 1.0:
|
|
return ratio,'completed'
|
|
else:
|
|
return ratio,'partial'
|
|
else:
|
|
return ratio,'partial'
|
|
|
|
else:
|
|
return ratio,status
|
|
|
|
def rank_results(ps):
|
|
return 1
|
|
|
|
def add_team_session(t,ps):
|
|
ps.team.add(t)
|
|
ps.save()
|
|
|
|
return 1
|
|
|
|
def add_rower_session(r,ps):
|
|
ps.rower.add(r)
|
|
ps.save()
|
|
|
|
return 1
|
|
|
|
def remove_team_session(t,ps):
|
|
ps.team.remove(t)
|
|
|
|
return 1
|
|
|
|
def remove_rower_session(r,ps):
|
|
ps.rower.remove(r)
|
|
|
|
return 1
|
|
|
|
def get_dates_timeperiod(timeperiod):
|
|
# set start end date according timeperiod
|
|
if timeperiod=='today':
|
|
startdate=date.today()
|
|
enddate=date.today()
|
|
elif timeperiod=='tomorrow':
|
|
startdate=date.today()+timezone.timedelta(days=1)
|
|
enddate=date.today()+timezone.timedelta(days=1)
|
|
elif timeperiod=='thisweek':
|
|
today = date.today()
|
|
startdate = date.today()-timezone.timedelta(days=today.weekday())
|
|
enddate = startdate+timezone.timedelta(days=6)
|
|
elif timeperiod=='thismonth':
|
|
today = date.today()
|
|
startdate = today.replace(day=1)
|
|
enddate = startdate+timezone.timedelta(days=32)
|
|
enddate = enddate.replace(day=1)
|
|
enddate = enddate-timezone.timedelta(days=1)
|
|
elif timeperiod=='lastweek':
|
|
today = date.today()
|
|
enddate = today-timezone.timedelta(days=today.weekday())-timezone.timedelta(days=1)
|
|
startdate = enddate-timezone.timedelta(days=6)
|
|
elif timeperiod=='lastmonth':
|
|
today = date.today()
|
|
startdate = today.replace(day=1)
|
|
startdate = startdate-timezone.timedelta(days=3)
|
|
startdate = startdate.replace(day=1)
|
|
enddate = startdate+timezone.timedelta(days=32)
|
|
enddate = enddate.replace(day=1)
|
|
enddate = enddate-timezone.timedelta(days=1)
|
|
else:
|
|
startdate = date.today()
|
|
enddate = date.today()
|
|
|
|
return startdate,enddate
|
|
|
|
def get_sessions(r,startdate=date.today(),
|
|
enddate=date.today()+timezone.timedelta(+1000)):
|
|
|
|
sps = PlannedSession.objects.filter(
|
|
rower__in=[r],
|
|
startdate__lte=enddate,
|
|
enddate__gte=startdate,
|
|
).order_by("startdate","enddate")
|
|
|
|
return sps
|
|
|
|
def get_workouts_session(r,ps):
|
|
ws = Workout.objects.filter(user=r,plannedsession=ps)
|
|
|
|
return ws
|
|
|
|
def update_plannedsession(ps,cd):
|
|
for attr, value in cd.items():
|
|
setattr(ps, attr, value)
|
|
|
|
ps.save()
|
|
|
|
return 1,'Planned Session Updated'
|