diff --git a/008fc633-d9d4-4abc-9812-e22014e19498.tcx b/008fc633-d9d4-4abc-9812-e22014e19498.tcx deleted file mode 100644 index 31d671d7..00000000 --- a/008fc633-d9d4-4abc-9812-e22014e19498.tcx +++ /dev/null @@ -1,2523 +0,0 @@ - - - - - 2016-05-20T13:41:26.962390+00:00 - - 537 - 2000 - 1 - - 148 - - - 156 - - Active - 21 - Manual - - - - 5.4 - - 127 - - 0 - - - 19 - - - - - - 13.1 - - 127 - - 19 - - - 26 - - - - - - 21.0 - - 128 - - 20 - - - 45 - - - - - - 30.3 - - 129 - - 20 - - - 64 - - - - - - 39.0 - - 130 - - 20 - - - 74 - - - - - - 48.2 - - 131 - - 21 - - - 80 - - - - - - 57.6 - - 131 - - 20 - - - 83 - - - - - - 66.4 - - 132 - - 20 - - - 87 - - - - - - 75.5 - - 132 - - 21 - - - 86 - - - - - - 85.1 - - 132 - - 20 - - - 88 - - - - - - 95.0 - - 132 - - 21 - - - 100 - - - - - - 105.0 - - 133 - - 22 - - - 127 - - - - - - 115.3 - - 134 - - 21 - - - 135 - - - - - - 125.8 - - 135 - - 21 - - - 139 - - - - - - 136.6 - - 136 - - 21 - - - 146 - - - - - - 147.2 - - 137 - - 22 - - - 150 - - - - - - 157.6 - - 139 - - 22 - - - 152 - - - - - - 167.8 - - 140 - - 21 - - - 146 - - - - - - 178.5 - - 140 - - 22 - - - 150 - - - - - - 188.5 - - 141 - - 21 - - - 155 - - - - - - 199.3 - - 141 - - 21 - - - 148 - - - - - - 209.4 - - 142 - - 22 - - - 151 - - - - - - 219.4 - - 142 - - 22 - - - 151 - - - - - - 230.2 - - 143 - - 22 - - - 148 - - - - - - 240.2 - - 144 - - 22 - - - 147 - - - - - - 250.1 - - 145 - - 23 - - - 150 - - - - - - 259.6 - - 145 - - 23 - - - 152 - - - - - - 270.3 - - 145 - - 23 - - - 152 - - - - - - 280.6 - - 145 - - 22 - - - 149 - - - - - - 290.7 - - 144 - - 22 - - - 150 - - - - - - 300.8 - - 145 - - 23 - - - 149 - - - - - - 311.1 - - 145 - - 22 - - - 152 - - - - - - 321.2 - - 145 - - 22 - - - 157 - - - - - - 331.9 - - 145 - - 21 - - - 150 - - - - - - 342.0 - - 146 - - 22 - - - 151 - - - - - - 352.4 - - 146 - - 22 - - - 151 - - - - - - 363.0 - - 146 - - 22 - - - 153 - - - - - - 373.4 - - 147 - - 22 - - - 152 - - - - - - 383.9 - - 147 - - 22 - - - 153 - - - - - - 394.6 - - 147 - - 22 - - - 152 - - - - - - 405.0 - - 147 - - 21 - - - 149 - - - - - - 415.3 - - 148 - - 22 - - - 152 - - - - - - 426.0 - - 148 - - 22 - - - 151 - - - - - - 436.5 - - 148 - - 21 - - - 149 - - - - - - 446.9 - - 148 - - 22 - - - 149 - - - - - - 456.9 - - 149 - - 22 - - - 156 - - - - - - 467.6 - - 149 - - 22 - - - 155 - - - - - - 478.5 - - 150 - - 22 - - - 156 - - - - - - 489.0 - - 150 - - 21 - - - 154 - - - - - - 499.1 - - 150 - - 21 - - - 148 - - - - - - 510.0 - - 150 - - 22 - - - 151 - - - - - - 519.9 - - 149 - - 22 - - - 153 - - - - - - 530.6 - - 149 - - 22 - - - 151 - - - - - - 540.8 - - 149 - - 22 - - - 148 - - - - - - 550.8 - - 148 - - 22 - - - 149 - - - - - - 560.8 - - 148 - - 22 - - - 144 - - - - - - 571.0 - - 147 - - 22 - - - 149 - - - - - - 580.7 - - 147 - - 22 - - - 150 - - - - - - 591.2 - - 147 - - 22 - - - 151 - - - - - - 601.4 - - 147 - - 22 - - - 150 - - - - - - 611.4 - - 147 - - 23 - - - 153 - - - - - - 621.8 - - 147 - - 23 - - - 151 - - - - - - 632.1 - - 147 - - 22 - - - 155 - - - - - - 642.3 - - 147 - - 22 - - - 154 - - - - - - 652.0 - - 148 - - 23 - - - 157 - - - - - - 662.7 - - 148 - - 23 - - - 162 - - - - - - 673.1 - - 148 - - 23 - - - 163 - - - - - - 683.6 - - 149 - - 22 - - - 163 - - - - - - 693.8 - - 149 - - 22 - - - 162 - - - - - - 703.8 - - 149 - - 22 - - - 164 - - - - - - 714.7 - - 150 - - 23 - - - 162 - - - - - - 724.9 - - 150 - - 22 - - - 162 - - - - - - 735.2 - - 151 - - 23 - - - 159 - - - - - - 745.4 - - 151 - - 22 - - - 158 - - - - - - 756.0 - - 151 - - 23 - - - 164 - - - - - - 766.3 - - 150 - - 22 - - - 163 - - - - - - 776.5 - - 150 - - 22 - - - 161 - - - - - - 786.9 - - 150 - - 23 - - - 163 - - - - - - 797.2 - - 150 - - 22 - - - 165 - - - - - - 807.8 - - 150 - - 23 - - - 166 - - - - - - 818.2 - - 150 - - 23 - - - 166 - - - - - - 828.4 - - 150 - - 22 - - - 168 - - - - - - 839.2 - - 150 - - 23 - - - 169 - - - - - - 849.6 - - 151 - - 23 - - - 166 - - - - - - 860.1 - - 151 - - 22 - - - 172 - - - - - - 870.3 - - 152 - - 22 - - - 172 - - - - - - 881.1 - - 152 - - 22 - - - 169 - - - - - - 891.7 - - 152 - - 23 - - - 167 - - - - - - 902.1 - - 152 - - 22 - - - 164 - - - - - - 913.1 - - 152 - - 22 - - - 161 - - - - - - 923.9 - - 153 - - 22 - - - 158 - - - - - - 934.6 - - 154 - - 21 - - - 158 - - - - - - 945.4 - - 154 - - 21 - - - 154 - - - - - - 956.0 - - 155 - - 21 - - - 155 - - - - - - 966.7 - - 155 - - 21 - - - 152 - - - - - - 977.4 - - 156 - - 21 - - - 150 - - - - - - 988.1 - - 156 - - 21 - - - 157 - - - - - - 998.8 - - 156 - - 21 - - - 155 - - - - - - 1009.6 - - 156 - - 21 - - - 151 - - - - - - 1020.6 - - 156 - - 21 - - - 147 - - - - - - 1031.5 - - 156 - - 20 - - - 145 - - - - - - 1042.5 - - 156 - - 21 - - - 144 - - - - - - 1053.3 - - 155 - - 20 - - - 145 - - - - - - 1064.1 - - 155 - - 21 - - - 147 - - - - - - 1075.3 - - 155 - - 20 - - - 142 - - - - - - 1086.1 - - 155 - - 20 - - - 136 - - - - - - 1097.5 - - 155 - - 21 - - - 141 - - - - - - 1108.5 - - 155 - - 20 - - - 146 - - - - - - 1119.2 - - 155 - - 20 - - - 143 - - - - - - 1130.6 - - 155 - - 20 - - - 143 - - - - - - 1141.3 - - 155 - - 20 - - - 143 - - - - - - 1152.4 - - 155 - - 21 - - - 142 - - - - - - 1163.3 - - 155 - - 20 - - - 138 - - - - - - 1173.8 - - 154 - - 20 - - - 141 - - - - - - 1184.8 - - 154 - - 21 - - - 146 - - - - - - 1195.8 - - 153 - - 21 - - - 146 - - - - - - 1206.6 - - 152 - - 21 - - - 141 - - - - - - 1217.3 - - 153 - - 21 - - - 141 - - - - - - 1227.8 - - 152 - - 21 - - - 140 - - - - - - 1238.7 - - 152 - - 21 - - - 143 - - - - - - 1249.5 - - 151 - - 21 - - - 149 - - - - - - 1260.1 - - 151 - - 20 - - - 141 - - - - - - 1270.9 - - 151 - - 21 - - - 141 - - - - - - 1281.8 - - 150 - - 21 - - - 145 - - - - - - 1292.7 - - 151 - - 20 - - - 142 - - - - - - 1303.4 - - 151 - - 20 - - - 141 - - - - - - 1314.3 - - 151 - - 21 - - - 141 - - - - - - 1325.2 - - 151 - - 21 - - - 146 - - - - - - 1336.1 - - 152 - - 20 - - - 143 - - - - - - 1346.9 - - 152 - - 21 - - - 144 - - - - - - 1357.4 - - 152 - - 20 - - - 141 - - - - - - 1368.1 - - 152 - - 21 - - - 138 - - - - - - 1379.0 - - 152 - - 20 - - - 142 - - - - - - 1389.5 - - 153 - - 21 - - - 145 - - - - - - 1399.9 - - 152 - - 21 - - - 138 - - - - - - 1410.7 - - 152 - - 20 - - - 139 - - - - - - 1422.0 - - 152 - - 20 - - - 139 - - - - - - 1432.8 - - 151 - - 20 - - - 141 - - - - - - 1443.6 - - 151 - - 21 - - - 146 - - - - - - 1454.4 - - 152 - - 20 - - - 143 - - - - - - 1465.1 - - 151 - - 21 - - - 143 - - - - - - 1475.9 - - 152 - - 21 - - - 145 - - - - - - 1486.6 - - 152 - - 21 - - - 148 - - - - - - 1497.4 - - 153 - - 21 - - - 143 - - - - - - 1508.2 - - 153 - - 20 - - - 140 - - - - - - 1519.2 - - 154 - - 20 - - - 144 - - - - - - 1530.0 - - 154 - - 21 - - - 143 - - - - - - 1540.9 - - 153 - - 20 - - - 141 - - - - - - 1551.3 - - 153 - - 21 - - - 143 - - - - - - 1562.6 - - 153 - - 21 - - - 146 - - - - - - 1573.3 - - 153 - - 20 - - - 141 - - - - - - 1584.2 - - 152 - - 20 - - - 139 - - - - - - 1594.6 - - 152 - - 21 - - - 145 - - - - - - 1606.0 - - 152 - - 21 - - - 143 - - - - - - 1616.2 - - 152 - - 20 - - - 138 - - - - - - 1627.4 - - 152 - - 21 - - - 140 - - - - - - 1638.0 - - 152 - - 21 - - - 144 - - - - - - 1649.2 - - 151 - - 20 - - - 143 - - - - - - 1660.2 - - 152 - - 20 - - - 143 - - - - - - 1670.8 - - 151 - - 20 - - - 142 - - - - - - 1681.4 - - 151 - - 21 - - - 140 - - - - - - 1692.1 - - 151 - - 21 - - - 140 - - - - - - 1702.5 - - 150 - - 21 - - - 141 - - - - - - 1713.7 - - 150 - - 21 - - - 144 - - - - - - 1724.4 - - 150 - - 21 - - - 146 - - - - - - 1735.1 - - 150 - - 20 - - - 141 - - - - - - 1745.6 - - 150 - - 21 - - - 140 - - - - - - 1756.3 - - 150 - - 21 - - - 141 - - - - - - 1766.2 - - 151 - - 20 - - - 142 - - - - - - 1777.1 - - 150 - - 22 - - - 138 - - - - - - 1787.5 - - 150 - - 21 - - - 138 - - - - - - 1797.7 - - 150 - - 22 - - - 140 - - - - - - 1808.4 - - 150 - - 21 - - - 140 - - - - - - 1818.4 - - 149 - - 21 - - - 138 - - - - - - 1828.9 - - 149 - - 22 - - - 146 - - - - - - 1839.9 - - 149 - - 21 - - - 142 - - - - - - 1850.5 - - 148 - - 21 - - - 142 - - - - - - 1861.2 - - 148 - - 21 - - - 145 - - - - - - 1871.9 - - 147 - - 21 - - - 143 - - - - - - 1882.6 - - 147 - - 20 - - - 139 - - - - - - 1893.3 - - 148 - - 20 - - - 140 - - - - - - 1904.3 - - 149 - - 21 - - - 144 - - - - - - 1915.4 - - 149 - - 20 - - - 148 - - - - - - 1926.2 - - 150 - - 20 - - - 139 - - - - - - 1937.3 - - 151 - - 20 - - - 140 - - - - - - 1947.8 - - 152 - - 20 - - - 144 - - - - - - 1959.1 - - 152 - - 20 - - - 142 - - - - - - 1969.8 - - 153 - - 20 - - - 140 - - - - - - 1980.6 - - 153 - - 21 - - - 143 - - - - - - 1991.4 - - 153 - - 21 - - - 143 - - - - - - 2000.0 - - 154 - - 21 - - - 147 - - - - - - <Element 'Notes' at 0x7f5eb3c3ef98> - - - - rowsandall.com/rowingdata - - - rowingdata - - - 0 - 75 - - Release - - EN - 000-00000-00 - - diff --git a/03f8abfb-ccec-45bf-ac29-b193477d2045.tcx b/03f8abfb-ccec-45bf-ac29-b193477d2045.tcx deleted file mode 100644 index eb0a1c3e..00000000 --- a/03f8abfb-ccec-45bf-ac29-b193477d2045.tcx +++ /dev/null @@ -1,2523 +0,0 @@ - - - - - 2016-05-20T13:41:26.962390+00:00 - - 537 - 2000 - 1 - - 148 - - - 156 - - Active - 21 - Manual - - - - 5.4 - - 127 - - 0 - - - 19 - - - - - - 13.1 - - 127 - - 19 - - - 26 - - - - - - 21.0 - - 128 - - 20 - - - 45 - - - - - - 30.3 - - 129 - - 20 - - - 64 - - - - - - 39.0 - - 130 - - 20 - - - 74 - - - - - - 48.2 - - 131 - - 21 - - - 80 - - - - - - 57.6 - - 131 - - 20 - - - 83 - - - - - - 66.4 - - 132 - - 20 - - - 87 - - - - - - 75.5 - - 132 - - 21 - - - 86 - - - - - - 85.1 - - 132 - - 20 - - - 88 - - - - - - 95.0 - - 132 - - 21 - - - 100 - - - - - - 105.0 - - 133 - - 22 - - - 127 - - - - - - 115.3 - - 134 - - 21 - - - 135 - - - - - - 125.8 - - 135 - - 21 - - - 139 - - - - - - 136.6 - - 136 - - 21 - - - 146 - - - - - - 147.2 - - 137 - - 22 - - - 150 - - - - - - 157.6 - - 139 - - 22 - - - 152 - - - - - - 167.8 - - 140 - - 21 - - - 146 - - - - - - 178.5 - - 140 - - 22 - - - 150 - - - - - - 188.5 - - 141 - - 21 - - - 155 - - - - - - 199.3 - - 141 - - 21 - - - 148 - - - - - - 209.4 - - 142 - - 22 - - - 151 - - - - - - 219.4 - - 142 - - 22 - - - 151 - - - - - - 230.2 - - 143 - - 22 - - - 148 - - - - - - 240.2 - - 144 - - 22 - - - 147 - - - - - - 250.1 - - 145 - - 23 - - - 150 - - - - - - 259.6 - - 145 - - 23 - - - 152 - - - - - - 270.3 - - 145 - - 23 - - - 152 - - - - - - 280.6 - - 145 - - 22 - - - 149 - - - - - - 290.7 - - 144 - - 22 - - - 150 - - - - - - 300.8 - - 145 - - 23 - - - 149 - - - - - - 311.1 - - 145 - - 22 - - - 152 - - - - - - 321.2 - - 145 - - 22 - - - 157 - - - - - - 331.9 - - 145 - - 21 - - - 150 - - - - - - 342.0 - - 146 - - 22 - - - 151 - - - - - - 352.4 - - 146 - - 22 - - - 151 - - - - - - 363.0 - - 146 - - 22 - - - 153 - - - - - - 373.4 - - 147 - - 22 - - - 152 - - - - - - 383.9 - - 147 - - 22 - - - 153 - - - - - - 394.6 - - 147 - - 22 - - - 152 - - - - - - 405.0 - - 147 - - 21 - - - 149 - - - - - - 415.3 - - 148 - - 22 - - - 152 - - - - - - 426.0 - - 148 - - 22 - - - 151 - - - - - - 436.5 - - 148 - - 21 - - - 149 - - - - - - 446.9 - - 148 - - 22 - - - 149 - - - - - - 456.9 - - 149 - - 22 - - - 156 - - - - - - 467.6 - - 149 - - 22 - - - 155 - - - - - - 478.5 - - 150 - - 22 - - - 156 - - - - - - 489.0 - - 150 - - 21 - - - 154 - - - - - - 499.1 - - 150 - - 21 - - - 148 - - - - - - 510.0 - - 150 - - 22 - - - 151 - - - - - - 519.9 - - 149 - - 22 - - - 153 - - - - - - 530.6 - - 149 - - 22 - - - 151 - - - - - - 540.8 - - 149 - - 22 - - - 148 - - - - - - 550.8 - - 148 - - 22 - - - 149 - - - - - - 560.8 - - 148 - - 22 - - - 144 - - - - - - 571.0 - - 147 - - 22 - - - 149 - - - - - - 580.7 - - 147 - - 22 - - - 150 - - - - - - 591.2 - - 147 - - 22 - - - 151 - - - - - - 601.4 - - 147 - - 22 - - - 150 - - - - - - 611.4 - - 147 - - 23 - - - 153 - - - - - - 621.8 - - 147 - - 23 - - - 151 - - - - - - 632.1 - - 147 - - 22 - - - 155 - - - - - - 642.3 - - 147 - - 22 - - - 154 - - - - - - 652.0 - - 148 - - 23 - - - 157 - - - - - - 662.7 - - 148 - - 23 - - - 162 - - - - - - 673.1 - - 148 - - 23 - - - 163 - - - - - - 683.6 - - 149 - - 22 - - - 163 - - - - - - 693.8 - - 149 - - 22 - - - 162 - - - - - - 703.8 - - 149 - - 22 - - - 164 - - - - - - 714.7 - - 150 - - 23 - - - 162 - - - - - - 724.9 - - 150 - - 22 - - - 162 - - - - - - 735.2 - - 151 - - 23 - - - 159 - - - - - - 745.4 - - 151 - - 22 - - - 158 - - - - - - 756.0 - - 151 - - 23 - - - 164 - - - - - - 766.3 - - 150 - - 22 - - - 163 - - - - - - 776.5 - - 150 - - 22 - - - 161 - - - - - - 786.9 - - 150 - - 23 - - - 163 - - - - - - 797.2 - - 150 - - 22 - - - 165 - - - - - - 807.8 - - 150 - - 23 - - - 166 - - - - - - 818.2 - - 150 - - 23 - - - 166 - - - - - - 828.4 - - 150 - - 22 - - - 168 - - - - - - 839.2 - - 150 - - 23 - - - 169 - - - - - - 849.6 - - 151 - - 23 - - - 166 - - - - - - 860.1 - - 151 - - 22 - - - 172 - - - - - - 870.3 - - 152 - - 22 - - - 172 - - - - - - 881.1 - - 152 - - 22 - - - 169 - - - - - - 891.7 - - 152 - - 23 - - - 167 - - - - - - 902.1 - - 152 - - 22 - - - 164 - - - - - - 913.1 - - 152 - - 22 - - - 161 - - - - - - 923.9 - - 153 - - 22 - - - 158 - - - - - - 934.6 - - 154 - - 21 - - - 158 - - - - - - 945.4 - - 154 - - 21 - - - 154 - - - - - - 956.0 - - 155 - - 21 - - - 155 - - - - - - 966.7 - - 155 - - 21 - - - 152 - - - - - - 977.4 - - 156 - - 21 - - - 150 - - - - - - 988.1 - - 156 - - 21 - - - 157 - - - - - - 998.8 - - 156 - - 21 - - - 155 - - - - - - 1009.6 - - 156 - - 21 - - - 151 - - - - - - 1020.6 - - 156 - - 21 - - - 147 - - - - - - 1031.5 - - 156 - - 20 - - - 145 - - - - - - 1042.5 - - 156 - - 21 - - - 144 - - - - - - 1053.3 - - 155 - - 20 - - - 145 - - - - - - 1064.1 - - 155 - - 21 - - - 147 - - - - - - 1075.3 - - 155 - - 20 - - - 142 - - - - - - 1086.1 - - 155 - - 20 - - - 136 - - - - - - 1097.5 - - 155 - - 21 - - - 141 - - - - - - 1108.5 - - 155 - - 20 - - - 146 - - - - - - 1119.2 - - 155 - - 20 - - - 143 - - - - - - 1130.6 - - 155 - - 20 - - - 143 - - - - - - 1141.3 - - 155 - - 20 - - - 143 - - - - - - 1152.4 - - 155 - - 21 - - - 142 - - - - - - 1163.3 - - 155 - - 20 - - - 138 - - - - - - 1173.8 - - 154 - - 20 - - - 141 - - - - - - 1184.8 - - 154 - - 21 - - - 146 - - - - - - 1195.8 - - 153 - - 21 - - - 146 - - - - - - 1206.6 - - 152 - - 21 - - - 141 - - - - - - 1217.3 - - 153 - - 21 - - - 141 - - - - - - 1227.8 - - 152 - - 21 - - - 140 - - - - - - 1238.7 - - 152 - - 21 - - - 143 - - - - - - 1249.5 - - 151 - - 21 - - - 149 - - - - - - 1260.1 - - 151 - - 20 - - - 141 - - - - - - 1270.9 - - 151 - - 21 - - - 141 - - - - - - 1281.8 - - 150 - - 21 - - - 145 - - - - - - 1292.7 - - 151 - - 20 - - - 142 - - - - - - 1303.4 - - 151 - - 20 - - - 141 - - - - - - 1314.3 - - 151 - - 21 - - - 141 - - - - - - 1325.2 - - 151 - - 21 - - - 146 - - - - - - 1336.1 - - 152 - - 20 - - - 143 - - - - - - 1346.9 - - 152 - - 21 - - - 144 - - - - - - 1357.4 - - 152 - - 20 - - - 141 - - - - - - 1368.1 - - 152 - - 21 - - - 138 - - - - - - 1379.0 - - 152 - - 20 - - - 142 - - - - - - 1389.5 - - 153 - - 21 - - - 145 - - - - - - 1399.9 - - 152 - - 21 - - - 138 - - - - - - 1410.7 - - 152 - - 20 - - - 139 - - - - - - 1422.0 - - 152 - - 20 - - - 139 - - - - - - 1432.8 - - 151 - - 20 - - - 141 - - - - - - 1443.6 - - 151 - - 21 - - - 146 - - - - - - 1454.4 - - 152 - - 20 - - - 143 - - - - - - 1465.1 - - 151 - - 21 - - - 143 - - - - - - 1475.9 - - 152 - - 21 - - - 145 - - - - - - 1486.6 - - 152 - - 21 - - - 148 - - - - - - 1497.4 - - 153 - - 21 - - - 143 - - - - - - 1508.2 - - 153 - - 20 - - - 140 - - - - - - 1519.2 - - 154 - - 20 - - - 144 - - - - - - 1530.0 - - 154 - - 21 - - - 143 - - - - - - 1540.9 - - 153 - - 20 - - - 141 - - - - - - 1551.3 - - 153 - - 21 - - - 143 - - - - - - 1562.6 - - 153 - - 21 - - - 146 - - - - - - 1573.3 - - 153 - - 20 - - - 141 - - - - - - 1584.2 - - 152 - - 20 - - - 139 - - - - - - 1594.6 - - 152 - - 21 - - - 145 - - - - - - 1606.0 - - 152 - - 21 - - - 143 - - - - - - 1616.2 - - 152 - - 20 - - - 138 - - - - - - 1627.4 - - 152 - - 21 - - - 140 - - - - - - 1638.0 - - 152 - - 21 - - - 144 - - - - - - 1649.2 - - 151 - - 20 - - - 143 - - - - - - 1660.2 - - 152 - - 20 - - - 143 - - - - - - 1670.8 - - 151 - - 20 - - - 142 - - - - - - 1681.4 - - 151 - - 21 - - - 140 - - - - - - 1692.1 - - 151 - - 21 - - - 140 - - - - - - 1702.5 - - 150 - - 21 - - - 141 - - - - - - 1713.7 - - 150 - - 21 - - - 144 - - - - - - 1724.4 - - 150 - - 21 - - - 146 - - - - - - 1735.1 - - 150 - - 20 - - - 141 - - - - - - 1745.6 - - 150 - - 21 - - - 140 - - - - - - 1756.3 - - 150 - - 21 - - - 141 - - - - - - 1766.2 - - 151 - - 20 - - - 142 - - - - - - 1777.1 - - 150 - - 22 - - - 138 - - - - - - 1787.5 - - 150 - - 21 - - - 138 - - - - - - 1797.7 - - 150 - - 22 - - - 140 - - - - - - 1808.4 - - 150 - - 21 - - - 140 - - - - - - 1818.4 - - 149 - - 21 - - - 138 - - - - - - 1828.9 - - 149 - - 22 - - - 146 - - - - - - 1839.9 - - 149 - - 21 - - - 142 - - - - - - 1850.5 - - 148 - - 21 - - - 142 - - - - - - 1861.2 - - 148 - - 21 - - - 145 - - - - - - 1871.9 - - 147 - - 21 - - - 143 - - - - - - 1882.6 - - 147 - - 20 - - - 139 - - - - - - 1893.3 - - 148 - - 20 - - - 140 - - - - - - 1904.3 - - 149 - - 21 - - - 144 - - - - - - 1915.4 - - 149 - - 20 - - - 148 - - - - - - 1926.2 - - 150 - - 20 - - - 139 - - - - - - 1937.3 - - 151 - - 20 - - - 140 - - - - - - 1947.8 - - 152 - - 20 - - - 144 - - - - - - 1959.1 - - 152 - - 20 - - - 142 - - - - - - 1969.8 - - 153 - - 20 - - - 140 - - - - - - 1980.6 - - 153 - - 21 - - - 143 - - - - - - 1991.4 - - 153 - - 21 - - - 143 - - - - - - 2000.0 - - 154 - - 21 - - - 147 - - - - - - <Element 'Notes' at 0x13b50a20> - - - - rowsandall.com/rowingdata - - - rowingdata - - - 0 - 75 - - Release - - EN - 000-00000-00 - - diff --git a/b90680ee-35d5-4633-9974-fdc4bba4c68f.tcx b/b90680ee-35d5-4633-9974-fdc4bba4c68f.tcx deleted file mode 100644 index 97ac8d4f..00000000 --- a/b90680ee-35d5-4633-9974-fdc4bba4c68f.tcx +++ /dev/null @@ -1,2523 +0,0 @@ - - - - - 2016-05-20T13:41:26.962390+00:00 - - 537 - 2000 - 1 - - 148 - - - 156 - - Active - 21 - Manual - - - - 5.4 - - 127 - - 0 - - - 19 - - - - - - 13.1 - - 127 - - 19 - - - 26 - - - - - - 21.0 - - 128 - - 20 - - - 45 - - - - - - 30.3 - - 129 - - 20 - - - 64 - - - - - - 39.0 - - 130 - - 20 - - - 74 - - - - - - 48.2 - - 131 - - 21 - - - 80 - - - - - - 57.6 - - 131 - - 20 - - - 83 - - - - - - 66.4 - - 132 - - 20 - - - 87 - - - - - - 75.5 - - 132 - - 21 - - - 86 - - - - - - 85.1 - - 132 - - 20 - - - 88 - - - - - - 95.0 - - 132 - - 21 - - - 100 - - - - - - 105.0 - - 133 - - 22 - - - 127 - - - - - - 115.3 - - 134 - - 21 - - - 135 - - - - - - 125.8 - - 135 - - 21 - - - 139 - - - - - - 136.6 - - 136 - - 21 - - - 146 - - - - - - 147.2 - - 137 - - 22 - - - 150 - - - - - - 157.6 - - 139 - - 22 - - - 152 - - - - - - 167.8 - - 140 - - 21 - - - 146 - - - - - - 178.5 - - 140 - - 22 - - - 150 - - - - - - 188.5 - - 141 - - 21 - - - 155 - - - - - - 199.3 - - 141 - - 21 - - - 148 - - - - - - 209.4 - - 142 - - 22 - - - 151 - - - - - - 219.4 - - 142 - - 22 - - - 151 - - - - - - 230.2 - - 143 - - 22 - - - 148 - - - - - - 240.2 - - 144 - - 22 - - - 147 - - - - - - 250.1 - - 145 - - 23 - - - 150 - - - - - - 259.6 - - 145 - - 23 - - - 152 - - - - - - 270.3 - - 145 - - 23 - - - 152 - - - - - - 280.6 - - 145 - - 22 - - - 149 - - - - - - 290.7 - - 144 - - 22 - - - 150 - - - - - - 300.8 - - 145 - - 23 - - - 149 - - - - - - 311.1 - - 145 - - 22 - - - 152 - - - - - - 321.2 - - 145 - - 22 - - - 157 - - - - - - 331.9 - - 145 - - 21 - - - 150 - - - - - - 342.0 - - 146 - - 22 - - - 151 - - - - - - 352.4 - - 146 - - 22 - - - 151 - - - - - - 363.0 - - 146 - - 22 - - - 153 - - - - - - 373.4 - - 147 - - 22 - - - 152 - - - - - - 383.9 - - 147 - - 22 - - - 153 - - - - - - 394.6 - - 147 - - 22 - - - 152 - - - - - - 405.0 - - 147 - - 21 - - - 149 - - - - - - 415.3 - - 148 - - 22 - - - 152 - - - - - - 426.0 - - 148 - - 22 - - - 151 - - - - - - 436.5 - - 148 - - 21 - - - 149 - - - - - - 446.9 - - 148 - - 22 - - - 149 - - - - - - 456.9 - - 149 - - 22 - - - 156 - - - - - - 467.6 - - 149 - - 22 - - - 155 - - - - - - 478.5 - - 150 - - 22 - - - 156 - - - - - - 489.0 - - 150 - - 21 - - - 154 - - - - - - 499.1 - - 150 - - 21 - - - 148 - - - - - - 510.0 - - 150 - - 22 - - - 151 - - - - - - 519.9 - - 149 - - 22 - - - 153 - - - - - - 530.6 - - 149 - - 22 - - - 151 - - - - - - 540.8 - - 149 - - 22 - - - 148 - - - - - - 550.8 - - 148 - - 22 - - - 149 - - - - - - 560.8 - - 148 - - 22 - - - 144 - - - - - - 571.0 - - 147 - - 22 - - - 149 - - - - - - 580.7 - - 147 - - 22 - - - 150 - - - - - - 591.2 - - 147 - - 22 - - - 151 - - - - - - 601.4 - - 147 - - 22 - - - 150 - - - - - - 611.4 - - 147 - - 23 - - - 153 - - - - - - 621.8 - - 147 - - 23 - - - 151 - - - - - - 632.1 - - 147 - - 22 - - - 155 - - - - - - 642.3 - - 147 - - 22 - - - 154 - - - - - - 652.0 - - 148 - - 23 - - - 157 - - - - - - 662.7 - - 148 - - 23 - - - 162 - - - - - - 673.1 - - 148 - - 23 - - - 163 - - - - - - 683.6 - - 149 - - 22 - - - 163 - - - - - - 693.8 - - 149 - - 22 - - - 162 - - - - - - 703.8 - - 149 - - 22 - - - 164 - - - - - - 714.7 - - 150 - - 23 - - - 162 - - - - - - 724.9 - - 150 - - 22 - - - 162 - - - - - - 735.2 - - 151 - - 23 - - - 159 - - - - - - 745.4 - - 151 - - 22 - - - 158 - - - - - - 756.0 - - 151 - - 23 - - - 164 - - - - - - 766.3 - - 150 - - 22 - - - 163 - - - - - - 776.5 - - 150 - - 22 - - - 161 - - - - - - 786.9 - - 150 - - 23 - - - 163 - - - - - - 797.2 - - 150 - - 22 - - - 165 - - - - - - 807.8 - - 150 - - 23 - - - 166 - - - - - - 818.2 - - 150 - - 23 - - - 166 - - - - - - 828.4 - - 150 - - 22 - - - 168 - - - - - - 839.2 - - 150 - - 23 - - - 169 - - - - - - 849.6 - - 151 - - 23 - - - 166 - - - - - - 860.1 - - 151 - - 22 - - - 172 - - - - - - 870.3 - - 152 - - 22 - - - 172 - - - - - - 881.1 - - 152 - - 22 - - - 169 - - - - - - 891.7 - - 152 - - 23 - - - 167 - - - - - - 902.1 - - 152 - - 22 - - - 164 - - - - - - 913.1 - - 152 - - 22 - - - 161 - - - - - - 923.9 - - 153 - - 22 - - - 158 - - - - - - 934.6 - - 154 - - 21 - - - 158 - - - - - - 945.4 - - 154 - - 21 - - - 154 - - - - - - 956.0 - - 155 - - 21 - - - 155 - - - - - - 966.7 - - 155 - - 21 - - - 152 - - - - - - 977.4 - - 156 - - 21 - - - 150 - - - - - - 988.1 - - 156 - - 21 - - - 157 - - - - - - 998.8 - - 156 - - 21 - - - 155 - - - - - - 1009.6 - - 156 - - 21 - - - 151 - - - - - - 1020.6 - - 156 - - 21 - - - 147 - - - - - - 1031.5 - - 156 - - 20 - - - 145 - - - - - - 1042.5 - - 156 - - 21 - - - 144 - - - - - - 1053.3 - - 155 - - 20 - - - 145 - - - - - - 1064.1 - - 155 - - 21 - - - 147 - - - - - - 1075.3 - - 155 - - 20 - - - 142 - - - - - - 1086.1 - - 155 - - 20 - - - 136 - - - - - - 1097.5 - - 155 - - 21 - - - 141 - - - - - - 1108.5 - - 155 - - 20 - - - 146 - - - - - - 1119.2 - - 155 - - 20 - - - 143 - - - - - - 1130.6 - - 155 - - 20 - - - 143 - - - - - - 1141.3 - - 155 - - 20 - - - 143 - - - - - - 1152.4 - - 155 - - 21 - - - 142 - - - - - - 1163.3 - - 155 - - 20 - - - 138 - - - - - - 1173.8 - - 154 - - 20 - - - 141 - - - - - - 1184.8 - - 154 - - 21 - - - 146 - - - - - - 1195.8 - - 153 - - 21 - - - 146 - - - - - - 1206.6 - - 152 - - 21 - - - 141 - - - - - - 1217.3 - - 153 - - 21 - - - 141 - - - - - - 1227.8 - - 152 - - 21 - - - 140 - - - - - - 1238.7 - - 152 - - 21 - - - 143 - - - - - - 1249.5 - - 151 - - 21 - - - 149 - - - - - - 1260.1 - - 151 - - 20 - - - 141 - - - - - - 1270.9 - - 151 - - 21 - - - 141 - - - - - - 1281.8 - - 150 - - 21 - - - 145 - - - - - - 1292.7 - - 151 - - 20 - - - 142 - - - - - - 1303.4 - - 151 - - 20 - - - 141 - - - - - - 1314.3 - - 151 - - 21 - - - 141 - - - - - - 1325.2 - - 151 - - 21 - - - 146 - - - - - - 1336.1 - - 152 - - 20 - - - 143 - - - - - - 1346.9 - - 152 - - 21 - - - 144 - - - - - - 1357.4 - - 152 - - 20 - - - 141 - - - - - - 1368.1 - - 152 - - 21 - - - 138 - - - - - - 1379.0 - - 152 - - 20 - - - 142 - - - - - - 1389.5 - - 153 - - 21 - - - 145 - - - - - - 1399.9 - - 152 - - 21 - - - 138 - - - - - - 1410.7 - - 152 - - 20 - - - 139 - - - - - - 1422.0 - - 152 - - 20 - - - 139 - - - - - - 1432.8 - - 151 - - 20 - - - 141 - - - - - - 1443.6 - - 151 - - 21 - - - 146 - - - - - - 1454.4 - - 152 - - 20 - - - 143 - - - - - - 1465.1 - - 151 - - 21 - - - 143 - - - - - - 1475.9 - - 152 - - 21 - - - 145 - - - - - - 1486.6 - - 152 - - 21 - - - 148 - - - - - - 1497.4 - - 153 - - 21 - - - 143 - - - - - - 1508.2 - - 153 - - 20 - - - 140 - - - - - - 1519.2 - - 154 - - 20 - - - 144 - - - - - - 1530.0 - - 154 - - 21 - - - 143 - - - - - - 1540.9 - - 153 - - 20 - - - 141 - - - - - - 1551.3 - - 153 - - 21 - - - 143 - - - - - - 1562.6 - - 153 - - 21 - - - 146 - - - - - - 1573.3 - - 153 - - 20 - - - 141 - - - - - - 1584.2 - - 152 - - 20 - - - 139 - - - - - - 1594.6 - - 152 - - 21 - - - 145 - - - - - - 1606.0 - - 152 - - 21 - - - 143 - - - - - - 1616.2 - - 152 - - 20 - - - 138 - - - - - - 1627.4 - - 152 - - 21 - - - 140 - - - - - - 1638.0 - - 152 - - 21 - - - 144 - - - - - - 1649.2 - - 151 - - 20 - - - 143 - - - - - - 1660.2 - - 152 - - 20 - - - 143 - - - - - - 1670.8 - - 151 - - 20 - - - 142 - - - - - - 1681.4 - - 151 - - 21 - - - 140 - - - - - - 1692.1 - - 151 - - 21 - - - 140 - - - - - - 1702.5 - - 150 - - 21 - - - 141 - - - - - - 1713.7 - - 150 - - 21 - - - 144 - - - - - - 1724.4 - - 150 - - 21 - - - 146 - - - - - - 1735.1 - - 150 - - 20 - - - 141 - - - - - - 1745.6 - - 150 - - 21 - - - 140 - - - - - - 1756.3 - - 150 - - 21 - - - 141 - - - - - - 1766.2 - - 151 - - 20 - - - 142 - - - - - - 1777.1 - - 150 - - 22 - - - 138 - - - - - - 1787.5 - - 150 - - 21 - - - 138 - - - - - - 1797.7 - - 150 - - 22 - - - 140 - - - - - - 1808.4 - - 150 - - 21 - - - 140 - - - - - - 1818.4 - - 149 - - 21 - - - 138 - - - - - - 1828.9 - - 149 - - 22 - - - 146 - - - - - - 1839.9 - - 149 - - 21 - - - 142 - - - - - - 1850.5 - - 148 - - 21 - - - 142 - - - - - - 1861.2 - - 148 - - 21 - - - 145 - - - - - - 1871.9 - - 147 - - 21 - - - 143 - - - - - - 1882.6 - - 147 - - 20 - - - 139 - - - - - - 1893.3 - - 148 - - 20 - - - 140 - - - - - - 1904.3 - - 149 - - 21 - - - 144 - - - - - - 1915.4 - - 149 - - 20 - - - 148 - - - - - - 1926.2 - - 150 - - 20 - - - 139 - - - - - - 1937.3 - - 151 - - 20 - - - 140 - - - - - - 1947.8 - - 152 - - 20 - - - 144 - - - - - - 1959.1 - - 152 - - 20 - - - 142 - - - - - - 1969.8 - - 153 - - 20 - - - 140 - - - - - - 1980.6 - - 153 - - 21 - - - 143 - - - - - - 1991.4 - - 153 - - 21 - - - 143 - - - - - - 2000.0 - - 154 - - 21 - - - 147 - - - - - - <Element 'Notes' at 0x000002C71C48FE58> - - - - rowsandall.com/rowingdata - - - rowingdata - - - 0 - 75 - - Release - - EN - 000-00000-00 - - diff --git a/c6c032ca-da24-42cf-b61f-02816b7e2ccd.tcx b/c6c032ca-da24-42cf-b61f-02816b7e2ccd.tcx deleted file mode 100644 index 98408a5a..00000000 --- a/c6c032ca-da24-42cf-b61f-02816b7e2ccd.tcx +++ /dev/null @@ -1,2523 +0,0 @@ - - - - - 2016-05-20T13:41:26.962390+00:00 - - 537 - 2000 - 1 - - 148 - - - 156 - - Active - 21 - Manual - - - - 5.4 - - 127 - - 0 - - - 19 - - - - - - 13.1 - - 127 - - 19 - - - 26 - - - - - - 21.0 - - 128 - - 20 - - - 45 - - - - - - 30.3 - - 129 - - 20 - - - 64 - - - - - - 39.0 - - 130 - - 20 - - - 74 - - - - - - 48.2 - - 131 - - 21 - - - 80 - - - - - - 57.6 - - 131 - - 20 - - - 83 - - - - - - 66.4 - - 132 - - 20 - - - 87 - - - - - - 75.5 - - 132 - - 21 - - - 86 - - - - - - 85.1 - - 132 - - 20 - - - 88 - - - - - - 95.0 - - 132 - - 21 - - - 100 - - - - - - 105.0 - - 133 - - 22 - - - 127 - - - - - - 115.3 - - 134 - - 21 - - - 135 - - - - - - 125.8 - - 135 - - 21 - - - 139 - - - - - - 136.6 - - 136 - - 21 - - - 146 - - - - - - 147.2 - - 137 - - 22 - - - 150 - - - - - - 157.6 - - 139 - - 22 - - - 152 - - - - - - 167.8 - - 140 - - 21 - - - 146 - - - - - - 178.5 - - 140 - - 22 - - - 150 - - - - - - 188.5 - - 141 - - 21 - - - 155 - - - - - - 199.3 - - 141 - - 21 - - - 148 - - - - - - 209.4 - - 142 - - 22 - - - 151 - - - - - - 219.4 - - 142 - - 22 - - - 151 - - - - - - 230.2 - - 143 - - 22 - - - 148 - - - - - - 240.2 - - 144 - - 22 - - - 147 - - - - - - 250.1 - - 145 - - 23 - - - 150 - - - - - - 259.6 - - 145 - - 23 - - - 152 - - - - - - 270.3 - - 145 - - 23 - - - 152 - - - - - - 280.6 - - 145 - - 22 - - - 149 - - - - - - 290.7 - - 144 - - 22 - - - 150 - - - - - - 300.8 - - 145 - - 23 - - - 149 - - - - - - 311.1 - - 145 - - 22 - - - 152 - - - - - - 321.2 - - 145 - - 22 - - - 157 - - - - - - 331.9 - - 145 - - 21 - - - 150 - - - - - - 342.0 - - 146 - - 22 - - - 151 - - - - - - 352.4 - - 146 - - 22 - - - 151 - - - - - - 363.0 - - 146 - - 22 - - - 153 - - - - - - 373.4 - - 147 - - 22 - - - 152 - - - - - - 383.9 - - 147 - - 22 - - - 153 - - - - - - 394.6 - - 147 - - 22 - - - 152 - - - - - - 405.0 - - 147 - - 21 - - - 149 - - - - - - 415.3 - - 148 - - 22 - - - 152 - - - - - - 426.0 - - 148 - - 22 - - - 151 - - - - - - 436.5 - - 148 - - 21 - - - 149 - - - - - - 446.9 - - 148 - - 22 - - - 149 - - - - - - 456.9 - - 149 - - 22 - - - 156 - - - - - - 467.6 - - 149 - - 22 - - - 155 - - - - - - 478.5 - - 150 - - 22 - - - 156 - - - - - - 489.0 - - 150 - - 21 - - - 154 - - - - - - 499.1 - - 150 - - 21 - - - 148 - - - - - - 510.0 - - 150 - - 22 - - - 151 - - - - - - 519.9 - - 149 - - 22 - - - 153 - - - - - - 530.6 - - 149 - - 22 - - - 151 - - - - - - 540.8 - - 149 - - 22 - - - 148 - - - - - - 550.8 - - 148 - - 22 - - - 149 - - - - - - 560.8 - - 148 - - 22 - - - 144 - - - - - - 571.0 - - 147 - - 22 - - - 149 - - - - - - 580.7 - - 147 - - 22 - - - 150 - - - - - - 591.2 - - 147 - - 22 - - - 151 - - - - - - 601.4 - - 147 - - 22 - - - 150 - - - - - - 611.4 - - 147 - - 23 - - - 153 - - - - - - 621.8 - - 147 - - 23 - - - 151 - - - - - - 632.1 - - 147 - - 22 - - - 155 - - - - - - 642.3 - - 147 - - 22 - - - 154 - - - - - - 652.0 - - 148 - - 23 - - - 157 - - - - - - 662.7 - - 148 - - 23 - - - 162 - - - - - - 673.1 - - 148 - - 23 - - - 163 - - - - - - 683.6 - - 149 - - 22 - - - 163 - - - - - - 693.8 - - 149 - - 22 - - - 162 - - - - - - 703.8 - - 149 - - 22 - - - 164 - - - - - - 714.7 - - 150 - - 23 - - - 162 - - - - - - 724.9 - - 150 - - 22 - - - 162 - - - - - - 735.2 - - 151 - - 23 - - - 159 - - - - - - 745.4 - - 151 - - 22 - - - 158 - - - - - - 756.0 - - 151 - - 23 - - - 164 - - - - - - 766.3 - - 150 - - 22 - - - 163 - - - - - - 776.5 - - 150 - - 22 - - - 161 - - - - - - 786.9 - - 150 - - 23 - - - 163 - - - - - - 797.2 - - 150 - - 22 - - - 165 - - - - - - 807.8 - - 150 - - 23 - - - 166 - - - - - - 818.2 - - 150 - - 23 - - - 166 - - - - - - 828.4 - - 150 - - 22 - - - 168 - - - - - - 839.2 - - 150 - - 23 - - - 169 - - - - - - 849.6 - - 151 - - 23 - - - 166 - - - - - - 860.1 - - 151 - - 22 - - - 172 - - - - - - 870.3 - - 152 - - 22 - - - 172 - - - - - - 881.1 - - 152 - - 22 - - - 169 - - - - - - 891.7 - - 152 - - 23 - - - 167 - - - - - - 902.1 - - 152 - - 22 - - - 164 - - - - - - 913.1 - - 152 - - 22 - - - 161 - - - - - - 923.9 - - 153 - - 22 - - - 158 - - - - - - 934.6 - - 154 - - 21 - - - 158 - - - - - - 945.4 - - 154 - - 21 - - - 154 - - - - - - 956.0 - - 155 - - 21 - - - 155 - - - - - - 966.7 - - 155 - - 21 - - - 152 - - - - - - 977.4 - - 156 - - 21 - - - 150 - - - - - - 988.1 - - 156 - - 21 - - - 157 - - - - - - 998.8 - - 156 - - 21 - - - 155 - - - - - - 1009.6 - - 156 - - 21 - - - 151 - - - - - - 1020.6 - - 156 - - 21 - - - 147 - - - - - - 1031.5 - - 156 - - 20 - - - 145 - - - - - - 1042.5 - - 156 - - 21 - - - 144 - - - - - - 1053.3 - - 155 - - 20 - - - 145 - - - - - - 1064.1 - - 155 - - 21 - - - 147 - - - - - - 1075.3 - - 155 - - 20 - - - 142 - - - - - - 1086.1 - - 155 - - 20 - - - 136 - - - - - - 1097.5 - - 155 - - 21 - - - 141 - - - - - - 1108.5 - - 155 - - 20 - - - 146 - - - - - - 1119.2 - - 155 - - 20 - - - 143 - - - - - - 1130.6 - - 155 - - 20 - - - 143 - - - - - - 1141.3 - - 155 - - 20 - - - 143 - - - - - - 1152.4 - - 155 - - 21 - - - 142 - - - - - - 1163.3 - - 155 - - 20 - - - 138 - - - - - - 1173.8 - - 154 - - 20 - - - 141 - - - - - - 1184.8 - - 154 - - 21 - - - 146 - - - - - - 1195.8 - - 153 - - 21 - - - 146 - - - - - - 1206.6 - - 152 - - 21 - - - 141 - - - - - - 1217.3 - - 153 - - 21 - - - 141 - - - - - - 1227.8 - - 152 - - 21 - - - 140 - - - - - - 1238.7 - - 152 - - 21 - - - 143 - - - - - - 1249.5 - - 151 - - 21 - - - 149 - - - - - - 1260.1 - - 151 - - 20 - - - 141 - - - - - - 1270.9 - - 151 - - 21 - - - 141 - - - - - - 1281.8 - - 150 - - 21 - - - 145 - - - - - - 1292.7 - - 151 - - 20 - - - 142 - - - - - - 1303.4 - - 151 - - 20 - - - 141 - - - - - - 1314.3 - - 151 - - 21 - - - 141 - - - - - - 1325.2 - - 151 - - 21 - - - 146 - - - - - - 1336.1 - - 152 - - 20 - - - 143 - - - - - - 1346.9 - - 152 - - 21 - - - 144 - - - - - - 1357.4 - - 152 - - 20 - - - 141 - - - - - - 1368.1 - - 152 - - 21 - - - 138 - - - - - - 1379.0 - - 152 - - 20 - - - 142 - - - - - - 1389.5 - - 153 - - 21 - - - 145 - - - - - - 1399.9 - - 152 - - 21 - - - 138 - - - - - - 1410.7 - - 152 - - 20 - - - 139 - - - - - - 1422.0 - - 152 - - 20 - - - 139 - - - - - - 1432.8 - - 151 - - 20 - - - 141 - - - - - - 1443.6 - - 151 - - 21 - - - 146 - - - - - - 1454.4 - - 152 - - 20 - - - 143 - - - - - - 1465.1 - - 151 - - 21 - - - 143 - - - - - - 1475.9 - - 152 - - 21 - - - 145 - - - - - - 1486.6 - - 152 - - 21 - - - 148 - - - - - - 1497.4 - - 153 - - 21 - - - 143 - - - - - - 1508.2 - - 153 - - 20 - - - 140 - - - - - - 1519.2 - - 154 - - 20 - - - 144 - - - - - - 1530.0 - - 154 - - 21 - - - 143 - - - - - - 1540.9 - - 153 - - 20 - - - 141 - - - - - - 1551.3 - - 153 - - 21 - - - 143 - - - - - - 1562.6 - - 153 - - 21 - - - 146 - - - - - - 1573.3 - - 153 - - 20 - - - 141 - - - - - - 1584.2 - - 152 - - 20 - - - 139 - - - - - - 1594.6 - - 152 - - 21 - - - 145 - - - - - - 1606.0 - - 152 - - 21 - - - 143 - - - - - - 1616.2 - - 152 - - 20 - - - 138 - - - - - - 1627.4 - - 152 - - 21 - - - 140 - - - - - - 1638.0 - - 152 - - 21 - - - 144 - - - - - - 1649.2 - - 151 - - 20 - - - 143 - - - - - - 1660.2 - - 152 - - 20 - - - 143 - - - - - - 1670.8 - - 151 - - 20 - - - 142 - - - - - - 1681.4 - - 151 - - 21 - - - 140 - - - - - - 1692.1 - - 151 - - 21 - - - 140 - - - - - - 1702.5 - - 150 - - 21 - - - 141 - - - - - - 1713.7 - - 150 - - 21 - - - 144 - - - - - - 1724.4 - - 150 - - 21 - - - 146 - - - - - - 1735.1 - - 150 - - 20 - - - 141 - - - - - - 1745.6 - - 150 - - 21 - - - 140 - - - - - - 1756.3 - - 150 - - 21 - - - 141 - - - - - - 1766.2 - - 151 - - 20 - - - 142 - - - - - - 1777.1 - - 150 - - 22 - - - 138 - - - - - - 1787.5 - - 150 - - 21 - - - 138 - - - - - - 1797.7 - - 150 - - 22 - - - 140 - - - - - - 1808.4 - - 150 - - 21 - - - 140 - - - - - - 1818.4 - - 149 - - 21 - - - 138 - - - - - - 1828.9 - - 149 - - 22 - - - 146 - - - - - - 1839.9 - - 149 - - 21 - - - 142 - - - - - - 1850.5 - - 148 - - 21 - - - 142 - - - - - - 1861.2 - - 148 - - 21 - - - 145 - - - - - - 1871.9 - - 147 - - 21 - - - 143 - - - - - - 1882.6 - - 147 - - 20 - - - 139 - - - - - - 1893.3 - - 148 - - 20 - - - 140 - - - - - - 1904.3 - - 149 - - 21 - - - 144 - - - - - - 1915.4 - - 149 - - 20 - - - 148 - - - - - - 1926.2 - - 150 - - 20 - - - 139 - - - - - - 1937.3 - - 151 - - 20 - - - 140 - - - - - - 1947.8 - - 152 - - 20 - - - 144 - - - - - - 1959.1 - - 152 - - 20 - - - 142 - - - - - - 1969.8 - - 153 - - 20 - - - 140 - - - - - - 1980.6 - - 153 - - 21 - - - 143 - - - - - - 1991.4 - - 153 - - 21 - - - 143 - - - - - - 2000.0 - - 154 - - 21 - - - 147 - - - - - - <Element 'Notes' at 0x15038e80> - - - - rowsandall.com/rowingdata - - - rowingdata - - - 0 - 75 - - Release - - EN - 000-00000-00 - - diff --git a/requirements.txt b/requirements.txt index 707dd8b5..8f8eb580 100644 --- a/requirements.txt +++ b/requirements.txt @@ -174,7 +174,7 @@ ratelim==0.1.6 redis==3.2.1 requests==2.21.0 requests-oauthlib==1.2.0 -rowingdata==2.6.4 +rowingdata==2.6.7 rowingphysics==0.5.0 rq==0.13.0 rules==2.1 diff --git a/rowers/c2stuff.py b/rowers/c2stuff.py index 4a082f35..83d18ae7 100644 --- a/rowers/c2stuff.py +++ b/rowers/c2stuff.py @@ -14,6 +14,7 @@ import datetime from requests import Request, Session import rowers.mytypes as mytypes from rowers.mytypes import otwtypes +from rowers.rower_rules import is_workout_user,ispromember from iso8601 import ParseError import numpy @@ -155,7 +156,7 @@ def add_stroke_data(user,c2id,workoutid,startdatetime,csvfilename, def get_c2_workouts(rower): - if not isprorower(rower): + if not ispromember(rower.user): return 0 try: @@ -863,7 +864,7 @@ def workout_c2_upload(user,w): r = Rower.objects.get(user=user) # ready to upload. Hurray - if (checkworkoutuser(user,w)): + if (is_workout_user(user,w)): c2userid = get_userid(r.c2token) if not c2userid: raise NoTokenError("User has no token") diff --git a/rowers/dataprepnodjango.py b/rowers/dataprepnodjango.py index f41498fb..15f66293 100644 --- a/rowers/dataprepnodjango.py +++ b/rowers/dataprepnodjango.py @@ -140,10 +140,10 @@ def timedeltaconv(x): def rdata(file,rower=rrower()): try: - res = rrdata(file,rower=rower) + res = rrdata(csvfile=file,rower=rower) except IOError: try: - res = rrdata(file+'.gz',rower=rower) + res = rrdata(csvfile=file+'.gz',rower=rower) except IOError: res = 0 @@ -948,7 +948,7 @@ def smalldataprep(therows,xparam,yparam1,yparam2): f1 = workout.csvfilename try: - rowdata = dataprep(rrdata(f1).df) + rowdata = dataprep(rrdata(csvfile=f1).df) rowdata = pd.DataFrame({xparam: rowdata[xparam], yparam1: rowdata[yparam1], @@ -960,7 +960,7 @@ def smalldataprep(therows,xparam,yparam1,yparam2): df = pd.concat([df,rowdata],ignore_index=True) except IOError: try: - rowdata = dataprep(rrdata(f1+'.gz').df) + rowdata = dataprep(rrdata(csvfile=f1+'.gz').df) rowdata = pd.DataFrame({xparam: rowdata[xparam], yparam1: rowdata[yparam1], yparam2: rowdata[yparam2], diff --git a/rowers/decorators.py b/rowers/decorators.py index f9d03ed7..78dc7af6 100644 --- a/rowers/decorators.py +++ b/rowers/decorators.py @@ -4,6 +4,7 @@ from __future__ import print_function from __future__ import unicode_literals from django.contrib.auth.decorators import login_required,user_passes_test +from django.urls import reverse from django.http import HttpResponseRedirect from django.core.exceptions import PermissionDenied @@ -29,6 +30,9 @@ def user_passes_test(test_func, message=default_message,login_url=None,redirect_ def decorator(view_func): @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): + if request.user.is_anonymous: + url = reverse('login')+'?next='+request.path + return HttpResponseRedirect(url) if not test_func(request.user): messages.error(request, message) return HttpResponseRedirect(login_url) @@ -48,4 +52,3 @@ def login_required_message(function=None, message=default_message): if function: return actual_decorator(function) return actual_decorator - diff --git a/rowers/forms.py b/rowers/forms.py index 20882308..530c842d 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -1404,6 +1404,7 @@ class FlexAxesForm(forms.Form): extrametrics = kwargs.pop('extrametrics',[]) super(FlexAxesForm, self).__init__(*args, **kwargs) + rower = Rower.objects.get(user=request.user) axchoicespro = ( diff --git a/rowers/imports.py b/rowers/imports.py index fe1a85e6..d3a3ab01 100644 --- a/rowers/imports.py +++ b/rowers/imports.py @@ -43,7 +43,7 @@ from django.contrib.auth.decorators import login_required # from .models import Profile from rowingdata import rowingdata, make_cumvalues import pandas as pd -from rowers.models import Rower,Workout,checkworkoutuser,TombStone +from rowers.models import Rower,Workout,TombStone import rowers.mytypes as mytypes from rowsandall_app.settings import ( C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, @@ -54,7 +54,7 @@ from rowsandall_app.settings import ( from rowers.utils import ( NoTokenError, custom_exception_handler, ewmovingaverage, - geo_distance,isprorower,uniqify + geo_distance,uniqify ) @@ -144,7 +144,7 @@ def imports_do_refresh_token(refreshtoken,oauth_data,access_token=''): else: grant_type = post_data.pop('grant_type',None) - if oauth_data['bearer_auth']: + if oauth_data['bearer_auth']: headers['authorization'] = 'Bearer %s' % access_token baseurl = oauth_data['base_url'] @@ -159,7 +159,7 @@ def imports_do_refresh_token(refreshtoken,oauth_data,access_token=''): headers=headers) - + if response.status_code == 200 or response.status_code == 201: token_json = response.json() else: @@ -186,7 +186,7 @@ def imports_do_refresh_token(refreshtoken,oauth_data,access_token=''): expires_in = int(expires_in) except (TypeError,ValueError): expires_in = 0 - + return [thetoken,expires_in,refresh_token] @@ -199,20 +199,20 @@ def imports_get_token( client_secret = oauth_data['client_secret'] client_id = oauth_data['client_id'] base_uri = oauth_data['base_url'] - + client_auth = requests.auth.HTTPBasicAuth( client_id,client_secret ) - + post_data = {"grant_type": "authorization_code", "code": code, "redirect_uri": redirect_uri, "client_secret": client_secret, "client_id": client_id, } - + try: headers = oauth_data['headers'] except KeyError: @@ -229,7 +229,7 @@ def imports_get_token( else: grant_type = post_data.pop('grant_type',None) - + if 'json' in oauth_data['content_type']: response = requests.post( base_uri, @@ -262,7 +262,7 @@ def imports_get_token( else: return [0,0,0] - + return [thetoken,expires_in,refresh_token] # Make authorization URL including random string @@ -293,8 +293,8 @@ def imports_token_refresh(user,tokenname,refreshtokenname,expirydatename,oauth_d # for Strava transition if not refreshtoken: refreshtoken = getattr(r,tokenname) - - + + res = imports_do_refresh_token(refreshtoken,oauth_data) access_token = res[0] expires_in = res[1] @@ -309,4 +309,3 @@ def imports_token_refresh(user,tokenname,refreshtokenname,expirydatename,oauth_d r.save() return access_token - diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 428c1968..73c72151 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -2680,7 +2680,10 @@ def interactive_windchart(id=0,promember=0): if rowdata == 0: return 0 - dist = rowdata.df.loc[:,'cum_dist'] + try: + dist = rowdata.df.loc[:,'cum_dist'] + except KeyError: + return ['','No Data Found'] try: vwind = rowdata.df.loc[:,'vwind'] @@ -2770,7 +2773,10 @@ def interactive_streamchart(id=0,promember=0): if rowdata == 0: return "","No Valid Data Available" - dist = rowdata.df.loc[:,'cum_dist'] + try: + dist = rowdata.df.loc[:,'cum_dist'] + except KeyError: + return ['','No Data found'] try: vstream = rowdata.df.loc[:,'vstream'] diff --git a/rowers/mailprocessing.py b/rowers/mailprocessing.py index 37017602..fb275a11 100644 --- a/rowers/mailprocessing.py +++ b/rowers/mailprocessing.py @@ -64,18 +64,18 @@ def send_confirm(user, name, link, options): def rdata(file, rower=rrower()): """ Reads rowingdata data or returns 0 on Error """ try: - result = rrdata(file, rower=rower) + result = rrdata(csvfile=file, rower=rower) except IOError: try: - result = rrdata(file + '.gz', rower=rower) + result = rrdata(csvfile=file + '.gz', rower=rower) except IOError: result = 0 except TypeError: try: - result = rrdata(file) + result = rrdata(csvfile=file) except IOError: try: - result = rrdata(file+'.gz', rower=rower) + result = rrdata(csvfile=file+'.gz', rower=rower) except IOError: result = 0 diff --git a/rowers/models.py b/rowers/models.py index 01f49265..e412de4f 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -39,6 +39,10 @@ import pandas as pd from dateutil import parser import datetime +#from rules.contrib.models import RulesModel + +from rowers.rower_rules import * + from rowers.rows import validate_file_extension from collections import OrderedDict from timezonefinder import TimezoneFinder @@ -53,6 +57,10 @@ from rowsandall_app.settings import ( TWEET_CONSUMER_SECRET, ) + + +# END PERMISSIONS + tweetapi = twitter.Api(consumer_key=TWEET_CONSUMER_KEY, consumer_secret=TWEET_CONSUMER_SECRET, access_token_key=TWEET_ACCESS_TOKEN_KEY, @@ -322,14 +330,7 @@ class C2WorldClassAgePerformance(models.Model): return thestring -def is_not_basic(user): - if user.rower.rowerplan == 'basic': - raise ValidationError( - "Basic user cannot be team manager" - ) - -# For future Team functionality @python_2_unicode_compatible class Team(models.Model): choices = ( @@ -344,30 +345,28 @@ class Team(models.Model): name = models.CharField(max_length=150,unique=True,verbose_name='Team Name') notes = models.CharField(blank=True,max_length=200,verbose_name='Team Purpose') - manager = models.ForeignKey(User, null=True,on_delete=models.CASCADE) # validators=[is_not_basic]) + manager = models.ForeignKey(User, null=True,on_delete=models.CASCADE) private = models.CharField(max_length=30,choices=choices,default='open', verbose_name='Team Type') viewing = models.CharField(max_length=30,choices=viewchoices,default='allmembers',verbose_name='Sharing Behavior') + def __str__(self): return self.name def save(self, *args, **kwargs): manager = self.manager - if manager.rower.rowerplan == 'basic': - if manager.rower.protrialexpires < datetime.date.today() and manager.rower.plantrialexpires < datetime.date.today(): + if not can_have_teams(manager): raise ValidationError( "Basic user cannot be team manager" ) - if manager.rower.rowerplan in ['plan','pro']: - otherteams = Team.objects.filter(manager=manager) - if otherteams.count() >= 1: - raise ValidationError( - "Pro and Self-Coach users cannot have more than one team" - ) + if not can_add_team(manager): + raise ValidationError( + "Pro and Self-Coach users cannot have more than one team" + ) super(Team, self).save(*args,**kwargs) @@ -658,6 +657,9 @@ class CoachingGroup(models.Model): rs = Rower.objects.filter(coachinggroups__in=[self]) return rs.count() + def get_coaches(self): + return Rower.objects.filter(mycoachgroup=self) + # Extension of User with rowing specific data @python_2_unicode_compatible class Rower(models.Model): @@ -896,6 +898,20 @@ class Rower(models.Model): super(Rower, self).save(*args, **kwargs) + def get_managed_teams(self): + return Team.objects.filter(manager=self.user) + + def get_coaches(self): + coaches = [] + for group in self.coachinggroups.all(): + try: + coach = Rower.objects.get(mycoachgroup=group) + coaches.append(coach) + except Rower.DoesNotExist: + pass + + return coaches + class DeactivateUserForm(forms.ModelForm): class Meta: model = User @@ -925,18 +941,19 @@ class CoachOffer(models.Model): from django.db.models.signals import m2m_changed + def check_teams_on_change(sender, **kwargs): instance = kwargs.pop('instance', None) action = kwargs.pop('action', None) pk_set = kwargs.pop('pk_set',None) - if action == 'pre_add' and instance.rowerplan=='basic': - if instance.protrialexpires < datetime.date.today() and instance.plantrialexpires < datetime.date.today(): - for id in pk_set: - team = Team.objects.get(id=id) - if team.manager.rower.rowerplan not in ['coach']: - raise ValidationError( - "You cannot join a team led by a Pro, Free Coach Plan or Self-Coach user" - ) + if action == 'pre_add': + #if instance.protrialexpires < datetime.date.today() and instance.plantrialexpires < datetime.date.today(): + for id in pk_set: + team = Team.objects.get(id=id) + if not can_join_team(instance.user,team): + raise ValidationError( + "You cannot join a team led by a Pro, Free Coach Plan or Self-Coach user" + ) m2m_changed.connect(check_teams_on_change, sender=Rower.team.through) @@ -1165,95 +1182,7 @@ class BasePlannedSessionFormSet(BaseFormSet): return -# Check if workout is owned by this user -def checkworkoutuser(user,workout): - if user.is_anonymous: - return False - try: - r = Rower.objects.get(user=user) - if workout.user == r: - return True - coaches = [] - for group in workout.user.coachinggroups.all(): - coach = Rower.objects.get(mycoachgroup=group) - coaches.append(coach) - for coach in coaches: - if user.rower == coach and workout.privacy == 'visible': - return True - else: - return False - except Rower.DoesNotExist: - return False -# Check if workout may be viewed by this user -def checkworkoutuserview(user,workout): - if user.is_anonymous: - return False - try: - r = Rower.objects.get(user=user) - if workout.user == r: - return True - teams = workout.user.team.all() - - for team in teams: - if team in r.team.all(): - return True - return False - except Rower.DoesNotExist: - return False - - return False - -def checkviewworkouts(user,rower): - try: - r = user.rower - if rower == r: - return True - teams = Team.objects.filter(manager=user) - - if rower in Rower.objects.filter(team__in=teams): - return True - - if rower in Rower.objects.filter(coachinggroups__in=[user.rower.mycoachgroup]): - return True - - - except Rower.DoesNotExist: - return False - -# check if user is plan and rower is in his group -def checkaccessplanuser(user,rower): - try: - r = Rower.objects.get(user=user) - if rower == r: - return True - team_managers = [t.manager for t in rower.team.all() if t.manager.rower.rowerplan in ['plan','coach','freecoach']] - if user.rower.rowerplan != 'basic': - return user in team_managers - else: - return False - - return False - except Rower.DoesNotExist: - return False - -# Check if user is coach or rower -def checkaccessuser(user,rower): - try: - r = Rower.objects.get(user=user) - if rower == r: - return True - coaches = [] - for group in rower.coachinggroups.all(): - coach = Rower.objects.get(mycoachgroup=group) - coaches.append(coach) - for coach in coaches: - if user.rower == coach: - return True - else: - return False - except Rower.DoesNotExist: - return False timezones = ( (x,x) for x in pytz.common_timezones @@ -1354,6 +1283,18 @@ class TrainingTarget(models.Model): return stri +def check_trainingtarget_on_change(sender,**kwargs): + instance = kwargs.pop('instance',None) + action = kwargs.pop('action',None) + pk_set = kwargs.pop('pk_set',None) + if action == 'pre_add': + for id in pk_set: + rower = Rower.objects.get(id=id) + if not can_plan_user(instance.manager.user,rower): + raise ValidationError("You cannot add this rower. Not your coachee") + +m2m_changed.connect(check_trainingtarget_on_change, sender=TrainingTarget.rowers.through) + class TrainingTargetForm(ModelForm): class Meta: model = TrainingTarget @@ -1423,12 +1364,12 @@ class TrainingPlan(models.Model): def save(self, *args, **kwargs): manager = self.manager + if not can_add_plan(manager.user): + raise ValidationError( + "Basic user cannot have a training plan" + ) + - if manager.rowerplan in ['basic','pro']: - if manager.plantrialexpires < timezone.now().date(): - raise ValidationError( - "Basic user cannot have a training plan" - ) if self.enddate < self.startdate: startdate = self.startdate @@ -1439,6 +1380,13 @@ class TrainingPlan(models.Model): if not self.enddate <= self.startdate: super(TrainingPlan,self).save(*args, **kwargs) + # only add athletes that are allowed to be added + for rower in self.rowers.all(): + if can_plan_user(manager.user,rower): + self.rowers.add(rower) + else: + self.rowers.remove(rower) + if self.status: otherplans = TrainingPlan.objects.filter( status=True).exclude( @@ -1475,6 +1423,18 @@ class TrainingPlan(models.Model): else: createmacrofillers(self) +def check_trainingplan_on_change(sender, **kwargs): + instance = kwargs.pop('instance',None) + action = kwargs.pop('action',None) + pk_set = kwargs.pop('pk_set',None) + if action == 'pre_add': + for id in pk_set: + rower = Rower.objects.get(id=id) + if not can_plan_user(instance.manager.user,rower): + raise ValidationError("You cannot add this rower. Not your coachee") + +m2m_changed.connect(check_trainingplan_on_change, sender=TrainingPlan.rowers.through) + class TrainingPlanForm(ModelForm): class Meta: @@ -2158,11 +2118,10 @@ class PlannedSession(models.Model): manager = self.manager if self.sessiontype not in ['race','indoorrace']: - if manager.rower.rowerplan in ['basic','pro']: - if manager.rower.plantrialexpires < timezone.now().date(): - raise ValidationError( - "You must be a Self-Coach user or higher to create a planned session" - ) + if not can_add_session(self.manager): + raise ValidationError( + "You must be a Self-Coach user or higher to create a planned session" + ) # sort units @@ -2769,7 +2728,7 @@ class Workout(models.Model): def save(self, *args, **kwargs): user = self.user - if self.user.rowerplan == 'freecoach': + if not can_add_workout(user.user): raise forms.ValidationError("Free Coach User cannot have any workouts") super(Workout, self).save(*args, **kwargs) diff --git a/rowers/permissions.py b/rowers/permissions.py index 2d32add8..4950f910 100644 --- a/rowers/permissions.py +++ b/rowers/permissions.py @@ -22,7 +22,7 @@ class IsOwnerOrReadOnly(permissions.BasePermission): return obj.user == request.user class IsOwnerOrNot(permissions.BasePermission): - + def has_object_permission(self, request, view, obj): r = Rower.objects.get(user=request.user) return (obj.user == r) diff --git a/rowers/polarstuff.py b/rowers/polarstuff.py index dc4f397a..2466c1e7 100644 --- a/rowers/polarstuff.py +++ b/rowers/polarstuff.py @@ -38,7 +38,7 @@ from django.contrib.auth.decorators import login_required from rowingdata import rowingdata import pandas as pd from rowers.models import Rower,Workout -from rowers.models import checkworkoutuser + import rowers.dataprep as dataprep from rowers.dataprep import columndict @@ -50,7 +50,7 @@ from stravalib.exc import ActivityUploadFailed,TimeoutExceeded from django_mailbox.models import Message,Mailbox,MessageAttachment from rowsandall_app.settings import ( - POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET, + POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET, ) #baseurl = 'https://polaraccesslink.com/v3-example' @@ -79,7 +79,7 @@ def get_token(code): except TypeError: headers = { 'Authorization': 'Basic %s' % base64.b64encode( bytes(auth_string,'utf-8')).decode('utf-8') } - + response = requests.post("https://polarremote.com/v2/oauth2/token", data=post_data, headers=headers) @@ -110,7 +110,7 @@ def make_authorization_url(): import urllib url = "https://flow.polar.com/oauth2/authorization" +urllib.parse.urlencode(params) - + return HttpResponseRedirect(url) def get_polar_notifications(): @@ -130,13 +130,13 @@ def get_polar_notifications(): response = requests.get(url, headers=headers) available_data = [] - + if response.status_code == 200: available_data = response.json()['available-user-data'] - + return available_data -from rowers.utils import isprorower +from rowers.rower_rules import ispromember def get_all_new_workouts(available_data,testing=False): for record in available_data: @@ -146,7 +146,7 @@ def get_all_new_workouts(available_data,testing=False): try: r = Rower.objects.get(polaruserid=record['user-id']) u = r.user - if r.polar_auto_import and isprorower(r): + if r.polar_auto_import and ispromember(u): exercise_list = get_polar_workouts(u) if testing: print(exercise_list) @@ -154,13 +154,13 @@ def get_all_new_workouts(available_data,testing=False): pass return 1 - + def get_polar_workouts(user): r = Rower.objects.get(user=user) exercise_list = [] - + if (r.polartoken == '') or (r.polartoken is None): s = "Token doesn't exist. Need to authorize" return custom_exception_handler(401,s) @@ -195,7 +195,7 @@ def get_polar_workouts(user): uploadoptions, default_flow_style=False ) - + transactionid = response.json()['transaction-id'] url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}'.format( transactionid = transactionid, @@ -229,11 +229,11 @@ def get_polar_workouts(user): a = MessageAttachment(message=msg,document=filename[6:]) a.save() - + exercise_dict['filename'] = filename else: exercise_dict['filename'] = '' - + exercise_list.append(exercise_dict) # commit transaction @@ -280,7 +280,7 @@ def get_polar_user_info(user,physical=False): def get_polar_workout(user,id,transactionid): - + r = Rower.objects.get(user=user) if (r.polartoken == '') or (r.polartoken is None): s = "Token doesn't exist. Need to authorize" @@ -326,7 +326,7 @@ def get_polar_workout(user,id,transactionid): ) response = requests.get(url,headers = headers2) - + if response.status_code == 200: result = response.text # commit transaction @@ -337,7 +337,3 @@ def get_polar_workout(user,id,transactionid): return result return None - - - - diff --git a/rowers/rower_rules.py b/rowers/rower_rules.py new file mode 100644 index 00000000..9a890920 --- /dev/null +++ b/rowers/rower_rules.py @@ -0,0 +1,708 @@ +import rules +import datetime + +# PERMISSIONS + +# USER permissions + +""" +USER permissions +- There are 5 types of user: basic, pro, plan, coach, freecoach +- These methods exist on user + - user.rower + - user.is_anonymous + - user.is_staff + +- These methods exist on rower + - rower.rowerplan + - rower.protrialexpires + - rower.plantrialexpires + - rower.mycoachgroup + - rower.coachinggroups + - rower.team + +- These Rules apply to Rowers + - Coach can have any number of groups + - test_permissions.PermissionFreeCoach.test_coach_groupmanager + - test_permissions.PermissionsBasicsTests.test_coach_groupmanager + - test_permissions.PermissionsViewTests.test_coach_groups_create + - Pro and Plan users can have one group and not more + - test_permissions.PermissionsFreeCoach.test_pro_groupmanager + - test_permissions.PermissionsViewTests.test_pro_groups_create + - Free Coach user cannot have workouts + - test_permissions.PermissionFreeCoach.test_add_workout_freecoach + - Free coach can create more than one group + - test_permissions.PermissionsFreeCoach.test_plan_groupmanager + - Free Coach & Plan (Self Coach) can create planned sessions and team planned sessions + - test_permissions.PermissionsFreeCoach.test_plan_create_session + - test_permissions.PermissionsFreeCoach.test_coach_create_session + - Pro cannot create planned sessions or team planned sessions + - test_permissions.PermissionsViewTests.test_pro_create_session + - Basic cannot join groups led by Free Coach + - test_permissions.PermissionFreeCoach.test_add_basic_pro_or_plan + - Coach can edit athlete settings (if in coachinggroup) + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_prefs + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_prefs_not + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_settings + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_settings_not + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_account + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_account_not + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_exportsettings + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_exportsettings_not + - Coach can upload a workout on behalf of athlete + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload_not + - Pro and Plan cannot upload a workout on behalf of athlete + - test_permissions.PermissionsViewTests.test_plan_edit_athlete_upload + - Coach can run analytics for athlete + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_analysis + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_analysis_not + - test_permissions.PermissionsViewTests.test_pro_edit_athlete_analysis + - Pro and Plan user cannot run analysis for members of their groups + - test_permissions.PermissionsViewTests.test_plan_edit_athlete_analysis + - Pro and Plan user cannot edit athlete sessings + - test_permissions.PermissionsViewTests.test_plan_edit_athlete_settings + - test_permissions.PermissionsViewTests.test_pro_edit_athlete_settings + - Self-Coach and Pro cannot create more than one group + - test_permissions.PermissionsFreeCoach.test_plan_groupmanager + - Pro users and higher can join group led by other Pro or higher user + - test_permissions.PermissionsFreeCoach.test_add_proplan_pro_or_plan + - Pro or basic cannot create planned sessions or team planned sessions + - test_permissions.PermissionsFreeCoach.test_pro_create_plannedsession + +""" + +# used in can_plan_user +@rules.predicate +def user_is_not_basic(user): + if user.rower.rowerplan != 'basic': + return True + + if user.rower.protrialexpires >= datetime.date.today() and user.rower.plantrialexpires >= datetime.date.today(): + return True + + return False + +@rules.predicate +def can_start_trial(user): + if user.is_anonymous: + return False + + + return user.rower.protrialexpires == datetime.date(1970,1,1) + +@rules.predicate +def can_start_plantrial(user): + if user.is_anonymous: + return False + + 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'] + +def is_paid_coach(user): + return user.rower.rowerplan == 'coach' + +@rules.predicate +def is_planmember(user): + try: + r = user.rower + except AttributeError: + return False + + return r.rowerplan in ['coach','plan'] # freecoach? + +@rules.predicate +def is_promember(user): + try: + r = user.rower + except AttributeError: + return False + + return r.rowerplan in ['pro','coach','plan'] # freecoach? + +@rules.predicate +def is_protrial(user): + try: + r = user.rower + except AttributeError: + return False + + if r.rowerplan == 'basic': + return r.protrialexpires >= datetime.date.today() + if r.rowerplan == 'freecoach': + if r.mycoachgroup is not None: + return len(r.mycoachgroup)>=4 + + return False + +ispromember = is_promember | is_protrial + +can_have_teams = ispromember | is_coach + +@rules.predicate +def can_add_team(user): + if is_coach(user): + return True + + if ispromember(user): + otherteams = user.rower.get_managed_teams() + if otherteams.count() == 0: + return True + + return False + +@rules.predicate +def can_add_plan(user): + return isplanmember(user) or is_coach(user) + +@rules.predicate +def can_add_workout(user): + if user.is_anonymous: + return False + + return user.rower.rowerplan != 'freecoach' + +@rules.predicate +def is_plantrial(user): + try: + r = user.rower + except AttributeError: + return False + + if r.rowerplan in ['basic','pro']: + return r.plantrialexpires >= datetime.date.today() + if r.rowerplan == 'freecoach': + if r.mycoachgroup is not None: + return len(r.mycoachgroup)>=4 + + return False + + +isplanmember = is_planmember | is_plantrial + +@rules.predicate +def can_add_session(user): + return isplanmember(user) or is_coach(user) + +# User / Coach relationships (Rower object) + +@rules.predicate +def can_plan(user): + return user.rower.rowerplan in ['plan','coach','freecoach'] + +# checks if rower is coach of user (or is user himself) +@rules.predicate +def is_coach_user(usercoach,userrower): + if usercoach == userrower: + return True + + if not is_coach(usercoach): + return False + + r = userrower.rower + + coaches = [] + + for group in r.coachinggroups.all(): + newcoaches = group.get_coaches() + for coach in newcoaches: + coaches.append(coach) + + for coach in coaches: + if usercoach.rower == coach: + return True + + return False + +# checks if rower is coach of user (or is user himself) +@rules.predicate +def is_anonymous_or_coach(usercoach,userrower): + print(usercoach,userrower) + if usercoach == userrower: + return True + + if userrower.is_anonymous and userrower.is_anonymous: + return True + + if not is_coach(usercoach): + return False + + r = userrower.rower + + coaches = [] + + for group in r.coachinggroups.all(): + newcoaches = group.get_coaches() + for coach in newcoaches: + coaches.append(coach) + + for coach in coaches: + if usercoach.rower == coach: + return True + + return False + +# check if rower and user are members of the same team +@rules.predicate +def is_rower_team_member(user,rower): + if user.rower == rower: + return True + + teams = rower.team.all() + + for team in teams: + if team.private == 'open': + if team in rower.team.all(): + return True + if team.manager == rower.user: + return True + + return False + +@rules.predicate +def can_add_workout_member(user,rower): + if not user: + return False + if user.is_anonymous: + return False + if user == rower.user: + return True + # only below tested - need test user == rower.user + return is_coach(user) and user.rower in rower.get_coaches() + +# check if user can plan for the rower +@rules.predicate +def can_plan_user(user,rower): + # user must have planning permission + if not can_plan(user): + return False + + # if has planning permission, can always plan for himself + if rower == user.rower: + return True + + teams = user.rower.get_managed_teams() + # free coach, plan etc cannot plan for basic + if not is_paid_coach(user) and user_is_not_basic(user): + for t in teams: + if rower in t.rower.all(): + return True + + # paying coach can plan for all kinds of rowers + if is_paid_coach(user): + for t in teams: + if rower in t.rower.all(): + return True + + return False + +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('rower.is_staff',is_staff) + +# WORKOUT permissions + +""" +WORKOUT permissions +- These methods exist on Workout + - workout.privacy + +- These rules apply to workouts + - User can add, delete and change their own workouts + - test_aworkouts + - Coach can add and change workouts for their athletes, but not delete + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_upload_not + - Basic, Pro and Plan user can view but cannot add or change an athlete's workout + - test_permissions.PermissionsViewTests.test_coach_edit_athlete_workout + - test_permissions.PermissionsViewTests.test_plan_edit_athlete_upload + - test_permissions.PermissionsViewTests.test_plan_edit_athlete_workout + - test_permissions.PermissionsViewTests.test_basic_edit_athelte_workout + - Anonymous users can view team members' workout (but not see list of workouts) + - test_aworkouts + + - Rules for Workouts are transferred to objects related to the Workout, + - Charts + - Video Analysis + - WorkoutComment? + +""" + +# check if user is owner or coach of owner of workout +@rules.predicate +def is_workout_user(user,workout): + if user.is_anonymous: + return False + + try: + r = user.rower + except AttributeError: + return False + + if workout.user == r: + return True + + return is_coach_user(user,workout.user.user) + +# check if user is in same team as owner of workout +@rules.predicate +def is_workout_team(user,workout): + if user.is_anonymous: + return False + + try: + r = user.rower + except AttributeError: + return False + + if workout.user == r: + return True + + return is_rower_team_member(user,workout.user) + +# check if user can see workout +@rules.predicate +def can_view_workout(user,workout): + if workout.privacy != 'private': + return True + return user.rower == workout.user + +can_change_workout = is_workout_user + +rules.add_perm('workout.change_workout',can_change_workout) # replaces checkworkoutuser +rules.add_perm('workout.view_workout',can_view_workout) # replaces checkworkoutuserview + + + +# checkviewworkouts + +# PLANNING permissions + +""" +- These rules apply to planning + - Free coach can create planned sessions and team planned sessions + - test_permissions.PermissionsViewTests.test_coach_create_session + - Self coach and higher can create planned sessions and team planned sessions + - test_permissions.PermissionsFreeCoach.test_plan_create_session + - test_permissions.PermissionsFreeCoach.test_coach_create_session + - Coach can create planned sessions and team planned sessions + - test_permissions.PermissionsFreeCoach.test_plan_create_session + - test_permissions.PermissionsFreeCoach.test_coach_create_session + - Self Coach and higher can create planned sessions and team planned sessions + - test_permissions.PermissionsViewTests.test_plan_create_session + - Pro or Basic cannot create planned sessions or team planned sessions + - test_permissions.PermissionsFreeCoach.test_pro_create_plannedsession + - test_permissions.PermissionsFreeCoach.test_basic_create_plannedsession + - WHO can comment (plannedsession_comment_view) + - Only Session manager can change session + - Strict View rules (stricter than workouts) + - Basic user cannot manage a training plan + + - TrainingTarget + - rules for view, add, change, delete + - TrainingPlan + - rules for view, add, change, delete + - Cycle + - inherits rules from TrainingPlan + - PlannedSession + - rules for view, add, change, delete, clone, save as template + - check team + + - Special rules for Race (cannot be edited ex post) + +""" + +# Training Target rules + +# untested can_view_target to can_delete_target +@rules.predicate +def can_view_target(user,target): + if user.is_anonymous: + return False + if user == target.manager.user: + return True + + # a target's coach can view as well + if is_coach_user(user,target.manager.user): + return True + + # the object can view as well + if user.rower in target.rowers.all(): + return True + +@rules.predicate +def can_change_target(user,target): + if user.is_anonymous: + return False + return user == target.manager.user + +@rules.predicate +def can_delete_target(user,target): + if user.is_anonymous: + return False + return user == target.manager.user + +rules.add_perm('target.view_target',can_view_target) +rules.add_perm('target.change_target',can_change_target) +rules.add_perm('target.delete_target',can_delete_target) + +@rules.predicate +def can_view_plan(user,plan): + if user.is_anonymous: + return False + if user == plan.manager.user: + return True + + # a plan's coach can view as well + # below untested + if is_coach_user(user,plan.manager.user): + return True + + # the object can view as well + if user.rower in plan.rowers.all(): + return True + +@rules.predicate +def can_change_plan(user,plan): + if user.is_anonymous: + return False + return user == plan.manager.user + +# below untested +@rules.predicate +def can_delete_plan(user,plan): + if user.is_anonymous: + return False + return user == plan.manager.user + + + +rules.add_perm('plan.view_plan',can_view_plan) +rules.add_perm('plan.change_plan',can_change_plan) +rules.add_perm('plan.delete_plan',can_delete_plan) +rules.add_perm('plan.can_add_plan',can_add_plan) + +# untested +@rules.predicate +def can_view_cycle(user,cycle): + try: + return can_view_cycle(user,cycle.plan) + except AttributeError: + return can_view_plan(user,cycle.plan) + + return False + +@rules.predicate +def can_change_cycle(user,cycle): + try: + return can_change_cycle(user,cycle.plan) + except AttributeError: + return can_change_plan(user,cycle.plan) + + return False + +@rules.predicate +def can_delete_cycle(user,cycle): + try: + return can_delete_cycle(user,cycle.plan) + except AttributeError: + return can_delete_plan(user,cycle.plan) + + return False + + +rules.add_perm('cycle.view_cycle',can_view_cycle) +rules.add_perm('cycle.change_cycle',can_change_cycle) +rules.add_perm('cycle.delete_cycle',can_delete_cycle) + + +# check if user has view access to session +@rules.predicate +def can_view_session(user,session): + if session.sessiontype in ['race','indoorrace']: + return True + if user.is_anonymous: + return False + # session manager can view session + if user == session.manager: + return True + # if you're a rower in the session you can view it + # below untested + if user.rower in session.rower.all(): + return True + # coach users can view sessions created by their team members + # below untested + if is_coach(user): + teams = user.rower.get_managed_teams() + teamusers = [member.u for member in t.rower.all()] + if session.manager in teamusers: + return True + + return False + +@rules.predicate +def can_change_session(user,session): + if user.is_anonymous: + return False + # session part of a race should not be changed through the session interface + if session.sessiontype in ['race','indoorrace']: + return False + if user == session.manager: + return True + + return False + +@rules.predicate +def can_delete_session(user,session): + if user.is_anonymous: + return False + + if session.sessiontype in ['race','indoorrace']: + return False + + if user == session.manager: + return True + + return False + + + +rules.add_perm('plannedsession.add_session',can_add_session) +rules.add_perm('plannedsession.view_session',can_view_session) +rules.add_perm('plannedsession.change_session',can_change_session) +rules.add_perm('plannedsession.delete_session',can_delete_session) + +# TEAM (group) permissions + +""" +- These methods exist on team + - team.manager + - team.private + +- These rules apply to a team + - A Pro or Plan rower can be manager of only 1 team + - test_permissions.PermissionsFreeCoach.test_pro_groupmanager + - test_permissions.PermissionsViewTests.test_pro_groups_create + - A coach can have any number of teams (as manager) + - test_permissions.PermissionsBasicTest.test_coach_groupmanager + - Basic user cannot manage a group + - test_permissions.PermissionsFreeCoach.test_basic_groupmanager + - Basic user cannot join groups led by Free Coach or Pro + - test_permissions.PermissionFreeCoach.test_add_basic_pro_or_plan + - Basic athletes can be member of Coach led group + - test_permissions.PermissionsBasicTest.test_add_coach + - Pro users (and higher) can join team led by other Pro (or higher) user + - test_permissions.PermissionsFreeCoach.test_add_proplan_pro_or_plan + - test_permissions.PermissionsViewTests.test_team_member_request_pro_pro + - test_permissions.PermissionsViewTests.test_team_member_request_basic_pro + - On downgrade, Coach users lose all but their oldest team (add test!) + +""" + +# check if user is manager of the team +@rules.predicate +def is_team_manager(user,team): + return team.manager == user + +# check is user is member of team - untested +@rules.predicate +def is_team_member(user,team): + members = team.rower.all() + return user in [member.user for member in members] + +# check if user can view team +@rules.predicate +def can_view_team(user,team): + # user based - below untested + if user.rower.rowerplan == 'basic' and team.manager.rower.rowerplan != 'coach': + return False + # team is public + if team.private == 'open': + return True + # team is private - below untested + return is_team_member(user,team) | is_team_manager(user,team) + +@rules.predicate +def can_change_team(user,team): + return is_team_manager(user,team) + +@rules.predicate +def can_delete_team(user,team): + return is_team_manager(user,team) + +@rules.predicate +def can_join_team(user,team): + return is_paid_coach(team.manager) or ispromember(user) + +# For Team functionality +rules.add_perm('teams.view_team',can_view_team) +rules.add_perm('teams.add_team',user_is_not_basic) +rules.add_perm('teams.change_team',can_change_team) +rules.add_perm('teams.delete_team',can_delete_team) + +# RACING permissions + +""" + - VirtualRace + - rules to add, view, delete, change + - GeoCourse + - rules to add, view, delete, change + - RaceLogo +""" + +@rules.predicate +def can_change_course(user,course): + if user.is_anonymous: + return False + + return course.manager == user.rower + +# untested +@rules.predicate +def can_delete_course(user,course): + if user.is_anonymous: + return False + + return course.manager == user.rower + +@rules.predicate +def can_delete_logo(user,logo): + if user.is_anonymous: + return False + + return logo.user == user + +@rules.predicate +def can_change_race(user,race): + if user.is_anonymous: + return False + + return race.manager == user + +# everybody can view or add a course +rules.add_perm('course.change_course',can_change_course) +rules.add_perm('course.delete_course',can_delete_course) + +rules.add_perm('racelogo.delete_logo',can_delete_logo) + +# everybody can view a race +rules.add_perm('virtualevent.change_race',can_change_race) +# can races be deleted? + + +# ANALYSIS permissions + +""" + - Conditions + - Alerts + - rules to add, view, delete, change + - cpdata +""" diff --git a/rowers/runkeeperstuff.py b/rowers/runkeeperstuff.py index 5e21b11a..4b2b3322 100644 --- a/rowers/runkeeperstuff.py +++ b/rowers/runkeeperstuff.py @@ -7,6 +7,8 @@ from __future__ import unicode_literals, absolute_import from rowers.imports import * import re +from rowers.rower_rules import is_workout_user + from rowsandall_app.settings import ( C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET, @@ -285,7 +287,7 @@ def workout_runkeeper_upload(user,w): # ready to upload. Hurray - if (checkworkoutuser(user,w)): + if (is_workout_user(user,w)): data = createrunkeeperworkoutdata(w) if not data: message = "Data error in Runkeeper Upload" diff --git a/rowers/sporttracksstuff.py b/rowers/sporttracksstuff.py index 2828a18f..28fc3168 100644 --- a/rowers/sporttracksstuff.py +++ b/rowers/sporttracksstuff.py @@ -18,6 +18,7 @@ from rowsandall_app.settings import ( ) import rowers.mytypes as mytypes +from rowers.rower_rules import is_workout_user oauth_data = { 'client_id': SPORTTRACKS_CLIENT_ID, @@ -265,7 +266,7 @@ def workout_sporttracks_upload(user,w): thetoken = sporttracks_open(user) - if (checkworkoutuser(user,w)): + if (is_workout_user(user,w)): data = createsporttracksworkoutdata(w) if not data: message = "Data error" diff --git a/rowers/stravastuff.py b/rowers/stravastuff.py index d8663c97..30e8ab61 100644 --- a/rowers/stravastuff.py +++ b/rowers/stravastuff.py @@ -18,6 +18,8 @@ queuehigh = django_rq.get_queue('low') from rowers.dataprep import columndict +from rowers.rower_rules import is_workout_user,ispromember + import stravalib from stravalib.exc import ActivityUploadFailed,TimeoutExceeded @@ -123,7 +125,7 @@ def get_strava_workout_list(user,limit_n=0): # gets all new Strava workouts for a rower def get_strava_workouts(rower): - if not isprorower(rower): + if not ispromember(rower.user): return 0 try: @@ -632,7 +634,7 @@ def workout_strava_upload(user,w): s = "Token doesn't exist. Need to authorize" raise NoTokenError("Your hovercraft is full of eels") else: - if (checkworkoutuser(user,w)): + if (is_workout_user(user,w)): try: tcxfile,tcxmesg = createstravaworkoutdata(w) if tcxfile: diff --git a/rowers/teams.py b/rowers/teams.py index 4c8ee0a4..aa1c8903 100644 --- a/rowers/teams.py +++ b/rowers/teams.py @@ -26,6 +26,8 @@ from rowers.models import ( CoachingGroup ) +from rowers.rower_rules import is_team_manager,is_team_member,is_coach + from rowers.tasks import ( handle_sendemail_invite, handle_sendemail_request, @@ -53,14 +55,15 @@ def handle_remove_workouts_team(ws,t): return 1 def handle_add_workouts_team(ws,t): - + for w in ws: w.team.add(t) return 1 def update_team(t,name,manager,private,notes,viewing): - if t.manager != manager: + + if not is_team_manager(manager,t): return (0,'You are not the manager of this team') try: t.name = name @@ -78,11 +81,11 @@ def create_team(name,manager,private='open',notes='',viewing='allmembers'): if manager.rower.rowerplan == 'basic': if manager.rower.protrialexpires < timezone.now().date() and manager.rower.plantrialexpires < timezone.now().date(): return (0,'You need to upgrade to a paid plan to establish a team') - if manager.rower.rowerplan not in ('coach','freecoach'): + if not is_coach(manager): ts = Team.objects.filter(manager=manager) if len(ts)>=1: return (0,'You need to upgrade to the Coach plan to have more than one team') - + try: t = Team(name=name,manager=manager,notes=notes, private=private,viewing=viewing) @@ -99,24 +102,11 @@ def remove_team(id): send_team_delete_mail(t,r) return t.delete() -#def set_teamplanexpires(rower): -# ts = Team.objects.filter(rower=rower) - -# texp = datetime.date(timezone.now()) - -# for t in ts: -# print t.name -# mr = Rower.objects.get(user=t.manager) -# if mr.teamplanexpires > texp: -# rower.teamplanexpires = mr.teamplanexpires - -# t.save() - return (1,'Updated rower team expiry') def add_coach(coach,rower): # get coaching group - + coachgroup = coach.mycoachgroup if coachgroup is None: coachgroup = CoachingGroup(name=coach.user.first_name) @@ -126,7 +116,7 @@ def add_coach(coach,rower): if get_coach_club_size(coach) invitation.issuedate+timedelta(days=inviteduration): revoke_invite(invitation.team.manager,invitation.id) return (0,'The invitation has expired') - + t = invitation.team result, comment = add_member(t.id,r) if not result: @@ -698,7 +683,7 @@ def process_coachoffer_code(user,code): return result else: send_coachoffer_accepted_email(rekwest) - + rekwest.delete() return result @@ -732,7 +717,7 @@ def send_coachrequest_accepted_email(rekwest): res = myqueue(queuehigh, handle_sendemail_coachrequest_accepted, email,coachname,name) - + def send_coachoffer_accepted_email(rekwest): coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name @@ -743,5 +728,3 @@ def send_coachoffer_accepted_email(rekwest): res = myqueue(queuehigh, handle_sendemail_coachoffer_accepted, coachemail,coachname,name) - - diff --git a/rowers/templates/menu_other.html b/rowers/templates/menu_other.html index fad56ed0..a3961006 100644 --- a/rowers/templates/menu_other.html +++ b/rowers/templates/menu_other.html @@ -14,7 +14,7 @@ {% else %}  Compare {% endif %} - +
  •  Upload
  • @@ -33,7 +33,7 @@
  • - + - - {% include 'menuscript.html' %} diff --git a/rowers/templates/menu_profile.html b/rowers/templates/menu_profile.html index bdeb6f54..05cf98f1 100644 --- a/rowers/templates/menu_profile.html +++ b/rowers/templates/menu_profile.html @@ -44,13 +44,13 @@ {% if user.is_authenticated and user|is_manager and rower %}

     

    -{% if user|coach_rowers %} +{% if request.user|coach_rowers %}