From 8ca9446e486fc98909a383832b26bfff11db85f4 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 15 Apr 2021 18:06:30 +0200 Subject: [PATCH] further cleanupp --- rowers/templates/alert_delete_confirm.html | 6 +- rowers/tests/test_analysis.py | 597 ++---- rowers/tests/test_permissions.py | 8 +- rowers/tests/test_urls.py | 73 - rowers/tests/viewnames.csv | 9 - rowers/urls.py | 19 - rowers/views/analysisviews.py | 2035 +------------------- 7 files changed, 147 insertions(+), 2600 deletions(-) diff --git a/rowers/templates/alert_delete_confirm.html b/rowers/templates/alert_delete_confirm.html index 8871a27d..39a7646f 100644 --- a/rowers/templates/alert_delete_confirm.html +++ b/rowers/templates/alert_delete_confirm.html @@ -6,20 +6,20 @@ {% block main %}

Confirm Delete

This will permanently delete the alert

- +
  • {% csrf_token %}

    Are you sure you want to delete {{ object }}?

    - +

- + {% endblock %} diff --git a/rowers/tests/test_analysis.py b/rowers/tests/test_analysis.py index 5deb71b9..b79abbd4 100644 --- a/rowers/tests/test_analysis.py +++ b/rowers/tests/test_analysis.py @@ -75,104 +75,6 @@ class WorkoutCompareTest(TestCase): self.assertEqual(response.status_code,200) -class BoxPlotTest(TestCase): - def setUp(self): - self.u = UserFactory() - - self.r = Rower.objects.create(user=self.u, - birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=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-boxplot-select/' - - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - @patch('rowers.dataprep.create_engine') - @patch('rowers.dataprep.getsmallrowdata_db') - @patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multi) - def donot_test_workouts_boxplot_submit(self, mocked_sqlalchemy, - mocked_getsmallrowdata_db, - mocked_df): - - login = self.c.login(username=self.u.username,password=self.password) - self.assertTrue(login) - - form_data = { - 'workouts':['1','2','3'], - 'includereststrokes':False, - 'spmmax':55.0, - 'spmmin':15.0, - 'workmax':1500.0, - 'workmin':0.0, - 'yparam':'spm', - } - - form = WorkoutMultipleCompareForm(form_data) - chartform = BoxPlotChoiceForm(form_data) - - self.assertTrue(form.is_valid()) - self.assertTrue(chartform.is_valid()) - - response = self.c.get('/rowers/user-boxplot/',follow=True) - self.assertEqual(response.status_code,200) - self.assertRedirects(response, - expected_url='/rowers/user-boxplot-select/user/1/', - status_code=302,target_status_code=200) - - response = self.c.post('/rowers/user-boxplot/',form_data) - - self.assertEqual(response.status_code,200) - - options = {} - options['spmmin'] = 15 - options['spmmax'] = 55 - options['workmin'] = 0 - options['workmax'] = 5500 - options['ids'] = [1,2,3] - options['userid'] = 1 - options['plotfield'] = 'spm' - options['rankingonly'] = False - options['cpfit'] = 'data' - options['piece'] = 4 - - session = self.c.session - session['options'] = options - session.save() - response = self.c.get('/') - - sessionoptions = session['options'] - self.assertEqual(sessionoptions['ids'],[1,2,3]) - - response = self.c.get('/rowers/user-boxplot-data/') - - - self.assertEqual(response.status_code,200) class ListWorkoutTest(TestCase): @@ -316,382 +218,6 @@ class ForcecurveTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) -class CumStatsTest(TestCase): - def setUp(self): - self.u = UserFactory() - - self.r = Rower.objects.create(user=self.u, - birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=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.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats) - def test_cumstats(self, mocked_df): - 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() - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except (ValueError, AttributeError): - pass - try: - enddate = pytz.utc.localize(enddate) - except (ValueError, AttributeError): - pass - - url = '/rowers/cumstats/' - response = self.c.get(url) - - self.assertEqual(response.status_code,200) - -class CumFlexTest(TestCase): - def setUp(self): - self.u = UserFactory() - - self.r = Rower.objects.create(user=self.u, - birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=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.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multiflex) - def test_cumflex(self, mocked_df): - 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() - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except (ValueError, AttributeError): - pass - try: - enddate = pytz.utc.localize(enddate) - except (ValueError, AttributeError): - pass - - waterboattype = [u'1x', - u'2x', - u'2x+', - u'2-', - u'2+', - u'3x+', - u'3x-', - u'4x', - u'4x+', - u'4-', - u'4+', - u'8+', - u'8x+'] - - form_data = { - 'startdate':startdate, - 'enddate':enddate, - 'modality':u'all', - 'waterboattype': waterboattype, - 'xaxis':'spm', - 'yaxis1':'hr', - 'yaxis2':'power', - } - - form = TrendFlexModalForm(form_data) - self.assertTrue(form.is_valid()) - - self.factory.user = self.u - form = FlexAxesForm(self.factory,form_data) - - - url = '/rowers/flexall/' - - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - response = self.c.post(url, form_data) - self.assertEqual(response.status_code,200) - - - options = {'enddatestring': '2019-01-14', - 'includereststrokes': False, - 'modality': u'water', - 'rankingonly': False, - 'startdatestring': '2018-12-15', - 'theuser': 2, - 'waterboattype': [u'1x', - u'2x', - u'2x+', - u'2-', - u'2+', - u'3x+', - u'3x-', - u'4x', - u'4x+', - u'4-', - u'4+', - u'8+', - u'8x+'], - 'xparam': u'spm', - 'yparam1': u'hr', - 'yparam2': u'power'} - - session = self.c.session - session['options'] = options - session.save() - response = self.c.get('/') - - url = '/rowers/flexalldata/' - response = self.c.get(url) - self.assertEqual(response.status_code, 200) - - -class MultiFlexTest(TestCase): - def setUp(self): - self.u = UserFactory() - - self.r = Rower.objects.create(user=self.u, - birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=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.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multiflex) - def test_multiflex(self, mocked_df): - 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() - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except (ValueError, AttributeError): - pass - try: - enddate = pytz.utc.localize(enddate) - except (ValueError, AttributeError): - pass - - waterboattype = [u'1x', - u'2x', - u'2x+', - u'2-', - u'2+', - u'3x+', - u'3x-', - u'4x', - u'4x+', - u'4-', - u'4+', - u'8+', - u'8x+'] - - form_data = { - 'startdate':startdate, - 'enddate':enddate, - 'modality':u'all', - 'waterboattype': waterboattype, - 'binsize':u'1', - 'palette':u'monochrome_blue', - 'spmmax':55, - 'spmmin':15, - 'workmax':1500, - 'workmin':0, - 'workouts':[1,2,3,4,5], - 'workoutselectform':'Create Chart', - 'xparam':'spm', - 'yparam':'power', - 'groupby':'spm', - } - - form = MultiFlexChoiceForm(form_data) - self.assertTrue(form.is_valid()) - - url = '/rowers/user-multiflex-select/' - - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - url = '/rowers/user-multiflex/user/1/' - reponse = self.c.post(url, form_data,follow=True) - self.assertEqual(response.status_code, 200) - - options={ - 'includereststrokes':False, - 'ploterrorbars':True, - 'userid':0, - 'palette': 'monochrome_blue', - 'groupby': 'power', - 'binsize': 1, - 'xparam': 'spm', - 'yparam': 'power', - 'spmmin': 15, - 'spmmax': 55, - 'workmin': 400, - 'workmax': 1500, - 'ids': [1,2,3,4,5], - 'ploterrorbars':False, - } - - session = self.c.session - session['options'] = options - session.save() - response = self.c.get('/') - - url = '/rowers/user-multiflex-data/' - response = self.c.get(url) - self.assertEqual(response.status_code, 200) - -class HistoTest(TestCase): - def setUp(self): - self.u = UserFactory() - - self.r = Rower.objects.create(user=self.u, - birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=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', side_effect=mocked_getpowerdata_db) - def test_histo_workouts(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() - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except (ValueError, AttributeError): - pass - try: - enddate = pytz.utc.localize(enddate) - except (ValueError, AttributeError): - pass - - waterboattype = [u'1x', - u'2x', - u'2x+', - u'2-', - u'2+', - u'3x+', - u'3x-', - u'4x', - u'4x+', - u'4-', - u'4+', - u'8+', - u'8x+'] - - form_data = { - 'startdate':startdate, - 'enddate':enddate, - 'modality':u'all', - 'histoparam':'power', - 'rankingonly': False, - 'includereststrokes':False, - 'workouttypes': ['water'], - 'waterboattype': waterboattype - } - - url = '/rowers/histo/' - response = self.c.get(url) - self.assertEqual(response.status_code,200) - - response = self.c.post(url, form_data) - self.assertEqual(response.status_code,200) - - - options = { - 'includereststrokes':False, - 'rankingonly':False, - 'modality':'all', - 'waterboattype':waterboattype, - 'theuser':0, - 'enddatestring':enddate.strftime("%Y-%m-%d"), - 'startdatestring':startdate.strftime("%Y-%m-%d"), - } - - session = self.c.session - session['options'] = options - session.save() - response = self.c.get('/') - - sessionoptions = session['options'] - - response = self.c.get('/rowers/histodata/') - self.assertEqual(response.status_code,200) - - - #-------------------------------------------------- - - class WorkoutCompareTestNew(TestCase): def setUp(self): @@ -1642,3 +1168,126 @@ class MarkerPerformanceTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) + +class AlertTest(TestCase): + def setUp(self): + self.u = UserFactory() + + self.r = Rower.objects.create(user=self.u, + birthdate=faker.profile()['birthdate'], + gdproptin=True,surveydone=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() + + # need a 2k, 5k, 1h row + self.werg2k = WorkoutFactory( + user=self.r, + duration=datetime.time(hour=0,minute=7,second=0), + distance=2000, + workouttype='rower', + rankingpiece=True, + ) + + # need a 2k, 5k, 1h row + self.werg5k = WorkoutFactory( + user=self.r, + duration=datetime.time(hour=0,minute=18,second=0), + distance=5000, + workouttype='rower', + rankingpiece=True, + ) + + # need a 2k, 5k, 1h row + self.werg1h = WorkoutFactory( + user=self.r, + duration=datetime.time(hour=1,minute=0,second=0), + distance=15000, + workouttype='rower', + rankingpiece=True, + ) + + 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.alerts.getsmallrowdata_db') + def test_alerts(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() + + url = reverse('alerts_view') + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + # create alert + url = reverse('alert_create_view') + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + data = { + 'name': 'Ss', + 'period':7, + 'emailalert': True, + 'boattype':'1x', + 'workouttype':'water', + 'reststrokes':False, + 'metric':'spm', + 'condition':'<', + 'value1':20, + 'value2':22, + # management_form data + 'form-INITIAL_FORMS': '0', + 'form-TOTAL_FORMS': '1', + 'form-MAX_NUM_FORMS': '', + + # First condition data + 'form-0-metric': 'hr', + 'form-0-condition': '>', + 'form-0-value1': 120, + 'form-0-value2': 130 + } + + + form = AlertEditForm(data) + self.assertTrue(form.is_valid()) + + response = self.c.post(url,data,follow=True) + expected_url = reverse('alert_edit_view',kwargs={'id':1}) + self.assertRedirects(response,expected_url=expected_url,status_code=302,target_status_code=200) + + url = expected_url + response = self.c.post(url,data) + self.assertEqual(response.status_code,200) + + data = {} + + url = reverse('alert_report_view',kwargs={'id':1,'userid':self.u.id}) + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + # delete + url = '/rowers/alerts/1/delete/' + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + + response = self.c.post(url,data,follow=True) + expected_url = reverse('alerts_view') + self.assertRedirects(response,expected_url=expected_url,status_code=302,target_status_code=200) + + # diff --git a/rowers/tests/test_permissions.py b/rowers/tests/test_permissions.py index e2a093db..5f4bcdd2 100644 --- a/rowers/tests/test_permissions.py +++ b/rowers/tests/test_permissions.py @@ -857,7 +857,7 @@ class PermissionsViewTests(TestCase): self.assertTrue(login) - url = reverse('cumstats', + url = reverse('analysis_new', kwargs={ 'userid':self.ubasic.id, } @@ -877,7 +877,7 @@ class PermissionsViewTests(TestCase): self.assertTrue(login) - url = reverse('cumstats', + url = reverse('analysis_new', kwargs={ 'userid':self.ubasic.id, } @@ -1153,7 +1153,7 @@ class PermissionsViewTests(TestCase): self.assertTrue(login) - url = reverse('cumstats', + url = reverse('analysis_new', kwargs={ 'userid':self.ubasic.id, } @@ -1276,7 +1276,7 @@ class PermissionsViewTests(TestCase): self.assertTrue(login) - url = reverse('cumstats', + url = reverse('analysis_new', kwargs={ 'userid':self.ubasic.id, } diff --git a/rowers/tests/test_urls.py b/rowers/tests/test_urls.py index 6a75c617..c34057d8 100644 --- a/rowers/tests/test_urls.py +++ b/rowers/tests/test_urls.py @@ -68,10 +68,6 @@ class URLTests(TestCase): '/rowers/404/', '/rowers/500/', '/rowers/502/', -# '/rowers/1/list-workouts/', -# '/rowers/1/list-workouts/2016-01-01/2016-12-31/', -# '/rowers/1/ote-bests/', -# '/rowers/1/ote-bests2/2016-01-01/2016-12-31/', '/rowers/about/', '/rowers/workout/addmanual/', '/rowers/agegroupcp/30/', @@ -86,29 +82,10 @@ class URLTests(TestCase): '/rowers/courses/upload/', '/rowers/createplan/', '/rowers/createplan/user/1/', - '/rowers/cumstats/', -# '/rowers/cumstats/2016-01-01/2016-12-31/', - '/rowers/cumstats/user/1/', -# '/rowers/cumstats/user/1/2016-01-01/2016-12-31/', '/rowers/developers/', '/rowers/email/', '/rowers/email/thankyou/', -# '/rowers/fitness-progress/', -# '/rowers/fitness-progress/user/1/', -# '/rowers/fitness-progress/user/1/rower/', - '/rowers/flexall/', - '/rowers/flexall/spm/hr/None/', -# '/rowers/flexall/spm/hr/None/2016-01-01/2016-12-31/', -# '/rowers/flexall/spm/hr/None/2016-01-01/2016-12-31/user/1/', - '/rowers/flexall/user/1/', - '/rowers/flexalldata/', '/rowers/help/', - '/rowers/histo/', - '/rowers/histo/user/1/', -# '/rowers/histo/user/1/2016-01-01/2016-12-31/', - '/rowers/histodata/', -# '/rowers/job-kill/1/', -# '/rowers/jobs-status/', '/rowers/laboratory/', '/rowers/laboratory/user/1/', '/rowers/legal/', @@ -116,8 +93,6 @@ class URLTests(TestCase): '/rowers/list-graphs/', '/rowers/list-jobs/', '/rowers/list-workouts/', -# '/rowers/list-workouts/2016-01-01/2016-12-31/', -# '/rowers/list-workouts/2016-01-01/2016-12-31/user/1/', '/rowers/list-workouts/ranking/', '/rowers/list-workouts/user/1/', '/rowers/me/calcdps/', @@ -135,65 +110,23 @@ class URLTests(TestCase): '/rowers/me/workflowconfig2/', '/rowers/me/workflowconfig2/user/1/', '/rowers/me/workflowdefault/', -# '/rowers/multi-compare/', -# '/rowers/ote-bests/', -# '/rowers/ote-bests/2016-01-01/2016-12-31/', -# '/rowers/ote-bests/user/1/', -# '/rowers/ote-bests/user/1/2016-01-01/2016-12-31/', '/rowers/ote-bests2/', -# '/rowers/ote-bests2/2016-01-01/2016-12-31/', '/rowers/ote-bests2/user/1/', -# '/rowers/ote-ranking/', -# '/rowers/ote-ranking/2016-01-01/2016-12-31/', -# '/rowers/ote-ranking/user/1/', -# '/rowers/ote-ranking/user/1/2016-01-01/2016-12-31/', -# '/rowers/otw-bests/', -# '/rowers/otw-bests/2016-01-01/2016-12-31/', -# '/rowers/otw-bests/user/1/2016-01-01/2016-12-31/', '/rowers/partners/', '/rowers/physics/', '/rowers/planrequired/', -# '/rowers/promembership/', '/rowers/register/', '/rowers/register/thankyou/', '/rowers/sessions/', -# '/rowers/sessions/2016-01-01/2016-12-31/', -# '/rowers/sessions/2016-01-01/2016-12-31/user/1/', '/rowers/sessions/coach/', -# '/rowers/sessions/coach/user/1/', '/rowers/sessions/create/', -# '/rowers/sessions/create/user/1/', '/rowers/sessions/manage/', -# '/rowers/sessions/manage/user/1/', '/rowers/sessions/multiclone/', -# '/rowers/sessions/multiclone/user/1/', '/rowers/sessions/multicreate/', -# '/rowers/sessions/multicreate/user/1/', '/rowers/sessions/print/', -# '/rowers/sessions/print/user/1/', '/rowers/sessions/teamcreate/', -# '/rowers/sessions/user/1/', '/rowers/team-compare-select/', '/rowers/team-compare-select/workout/'+encoded1+'/', -# '/rowers/team-compare-select/2016-01-01/2016-12-31/', -# '/rowers/test-job/2/', -# '/rowers/test-job2/2/', -# '/rowers/test_callback/', -# '/rowers/updatefitness/', -# '/rowers/updatefitness/rower/', -# '/rowers/updatefitness/rower/50/', -# '/rowers/user-boxplot/', -# '/rowers/user-boxplot-data/', -# '/rowers/user-boxplot-select/', -# '/rowers/user-boxplot-select/user/1/', -# '/rowers/user-boxplot/user/1/', -# '/rowers/user-multiflex-data/', -# '/rowers/user-multiflex-select/', -# '/rowers/user-multiflex-select/2016-01-01/2016-12-31/', -# '/rowers/user-multiflex-select/user/1/', -# '/rowers/user-multiflex-select/user/1/2016-01-01/2016-12-31/', -# '/rowers/user-multiflex/', -# '/rowers/user-multiflex/user/1/', '/rowers/workout/'+encoded1+'/', '/rowers/workout/'+encoded1+'/adddistanceplot/', '/rowers/workout/'+encoded1+'/adddistanceplot2/', @@ -224,27 +157,21 @@ class URLTests(TestCase): '/rowers/workout/'+encoded1+'/split/', '/rowers/workout/'+encoded1+'/stats/', '/rowers/workout/'+encoded1+'/stream/', -# '/rowers/workout/'+encoded1+'/task/', -# '/rowers/workout/'+encoded1+'/teststrokedata/', '/rowers/workout/'+encoded1+'/toggle-ranking/', '/rowers/workout/'+encoded1+'/undosmoothenpace/', '/rowers/workout/'+encoded1+'/unsubscribe/', -# '/rowers/workout/'+encoded1+'/updatecp/', '/rowers/workout/'+encoded1+'/view/', '/rowers/workout/'+encoded1+'/wind/', '/rowers/workout/'+encoded1+'/workflow/', '/rowers/workout/fusion/'+encoded1+'/', -# '/rowers/workout/fusion/'+encoded1+'/2016-01-01/2016-12-31/', '/rowers/workout/upload/', '/rowers/workout/upload/team/', '/rowers/workouts-join/', '/rowers/workouts-join-select/', -# '/rowers/workouts-join-select/2016-01-01/2016-12-31/', ] - # urlstotest = ['/rowers/createplan/user/1/'] lijst = [] for url in urlstotest: diff --git a/rowers/tests/viewnames.csv b/rowers/tests/viewnames.csv index a8f12ac7..8d399ca0 100644 --- a/rowers/tests/viewnames.csv +++ b/rowers/tests/viewnames.csv @@ -26,9 +26,7 @@ 25,27,team_comparison_select,compare with a team member workout,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,TRUE,TRUE,TRUE,TRUE, 26,28,workouts_join_view,join workouts,TRUE,302,pro,302,302,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE, 27,29,workouts_join_select,select workouts to join,TRUE,404,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE, -28,30,user_boxplot_select,select boxplots,TRUE,302,pro,200,302,pro,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, 29,31,analysis_new,analysis front page,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, -30,32,user_multiflex_select,select multiflex data,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, 31,33,session_jobs_view,view jobs,TRUE,302,basic,200,302,FALSE,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, 32,34,session_jobs_status,view jobs,TRUE,302,basic,200,302,FALSE,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, 33,35,kill_async_job,kill job,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, @@ -38,9 +36,6 @@ 41,43,cum_flex,flex all chart,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, 42,44,analysis_view_data,redirects to analysis direct,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, 43,47,cum_flex_data,flex all chart data (json),TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, -44,48,histo,histogram view,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, -45,49,histo_data,histogram data,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE,TRUE, -46,51,cumstats,cumulative statistics,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,TRUE,TRUE, 47,53,graph_show_view,show a chart,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, 48,54,GraphDelete,delete a chart,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, 49,55,get_thumbnails,get thumbnails,TRUE,403,basic,200,302,basic,403,403,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE, @@ -114,10 +109,6 @@ 119,148,alert_edit_view,edit alert,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE, 120,150,alert_create_view,create alert,TRUE,302,pro,200,403,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE, 121,152,alert_report_view,view alerts report,TRUE,302,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,FALSE,FALSE,FALSE, -122,155,boxplot_view,View boxplot,TRUE,302,pro,302,403,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE, -123,157,boxplot_view_data,data for boxplot,TRUE,302,pro,200,403,pro,200,403,coach,200,403,FALSE,FALSE,FALSE,FALSE,FALSE, -124,158,multiflex_view,view multiflex,TRUE,302,pro,302,403,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,TRUE,TRUE, -125,160,multiflex_data,data for multiflex,TRUE,302,pro,200,403,pro,200,403,coach,200,403,FALSE,FALSE,FALSE,FALSE,FALSE, 126,161,deactivate_user,deactivate a user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE, 127,162,remove_user,remove a user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE, 128,163,user_gdpr_confirm,GDPR confirmation,TRUE,302,basic,302,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE,TRUE, diff --git a/rowers/urls.py b/rowers/urls.py index eb62075a..3df7665a 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -325,8 +325,6 @@ urlpatterns = [ re_path(r'^workouts-join/user/(?P\d+)$',views.workouts_join_view,name='workouts_join_view'), re_path(r'^workouts-join-select/$',views.workouts_join_select,name='workouts_join_select'), re_path(r'^workouts-join-select/user/(?P\d+)/$',views.workouts_join_select,name='workouts_join_select'), - re_path(r'^user-boxplot-select/user/(?P\d+)/$',views.user_boxplot_select,name='user_boxplot_select'), - re_path(r'^user-boxplot-select/$',views.user_boxplot_select,name='user_boxplot_select'), re_path(r'^user-analysis-select/(?P\w.*)/workout/(?P\b[0-9A-Fa-f]+\b)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/user/(?P\d+)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/team/(?P\d+)/$',views.analysis_new,name='analysis_new'), @@ -334,8 +332,6 @@ urlpatterns = [ re_path(r'^user-analysis-select/team/(?P\d+)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/(?P\w.*)/$',views.analysis_new,name='analysis_new'), re_path(r'^user-analysis-select/$',views.analysis_new,name='analysis_new'), - re_path(r'^user-multiflex-select/user/(?P\d+)/$',views.user_multiflex_select,name='user_multiflex_select'), - re_path(r'^user-multiflex-select/$',views.user_multiflex_select,name='user_multiflex_select'), 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'^job-kill/(?P.*)/$',views.kill_async_job), @@ -356,16 +352,7 @@ urlpatterns = [ re_path(r'^performancemanager/user/(?P\d+)/(?P\w+.*)/$',views.performancemanager_view,name='performancemanager_view'), re_path(r'^ote-bests2/user/(?P\d+)/$',views.rankings_view2,name='rankings_view2'), re_path(r'^ote-bests2/$',views.rankings_view2,name='rankings_view2'), - re_path(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/$',views.cum_flex,name='cum_flex'), re_path(r'^analysisdata/$',views.analysis_view_data,name='analysis_view_data'), - re_path(r'^flexall/user/(?P\d+)/$',views.cum_flex,name='cum_flex'), - re_path(r'^flexall/$',views.cum_flex,name='cum_flex'), - re_path(r'^flexalldata/$',views.cum_flex_data,name='cum_flex_data'), - re_path(r'^histo/user/(?P\d+)/$',views.histo,name='histo'), - re_path(r'^histodata/$',views.histo_data,name='histo_data'), - re_path(r'^histo/$',views.histo,name='histo'), - re_path(r'^cumstats/user/(?P\d+)/$',views.cumstats,name='cumstats'), - re_path(r'^cumstats/$',views.cumstats,name='cumstats'), re_path(r'^graph/(?P\d+)/$',views.graph_show_view,name='graph_show_view'), re_path(r'^graph/(?P\d+)/delete/$',views.GraphDelete.as_view(),name='graph_delete'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/get-thumbnails/$',views.get_thumbnails, @@ -541,12 +528,6 @@ urlpatterns = [ re_path(r'^alerts/(?P\d+)/report/user/(?P\d+)/$',views.alert_report_view,name='alert_report_view'), re_path(r'^alerts/(?P\d+)/report/(?P\d+)/user/(?P\d+)/$',views.alert_report_view,name='alert_report_view'), re_path(r'^alerts/(?P\d+)/report/$',views.alert_report_view,name='alert_report_view'), - re_path(r'^user-boxplot/user/(?P\d+)/$',views.boxplot_view,name='boxplot_view'), - re_path(r'^user-boxplot/$',views.boxplot_view,name='boxplot_view'), - re_path(r'^user-boxplot-data/$',views.boxplot_view_data,name='boxplot_view_data'), - re_path(r'^user-multiflex/user/(?P\d+)/$',views.multiflex_view,name='multiflex_view'), - re_path(r'^user-multiflex/$',views.multiflex_view,name='multiflex_view'), - re_path(r'^user-multiflex-data/$',views.multiflex_data,name='multiflex_data'), re_path(r'^me/deactivate/$',views.deactivate_user,name='deactivate_user'), re_path(r'^me/delete/$',views.remove_user,name='remove_user'), re_path(r'^survey/$',views.survey,name='survey'), diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index 848b1820..b945f96f 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -954,606 +954,6 @@ def analysis_view_data(request,userid=0): }) -# Histogram for a date/time range -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def histo(request,userid=0, - startdate=timezone.now()-datetime.timedelta(days=365), - enddate=timezone.now(), - deltadays=-1, - enddatestring=timezone.now().strftime("%Y-%m-%d"), - startdatestring=(timezone.now()-datetime.timedelta(days=30)).strftime("%Y-%m-%d"), - options={ - 'includereststrokes':False, - 'workouttypes':[i[0] for i in mytypes.workouttypes], - 'waterboattype':mytypes.waterboattype, - 'rankingonly': False, - 'histoparam':'power' - }): - - r = getrequestrower(request,userid=userid) - theuser = r.user - - if 'histoparam' in request.session: # pragma: no cover - histoparam = request.session['histoparam'] - else: - histoparam = 'power' - - if 'waterboattype' in request.session: # pragma: no cover - waterboattype = request.session['waterboattype'] - else: - waterboattype = mytypes.waterboattype - - - if 'rankingonly' in request.session: # pragma: no cover - rankingonly = request.session['rankingonly'] - else: - rankingonly = False - - if 'modalities' in request.session: # pragma: no cover - modalities = request.session['modalities'] - if len(modalities) > 1: - modality = 'all' - else: # pragma: no cover - modality = modalities[0] - else: - modalities = [m[0] for m in mytypes.workouttypes] - modality = 'all' - - - try: - rankingonly = options['rankingonly'] - except KeyError: # pragma: no cover - rankingonly = False - - try: - includereststrokes = options['includereststrokes'] - except KeyError: # pragma: no cover - includereststrokes = False - - - workstrokesonly = not includereststrokes - - waterboattype = mytypes.waterboattype - - - if startdatestring != "": - startdate = iso8601.parse_date(startdatestring) - - if enddatestring != "": - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - - - # get all indoor rows of in date range - - # process form - if request.method == 'POST': - form = DateRangeForm(request.POST) - modalityform = TrendFlexModalForm(request.POST) - histoform = HistoForm(request.POST) - if form.is_valid(): - startdate = form.cleaned_data['startdate'] - enddate = form.cleaned_data['enddate'] - if startdate > enddate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - if modalityform.is_valid(): - modality = modalityform.cleaned_data['modality'] - waterboattype = modalityform.cleaned_data['waterboattype'] - rankingonly = modalityform.cleaned_data['rankingonly'] - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: # pragma: no cover - modalities = [modality] - - if modality != 'water': - waterboattype = [b[0] for b in mytypes.boattypes] - - - request.session['modalities'] = modalities - request.session['waterboattype'] = waterboattype - request.session['rankingonly'] = rankingonly - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - if histoform.is_valid(): - includereststrokes = histoform.cleaned_data['includereststrokes'] - histoparam = histoform.cleaned_data['histoparam'] - request.session['histoparam'] = histoparam - request.session['includereststrokes'] = includereststrokes - else: - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - includereststrokes = False - - workstrokesonly = not includereststrokes - modalityform = TrendFlexModalForm( - initial={ - 'modality':modality, - 'waterboattype':waterboattype, - 'rankingonly':rankingonly, - } - ) - histoform = HistoForm(initial={ - 'includereststrokes':False, - 'histoparam':histoparam - }) - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: # pragma: no cover - negtypes.append(b[0]) - - - - script = '' - div = get_call() - js_resources = '' - css_resources = '' - - - - - options = { - 'modality': modality, - 'theuser': theuser.id, - 'waterboattype':waterboattype, - 'startdatestring':startdatestring, - 'enddatestring':enddatestring, - 'rankingonly':rankingonly, - 'includereststrokes':includereststrokes, - 'histoparam':histoparam, - } - - request.session['options'] = options - - promember=0 - mayedit=0 - if not request.user.is_anonymous: - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember = 1 - - - request.session['options'] = options - - breadcrumbs = [ - { - 'url':'/rowers/analysis', - 'name':'Analysis' - }, - { - 'url':reverse('histo'), - 'name': 'Histogram' - } - ] - - return render(request, 'histo.html', - {'interactiveplot':script, - 'the_div':div, - 'breadcrumbs':breadcrumbs, - 'id':theuser, - 'active':'nav-analysis', - 'theuser':theuser, - 'rower':r, - 'startdate':startdate, - 'enddate':enddate, - 'form':form, - 'optionsform':modalityform, - 'histoform':histoform, - 'teams':get_my_teams(request.user), - }) - -# The Flex plot for a large selection of workouts -@login_required() -def cum_flex_data( - request, - options={ - 'includereststrokes':False, - 'rankingonly':False, - 'modality':'all', - 'waterboattype':mytypes.waterboattype, - 'theuser':0, - 'xparam':'spm', - 'yparam1':'power', - 'yparam2':'None', - 'enddatestring':timezone.now().strftime("%Y-%m-%d"), - 'startdatestring':(timezone.now()-datetime.timedelta(days=30)).strftime("%Y-%m-%d"), - 'deltadays':-1, - }): - - def_options = options - - if 'options' in request.session: - options = request.session['options'] - - - modality = keyvalue_get_default('modality',options,def_options) - rankingonly = keyvalue_get_default('rankingonly',options,def_options) - includereststrokes = keyvalue_get_default('includereststrokes',options,def_options) - waterboattype = keyvalue_get_default('waterboattype',options,def_options) - workstrokesonly = not includereststrokes - theuser = keyvalue_get_default('theuser',options,def_options) - xparam = keyvalue_get_default('xparam',options,def_options) - yparam1 = keyvalue_get_default('yparam1',options,def_options) - yparam2 = keyvalue_get_default('yparam2',options,def_options) - startdatestring = keyvalue_get_default('startdatestring',options,def_options) - enddatestring = keyvalue_get_default('enddatestring',options,def_options) - - - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: # pragma: no cover - modalities = [modality] - - try: - startdate = iso8601.parse_date(startdatestring) - except ParseError: # pragma: no cover - startdate = timezone.now()-datetime.timedelta(days=7) - - try: - enddate = iso8601.parse_date(enddatestring) - except ParseError: # pragma: no cover - enddate = timezone.now() - - - if enddate < startdate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - - promember=0 - if theuser == 0: - theuser = request.user.id - - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - - r2 = getrower(theuser) - - if rankingonly: # pragma: no cover - rankingpiece = [True,] - else: - rankingpiece = [True,False] - - allworkouts = Workout.objects.filter(user=r2, - workouttype__in=modalities, - boattype__in=waterboattype, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - rankingpiece__in=rankingpiece) - - if allworkouts: - res = interactive_cum_flex_chart2(allworkouts,xparam=xparam, - yparam1=yparam1, - yparam2=yparam2, - promember=promember, - workstrokesonly=workstrokesonly, - ) - script = res[0] - div = res[1] - else: - script = '' - div = '

No pieces uploaded for this date range.

' - - scripta = script.split('\n')[2:-1] - script = ''.join(scripta) - - data = { - "script":script, - "div":div, - } - - return JSONResponse(data) - -# The Flex plot for a large selection of workouts -@login_required() -def histo_data( - request, - options={ - 'includereststrokes':False, - 'rankingonly':False, - 'modality':'all', - 'waterboattype':mytypes.waterboattype, - 'theuser':0, - 'enddatestring':timezone.now().strftime("%Y-%m-%d"), - 'startdatestring':(timezone.now()-datetime.timedelta(days=30)).strftime("%Y-%m-%d"), - 'deltadays':-1, - 'histoparam':'power', - }): - - def_options = options - - - if 'options' in request.session: - options = request.session['options'] - - modality = keyvalue_get_default('modality',options,def_options) - rankingonly = keyvalue_get_default('rankingonly',options,def_options) - includereststrokes = keyvalue_get_default('includereststrokes',options,def_options) - waterboattype = keyvalue_get_default('waterboattype',options,def_options) - workstrokesonly = not includereststrokes - theuser = keyvalue_get_default('theuser',options,def_options) - startdatestring = keyvalue_get_default('startdatestring',options,def_options) - enddatestring = keyvalue_get_default('enddatestring',options,def_options) - histoparam = keyvalue_get_default('histoparam',options,def_options) - - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: # pragma: no cover - modalities = [modality] - - try: - startdate = iso8601.parse_date(startdatestring) - except ParseError: # pragma: no cover - startdate = timezone.now()-datetime.timedelta(days=7) - - try: - enddate = iso8601.parse_date(enddatestring) - except ParseError: # pragma: no cover - enddate = timezone.now() - - - if enddate < startdate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - - promember=0 - if theuser == 0: - theuser = request.user.id - - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - - r2 = getrower(theuser) - - if rankingonly: # pragma: no cover - rankingpiece = [True,] - else: - rankingpiece = [True,False] - - allworkouts = Workout.objects.filter(user=r2, - workouttype__in=modalities, - boattype__in=waterboattype, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - rankingpiece__in=rankingpiece) - - if allworkouts: - res = interactive_histoall(allworkouts,histoparam,includereststrokes) - script = res[0] - div = res[1] - else: - script = '' - div = '

No pieces uploaded for this date range.

' - - scripta = script.split('\n')[2:-1] - script = ''.join(scripta) - - data = { - "script":script, - "div":div, - } - - return JSONResponse(data) - - - - -@login_required() -def cum_flex(request,theuser=0, - xparam='spm', - yparam1='power', - yparam2='None', - startdate=timezone.now()-datetime.timedelta(days=10), - enddate=timezone.now(), - deltadays=-1, - enddatestring=timezone.now().strftime("%Y-%m-%d"), - startdatestring=(timezone.now()-datetime.timedelta(days=30)).strftime("%Y-%m-%d"), - options={ - 'includereststrokes':False, - 'workouttypes':[i[0] for i in mytypes.workouttypes], - 'waterboattype':mytypes.waterboattype, - 'rankingonly':False, - }): - - - r = getrequestrower(request,userid=theuser) - theuser = r.user - - if 'waterboattype' in request.session: # pragma: no cover - waterboattype = request.session['waterboattype'] - else: - waterboattype = mytypes.waterboattype - - - if 'rankingonly' in request.session: # pragma: no cover - rankingonly = request.session['rankingonly'] - else: - rankingonly = False - - if 'modalities' in request.session: # pragma: no cover - modalities = request.session['modalities'] - if len(modalities) > 1: - modality = 'all' - else: - modality = modalities[0] - else: - modalities = [m[0] for m in mytypes.workouttypes] - modality = 'all' - - - try: - rankingonly = options['rankingonly'] - except KeyError: # pragma: no cover - rankingonly = False - - try: - includereststrokes = options['includereststrokes'] - except KeyError: # pragma: no cover - includereststrokes = False - - - workstrokesonly = not includereststrokes - - waterboattype = mytypes.waterboattype - - - if startdatestring != "": - startdate = iso8601.parse_date(startdatestring) - - if enddatestring != "": - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - - - # get all indoor rows of in date range - - # process form - if request.method == 'POST': - form = DateRangeForm(request.POST) - modalityform = TrendFlexModalForm(request.POST) - flexaxesform = FlexAxesForm(request,request.POST) - if form.is_valid(): - startdate = form.cleaned_data['startdate'] - enddate = form.cleaned_data['enddate'] - if startdate > enddate: # pragma: no cover - s = enddate - enddate = startdate - startdate = s - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - if modalityform.is_valid(): - modality = modalityform.cleaned_data['modality'] - waterboattype = modalityform.cleaned_data['waterboattype'] - rankingonly = modalityform.cleaned_data['rankingonly'] - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: # pragma: no cover - modalities = [modality] - - if modality != 'water': - waterboattype = [b[0] for b in mytypes.boattypes] - - - request.session['modalities'] = modalities - request.session['waterboattype'] = waterboattype - request.session['rankingonly'] = rankingonly - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - if flexaxesform.is_valid(): - xparam = flexaxesform.cleaned_data['xaxis'] - yparam1 = flexaxesform.cleaned_data['yaxis1'] - yparam2 = flexaxesform.cleaned_data['yaxis2'] - else: - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - includereststrokes = False - - workstrokesonly = not includereststrokes - modalityform = TrendFlexModalForm( - initial={ - 'modality':modality, - 'waterboattype':waterboattype, - 'rankingonly':rankingonly, - } - ) - initial = { - 'xaxis':xparam, - 'yaxis1':yparam1, - 'yaxis2':yparam2 - } - flexaxesform = FlexAxesForm(request,initial=initial) - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: # pragma: no cover - negtypes.append(b[0]) - - - - script = '' - div = get_call() - js_resources = '' - css_resources = '' - - - - - options = { - 'xparam': xparam, - 'yparam1': yparam1, - 'yparam2': yparam2, - 'modality': modality, - 'theuser': theuser.id, - 'waterboattype':waterboattype, - 'startdatestring':startdatestring, - 'enddatestring':enddatestring, - 'rankingonly':rankingonly, - 'includereststrokes':includereststrokes, - } - - request.session['options'] = options - - promember=0 - mayedit=0 - if not request.user.is_anonymous: - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember = 1 - - - request.session['options'] = options - - - return render(request, 'cum_flex.html', - {'interactiveplot':script, - 'the_div':div, - 'js_res': js_resources, - 'css_res':css_resources, - 'id':theuser, - 'rower':r, - 'active':'nav-analysis', - 'theuser':theuser, - 'startdate':startdate, - 'enddate':enddate, - 'form':form, - 'optionsform':modalityform, - 'xparam':xparam, - 'yparam1':yparam1, - 'yparam2':yparam2, - 'promember':promember, - 'teams':get_my_teams(request.user), - 'flexaxesform':flexaxesform, - }) def planrequired_view(request): @@ -1895,7 +1295,7 @@ def rankings_view2(request,userid=0, if dateform.is_valid(): startdate = dateform.cleaned_data['startdate'] enddate = dateform.cleaned_data['enddate'] - if startdate > enddate: + if startdate > enddate: # pragma: no cover s = enddate enddate = startdate startdate = s @@ -1928,7 +1328,7 @@ def rankings_view2(request,userid=0, # get all 2k (if any) - this rower, in date range try: r = getrower(theuser) - except Rower.DoesNotExist: + except Rower.DoesNotExist: # pragma: no cover allergworkouts = [] r=0 @@ -2012,7 +1412,7 @@ def rankings_view2(request,userid=0, message = res[5] try: testcalc = pd.Series(res[6])*3 - except TypeError: + except TypeError: # pragma: no cover age = 0 else: @@ -2085,7 +1485,7 @@ def rankings_view2(request,userid=0, pwr3 = 50. velo3 = (pwr3/2.8)**(1./3.) - if np.isnan(velo3) or velo3 <= 0: + if np.isnan(velo3) or velo3 <= 0: # pragma: no cover velo3 = 1.0 t3 = rankingdistance/velo3 @@ -2206,21 +1606,21 @@ def otecp_toadmin_view(request,theuser=0, enddate=timezone.now(), startdatestring="", enddatestring="", - ): + ): # pragma: no cover - if startdatestring != "": + if startdatestring != "": # pragma: no cover try: startdate = iso8601.parse_date(startdatestring) except ParseError: pass - if enddatestring != "": + if enddatestring != "": # pragma: no cover try: enddate = iso8601.parse_date(enddatestring) except ParseError: pass - if theuser == 0: + if theuser == 0: # pragma: no cover theuser = request.user.id u = User.objects.get(id=theuser) @@ -2280,7 +1680,7 @@ def otwcp_toadmin_view(request,theuser=0, enddate=timezone.now(), startdatestring="", enddatestring="", - ): + ): # pragma: no cover if startdatestring != "": try: @@ -2345,1407 +1745,6 @@ def otwcp_toadmin_view(request,theuser=0, return response - -# Multi Flex Chart with Grouping -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def user_multiflex_select(request, - startdatestring="", - enddatestring="", - message='', - successmessage='', - startdate=timezone.now()-datetime.timedelta(days=30), - enddate=timezone.now(), - userid=0): - - r = getrequestrower(request,userid=userid) - user = r.user - - if 'options' in request.session: - options = request.session['options'] - else: - options = {} - - try: - palette = request.session['palette'] - except KeyError: - palette = 'monochrome_blue' - - try: - includereststrokes = request.session['includereststrokes'] - except KeyError: - includereststrokes = False - - try: - ploterrorbars = request.session['ploterrorbars'] - except: - ploterrorbars = False - - if 'startdate' in request.session: - startdate = iso8601.parse_date(request.session['startdate']) - - - if 'enddate' in request.session: - enddate = iso8601.parse_date(request.session['enddate']) - - try: - waterboattype = request.session['waterboattype'] - except KeyError: - waterboattype = mytypes.waterboattype - else: - waterboattype = mytypes.waterboattype - - if 'rankingonly' in request.session: - rankingonly = request.session['rankingonly'] - else: - rankingonly = False - - - if 'modalities' in request.session: - modalities = request.session['modalities'] - if len(modalities) > 1: - modality = 'all' - else: - modality = modalities[0] - else: - modalities = [m[0] for m in mytypes.workouttypes] - modality = 'all' - - if request.method == 'POST': - dateform = DateRangeForm(request.POST) - if dateform.is_valid(): - startdate = dateform.cleaned_data['startdate'] - enddate = dateform.cleaned_data['enddate'] - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - request.session['startdate'] = startdatestring - request.session['enddate'] = enddatestring - modalityform = TrendFlexModalForm(request.POST) - if modalityform.is_valid(): - modality = modalityform.cleaned_data['modality'] - waterboattype = modalityform.cleaned_data['waterboattype'] - rankingonly = modalityform.cleaned_data['rankingonly'] - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: - modalities = [modality] - - if modality != 'water': - waterboattype = [b[0] for b in mytypes.boattypes] - - - request.session['modalities'] = modalities - request.session['waterboattype'] = waterboattype - request.session['rankingonly'] = rankingonly - else: - dateform = DateRangeForm(initial={ - 'startdate':startdate, - 'enddate':enddate, - }) - - - startdate = datetime.datetime.combine(startdate,datetime.time()) - enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59)) - #enddate = enddate+datetime.timedelta(days=1) - - if startdatestring: - startdate = iso8601.parse_date(startdatestring) - if enddatestring: - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: - s = enddate - enddate = startdate - startdate = s - - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: - negtypes.append(b[0]) - - if rankingonly: - rankingpiece = [True] - else: - rankingpiece = [True,False] - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except (ValueError, AttributeError): - pass - try: - enddate = pytz.utc.localize(enddate) - except (ValueError, AttributeError): - pass - - workouts = Workout.objects.filter( - user=r, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - workouttype__in=modalities, - rankingpiece__in=rankingpiece - ).order_by( - "-date", "-starttime" - ).exclude( - boattype__in=negtypes - ) - - query = request.GET.get('q') - if query: - query_list = query.split() - workouts = workouts.filter( - reduce(operator.and_, - (Q(name__icontains=q) for q in query_list)) | - reduce(operator.and_, - (Q(notes__icontains=q) for q in query_list)) - ) - searchform = SearchForm(initial={'q':query}) - else: - searchform = SearchForm() - - form = WorkoutMultipleCompareForm() - form.fields["workouts"].queryset = workouts - - chartform = MultiFlexChoiceForm(initial={ - 'palette':palette, - 'ploterrorbars':ploterrorbars, - 'includereststrokes':includereststrokes, - }) - - modalityform = TrendFlexModalForm(initial={ - 'modality':modality, - 'waterboattype':waterboattype, - 'rankingonly':rankingonly, - }) - - messages.info(request,successmessage) - messages.error(request,message) - - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - request.session['startdate'] = startdatestring - request.session['enddate'] = enddatestring - - request.session['waterboattype'] = waterboattype - request.session['rankingonly'] = rankingonly - request.session['modalities'] = modalities - - - breadcrumbs = [ - { - 'url':'/rowers/analysis', - 'name':'Analysis' - }, - { - 'url':reverse(user_multiflex_select,kwargs={'userid':userid}), - 'name': 'Compare Select' - }, - { - 'url':reverse('multi_compare_view'), - 'name': 'Comparison Chart' - } - ] - - return render(request, 'user_multiflex_select.html', - {'workouts': workouts, - 'dateform':dateform, - 'breadcrumbs':breadcrumbs, - 'startdate':startdate, - 'enddate':enddate, - 'theuser':user, - 'rower':r, - 'form':form, - 'chartform':chartform, - 'searchform':searchform, - 'modalityform':modalityform, - 'teams':get_my_teams(request.user), - }) - -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def multiflex_data(request,userid=0, - options={ - 'includereststrokes':False, - 'ploterrorbars':False, - 'userid':0, - 'palette': 'monochrome_blue', - 'groupby': 'spm', - 'binsize': 1, - 'xparam': 'hr', - 'yparam': 'pace', - 'spmmin': 15, - 'spmmax': 55, - 'workmin': 400, - 'workmax': 1500, - 'ids': [], - 'ploterrorbars':False, - }): - - def_options = options - - if 'options' in request.session: - options = request.session['options'] - - try: - includereststrokes = options['includereststrokes'] - except KeyError: - includereststrokes = False - - try: - ploterrorbars = options['ploterrorbars'] - except KeyError: - ploterrorbars = False - - try: - palette = request.session['palette'] - except KeyError: - palette = 'monochrome_blue' - - workstrokesonly = not includereststrokes - - if userid==0: - userid = request.user.id - - - palette = keyvalue_get_default('palette',options, def_options) - groupby = keyvalue_get_default('groupby',options, def_options) - binsize = keyvalue_get_default('binsize',options, def_options) - xparam = keyvalue_get_default('xparam',options, def_options) - yparam = keyvalue_get_default('yparam',options, def_options) - spmmin = keyvalue_get_default('spmmin',options, def_options) - spmmax = keyvalue_get_default('spmmax',options, def_options) - workmin = keyvalue_get_default('workmin',options, def_options) - workmax = keyvalue_get_default('workmax',options, def_options) - ids = keyvalue_get_default('ids',options, def_options) - - workouts = [] - - for id in ids: - try: - workouts.append(Workout.objects.get(id=id)) - except Workout.DoesNotExist: - pass - - labeldict = { - int(w.id): w.__str__() for w in workouts - } - - fieldlist,fielddict = dataprep.getstatsfields() - fieldlist = [xparam,yparam,groupby, - 'workoutid','spm','driveenergy', - 'workoutstate'] - - # prepare data frame - datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist) - - if xparam == groupby: - datadf['groupby'] = datadf[xparam] - groupy = 'groupby' - - datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) - - - datadf = dataprep.filter_df(datadf,'spm',spmmin, - largerthan=True) - datadf = dataprep.filter_df(datadf,'spm',spmmax, - largerthan=False) - - datadf = dataprep.filter_df(datadf,'driveenergy',workmin, - largerthan=True) - datadf = dataprep.filter_df(datadf,'driveneergy',workmax, - largerthan=False) - - - datadf.dropna(axis=0,how='any',inplace=True) - - - datemapping = { - w.id:w.date for w in workouts - } - - datadf['date'] = datadf['workoutid'] - datadf['date'].replace(datemapping,inplace=True) - - today = datetime.date.today() - try: - datadf['days ago'] = map(lambda x : x.days, datadf.date - today) - except TypeError: - datadf['days ago'] = 0 - - if groupby != 'date': - try: - bins = np.arange(datadf[groupby].min()-binsize, - datadf[groupby].max()+binsize, - binsize) - groups = datadf.groupby(pd.cut(datadf[groupby],bins,labels=False)) - except (ValueError, AttributeError): - messages.error( - request, - "Unable to compete. Probably not enough data selected" - ) - url = reverse(user_multiflex_select) - return HttpResponseRedirect(url) - else: - bins = np.arange(datadf['days ago'].min()-binsize, - datadf['days ago'].max()+binsize, - binsize, - ) - groups = datadf.groupby(pd.cut(datadf['days ago'], bins, - labels=False)) - - - xvalues = groups.mean()[xparam] - yvalues = groups.mean()[yparam] - xerror = groups.std()[xparam] - yerror = groups.std()[yparam] - groupsize = groups.count()[xparam] - - mask = groupsize <= min([0.01*groupsize.sum(),0.2*groupsize.mean()]) - xvalues.loc[mask] = np.nan - - yvalues.loc[mask] = np.nan - xerror.loc[mask] = np.nan - yerror.loc[mask] = np.nan - groupsize.loc[mask] = np.nan - - xvalues.dropna(inplace=True) - yvalues.dropna(inplace=True) - xerror.dropna(inplace=True) - yerror.dropna(inplace=True) - groupsize.dropna(inplace=True) - - if len(groupsize) == 0: - messages.error(request,'No data in selection') - url = reverse(user_multiflex_select) - return HttpResponseRedirect(url) - else: - groupsize = 30.*np.sqrt(groupsize/float(groupsize.max())) - - df = pd.DataFrame({ - xparam:xvalues, - yparam:yvalues, - 'x':xvalues, - 'y':yvalues, - 'xerror':xerror, - 'yerror':yerror, - 'groupsize':groupsize, - }) - - - if yparam == 'pace': - df['y'] = dataprep.paceformatsecs(df['y']/1.0e3) - - aantal = len(df) - - if groupby != 'date': - try: - df['groupval'] = groups.mean()[groupby] - df['groupval'].loc[mask] = np.nan - - groupcols = df['groupval'] - except (ValueError, AttributeError): - df['groupval'] = groups.mean()[groupby].fillna(value=0) - df['groupval'].loc[mask] = np.nan - groupcols = df['groupval'] - except KeyError: - messages.error(request,'Data selection error') - url = reverse(user_multiflex_select) - return HttpResponseRedirect(url) - else: - try: - dates = groups.min()[groupby] - dates.loc[mask] = np.nan - dates.dropna(inplace=True) - df['groupval'] = [x.strftime("%Y-%m-%d") for x in dates] - df['groupval'].loc[mask] = np.nan - groupcols = 100.*np.arange(aantal)/float(aantal) - except AttributeError: - df['groupval'] = groups.mean()['days ago'].fillna(value=0) - groupcols = 100.*np.arange(aantal)/float(aantal) - - - groupcols = (groupcols-groupcols.min())/(groupcols.max()-groupcols.min()) - - if aantal == 1: - groupcols = np.array([1.]) - - - colors = range_to_color_hex(groupcols,palette=palette) - - df['color'] = colors - - clegendx = np.arange(0,1.2,.2) - legcolors = range_to_color_hex(clegendx,palette=palette) - if groupby != 'date': - clegendy = df['groupval'].min()+clegendx*(df['groupval'].max()-df['groupval'].min()) - else: - clegendy = df.index.min()+clegendx*(df.index.max()-df.index.min()) - - - - colorlegend = zip(range(6),clegendy,legcolors) - - - if userid == 0: - extratitle = '' - else: - u = User.objects.get(id=userid) - extratitle = ' '+u.first_name+' '+u.last_name - - - - script,div = interactive_multiflex(df,xparam,yparam, - groupby, - extratitle=extratitle, - ploterrorbars=ploterrorbars, - binsize=binsize, - colorlegend=colorlegend, - spmmin=spmmin,spmmax=spmmax, - workmin=workmin,workmax=workmax) - - scripta= script.split('\n')[2:-1] - script = ''.join(scripta) - - - return JSONResponse({ - "script":script, - "div":div, - }) - - -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def multiflex_view(request,userid=0, - options={ - 'includereststrokes':False, - 'ploterrorbars':False, - }): - - if 'options' in request.session: - options = request.session['options'] - - try: - includereststrokes = options['includereststrokes'] - except KeyError: - includereststrokes = False - - try: - ploterrorbars = options['ploterrorbars'] - except KeyError: - ploterrorbars = False - - try: - palette = request.session['palette'] - except KeyError: - palette = 'monochrome_blue' - - if 'startdate' in request.session: - startdate = iso8601.parse_date(request.session['startdate']) - - - if 'enddate' in request.session: - enddate = iso8601.parse_date(request.session['enddate']) - - workstrokesonly = not includereststrokes - - if userid==0: - userid = request.user.id - - if request.method == 'POST' and 'workouts' in request.POST: - form = WorkoutMultipleCompareForm(request.POST) - chartform = MultiFlexChoiceForm(request.POST) - if form.is_valid() and chartform.is_valid(): - cd = form.cleaned_data - workouts = cd['workouts'] - xparam = chartform.cleaned_data['xparam'] - yparam = chartform.cleaned_data['yparam'] - includereststrokes = chartform.cleaned_data['includereststrokes'] - ploterrorbars = chartform.cleaned_data['ploterrorbars'] - - workstrokesonly = not includereststrokes - palette = chartform.cleaned_data['palette'] - - groupby = chartform.cleaned_data['groupby'] - binsize = chartform.cleaned_data['binsize'] - if binsize <= 0: - binsize = 1 - if groupby == 'pace': - binsize *= 1000 - - spmmin = chartform.cleaned_data['spmmin'] - spmmax = chartform.cleaned_data['spmmax'] - workmin = chartform.cleaned_data['workmin'] - workmax = chartform.cleaned_data['workmax'] - - ids = [int(w.id) for w in workouts] - request.session['ids'] = ids - - else: - return HttpResponse("Form is not valid") - elif request.method == 'POST' and 'ids' in request.session: - chartform = MultiFlexChoiceForm(request.POST) - if chartform.is_valid(): - xparam = chartform.cleaned_data['xparam'] - yparam = chartform.cleaned_data['yparam'] - includereststrokes = chartform.cleaned_data['includereststrokes'] - ploterrorbars = chartform.cleaned_data['ploterrorbars'] - request.session['ploterrorbars'] = ploterrorbars - request.session['includereststrokes'] = includereststrokes - workstrokesonly = not includereststrokes - palette = chartform.cleaned_data['palette'] - - groupby = chartform.cleaned_data['groupby'] - binsize = chartform.cleaned_data['binsize'] - if binsize <= 0: - binsize = 1 - if groupby == 'pace': - binsize *= 1000. - - spmmin = chartform.cleaned_data['spmmin'] - spmmax = chartform.cleaned_data['spmmax'] - workmin = chartform.cleaned_data['workmin'] - workmax = chartform.cleaned_data['workmax'] - - ids = request.session['ids'] - request.session['ids'] = ids - workouts = dataprep.get_workouts(ids,userid) - if not workouts: - message = 'Error: Workouts in session storage do not belong to this user.' - messages.error(request,message) - url = reverse(user_multiflex_select, - kwargs={ - 'userid':userid, - } - ) - return HttpResponseRedirect(url) - - # workouts = [Workout.objects.get(id=id) for id in ids] - - - else: - return HttpResponse("invalid form") - else: - url = reverse(user_multiflex_select) - return HttpResponseRedirect(url) - - div = get_call() - - options['includereststrokes'] = includereststrokes - options['ploterrorbars'] = ploterrorbars - options['userid'] = userid - options['palette'] = palette - options['groupby'] = groupby - options['binsize'] = binsize - options['xparam'] = xparam - options['yparam'] = yparam - options['spmmin'] = spmmin - options['spmmax'] = spmmax - options['workmin'] = workmin - options['workmax'] = workmax - options['idso'] = ids - - - request.session['options'] = options - - r = getrequestrower(request,userid=userid) - - breadcrumbs = [ - { - 'url':'/rowers/analysis', - 'name':'Analysis' - }, - { - 'url':reverse(user_multiflex_select,kwargs={'userid':userid}), - 'name': 'Trend Flex Select' - }, - { - 'url':reverse(multiflex_view), - 'name': 'Trend Flex Chart' - } - ] - - - return render(request,'multiflex.html', - {'interactiveplot':'', - 'active':'nav-analysis', - 'rower':r, - 'breadcrumbs':breadcrumbs, - 'the_div':div, - 'active':'nav-analysis', - 'chartform':chartform, - 'userid':userid, - 'teams':get_my_teams(request.user), - }) - - -# Box plots -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def user_boxplot_select(request, - startdatestring="", - enddatestring="", - message='', - successmessage='', - startdate=timezone.now()-datetime.timedelta(days=30), - enddate=timezone.now(), - options={ - 'includereststrokes':False, - 'workouttypes':['rower','dynamic','slides'], - 'waterboattype':mytypes.waterboattype, - 'rankingonly':False, - }, - userid=0): - - r = getrequestrower(request,userid=userid) - user = r.user - userid = user.id - - if 'options' in request.session: - options = request.session['options'] - - - try: - workouttypes = options['workouttypes'] - except KeyError: - workouttypes = ['rower','dynamic','slides'] - - try: - rankingonly = options['rankingonly'] - except KeyError: - rankingonly = False - - try: - includereststrokes = options['includereststrokes'] - except KeyError: - includereststrokes = False - - if 'startdate' in request.session: - startdate = iso8601.parse_date(request.session['startdate']) - - - if 'enddate' in request.session: - enddate = iso8601.parse_date(request.session['enddate']) - - workstrokesonly = not includereststrokes - - waterboattype = mytypes.waterboattype - - - if startdatestring != "": - startdate = iso8601.parse_date(startdatestring) - - if enddatestring != "": - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: - s = enddate - enddate = startdate - startdate = s - - - if request.method == 'POST': - dateform = DateRangeForm(request.POST) - if dateform.is_valid(): - startdate = dateform.cleaned_data['startdate'] - enddate = dateform.cleaned_data['enddate'] - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - request.session['startdate'] = startdatestring - request.session['enddate'] = enddatestring - optionsform = TrendFlexModalForm(request.POST) - if optionsform.is_valid(): - modality = optionsform.cleaned_data['modality'] - waterboattype = optionsform.cleaned_data['waterboattype'] - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: - modalities = [modality] - if modality != 'water': - waterboattype = [b[0] for b in mytypes.boattypes] - - - if 'rankingonly' in optionsform.cleaned_data: - rankingonly = optionsform.cleaned_data['rankingonly'] - else: - rankingonly = False - - request.session['modalities'] = modalities - request.session['waterboattype'] = waterboattype - else: - dateform = DateRangeForm(initial={ - 'startdate':startdate, - 'enddate':enddate, - }) - - if 'modalities' in request.session: - modalities = request.session['modalities'] - if len(modalities) > 1: - modality = 'all' - else: - modality = modalities[0] - else: - modalities = [m[0] for m in mytypes.workouttypes] - modality = 'all' - - - - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: - negtypes.append(b[0]) - - - startdate = datetime.datetime.combine(startdate,datetime.time()) - enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59)) - #enddate = enddate+datetime.timedelta(days=1) - - if startdatestring: - startdate = iso8601.parse_date(startdatestring) - if enddatestring: - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: - s = enddate - enddate = startdate - startdate = s - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: - negtypes.append(b[0]) - - # make sure the dates are not naive - try: - startdate = pytz.utc.localize(startdate) - except (ValueError, AttributeError): - pass - try: - enddate = pytz.utc.localize(enddate) - except (ValueError, AttributeError): - pass - - workouts = Workout.objects.filter(user=r, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - workouttype__in=modalities, - ).order_by( - "-date", "-starttime" - ).exclude(boattype__in=negtypes) - # workouttypes = [w for w in workouttypes if w not in mytypes.otwtypes] - - if rankingonly: - workouts = workouts.exclude(rankingpiece=False) - - query = request.GET.get('q') - if query: - query_list = query.split() - workouts = workouts.filter( - reduce(operator.and_, - (Q(name__icontains=q) for q in query_list)) | - reduce(operator.and_, - (Q(notes__icontains=q) for q in query_list)) - ) - searchform = SearchForm(initial={'q':query}) - else: - searchform = SearchForm() - - form = WorkoutMultipleCompareForm() - form.fields["workouts"].queryset = workouts - - chartform = BoxPlotChoiceForm() - optionsform = TrendFlexModalForm(initial={ - 'modality':modality, - 'waterboattype':waterboattype, - 'rankingonly':rankingonly, - }) - - messages.info(request,successmessage) - messages.error(request,message) - - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - request.session['startdate'] = startdatestring - request.session['enddate'] = enddatestring - - - breadcrumbs = [ - { - 'url':'/rowers/analysis', - 'name':'Analysis' - }, - { - 'url':reverse(user_boxplot_select,kwargs={'userid':userid}), - 'name': 'BoxPlot Select' - }, - ] - return render(request, 'user_boxplot_select.html', - {'workouts': workouts, - 'dateform':dateform, - 'startdate':startdate, - 'enddate':enddate, - 'rower':r, - 'breadcrumbs':breadcrumbs, - 'theuser':user, - 'form':form, - 'active':'nav-analysis', - 'chartform':chartform, - 'searchform':searchform, - 'optionsform':optionsform, - 'teams':get_my_teams(request.user), - }) - -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def boxplot_view_data(request,userid=0, - options={ - 'includereststrokes':False, - 'spmmin':15, - 'spmmax':55, - 'workmin':0, - 'workmax':1500, - 'ids':[], - 'userid':0, - 'plotfield':'spm', - }): - - if 'options' in request.session: - options = request.session['options'] - - try: - includereststrokes = options['includereststrokes'] - spmmin = options['spmmin'] - spmmax = options['spmmax'] - workmin = options['workmin'] - workmax = options['workmax'] - ids = options['ids'] - userid = options['userid'] - plotfield = options['plotfield'] - except KeyError: - includereststrokes = False - spmmin = 15 - spmmax = 55 - workmin = 0 - workmax = 55 - ids = [] - userid = 0 - plotfield = 'spm' - - - workstrokesonly = not includereststrokes - - if userid==0: - userid = request.user.id - - workouts = [] - - - if not ids: - return JSONResponse({ - "script":'', - "div":'No data found' - }) - - for id in ids: - try: - workouts.append(Workout.objects.get(id=id)) - except Workout.DoesNotExist: - pass - - labeldict = { - int(w.id): w.__str__() for w in workouts - } - - - datemapping = { - w.id:w.date for w in workouts - } - - - - fieldlist,fielddict = dataprep.getstatsfields() - fieldlist = [plotfield,'workoutid','spm','driveenergy', - 'workoutstate'] - - # prepare data frame - datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist) - - - - datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) - - datadf = dataprep.filter_df(datadf,'spm',spmmin, - largerthan=True) - datadf = dataprep.filter_df(datadf,'spm',spmmax, - largerthan=False) - datadf = dataprep.filter_df(datadf,'driveenergy',workmin, - largerthan=True) - datadf = dataprep.filter_df(datadf,'driveneergy',workmax, - largerthan=False) - - datadf.dropna(axis=0,how='any',inplace=True) - - - datadf['workoutid'].replace(datemapping,inplace=True) - datadf.rename(columns={"workoutid":"date"},inplace=True) - datadf = datadf.sort_values(['date']) - - if userid == 0: - extratitle = '' - else: - u = User.objects.get(id=userid) - extratitle = ' '+u.first_name+' '+u.last_name - - - - script,div = interactive_boxchart(datadf,plotfield, - extratitle=extratitle, - spmmin=spmmin,spmmax=spmmax,workmin=workmin,workmax=workmax) - - scripta = script.split('\n')[2:-1] - script = ''.join(scripta) - - - return JSONResponse({ - "script":script, - "div":div, - }) - -@user_passes_test(ispromember,login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def boxplot_view(request,userid=0, - options={ - 'includereststrokes':False, - 'rankingonly':False, - }): - - if 'options' in request.session: - options = request.session['options'] - else: - options = {} - - try: - includereststrokes = options['includereststrokes'] - except KeyError: - includereststrokes = False - options['includereststrokes'] = False - - try: - rankingonly = options['rankingonly'] - except KeyError: - rankingonly = False - options['rankingonly'] = False - - workstrokesonly = not includereststrokes - - if userid==0: - userid = request.user.id - - - if request.method == 'POST' and 'workouts' in request.POST: - form = WorkoutMultipleCompareForm(request.POST) - chartform = BoxPlotChoiceForm(request.POST) - if form.is_valid() and chartform.is_valid(): - cd = form.cleaned_data - workouts = cd['workouts'] - plotfield = chartform.cleaned_data['yparam'] - includereststrokes = chartform.cleaned_data['includereststrokes'] - request.session['includereststrokes'] = includereststrokes - workstrokesonly = not includereststrokes - - spmmin = chartform.cleaned_data['spmmin'] - spmmax = chartform.cleaned_data['spmmax'] - workmin = chartform.cleaned_data['workmin'] - workmax = chartform.cleaned_data['workmax'] - - ids = [int(w.id) for w in workouts] - request.session['ids'] = ids - - else: - url = reverse(user_boxplot_select,kwargs={'userid':userid}) - return HttpResponseRedirect(url) - elif request.method == 'POST' and 'ids' in request.session: - chartform = BoxPlotChoiceForm(request.POST) - if chartform.is_valid(): - plotfield = chartform.cleaned_data['yparam'] - includereststrokes = chartform.cleaned_data['includereststrokes'] - spmmin = chartform.cleaned_data['spmmin'] - spmmax = chartform.cleaned_data['spmmax'] - workmin = chartform.cleaned_data['workmin'] - workmax = chartform.cleaned_data['workmax'] - request.session['includereststrokes'] = includereststrokes - workstrokesonly = not includereststrokes - ids = request.session['ids'] - request.session['ids'] = ids - - - else: - url = reverse(user_boxplot_select,kwargs={'userid':userid}) - return HttpResponseRedirect(url) - else: - url = reverse(user_boxplot_select,kwargs={'userid':userid}) - return HttpResponseRedirect(url) - - div = get_call() - - - options['spmmin'] = spmmin - options['spmmax'] = spmmax - options['workmin'] = workmin - options['workmax'] = workmax - options['ids'] = ids - options['userid'] = userid - options['plotfield'] = plotfield - options['rankingonly'] = rankingonly - - - request.session['options'] = options - - r = getrequestrower(request,userid=userid) - breadcrumbs = [ - { - 'url':'/rowers/Analysis', - 'name':'Analysis' - }, - { - 'url':reverse(user_boxplot_select,kwargs={'userid':userid}), - 'name': 'BoxPlot Select' - }, - { - 'url':reverse(boxplot_view,kwargs={'userid':userid}), - 'name': 'BoxPlot Select' - }, - ] - - return render(request,'boxplot.html', - {'interactiveplot':'', - 'the_div':div, - 'rower':r, - 'breadcrumbs':breadcrumbs, - 'active':'nav-analysis', - 'chartform':chartform, - 'userid':userid, - 'teams':get_my_teams(request.user), - }) - - -# Cumulative stats page -@user_passes_test(ispromember,login_url="/rowers/paidplans",message="This functionality requires a Pro plan or higher. If you are already a Pro user, please log in to access this functionality",redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def cumstats(request,userid=0, - startdate=timezone.now()-datetime.timedelta(days=30), - enddate=timezone.now(), - deltadays=-1, - startdatestring="", - enddatestring="", - options={ - 'includereststrokes':False, - 'workouttypes':['rower','dynamic','slides'], - 'waterboattype':mytypes.waterboattype, - 'rankingonly':False, - }): - - r = getrequestrower(request,userid=userid) - theuser = r.user - - if 'waterboattype' in request.session: - waterboattype = request.session['waterboattype'] - else: - waterboattype = mytypes.waterboattype - - - if 'rankingonly' in request.session: - rankingonly = request.session['rankingonly'] - else: - rankingonly = False - - if 'modalities' in request.session: - modalities = request.session['modalities'] - if len(modalities) > 1: - modality = 'all' - else: - modality = modalities[0] - else: - modalities = [m[0] for m in mytypes.workouttypes] - modality = 'all' - - - try: - rankingonly = options['rankingonly'] - except KeyError: - rankingonly = False - - try: - includereststrokes = options['includereststrokes'] - except KeyError: - includereststrokes = False - - - workstrokesonly = not includereststrokes - - waterboattype = mytypes.waterboattype - - - if startdatestring != "": - startdate = iso8601.parse_date(startdatestring) - - if enddatestring != "": - enddate = iso8601.parse_date(enddatestring) - - if enddate < startdate: - s = enddate - enddate = startdate - startdate = s - - - # get all indoor rows of in date range - - # process form - if request.method == 'POST': - form = DateRangeForm(request.POST) - modalityform = TrendFlexModalForm(request.POST) - if form.is_valid(): - startdate = form.cleaned_data['startdate'] - enddate = form.cleaned_data['enddate'] - if startdate > enddate: - s = enddate - enddate = startdate - startdate = s - startdatestring = startdate.strftime('%Y-%m-%d') - enddatestring = enddate.strftime('%Y-%m-%d') - if modalityform.is_valid(): - modality = modalityform.cleaned_data['modality'] - waterboattype = modalityform.cleaned_data['waterboattype'] - rankingonly = modalityform.cleaned_data['rankingonly'] - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: - modalities = [modality] - - if modality != 'water': - waterboattype = [b[0] for b in mytypes.boattypes] - - - request.session['modalities'] = modalities - request.session['waterboattype'] = waterboattype - request.session['rankingonly'] = rankingonly - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - else: - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - includereststrokes = False - - workstrokesonly = not includereststrokes - modalityform = TrendFlexModalForm( - initial={ - 'modality':modality, - 'waterboattype':waterboattype, - 'rankingonly':rankingonly, - } - ) - - negtypes = [] - for b in mytypes.boattypes: - if b[0] not in waterboattype: - negtypes.append(b[0]) - - - - script = '' - div = get_call() - js_resources = '' - css_resources = '' - - options = { - 'modality': modality, - 'userid': theuser.id, - 'waterboattype':waterboattype, - 'startdatestring':startdatestring, - 'enddatestring':enddatestring, - 'rankingonly':rankingonly, - 'includereststrokes':includereststrokes, - } - - - request.session['options'] = options - - - if modality == 'all': - modalities = [m[0] for m in mytypes.workouttypes] - else: - modalities = [modality] - - try: - startdate = iso8601.parse_date(startdatestring) - except ParseError: - startdate = timezone.now()-datetime.timedelta(days=7) - - try: - enddate = iso8601.parse_date(enddatestring) - except ParseError: - enddate = timezone.now() - - - if enddate < startdate: - s = enddate - enddate = startdate - startdate = s - - promember=0 - if theuser == 0: - theuser = request.user.id - - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - - r2 = getrower(theuser) - - if rankingonly: - rankingpiece = [True,] - else: - rankingpiece = [True,False] - - allworkouts = Workout.objects.filter( - user=r2, - workouttype__in=modalities, - boattype__in=waterboattype, - startdatetime__gte=startdate, - startdatetime__lte=enddate, - rankingpiece__in=rankingpiece - ).order_by("-date", "-starttime") - - ids = [int(workout.id) for workout in allworkouts] - - datemapping = { - w.id:w.date for w in allworkouts - } - - - - fieldlist,fielddict = dataprep.getstatsfields() - - # prepare data frame - datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist) - - datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) - try: - datadf['pace'] = datadf['pace']/1000. - except KeyError: - pass - - request.session['rowerid'] = r.id - - if datadf.empty: - stats = {} - cordict = {} - - response = render(request, - 'cumstats.html', - { - 'stats':stats, - 'teams':get_my_teams(request.user), - 'options':options, - 'active':'nav-analysis', - 'rower':r, - 'id':theuser, - 'theuser':theuser, - 'startdate':startdate, - 'enddate':enddate, - 'form':form, - 'optionsform':modalityform, - 'cordict':cordict, - }) - - request.session['options'] = options - - return response - - - - # Create stats - stats = {} - try: - fielddict.pop('pace') - except KeyError: - pass - - for field,verbosename in fielddict.items(): - thedict = { - 'mean':datadf[field].mean(), - 'min': datadf[field].min(), - 'std': datadf[field].std(), - 'max': datadf[field].max(), - 'median': datadf[field].median(), - 'firstq':datadf[field].quantile(q=0.25), - 'thirdq':datadf[field].quantile(q=0.75), - 'verbosename':verbosename, - } - stats[field] = thedict - - # Create a dict with correlation values - cor = datadf.corr(method='spearman') - cor.fillna(value=0,inplace=True) - cordict = {} - for field1,verbosename1 in fielddict.items(): - thedict = {} - for field2,verbosename2 in fielddict.items(): - try: - thedict[verbosename2] = cor.loc[field1,field2] - except KeyError: - thedict[verbosename2] = 0 - - cordict[verbosename1] = thedict - - # set options form correctly - initial = {} - initial['includereststrokes'] = includereststrokes - initial['waterboattype'] = waterboattype - initial['rankingonly'] = rankingonly - - - response = render(request, - 'cumstats.html', - { - 'stats':stats, - 'teams':get_my_teams(request.user), - 'active':'nav-analysis', - 'rower':r, - 'options':options, - 'id':theuser, - 'theuser':theuser, - 'startdate':startdate, - 'enddate':enddate, - 'form':form, - 'optionsform':modalityform, - 'cordict':cordict, - }) - - request.session['options'] = options - - return response - - def agegroupcpview(request,age,normalize=0): script,div = interactive_agegroupcpchart(age,normalized=normalize) @@ -3808,7 +1807,7 @@ def alerts_view(request,userid=0): stats = [] - for alert in alerts: + for alert in alerts: # pragma: no cover stats.append(alert_get_stats(alert)) @@ -4219,7 +2218,7 @@ def history_view(request,userid=0): ddict['id'] = wtype try: ddict['wtype'] = mytypes.workouttypes_ordered[wtype] - except KeyError: + except KeyError: # pragma: no cover ddict['wtype'] = wtype ddict['distance'] = wmeters ddict['duration'] = "{whours}:{wminutes:02d}:{wseconds:02d}".format( @@ -4330,7 +2329,7 @@ def history_view_data(request,userid=0): yaxis = request.GET.get('yaxis','duration') - if yaxis.lower() not in ['duration','rscore','trimp']: + if yaxis.lower() not in ['duration','rscore','trimp']: # pragma: no cover yaxis = 'duration' g_workouts = Workout.objects.filter( @@ -4368,9 +2367,9 @@ def history_view_data(request,userid=0): a_workouts = g_workouts.filter(workouttype=wtype) wmeters, whours, wminutes,wseconds = get_totals(a_workouts) ddict = {} - try: + try: # pragma: no cover ddict['wtype'] = mytypes.workouttypes_ordered[wtype] - except KeyError: + except KeyError: # pragma: no cover ddict['wtype'] = wtype ddict['id'] = wtype @@ -4382,7 +2381,7 @@ def history_view_data(request,userid=0): ddf = getsmallrowdata_db(columns,ids=[w.id for w in a_workouts]) try: ddf['deltat'] = ddf['time'].diff().clip(lower=0) - except KeyError: + except KeyError: # pragma: no cover pass @@ -4393,7 +2392,7 @@ def history_view_data(request,userid=0): ddict['hrmean'] = int(wavg(ddf,'hr','deltat')) try: ddict['hrmax'] = ddf['hr'].max().astype(int) - except (ValueError, AttributeError): + except (ValueError, AttributeError): # pragma: no cover ddict['hrmax'] = 0 ddict['powermean'] = int(wavg(ddf,'power','deltat')) @@ -4417,7 +2416,7 @@ def history_view_data(request,userid=0): try: totalsdict['hrmean'] = int(wavg(df,'hr','deltat')) totalsdict['hrmax'] = df['hr'].max().astype(int) - except KeyError: + except KeyError: # pragma: no cover totalsdict['hrmean'] = 0 totalsdict['hrmax'] = 0