diff --git a/23099b58-7632-4d34-97e2-2f4890cf5773.tcx b/23099b58-7632-4d34-97e2-2f4890cf5773.tcx new file mode 100644 index 00000000..e7df305a --- /dev/null +++ b/23099b58-7632-4d34-97e2-2f4890cf5773.tcx @@ -0,0 +1,2523 @@ + + + + + 2016-05-20T13:41:26.962390+00:00 + + 537 + 2000 + 118 + + 148 + + + 156 + + Active + 21 + Manual + + + 2016-05-20T13:41:26+00:00 + 5.4 + + 127 + + 0 + + + 19 + + + + + 2016-05-20T13:41:29.238150+00:00 + 13.1 + + 127 + + 19 + + + 26 + + + + + 2016-05-20T13:41:32.148290+00:00 + 21.0 + + 128 + + 20 + + + 45 + + + + + 2016-05-20T13:41:35.269000+00:00 + 30.3 + + 129 + + 20 + + + 64 + + + + + 2016-05-20T13:41:38.152180+00:00 + 39.0 + + 130 + + 20 + + + 74 + + + + + 2016-05-20T13:41:41.148270+00:00 + 48.2 + + 131 + + 21 + + + 80 + + + + + 2016-05-20T13:41:44.148910+00:00 + 57.6 + + 131 + + 20 + + + 83 + + + + + 2016-05-20T13:41:46.908250+00:00 + 66.4 + + 132 + + 20 + + + 87 + + + + + 2016-05-20T13:41:49.819010+00:00 + 75.5 + + 132 + + 21 + + + 86 + + + + + 2016-05-20T13:41:52.942510+00:00 + 85.1 + + 132 + + 20 + + + 88 + + + + + 2016-05-20T13:41:55.639670+00:00 + 95.0 + + 132 + + 21 + + + 100 + + + + + 2016-05-20T13:41:58.370000+00:00 + 105.0 + + 133 + + 22 + + + 127 + + + + + 2016-05-20T13:42:01.188270+00:00 + 115.3 + + 134 + + 21 + + + 135 + + + + + 2016-05-20T13:42:04.008300+00:00 + 125.8 + + 135 + + 21 + + + 139 + + + + + 2016-05-20T13:42:06.888990+00:00 + 136.6 + + 136 + + 21 + + + 146 + + + + + 2016-05-20T13:42:09.678900+00:00 + 147.2 + + 137 + + 22 + + + 150 + + + + + 2016-05-20T13:42:12.469140+00:00 + 157.6 + + 139 + + 22 + + + 152 + + + + + 2016-05-20T13:42:15.199010+00:00 + 167.8 + + 140 + + 21 + + + 146 + + + + + 2016-05-20T13:42:17.963080+00:00 + 178.5 + + 140 + + 22 + + + 150 + + + + + 2016-05-20T13:42:20.658340+00:00 + 188.5 + + 141 + + 21 + + + 155 + + + + + 2016-05-20T13:42:23.538800+00:00 + 199.3 + + 141 + + 21 + + + 148 + + + + + 2016-05-20T13:42:26.269790+00:00 + 209.4 + + 142 + + 22 + + + 151 + + + + + 2016-05-20T13:42:28.848350+00:00 + 219.4 + + 142 + + 22 + + + 151 + + + + + 2016-05-20T13:42:31.729550+00:00 + 230.2 + + 143 + + 22 + + + 148 + + + + + 2016-05-20T13:42:34.398400+00:00 + 240.2 + + 144 + + 22 + + + 147 + + + + + 2016-05-20T13:42:37.038360+00:00 + 250.1 + + 145 + + 23 + + + 150 + + + + + 2016-05-20T13:42:39.499250+00:00 + 259.6 + + 145 + + 23 + + + 152 + + + + + 2016-05-20T13:42:42.349070+00:00 + 270.3 + + 145 + + 23 + + + 152 + + + + + 2016-05-20T13:42:45.079070+00:00 + 280.6 + + 145 + + 22 + + + 149 + + + + + 2016-05-20T13:42:47.752890+00:00 + 290.7 + + 144 + + 22 + + + 150 + + + + + 2016-05-20T13:42:50.452350+00:00 + 300.8 + + 145 + + 23 + + + 149 + + + + + 2016-05-20T13:42:53.182630+00:00 + 311.1 + + 145 + + 22 + + + 152 + + + + + 2016-05-20T13:42:55.789410+00:00 + 321.2 + + 145 + + 22 + + + 157 + + + + + 2016-05-20T13:42:58.671890+00:00 + 331.9 + + 145 + + 21 + + + 150 + + + + + 2016-05-20T13:43:01.338860+00:00 + 342.0 + + 146 + + 22 + + + 151 + + + + + 2016-05-20T13:43:04.068490+00:00 + 352.4 + + 146 + + 22 + + + 151 + + + + + 2016-05-20T13:43:06.862620+00:00 + 363.0 + + 146 + + 22 + + + 153 + + + + + 2016-05-20T13:43:09.618500+00:00 + 373.4 + + 147 + + 22 + + + 152 + + + + + 2016-05-20T13:43:12.379160+00:00 + 383.9 + + 147 + + 22 + + + 153 + + + + + 2016-05-20T13:43:15.229200+00:00 + 394.6 + + 147 + + 22 + + + 152 + + + + + 2016-05-20T13:43:17.963150+00:00 + 405.0 + + 147 + + 21 + + + 149 + + + + + 2016-05-20T13:43:20.692490+00:00 + 415.3 + + 148 + + 22 + + + 152 + + + + + 2016-05-20T13:43:23.628520+00:00 + 426.0 + + 148 + + 22 + + + 151 + + + + + 2016-05-20T13:43:26.329210+00:00 + 436.5 + + 148 + + 21 + + + 149 + + + + + 2016-05-20T13:43:29.148960+00:00 + 446.9 + + 148 + + 22 + + + 149 + + + + + 2016-05-20T13:43:31.668570+00:00 + 456.9 + + 149 + + 22 + + + 156 + + + + + 2016-05-20T13:43:34.490920+00:00 + 467.6 + + 149 + + 22 + + + 155 + + + + + 2016-05-20T13:43:37.369250+00:00 + 478.5 + + 150 + + 22 + + + 156 + + + + + 2016-05-20T13:43:40.189230+00:00 + 489.0 + + 150 + + 21 + + + 154 + + + + + 2016-05-20T13:43:42.798860+00:00 + 499.1 + + 150 + + 21 + + + 148 + + + + + 2016-05-20T13:43:45.708750+00:00 + 510.0 + + 150 + + 22 + + + 151 + + + + + 2016-05-20T13:43:48.318590+00:00 + 519.9 + + 149 + + 22 + + + 153 + + + + + 2016-05-20T13:43:51.199500+00:00 + 530.6 + + 149 + + 22 + + + 151 + + + + + 2016-05-20T13:43:53.869290+00:00 + 540.8 + + 149 + + 22 + + + 148 + + + + + 2016-05-20T13:43:56.572490+00:00 + 550.8 + + 148 + + 22 + + + 149 + + + + + 2016-05-20T13:43:59.212410+00:00 + 560.8 + + 148 + + 22 + + + 144 + + + + + 2016-05-20T13:44:01.912890+00:00 + 571.0 + + 147 + + 22 + + + 149 + + + + + 2016-05-20T13:44:04.459350+00:00 + 580.7 + + 147 + + 22 + + + 150 + + + + + 2016-05-20T13:44:07.249360+00:00 + 591.2 + + 147 + + 22 + + + 151 + + + + + 2016-05-20T13:44:09.949930+00:00 + 601.4 + + 147 + + 22 + + + 150 + + + + + 2016-05-20T13:44:12.619870+00:00 + 611.4 + + 147 + + 23 + + + 153 + + + + + 2016-05-20T13:44:15.378800+00:00 + 621.8 + + 147 + + 23 + + + 151 + + + + + 2016-05-20T13:44:18.049420+00:00 + 632.1 + + 147 + + 22 + + + 155 + + + + + 2016-05-20T13:44:20.719440+00:00 + 642.3 + + 147 + + 22 + + + 154 + + + + + 2016-05-20T13:44:23.298970+00:00 + 652.0 + + 148 + + 23 + + + 157 + + + + + 2016-05-20T13:44:26.178820+00:00 + 662.7 + + 148 + + 23 + + + 162 + + + + + 2016-05-20T13:44:28.669980+00:00 + 673.1 + + 148 + + 23 + + + 163 + + + + + 2016-05-20T13:44:31.429270+00:00 + 683.6 + + 149 + + 22 + + + 163 + + + + + 2016-05-20T13:44:34.042790+00:00 + 693.8 + + 149 + + 22 + + + 162 + + + + + 2016-05-20T13:44:36.589070+00:00 + 703.8 + + 149 + + 22 + + + 164 + + + + + 2016-05-20T13:44:39.412800+00:00 + 714.7 + + 150 + + 23 + + + 162 + + + + + 2016-05-20T13:44:42.078870+00:00 + 724.9 + + 150 + + 22 + + + 162 + + + + + 2016-05-20T13:44:44.783760+00:00 + 735.2 + + 151 + + 23 + + + 159 + + + + + 2016-05-20T13:44:47.450710+00:00 + 745.4 + + 151 + + 22 + + + 158 + + + + + 2016-05-20T13:44:50.149400+00:00 + 756.0 + + 151 + + 23 + + + 164 + + + + + 2016-05-20T13:44:52.789720+00:00 + 766.3 + + 150 + + 22 + + + 163 + + + + + 2016-05-20T13:44:55.429750+00:00 + 776.5 + + 150 + + 22 + + + 161 + + + + + 2016-05-20T13:44:58.069700+00:00 + 786.9 + + 150 + + 23 + + + 163 + + + + + 2016-05-20T13:45:00.742790+00:00 + 797.2 + + 150 + + 22 + + + 165 + + + + + 2016-05-20T13:45:03.442700+00:00 + 807.8 + + 150 + + 23 + + + 166 + + + + + 2016-05-20T13:45:06.139610+00:00 + 818.2 + + 150 + + 23 + + + 166 + + + + + 2016-05-20T13:45:08.689490+00:00 + 828.4 + + 150 + + 22 + + + 168 + + + + + 2016-05-20T13:45:11.479530+00:00 + 839.2 + + 150 + + 23 + + + 169 + + + + + 2016-05-20T13:45:14.119610+00:00 + 849.6 + + 151 + + 23 + + + 166 + + + + + 2016-05-20T13:45:16.792860+00:00 + 860.1 + + 151 + + 22 + + + 172 + + + + + 2016-05-20T13:45:19.368950+00:00 + 870.3 + + 152 + + 22 + + + 172 + + + + + 2016-05-20T13:45:22.158960+00:00 + 881.1 + + 152 + + 22 + + + 169 + + + + + 2016-05-20T13:45:24.889580+00:00 + 891.7 + + 152 + + 23 + + + 167 + + + + + 2016-05-20T13:45:27.558940+00:00 + 902.1 + + 152 + + 22 + + + 164 + + + + + 2016-05-20T13:45:30.469760+00:00 + 913.1 + + 152 + + 22 + + + 161 + + + + + 2016-05-20T13:45:33.259860+00:00 + 923.9 + + 153 + + 22 + + + 158 + + + + + 2016-05-20T13:45:36.079590+00:00 + 934.6 + + 154 + + 21 + + + 158 + + + + + 2016-05-20T13:45:38.899560+00:00 + 945.4 + + 154 + + 21 + + + 154 + + + + + 2016-05-20T13:45:41.689980+00:00 + 956.0 + + 155 + + 21 + + + 155 + + + + + 2016-05-20T13:45:44.568940+00:00 + 966.7 + + 155 + + 21 + + + 152 + + + + + 2016-05-20T13:45:47.329670+00:00 + 977.4 + + 156 + + 21 + + + 150 + + + + + 2016-05-20T13:45:50.149560+00:00 + 988.1 + + 156 + + 21 + + + 157 + + + + + 2016-05-20T13:45:52.969660+00:00 + 998.8 + + 156 + + 21 + + + 155 + + + + + 2016-05-20T13:45:55.879910+00:00 + 1009.6 + + 156 + + 21 + + + 151 + + + + + 2016-05-20T13:45:58.789690+00:00 + 1020.6 + + 156 + + 21 + + + 147 + + + + + 2016-05-20T13:46:01.729660+00:00 + 1031.5 + + 156 + + 20 + + + 145 + + + + + 2016-05-20T13:46:04.669610+00:00 + 1042.5 + + 156 + + 21 + + + 144 + + + + + 2016-05-20T13:46:07.549730+00:00 + 1053.3 + + 155 + + 20 + + + 145 + + + + + 2016-05-20T13:46:10.458930+00:00 + 1064.1 + + 155 + + 21 + + + 147 + + + + + 2016-05-20T13:46:13.488980+00:00 + 1075.3 + + 155 + + 20 + + + 142 + + + + + 2016-05-20T13:46:16.429320+00:00 + 1086.1 + + 155 + + 20 + + + 136 + + + + + 2016-05-20T13:46:19.519650+00:00 + 1097.5 + + 155 + + 21 + + + 141 + + + + + 2016-05-20T13:46:22.459630+00:00 + 1108.5 + + 155 + + 20 + + + 146 + + + + + 2016-05-20T13:46:25.338880+00:00 + 1119.2 + + 155 + + 20 + + + 143 + + + + + 2016-05-20T13:46:28.459530+00:00 + 1130.6 + + 155 + + 20 + + + 143 + + + + + 2016-05-20T13:46:31.401590+00:00 + 1141.3 + + 155 + + 20 + + + 143 + + + + + 2016-05-20T13:46:34.339560+00:00 + 1152.4 + + 155 + + 21 + + + 142 + + + + + 2016-05-20T13:46:37.309450+00:00 + 1163.3 + + 155 + + 20 + + + 138 + + + + + 2016-05-20T13:46:40.098920+00:00 + 1173.8 + + 154 + + 20 + + + 141 + + + + + 2016-05-20T13:46:43.039950+00:00 + 1184.8 + + 154 + + 21 + + + 146 + + + + + 2016-05-20T13:46:46.039490+00:00 + 1195.8 + + 153 + + 21 + + + 146 + + + + + 2016-05-20T13:46:48.979630+00:00 + 1206.6 + + 152 + + 21 + + + 141 + + + + + 2016-05-20T13:46:51.949590+00:00 + 1217.3 + + 153 + + 21 + + + 141 + + + + + 2016-05-20T13:46:54.709590+00:00 + 1227.8 + + 152 + + 21 + + + 140 + + + + + 2016-05-20T13:46:57.589710+00:00 + 1238.7 + + 152 + + 21 + + + 143 + + + + + 2016-05-20T13:47:00.503120+00:00 + 1249.5 + + 151 + + 21 + + + 149 + + + + + 2016-05-20T13:47:03.408950+00:00 + 1260.1 + + 151 + + 20 + + + 141 + + + + + 2016-05-20T13:47:06.323410+00:00 + 1270.9 + + 151 + + 21 + + + 141 + + + + + 2016-05-20T13:47:09.229670+00:00 + 1281.8 + + 150 + + 21 + + + 145 + + + + + 2016-05-20T13:47:12.198960+00:00 + 1292.7 + + 151 + + 20 + + + 142 + + + + + 2016-05-20T13:47:15.079930+00:00 + 1303.4 + + 151 + + 20 + + + 141 + + + + + 2016-05-20T13:47:17.989660+00:00 + 1314.3 + + 151 + + 21 + + + 141 + + + + + 2016-05-20T13:47:20.959680+00:00 + 1325.2 + + 151 + + 21 + + + 146 + + + + + 2016-05-20T13:47:23.869730+00:00 + 1336.1 + + 152 + + 20 + + + 143 + + + + + 2016-05-20T13:47:26.782970+00:00 + 1346.9 + + 152 + + 21 + + + 144 + + + + + 2016-05-20T13:47:29.688910+00:00 + 1357.4 + + 152 + + 20 + + + 141 + + + + + 2016-05-20T13:47:32.539570+00:00 + 1368.1 + + 152 + + 21 + + + 138 + + + + + 2016-05-20T13:47:35.449720+00:00 + 1379.0 + + 152 + + 20 + + + 142 + + + + + 2016-05-20T13:47:38.329080+00:00 + 1389.5 + + 153 + + 21 + + + 145 + + + + + 2016-05-20T13:47:41.148960+00:00 + 1399.9 + + 152 + + 21 + + + 138 + + + + + 2016-05-20T13:47:44.088880+00:00 + 1410.7 + + 152 + + 20 + + + 139 + + + + + 2016-05-20T13:47:47.150600+00:00 + 1422.0 + + 152 + + 20 + + + 139 + + + + + 2016-05-20T13:47:50.029750+00:00 + 1432.8 + + 151 + + 20 + + + 141 + + + + + 2016-05-20T13:47:52.998850+00:00 + 1443.6 + + 151 + + 21 + + + 146 + + + + + 2016-05-20T13:47:55.880360+00:00 + 1454.4 + + 152 + + 20 + + + 143 + + + + + 2016-05-20T13:47:58.789400+00:00 + 1465.1 + + 151 + + 21 + + + 143 + + + + + 2016-05-20T13:48:01.639760+00:00 + 1475.9 + + 152 + + 21 + + + 145 + + + + + 2016-05-20T13:48:04.492770+00:00 + 1486.6 + + 152 + + 21 + + + 148 + + + + + 2016-05-20T13:48:07.429530+00:00 + 1497.4 + + 153 + + 21 + + + 143 + + + + + 2016-05-20T13:48:10.373270+00:00 + 1508.2 + + 153 + + 20 + + + 140 + + + + + 2016-05-20T13:48:13.309500+00:00 + 1519.2 + + 154 + + 20 + + + 144 + + + + + 2016-05-20T13:48:16.279570+00:00 + 1530.0 + + 154 + + 21 + + + 143 + + + + + 2016-05-20T13:48:19.160740+00:00 + 1540.9 + + 153 + + 20 + + + 141 + + + + + 2016-05-20T13:48:21.948820+00:00 + 1551.3 + + 153 + + 21 + + + 143 + + + + + 2016-05-20T13:48:25.039520+00:00 + 1562.6 + + 153 + + 21 + + + 146 + + + + + 2016-05-20T13:48:27.949340+00:00 + 1573.3 + + 153 + + 20 + + + 141 + + + + + 2016-05-20T13:48:30.890880+00:00 + 1584.2 + + 152 + + 20 + + + 139 + + + + + 2016-05-20T13:48:33.648790+00:00 + 1594.6 + + 152 + + 21 + + + 145 + + + + + 2016-05-20T13:48:36.770050+00:00 + 1606.0 + + 152 + + 21 + + + 143 + + + + + 2016-05-20T13:48:39.499600+00:00 + 1616.2 + + 152 + + 20 + + + 138 + + + + + 2016-05-20T13:48:42.559140+00:00 + 1627.4 + + 152 + + 21 + + + 140 + + + + + 2016-05-20T13:48:45.439020+00:00 + 1638.0 + + 152 + + 21 + + + 144 + + + + + 2016-05-20T13:48:48.439810+00:00 + 1649.2 + + 151 + + 20 + + + 143 + + + + + 2016-05-20T13:48:51.379570+00:00 + 1660.2 + + 152 + + 20 + + + 143 + + + + + 2016-05-20T13:48:54.259600+00:00 + 1670.8 + + 151 + + 20 + + + 142 + + + + + 2016-05-20T13:48:57.139300+00:00 + 1681.4 + + 151 + + 21 + + + 140 + + + + + 2016-05-20T13:49:00.049550+00:00 + 1692.1 + + 151 + + 21 + + + 140 + + + + + 2016-05-20T13:49:02.838790+00:00 + 1702.5 + + 150 + + 21 + + + 141 + + + + + 2016-05-20T13:49:05.839540+00:00 + 1713.7 + + 150 + + 21 + + + 144 + + + + + 2016-05-20T13:49:08.749400+00:00 + 1724.4 + + 150 + + 21 + + + 146 + + + + + 2016-05-20T13:49:11.689540+00:00 + 1735.1 + + 150 + + 20 + + + 141 + + + + + 2016-05-20T13:49:14.538900+00:00 + 1745.6 + + 150 + + 21 + + + 140 + + + + + 2016-05-20T13:49:17.389440+00:00 + 1756.3 + + 150 + + 21 + + + 141 + + + + + 2016-05-20T13:49:20.058880+00:00 + 1766.2 + + 151 + + 20 + + + 142 + + + + + 2016-05-20T13:49:23.059530+00:00 + 1777.1 + + 150 + + 22 + + + 138 + + + + + 2016-05-20T13:49:25.880610+00:00 + 1787.5 + + 150 + + 21 + + + 138 + + + + + 2016-05-20T13:49:28.608730+00:00 + 1797.7 + + 150 + + 22 + + + 140 + + + + + 2016-05-20T13:49:31.582600+00:00 + 1808.4 + + 150 + + 21 + + + 140 + + + + + 2016-05-20T13:49:34.278700+00:00 + 1818.4 + + 149 + + 21 + + + 138 + + + + + 2016-05-20T13:49:37.068660+00:00 + 1828.9 + + 149 + + 22 + + + 146 + + + + + 2016-05-20T13:49:40.039460+00:00 + 1839.9 + + 149 + + 21 + + + 142 + + + + + 2016-05-20T13:49:42.889790+00:00 + 1850.5 + + 148 + + 21 + + + 142 + + + + + 2016-05-20T13:49:45.772580+00:00 + 1861.2 + + 148 + + 21 + + + 145 + + + + + 2016-05-20T13:49:48.708690+00:00 + 1871.9 + + 147 + + 21 + + + 143 + + + + + 2016-05-20T13:49:51.679450+00:00 + 1882.6 + + 147 + + 20 + + + 139 + + + + + 2016-05-20T13:49:54.499470+00:00 + 1893.3 + + 148 + + 20 + + + 140 + + + + + 2016-05-20T13:49:57.409440+00:00 + 1904.3 + + 149 + + 21 + + + 144 + + + + + 2016-05-20T13:50:00.439330+00:00 + 1915.4 + + 149 + + 20 + + + 148 + + + + + 2016-05-20T13:50:03.408680+00:00 + 1926.2 + + 150 + + 20 + + + 139 + + + + + 2016-05-20T13:50:06.378680+00:00 + 1937.3 + + 151 + + 20 + + + 140 + + + + + 2016-05-20T13:50:09.168860+00:00 + 1947.8 + + 152 + + 20 + + + 144 + + + + + 2016-05-20T13:50:12.229650+00:00 + 1959.1 + + 152 + + 20 + + + 142 + + + + + 2016-05-20T13:50:15.138650+00:00 + 1969.8 + + 153 + + 20 + + + 140 + + + + + 2016-05-20T13:50:18.049470+00:00 + 1980.6 + + 153 + + 21 + + + 143 + + + + + 2016-05-20T13:50:20.959460+00:00 + 1991.4 + + 153 + + 21 + + + 143 + + + + + 2016-05-20T13:50:23.242360+00:00 + 2000.0 + + 154 + + 21 + + + 147 + + + + + + <Element 'Notes' at 0x7f433c451b38> + + + + rowsandall.com/rowingdata + + + rowingdata + + + 0 + 75 + + Release + + EN + 000-00000-00 + + diff --git a/requirements.txt b/requirements.txt index 05616a35..00ed095f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,215 +1,138 @@ -amqp==2.4.2 -apipkg==1.5 +amqp==2.5.2 +anytree==2.8.0 +apparmor==2.13.3 appdirs==1.4.3 -arcgis==1.6.0 -arrow==0.13.1 -asn1crypto==0.24.0 -atomicwrites==1.3.0 -attrs==19.1.0 +asn1crypto==1.3.0 +attrs==19.3.0 backcall==0.1.0 -beautifulsoup4==4.7.1 -billiard==3.6.0.0 +beautifulsoup4==4.8.2 +billiard==3.6.1.0 bleach==3.1.0 -bokeh==1.0.4 boto==2.49.0 -braintree==3.55.0 -cairocffi==1.0.2 +btrfsutil==1.1.1 +CacheControl==0.12.6 +case==1.5.3 +catfish==1.4.13 celery==4.3.0 -certifi==2019.3.9 -cffi==1.12.2 +ceph-volume==1.0.0 +cephfs==2.0.0 +cephfs-shell==0.0.1 +certifi==2019.11.28 +cffi==1.13.2 chardet==3.0.4 -Click==7.0 -cloudpickle==1.2.2 -colorama==0.4.1 -colorclass==2.2.0 -cookies==2.2.1 -coreapi==2.3.3 -coreschema==0.0.4 -coverage==4.5.3 -cryptography==2.6.1 +colorama==0.4.3 +contextlib2==0.6.0 +cryptography==2.8 cycler==0.10.0 -dask==2.6.0 -decorator==4.4.0 -defusedxml==0.5.0 -Django==2.1.7 -django-analytical==2.5.0 -django-async-messages==0.3.1 -django-braces==1.13.0 -django-classy-tags==0.8.0 -django-cookie-law==2.0.1 -django-cors-headers==2.5.2 -django-countries==5.3.3 -django-datetime-widget==0.9.3 -django-debug-toolbar==2.0 -django-extensions==2.1.6 -django-htmlmin==0.11.0 -django-leaflet==0.24.0 -django-mailbox==4.8.0 -django-oauth-toolkit==1.2.0 -django-oauth2-provider==0.2.6.1 -django-redis==4.10.0 -django-rest-framework==0.1.0 -django-rest-swagger==2.2.0 -django-rq==1.3.1 -django-rq-dashboard==0.3.3 -django-ses==0.8.10 -django-shell-plus==1.1.7 -django-social-share==1.3.2 -django-suit==0.2.26 -django-suit-rq==1.0.1 -django-tz-detect==0.2.9 -djangorestframework==3.9.2 +decorator==4.4.1 +defusedxml==0.6.0 +distlib==0.3.0 +distro==1.4.0 docopt==0.6.2 -docutils==0.14 entrypoints==0.3 -execnet==1.5.0 -factory-boy==2.11.1 -Faker==1.0.4 -fastparquet==0.3.2 -fitparse==1.1.0 -Flask==1.0.2 -fsspec==0.5.2 -future==0.17.1 -geocoder==1.38.1 -geos==0.2.1 -grpcio==1.26.0 -grpcio-tools==1.26.0 -holoviews==1.11.3 +gufw==19.10.0 html5lib==1.0.1 htmlmin==0.1.12 -HTMLParser==0.0.2 -httplib2==0.12.1 -hvplot==0.4.0 -icalendar==4.0.3 +httplib2==0.14.0 idna==2.8 -image==1.5.27 -importlib-resources==1.0.2 -ipykernel==5.1.0 -ipython==7.4.0 -ipython-genutils==0.2.0 -ipywidgets==7.4.2 -iso8601==0.1.12 -isodate==0.6.0 -itsdangerous==1.1.0 -itypes==1.1.0 -jedi==0.13.3 -jeepney==0.4 -Jinja2==2.10 -json5==0.8.5 -jsonschema==3.0.1 -jupyter==1.0.0 -jupyter-client==5.2.4 +importlib-metadata==1.4.0 +ipykernel==5.1.3 +ipython==7.11.1 +ipython-genutils==0.1.0 +ipywidgets==7.5.1 +Jade-Application-Kit==2.1.3 +jedi==0.15.1 +Jinja2==2.10.3 +jsonschema==3.2.0 +jupyter-client==5.3.4 jupyter-console==6.0.0 -jupyter-core==4.4.0 -jupyterlab==0.35.4 -jupyterlab-server==0.3.0 -keyring==18.0.0 -kiwisolver==1.0.1 -kombu==4.5.0 -llvmlite==0.30.0 -lxml==4.3.2 -Markdown==3.0.1 +jupyter-core==4.6.1 +keyutils==0.6 +kiwisolver==1.1.0 +kombu==4.6.7 +lensfun==0.3.2 +LibAppArmor==2.13.3 +lightdm-gtk-greeter-settings==1.2.2 +lockfile==0.12.2 +louis==3.12.0 +lxml==4.4.2 MarkupSafe==1.1.1 -matplotlib==3.0.3 -minify==0.1.4 -MiniMockTest==0.5 +matplotlib==3.1.2 +menulibre==2.2.1 mistune==0.8.4 -mock==2.0.0 -more-itertools==6.0.0 -mpld3==0.3 -mysqlclient==1.4.2.post1 -nbconvert==5.4.1 +more-itertools==8.1.0 +msgpack==0.6.2 +mugshot==0.4.2 +nbconvert==5.6.1 nbformat==4.4.0 -newrelic==5.2.1.129 nose==1.3.7 -nose-parameterized==0.6.0 -notebook==5.7.6 -numba==0.46.0 -numpy==1.16.2 -oauth2==1.9.0.post1 -oauthlib==3.0.1 -openapi-codec==1.3.2 -packaging==19.0 -pandas==0.24.2 +notebook==6.0.2 +npyscreen==4.10.5 +numpy==1.18.1 +openshot-qt==2.4.4 +ordered-set==3.1.1 +packaging==20.0 +pacman-mirrors==4.16.2 pandocfilters==1.4.2 -param==1.8.2 -parso==0.3.4 -pathspec==0.5.9 -pbr==5.1.3 -pexpect==4.6.0 +parso==0.5.2 +pep517==0.6.0 +pexpect==4.7.0 pickleshare==0.7.5 -Pillow==5.4.1 -pip-upgrader==1.4.6 -pluggy==0.9.0 -prometheus-client==0.6.0 -prompt-toolkit==2.0.9 -protobuf==3.11.1 -psycopg2==2.8.1 +Pillow==6.2.1 +pkgconfig==1.5.1 +pkginfo==1.5.0.1 +ply==3.11 +progress==1.5 +prometheus-client==0.7.1 +prompt-toolkit==3.0.2 +psutil==5.6.7 ptyprocess==0.6.0 -py==1.8.0 -pyarrow==0.15.0 +pycairo==1.18.2 pycparser==2.19 -Pygments==2.3.1 -pyparsing==2.3.1 -pyrsistent==0.14.11 -pyshp==2.1.0 -pytest==4.3.1 -pytest-django==3.4.8 -pytest-forked==1.0.2 -pytest-runner==4.4 -pytest-sugar==0.9.2 -pytest-xdist==1.27.0 -python-dateutil==2.8.0 -python-memcached==1.59 -python-twitter==3.5 -pytz==2018.9 -pyviz-comms==0.7.1 -pywin32-ctypes==0.2.0 -pywinpty==0.5.5 -PyYAML==5.1 -pyzmq==18.0.1 -qtconsole==4.4.3 -ratelim==0.1.6 -redis==3.2.1 -requests==2.21.0 -requests-oauthlib==1.2.0 -rowingdata==2.5.9 -rowingphysics==0.5.0 -rq==0.13.0 -rules==2.1 -scipy==1.2.1 -SecretStorage==3.1.1 +pycups==1.9.74 +pycurl==7.43.0.3 +Pygments==2.5.2 +PyGObject==3.34.0 +pymongo==3.10.1 +pyOpenSSL==19.1.0 +pyparsing==2.4.6 +PyQt5==5.14.1 +PyQt5-sip==12.7.0 +PyQtWebEngine==5.14.0 +Pyro4==4.77 +pyrsistent==0.15.7 +python-dateutil==2.8.1 +python-distutils-extra==2.39 +pytoml==0.1.21 +pytz==2019.3 +pyxdg==0.26 +PyYAML==5.3 +pyzmq==18.1.1 +rados==2.0.0 +rbd==2.0.0 +redis==3.3.11 +requests==2.22.0 +retrying==1.3.3 +rgw==2.0.0 +scipy==1.4.1 Send2Trash==1.5.0 -shell==1.0.1 -shortuuid==0.5.0 -simplejson==3.16.0 -six==1.12.0 -soupsieve==1.8 -SQLAlchemy==1.3.1 -sqlparse==0.3.0 -stravalib==0.10.2 -termcolor==1.1.0 -terminado==0.8.1 -terminaltables==3.1.0 -testpath==0.4.2 -text-unidecode==1.2 -thrift==0.11.0 -timezonefinder==4.0.1 -toolz==0.10.0 -tornado==6.0.1 -tqdm==4.31.1 -traitlets==4.3.2 -units==0.7 -uritemplate==3.0.0 -urllib3==1.24.1 -VerbalExpressions==0.0.2 +serpent==1.27 +six==1.13.0 +soupsieve==1.9.5 +SQLAlchemy==1.3.12 +team==1.0 +terminado==0.8.3 +testpath==0.4.4 +tornado==6.0.3 +traitlets==4.3.3 +udiskie==2.0.2 +ufw==0.36 +urllib3==1.25.7 vine==1.3.0 -wcwidth==0.1.7 +virtualenv==16.1.0 +wcwidth==0.1.8 webencodings==0.5.1 -Werkzeug==0.15.1 -widgetsnbextension==3.4.2 +widgetsnbextension==3.5.1 +wrapt==1.11.2 xlrd==1.2.0 -xmltodict==0.12.0 -yamjam==0.1.7 -yamllint==1.15.0 -yuicompressor==2.4.8 +zipp==0.6.0 diff --git a/rowers/models.py b/rowers/models.py index d06ab70e..e412de4f 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2301,6 +2301,35 @@ class PlannedSessionForm(ModelForm): self.fields['sessiontype'].choices = regularsessiontypechoices +class PlannedSessionTemplateForm(ModelForm): + + class Meta: + model = PlannedSession + fields = [ + 'name', + 'sessiontype', + 'sessionmode', + 'criterium', + 'sessionvalue', + 'sessionunit', + 'course', + 'comment', + ] + + dateTimeOptions = { + 'format': 'yyyy-mm-dd', + 'autoclose': True, + } + + widgets = { + 'comment': forms.Textarea, + } + + def __init__(self,*args,**kwargs): + super(PlannedSessionTemplateForm, self).__init__(*args, **kwargs) + self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name") + self.fields['sessiontype'].choices = regularsessiontypechoices + def get_course_timezone(course): polygons = GeoPolygon.objects.filter(course = course) points = GeoPoint.objects.filter(polygon = polygons[0]) diff --git a/rowers/rower_rules.py b/rowers/rower_rules.py index df9892e6..9a890920 100644 --- a/rowers/rower_rules.py +++ b/rowers/rower_rules.py @@ -98,6 +98,10 @@ def can_start_plantrial(user): return user.rower.plantrialexpires == datetime.date(1970,1,1) +@rules.predicate +def is_staff(user): + return user.is_staff + @rules.predicate def is_coach(user): return user.rower.rowerplan in ['coach','freecoach'] @@ -302,7 +306,7 @@ def can_plan_user(user,rower): rules.add_perm('rower.add_plan',can_plan_user) # replaces checkaccessplanuser rules.add_perm('rower.is_coach',is_coach_user) # replaces checkaccessuser rules.add_perm('rower.is_pro',ispromember) -rules.add_perm('anonymous.is_coach',is_anonymous_or_coach) +rules.add_perm('rower.is_staff',is_staff) # WORKOUT permissions diff --git a/rowers/templates/menuscript.html b/rowers/templates/menuscript.html index 9ba9250f..16994896 100644 --- a/rowers/templates/menuscript.html +++ b/rowers/templates/menuscript.html @@ -33,3 +33,4 @@ }); }); + diff --git a/rowers/templates/plannedsessioncreate.html b/rowers/templates/plannedsessioncreate.html index 5c5f7ff1..38f29545 100644 --- a/rowers/templates/plannedsessioncreate.html +++ b/rowers/templates/plannedsessioncreate.html @@ -108,6 +108,7 @@ Name Value   + Edit Delete @@ -125,8 +126,11 @@ {{ ps.sessionvalue }} {{ ps.sessionunit }} + + Edit Template + - Delete + Delete {% endfor %} diff --git a/rowers/templates/plannedsessionteamcreate.html b/rowers/templates/plannedsessionteamcreate.html index 2cba5493..55dabe13 100644 --- a/rowers/templates/plannedsessionteamcreate.html +++ b/rowers/templates/plannedsessionteamcreate.html @@ -115,6 +115,7 @@ Name Value   + Edit Delete @@ -132,6 +133,9 @@ {{ ps.sessionvalue }} {{ ps.sessionunit }} + + Edit Template + Delete diff --git a/rowers/templates/plannedsessiontemplateedit.html b/rowers/templates/plannedsessiontemplateedit.html new file mode 100644 index 00000000..34dde816 --- /dev/null +++ b/rowers/templates/plannedsessiontemplateedit.html @@ -0,0 +1,197 @@ +{% extends "newbase.html" %} +{% load staticfiles %} +{% load rowerfilters %} + +{% block title %}Update Template Session{% endblock %} + +{% block main %} +

Edit Session Template

+ + + +
    +
  • +

    {{ thesession.name }}

    +
    + {% if form.errors %} +

    + Please correct the error{{ form.errors|pluralize }} below. +

    + {% endif %} +

    + + {{ form.as_table }} +
    +

    + {% csrf_token %} +
    + +
    +

    + Delete +

    + +
    + +
  • +
  • +

    Templates

    +

    + Click on session name to clone to current period +

    + + + + + + + + + + + + {% for ps in sessiontemplates %} + + + + + + + + {% endfor %} + +
    NameValue EditDelete
    + {% if ps.name != '' %} + {{ ps.name }} + {% else %} + Unnamed Session + {% endif %} + {{ ps.sessionvalue }} {{ ps.sessionunit }} + Edit Template + + Delete +
    +
  • +
+ +{% endblock %} + +{% block sidebar %} +{% include 'menu_plan.html' %} +{% endblock %} + + +{% block scripts %} + + + +{% endblock %} diff --git a/rowers/templates/plannedsessionview.html b/rowers/templates/plannedsessionview.html index a8d0ad65..e6e9666d 100644 --- a/rowers/templates/plannedsessionview.html +++ b/rowers/templates/plannedsessionview.html @@ -16,6 +16,8 @@

Edit Session + / + Save to template

{% endif %}

Session {{ psdict.name.1 }}

@@ -157,11 +159,11 @@
  • Course

    {{ coursediv|safe }} - + {{ coursescript|safe }}
  • {% endif %} - + diff --git a/rowers/tests/viewnames.csv b/rowers/tests/viewnames.csv index 1978647e..0d67bacc 100644 --- a/rowers/tests/viewnames.csv +++ b/rowers/tests/viewnames.csv @@ -1,312 +1,311 @@ -,id,view,function,anonymous,anonymous_response,own,own_response,own_nonperm,member,member_response,member_nonperm,coachee,coachee_response,coachee_nonperm,is_staff,userid,workoutid,dotest -0,0,workouts_summaries_email_view,sends summary excel with workouts list and links to data to user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,TRUE -1,1,rower_update_empower_view,updates old Empower Oarlock files (corrects Power bug),TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -2,2,agegroupcpview,needs age,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -3,4,ajax_agegrouprecords,gets age group records from C2 ,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -4,5,fitness_metric_view,updates a person's fitness metric,TRUE,302,basic,302,302,FALSE,403,302,FALSE,403,403,FALSE,FALSE,FALSE,TRUE -5,6,agegrouprecordview,shows ergo age group records,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -6,7,workouts_view,workouts list,TRUE,302,basic,200,302,basic,200,403,coach,200,403,FALSE,TRUE,FALSE,TRUE -7,8,virtualevents_view,virtual races list,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -8,9,virtualevent_create_view,create virtual event,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -9,10,indoorvirtualevent_create_view,create indoor virtual event,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -10,11,virtualevent_toggle_email_view,toggle email notifications,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -11,12,indoorvirtualevent_toggle_email_view,toggle email notifications,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -12,13,virtualevent_view,view virtual race,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -13,14,virtualevent_ranking_view,view ranking,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -14,15,virtualevent_edit_view,edit race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -15,16,indoorvirtualevent_edit_view,edit race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -16,17,virtualevent_register_view,register for race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -17,18,indoorvirtualevent_register_view,register for race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -18,19,virtualevent_addboat_view,add a new boat type,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -19,20,virtualevent_withdraw_view,withdraw,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -20,21,virtualevent_submit_result_view,submit a result,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,TRUE,FALSE -21,22,virtualevent_disqualify_view,disqualify a racer,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE -22,24,courses_view,see race courses,TRUE,200,FALSE,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -23,25,course_upload_view,upload a new course,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE -24,26,addmanual_view,upload a manual workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,TRUE -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 -26,28,workouts_join_view,join workouts,TRUE,302,pro,302,302,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,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 -28,30,user_boxplot_select,select boxplots,TRUE,302,pro,200,302,pro,403,403,coach,200,302,FALSE,TRUE,FALSE,TRUE -29,31,analysis_new,front page for analysis section,TRUE,200,basic,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,TRUE -30,32,user_multiflex_select,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -31,33,session_jobs_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -32,34,session_jobs_status,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -33,35,kill_async_job,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -34,36,post_progress,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -35,37,graphs_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -36,38,fitnessmetric_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -37,39,rankings_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -38,40,rankings_view2,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -39,41,otwrankings_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -40,42,oterankings_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -41,43,cum_flex,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -42,44,analysis_view_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -43,47,cum_flex_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -44,48,histo,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -45,49,histo_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -46,51,cumstats,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -47,53,graph_show_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -48,54,GraphDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -49,55,get_thumbnails,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -50,56,otw_use_impeller,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -51,57,otw_use_gps,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -52,58,workout_toggle_ranking,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -53,59,team_workout_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -54,60,workout_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -55,61,workout_histo_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -56,62,workout_forcecurve_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -57,63,workout_unsubscribe_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -58,64,workout_comment_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -59,65,workout_tcxemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -60,66,workout_gpxemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -61,67,workout_csvemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -62,68,workout_csvtoadmin_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -63,69,workout_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -64,70,workout_map_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -65,71,workout_update_cp_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -66,72,instroke_chart,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -67,73,instroke_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -68,74,workout_stats_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -69,75,workout_data_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -70,76,workout_otwsetpower_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -71,77,workout_otwpowerplot_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -72,78,workout_wind_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -73,79,workout_uploadimage_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -74,80,virtualevent_compare_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -75,81,virtualevent_uploadimage_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -76,82,virtualevent_setlogo_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -77,83,logo_delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -78,84,workout_downloadwind_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -79,85,workout_downloadmetar_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -80,86,workout_stream_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -81,87,workout_summary_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -82,88,workout_summary_restore_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -83,89,workout_split_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -84,90,workout_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -85,91,workout_video_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -86,92,VideoDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -87,93,workout_video_view_mini,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -88,94,workout_video_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -89,95,list_videos,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -90,96,video_selectworkout,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -91,98,workout_fusion_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -92,99,workout_fusion_list,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -93,100,TemplateView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -94,103,workout_add_chart_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -95,112,WorkoutDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -96,113,workout_smoothenpace_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -97,114,workout_undo_smoothenpace_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -98,115,workout_c2import_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -99,120,workout_stravaimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -100,122,workout_getc2workout_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -101,124,workout_getimportview,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -102,125,workout_getstravaworkout_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -103,126,workout_getstravaworkout_next,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -104,127,workout_sporttracksimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -105,129,workout_getsporttracksworkout_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -106,130,workout_polarimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -107,132,workout_runkeeperimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -108,134,workout_underarmourimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -109,135,workout_c2_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -110,136,workout_strava_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -111,137,workout_recalcsummary_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -112,138,workout_sporttracks_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -113,139,workout_runkeeper_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -114,140,workout_underarmour_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -115,141,workout_tp_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -116,142,multi_compare_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -117,145,alerts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -118,147,AlertDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -119,148,alert_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -120,150,alert_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -121,152,alert_report_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -122,155,boxplot_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -123,157,boxplot_view_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -124,158,multiflex_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -125,160,multiflex_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -126,161,deactivate_user,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -127,162,remove_user,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -128,163,user_gdpr_confirm,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -129,165,user_gdpr_optin,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -130,167,rower_teams_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -131,168,rower_calcdps_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -132,169,rower_exportsettings_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -133,171,team_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -134,172,team_members_stats_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -135,173,team_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -136,174,team_leaveconfirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -137,175,team_leave_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -138,176,team_deleteconfirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -139,177,team_requestmembership_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -140,178,reject_revoke_coach_request,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -141,179,coach_drop_athlete_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -142,180,coach_drop_athlete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -143,181,athlete_drop_coach_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -144,182,athlete_drop_coach_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -145,184,reject_revoke_coach_offer,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -146,186,request_coaching_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -147,187,offer_coaching_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -148,188,coach_accept_coachrequest_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -149,189,rower_accept_coachoffer_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -150,190,team_delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -151,191,team_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -152,192,manager_member_drop_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -153,193,invitation_reject_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -154,194,invitation_revoke_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -155,195,rower_invitations_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -156,196,raise_500,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -157,198,request_revoke_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -158,199,request_reject_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -159,200,manager_requests_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -160,202,rower_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -161,204,rower_prefs_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -162,205,transactions_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -163,208,rower_c2_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -164,209,rower_polar_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -165,210,rower_revokeapp_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -166,211,rower_strava_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -167,212,rower_sporttracks_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -168,213,rower_underarmour_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -169,214,rower_tp_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -170,215,rower_runkeeper_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -171,216,rower_sporttracks_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -172,217,rower_underarmour_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -173,218,rower_tp_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -174,219,rower_c2_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -175,220,rower_favoritecharts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -176,222,workout_workflow_config2_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -177,224,workflow_default_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -178,225,sendmail,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -179,231,analysis_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -180,232,laboratory_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -181,233,errormessage_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -182,237,payment_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -183,238,upgrade_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -184,240,downgrade_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -185,241,billing_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -186,242,upgrade_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -187,243,downgrade_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -188,244,payment_completed_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -189,245,downgrade_completed_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -190,246,paidplans_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -191,247,plan_stop_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -192,248,plan_tobasic_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -193,249,checkouts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -194,250,upgrade_checkouts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -195,251,downgrade_checkouts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -196,252,planrequired_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -197,253,start_trial_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -198,254,start_plantrial_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -199,256,rower_register_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -200,257,freecoach_register_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -201,259,workout_workflow_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -202,260,workout_flexchart3_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -203,264,rower_process_testcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -204,265,rower_create_trainingplan,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -205,267,TrainingPlanDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -206,268,MicroCycleDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -207,269,MesoCycleDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -208,270,MacroCycleDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -209,271,rower_trainingplan_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -210,279,rower_trainingplan_execution_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -211,281,TrainingMacroCycleUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -212,282,TrainingMesoCycleUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -213,283,planmacrocyclebymonth,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -214,285,planmesocyclebyweek,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -215,287,TrainingMicroCycleUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -216,288,rower_delete_trainingtarget,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -217,289,TrainingPlanUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -218,290,TrainingTargetUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -219,291,strokedataform,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -220,292,plannedsession_teamcreate_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -221,296,plannedsession_teamedit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -222,298,plannedsession_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -223,300,plannedsession_multiclone_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -224,302,plannedsession_multicreate_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -225,305,plannedsession_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -226,306,plannedsession_totemplate_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -227,307,plannedsession_compare_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -228,310,plannedsession_clone_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -229,311,plannedsession_teamclone_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -230,313,plannedsession_detach_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -231,315,plannedsession_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -232,317,PlannedSessionDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -233,319,plannedsessions_manage_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -234,323,plannedsessions_coach_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -235,325,plannedsessions_coach_icsemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -236,326,plannedsessions_print_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -237,327,plannedsession_comment_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -238,330,plannedsessions_icsemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -239,332,plannedsessions_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE -240,334,course_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -241,335,course_delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -242,336,course_kmldownload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -243,337,course_replace_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -244,338,course_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -245,339,course_map_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -246,341,c2listdebug_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -247,343,rower_process_callback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -248,344,rower_process_stravacallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -249,345,rower_process_sporttrackscallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -250,346,rower_process_underarmourcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -251,347,rower_process_polarcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -252,348,rower_process_runkeepercallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -253,349,rower_process_tpcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -254,350,rower_process_twittercallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -255,351,set_language,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -256,352,SetOffsetView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -257,353,stats,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -258,354,stats_json,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -259,355,jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -260,356,workers,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -261,357,worker_details,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -262,358,finished_jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -263,359,started_jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -264,360,deferred_jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -265,361,clear_queue,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -266,362,requeue_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -267,363,job_detail,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -268,364,delete_job,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -269,365,actions,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -270,366,requeue_job_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -271,367,enqueue_job,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -272,368,JavaScriptCatalog,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -273,369,serve,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -274,371,LoginView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -275,372,LogoutView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -276,373,PasswordChangeView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -277,374,PasswordChangeDoneView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -278,375,PasswordResetView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -279,376,PasswordResetDoneView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -280,377,PasswordResetConfirmView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -281,378,PasswordResetCompleteView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -282,386,index,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -283,387,login,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -284,388,logout,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -285,389,password_change,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -286,390,password_change_done,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -287,391,i18n_javascript,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -288,392,shortcut,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -289,393,changelist_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -290,394,add_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -291,395,autocomplete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -292,396,history_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -293,397,delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -294,398,change_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -295,399,RedirectView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -296,568,app_index,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -297,571,landingview,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -298,573,get_blog_posts,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -299,576,AuthorizationView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -300,577,TokenView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -301,578,WorkoutViewSet,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -302,582,RowerViewSet,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -303,586,FavoriteChartViewSet,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -304,590,APIRootView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -305,592,SwaggerSchemaView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -306,595,strokedatajson,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE -307,596,error500_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -308,603,failed_queue_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -309,604,failed_queue_empty,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE -310,605,failed_job_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE +,id,view,function,anonymous,anonymous_response,own,own_response,own_nonperm,member,member_response,member_nonperm,coachee,coachee_response,coachee_nonperm,is_staff,userid,workoutid,dotest,realtest +0,0,workouts_summaries_email_view,sends summary excel with workouts list and links to data to user,TRUE,302,basic,200,302,FALSE,403,403,FALSE,403,403,FALSE,FALSE,FALSE,FALSE,TRUE +1,1,rower_update_empower_view,updates old Empower Oarlock files (corrects Power bug),TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +2,2,agegroupcpview,needs age,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +3,4,ajax_agegrouprecords,gets age group records from C2 ,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +4,5,fitness_metric_view,updates a person's fitness metric,TRUE,302,basic,302,302,FALSE,403,302,FALSE,403,403,FALSE,FALSE,FALSE,FALSE,TRUE +5,6,agegrouprecordview,shows ergo age group records,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +6,7,workouts_view,workouts list,TRUE,302,basic,200,302,basic,200,403,coach,200,403,FALSE,TRUE,FALSE,FALSE,TRUE +7,8,virtualevents_view,virtual races list,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +8,9,virtualevent_create_view,create virtual event,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +9,10,indoorvirtualevent_create_view,create indoor virtual event,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +10,11,virtualevent_toggle_email_view,toggle email notifications,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +11,12,indoorvirtualevent_toggle_email_view,toggle email notifications,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +12,13,virtualevent_view,view virtual race,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +13,14,virtualevent_ranking_view,view ranking,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +14,15,virtualevent_edit_view,edit race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +15,16,indoorvirtualevent_edit_view,edit race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +16,17,virtualevent_register_view,register for race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +17,18,indoorvirtualevent_register_view,register for race,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +18,19,virtualevent_addboat_view,add a new boat type,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +19,20,virtualevent_withdraw_view,withdraw,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +20,21,virtualevent_submit_result_view,submit a result,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +21,22,virtualevent_disqualify_view,disqualify a racer,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +22,24,courses_view,see race courses,TRUE,200,FALSE,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +23,25,course_upload_view,upload a new course,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +24,26,addmanual_view,upload a manual workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +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,FALSE,TRUE +26,28,workouts_join_view,join workouts,TRUE,302,pro,302,302,pro,403,403,coach,302,403,FALSE,TRUE,FALSE,FALSE,TRUE +27,29,workouts_join_select,select workouts to join,TRUE,404,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,FALSE,TRUE +28,30,user_boxplot_select,select boxplots,TRUE,302,pro,200,302,pro,403,403,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +29,31,analysis_new,analysis front page,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +30,32,user_multiflex_select,select multiflex data,TRUE,302,pro,200,302,FALSE,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +31,33,session_jobs_view,view jobs,TRUE,302,basic,200,302,FALSE,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +32,34,session_jobs_status,view jobs,TRUE,302,basic,200,302,FALSE,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +33,35,kill_async_job,kill job,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +34,36,post_progress,post progress,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +35,37,graphs_view,view charts,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +36,38,fitnessmetric_view,view fitness metric,TRUE,302,plan,200,302,plan,403,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +37,39,rankings_view,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +38,40,rankings_view2,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +39,41,otwrankings_view,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +40,42,oterankings_view,view ranking,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +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,302,302,pro,302,302,coach,302,302,FALSE,FALSE,FALSE,FALSE,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,FALSE,TRUE +45,49,histo_data,histogram data,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +46,51,cumstats,cumulative statistics,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,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,FALSE,TRUE +50,56,otw_use_impeller,switch to impeller data,TRUE,403,basic,302,302,basic,403,302,coach,302,302,FALSE,FALSE,TRUE,FALSE,TRUE +51,57,otw_use_gps,switch to GPS data,TRUE,403,basic,302,302,basic,403,302,coach,302,302,FALSE,FALSE,TRUE,FALSE,TRUE +52,58,workout_toggle_ranking,toggle ranking,TRUE,302,basic,302,302,basic,403,302,coach,302,302,FALSE,FALSE,TRUE,FALSE,TRUE +53,59,team_workout_upload_view,upload workout for team member,TRUE,302,coach,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +54,60,workout_upload_view,upload a workout,TRUE,302,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +55,61,workout_histo_view,histogram ,TRUE,302,basic,200,302,basic,403,403,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +56,62,workout_forcecurve_view,force curve,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +57,63,workout_unsubscribe_view,unsubscribe from comments,TRUE,302,basic,200,302,basic,200,302,basic,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +58,64,workout_comment_view,comment on workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +59,65,workout_tcxemail_view,download TCX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +60,66,workout_gpxemail_view,download GPX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +61,67,workout_csvemail_view,download CSV file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +62,68,workout_csvtoadmin_view,send CSV to admin,TRUE,403,basic,200,200,basic,200,200,coach,200,200,TRUE,FALSE,TRUE,FALSE,TRUE +63,69,workout_edit_view,Edit Workout,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +64,70,workout_map_view,View workout Map,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +65,71,workout_update_cp_view,Update CP data based on new workout,TRUE,403,pro,302,302,pro,403,403,coach,302,302,FALSE,FALSE,TRUE,FALSE,TRUE +66,72,instroke_chart,View In-Stroke data chart,TRUE,302,pro,302,302,pro,403,403,coach,302,302,FALSE,FALSE,FALSE,FALSE,FALSE +67,73,instroke_view,Create in stroke chart,TRUE,403,basic,200,302,basic,403,403,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +68,74,workout_stats_view,View Workout Stats,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +69,75,workout_data_view,shows the detailed data for a workout,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +70,76,workout_otwsetpower_view,set weight and start offline OTW power calculations,TRUE,403,pro,200,302,pro,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +71,77,workout_otwpowerplot_view,generates OTW power chart,TRUE,200,basic,200,200,basic,200,200,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +72,78,workout_wind_view,set wind,TRUE,403,pro,200,302,pro,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +73,79,workout_uploadimage_view,upload image,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +74,80,virtualevent_compare_view,compare workouts from a virtual event,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +75,81,virtualevent_uploadimage_view,upload image to virtual event,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +76,82,virtualevent_setlogo_view,set logo of virtual event,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +77,83,logo_delete_view,delete logo,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +78,84,workout_downloadwind_view,download Wind,TRUE,403,pro,302,302,pro,403,403,coach,302,403,FALSE,FALSE,TRUE,FALSE,FALSE +79,85,workout_downloadmetar_view,download METAR,TRUE,403,pro,200,302,pro,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,FALSE +80,86,workout_stream_view,edit stream (redirects as no data in test suite),TRUE,403,pro,200,302,pro,403,403,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +81,87,workout_summary_edit_view,edit workout summary,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +82,88,workout_summary_restore_view,restore workout summary,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,FALSE,TRUE +83,89,workout_split_view,split workout,TRUE,403,pro,200,302,pro,403,403,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +84,90,workout_view,view workout ,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +85,91,workout_video_create_view,add video ,TRUE,403,pro,200,302,pro,403,403,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +86,92,VideoDelete,delete video,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +87,93,workout_video_view_mini,minimal view,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +88,94,workout_video_view,"video view (not tested, no video in test suite)",TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +89,95,list_videos,list my videos,TRUE,302,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,TRUE +90,96,video_selectworkout,select workout to create video,TRUE,302,pro,200,302,pro,403,403,coach,200,302,FALSE,TRUE,FALSE,FALSE,TRUE +91,98,workout_fusion_view,needs to workouts,TRUE,403,pro,200,302,pro,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +92,99,workout_fusion_list,list workouts to fuse with,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE +94,103,workout_add_chart_view,add chart,TRUE,403,basic,302,403,basic,403,403,coach,302,403,FALSE,FALSE,TRUE,TRUE,FALSE +95,112,WorkoutDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +96,113,workout_smoothenpace_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +97,114,workout_undo_smoothenpace_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +98,115,workout_c2import_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +99,120,workout_stravaimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +100,122,workout_getc2workout_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +101,124,workout_getimportview,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +102,125,workout_getstravaworkout_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +103,126,workout_getstravaworkout_next,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +104,127,workout_sporttracksimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +105,129,workout_getsporttracksworkout_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +106,130,workout_polarimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +107,132,workout_runkeeperimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +108,134,workout_underarmourimport_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +109,135,workout_c2_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +110,136,workout_strava_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +111,137,workout_recalcsummary_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +112,138,workout_sporttracks_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +113,139,workout_runkeeper_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +114,140,workout_underarmour_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +115,141,workout_tp_upload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +116,142,multi_compare_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +117,145,alerts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +118,147,AlertDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +119,148,alert_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +120,150,alert_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +121,152,alert_report_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +122,155,boxplot_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +123,157,boxplot_view_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +124,158,multiflex_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +125,160,multiflex_data,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +126,161,deactivate_user,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +127,162,remove_user,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +128,163,user_gdpr_confirm,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +129,165,user_gdpr_optin,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +130,167,rower_teams_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +131,168,rower_calcdps_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +132,169,rower_exportsettings_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +133,171,team_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +134,172,team_members_stats_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +135,173,team_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +136,174,team_leaveconfirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +137,175,team_leave_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +138,176,team_deleteconfirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +139,177,team_requestmembership_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +140,178,reject_revoke_coach_request,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +141,179,coach_drop_athlete_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +142,180,coach_drop_athlete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +143,181,athlete_drop_coach_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +144,182,athlete_drop_coach_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +145,184,reject_revoke_coach_offer,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +146,186,request_coaching_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +147,187,offer_coaching_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +148,188,coach_accept_coachrequest_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +149,189,rower_accept_coachoffer_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +150,190,team_delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +151,191,team_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +152,192,manager_member_drop_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +153,193,invitation_reject_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +154,194,invitation_revoke_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +155,195,rower_invitations_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +156,196,raise_500,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +157,198,request_revoke_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +158,199,request_reject_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +159,200,manager_requests_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +160,202,rower_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +161,204,rower_prefs_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +162,205,transactions_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +163,208,rower_c2_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +164,209,rower_polar_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +165,210,rower_revokeapp_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +166,211,rower_strava_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +167,212,rower_sporttracks_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +168,213,rower_underarmour_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +169,214,rower_tp_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +170,215,rower_runkeeper_authorize,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +171,216,rower_sporttracks_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +172,217,rower_underarmour_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +173,218,rower_tp_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +174,219,rower_c2_token_refresh,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +175,220,rower_favoritecharts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +176,222,workout_workflow_config2_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +177,224,workflow_default_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +178,225,sendmail,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +179,231,analysis_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +180,232,laboratory_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +181,233,errormessage_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +182,237,payment_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +183,238,upgrade_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +184,240,downgrade_confirm_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +185,241,billing_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +186,242,upgrade_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +187,243,downgrade_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +188,244,payment_completed_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +189,245,downgrade_completed_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +190,246,paidplans_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +191,247,plan_stop_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +192,248,plan_tobasic_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +193,249,checkouts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +194,250,upgrade_checkouts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +195,251,downgrade_checkouts_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +196,252,planrequired_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +197,253,start_trial_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +198,254,start_plantrial_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +199,256,rower_register_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +200,257,freecoach_register_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +201,259,workout_workflow_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +202,260,workout_flexchart3_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +203,264,rower_process_testcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +204,265,rower_create_trainingplan,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +205,267,TrainingPlanDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +206,268,MicroCycleDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +207,269,MesoCycleDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +208,270,MacroCycleDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +209,271,rower_trainingplan_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +210,279,rower_trainingplan_execution_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +211,281,TrainingMacroCycleUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +212,282,TrainingMesoCycleUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +213,283,planmacrocyclebymonth,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +214,285,planmesocyclebyweek,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +215,287,TrainingMicroCycleUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +216,288,rower_delete_trainingtarget,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +217,289,TrainingPlanUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +218,290,TrainingTargetUpdate,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +219,291,strokedataform,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +220,292,plannedsession_teamcreate_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +221,296,plannedsession_teamedit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +222,298,plannedsession_create_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +223,300,plannedsession_multiclone_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +224,302,plannedsession_multicreate_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +225,305,plannedsession_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +226,306,plannedsession_totemplate_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +227,307,plannedsession_compare_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +228,310,plannedsession_clone_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +229,311,plannedsession_teamclone_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +230,313,plannedsession_detach_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +231,315,plannedsession_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +232,317,PlannedSessionDelete,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +233,319,plannedsessions_manage_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +234,323,plannedsessions_coach_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +235,325,plannedsessions_coach_icsemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +236,326,plannedsessions_print_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +237,327,plannedsession_comment_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +238,330,plannedsessions_icsemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +239,332,plannedsessions_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,TRUE,FALSE,FALSE,FALSE +240,334,course_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +241,335,course_delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +242,336,course_kmldownload_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +243,337,course_replace_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +244,338,course_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +245,339,course_map_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +246,341,c2listdebug_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +247,343,rower_process_callback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +248,344,rower_process_stravacallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +249,345,rower_process_sporttrackscallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +250,346,rower_process_underarmourcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +251,347,rower_process_polarcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +252,348,rower_process_runkeepercallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +253,349,rower_process_tpcallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +254,350,rower_process_twittercallback,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +255,351,set_language,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +256,352,SetOffsetView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +257,353,stats,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +258,354,stats_json,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +259,355,jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +260,356,workers,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +261,357,worker_details,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +262,358,finished_jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +263,359,started_jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +264,360,deferred_jobs,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +265,361,clear_queue,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +266,362,requeue_all,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +267,363,job_detail,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +268,364,delete_job,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +269,365,actions,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +270,366,requeue_job_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +271,367,enqueue_job,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +272,368,JavaScriptCatalog,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +273,369,serve,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +274,371,LoginView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +275,372,LogoutView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +276,373,PasswordChangeView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +277,374,PasswordChangeDoneView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +278,375,PasswordResetView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +279,376,PasswordResetDoneView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +280,377,PasswordResetConfirmView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +281,378,PasswordResetCompleteView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +282,386,index,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +283,387,login,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +284,388,logout,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +285,389,password_change,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +286,390,password_change_done,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +287,391,i18n_javascript,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +288,392,shortcut,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +289,393,changelist_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +290,394,add_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +291,395,autocomplete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +292,396,history_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +293,397,delete_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +294,398,change_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +295,399,RedirectView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +296,568,app_index,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +297,571,landingview,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +298,573,get_blog_posts,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +299,576,AuthorizationView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +300,577,TokenView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +301,578,WorkoutViewSet,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +302,582,RowerViewSet,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +303,586,FavoriteChartViewSet,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +304,590,APIRootView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +305,592,SwaggerSchemaView,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +306,595,strokedatajson,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +307,596,error500_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +308,603,failed_queue_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +309,604,failed_queue_empty,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE +310,605,failed_job_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE diff --git a/rowers/urls.py b/rowers/urls.py index dbae602e..d07c68e9 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -246,26 +246,27 @@ urlpatterns = [ re_path(r'^record-progress/(?P.*)/$',views.post_progress), re_path(r'^record-progress/$',views.post_progress), re_path(r'^list-graphs/$',views.graphs_view,name='graphs_view'), + re_path(r'^list-graphs/user/(?P\d+)/$',views.graphs_view,name='graphs_view'), re_path(r'^fitness-progress/$',views.fitnessmetric_view,name='fitnessmetric_view'), - re_path(r'^fitness-progress/user/(?P\d+)/$',views.fitnessmetric_view,name='fitnessmetric_view'), - re_path(r'^fitness-progress/user/(?P\d+)/(?P\w+.*)/$',views.fitnessmetric_view,name='fitnessmetric_view'), + re_path(r'^fitness-progress/user/(?P\d+)/$',views.fitnessmetric_view,name='fitnessmetric_view'), + re_path(r'^fitness-progress/user/(?P\d+)/(?P\w+.*)/$',views.fitnessmetric_view,name='fitnessmetric_view'), # re_path(r'^ote-bests/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'), - re_path(r'^ote-bests/user/(?P\d+)/$',views.rankings_view,name='rankings_view'), + re_path(r'^ote-bests/user/(?P\d+)/$',views.rankings_view,name='rankings_view'), # re_path(r'^ote-bests/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'), re_path(r'^ote-bests/$',views.rankings_view,name='rankings_view'), - re_path(r'^(?P\d+)/ote-bests/$',views.rankings_view,name='rankings_view'), + re_path(r'^(?P\d+)/ote-bests/$',views.rankings_view,name='rankings_view'), # re_path(r'^(?P\d+)/ote-bests2/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'), - re_path(r'^ote-bests2/user/(?P\d+)/$',views.rankings_view2,name='rankings_view2'), + re_path(r'^ote-bests2/user/(?P\d+)/$',views.rankings_view2,name='rankings_view2'), # re_path(r'^ote-bests2/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'), re_path(r'^ote-bests2/$',views.rankings_view2,name='rankings_view2'), # re_path(r'^otw-bests/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'), # re_path(r'^otw-bests/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'), - re_path(r'^otw-bests/user/(?P\d+)/$',views.otwrankings_view,name='otwrankings_view'), + re_path(r'^otw-bests/user/(?P\d+)/$',views.otwrankings_view,name='otwrankings_view'), re_path(r'^otw-bests/$',views.otwrankings_view,name='otwrankings_view'), # re_path(r'^ote-ranking/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'), # re_path(r'^ote-ranking/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'), re_path(r'^ote-ranking/$',views.oterankings_view,name='oterankings_view'), - re_path(r'^ote-ranking/user/(?P\d+)/$',views.oterankings_view,name='oterankings_view'), + re_path(r'^ote-ranking/user/(?P\d+)/$',views.oterankings_view,name='oterankings_view'), # re_path(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.cum_flex,name='cum_flex'), # re_path(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.cum_flex,name='cum_flex'), re_path(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/$',views.cum_flex,name='cum_flex'), @@ -273,7 +274,7 @@ urlpatterns = [ 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'^histo/user/(?P\d+)/$',views.histo,name='histo'), re_path(r'^histodata/$',views.histo_data,name='histo_data'), # re_path(r'^histo/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.histo,name='histo'), re_path(r'^histo/$',views.histo,name='histo'), @@ -356,6 +357,7 @@ urlpatterns = [ re_path(r'^video/(?P\w.+)/$',views.workout_video_view, name='workout_video_view'), re_path(r'^videos/',views.list_videos,name='list_videos'), + re_path(r'^add-video/user/(?P\d+)/$',views.video_selectworkout,name='video_selectworkout'), re_path(r'^add-video/',views.video_selectworkout,name='video_selectworkout'), # re_path(r'^workout/(?P\d+)/$',views.workout_view,name='workout_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/$',views.workout_view,name='workout_view'), @@ -450,7 +452,7 @@ urlpatterns = [ 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'), + re_path(r'^survey/$',views.survey,name='survey'), re_path(r'^me/gdpr-optin-confirm/?/$',views.user_gdpr_confirm,name='user_gdpr_confirm'), re_path(r'^me/gdpr-optin-confirm/$',views.user_gdpr_confirm,name='user_gdpr_confirm'), re_path(r'^me/gdpr-optin/?/$',views.user_gdpr_optin,name='user_gdpr_optin'), @@ -667,6 +669,7 @@ urlpatterns = [ views.plannedsession_multicreate_view, name='plannedsession_multicreate_view'), re_path(r'^sessions/(?P\d+)/edit/$',views.plannedsession_edit_view), + re_path(r'^sessions/(?P\d+)/templateedit/',views.plannedsession_templateedit_view), re_path(r'^sessions/(?P\d+)/maketemplate/$',views.plannedsession_totemplate_view), re_path(r'^sessions/(?P\d+)/compare/$', views.plannedsession_compare_view, diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index be1190da..67392db8 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -730,7 +730,7 @@ def analysis_view_data(request,userid=0): 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,theuser=0, +def histo(request,userid=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), deltadays=-1, @@ -744,7 +744,7 @@ def histo(request,theuser=0, 'histoparam':'power' }): - r = getrequestrower(request,userid=theuser) + r = getrequestrower(request,userid=userid) theuser = r.user if 'histoparam' in request.session: @@ -1335,13 +1335,13 @@ def planrequired_view(request): @user_passes_test(isplanmember,login_url="/rowers/paidplans", message="This functionality requires a Coach or Self-Coach plan", redirect_field_name=None) -@permission_required('rower.is_coach',fn=get_user_by_id,raise_exception=True) -def fitnessmetric_view(request,id=0,mode='rower', +@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) +def fitnessmetric_view(request,userid=0,mode='rower', startdate=timezone.now()-timezone.timedelta(days=365), enddate=timezone.now()): - therower = getrequestrower(request,userid=id) + therower = getrequestrower(request,userid=userid) theuser = therower.user @@ -1391,7 +1391,8 @@ def fitnessmetric_view(request,id=0,mode='rower', # Show ranking distances including predicted paces @login_required() -def rankings_view(request,theuser=0, +@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) +def rankings_view(request,userid=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), deltadays=-1, @@ -1412,25 +1413,25 @@ def rankings_view(request,theuser=0, enddate = startdate startdate = s - if theuser == 0: - theuser = request.user.id + promember=0 - if not request.user.is_anonymous: - r = getrower(request.user) - if r.birthdate: - age = calculate_age(r.birthdate) - worldclasspower = int(metrics.getagegrouprecord( - age, - sex=r.sex, - weightcategory=r.weightcategory, - )) - else: - worldclasspower = None + r = getrequestrower(request,userid=userid) + theuser = r.user.id - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 + if r.birthdate: + age = calculate_age(r.birthdate) + worldclasspower = int(c2stuff.getagegrouprecord( + age, + sex=r.sex, + weightcategory=r.weightcategory, + )) + else: + worldclasspower = None + + result = request.user.is_authenticated and ispromember(request.user) + if result: + promember=1 # get all indoor rows in date range @@ -1741,7 +1742,8 @@ def ajax_agegrouprecords(request, # Show ranking distances including predicted paces @login_required() -def rankings_view2(request,theuser=0, +@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) +def rankings_view2(request,userid=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), deltadays=-1, @@ -1762,83 +1764,84 @@ def rankings_view2(request,theuser=0, enddate = startdate startdate = s - if theuser == 0: - theuser = request.user.id + if userid == 0: + userid = request.user.id else: lastupdated = "01-01-1900" promember=0 - if not request.user.is_anonymous: - r = getrower(request.user) + r = getrequestrower(request,userid=userid) + theuser = r.user + + wcdurations = [] + wcpower = [] + + lastupdated = "01-01-1900" + userid = 0 + if 'options' in request.session: + options = request.session['options'] + try: + wcdurations = options['wcdurations'] + wcpower = options['wcpower'] + lastupdated = options['lastupdated'] + except KeyError: + pass + try: + userid = options['userid'] + except KeyError: + userid = 0 + else: + options = {} + + + + lastupdatedtime = arrow.get(lastupdated).timestamp + current_time = arrow.utcnow().timestamp + + deltatime_seconds = current_time - lastupdatedtime + recalc = False + if str(userid) != str(theuser) or deltatime_seconds > 3600: + recalc = True + options['lastupdated'] = arrow.utcnow().isoformat() + else: + recalc = False + + options['userid'] = theuser.id + + if r.birthdate: + age = calculate_age(r.birthdate) + else: + worldclasspower = None + age = 0 + + agerecords = CalcAgePerformance.objects.filter( + age = age, + sex = r.sex, + weightcategory = r.weightcategory) + + if len(agerecords) == 0: + recalc = True + wcpower = [] + wcduration = [] + else: wcdurations = [] wcpower = [] + for record in agerecords: + wcdurations.append(record.duration) + wcpower.append(record.power) - lastupdated = "01-01-1900" - userid = 0 - if 'options' in request.session: - options = request.session['options'] - try: - wcdurations = options['wcdurations'] - wcpower = options['wcpower'] - lastupdated = options['lastupdated'] - except KeyError: - pass - try: - userid = options['userid'] - except KeyError: - userid = 0 - else: - options = {} + options['wcpower'] = wcpower + options['wcdurations'] = wcdurations + if theuser: + options['userid'] = theuser.id + + request.session['options'] = options - - lastupdatedtime = arrow.get(lastupdated).timestamp - current_time = arrow.utcnow().timestamp - - deltatime_seconds = current_time - lastupdatedtime - recalc = False - if str(userid) != str(theuser) or deltatime_seconds > 3600: - recalc = True - options['lastupdated'] = arrow.utcnow().isoformat() - else: - recalc = False - - options['userid'] = theuser - - if r.birthdate: - age = calculate_age(r.birthdate) - else: - worldclasspower = None - age = 0 - - agerecords = CalcAgePerformance.objects.filter( - age = age, - sex = r.sex, - weightcategory = r.weightcategory) - - if len(agerecords) == 0: - recalc = True - wcpower = [] - wcduration = [] - else: - wcdurations = [] - wcpower = [] - for record in agerecords: - wcdurations.append(record.duration) - wcpower.append(record.power) - - options['wcpower'] = wcpower - options['wcdurations'] = wcdurations - if theuser: - options['userid'] = theuser - - request.session['options'] = options - - - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 + result = request.user.is_authenticated and ispromember(request.user) + if result: + promember=1 # get all indoor rows in date range @@ -1887,10 +1890,7 @@ def rankings_view2(request,theuser=0, r=0 - try: - uu = User.objects.get(id=theuser) - except User.DoesNotExist: - uu = '' + uu = theuser # test to fix bug @@ -2155,7 +2155,7 @@ def rankings_view2(request,theuser=0, 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 otwrankings_view(request,theuser=0, +def otwrankings_view(request,userid=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), startdatestring="", @@ -2178,22 +2178,10 @@ def otwrankings_view(request,theuser=0, enddate = startdate startdate = s - if theuser == 0: - if 'rowerid' in request.session: - try: - r = Rower.objects.get(id=request.session['rowerid']) - theuser = r.user.id - except Rower.DoesNotExist: - theuser = request.user.id - else: - theuser = request.user.id + r = getrequestrower(request,userid=userid) + promember = True - promember=0 - if not request.user.is_anonymous: - r = Rower.objects.get(user=request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 + theuser = r.user # get all OTW rows in date range @@ -2247,10 +2235,7 @@ def otwrankings_view(request,theuser=0, - try: - uu = User.objects.get(id=theuser) - except User.DoesNotExist: - uu = '' + uu = theuser # test to fix bug @@ -2561,7 +2546,7 @@ def otwcp_toadmin_view(request,theuser=0, 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 oterankings_view(request,theuser=0, +def oterankings_view(request,userid=0, startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now(), startdatestring="", @@ -2584,23 +2569,11 @@ def oterankings_view(request,theuser=0, enddate = startdate startdate = s - if theuser == 0: - if 'rowerid' in request.session: - try: - r = Rower.objects.get(id=request.session['rowerid']) - theuser = r.user.id - except Rower.DoesNotExist: - theuser = request.user.id - else: - theuser = request.user.id + r = getrequestrower(request,userid=userid) + theuser = r.user promember=0 - if not request.user.is_anonymous: - r = Rower.objects.get(user=request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 # get all OTW rows in date range @@ -2674,10 +2647,8 @@ def oterankings_view(request,theuser=0, raise Http404("Rower doesn't exist") - try: - uu = User.objects.get(id=theuser) - except User.DoesNotExist: - uu = '' + uu = theuser + # test to fix bug diff --git a/rowers/views/exportviews.py b/rowers/views/exportviews.py index afdfc7c9..b415696a 100644 --- a/rowers/views/exportviews.py +++ b/rowers/views/exportviews.py @@ -261,6 +261,7 @@ def workout_csvemail_view(request,id=0): # Get Workout CSV file and send it to user's email address @login_required() +@permission_required('rower.is_staff',fn=get_user_by_userid,raise_exception=True) def workout_csvtoadmin_view(request,id=0): message = "" r = getrower(request.user) diff --git a/rowers/views/paymentviews.py b/rowers/views/paymentviews.py index 34a1f133..344f84ac 100644 --- a/rowers/views/paymentviews.py +++ b/rowers/views/paymentviews.py @@ -13,8 +13,8 @@ def paidplans_view(request): else: r = None - - + + return render(request, 'paidplans.html', {'rower':r}) @@ -24,7 +24,7 @@ def billing_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': @@ -42,7 +42,7 @@ def billing_view(request): for attr, value in cd.items(): setattr(r, attr, value) r.save() - + if billingaddressform.is_valid(): if planselectform.is_valid(): plan = planselectform.cleaned_data['plan'] @@ -58,7 +58,7 @@ def billing_view(request): }) return HttpResponseRedirect(url) - + else: billingaddressform = RowerBillingAddressForm(instance=r) planselectform = PlanSelectForm(paymentprocessor='braintree') @@ -69,13 +69,13 @@ def billing_view(request): 'billingaddressform':billingaddressform, 'planselectform':planselectform, }) - + @login_required() def upgrade_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': @@ -93,7 +93,7 @@ def upgrade_view(request): for attr, value in cd.items(): setattr(r, attr, value) r.save() - + if planselectform.is_valid(): plan = planselectform.cleaned_data['plan'] if billingaddressform.is_valid(): @@ -102,7 +102,7 @@ def upgrade_view(request): 'planid':plan.id }) return HttpResponseRedirect(url) - + else: billingaddressform = RowerBillingAddressForm(instance=r) planselectform = PlanSelectForm(paymentprocessor='braintree', @@ -114,13 +114,13 @@ def upgrade_view(request): 'billingaddressform':billingaddressform, 'planselectform':planselectform, }) - + @login_required() def downgrade_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': @@ -138,7 +138,7 @@ def downgrade_view(request): for attr, value in cd.items(): setattr(r, attr, value) r.save() - + if planselectform.is_valid(): plan = planselectform.cleaned_data['plan'] @@ -150,14 +150,14 @@ def downgrade_view(request): return HttpResponseRedirect(url) else: nextview = downgrade_confirm_view - + if billingaddressform.is_valid(): url = reverse(nextview, kwargs={ 'planid':plan.id }) return HttpResponseRedirect(url) - + else: billingaddressform = RowerBillingAddressForm(instance=r) planselectform = PlanSelectForm(paymentprocessor='braintree', @@ -169,17 +169,17 @@ def downgrade_view(request): 'billingaddressform':billingaddressform, 'planselectform':planselectform, }) - + @login_required() def plan_stop_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower subscriptions = [] - + if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed') @@ -189,7 +189,7 @@ def plan_stop_view(request): except ProcessorCustomerError: r.paymentprocessor = None r.save() - + return render(request, @@ -203,7 +203,7 @@ def plan_tobasic_view(request,id=0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paidplan.paymentprocessor == 'braintree': @@ -217,15 +217,15 @@ def plan_tobasic_view(request,id=0): url = reverse(plan_stop_view) return HttpResponseRedirect(url) - - + + @login_required() def upgrade_confirm_view(request,planid = 0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + try: plan = PaidPlan.objects.get(id=planid) except PaidPlan.DoesNotExist: @@ -253,7 +253,7 @@ def downgrade_confirm_view(request,planid = 0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + try: plan = PaidPlan.objects.get(id=planid) except PaidPlan.DoesNotExist: @@ -279,7 +279,7 @@ def payment_confirm_view(request,planid = 0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + try: plan = PaidPlan.objects.get(id=planid) except PaidPlan.DoesNotExist: @@ -350,13 +350,13 @@ def checkouts_view(request): url = reverse(paidplans_view) return HttpResponseRedirect(url) - + @login_required() def upgrade_checkouts_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower @@ -402,7 +402,7 @@ def downgrade_checkouts_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower @@ -450,7 +450,7 @@ def payment_completed_view(request): amount = request.GET.get('amount',0) - + r = request.user.rower return render(request, @@ -465,7 +465,7 @@ def downgrade_completed_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower return render(request, @@ -480,7 +480,7 @@ def rower_register_view(request): nextpage = request.GET.get('next','/rowers/list-workouts/') if nextpage == '': nextpage = '/rowers/list-workouts/' - + if request.method == 'POST': #form = RegistrationFormUniqueEmail(request.POST) form = RegistrationFormSex(request.POST) @@ -517,7 +517,7 @@ def rower_register_view(request): timestr = strftime("%Y%m%d-%H%M%S") f2 = f[:-7]+timestr+'.csv.gz' copyfile(f,f2) - + response = dataprep.new_workout_from_file(therower,f2, title='New User Sample Data', notes='This is an example workout to get you started') @@ -527,17 +527,17 @@ def rower_register_view(request): w.startdatetime = timezone.now() w.date = timezone.now().date() w.save() - + # Create and send email fullemail = first_name + " " + last_name + " " + "<" + email + ">" subject = "Thank you for registering on rowsandall.com" from_address = 'Sander Roosendaal ' d = {'first_name':theuser.first_name} - + send_template_email(from_address,[fullemail], subject,'registeremail.html',d) - + subject2 = "New User" message2 = "New user registered.\n" @@ -550,7 +550,7 @@ def rower_register_view(request): theuser = authenticate(username=username,password=password) login(request,theuser) - + return HttpResponseRedirect(nextpage) # '/rowers/register/thankyou/') @@ -572,7 +572,7 @@ def freecoach_register_view(request): nextpage = request.GET.get('next','/rowers/me/teams/') if nextpage == '': nextpage = '/rowers/me/teams/' - + if request.method == 'POST': #form = RegistrationFormUniqueEmail(request.POST) form = RegistrationFormSex(request.POST) @@ -605,17 +605,17 @@ def freecoach_register_view(request): # create default favorite charts add_defaultfavorites(therower) - + # Create and send email fullemail = first_name + " " + last_name + " " + "<" + email + ">" subject = "Thank you for registering on rowsandall.com" from_address = 'Sander Roosendaal ' d = {'first_name':theuser.first_name} - + send_template_email(from_address,[fullemail], subject,'coachregisteremail.html',d) - + subject2 = "New Free Coach" message2 = "New Free Coach registered.\n" @@ -628,7 +628,7 @@ def freecoach_register_view(request): theuser = authenticate(username=username,password=password) login(request,theuser) - + return HttpResponseRedirect(nextpage) else: @@ -647,6 +647,7 @@ def freecoach_register_view(request): 'next':nextpage,}) @login_required() +@permission_required('rower.is_staff',fn=get_user_by_userid,raise_exception=True) def transactions_view(request): if not request.user.is_staff: raise PermissionDenied("Not Allowed") @@ -662,7 +663,7 @@ def transactions_view(request): response = HttpResponse(df.to_csv()) response['Content-Disposition'] = 'attachment; filename="%s"' % filename response['Content-Type'] = 'application/octet-stream' - + return response else: @@ -673,4 +674,3 @@ def transactions_view(request): { 'dateform':dateform }) - diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index 2548c41f..b5ec6dad 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -685,7 +685,9 @@ def plannedsession_teamcreate_view(request, enddatestring = enddate.strftime('%Y-%m-%d') url += '?when='+startdatestring+'/'+enddatestring - return HttpResponseRedirect(url) + next = request.GET.get('next', url) + + return HttpResponseRedirect(next) else: timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d') breadcrumbs = [ @@ -873,8 +875,8 @@ def plannedsession_teamedit_view(request, enddatestring = enddate.strftime('%Y-%m-%d') url += '?when='+startdatestring+'/'+enddatestring - - return HttpResponseRedirect(url) + next = request.GET.get('next', url) + return HttpResponseRedirect(next) else: sessioncreateform = PlannedSessionForm(instance=ps) sessionteamselectform = PlannedSessionTeamForm( @@ -1436,8 +1438,8 @@ def plannedsession_clone_view(request,id=0,userid=0): enddatestring = enddate.strftime('%Y-%m-%d') url += '?when='+startdatestring+'/'+enddatestring - - return HttpResponseRedirect(url) + next = request.GET.get('next', url) + return HttpResponseRedirect(next) # Clone an existing planned session # need clarity on cloning behavior time shift @@ -1497,8 +1499,102 @@ def plannedsession_teamclone_view(request,id=0): enddatestring = enddate.strftime('%Y-%m-%d') url += '?when='+startdatestring+'/'+enddatestring + next = request.GET.get('next', url) + return HttpResponseRedirect(next) + +@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True) +@user_passes_test(can_plan, login_url="/rowers/paidplans/", +message="This functionality requires a Coach or Self-Coach plan", +redirect_field_name=None) +def plannedsession_templateedit_view(request,id=0): + r = getrequestrower(request) + startdate,enddate = get_dates_timeperiod(request) + try: + trainingplan = TrainingPlan.objects.filter( + startdate__lte = startdate, + rowers = r, + enddate__gte = enddate)[0] + except IndexError: + trainingplan = None + + try: + ps = PlannedSession.objects.get(id=id) + except PlannedSession.DoesNotExist: + raise Http404("Planned Session does not exist") + + if ps.manager != request.user: + raise PermissionDenied("You are not allowed to edit this planned session") + + if ps.sessiontype in ['race','indoorrace']: + raise PermissionDenied("You are not allowed to edit this planned session because it is a race") + + if not ps.is_template: + ps.pk = None + ps.id = None + ps.is_template = True + ps.startdate = datetime.date(1970,1,1) + ps.enddate = datetime.date(1970,1,1) + ps.team.clear() + ps.save() + + sessioncreateform = PlannedSessionTemplateForm(instance=ps) + + if request.method == 'POST': + sessioncreateform = PlannedSessionTemplateForm(request.POST,instance=ps) + if sessioncreateform.is_valid(): + cd = sessioncreateform.cleaned_data + if cd['sessionunit'] == 'min': + cd['sessionmode'] = 'time' + elif cd['sessionunit'] in ['km','m']: + cd['sessionmode'] = 'distance' + + res, message = update_plannedsession(ps,cd) + + if res: + messages.info(request,message) + else: + messages.error(request,message) + + url = reverse(plannedsession_templateedit_view, + kwargs = { + 'id':int(ps.id), + }) + + startdatestring = startdate.strftime('%Y-%m-%d') + enddatestring = enddate.strftime('%Y-%m-%d') + url += '?when='+startdatestring+'/'+enddatestring + next = request.GET.get('next', url) + return HttpResponseRedirect(next) + + breadcrumbs = [ + { + 'url': reverse(plannedsessions_view), + 'name': 'Sessions' + }, + { + 'url':reverse(plannedsession_templateedit_view, + kwargs={ + 'id':id, + } + ), + 'name': 'Edit' + } + ] + + sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True) + + return render(request,'plannedsessiontemplateedit.html', + { + 'teams':get_my_teams(request.user), + 'plan': trainingplan, + 'breadcrumbs': breadcrumbs, + 'form': sessioncreateform, + 'active':'nav-plan', + 'thesession': ps, + 'sessiontemplates': sessiontemplates, + 'rower': r, + }) - return HttpResponseRedirect(url) @permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True) @user_passes_test(can_plan, login_url="/rowers/paidplans/", @@ -1525,7 +1621,9 @@ def plannedsession_totemplate_view(request,id=0): enddatestring = enddate.strftime('%Y-%m-%d') url += '?when='+startdatestring+'/'+enddatestring - return HttpResponseRedirect(url) + next = request.GET.get('next', url) + + return HttpResponseRedirect(next) # Edit an existing planned session @permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True) @@ -1663,8 +1761,8 @@ def plannedsession_detach_view(request,id=0,psid=0): remove_workout_plannedsession(w,ps) url = reverse(plannedsession_view,kwargs={'id':psid}) - - return HttpResponseRedirect(url) + next = request.GET.get('next', url) + return HttpResponseRedirect(next) @login_required() @permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True) @@ -1892,8 +1990,9 @@ class PlannedSessionDelete(DeleteView): w.save() url = reverse(plannedsessions_view) + next = self.request.GET.get('next',url) - return url + return next def get_object(self, *args, **kwargs): obj = super(PlannedSessionDelete, self).get_object(*args, **kwargs) diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 19deb0cf..e6a6e7e6 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -120,7 +120,7 @@ from rowers.models import ( WorkoutComment,WorkoutCommentForm,RowerExportForm, CalcAgePerformance, PowerTimeFitnessMetric,BlogPost, - PlannedSessionForm, + PlannedSessionForm,PlannedSessionTemplateForm, PlannedSessionFormSmall,GeoCourseEditForm,VirtualRace, VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm, IndoorVirtualRaceResultForm,IndoorVirtualRaceResult, diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py index d3f4903d..d82f5b47 100644 --- a/rowers/views/userviews.py +++ b/rowers/views/userviews.py @@ -5,6 +5,31 @@ from __future__ import unicode_literals from rowers.views.statements import * +@login_required() +def survey(request): + + r = getrower(request.user) + + surveyform = SurveyForm() + + if request.method == 'POST': + form = SurveyForm(request.POST) + r.surveydone = True + r.surveydonedate = timezone.now() + r.save() + + nexturl = request.GET.get('next') + return HttpResponseRedirect(nexturl) + + context = { + 'teams':get_my_teams(request.user), + 'rower':r, + 'form':surveyform, + } + + + return render(request,'survey.html',context) + @login_required() def start_trial_view(request): r = getrower(request.user) diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 376f563e..a52d31e4 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -386,21 +386,18 @@ def workout_video_create_view(request,id=0): @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. If you are already a Pro user, please log in to access this functionality", redirect_field_name=None) +@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True) def workout_forcecurve_view(request,id=0,workstrokesonly=False): row = get_workout(id) promember=0 mayedit=0 - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - if request.user == row.user.user: - mayedit=1 - if not promember: - return HttpResponseRedirect("/rowers/about/") + r = getrequestrower(request) + promember = 1 + + if r == row.user: + mayedit = 1 if request.method == 'POST': form = ForceCurveOptionsForm(request.POST) @@ -503,21 +500,15 @@ def otw_use_gps(request,id=0): # Show Stroke power histogram for a workout @login_required() +@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True) def workout_histo_view(request,id=0): w = get_workout(id) + r = getrequestrower(request) + promember = 1 - promember=0 mayedit=0 - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - if request.user == w.user.user: - mayedit=1 - - if not promember: - return HttpResponseRedirect("/rowers/about/") + if w.user == r: + mayedit = 1 res = interactive_histoall([w],'power',False) script = res[0] @@ -745,6 +736,7 @@ def fitness_metric_view(request,mode='rower',days=42): @permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True) +@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) @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. If you are already a Pro user, please log in to access this functionality", redirect_field_name=None) @@ -854,6 +846,7 @@ defaultoptions = { @user_passes_test(ispromember, login_url="/rowers/paidplans", message="This functionality requires a Pro plan or higher", redirect_field_name=None) +@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) def video_selectworkout(request,userid=0,teamid=0): r = getrequestrower(request, userid=userid) user = r.user @@ -1975,17 +1968,15 @@ def workouts_view(request,message='',successmessage='', @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. If you are already a Pro user, please log in to access this functionality", redirect_field_name=None) -def workout_fusion_list(request,id=0,message='',successmessage='', +@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True) +def workout_fusion_list(request,id=0, startdatestring="",enddatestring="", startdate=timezone.now()-datetime.timedelta(days=365), enddate=timezone.now()): - try: - r = getrower(request.user) - except Rower.DoesNotExist: - raise Http404("User has no rower instance") + r = getrequestrower(request) - u = User.objects.get(id=r.user.id) + u = r.user if request.method == 'POST': dateform = DateRangeForm(request.POST) if dateform.is_valid(): @@ -2013,6 +2004,8 @@ def workout_fusion_list(request,id=0,message='',successmessage='', if id: theid = encoder.decode_hex(id) + w = get_workout(id) + r = w.user workouts = Workout.objects.filter(user=r, startdatetime__gte=startdate, @@ -2042,8 +2035,6 @@ def workout_fusion_list(request,id=0,message='',successmessage='', workouts = paginator.page(paginator.num_pages) row = get_workout(id) - messages.info(request,successmessage) - messages.error(request,message) breadcrumbs = [ { @@ -2618,7 +2609,9 @@ def workout_stream_view(request,id=0,message="",successmessage=""): rowdata = rdata(f1) if rowdata == 0: - return HttpResponse("Error: CSV Data File Not Found") + messages.info(request,"Error: CSV data file not found") + url = reverse('workout_edit_view',kwargs={'id':encoder.encode_hex(row.id)}) + return HttpResponseRedirect(url) if request.method == 'POST': # process form @@ -3710,14 +3703,12 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""): # r = getrower(u) promember=0 - mayedit=0 - if not request.user.is_anonymous: - r = getrower(request.user) - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember=1 - if request.user == w.user.user: - mayedit=1 + mayedit = 0 + result = request.user.is_authenticated and ispromember(request.user) + if result: + promember=1 + if request.user == w.user.user: + mayedit=1 # create interactive plot res = interactive_otw_advanced_pace_chart(encoder.decode_hex(id),promember=promember) @@ -5062,46 +5053,45 @@ def list_videos(request): }) @login_required() -def graphs_view(request): +def graphs_view(request,userid=0): request.session['referer'] = reverse('graphs_view') + r = getrequestrower(request,userid=userid) + workouts = Workout.objects.filter(user=r).order_by("-date", "-starttime") + 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() + + g = GraphImage.objects.filter(workout__in=workouts).order_by("-creationdatetime") + + + paginator = Paginator(g,8) + page = request.GET.get('page') + try: - r = getrower(request.user) - workouts = Workout.objects.filter(user=r).order_by("-date", "-starttime") - 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() + g = paginator.page(page) + except PageNotAnInteger: + g = paginator.page(1) + except EmptyPage: + g = paginator.page(paginator.num_pages) - g = GraphImage.objects.filter(workout__in=workouts).order_by("-creationdatetime") - - - paginator = Paginator(g,8) - page = request.GET.get('page') - - try: - g = paginator.page(page) - except PageNotAnInteger: - g = paginator.page(1) - except EmptyPage: - g = paginator.page(paginator.num_pages) - - return render(request, 'list_graphs.html', + return render(request, 'list_graphs.html', {'graphs': g, 'searchform':searchform, 'active':'nav-workouts', 'teams':get_my_teams(request.user), + 'rower':r, }) - except Rower.DoesNotExist: - raise Http404("User has no rower instance") + # Show the chart (png image) def graph_show_view(request,id):