updatefitnessmetric as middleware
This commit is contained in:
@@ -515,7 +515,7 @@ def paceformatsecs(values):
|
||||
|
||||
return out
|
||||
|
||||
def fitnessmetric_to_sql(m,table='powertimefitnessmetric'):
|
||||
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False):
|
||||
engine = create_engine(database_url, echo=False)
|
||||
columns = ', '.join(m.keys())
|
||||
placeholders = ", ".join(["?"] * len(m))
|
||||
@@ -529,7 +529,7 @@ def fitnessmetric_to_sql(m,table='powertimefitnessmetric'):
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
|
||||
return result
|
||||
return 1
|
||||
|
||||
|
||||
def getcpdata_sql(rower_id,table='cpdata'):
|
||||
|
||||
@@ -495,6 +495,26 @@ def getsmallrowdata_db(columns,ids=[],debug=False):
|
||||
|
||||
return data
|
||||
|
||||
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False):
|
||||
if debug:
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
columns = ', '.join(m.keys())
|
||||
placeholders = ", ".join(["?"] * len(m))
|
||||
|
||||
query = "INSERT into %s ( %s ) Values (%s)" % (table, columns, placeholders)
|
||||
|
||||
values = tuple(m[key] for key in m.keys())
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query,values)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
61
rowers/middleware.py
Normal file
61
rowers/middleware.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from django.utils import timezone
|
||||
from rowers.models import Workout, PowerTimeFitnessMetric, Rower
|
||||
import datetime
|
||||
|
||||
def getrower(user):
|
||||
try:
|
||||
r = Rower.objects.get(user=user)
|
||||
except Rower.DoesNotExist:
|
||||
r = Rower(user=user)
|
||||
r.save()
|
||||
|
||||
return r
|
||||
|
||||
def do_update(user,mode='rower',days=42):
|
||||
r = getrower(user)
|
||||
|
||||
startdate = timezone.now()-datetime.timedelta(days=days)
|
||||
|
||||
# test if not something already done
|
||||
now_date = timezone.now().strftime('%Y-%m-%d')
|
||||
ms = PowerTimeFitnessMetric.objects.filter(
|
||||
user=user,
|
||||
workoutmode=mode)
|
||||
|
||||
if len(ms) == 0:
|
||||
return 0
|
||||
|
||||
max_workout_id = max([m.last_workout for m in ms])
|
||||
last_update_date = max([m.date.strftime('%Y-%m-%d') for m in ms])
|
||||
|
||||
if mode == 'rower':
|
||||
workouts = Workout.objects.filter(
|
||||
user=r,
|
||||
workouttype__in=['rower','dynamic','slides'],
|
||||
startdatetime__gte=startdate)
|
||||
else:
|
||||
workouts = Workout.objects.filter(
|
||||
user=r,
|
||||
workouttype__in=['water','coastal'],
|
||||
startdatetime__gte=startdate)
|
||||
|
||||
theids = [int(w.id) for w in workouts]
|
||||
max_id = max(theids)
|
||||
|
||||
if last_update_date < now_date and max_workout_id < max_id:
|
||||
job = myqueue(queue,
|
||||
handle_updatefitnessmetric,
|
||||
request.user.id,mode,theids,
|
||||
)
|
||||
|
||||
return 1
|
||||
|
||||
class PowerTimeFitnessMetricMiddleWare(object):
|
||||
def process_request(self, request):
|
||||
# Code to be executed before the view is called
|
||||
|
||||
result = do_update(request.user,mode='rower')
|
||||
result = do_update(request.user,mode='water')
|
||||
|
||||
|
||||
|
||||
@@ -249,6 +249,7 @@ class PowerTimeFitnessMetric(models.Model):
|
||||
)
|
||||
|
||||
date = models.DateField(default=timezone.now)
|
||||
last_workout = models.IntegerField(default=0)
|
||||
user = models.ForeignKey(User)
|
||||
PowerFourMin = models.FloatField(default=0)
|
||||
PowerTwoK = models.FloatField(default=0)
|
||||
|
||||
@@ -25,13 +25,14 @@ from rowsandall_app.settings import PROGRESS_CACHE_SECRET
|
||||
import pandas as pd
|
||||
|
||||
from django_rq import job
|
||||
from django.utils import timezone
|
||||
|
||||
from utils import deserialize_list
|
||||
|
||||
from rowers.dataprepnodjango import (
|
||||
update_strokedata, new_workout_from_file,
|
||||
getsmallrowdata_db, updatecpdata_sql,
|
||||
update_agegroup_db,
|
||||
update_agegroup_db,fitnessmetric_to_sql
|
||||
)
|
||||
|
||||
from django.core.mail import send_mail, EmailMessage
|
||||
@@ -612,6 +613,82 @@ def handle_updateergcp(rower_id,workoutfilenames,debug=False,**kwargs):
|
||||
|
||||
return 1
|
||||
|
||||
@app.task
|
||||
def handle_updatefitnessmetric(user_id,mode,workoutids,debug=False,
|
||||
**kwargs):
|
||||
|
||||
columns = ['power','workoutid','time']
|
||||
df = getsmallrowdata_db(columns,ids=workoutids,debug=debug)
|
||||
df.dropna(inplace=True,axis=0)
|
||||
|
||||
if df.empty:
|
||||
# change this
|
||||
return 2
|
||||
|
||||
# df is not empty. We continue
|
||||
dfgrouped = df.groupby(['workoutid'])
|
||||
maxt = 1.05*df['time'].max()/1000.
|
||||
|
||||
logarr = datautils.getlogarr(maxt)
|
||||
|
||||
delta,cpvalue,avgpower = datautils.getcp(dfgrouped,logarr)
|
||||
|
||||
powerdf = pd.DataFrame({
|
||||
'Delta':delta,
|
||||
'CP':cpvalue,
|
||||
})
|
||||
|
||||
powerdf = powerdf[powerdf['CP']>0]
|
||||
powerdf.dropna(axis=0,inplace=True)
|
||||
powerdf.sort_values(['Delta','CP'],ascending=[1,0],inplace=True)
|
||||
powerdf.drop_duplicates(subset='Delta',keep='first',inplace=True)
|
||||
|
||||
p1,fitt,fitpower,ratio = datautils.cpfit(powerdf)
|
||||
# This is code duplication from datautils -- correct asap
|
||||
fitfunc = lambda pars,x: abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
|
||||
|
||||
powerfourmin = fitfunc(p1,240.)
|
||||
powerhour = fitfunc(p1,3600.)
|
||||
|
||||
# 2k power
|
||||
velofourmin = (powerfourmin/2.8)**(1./3.)
|
||||
dfourmin = 240.*velofourmin
|
||||
dratio = 2000./dfourmin
|
||||
pacefourmin = 500./velofourmin
|
||||
|
||||
# assume 5 sec per doubling drop
|
||||
pace2k = pacefourmin + 5.*np.log10(dratio)/np.log10(2.)
|
||||
velo2k = 500./pace2k
|
||||
t2k = 2000./velo2k
|
||||
pwr2k = fitfunc(p1,t2k)
|
||||
velo2 = (pwr2k/2.8)**(1./3.)
|
||||
if np.isnan(velo2) or velo2 <= 0:
|
||||
velo2 = 1.0
|
||||
|
||||
t2 = 2000./velo2
|
||||
|
||||
pwr2k = fitfunc(p1,t2)
|
||||
|
||||
velo3 = (pwr2k/2.8)**(1./3.)
|
||||
|
||||
t3 = 2000./velo3
|
||||
|
||||
power2k = fitfunc(p1,t3)
|
||||
|
||||
|
||||
mdict = {
|
||||
'user_id': user_id,
|
||||
'PowerFourMin': powerfourmin,
|
||||
'PowerTwoK': power2k,
|
||||
'PowerOneHour': powerhour,
|
||||
'workoutmode': mode,
|
||||
'last_workout': max(workoutids),
|
||||
'date': timezone.now().strftime('%Y-%m-%d'),
|
||||
}
|
||||
|
||||
result = fitnessmetric_to_sql(mdict,debug=debug)
|
||||
|
||||
return result
|
||||
|
||||
@app.task
|
||||
def handle_updatecp(rower_id,workoutids,debug=False,table='cpdata',**kwargs):
|
||||
|
||||
@@ -15,6 +15,7 @@ landingpages = (
|
||||
)
|
||||
|
||||
|
||||
|
||||
workflowmiddlepanel = (
|
||||
('panel_statcharts.html','Static Charts'),
|
||||
('flexthumbnails.html','Flex Charts'),
|
||||
|
||||
115
rowers/views.py
115
rowers/views.py
@@ -109,7 +109,8 @@ from rowers.tasks import (
|
||||
handle_sendemail_unrecognized,handle_sendemailnewcomment,
|
||||
handle_sendemailnewresponse, handle_updatedps,
|
||||
handle_updatecp,long_test_task,long_test_task2,
|
||||
handle_zip_file,handle_getagegrouprecords
|
||||
handle_zip_file,handle_getagegrouprecords,
|
||||
handle_updatefitnessmetric
|
||||
)
|
||||
|
||||
from scipy.signal import savgol_filter
|
||||
@@ -159,6 +160,20 @@ class JSONResponse(HttpResponse):
|
||||
kwargs['content_type'] = 'application/json'
|
||||
super(JSONResponse, self).__init__(content, **kwargs)
|
||||
|
||||
|
||||
def getrower(user):
|
||||
try:
|
||||
r = Rower.objects.get(user=user)
|
||||
except Rower.DoesNotExist:
|
||||
r = Rower(user=user)
|
||||
r.save()
|
||||
|
||||
return r
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def getvalue(data):
|
||||
perc = 0
|
||||
total = 1
|
||||
@@ -737,6 +752,8 @@ def iscoachmember(user):
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def getrower(user):
|
||||
try:
|
||||
r = Rower.objects.get(user=user)
|
||||
@@ -746,6 +763,8 @@ def getrower(user):
|
||||
|
||||
return r
|
||||
|
||||
|
||||
|
||||
# Check if a user is a Pro member
|
||||
def ispromember(user):
|
||||
if not user.is_anonymous():
|
||||
@@ -3211,6 +3230,16 @@ def addmanual_view(request):
|
||||
def fitness_metric_view(request,mode='rower',days=42):
|
||||
r = getrower(request.user)
|
||||
startdate = timezone.now()-datetime.timedelta(days=days)
|
||||
|
||||
# test if not something already done
|
||||
ms = PowerTimeFitnessMetric.objects.filter(user=request.user)
|
||||
max_workout_id = max([m.last_workout for m in ms])
|
||||
last_update_date = max([m.date.strftime('%Y-%m-%d') for m in ms])
|
||||
|
||||
|
||||
now_date = timezone.now().strftime('%Y-%m-%d')
|
||||
|
||||
|
||||
if mode == 'rower':
|
||||
workouts = Workout.objects.filter(
|
||||
user=r,
|
||||
@@ -3223,88 +3252,18 @@ def fitness_metric_view(request,mode='rower',days=42):
|
||||
startdatetime__gte=startdate)
|
||||
|
||||
theids = [int(w.id) for w in workouts]
|
||||
columns = ['power','workoutid','time']
|
||||
df = getsmallrowdata_db(columns,ids=theids)
|
||||
df.dropna(inplace=True,axis=0)
|
||||
max_id = max(theids)
|
||||
|
||||
if df.empty:
|
||||
# change this
|
||||
return 'aap'
|
||||
|
||||
# df is not empty. We continue
|
||||
dfgrouped = df.groupby(['workoutid'])
|
||||
maxt = 1.05*df['time'].max()/1000.
|
||||
|
||||
logarr = datautils.getlogarr(maxt)
|
||||
|
||||
delta,cpvalue,avgpower = datautils.getcp(dfgrouped,logarr)
|
||||
|
||||
powerdf = pd.DataFrame({
|
||||
'Delta':delta,
|
||||
'CP':cpvalue,
|
||||
})
|
||||
|
||||
powerdf = powerdf[powerdf['CP']>0]
|
||||
powerdf.dropna(axis=0,inplace=True)
|
||||
powerdf.sort_values(['Delta','CP'],ascending=[1,0],inplace=True)
|
||||
powerdf.drop_duplicates(subset='Delta',keep='first',inplace=True)
|
||||
|
||||
p1,fitt,fitpower,ratio = datautils.cpfit(powerdf)
|
||||
# This is code duplication from datautils -- correct asap
|
||||
fitfunc = lambda pars,x: abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
|
||||
|
||||
powerfourmin = fitfunc(p1,240.)
|
||||
powerhour = fitfunc(p1,3600.)
|
||||
|
||||
# 2k power
|
||||
velofourmin = (powerfourmin/2.8)**(1./3.)
|
||||
dfourmin = 240.*velofourmin
|
||||
dratio = 2000./dfourmin
|
||||
pacefourmin = 500./velofourmin
|
||||
|
||||
# assume 5 sec per doubling drop
|
||||
pace2k = pacefourmin + 5.*np.log10(dratio)/np.log10(2.)
|
||||
velo2k = 500./pace2k
|
||||
t2k = 2000./velo2k
|
||||
pwr2k = fitfunc(p1,t2k)
|
||||
velo2 = (pwr2k/2.8)**(1./3.)
|
||||
if np.isnan(velo2) or velo2 <= 0:
|
||||
velo2 = 1.0
|
||||
|
||||
t2 = 2000./velo2
|
||||
|
||||
pwr2k = fitfunc(p1,t2)
|
||||
|
||||
velo3 = (pwr2k/2.8)**(1./3.)
|
||||
|
||||
t3 = 2000./velo3
|
||||
|
||||
power2k = fitfunc(p1,t3)
|
||||
if last_update_date >= now_date or max_workout_id >= max_id:
|
||||
return HttpResponse("already done today or no new workouts")
|
||||
|
||||
|
||||
mdict = {
|
||||
'user_id': request.user.id,
|
||||
'PowerFourMin': powerfourmin,
|
||||
'PowerTwoK': power2k,
|
||||
'PowerOneHour': powerhour,
|
||||
'workoutmode': mode,
|
||||
'date': timezone.now().strftime('%Y-%m-%d'),
|
||||
}
|
||||
|
||||
result = dataprep.fitnessmetric_to_sql(mdict)
|
||||
|
||||
m = PowerTimeFitnessMetric(
|
||||
user=request.user,
|
||||
PowerFourMin = powerfourmin,
|
||||
PowerTwoK = power2k,
|
||||
PowerOneHour = powerhour,
|
||||
workoutmode = mode,
|
||||
date = timezone.now()
|
||||
job = myqueue(queue,
|
||||
handle_updatefitnessmetric,
|
||||
request.user.id,mode,theids,
|
||||
)
|
||||
|
||||
m.save()
|
||||
|
||||
return HttpResponse("success")
|
||||
return HttpResponse("job queued")
|
||||
|
||||
|
||||
# Show ranking distances including predicted paces
|
||||
|
||||
@@ -93,6 +93,7 @@ MIDDLEWARE_CLASSES = [
|
||||
'async_messages.middleware.AsyncMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'tz_detect.middleware.TimezoneMiddleware',
|
||||
'rowers.middleware.PowerTimeFitnessMetricMiddleWare',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'rowsandall_app.urls'
|
||||
|
||||
Reference in New Issue
Block a user