Private
Public Access
1
0
This commit is contained in:
Sander Roosendaal
2019-05-27 07:44:04 +02:00
10 changed files with 22379 additions and 46 deletions

View File

@@ -18,6 +18,7 @@ workouttypes = (
('c-boat','Dutch C boat'), ('c-boat','Dutch C boat'),
('churchboat','Finnish Church boat'), ('churchboat','Finnish Church boat'),
('Ride','Ride'), ('Ride','Ride'),
('Bike','Bike'),
('Run','Run'), ('Run','Run'),
('NordicSki','NordicSki'), ('NordicSki','NordicSki'),
('Swim','Swim'), ('Swim','Swim'),
@@ -31,6 +32,7 @@ workouttypes = (
('InlineSkate','InlineSkate'), ('InlineSkate','InlineSkate'),
('Kayaking','Kayaking'), ('Kayaking','Kayaking'),
('Workout','Workout'), ('Workout','Workout'),
('Yoga','Yoga'),
('other','Other'), ('other','Other'),
) )
@@ -60,6 +62,7 @@ stravamapping = collections.OrderedDict({
'InlineSkate':'InlineSkate', 'InlineSkate':'InlineSkate',
'Kayaking':'Kayaking', 'Kayaking':'Kayaking',
'Workout':'Workout', 'Workout':'Workout',
'Yoga':'Yoga',
'other':'Workout', 'other':'Workout',
}) })
@@ -91,6 +94,7 @@ stmapping = collections.OrderedDict({
'InlineSkate':'Skating:InlineSkate', 'InlineSkate':'Skating:InlineSkate',
'Kayaking':'Other:Kayaking', 'Kayaking':'Other:Kayaking',
'Workout':'Other:Workout', 'Workout':'Other:Workout',
'Yoga':'Other',
'other':'Other', 'other':'Other',
}) })
@@ -122,7 +126,7 @@ rkmapping = collections.OrderedDict({
'Kayaking':'Other', 'Kayaking':'Other',
'Workout':'Other', 'Workout':'Other',
'other':'Other', 'other':'Other',
'Yoga':'Other',
}) })
polarmapping = collections.OrderedDict({ polarmapping = collections.OrderedDict({
@@ -152,7 +156,7 @@ polarmapping = collections.OrderedDict({
'Kayaking':'Kayaking', 'Kayaking':'Kayaking',
'Workout':'Other Indoor', 'Workout':'Other Indoor',
'other':'Other Indoor', 'other':'Other Indoor',
'Yoga':'Yoga',
}) })
tpmapping = collections.OrderedDict({ tpmapping = collections.OrderedDict({
@@ -182,7 +186,7 @@ tpmapping = collections.OrderedDict({
'Kayaking':'other', 'Kayaking':'other',
'Workout':'other', 'Workout':'other',
'other':'other', 'other':'other',
'Yoga':'other',
}) })
c2mapping = collections.OrderedDict({ c2mapping = collections.OrderedDict({
@@ -212,6 +216,7 @@ c2mapping = collections.OrderedDict({
'Kayaking':None, 'Kayaking':None,
'Workout':None, 'Workout':None,
'other':None, 'other':None,
'Yoga':None,
}) })

View File

@@ -319,7 +319,11 @@ def get_workout(user,stravaid):
if t is not None: if t is not None:
nr_rows = len(t) nr_rows = len(t)
else: else:
return(0,"Error: Time data wasnt found") duration = int(workoutsummary['elapsed_time'])
t = pd.Series(range(duration+1))
nr_rows = len(t)
if nr_rows == 0: if nr_rows == 0:
return (0,"Error: Time data had zero length") return (0,"Error: Time data had zero length")

View File

@@ -173,6 +173,11 @@ def mocked_getsmallrowdata_db(*args, **kwargs):
return df return df
def mocked_read_cols_df_sql(*args, **kwargs):
df = pd.read_csv('rowers/tests/testdata/readcols.csv')
return df,[]
def mocked_getsmallrowdata_db_water(*args, **kwargs): def mocked_getsmallrowdata_db_water(*args, **kwargs):
df = pd.read_csv('rowers/tests/testdata/colsfromdb.csv') df = pd.read_csv('rowers/tests/testdata/colsfromdb.csv')

View File

@@ -8,6 +8,7 @@ from .statements import *
nu = datetime.datetime.now() nu = datetime.datetime.now()
from rowers.views import *
class WorkoutCompareTest(TestCase): class WorkoutCompareTest(TestCase):
@@ -696,6 +697,409 @@ class WorkoutCompareTestNew(TestCase):
'xparam':'hr', 'xparam':'hr',
'plotfield':'spm', 'plotfield':'spm',
'yparam':'pace', 'yparam':'pace',
'yaxis2':'hr',
'groupby':'spm',
'palette':'monochrome_blue',
'xaxis':'time',
'yaxis1':'power',
'yaxis2':'hr',
'startdate':startdate,
'enddate':enddate,
'plottype':'scatter',
'spmmin':15,
'spmmax':55,
'workmin':0,
'workmax':1500,
'includereststrokes':False,
'modality':'all',
'waterboattype':['1x','2x','4x'],
'rankingonly':False,
'workouts':[1,2,3]
}
form = AnalysisChoiceForm(form_data)
optionsform = AnalysisOptionsForm(form_data)
dateform = DateRangeForm(form_data)
result = form.is_valid()
if not result:
print(form.errors)
self.assertTrue(form.is_valid())
self.assertTrue(optionsform.is_valid())
self.assertTrue(dateform.is_valid())
response = self.c.post('/rowers/user-analysis-select/',form_data)
self.assertEqual(response.status_code,200)
class WorkoutBoxPlotTestNew(TestCase):
def setUp(self):
self.u = UserFactory()
self.r = Rower.objects.create(user=self.u,
birthdate=faker.profile()['birthdate'],
gdproptin=True,
gdproptindate=timezone.now(),
rowerplan='coach')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
self.factory = RequestFactory()
self.password = faker.word()
self.u.set_password(self.password)
self.u.save()
def tearDown(self):
for workout in self.user_workouts:
try:
os.remove(workout.csvfilename)
except (IOError, FileNotFoundError, OSError):
pass
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db')
def test_workouts_boxplot(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
url = '/rowers/user-analysis-select/boxplot/'
response = self.c.get(url)
self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
def test_workouts_boxplot_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login)
startdate = (self.user_workouts[0].startdatetime-datetime.timedelta(days=3)).date()
enddate = (self.user_workouts[0].startdatetime+datetime.timedelta(days=3)).date()
form_data = {
'function':'boxplot',
'xparam':'hr',
'plotfield':'spm',
'yparam':'pace',
'groupby':'spm',
'palette':'monochrome_blue',
'xaxis':'time',
'yaxis1':'power',
'yaxis2':'hr',
'startdate':startdate,
'enddate':enddate,
'plottype':'scatter',
'spmmin':15,
'spmmax':55,
'workmin':0,
'workmax':1500,
'includereststrokes':False,
'modality':'all',
'waterboattype':['1x','2x','4x'],
'rankingonly':False,
'workouts':[1,2,3]
}
form = AnalysisChoiceForm(form_data)
optionsform = AnalysisOptionsForm(form_data)
dateform = DateRangeForm(form_data)
result = form.is_valid()
if not result:
print(form.errors)
self.assertTrue(form.is_valid())
self.assertTrue(optionsform.is_valid())
self.assertTrue(dateform.is_valid())
response = self.c.post('/rowers/user-analysis-select/',form_data)
self.assertEqual(response.status_code,200)
class WorkoutHistoTestNew(TestCase):
def setUp(self):
self.u = UserFactory()
self.r = Rower.objects.create(user=self.u,
birthdate=faker.profile()['birthdate'],
gdproptin=True,
gdproptindate=timezone.now(),
rowerplan='coach')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
self.factory = RequestFactory()
self.password = faker.word()
self.u.set_password(self.password)
self.u.save()
def tearDown(self):
for workout in self.user_workouts:
try:
os.remove(workout.csvfilename)
except (IOError, FileNotFoundError, OSError):
pass
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db')
def test_workouts_histo(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
url = '/rowers/user-analysis-select/histo/'
response = self.c.get(url)
self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
def test_workouts_histo_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login)
startdate = (self.user_workouts[0].startdatetime-datetime.timedelta(days=3)).date()
enddate = (self.user_workouts[0].startdatetime+datetime.timedelta(days=3)).date()
form_data = {
'function':'histo',
'xparam':'hr',
'plotfield':'spm',
'yparam':'pace',
'groupby':'spm',
'palette':'monochrome_blue',
'xaxis':'time',
'yaxis1':'power',
'yaxis2':'hr',
'startdate':startdate,
'enddate':enddate,
'plottype':'scatter',
'spmmin':15,
'spmmax':55,
'workmin':0,
'workmax':1500,
'includereststrokes':False,
'modality':'all',
'waterboattype':['1x','2x','4x'],
'rankingonly':False,
'workouts':[1,2,3]
}
form = AnalysisChoiceForm(form_data)
optionsform = AnalysisOptionsForm(form_data)
dateform = DateRangeForm(form_data)
result = form.is_valid()
if not result:
print(form.errors)
self.assertTrue(form.is_valid())
self.assertTrue(optionsform.is_valid())
self.assertTrue(dateform.is_valid())
response = self.c.post('/rowers/user-analysis-select/',form_data)
self.assertEqual(response.status_code,200)
class WorkoutFlexallTestNew(TestCase):
def setUp(self):
self.u = UserFactory()
self.r = Rower.objects.create(user=self.u,
birthdate=faker.profile()['birthdate'],
gdproptin=True,
gdproptindate=timezone.now(),
rowerplan='coach')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
self.factory = RequestFactory()
self.password = faker.word()
self.u.set_password(self.password)
self.u.save()
def tearDown(self):
for workout in self.user_workouts:
try:
os.remove(workout.csvfilename)
except (IOError, FileNotFoundError, OSError):
pass
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db')
def test_workouts_flexall(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
url = '/rowers/user-analysis-select/flexall/'
response = self.c.get(url)
self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
def test_workouts_flexall_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login)
startdate = (self.user_workouts[0].startdatetime-datetime.timedelta(days=3)).date()
enddate = (self.user_workouts[0].startdatetime+datetime.timedelta(days=3)).date()
form_data = {
'function':'flexall',
'xparam':'hr',
'plotfield':'spm',
'yparam':'pace',
'groupby':'spm',
'palette':'monochrome_blue',
'xaxis':'time',
'yaxis1':'power',
'yaxis2':'hr',
'startdate':startdate,
'enddate':enddate,
'plottype':'scatter',
'spmmin':15,
'spmmax':55,
'workmin':0,
'workmax':1500,
'includereststrokes':False,
'modality':'all',
'waterboattype':['1x','2x','4x'],
'rankingonly':False,
'workouts':[1,2,3]
}
form = AnalysisChoiceForm(form_data)
optionsform = AnalysisOptionsForm(form_data)
dateform = DateRangeForm(form_data)
result = form.is_valid()
if not result:
print(form.errors)
self.assertTrue(form.is_valid())
self.assertTrue(optionsform.is_valid())
self.assertTrue(dateform.is_valid())
response = self.c.post('/rowers/user-analysis-select/',form_data)
self.assertEqual(response.status_code,200)
class WorkoutStatsTestNew(TestCase):
def setUp(self):
self.u = UserFactory()
self.r = Rower.objects.create(user=self.u,
birthdate=faker.profile()['birthdate'],
gdproptin=True,
gdproptindate=timezone.now(),
rowerplan='coach')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
self.factory = RequestFactory()
self.password = faker.word()
self.u.set_password(self.password)
self.u.save()
def tearDown(self):
for workout in self.user_workouts:
try:
os.remove(workout.csvfilename)
except (IOError, FileNotFoundError, OSError):
pass
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db')
def test_workouts_stats(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
url = '/rowers/user-analysis-select/stats/'
response = self.c.get(url)
self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
@patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql)
def test_analysis_data(self,
mocked_sqlalchemy,
mocked_getsmallrowdata_db,
mocked_read_cols_df_sql,
):
startdate = (self.user_workouts[0].startdatetime-datetime.timedelta(days=3)).date()
enddate = (self.user_workouts[0].startdatetime+datetime.timedelta(days=3)).date()
options = {
'function':'flexall',
'xparam':'hr',
'plotfield':'spm',
'yparam':'pace',
'groupby':'spm',
'binsize':1,
'ploterrorbars':True,
'palette':'monochrome_blue',
'xaxis':'time',
'yaxis1':'power',
'yaxis2':'hr',
'startdate':startdate,
'enddate':enddate,
'plottype':'scatter',
'spmmin':15,
'spmmax':55,
'workmin':0,
'workmax':1500,
'includereststrokes':False,
'modality':'all',
'waterboattype':['1x','2x','4x'],
'rankingonly':False,
'ids':[1,2,3],
'userid':self.u.id,
}
workouts = self.user_workouts
script, div = boxplotdata(workouts,options)
script, div = trendflexdata(workouts,options)
# script, div = histodata(workouts,options)
script, div = flexalldata(workouts,options)
script, div = statsdata(workouts,options)
script, div = comparisondata(workouts,options)
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
def test_workouts_stats_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db):
login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login)
startdate = (self.user_workouts[0].startdatetime-datetime.timedelta(days=3)).date()
enddate = (self.user_workouts[0].startdatetime+datetime.timedelta(days=3)).date()
form_data = {
'function':'stats',
'xparam':'hr',
'plotfield':'spm',
'yparam':'pace',
'groupby':'spm', 'groupby':'spm',
'palette':'monochrome_blue', 'palette':'monochrome_blue',
'xaxis':'time', 'xaxis':'time',

21921
rowers/tests/testdata/readcols.csv vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -236,8 +236,8 @@ urlpatterns = [
re_path(r'^list-jobs/$',views.session_jobs_view,name='session_jobs_view'), re_path(r'^list-jobs/$',views.session_jobs_view,name='session_jobs_view'),
re_path(r'^jobs-status/$',views.session_jobs_status,name='session_jobs_status'), re_path(r'^jobs-status/$',views.session_jobs_status,name='session_jobs_status'),
re_path(r'^job-kill/(?P<id>.*)/$',views.kill_async_job), re_path(r'^job-kill/(?P<id>.*)/$',views.kill_async_job),
re_path(r'^test-job/(?P<aantal>\d+)/$',views.test_job_view), # re_path(r'^test-job/(?P<aantal>\d+)/$',views.test_job_view),
re_path(r'^test-job2/(?P<aantal>\d+)/$',views.test_job_view2), # re_path(r'^test-job2/(?P<aantal>\d+)/$',views.test_job_view2),
re_path(r'^record-progress/(?P<value>\d+)/(?P<id>.*)/$',views.post_progress,name='post_progress'), re_path(r'^record-progress/(?P<value>\d+)/(?P<id>.*)/$',views.post_progress,name='post_progress'),
re_path(r'^record-progress/(?P<id>.*)/$',views.post_progress), re_path(r'^record-progress/(?P<id>.*)/$',views.post_progress),
re_path(r'^record-progress/$',views.post_progress), re_path(r'^record-progress/$',views.post_progress),

View File

@@ -325,12 +325,7 @@ def trendflexdata(workouts, options,userid=0):
binsize) binsize)
groups = datadf.groupby(pd.cut(datadf[groupby],bins,labels=False)) groups = datadf.groupby(pd.cut(datadf[groupby],bins,labels=False))
except ValueError: except ValueError:
messages.error( return ('','Error: not enough data')
request,
"Unable to compete. Probably not enough data selected"
)
url = reverse(user_multiflex_select)
return HttpResponseRedirect(url)
else: else:
bins = np.arange(datadf['days ago'].min()-binsize, bins = np.arange(datadf['days ago'].min()-binsize,
datadf['days ago'].max()+binsize, datadf['days ago'].max()+binsize,

View File

@@ -621,40 +621,40 @@ def raise_500(request):
else: else:
return HttpResponse("invalid") return HttpResponse("invalid")
@login_required() #@login_required()
def test_job_view(request,aantal=100): #def test_job_view(request,aantal=100):
#
# session_key = request.session._session_key
#
# job = myqueue(queuehigh,long_test_task,int(aantal),
# session_key=session_key)
#
#
# try:
# request.session['async_tasks'] += [(job.id,'long_test_task')]
# except KeyError:
# request.session['async_tasks'] = [(job.id,'long_test_task')]
#
# url = reverse(session_jobs_status)
#
# return HttpResponseRedirect(url)
session_key = request.session._session_key #@login_required()
#def test_job_view2(request,aantal=100):
job = myqueue(queuehigh,long_test_task,int(aantal), #
session_key=session_key) #
# job = myqueue(queuehigh,long_test_task2,int(aantal),
# secret=settings.PROGRESS_CACHE_SECRET)#
try: #
request.session['async_tasks'] += [(job.id,'long_test_task')] #
except KeyError: # try:
request.session['async_tasks'] = [(job.id,'long_test_task')] # request.session['async_tasks'] += [(job.id,'long_test_task2')]
# except KeyError:
url = reverse(session_jobs_status) # request.session['async_tasks'] = [(job.id,'long_test_task2')]
#
return HttpResponseRedirect(url) # url = reverse(session_jobs_status)
#
@login_required() # return HttpResponseRedirect(url)
def test_job_view2(request,aantal=100):
job = myqueue(queuehigh,long_test_task2,int(aantal),
secret=settings.PROGRESS_CACHE_SECRET)
try:
request.session['async_tasks'] += [(job.id,'long_test_task2')]
except KeyError:
request.session['async_tasks'] = [(job.id,'long_test_task2')]
url = reverse(session_jobs_status)
return HttpResponseRedirect(url)
@csrf_exempt @csrf_exempt
def post_progress(request,id=None,value=0): def post_progress(request,id=None,value=0):

View File

@@ -60,7 +60,6 @@ def get_metar_data(airportcode,unixtime):
if s.ok: if s.ok:
doc = etree.fromstring(s.content) doc = etree.fromstring(s.content)
lengte = len(doc.xpath('data/METAR/station_id')) lengte = len(doc.xpath('data/METAR/station_id'))
print('Lengte ',lengte,int(lengte/2))
idnr = int(lengte/2) idnr = int(lengte/2)
try: try:
id = doc.xpath('data/METAR/station_id')[idnr].text id = doc.xpath('data/METAR/station_id')[idnr].text