Merge branch 'feature/tasks' into develop
This commit is contained in:
@@ -23,12 +23,12 @@ def time_in_path(df, p, maxmin='max', getall=False, name='unknown', logfile=None
|
||||
def f(x):
|
||||
return coordinate_in_path(x['latitude'], x['longitude'], p)
|
||||
|
||||
df['inpolygon'] = df.apply(f, axis=1)
|
||||
inpolygon = df.apply(lambda row:f(row), axis=1).copy()
|
||||
|
||||
if maxmin == 'max':
|
||||
b = (~df['inpolygon']).shift(-1)+df['inpolygon']
|
||||
b = (~inpolygon).shift(-1)+inpolygon
|
||||
else: # pragma: no cover
|
||||
b = (~df['inpolygon']).shift(1)+df['inpolygon']
|
||||
b = (~inpolygon).shift(1)+inpolygon
|
||||
|
||||
if len(df[b == 2]):
|
||||
if logfile is not None: # pragma: no cover
|
||||
@@ -90,7 +90,7 @@ def coursetime_first(data, paths, polygons=[], logfile=None):
|
||||
|
||||
try:
|
||||
entrytime, entrydistance = time_in_path(
|
||||
data, paths[0], maxmin='max', name=polygons[0][1], logfile=logfile)
|
||||
data, paths[0], maxmin='max', name=str(polygons[0]), logfile=logfile)
|
||||
coursecompleted = True
|
||||
except InvalidTrajectoryError: # pragma: no cover
|
||||
entrytime = data['time'].max()
|
||||
@@ -118,7 +118,7 @@ def coursetime_paths(data, paths, finalmaxmin='min', polygons=[], logfile=None):
|
||||
(
|
||||
entrytime,
|
||||
entrydistance
|
||||
) = time_in_path(data, paths[0], maxmin=finalmaxmin, name=polygons[0][1], logfile=logfile)
|
||||
) = time_in_path(data, paths[0], maxmin=finalmaxmin, name=str(polygons[0]), logfile=logfile)
|
||||
coursecompleted = True
|
||||
except InvalidTrajectoryError: # pragma: no cover
|
||||
entrytime = data['time'].max()
|
||||
@@ -129,7 +129,7 @@ def coursetime_paths(data, paths, finalmaxmin='min', polygons=[], logfile=None):
|
||||
if len(paths) > 1:
|
||||
try:
|
||||
time, dist = time_in_path(
|
||||
data, paths[0], name=polygons[0][1], logfile=logfile)
|
||||
data, paths[0], name=str(polygons[0]), logfile=logfile)
|
||||
data2 = data[data['time'] > time].copy()
|
||||
data2['time'] = data2['time'].apply(lambda x: x-time)
|
||||
data2['cum_dist'] = data2['cum_dist'].apply(lambda x: x-dist)
|
||||
|
||||
@@ -16,3 +16,7 @@ database_url = 'mysql://{user}:{password}@{host}:{port}/{database_name}'.format(
|
||||
|
||||
if settings.DEBUG or user == '':
|
||||
database_url = 'sqlite:///db.sqlite3'
|
||||
|
||||
#database_name_dev = DEV_DATABASES['default']['NAME']
|
||||
|
||||
database_url_debug = database_url
|
||||
|
||||
3126
rowers/dataprep.py
3126
rowers/dataprep.py
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ from django.shortcuts import redirect
|
||||
from django.http import HttpResponse
|
||||
from django.contrib import messages
|
||||
from rowers.mytypes import otwtypes
|
||||
from rowers.tasks import handle_sendemail_expired
|
||||
#from rowers.tasks import handle_sendemail_expired
|
||||
from django.utils import timezone
|
||||
from rowers.models import Workout, PowerTimeFitnessMetric, Rower, PaidPlan
|
||||
import datetime
|
||||
@@ -99,6 +99,7 @@ class RowerPlanMiddleWare(object):
|
||||
# remove from Free Coach groups
|
||||
|
||||
# send email
|
||||
from rowers.tasks import handle_sendemail_expired
|
||||
_ = myqueue(queue,
|
||||
handle_sendemail_expired,
|
||||
r.user.email,
|
||||
|
||||
@@ -553,8 +553,9 @@ def polygon_coord_center(polygon):
|
||||
return latitudes.mean(), longitudes.mean()
|
||||
|
||||
|
||||
def polygon_to_path(polygon):
|
||||
def polygon_to_path(polygon, debug=False):
|
||||
points = GeoPoint.objects.filter(polygon=polygon).order_by("order_in_poly")
|
||||
|
||||
s = []
|
||||
for point in points:
|
||||
s.append([point.latitude, point.longitude])
|
||||
|
||||
348
rowers/tasks.py
348
rowers/tasks.py
@@ -1,3 +1,22 @@
|
||||
import os
|
||||
|
||||
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
|
||||
from YamJam import yamjam
|
||||
CFG = yamjam()['rowsandallapp']
|
||||
|
||||
try:
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE",CFG['settings_name'])
|
||||
except KeyError: # pragma: no cover
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE","rowsandall_app.settings")
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
application = get_wsgi_application()
|
||||
from rowers.models import (
|
||||
Workout, GeoPolygon, GeoPoint, GeoCourse,
|
||||
VirtualRaceResult, CourseTestResult, Rower
|
||||
)
|
||||
|
||||
import math
|
||||
from rowers.courseutils import (
|
||||
coursetime_paths, coursetime_first, time_in_path,
|
||||
@@ -16,8 +35,7 @@ import rowers.longtask as longtask
|
||||
import requests
|
||||
import rowers.datautils as datautils
|
||||
|
||||
""" Background tasks done by Celery (develop) or QR (production) """
|
||||
import os
|
||||
""" Background tasks done by QR (production) """
|
||||
import time
|
||||
import gc
|
||||
import gzip
|
||||
@@ -36,8 +54,8 @@ import rowingdata
|
||||
from rowingdata import make_cumvalues
|
||||
from uuid import uuid4
|
||||
from rowingdata import rowingdata as rdata
|
||||
|
||||
from datetime import timedelta
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
from rowers.celery import app
|
||||
from celery import shared_task
|
||||
@@ -61,13 +79,15 @@ import rowers.otw_power_calculator_pb2_grpc as calculator_pb2_grpc
|
||||
import rowers.rowing_workout_metrics_pb2 as metrics_pb2
|
||||
import rowers.rowing_workout_metrics_pb2_grpc as metrics_pb2_grpc
|
||||
|
||||
from rowsandall_app.settings import SITE_URL
|
||||
from rowsandall_app.settings_dev import SITE_URL as SITE_URL_DEV
|
||||
from rowsandall_app.settings import PROGRESS_CACHE_SECRET
|
||||
from rowsandall_app.settings import SETTINGS_NAME
|
||||
from rowsandall_app.settings import workoutemailbox
|
||||
from rowsandall_app.settings import UPLOAD_SERVICE_SECRET, UPLOAD_SERVICE_URL
|
||||
from rowsandall_app.settings import NK_API_LOCATION
|
||||
from django.conf import settings
|
||||
SITE_URL = settings.SITE_URL
|
||||
SITE_URL_DEV = settings.SITE_URL
|
||||
PROGRESS_CACHE_SECRET = settings.PROGRESS_CACHE_SECRET
|
||||
SETTINGS_NAME = settings.SETTINGS_NAME
|
||||
|
||||
UPLOAD_SERVICE_URL = settings.UPLOAD_SERVICE_URL
|
||||
UPLOAD_SERVICE_SECRET = settings.UPLOAD_SERVICE_SECRET
|
||||
NK_API_LOCATION = settings.NK_API_LOCATION
|
||||
|
||||
from requests_oauthlib import OAuth1, OAuth1Session
|
||||
|
||||
@@ -83,16 +103,19 @@ from rowers.emails import htmlstrip
|
||||
from rowers import mytypes
|
||||
|
||||
|
||||
from rowers.dataprepnodjango import (
|
||||
from rowers.dataprep import (
|
||||
getsmallrowdata_db, updatecpdata_sql, update_c2id_sql,
|
||||
update_workout_field_sql,
|
||||
#update_workout_field_sql,
|
||||
update_agegroup_db, update_strokedata,
|
||||
add_c2_stroke_data_db, totaltime_sec_to_string,
|
||||
create_c2_stroke_data_db, update_empower,
|
||||
database_url_debug, database_url, dataprep,
|
||||
# database_url_debug,
|
||||
database_url, dataprep,
|
||||
# create_strava_stroke_data_db
|
||||
)
|
||||
|
||||
database_url_debug = database_url
|
||||
|
||||
|
||||
from rowers.opaque import encoder
|
||||
|
||||
@@ -277,7 +300,9 @@ def summaryfromsplitdata(splitdata, data, filename, sep='|', workouttype='rower'
|
||||
|
||||
@app.task
|
||||
def handle_request_post(url, data, debug=False, **kwargs): # pragma: no cover
|
||||
response = requests.post(url, data)
|
||||
if 'localhost' in url:
|
||||
url = 'http'+url[5:]
|
||||
response = requests.post(url, data, verify=False)
|
||||
dologging('upload_api.log', data)
|
||||
dologging('upload_api.log', response.status_code)
|
||||
return response.status_code
|
||||
@@ -297,10 +322,11 @@ def handle_c2_sync(workoutid, url, headers, data, debug=False, **kwargs):
|
||||
s = response.json()
|
||||
c2id = s['data']['id']
|
||||
|
||||
res = update_workout_field_sql(
|
||||
workoutid, 'uploadedtoc2', c2id, debug=debug)
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
workout.uploadedtoc2 = c2id
|
||||
workout.save()
|
||||
|
||||
return res
|
||||
return 1
|
||||
|
||||
|
||||
@app.task
|
||||
@@ -316,8 +342,10 @@ def handle_sporttracks_sync(workoutid, url, headers, data, debug=False, **kwargs
|
||||
|
||||
id = int(m)
|
||||
|
||||
_ = update_workout_field_sql(
|
||||
workoutid, 'uploadedtosporttracks', id, debug=debug)
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
workout.uploadedtosporttracks = id
|
||||
workout.save()
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
@@ -338,7 +366,7 @@ def handle_strava_sync(stravatoken, workoutid, filename, name, activity_type, de
|
||||
tb = traceback.format_exc()
|
||||
dologging('strava_fail.log', tb)
|
||||
failed = True
|
||||
except stravalib.exc.TimeoutExceeded:
|
||||
except stravalib.exc.TimeoutExceeded: # pragma: no cover
|
||||
dologging('strava_fail.log', 'Strava upload failed for Workout {id} TimeOutExceeded'.format(
|
||||
id=workoutid))
|
||||
tb = traceback.format_exc()
|
||||
@@ -378,8 +406,9 @@ def handle_strava_sync(stravatoken, workoutid, filename, name, activity_type, de
|
||||
failed = True
|
||||
|
||||
if not failed:
|
||||
_ = update_workout_field_sql(
|
||||
workoutid, 'uploadedtostrava', res.id, debug=debug)
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
workout.uploadedtostrava = res.id
|
||||
workout.save()
|
||||
try:
|
||||
act = client.update_activity(res.id, activity_type=activity_type,
|
||||
description=description, device_name='Rowsandall.com')
|
||||
@@ -507,37 +536,14 @@ def getagegrouprecord(age, sex='male', weightcategory='hwt',
|
||||
return power
|
||||
|
||||
|
||||
def polygon_to_path(polygon, debug=True):
|
||||
pid = polygon[0]
|
||||
query = "SELECT id, latitude, longitude FROM rowers_geopoint WHERE polygon_id = {pid}"\
|
||||
" ORDER BY order_in_poly ASC".format(
|
||||
pid=pid)
|
||||
if debug:
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else: # pragma: no cover
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
points = result.fetchall()
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
s = []
|
||||
|
||||
for point in points:
|
||||
s.append([point[1], point[2]])
|
||||
|
||||
p = path.Path(s[:-1])
|
||||
|
||||
return p
|
||||
from rowers.models import polygon_to_path
|
||||
|
||||
|
||||
@app.task(bind=True)
|
||||
def handle_check_race_course(self,
|
||||
f1, workoutid, courseid,
|
||||
recordid, useremail, userfirstname,
|
||||
**kwargs): # pragma: no cover
|
||||
**kwargs):
|
||||
|
||||
logfile = 'courselog_{workoutid}_{courseid}.log'.format(
|
||||
workoutid=workoutid, courseid=courseid)
|
||||
@@ -567,11 +573,11 @@ def handle_check_race_course(self,
|
||||
mode = kwargs['mode']
|
||||
|
||||
summary = False
|
||||
if 'summary' in kwargs:
|
||||
if 'summary' in kwargs: # pragma: no cover
|
||||
summary = kwargs['summary']
|
||||
|
||||
successemail = False
|
||||
if 'successemail' in kwargs:
|
||||
if 'successemail' in kwargs: # pragma: no cover
|
||||
successemail = kwargs['successemail']
|
||||
|
||||
try:
|
||||
@@ -606,35 +612,21 @@ def handle_check_race_course(self,
|
||||
|
||||
rowdata.fillna(method='backfill', inplace=True)
|
||||
|
||||
rowdata['time'] = rowdata['time']-rowdata.loc[0, 'time']
|
||||
rowdata = rowdata[rowdata['time'] > splitsecond]
|
||||
rowdata.loc[:, 'time'] = rowdata.loc[:, 'time'].copy()-rowdata.loc[0, 'time']
|
||||
rowdata = rowdata.copy()[rowdata['time'] > splitsecond]
|
||||
# we may want to expand the time (interpolate)
|
||||
rowdata['dt'] = rowdata['time'].apply(
|
||||
|
||||
rowdata.loc[:,'dt'] = rowdata['time'].apply(
|
||||
lambda x: safetimedelta(x)
|
||||
)
|
||||
).values
|
||||
|
||||
|
||||
rowdata = rowdata.resample('100ms', on='dt').mean()
|
||||
rowdata = rowdata.interpolate()
|
||||
|
||||
# initiate database engine
|
||||
course = GeoCourse.objects.get(id=courseid)
|
||||
polygons = course.polygons.all()
|
||||
|
||||
if debug: # pragma: no cover
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
# get polygons
|
||||
query = "SELECT id,name FROM rowers_geopolygon WHERE course_id = {courseid} ORDER BY order_in_course ASC".format(
|
||||
courseid=courseid
|
||||
)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
polygons = result.fetchall()
|
||||
|
||||
conn.close()
|
||||
|
||||
engine.dispose()
|
||||
|
||||
paths = []
|
||||
for polygon in polygons:
|
||||
@@ -649,7 +641,7 @@ def handle_check_race_course(self,
|
||||
try:
|
||||
entrytimes, entrydistances = time_in_path(rowdata, paths[0], maxmin='max', getall=True,
|
||||
name=polygons[0].name, logfile=logfile)
|
||||
except AttributeError: # for testing
|
||||
except AttributeError: # pragma: no cover
|
||||
entrytimes, entrydistances = time_in_path(rowdata, paths[0], maxmin='max', getall=True,
|
||||
name='Start', logfile=logfile)
|
||||
with open(logfile, 'ab') as f:
|
||||
@@ -718,7 +710,8 @@ def handle_check_race_course(self,
|
||||
'endsecond': endseconds,
|
||||
})
|
||||
|
||||
records = records[records['coursecompleted'] is True]
|
||||
#records = records[records['coursecompleted'] is True]
|
||||
records = records.loc[records['coursecompleted'], : ]
|
||||
|
||||
if len(records):
|
||||
coursecompleted = True
|
||||
@@ -736,35 +729,29 @@ def handle_check_race_course(self,
|
||||
coursedistance = coursemeters
|
||||
velo = coursedistance/coursetimeseconds
|
||||
points = 100*(2.-referencespeed/velo)
|
||||
query = 'UPDATE rowers_virtualraceresult SET coursecompleted = 1,'\
|
||||
' duration = "{duration}", distance = {distance},'\
|
||||
' workoutid = {workoutid}, startsecond = {startsecond},'\
|
||||
' endsecond = {endsecond}, points={points} WHERE id={recordid}'.format(
|
||||
recordid=recordid,
|
||||
duration=totaltime_sec_to_string(coursetimeseconds),
|
||||
distance=int(coursemeters),
|
||||
points=points,
|
||||
workoutid=workoutid,
|
||||
startsecond=startsecond,
|
||||
endsecond=endsecond,)
|
||||
|
||||
if mode == 'coursetest':
|
||||
query = 'UPDATE rowers_coursetestresult SET coursecompleted = 1,'\
|
||||
' duration = "{duration}", distance = {distance},'\
|
||||
' workoutid = {workoutid}, startsecond = {startsecond},'\
|
||||
' endsecond = {endsecond}, points={points} WHERE id={recordid}'.format(
|
||||
recordid=recordid,
|
||||
duration=totaltime_sec_to_string(coursetimeseconds),
|
||||
distance=int(coursemeters),
|
||||
points=points,
|
||||
workoutid=workoutid,
|
||||
startsecond=startsecond,
|
||||
endsecond=endsecond,)
|
||||
if mode != 'coursetest':
|
||||
record = VirtualRaceResult.objects.get(id=recordid)
|
||||
record.duration = totaltime_sec_to_string(coursetimeseconds)
|
||||
record.distance=int(coursemeters)
|
||||
record.points = points
|
||||
record.startsecond = startsecond
|
||||
record.endsecond = endsecond
|
||||
record.workoutid = workoutid
|
||||
record.coursecompleted = 1
|
||||
record.save()
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
else: # pragma: no cover
|
||||
record = CourseTestResult.objects.get(id=recordid)
|
||||
record.duration = totaltime_sec_to_string(coursetimeseconds)
|
||||
record.distance = int(coursemeters)
|
||||
record.workoutid = workoutid
|
||||
record.startsecond = startsecond
|
||||
record.endsecond = endsecond
|
||||
record.points = points
|
||||
record.save()
|
||||
|
||||
if summary:
|
||||
if summary: # pragma: no cover
|
||||
try:
|
||||
row = rdata(csvfile=f1)
|
||||
except IOError: # pragma: no cover
|
||||
@@ -784,17 +771,12 @@ def handle_check_race_course(self,
|
||||
|
||||
summary = row.allstats()
|
||||
row.write_csv(f1, gzip=True)
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
workout.summary = summary
|
||||
workout.save()
|
||||
|
||||
query = "UPDATE `rowers_workout` SET `summary` = '%s' WHERE `id` = %s" % (
|
||||
summary, workoutid)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
|
||||
if successemail:
|
||||
if successemail: # pragma: no cover
|
||||
handle_sendemail_coursesucceed(
|
||||
useremail, userfirstname, logfile, workoutid
|
||||
)
|
||||
@@ -804,36 +786,26 @@ def handle_check_race_course(self,
|
||||
return 1
|
||||
|
||||
else: # pragma: no cover
|
||||
query = 'UPDATE rowers_virtualraceresult SET coursecompleted = 0,'\
|
||||
' duration = "{duration}", distance = {distance},'\
|
||||
' workoutid = {workoutid}, startsecond = {startsecond},'\
|
||||
' endsecond = {endsecond}, points={points} WHERE id={recordid}'.format(
|
||||
recordid=recordid,
|
||||
duration=totaltime_sec_to_string(0),
|
||||
distance=0,
|
||||
points=0.0,
|
||||
workoutid=workoutid,
|
||||
startsecond=startsecond,
|
||||
endsecond=endsecond,)
|
||||
record = VirtualRaceResult.object.get(id=recordid)
|
||||
record.duration = totaltime_sec_to_string(0)
|
||||
record.distance = 0
|
||||
record.workoutid = workoutid
|
||||
record.startsecond = startsecond
|
||||
record.endsecond = endsecond
|
||||
record.points = 0
|
||||
record.save()
|
||||
|
||||
if mode == 'coursetest':
|
||||
query = 'UPDATE rowers_coursetestresult SET coursecompleted = 0,'\
|
||||
' duration = "{duration}", distance = {distance}, workoutid = {workoutid}'\
|
||||
', startsecond = {startsecond}, endsecond = {endsecond}'\
|
||||
', points={points} WHERE id={recordid}'.format(
|
||||
recordid=recordid,
|
||||
duration=totaltime_sec_to_string(0),
|
||||
distance=0,
|
||||
points=0,
|
||||
workoutid=workoutid,
|
||||
startsecond=startsecond,
|
||||
endsecond=endsecond,)
|
||||
record = CourseTestResult.objects.get(id=recordid)
|
||||
record.duration = totaltime_sec_to_string(0)
|
||||
record.distance = 0
|
||||
record.workoutid = workoutid
|
||||
record.startsecond = startsecond
|
||||
record.endsecond = endsecond
|
||||
record.points = 0
|
||||
record.save()
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
|
||||
# add times for all gates to log file
|
||||
with open(logfile, 'ab') as f:
|
||||
@@ -1086,10 +1058,7 @@ def handle_calctrimp(id,
|
||||
hrmax,
|
||||
hrmin,
|
||||
debug=False, **kwargs):
|
||||
if debug: # pragma: no cover
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
|
||||
tss = 0
|
||||
normp = 0
|
||||
@@ -1178,21 +1147,14 @@ def handle_calctrimp(id,
|
||||
if hrtss > 1000: # pragma: no cover
|
||||
hrtss = 0
|
||||
|
||||
query = 'UPDATE rowers_workout SET rscore = {tss},'\
|
||||
' normp = {normp}, trimp={trimp}, hrtss={hrtss},'\
|
||||
' normv={normv}, normw={normw} WHERE id={id}'.format(
|
||||
tss=int(tss),
|
||||
normp=int(normp),
|
||||
trimp=int(trimp),
|
||||
hrtss=int(hrtss),
|
||||
normv=normv,
|
||||
normw=normw,
|
||||
id=id,)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
_ = conn.execute(query)
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
workout = Workout.objects.get(id=id)
|
||||
workout.tss = int(tss)
|
||||
workout.normp = int(normp)
|
||||
workout.trimp = int(trimp)
|
||||
workout.hrtss = int(hrtss)
|
||||
workout.normv = normv
|
||||
workout.normw = normw
|
||||
workout.save()
|
||||
|
||||
return 1
|
||||
|
||||
@@ -1974,7 +1936,7 @@ def handle_sendemail_ical(first_name, last_name, email, url, icsfile, **kwargs):
|
||||
|
||||
try:
|
||||
os.remove(icsfile)
|
||||
except:
|
||||
except: # pragma: no cover
|
||||
pass
|
||||
|
||||
return 1
|
||||
@@ -2834,23 +2796,13 @@ def handle_update_wps(rid, types, ids, mode, debug=False, **kwargs):
|
||||
except ValueError: # pragma: no cover
|
||||
return 0
|
||||
|
||||
rower = Rower.objects.get(id=rid)
|
||||
if mode == 'water':
|
||||
query = "UPDATE `rowers_rower` SET `median_wps` = '%s' WHERE `id` = '%s'" % (
|
||||
wps_median, rid)
|
||||
rower.median_wps = wps_median
|
||||
else:
|
||||
query = "UPDATE `rowers_rower` SET `median_wps_erg` = '%s' WHERE `id` = '%s'" % (
|
||||
wps_median, rid)
|
||||
rower.median_wps_erg = wps_median
|
||||
|
||||
if debug: # pragma: no cover
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
_ = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
rower.save()
|
||||
|
||||
return wps_median
|
||||
|
||||
@@ -2999,23 +2951,8 @@ def handle_nk_async_workout(alldata, userid, nktoken, nkid, delaysec, defaulttim
|
||||
workoutid, error = add_workout_from_data(userid, nkid, data, df)
|
||||
|
||||
# dologging('nklog.log','NK Workout ID {id}'.format(id=workoutid))
|
||||
|
||||
if debug: # pragma: no cover
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
query = 'SELECT uploadedtonk from rowers_workout WHERE id ={workoutid}'.format(
|
||||
workoutid=workoutid)
|
||||
|
||||
newnkid = 0
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
tdata = result.fetchall()
|
||||
if tdata:
|
||||
newnkid = tdata[0][0]
|
||||
|
||||
conn.close()
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
newnkid = workout.uploadedtonk
|
||||
|
||||
parkedids = []
|
||||
try:
|
||||
@@ -3303,22 +3240,8 @@ def handle_c2_async_workout(alldata, userid, c2token, c2id, delaysec, defaulttim
|
||||
|
||||
workoutid = response.json()['id']
|
||||
|
||||
if debug: # pragma: no cover
|
||||
engine = create_engine(database_url_debug, echo=False)
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
query = 'SELECT uploadedtoc2 from rowers_workout WHERE id ={workoutid}'.format(
|
||||
workoutid=workoutid)
|
||||
|
||||
newc2id = 0
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
tdata = result.fetchall()
|
||||
if tdata: # pragma: no cover
|
||||
newc2id = tdata[0][0]
|
||||
|
||||
conn.close()
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
newc2id = workout.uploadedtoc2
|
||||
|
||||
parkedids = []
|
||||
with open('c2blocked.json', 'r') as c2blocked:
|
||||
@@ -3335,14 +3258,10 @@ def handle_c2_async_workout(alldata, userid, c2token, c2id, delaysec, defaulttim
|
||||
json.dump(tdata, c2blocked)
|
||||
|
||||
# set distance, time
|
||||
query = "UPDATE `rowers_workout` SET `distance` = '%s', `duration` = '%s' WHERE `id` = '%s'" % (
|
||||
distance, duration, workoutid)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
workout.distance = distance
|
||||
workout.duration = duration
|
||||
workout.save()
|
||||
|
||||
# summary
|
||||
if 'workout' in data:
|
||||
@@ -3359,14 +3278,9 @@ def handle_c2_async_workout(alldata, userid, c2token, c2id, delaysec, defaulttim
|
||||
summary, sa, results = summaryfromsplitdata(
|
||||
splitdata, data, csvfilename, workouttype=workouttype)
|
||||
|
||||
query = "UPDATE `rowers_workout` SET `summary` = '%s' WHERE `id` = %s" % (
|
||||
summary, workoutid)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
workout = Workout.objects.get(id=workoutid)
|
||||
workout.summary = summary
|
||||
workout.save()
|
||||
|
||||
from rowingdata.trainingparser import getlist
|
||||
if sa:
|
||||
|
||||
@@ -81,10 +81,13 @@ class AsyncTaskTests(TestCase):
|
||||
|
||||
def test_polygons(self):
|
||||
polygons = GeoPolygon.objects.all()
|
||||
|
||||
polygon = polygons[0]
|
||||
obj = (polygon.id,polygon.name)
|
||||
path = tasks.polygon_to_path(obj)
|
||||
self.assertEqual(len(path),4)
|
||||
|
||||
#obj = (polygon.id,polygon.name)
|
||||
path = tasks.polygon_to_path(polygon)
|
||||
|
||||
self.assertEqual(len(path),6)
|
||||
|
||||
def test_summaryfromsplitdata(self):
|
||||
splitdata = [
|
||||
@@ -495,21 +498,21 @@ class AsyncTaskTests(TestCase):
|
||||
|
||||
self.assertEqual(res,1)
|
||||
|
||||
@patch('rowers.dataprepnodjango.create_engine')
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
def test_handle_updateergcp(self,mocked_sqlalchemy):
|
||||
f1 = get_random_file()['filename']
|
||||
res = tasks.handle_updateergcp(1,[f1])
|
||||
self.assertEqual(res,1)
|
||||
|
||||
|
||||
@patch('rowers.dataprepnodjango.getsmallrowdata_db')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
def test_handle_updatecp(self,mocked_getsmallrowdata_db_updatecp):
|
||||
rower_id = 1
|
||||
workoutids = [1]
|
||||
res = tasks.handle_updatecp(rower_id,workoutids)
|
||||
self.assertEqual(res,1)
|
||||
|
||||
@patch('rowers.dataprepnodjango.getsmallrowdata_db')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
def test_handle_setcp(self,mocked_getsmallrowdata_db_setcp):
|
||||
strokesdf = pd.read_csv('rowers/tests/testdata/uhfull.csv')
|
||||
filename = 'rowers/tests/testdata/temp/pq.gz'
|
||||
@@ -521,7 +524,7 @@ class AsyncTaskTests(TestCase):
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
@patch('rowers.dataprepnodjango.getsmallrowdata_db')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
def test_handle_update_wps(self,mocked_getsmallrowdata_db_wps):
|
||||
ids = [1,2,3]
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ class CPChartTest(TestCase):
|
||||
|
||||
# add some tests of complex form data (no hr, no spm, zero spm, etc)
|
||||
|
||||
@patch('rowers.dataprepnodjango.create_engine')
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
def test_agerecords(self, mock_sqlalchemy):
|
||||
# update_records(url='rowers/tests/c2worldrecords.html',verbose=False)
|
||||
|
||||
|
||||
@@ -1554,6 +1554,36 @@ description: ""
|
||||
|
||||
self.instantplan.save()
|
||||
|
||||
self.startdate = (datetime.datetime.now()-datetime.timedelta(days=1)).date()
|
||||
self.enddate = (datetime.datetime.now()+datetime.timedelta(days=1)).date()
|
||||
self.preferreddate = datetime.datetime.now().date()
|
||||
|
||||
|
||||
self.ps = SessionFactory(startdate=self.startdate,enddate=self.enddate,
|
||||
sessiontype='session',
|
||||
sessionmode = 'time',
|
||||
criterium = 'none',
|
||||
sessionvalue = 60,
|
||||
sessionunit='min',
|
||||
preferreddate=self.preferreddate,
|
||||
manager=self.u,
|
||||
interval_string = '5x(800m/5min)'
|
||||
)
|
||||
|
||||
self.ps.save()
|
||||
|
||||
|
||||
result = plannedsessions.add_rower_session(self.r,self.ps)
|
||||
|
||||
self.step = PlannedSessionStep(
|
||||
manager = self.u,
|
||||
name = 'cd',
|
||||
durationvalue = '50000',
|
||||
durationtype = 'Distance',
|
||||
)
|
||||
|
||||
self.step.save()
|
||||
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
@@ -1562,6 +1592,72 @@ description: ""
|
||||
except (IOError, FileNotFoundError,OSError):
|
||||
pass
|
||||
|
||||
def test_stepadder(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/plans/stepeditor/{id}/'.format(id=self.ps.id)
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
url = '/rowers/plans/stepadder/{id}/'.format(id=self.ps.id)
|
||||
|
||||
bdy = json.dumps([self.step.id])
|
||||
|
||||
response = self.c.post(url, bdy, content_type='application/json',
|
||||
**{'HTTP_X_REQUESTED_WITH':'XMLHttpRequest'})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_stepdelete(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/plans/step/{id}/delete'.format(id=self.step.id)
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_stepedit(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/plans/step/{id}/edit/{psid}/'.format(
|
||||
id=self.step.id, psid=self.ps.id
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
data = {
|
||||
'durationtype': 'RepeatUntilStepsCmplt',
|
||||
'durationvalue': '0.0',
|
||||
#'targettype': None,
|
||||
'targetvalue': '8',
|
||||
'targetvaluelow': '0',
|
||||
'targetvaluehigh': '0',
|
||||
'intensity': 'Active',
|
||||
'description': 'aap'
|
||||
}
|
||||
|
||||
form = StepEditorForm(data)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
reponse = self.c.post(url, data)
|
||||
self.assertTrue(response.status_code,200)
|
||||
|
||||
def test_save_plan_yaml_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/saveasplan/?when={s}/{e}'.format(
|
||||
s = self.startdate.strftime("%Y-%m-%d"),
|
||||
e = self.enddate.strftime("%Y-%m-%d")
|
||||
)
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_clone_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
@@ -888,8 +888,7 @@ class ChallengesTest(TestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
@patch('rowers.tasks.create_engine', side_effect=mocked_sqlalchemy_courses)
|
||||
def notest_virtualevent_check_view(self,mocked_sqlalchemy_courses):
|
||||
def test_virtualevent_check_view(self):
|
||||
|
||||
res = tasks.handle_check_race_course(
|
||||
self.wthyro.csvfilename,
|
||||
@@ -898,7 +897,6 @@ class ChallengesTest(TestCase):
|
||||
self.result.id,
|
||||
self.wthyro.user.user.email,
|
||||
self.wthyro.user.user.first_name,
|
||||
mode='coursetest',
|
||||
)
|
||||
|
||||
self.assertEqual(res,1)
|
||||
|
||||
@@ -515,7 +515,7 @@ def rower_process_garmincallback(request): # pragma: no cover
|
||||
|
||||
# Process Rojabo callback
|
||||
@login_required()
|
||||
def rower_process_rojabocallback(request): # prgrma: no cover
|
||||
def rower_process_rojabocallback(request): # pragma: no cover
|
||||
# do stuff
|
||||
try:
|
||||
code = request.GET.get('code', None)
|
||||
|
||||
@@ -1409,7 +1409,7 @@ def save_plan_yaml(request, userid=0):
|
||||
steps = ps.steps
|
||||
steps['filename'] = ""
|
||||
workouts.append(steps)
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
if ps.sessionmode == 'distance':
|
||||
ps.interval_string = '{d}m'.format(d=ps.sessionvalue)
|
||||
elif ps.sessionmode == 'time':
|
||||
@@ -2994,7 +2994,8 @@ def rower_create_trainingplan(request, id=0):
|
||||
redirect_field_name=None)
|
||||
def stepadder(request, id=0):
|
||||
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
|
||||
if not is_ajax:
|
||||
|
||||
if not is_ajax: # pragma: no cover
|
||||
return JSONResponse(
|
||||
status=403, data={
|
||||
'status': 'false',
|
||||
@@ -3005,7 +3006,7 @@ def stepadder(request, id=0):
|
||||
|
||||
is_save = request.GET.get('save',0)
|
||||
|
||||
if request.method != 'POST':
|
||||
if request.method != 'POST': # pragma: no cover
|
||||
message = {'status': 'false',
|
||||
'message': 'this view cannot be accessed through GET'}
|
||||
return JSONResponse(status=403, data=message)
|
||||
@@ -3013,14 +3014,16 @@ def stepadder(request, id=0):
|
||||
try:
|
||||
json_data = json.loads(request.body)
|
||||
post_data = json_data
|
||||
except (KeyError, JSONDecodeError):
|
||||
except (KeyError, JSONDecodeError): # pragma: no cover
|
||||
q = request.POST
|
||||
post_data = {k: q.getlist(k) if len(
|
||||
q.getlist(k)) > 1 else v for k, v in q.items()}
|
||||
|
||||
# only allow local host
|
||||
hostt = request.get_host().split(':')
|
||||
if hostt[0] not in ['localhost', '127.0.0.1', 'dev.rowsandall.com', 'rowsandall.com']:
|
||||
|
||||
if hostt[0] not in ['localhost', '127.0.0.1', 'dev.rowsandall.com', 'rowsandall.com',
|
||||
'testserver']: # pragma: no cover
|
||||
message = {'status': 'false',
|
||||
'message': 'permission denied for host '+hostt[0]}
|
||||
return JSONResponse(status=403, data=message)
|
||||
@@ -3028,7 +3031,7 @@ def stepadder(request, id=0):
|
||||
if ps.steps:
|
||||
filename = ps.steps.get('filename','')
|
||||
sport = ps.steps.get('sport','rowing')
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
filename = ''
|
||||
sport = 'rowing'
|
||||
|
||||
@@ -3045,10 +3048,10 @@ def stepadder(request, id=0):
|
||||
d = step.asdict()
|
||||
d['stepId'] = nr
|
||||
steps['steps'].append(d)
|
||||
except PlannedSessionStep.DoesNotExist:
|
||||
except PlannedSessionStep.DoesNotExist: # pragma: no cover
|
||||
pass
|
||||
|
||||
if is_save:
|
||||
if is_save: # pragma: no cover
|
||||
# save the darn thing
|
||||
ps.steps = steps
|
||||
|
||||
@@ -3066,9 +3069,12 @@ def stepdelete(request, id=0):
|
||||
|
||||
step.delete()
|
||||
|
||||
backid = request.GET.get('id')
|
||||
backid = request.GET.get('id',0)
|
||||
|
||||
url = reverse(stepeditor,kwargs={'id':backid})
|
||||
if backid: # pragma: no cover
|
||||
url = reverse(stepeditor,kwargs={'id':backid})
|
||||
else:
|
||||
url = reverse('plannedsessions_view')
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@@ -3079,7 +3085,7 @@ def stepedit(request, id=0, psid=0):
|
||||
step = get_object_or_404(PlannedSessionStep, pk=id)
|
||||
try:
|
||||
ps = PlannedSession.objects.get(id=psid)
|
||||
except PlannedSession.DoesNotExist:
|
||||
except PlannedSession.DoesNotExist: # pragma: no cover
|
||||
ps = None
|
||||
|
||||
form = StepEditorForm(instance=step)
|
||||
@@ -3094,7 +3100,7 @@ def stepedit(request, id=0, psid=0):
|
||||
ee = ss.copy()
|
||||
ee.pop('stepId')
|
||||
|
||||
if (dd == ee):
|
||||
if (dd == ee): # pragma: no cover
|
||||
ss['durationType'] = form.cleaned_data['durationtype']
|
||||
ss['durationValue'] = form.cleaned_data['durationvalue']
|
||||
ss['targetType'] = form.cleaned_data['targettype']
|
||||
@@ -3126,15 +3132,15 @@ def stepedit(request, id=0, psid=0):
|
||||
step.name = form.cleaned_data['name']
|
||||
step.description = form.cleaned_data['description']
|
||||
|
||||
if step.durationtype == 'Time':
|
||||
if step.durationtype == 'Time': # pragma: no cover
|
||||
step.durationvalue *= 60000
|
||||
elif step.durationtype == 'Distance':
|
||||
elif step.durationtype == 'Distance': # pragma: no cover
|
||||
step.durationvalue *= 100
|
||||
|
||||
step.save()
|
||||
|
||||
|
||||
if step.durationtype == 'Time':
|
||||
if step.durationtype == 'Time': # pragma: no cover
|
||||
form.fields['durationvalue'].initial = step.durationvalue / 60000
|
||||
elif step.durationtype == 'Distance':
|
||||
form.fields['durationvalue'].initial = step.durationvalue / 100
|
||||
@@ -3143,7 +3149,7 @@ def stepedit(request, id=0, psid=0):
|
||||
stepdescription = step_to_string(step.asdict(), short=False)[0]
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'stepsave_and_return' in request.POST:
|
||||
if 'stepsave_and_return' in request.POST: # pragma: no cover
|
||||
url = reverse('stepeditor',kwargs = {'id': ps.id})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@@ -3204,7 +3210,7 @@ def stepeditor(request, id=0):
|
||||
targetvaluehigh = targetvaluehigh,
|
||||
intensity = intensity,
|
||||
)
|
||||
if not archived_steps.count() and durationvalue != 0:
|
||||
if not archived_steps.count():
|
||||
s = PlannedSessionStep(
|
||||
manager = request.user,
|
||||
durationtype = durationtype,
|
||||
@@ -3217,14 +3223,14 @@ def stepeditor(request, id=0):
|
||||
name = step.get('wkt_step_name','Step')
|
||||
)
|
||||
s.save()
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
s = archived_steps[0]
|
||||
currentsteps.append(s)
|
||||
|
||||
|
||||
form = StepEditorForm()
|
||||
|
||||
if request.method == 'POST':
|
||||
if request.method == 'POST': # pragma: no cover
|
||||
form = StepEditorForm(request.POST)
|
||||
if form.is_valid():
|
||||
step = form.save(commit=False)
|
||||
|
||||
Reference in New Issue
Block a user