Merge branch 'release/v9.20'
This commit is contained in:
574
2a1bfe9f-acd8-4fbc-9b75-8caf203e4fcf.gpx
Normal file
574
2a1bfe9f-acd8-4fbc-9b75-8caf203e4fcf.gpx
Normal file
@@ -0,0 +1,574 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="Oregon 400t" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"><metadata><link href="http://www.garmin.com"><text>Garmin International</text></link><time>2016-05-20T15:41:26</time></metadata><trk><name>Export by rowingdata</name><trkseg> <trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:26+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:29.238150+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:32.148290+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:35.269000+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:38.152180+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:41.148270+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:44.148910+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:46.908250+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:49.819010+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:52.942510+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:55.639670+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:41:58.370000+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:01.188270+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:04.008300+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:06.888990+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:09.678900+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:12.469140+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:15.199010+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:17.963080+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:20.658340+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:23.538800+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:26.269790+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:28.848350+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:31.729550+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:34.398400+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:37.038360+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:39.499250+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:42.349070+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:45.079070+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:47.752890+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:50.452350+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:53.182630+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:55.789410+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:42:58.671890+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:01.338860+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:04.068490+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:06.862620+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:09.618500+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:12.379160+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:15.229200+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:17.963150+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:20.692490+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:23.628520+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:26.329210+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:29.148960+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:31.668570+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:34.490920+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:37.369250+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:40.189230+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:42.798860+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:45.708750+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:48.318590+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:51.199500+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:53.869290+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:56.572490+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:43:59.212410+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:01.912890+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:04.459350+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:07.249360+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:09.949930+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:12.619870+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:15.378800+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:18.049420+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:20.719440+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:23.298970+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:26.178820+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:28.669980+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:31.429270+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:34.042790+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:36.589070+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:39.412800+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:42.078870+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:44.783760+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:47.450710+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:50.149400+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:52.789720+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:55.429750+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:44:58.069700+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:00.742790+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:03.442700+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:06.139610+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:08.689490+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:11.479530+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:14.119610+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:16.792860+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:19.368950+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:22.158960+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:24.889580+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:27.558940+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:30.469760+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:33.259860+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:36.079590+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:38.899560+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:41.689980+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:44.568940+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:47.329670+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:50.149560+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:52.969660+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:55.879910+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:45:58.789690+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:01.729660+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:04.669610+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:07.549730+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:10.458930+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:13.488980+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:16.429320+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:19.519650+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:22.459630+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:25.338880+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:28.459530+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:31.401590+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:34.339560+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:37.309450+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:40.098920+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:43.039950+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:46.039490+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:48.979630+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:51.949590+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:54.709590+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:46:57.589710+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:00.503120+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:03.408950+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:06.323410+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:09.229670+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:12.198960+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:15.079930+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:17.989660+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:20.959680+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:23.869730+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:26.782970+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:29.688910+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:32.539570+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:35.449720+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:38.329080+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:41.148960+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:44.088880+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:47.150600+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:50.029750+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:52.998850+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:55.880360+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:47:58.789400+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:01.639760+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:04.492770+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:07.429530+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:10.373270+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:13.309500+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:16.279570+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:19.160740+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:21.948820+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:25.039520+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:27.949340+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:30.890880+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:33.648790+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:36.770050+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:39.499600+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:42.559140+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:45.439020+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:48.439810+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:51.379570+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:54.259600+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:48:57.139300+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:00.049550+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:02.838790+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:05.839540+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:08.749400+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:11.689540+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:14.538900+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:17.389440+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:20.058880+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:23.059530+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:25.880610+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:28.608730+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:31.582600+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:34.278700+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:37.068660+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:40.039460+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:42.889790+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:45.772580+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:48.708690+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:51.679450+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:54.499470+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:49:57.409440+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:00.439330+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:03.408680+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:06.378680+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:09.168860+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:12.229650+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:15.138650+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:18.049470+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:20.959460+00:00</time>
|
||||
</trkpt>
|
||||
<trkpt lat="0.0" lon="0.0">
|
||||
<time>2016-05-20T13:50:23.242360+00:00</time>
|
||||
</trkpt>
|
||||
</trkseg></trk></gpx>
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .tasks import app as celery_app
|
||||
|
||||
|
||||
|
||||
@@ -118,11 +118,11 @@ def get_latlon(id):
|
||||
rowdata = rdata(w.csvfilename)
|
||||
try:
|
||||
try:
|
||||
latitude = rowdata.df.ix[:, ' latitude']
|
||||
longitude = rowdata.df.ix[:, ' longitude']
|
||||
latitude = rowdata.df.loc[:, ' latitude']
|
||||
longitude = rowdata.df.loc[:, ' longitude']
|
||||
except KeyError:
|
||||
latitude = 0 * rowdata.df.ix[:, 'TimeStamp (sec)']
|
||||
longitude = 0 * rowdata.df.ix[:, 'TimeStamp (sec)']
|
||||
latitude = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
|
||||
longitude = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
|
||||
return [latitude, longitude]
|
||||
except AttributeError:
|
||||
return [pd.Series([]), pd.Series([])]
|
||||
@@ -964,7 +964,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
totaltime = row.df['TimeStamp (sec)'].max(
|
||||
) - row.df['TimeStamp (sec)'].min()
|
||||
try:
|
||||
totaltime = totaltime + row.df.ix[0, ' ElapsedTime (sec)']
|
||||
totaltime = totaltime + row.df.loc[:, ' ElapsedTime (sec)'].iloc[0]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -2077,37 +2077,37 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
return 0
|
||||
|
||||
rowdatadf.set_index([range(len(rowdatadf))], inplace=True)
|
||||
t = rowdatadf.ix[:, 'TimeStamp (sec)']
|
||||
t = pd.Series(t - rowdatadf.ix[0, 'TimeStamp (sec)'])
|
||||
t = rowdatadf.loc[:, 'TimeStamp (sec)']
|
||||
t = pd.Series(t - rowdatadf.loc[:, 'TimeStamp (sec)'].iloc[0])
|
||||
|
||||
row_index = rowdatadf.ix[:, ' Stroke500mPace (sec/500m)'] > 3000
|
||||
row_index = rowdatadf.loc[:, ' Stroke500mPace (sec/500m)'] > 3000
|
||||
rowdatadf.loc[row_index, ' Stroke500mPace (sec/500m)'] = 3000.
|
||||
|
||||
p = rowdatadf.ix[:, ' Stroke500mPace (sec/500m)']
|
||||
p = rowdatadf.loc[:, ' Stroke500mPace (sec/500m)']
|
||||
try:
|
||||
velo = rowdatadf.ix[:,' AverageBoatSpeed (m/s)']
|
||||
velo = rowdatadf.loc[:,' AverageBoatSpeed (m/s)']
|
||||
except KeyError:
|
||||
velo = 500./p
|
||||
|
||||
hr = rowdatadf.ix[:, ' HRCur (bpm)']
|
||||
spm = rowdatadf.ix[:, ' Cadence (stokes/min)']
|
||||
cumdist = rowdatadf.ix[:, 'cum_dist']
|
||||
power = rowdatadf.ix[:, ' Power (watts)']
|
||||
averageforce = rowdatadf.ix[:, ' AverageDriveForce (lbs)']
|
||||
drivelength = rowdatadf.ix[:, ' DriveLength (meters)']
|
||||
hr = rowdatadf.loc[:, ' HRCur (bpm)']
|
||||
spm = rowdatadf.loc[:, ' Cadence (stokes/min)']
|
||||
cumdist = rowdatadf.loc[:, 'cum_dist']
|
||||
power = rowdatadf.loc[:, ' Power (watts)']
|
||||
averageforce = rowdatadf.loc[:, ' AverageDriveForce (lbs)']
|
||||
drivelength = rowdatadf.loc[:, ' DriveLength (meters)']
|
||||
try:
|
||||
workoutstate = rowdatadf.ix[:, ' WorkoutState']
|
||||
workoutstate = rowdatadf.loc[:, ' WorkoutState']
|
||||
except KeyError:
|
||||
workoutstate = 0 * hr
|
||||
|
||||
peakforce = rowdatadf.ix[:, ' PeakDriveForce (lbs)']
|
||||
peakforce = rowdatadf.loc[:, ' PeakDriveForce (lbs)']
|
||||
|
||||
forceratio = averageforce / peakforce
|
||||
forceratio = forceratio.fillna(value=0)
|
||||
|
||||
try:
|
||||
drivetime = rowdatadf.ix[:, ' DriveTime (ms)']
|
||||
recoverytime = rowdatadf.ix[:, ' StrokeRecoveryTime (ms)']
|
||||
drivetime = rowdatadf.loc[:, ' DriveTime (ms)']
|
||||
recoverytime = rowdatadf.loc[:, ' StrokeRecoveryTime (ms)']
|
||||
rhythm = 100. * drivetime / (recoverytime + drivetime)
|
||||
rhythm = rhythm.fillna(value=0)
|
||||
except:
|
||||
@@ -2152,7 +2152,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
else:
|
||||
drivenergy = drivelength * averageforce
|
||||
|
||||
distance = rowdatadf.ix[:, 'cum_dist']
|
||||
distance = rowdatadf.loc[:, 'cum_dist']
|
||||
velo = 500. / p
|
||||
|
||||
distanceperstroke = 60. * velo / spm
|
||||
@@ -2184,26 +2184,26 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
|
||||
if bands:
|
||||
# HR bands
|
||||
data['hr_ut2'] = rowdatadf.ix[:, 'hr_ut2']
|
||||
data['hr_ut1'] = rowdatadf.ix[:, 'hr_ut1']
|
||||
data['hr_at'] = rowdatadf.ix[:, 'hr_at']
|
||||
data['hr_tr'] = rowdatadf.ix[:, 'hr_tr']
|
||||
data['hr_an'] = rowdatadf.ix[:, 'hr_an']
|
||||
data['hr_max'] = rowdatadf.ix[:, 'hr_max']
|
||||
data['hr_ut2'] = rowdatadf.loc[:, 'hr_ut2']
|
||||
data['hr_ut1'] = rowdatadf.loc[:, 'hr_ut1']
|
||||
data['hr_at'] = rowdatadf.loc[:, 'hr_at']
|
||||
data['hr_tr'] = rowdatadf.loc[:, 'hr_tr']
|
||||
data['hr_an'] = rowdatadf.loc[:, 'hr_an']
|
||||
data['hr_max'] = rowdatadf.loc[:, 'hr_max']
|
||||
data['hr_bottom'] = 0.0 * data['hr']
|
||||
|
||||
try:
|
||||
tel = rowdatadf.ix[:, ' ElapsedTime (sec)']
|
||||
tel = rowdatadf.loc[:, ' ElapsedTime (sec)']
|
||||
except KeyError:
|
||||
rowdatadf[' ElapsedTime (sec)'] = rowdatadf['TimeStamp (sec)']
|
||||
|
||||
if barchart:
|
||||
# time increments for bar chart
|
||||
time_increments = rowdatadf.ix[:, ' ElapsedTime (sec)'].diff()
|
||||
time_increments = rowdatadf.loc[:, ' ElapsedTime (sec)'].diff()
|
||||
try:
|
||||
time_increments.ix[0] = time_increments.ix[1]
|
||||
time_increments.iloc[0] = time_increments.iloc[1]
|
||||
except KeyError:
|
||||
time_increments.ix[0] = 1.
|
||||
time_increments.iloc[0] = 1.
|
||||
|
||||
time_increments = 0.5 * time_increments + 0.5 * np.abs(time_increments)
|
||||
x_right = (t2 + time_increments.apply(lambda x: timedeltaconv(x)))
|
||||
@@ -2212,28 +2212,28 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
|
||||
if empower:
|
||||
try:
|
||||
wash = rowdatadf.ix[:, 'wash']
|
||||
wash = rowdatadf.loc[:, 'wash']
|
||||
except KeyError:
|
||||
wash = 0 * power
|
||||
|
||||
try:
|
||||
catch = rowdatadf.ix[:, 'catch']
|
||||
catch = rowdatadf.loc[:, 'catch']
|
||||
except KeyError:
|
||||
catch = 0 * power
|
||||
|
||||
try:
|
||||
finish = rowdatadf.ix[:, 'finish']
|
||||
finish = rowdatadf.loc[:, 'finish']
|
||||
except KeyError:
|
||||
finish = 0 * power
|
||||
|
||||
try:
|
||||
peakforceangle = rowdatadf.ix[:, 'peakforceangle']
|
||||
peakforceangle = rowdatadf.loc[:, 'peakforceangle']
|
||||
except KeyError:
|
||||
peakforceangle = 0 * power
|
||||
|
||||
if data['driveenergy'].mean() == 0:
|
||||
try:
|
||||
driveenergy = rowdatadf.ix[:, 'driveenergy']
|
||||
driveenergy = rowdatadf.loc[:, 'driveenergy']
|
||||
except KeyError:
|
||||
driveenergy = power * 60 / spm
|
||||
else:
|
||||
@@ -2246,7 +2246,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
drivelength = driveenergy / (averageforce * 4.44822)
|
||||
|
||||
try:
|
||||
slip = rowdatadf.ix[:, 'slip']
|
||||
slip = rowdatadf.loc[:, 'slip']
|
||||
except KeyError:
|
||||
slip = 0 * power
|
||||
|
||||
@@ -2319,11 +2319,11 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
|
||||
if otwpower:
|
||||
try:
|
||||
nowindpace = rowdatadf.ix[:, 'nowindpace']
|
||||
nowindpace = rowdatadf.loc[:, 'nowindpace']
|
||||
except KeyError:
|
||||
nowindpace = p
|
||||
try:
|
||||
equivergpower = rowdatadf.ix[:, 'equivergpower']
|
||||
equivergpower = rowdatadf.loc[:, 'equivergpower']
|
||||
except KeyError:
|
||||
equivergpower = 0 * p + 50.
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ def getsinglecp(df):
|
||||
|
||||
|
||||
dfnew = pd.DataFrame({
|
||||
'time':1000*(df['TimeStamp (sec)']-df.ix[0,'TimeStamp (sec)']),
|
||||
'time':1000*(df['TimeStamp (sec)']-df.loc[:,'TimeStamp (sec)'].iloc[0]),
|
||||
'power':df[' Power (watts)']
|
||||
})
|
||||
|
||||
@@ -304,14 +304,16 @@ def getmaxwattinterval(tt,ww,i):
|
||||
if len(w_roll):
|
||||
# now goes with # data points - should be fixed seconds
|
||||
indexmax = w_roll.idxmax(axis=1)
|
||||
# indexmaxpos = indexmax.get_loc(indexmax)
|
||||
indexmaxpos = indexmax
|
||||
try:
|
||||
t_0 = tt.ix[indexmax]
|
||||
t_1 = tt.ix[indexmax-i]
|
||||
deltas = tt.ix[indexmax-i:indexmax].diff().dropna()
|
||||
t_0 = tt.ix[indexmaxpos]
|
||||
t_1 = tt.ix[indexmaxpos-i]
|
||||
deltas = tt.ix[indexmaxpos-i:indexmaxpos].diff().dropna()
|
||||
testres = 1.0e-3*deltas.max() < 30.
|
||||
if testres:
|
||||
deltat = 1.0e-3*(t_0-t_1)
|
||||
wmax = w_roll.ix[indexmax]
|
||||
wmax = w_roll.ix[indexmaxpos]
|
||||
#if wmax > 800 or wmax*5.0e-4*deltat > 800.0:
|
||||
# wmax = 0
|
||||
else:
|
||||
|
||||
@@ -44,6 +44,7 @@ class BillingForm(forms.Form):
|
||||
max_digits=8)
|
||||
plan = forms.IntegerField(widget=forms.HiddenInput())
|
||||
payment_method_nonce = forms.CharField(max_length=255,required=True)
|
||||
tac= forms.BooleanField(required=True,initial=False)
|
||||
|
||||
|
||||
# login form
|
||||
|
||||
@@ -246,7 +246,7 @@ class PowerTimeFitnessMetric(models.Model):
|
||||
('water','On the water')
|
||||
)
|
||||
|
||||
date = models.DateField(default=timezone.now)
|
||||
date = models.DateField(default=datetime.date.today)
|
||||
last_workout = models.IntegerField(default=0)
|
||||
user = models.ForeignKey(User)
|
||||
PowerFourMin = models.FloatField(default=0)
|
||||
@@ -334,7 +334,7 @@ class TeamForm(ModelForm):
|
||||
class TeamInvite(models.Model):
|
||||
team = models.ForeignKey(Team)
|
||||
user = models.ForeignKey(User,null=True)
|
||||
issuedate = models.DateField(default=timezone.now)
|
||||
issuedate = models.DateField(default=datetime.date.today)
|
||||
code = models.CharField(max_length=150,unique=True)
|
||||
email = models.CharField(max_length=150,null=True,blank=True)
|
||||
|
||||
@@ -352,7 +352,7 @@ class TeamInviteForm(ModelForm):
|
||||
class TeamRequest(models.Model):
|
||||
team = models.ForeignKey(Team)
|
||||
user = models.ForeignKey(User,null=True)
|
||||
issuedate = models.DateField(default=timezone.now)
|
||||
issuedate = models.DateField(default=datetime.date.today)
|
||||
code = models.CharField(max_length=150,unique=True)
|
||||
|
||||
from utils import (
|
||||
@@ -655,8 +655,8 @@ class Rower(models.Model):
|
||||
|
||||
paidplan = models.ForeignKey(PaidPlan,null=True,default=None)
|
||||
|
||||
planexpires = models.DateField(default=timezone.now)
|
||||
teamplanexpires = models.DateField(default=timezone.now)
|
||||
planexpires = models.DateField(default=datetime.date.today)
|
||||
teamplanexpires = models.DateField(default=datetime.date.today)
|
||||
clubsize = models.IntegerField(default=0)
|
||||
protrialexpires = models.DateField(blank=True,null=True)
|
||||
plantrialexpires = models.DateField(blank=True,null=True)
|
||||
@@ -1022,10 +1022,10 @@ class GeoPoint(models.Model):
|
||||
|
||||
|
||||
def half_year_from_now():
|
||||
return timezone.now()+timezone.timedelta(days=182)
|
||||
return (timezone.now()+timezone.timedelta(days=182)).date()
|
||||
|
||||
def a_week_from_now():
|
||||
return timezone.now()+timezone.timedelta(days=7)
|
||||
return (timezone.now()+timezone.timedelta(days=7)).date()
|
||||
|
||||
# models related to training planning - draft
|
||||
# Do we need a separate class TestTarget?
|
||||
@@ -1089,20 +1089,6 @@ class TrainingTargetForm(ModelForm):
|
||||
|
||||
|
||||
|
||||
# SportTracks has a TrainingGoal like this
|
||||
#class TrainingGoal(models.Model):
|
||||
# rower = models.ForeignKey(Rower)
|
||||
# name = models.CharField(max_length=150,blank=True)
|
||||
# startdate = models.DateField(default=timezone.now)
|
||||
# enddate = models.DateField(
|
||||
# default=timezone.now()+datetime.timedelta(days=28))
|
||||
# goalmetric = models.CharField(max_length=150,default='rower',
|
||||
# choices = modechoices)
|
||||
# value = models.IntegerValue(default=1)
|
||||
|
||||
# I think we can use PlannedSession for that (in challenge mode)
|
||||
# although such a TrainingGoal could have automatically calculated
|
||||
# values without needing the user to assign
|
||||
|
||||
|
||||
class TrainingPlan(models.Model):
|
||||
@@ -1118,7 +1104,7 @@ class TrainingPlan(models.Model):
|
||||
name = models.CharField(max_length=150,blank=True)
|
||||
status = models.BooleanField(default=True,verbose_name='Active')
|
||||
target = models.ForeignKey(TrainingTarget,blank=True,null=True)
|
||||
startdate = models.DateField(default=timezone.now)
|
||||
startdate = models.DateField(default=datetime.date.today)
|
||||
enddate = models.DateField(
|
||||
default=half_year_from_now)
|
||||
|
||||
@@ -1482,7 +1468,7 @@ def macrocyclecheckdates(plan):
|
||||
class TrainingMacroCycle(models.Model):
|
||||
plan = models.ForeignKey(TrainingPlan)
|
||||
name = models.CharField(max_length=150,blank=True)
|
||||
startdate = models.DateField(default=timezone.now)
|
||||
startdate = models.DateField(default=datetime.date.today)
|
||||
enddate = models.DateField(
|
||||
default=half_year_from_now)
|
||||
notes = models.TextField(max_length=300,blank=True)
|
||||
@@ -1568,7 +1554,7 @@ class TrainingMacroCycleForm(ModelForm):
|
||||
class TrainingMesoCycle(models.Model):
|
||||
plan = models.ForeignKey(TrainingMacroCycle)
|
||||
name = models.CharField(max_length=150,blank=True)
|
||||
startdate = models.DateField(default=timezone.now)
|
||||
startdate = models.DateField(default=datetime.date.today)
|
||||
enddate = models.DateField(
|
||||
default=half_year_from_now)
|
||||
notes = models.TextField(max_length=300,blank=True)
|
||||
@@ -1643,7 +1629,7 @@ class TrainingMesoCycle(models.Model):
|
||||
class TrainingMicroCycle(models.Model):
|
||||
plan = models.ForeignKey(TrainingMesoCycle)
|
||||
name = models.CharField(max_length=150,blank=True)
|
||||
startdate = models.DateField(default=timezone.now)
|
||||
startdate = models.DateField(default=datetime.date.today)
|
||||
enddate = models.DateField(
|
||||
default=half_year_from_now)
|
||||
notes = models.TextField(max_length=300,blank=True)
|
||||
@@ -1790,7 +1776,7 @@ class PlannedSession(models.Model):
|
||||
comment = models.TextField(max_length=500,blank=True,
|
||||
)
|
||||
|
||||
startdate = models.DateField(default=timezone.now,
|
||||
startdate = models.DateField(default=datetime.date.today,
|
||||
verbose_name='On or After')
|
||||
|
||||
enddate = models.DateField(default=a_week_from_now,
|
||||
@@ -3302,10 +3288,10 @@ class RowerForm(ModelForm):
|
||||
# An announcement that goes to the right of the workouts list
|
||||
# optionally sends a tweet to our twitter account
|
||||
class SiteAnnouncement(models.Model):
|
||||
created = models.DateField(default=timezone.now)
|
||||
created = models.DateField(default=datetime.date.today)
|
||||
announcement = models.TextField(max_length=280)
|
||||
expires = models.DateField(default=timezone.now)
|
||||
modified = models.DateField(default=timezone.now)
|
||||
expires = models.DateField(default=datetime.date.today)
|
||||
modified = models.DateField(default=datetime.date.today)
|
||||
dotweet = models.BooleanField(default=False)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
as a price per year. You can downgrade or cancel your
|
||||
plan at any time, through the <a href="/rowers/me/edit/">settings page</a>.
|
||||
Please refer to our <a href="/rowers/legal/">terms and conditions</a> for our
|
||||
payments and refunds policy. Accepted payment methods are the payment methods offered
|
||||
payments and <a href="/rowers/legal/#refunds">refunds policy</a>.
|
||||
Accepted payment methods are the payment methods offered
|
||||
by
|
||||
<a href="https://www.braintreegateway.com/merchants/jytq7yxsm66qqdzb/verified">Braintree</a>
|
||||
through us. If you have any questions about our payments and refunds policy, please contact
|
||||
|
||||
@@ -72,6 +72,11 @@
|
||||
|
||||
<input type="hidden" id="nonce" name="payment_method_nonce" />
|
||||
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
|
||||
<p>
|
||||
<input id="tac" type="checkbox" name="tac" value="tac">I have taken note of the
|
||||
<a href="/rowers/legal/#refunds" target="_blank">Refund and Cancellation</a>
|
||||
Policy and agree with the <a href="/rowers/legal/" target="_blank">Terms of Service</a>.
|
||||
</p>
|
||||
{% csrf_token %}
|
||||
<button type="submit" id="submit-button"><span>Downgrade to the € {{ plan.price|currency }} plan</span></button>
|
||||
</form>
|
||||
|
||||
@@ -3,6 +3,52 @@
|
||||
{% block title %}Legal{% endblock title %}
|
||||
{% block main %}
|
||||
|
||||
<h1>Welcome to Rowsandall</h1>
|
||||
|
||||
<p>Welcome to Rowsandall. We want you to know and understand your rights and our rights relating
|
||||
to the provision o fthe Services (as defined below). Please review them carefully.
|
||||
Here are a few highlights:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
Your privacy is critically important to us. See how we collect and use your personal
|
||||
information in our <a href="#privacy">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#deactivation">You can cancel your membership or delete your account at any time.</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#content">You own your content, but give us a right to use it</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#conduct">We expect our members to act with respect and we can cancel
|
||||
your account if you act inappropriately</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#liability">Rowsandall is not liable for your activities and no warranties
|
||||
are made by Rowsandall</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#termination">
|
||||
We can cancel your account if you act inappropriately.
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#refunds">
|
||||
We offer paid plans with extended functionality. These are governed by
|
||||
our refund policy.
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#contact">
|
||||
There are easy ways to reach us if you have questions or need help.
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h1>Terms and Conditions</h1>
|
||||
<h2>Credit</h2>
|
||||
|
||||
@@ -32,7 +78,12 @@
|
||||
|
||||
</p>
|
||||
|
||||
<h2>Acceptable use</h2>
|
||||
<h2 id="conduct">Acceptable use</h2>
|
||||
|
||||
<p>You must not use this website to copy, store, host, transmit, sned, use, publish or
|
||||
distribute any material which is illegal, obscene, defamatory, threatening, harassing, abusive,
|
||||
or hateful or that advocates violence.
|
||||
</p>
|
||||
|
||||
<p>You must not use this website in any way that causes, or may cause, damage to the website or impairment of the availability or accessibility of the website; or in any way which is unlawful, illegal, fraudulent or harmful, or in connection with any unlawful, illegal, fraudulent or harmful purpose or activity.</p>
|
||||
|
||||
@@ -51,7 +102,7 @@
|
||||
|
||||
<p>rowsandall.com may disable your user ID and password in rowsandall.com’s sole discretion without notice or explanation.</p>
|
||||
|
||||
<h2>User content</h2>
|
||||
<h2 id="content">User content</h2>
|
||||
|
||||
<p>In these terms and conditions, <q>your user content</q> means material (including without limitation text, images, audio material, video material and audio-visual material) that you submit to this website, for whatever purpose.</p>
|
||||
|
||||
@@ -78,7 +129,7 @@
|
||||
|
||||
<p>Nothing on this website constitutes, or is meant to constitute, advice of any kind. If you require advice in relation to any legal, financial or medica] matter you should consult an appropriate professional.</p>
|
||||
|
||||
<h2>Limitations of liability</h2>
|
||||
<h2 id="liability">Limitations of liability</h2>
|
||||
|
||||
<p>rowsandall.com will not be liable to you (whether under the law of contact, the law of torts or otherwise) in relation to the contents of, or use of, or otherwise in connection with, this website:
|
||||
|
||||
@@ -136,6 +187,27 @@
|
||||
|
||||
<p>If a provision of these terms and conditions is determined by any court or other competent authority to be unlawful and/or unenforceable, the other provisions will continue in effect. If any unlawful and/or unenforceable provision would be lawful or enforceable if part of it were deleted, that part will be deemed to be deleted, and the rest of the provision will continue in effect. </p>
|
||||
|
||||
<h2 id="termination">Termination</h2>
|
||||
|
||||
<p>
|
||||
You agree that Rowsandall may, under certain circumstances and without prior notice,
|
||||
immediately terminate your accountand/or access to the site. Cause for such termination
|
||||
shall include, but not be limited to, (a) breaches or violations of the Terms or
|
||||
other incorporated agreements, policies, or guidelines, (b) requests by law enforcement
|
||||
or other government agencies, (c) a request by you (self-initiated account deletions),
|
||||
(d) discontinuance or material modification to the services (or any portion thereof), (e)
|
||||
unexpected technical or security issues or problems, f) extended periods of inactivity,
|
||||
and/or (g) nonpayment of any fees owed by you in connection with the Services.
|
||||
Termination of your account may include (x) removal of access to all offerings within the
|
||||
Services, (y) deletion of your information, files and Content associated with your account,
|
||||
and (z) barring of further use of the Services. Further, you agree that all terminations
|
||||
for cause shall be made in Rowsandall’s sole discretion and that Strava shall not be liable
|
||||
to you or any third party for any termination of your account or access to the Services.
|
||||
The following Sections shall survive termination of your account
|
||||
and/or the Terms: Member Content Submitted to the Services, Proprietary Rights,
|
||||
Your Feedback, Disclaimer of Warranties and Liability, Indemnity, Applicable Laws and General.
|
||||
</p>
|
||||
|
||||
<h2>Entire agreement</h2>
|
||||
|
||||
<p>These terms and conditions constitute the entire agreement between you and rowsandall.com in relation to your use of this website, and supersede all previous agreements in respect of your use of this website.</p>
|
||||
@@ -145,7 +217,7 @@
|
||||
<p>These terms and conditions will be governed by and construed in accordance with Czech Law and any disputes relating to these terms and conditions will be subject to the exclusive jurisdiction of the courts of The Czech Republic.</p>
|
||||
|
||||
|
||||
<h2>rowsandall.com’s details</h2>
|
||||
<h2 id="contact">rowsandall.com’s details</h2>
|
||||
|
||||
<p>The rowsandall.com site is owned by Rowsandall s.r.o., Nové sady 988/2, Staré Brno, 602 00 Brno, Czech Republic (company identification number 070 48 572)</p>
|
||||
|
||||
@@ -156,7 +228,7 @@
|
||||
{% include "refunds.html" %}
|
||||
|
||||
|
||||
<h2>Privacy Policy</h2>
|
||||
<h2 id="privacy">Privacy Policy</h2>
|
||||
|
||||
{% include "privacypolicy.html" %}
|
||||
|
||||
|
||||
@@ -302,7 +302,11 @@
|
||||
|
||||
<h2>Terms and Conditions, Contact Information</h2>
|
||||
|
||||
<p>Our paid plans follow the <a href="/rowers/legal/">Terms and Conditions</a>.</p>
|
||||
<p>
|
||||
Before purchasing any of our paid plans, you must
|
||||
review and acknowledge our <a href="/rowers/legal/">Terms and Conditions</a>,
|
||||
and <a href="/rowers/legal#refunds">Refunds and Returns Policy</a>
|
||||
</p>
|
||||
|
||||
<p>Payments are made to "Rowsandall s.r.o.", with the following contact information:</p>
|
||||
<p><strong>Rowsandall s.r.o.</strong><br />
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
as a price per year. You can downgrade or cancel your
|
||||
plan at any time, through the <a href="/rowers/me/edit/">settings page</a>.
|
||||
Please refer to our <a href="/rowers/legal/">terms and conditions</a> for our
|
||||
payments and refunds policy. Accepted payment methods are the payment methods offered
|
||||
<a href="/rowers/legel/#refunds">payments and refunds policy</a>.
|
||||
Accepted payment methods are the payment methods offered
|
||||
by
|
||||
<a href="https://www.braintreegateway.com/merchants/jytq7yxsm66qqdzb/verified">Braintree</a>
|
||||
through us. If you have any questions about our payments and refunds policy, please contact
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Payments will be procesed by Braintree (A PayPal service):
|
||||
Payments will be processed by Braintree (A PayPal service):
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://www.braintreegateway.com/merchants/{{ BRAINTREE_MERCHANT_ID }}/verified" target="_blank">
|
||||
@@ -93,6 +93,11 @@
|
||||
|
||||
<input type="hidden" id="nonce" name="payment_method_nonce" />
|
||||
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
|
||||
<p>
|
||||
<input id="tac" type="checkbox" name="tac" value="tac">I have taken note of the
|
||||
<a href="/rowers/legal/#refunds" target="_blank">Refund and Cancellation</a>
|
||||
Policy and agree with the <a href="/rowers/legal/" target="_blank">Terms of Service</a>.
|
||||
</p>
|
||||
{% csrf_token %}
|
||||
<button type="submit" id="submit-button"><span>Pay € {{ plan.price|currency }}</span></button>
|
||||
</form>
|
||||
@@ -101,7 +106,6 @@
|
||||
|
||||
{% include 'braintreedropin.html' %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<a href="/rowers/sessions/multiclone/user/{{ rower.user.id }}/?when={{ timeperiod }}">
|
||||
Clone multiple sessions
|
||||
</a>
|
||||
<button class="button green small" type="submit">Submit</button>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
{{ dateshiftform.as_table }}
|
||||
</table>
|
||||
<p>
|
||||
<input name='workoutselectform' class="button green" type="submit" value="Submit">
|
||||
<input name='workoutselectform' type="submit" value="Submit">
|
||||
</p>
|
||||
<p>You can use the date and search forms above to search through all
|
||||
sessions.</p>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<a href="/rowers/sessions/{{ plannedsession.id }}/clone">Clone</a>
|
||||
</p>
|
||||
<p>
|
||||
<input class="button green" type="submit" value="Save">
|
||||
<input type="submit" value="Save">
|
||||
</p>
|
||||
<div id="id_guidance" class="padded">
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
posts.
|
||||
</p>
|
||||
|
||||
<h2>Data Deletion</h2>
|
||||
<h2 id="deactivation">Membership Cancellation and Data Deletion</h2>
|
||||
|
||||
<p>If you have previously consented to allow rowsandall.com to store and process your personal
|
||||
data in accordance with this privacy policy, and you wish to withdraw your conent,
|
||||
@@ -237,7 +237,7 @@
|
||||
edit your heart rate and power settings, as well as functional threshold information and the account information accessible on your
|
||||
settings page under the header "Account Information". The team manager is not able to access or change your passwords, team memberships,
|
||||
favorite charts, export settings, workflow layout, or secret tokens. Also, the team manager is not able to download all your data,
|
||||
not can he deactivate or delete your account.
|
||||
nor can he deactivate or delete your account.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -274,6 +274,7 @@
|
||||
has suitable GDPR compliant measures in place.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Inactive Users - accounts are deleted after 18 months</h2>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
<p>Thank you for shopping at Rowsandall.</p>
|
||||
<p id="refunds">Thank you for shopping at Rowsandall.</p>
|
||||
|
||||
|
||||
<h3>Digital products</h3>
|
||||
@@ -9,19 +9,36 @@
|
||||
of the plan, you can cancel the recurring payment. We do not issue refunds for payments
|
||||
regarding the current plan period.</p>
|
||||
|
||||
<p>We do not issue refunds for digital products once the order is
|
||||
confirmed and the product is sent.</p>
|
||||
<p>If you are not 100% satisfied with your purchase, you can get a refund or
|
||||
exhchange the product for another one.
|
||||
</p>
|
||||
|
||||
<p>You can return a product for up to 30 days from the date you purchased it.
|
||||
To be eligible for a refund, you need to contact us using the contact information
|
||||
below. To improve our service, we ask you to explain how the product did not meet
|
||||
your expectations. If your refund is approved, we will initiate a refund to your
|
||||
credit card (or original method of payment). You will receive the credit within
|
||||
a certain amount of days, depending on your card issuer's policies.
|
||||
</p>
|
||||
|
||||
|
||||
<p>We recommend contacting us for assistance if you experience any issues receiving
|
||||
our products.</p>
|
||||
|
||||
<h3>Upgrades and Downgrades</h3>
|
||||
<h3>Upgrades and Downgrades, Cancellations</h3>
|
||||
|
||||
Upgrades and downgrades between paid plans are effective immediately, but the billing cycle
|
||||
is not changed. Upgrades are charged a pro-rated amount for the current billing cycle. Downgrades
|
||||
will result in a credit on our accounts, leading to a lower charge at the beginning of the
|
||||
subsequent billing cycle.
|
||||
<p>
|
||||
Upgrades and downgrades between paid plans are effective immediately, but the billing cycle
|
||||
is not changed. Upgrades are charged a pro-rated amount for the current billing cycle. Downgrades
|
||||
will result in a credit on our accounts, leading to a lower charge at the beginning of the
|
||||
subsequent billing cycle.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
With the exception of an approved refund within 30 days of purchase (see above), we do not
|
||||
issue refunds upon cancellation of the plan. If you are eligible for a refund, contact
|
||||
us within 30 days of your purchase.
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Contact us</h3>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Payments will be procesed by Braintree (A PayPal service):
|
||||
Payments will be processed by Braintree (A PayPal service):
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://www.braintreegateway.com/merchants/{{ BRAINTREE_MERCHANT_ID }}/verified" target="_blank">
|
||||
@@ -93,6 +93,11 @@
|
||||
|
||||
<input type="hidden" id="nonce" name="payment_method_nonce" />
|
||||
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
|
||||
<p>
|
||||
<input id="tac" type="checkbox" name="tac" value="tac">I have taken note of the
|
||||
<a href="/rowers/legal/#refunds" target="_blank">Refund and Cancellation</a>
|
||||
Policy and agree with the <a href="/rowers/legal/" target="_blank">Terms of Service</a>.
|
||||
</p>
|
||||
{% csrf_token %}
|
||||
<button type="submit" id="submit-button"><span>Upgrade to the € {{ plan.price|currency }} plan</span></button>
|
||||
</form>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<input class="button green" type="submit" value="Save">
|
||||
<input type="submit" value="Save">
|
||||
</form>
|
||||
</li>
|
||||
{% for graph in graphs %}
|
||||
|
||||
@@ -4,7 +4,7 @@ pytestmark = pytest.mark.django_db
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
import re
|
||||
from nose_parameterized import parameterized
|
||||
from parameterized import parameterized
|
||||
from django.test import TestCase, Client,override_settings, RequestFactory, TransactionTestCase
|
||||
|
||||
from django.core.management import call_command
|
||||
@@ -30,13 +30,15 @@ from rowers.tasks import handle_makeplot
|
||||
from rowers.utils import serialize_list,deserialize_list
|
||||
from rowers.utils import NoTokenError
|
||||
from rowers.plannedsessions import get_dates_timeperiod
|
||||
from shutil import copyfile
|
||||
from shutil import copyfile, copy
|
||||
from nose.tools import assert_true
|
||||
from mock import Mock, patch
|
||||
from minimocktest import MockTestCase
|
||||
import pandas as pd
|
||||
import rowers.c2stuff as c2stuff
|
||||
|
||||
from django.core.urlresolvers import reverse, reverse_lazy
|
||||
|
||||
import json
|
||||
import numpy as np
|
||||
|
||||
@@ -107,7 +109,8 @@ def get_random_file(filename='rowers/tests/testdata/testdata.csv',name=''):
|
||||
else:
|
||||
newfilename = 'rowers/tests/testdata/temp/'+fromstring+uuid4().hex[:16]+'.'+extension
|
||||
|
||||
copyfile(filename,newfilename)
|
||||
# copyfile(filename,newfilename)
|
||||
copy(filename,newfilename)
|
||||
|
||||
thedict = {
|
||||
'row':row,
|
||||
|
||||
52
rowers/tests/test_aworkouts.py
Normal file
52
rowers/tests/test_aworkouts.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from statements import *
|
||||
|
||||
nu = datetime.datetime.now()
|
||||
|
||||
class WaterWorkoutViewTest(TestCase):
|
||||
def setUp(self):
|
||||
self.u = UserFactory()
|
||||
|
||||
self.r = Rower.objects.create(user=self.u,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='coach')
|
||||
|
||||
self.c = Client()
|
||||
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
|
||||
self.factory = RequestFactory()
|
||||
self.password = faker.word()
|
||||
self.u.set_password(self.password)
|
||||
self.u.save()
|
||||
|
||||
result = get_random_file(filename='rowers/tests/testdata/onwater.csv')
|
||||
|
||||
self.wwater = WorkoutFactory(user=self.r,
|
||||
csvfilename=result['filename'],
|
||||
starttime=result['starttime'],
|
||||
startdatetime=result['startdatetime'],
|
||||
duration=result['duration'],
|
||||
distance=result['totaldist']
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
@patch('rowers.dataprep.create_engine')
|
||||
@patch('rowers.dataprep.getsmallrowdata_db')
|
||||
def test_forcecurve(self, mocked_sqlalchemy, mocked_getsmallrowdata_db):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = reverse('workout_forcecurve_view',kwargs={'id':self.wwater.id})
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
form_data = {
|
||||
'workstrokesonly': True
|
||||
}
|
||||
|
||||
response = self.c.post(url,form_data)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
@@ -366,6 +366,7 @@ class PaymentTest(TestCase):
|
||||
'amount':'15.00',
|
||||
'plan': plans[1].id,
|
||||
'payment_method_nonce': 'aap',
|
||||
'tac':'tac',
|
||||
}
|
||||
|
||||
form = BillingForm(form_data)
|
||||
@@ -410,6 +411,7 @@ class PaymentTest(TestCase):
|
||||
'amount':'15.00',
|
||||
'plan': plans[1].id,
|
||||
'payment_method_nonce': 'aap',
|
||||
'tac':'tac',
|
||||
}
|
||||
|
||||
form = BillingForm(form_data)
|
||||
@@ -453,6 +455,7 @@ class PaymentTest(TestCase):
|
||||
'amount':'15.00',
|
||||
'plan': plans[1].id,
|
||||
'payment_method_nonce': 'aap',
|
||||
'tac':'tac',
|
||||
}
|
||||
|
||||
form = BillingForm(form_data)
|
||||
@@ -470,3 +473,138 @@ class PaymentTest(TestCase):
|
||||
expected_url = '/rowers/downgradecompleted/',
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
@patch('rowers.views.braintreestuff.create_subscription', side_effect=mock_create_subscription)
|
||||
def test_checkouts_view(self,mock_subscription):
|
||||
u = UserFactory()
|
||||
r = Rower.objects.create(user=u,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='coach',
|
||||
paymentprocessor='braintree',
|
||||
street_address = faker.street_address(),
|
||||
city = faker.city(),
|
||||
postal_code = faker.postalcode(),
|
||||
country = faker.country(),
|
||||
)
|
||||
|
||||
r.save()
|
||||
u.set_password(self.password)
|
||||
u.save()
|
||||
|
||||
plans = PaidPlan.objects.all().order_by('price')
|
||||
plan = plans[1]
|
||||
|
||||
form_data = {
|
||||
'amount':'15.00',
|
||||
'plan': plans[1].id,
|
||||
'payment_method_nonce': 'aap',
|
||||
}
|
||||
|
||||
form = BillingForm(form_data)
|
||||
self.assertTrue(not form.is_valid())
|
||||
|
||||
login = self.c.login(username=u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/checkouts/'
|
||||
|
||||
response = self.c.post(url, form_data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
self.assertRedirects(response,
|
||||
expected_url = '/rowers/checkout/{planid}/'.format(
|
||||
planid=plans[1].id),
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
|
||||
@patch('rowers.views.braintreestuff.update_subscription', side_effect=mock_update_subscription)
|
||||
def test_upgrade_checkouts_view(self,mock_subscription):
|
||||
u = UserFactory()
|
||||
r = Rower.objects.create(user=u,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='coach',
|
||||
paymentprocessor='braintree',
|
||||
street_address = faker.street_address(),
|
||||
city = faker.city(),
|
||||
postal_code = faker.postalcode(),
|
||||
country = faker.country(),
|
||||
)
|
||||
|
||||
r.save()
|
||||
u.set_password(self.password)
|
||||
u.save()
|
||||
|
||||
plans = PaidPlan.objects.all().order_by('price')
|
||||
plan = plans[1]
|
||||
|
||||
form_data = {
|
||||
'amount':'15.00',
|
||||
'plan': plans[1].id,
|
||||
'payment_method_nonce': 'aap',
|
||||
# 'tac':'tac',
|
||||
}
|
||||
|
||||
form = BillingForm(form_data)
|
||||
self.assertTrue(not form.is_valid())
|
||||
|
||||
login = self.c.login(username=u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/upgradecheckouts/'
|
||||
|
||||
response = self.c.post(url, form_data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
self.assertRedirects(response,
|
||||
expected_url = '/rowers/upgradecheckout/{planid}/'.format(
|
||||
planid=plans[1].id),
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
@patch('rowers.views.braintreestuff.update_subscription', side_effect=mock_update_subscription)
|
||||
def test_downgrade_checkouts_view(self,mock_subscription):
|
||||
u = UserFactory()
|
||||
r = Rower.objects.create(user=u,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='coach',
|
||||
paymentprocessor='braintree',
|
||||
street_address = faker.street_address(),
|
||||
city = faker.city(),
|
||||
postal_code = faker.postalcode(),
|
||||
country = faker.country(),
|
||||
)
|
||||
|
||||
r.save()
|
||||
u.set_password(self.password)
|
||||
u.save()
|
||||
|
||||
plans = PaidPlan.objects.all().order_by('price')
|
||||
plan = plans[1]
|
||||
|
||||
form_data = {
|
||||
'amount':'15.00',
|
||||
'plan': plans[1].id,
|
||||
'payment_method_nonce': 'aap',
|
||||
# 'tac':'tac',
|
||||
}
|
||||
|
||||
form = BillingForm(form_data)
|
||||
self.assertTrue(not form.is_valid())
|
||||
|
||||
login = self.c.login(username=u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/downgradecheckouts/'
|
||||
|
||||
response = self.c.post(url, form_data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
self.assertRedirects(response,
|
||||
expected_url = '/rowers/downgradecheckout/{planid}/'.format(
|
||||
planid=plans[1].id),
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#from __future__ import print_function
|
||||
from statements import *
|
||||
nu = datetime.datetime.now()
|
||||
from rowers.utils import allmonths,allsundays
|
||||
|
||||
import rowers.plannedsessions as plannedsessions
|
||||
|
||||
@@ -124,7 +125,8 @@ class TrainingPlanTest(TestCase):
|
||||
tested = True
|
||||
|
||||
# add test for creating new sessions
|
||||
def sessions_create(self):
|
||||
def test_sessions_create(self):
|
||||
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
@@ -150,8 +152,10 @@ class TrainingPlanTest(TestCase):
|
||||
'name': faker.word(),
|
||||
}
|
||||
|
||||
print 'posting to sessions/create'
|
||||
|
||||
form = PlannedSessionForm(post_data)
|
||||
self.assertEqual(form.is_valid())
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post(url,post_data)
|
||||
self.assertEqual(response.status_code,200)
|
||||
@@ -988,3 +992,542 @@ class MandatoryTestCompleteTest(TestCase):
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
class PlannedSessionsView(TestCase):
|
||||
def setUp(self):
|
||||
# user
|
||||
self.u = UserFactory()
|
||||
|
||||
self.r = Rower.objects.create(user=self.u,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='coach')
|
||||
self.r.save()
|
||||
self.c = Client()
|
||||
|
||||
self.u2 = UserFactory(username='testbasicuser')
|
||||
self.r2 = Rower.objects.create(user=self.u2,
|
||||
birthdate=faker.profile()['birthdate'],
|
||||
gdproptin=True,
|
||||
gdproptindate=timezone.now(),
|
||||
rowerplan='basic')
|
||||
|
||||
self.password2 = faker.word()
|
||||
self.u2.set_password(self.password2)
|
||||
self.u2.save()
|
||||
|
||||
self.team = Team.objects.create(
|
||||
name = faker.word(),
|
||||
notes = faker.text(),
|
||||
manager = self.u,
|
||||
)
|
||||
|
||||
self.r.team.add(self.team)
|
||||
self.r2.team.add(self.team)
|
||||
self.r.save()
|
||||
self.r2.save()
|
||||
|
||||
# workouts
|
||||
# workout 1 - 2019-01-13, rScore 69
|
||||
result = get_random_file(filename='rowers/tests/testdata/2019-01-13_session.csv',name='sprintervals')
|
||||
|
||||
|
||||
self.factory = RequestFactory()
|
||||
self.password = faker.word()
|
||||
self.u.set_password(self.password)
|
||||
self.u.save()
|
||||
|
||||
self.w1 = Workout.objects.create(
|
||||
name='sprintervals',
|
||||
notes=faker.text(),
|
||||
startdatetime = result['startdatetime'],
|
||||
starttime = result['starttime'],
|
||||
workouttype='rower',
|
||||
date=result['date'],
|
||||
duration=result['duration'],
|
||||
distance=result['totaldist'],
|
||||
csvfilename=result['filename'],
|
||||
trimp = 77,
|
||||
rscore = 69,
|
||||
hrtss = 43,
|
||||
normp = 236,
|
||||
user=self.u.rower,
|
||||
)
|
||||
|
||||
|
||||
# plan
|
||||
self.target = TrainingTarget.objects.create(
|
||||
name = faker.word(),
|
||||
manager = self.u.rower,
|
||||
notes = faker.text()
|
||||
)
|
||||
self.target.rowers.add(self.u.rower)
|
||||
self.target.save()
|
||||
|
||||
self.plan = TrainingPlan.objects.create(
|
||||
manager = self.u.rower,
|
||||
name = faker.word(),
|
||||
status=True,
|
||||
target = self.target,
|
||||
startdate=timezone.now().date(),
|
||||
enddate = self.target.date,
|
||||
)
|
||||
|
||||
self.plan.rowers.add(self.u.rower)
|
||||
self.plan.save()
|
||||
|
||||
# cycles
|
||||
self.macro = TrainingMacroCycle.objects.create(
|
||||
plan=self.plan,
|
||||
name=faker.word(),
|
||||
type='userdefined',
|
||||
notes = faker.text(),
|
||||
startdate = self.plan.startdate,
|
||||
enddate = self.plan.enddate,
|
||||
)
|
||||
|
||||
mesos = TrainingMesoCycle.objects.filter(plan=self.macro)
|
||||
for m in mesos:
|
||||
m.delete()
|
||||
|
||||
monthstarts = [d for d in allmonths(self.macro.startdate,self.macro.enddate)]
|
||||
monthstarts.append(self.macro.enddate)
|
||||
|
||||
for i in range(len(monthstarts)-1):
|
||||
firstday = monthstarts[i]
|
||||
lastday = monthstarts[i+1]-datetime.timedelta(days=1)
|
||||
if lastday < self.macro.enddate and i == len(monthstarts)-2:
|
||||
lastday = self.macro.enddate
|
||||
|
||||
meso = TrainingMesoCycle(startdate=firstday,
|
||||
enddate=lastday,
|
||||
plan=self.macro,
|
||||
name = '%s' % firstday.strftime("%B"),
|
||||
type = 'userdefined')
|
||||
meso.save()
|
||||
|
||||
mesos = TrainingMesoCycle.objects.filter(plan=self.macro)
|
||||
|
||||
for cycle in mesos:
|
||||
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
||||
for m in micros:
|
||||
m.delete()
|
||||
|
||||
sundays = [s for s in allsundays(cycle.startdate,cycle.enddate)]
|
||||
|
||||
if sundays and sundays[-1] < cycle.enddate:
|
||||
sundays = sundays+[cycle.enddate]
|
||||
elif not sundays:
|
||||
sundays = [cycle.enddate]
|
||||
|
||||
for i in range(len(sundays)):
|
||||
if i==0:
|
||||
monday = cycle.startdate
|
||||
else:
|
||||
monday = sundays[i]-datetime.timedelta(days=6)
|
||||
if monday < cycle.startdate:
|
||||
monday = cycle.startdate
|
||||
|
||||
nextsunday = sundays[i]
|
||||
|
||||
micro = TrainingMicroCycle(startdate=monday,
|
||||
enddate=nextsunday,
|
||||
plan=cycle,
|
||||
name = 'Week %s' % monday.isocalendar()[1],
|
||||
type='userdefined')
|
||||
micro.save()
|
||||
|
||||
|
||||
# sessions
|
||||
startdatetime = self.w1.startdatetime
|
||||
|
||||
startdate = (startdatetime-datetime.timedelta(days=1)).date()
|
||||
enddate = (startdatetime+datetime.timedelta(days=1)).date()
|
||||
preferreddate = startdatetime.date()
|
||||
|
||||
self.startdate = startdate
|
||||
self.enddate = enddate
|
||||
|
||||
self.ps_rscore = SessionFactory(
|
||||
startdate=startdate,enddate=enddate,
|
||||
sessiontype='test',
|
||||
sessionmode = 'rScore',
|
||||
criterium = 'none',
|
||||
sessionvalue = 69,
|
||||
sessionunit='None',
|
||||
preferreddate=preferreddate,
|
||||
manager=self.u,
|
||||
)
|
||||
|
||||
|
||||
self.ps_rscore.save()
|
||||
added = plannedsessions.add_rower_session(self.u.rower,self.ps_rscore)
|
||||
|
||||
self.ps_dist = SessionFactory(
|
||||
startdate=startdate,enddate=enddate,
|
||||
sessiontype='test',
|
||||
sessionmode = 'distance',
|
||||
criterium = 'none',
|
||||
sessionvalue = result['totaldist'],
|
||||
sessionunit='m',
|
||||
preferreddate=preferreddate,
|
||||
manager=self.u,
|
||||
)
|
||||
|
||||
|
||||
self.ps_dist.save()
|
||||
added = plannedsessions.add_rower_session(self.u.rower,self.ps_dist)
|
||||
|
||||
self.ps_time = SessionFactory(
|
||||
startdate=startdate,enddate=enddate,
|
||||
sessiontype='test',
|
||||
sessionmode = 'time',
|
||||
criterium = 'none',
|
||||
sessionvalue = 38,
|
||||
sessionunit='min',
|
||||
preferreddate=preferreddate,
|
||||
manager=self.u,
|
||||
)
|
||||
|
||||
|
||||
self.ps_time.save()
|
||||
added = plannedsessions.add_rower_session(self.u.rower,self.ps_time)
|
||||
|
||||
self.ps_trimp = SessionFactory(
|
||||
startdate=startdate,enddate=enddate,
|
||||
sessiontype='test',
|
||||
sessionmode = 'TRIMP',
|
||||
criterium = 'none',
|
||||
sessionvalue = 77,
|
||||
sessionunit='none',
|
||||
preferreddate=preferreddate,
|
||||
manager=self.u,
|
||||
)
|
||||
|
||||
|
||||
self.ps_trimp.save()
|
||||
added = plannedsessions.add_rower_session(self.u.rower,self.ps_trimp)
|
||||
added = plannedsessions.add_team_session(self.team,self.ps_trimp)
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
os.remove(self.w1.csvfilename)
|
||||
except (IOError, WindowsError):
|
||||
pass
|
||||
|
||||
def test_clone_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/{id}/clone/'.format(id=self.ps_trimp.id)
|
||||
today = datetime.date.today()
|
||||
b = datetime.date.today()-timezone.timedelta(today.weekday())
|
||||
e = b+timezone.timedelta(days=6)
|
||||
|
||||
expected_url = '/rowers/sessions/teamedit/5/'
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
self.assertRedirects(response,
|
||||
expected_url=expected_url,
|
||||
status_code=302,target_status_code=200)
|
||||
|
||||
def test_multiclone_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/multiclone/'
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
formdata = {
|
||||
'startdate':self.startdate,
|
||||
'enddate':self.enddate,
|
||||
}
|
||||
|
||||
form = DateRangeForm(formdata)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post(url,formdata)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
url = '/rowers/sessions/multiclone/?startdate={startdate}&enddate={enddate}'.format(
|
||||
startdate = self.startdate,
|
||||
enddate = self.enddate
|
||||
)
|
||||
|
||||
formdata = {
|
||||
'plannedsessions':[self.ps_time.id,self.ps_trimp.id],
|
||||
'shiftstartdate':datetime.date.today()+timezone.timedelta(days=6)
|
||||
}
|
||||
|
||||
form = PlannedSessionMultipleCloneForm(formdata)
|
||||
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
form = SessionDateShiftForm(formdata)
|
||||
|
||||
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post(url,formdata,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
def test_multicreate_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
# get something
|
||||
url = '/rowers/sessions/multicreate/user/1/extra/1/'
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
data = {}
|
||||
|
||||
data['csrf_token'] = response.context['csrf_token']
|
||||
|
||||
management_form = response.context['ps_formset'].management_form
|
||||
for i in 'TOTAL_FORMS', 'INITIAL_FORMS', 'MIN_NUM_FORMS', 'MAX_NUM_FORMS':
|
||||
data['%s-%s' % (management_form.prefix,i)] = management_form[i].value()
|
||||
|
||||
for i in range(response.context['ps_formset'].total_form_count()):
|
||||
current_form = response.context['ps_formset'].forms[i]
|
||||
|
||||
for field_name in current_form.fields:
|
||||
value = current_form[field_name].value()
|
||||
data['%s-%s' % (current_form.prefix, field_name)] = value if value is not None else ''
|
||||
|
||||
|
||||
# post data
|
||||
response = self.c.post(url,data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_teamcreate_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/teamcreate/'
|
||||
response = self.c.get(url)
|
||||
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
form_data = {
|
||||
'team':[self.team.id],
|
||||
'startdate': self.w1.startdatetime.date(),
|
||||
'enddate': (self.w1.startdatetime+datetime.timedelta(days=5)).date(),
|
||||
'preferreddate': self.w1.startdatetime.date(),
|
||||
'name': faker.word(),
|
||||
'sessiontype': 'session',
|
||||
'sessionmode': 'distance',
|
||||
'criterium': 'none',
|
||||
'sessionvalue': 13000,
|
||||
'sessionunit': 'm',
|
||||
'course': '',
|
||||
'comment':faker.text()
|
||||
}
|
||||
|
||||
plannedsessionform = PlannedSessionForm(form_data)
|
||||
|
||||
self.assertTrue(plannedsessionform.is_valid())
|
||||
|
||||
teamform = PlannedSessionTeamForm(self.u,form_data)
|
||||
|
||||
self.assertTrue(teamform.is_valid())
|
||||
|
||||
response = self.c.post(url,form_data,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
def test_teamedit_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
|
||||
url = '/rowers/sessions/teamedit/{id}/'.format(id=self.ps_trimp.id)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
s = self.w1.startdatetime.date().strftime("%Y-%m-%d")
|
||||
e = (self.w1.startdatetime+datetime.timedelta(days=5)).date().strftime("%Y-%m-%d")
|
||||
p = self.w1.startdatetime.date().strftime("%Y-%m-%d")
|
||||
|
||||
form_data = {
|
||||
'team':['1'],
|
||||
'startdate': s,
|
||||
'enddate': e,
|
||||
'preferreddate': p,
|
||||
'name': faker.word(),
|
||||
'sessiontype': 'session',
|
||||
'sessionmode': 'distance',
|
||||
'criterium': 'none',
|
||||
'sessionvalue': 13000,
|
||||
'sessionunit': 'm',
|
||||
'course': '',
|
||||
'comment':faker.text(),
|
||||
'members': ['{id1}'.format(id1=self.r.id)],
|
||||
'initial-startdate':s,
|
||||
'initial-enddate':e,
|
||||
'initial-preferreddate':p
|
||||
|
||||
}
|
||||
|
||||
|
||||
form = PlannedSessionForm(form_data,instance=self.ps_trimp)
|
||||
if not form.is_valid():
|
||||
print form.errors
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
form = PlannedSessionTeamForm(self.u,form_data)
|
||||
if not form.is_valid():
|
||||
print form.errors
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
form = PlannedSessionTeamMemberForm(self.ps_trimp,form_data)
|
||||
if not form.is_valid():
|
||||
print form.errors
|
||||
self.assertTrue(form.is_valid())
|
||||
response = self.c.post(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
def test_coach_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
d1 = (self.ps_trimp.startdate-datetime.timedelta(days=1)).strftime(
|
||||
"%Y-%m-%d")
|
||||
d2 = (self.ps_trimp.enddate+datetime.timedelta(days=1)).strftime(
|
||||
"%Y-%m-%d")
|
||||
|
||||
sps = plannedsessions.get_sessions_manager(self.u,teamid=0,
|
||||
enddate=d2,startdate=d1)
|
||||
|
||||
self.assertTrue(len(sps)>0)
|
||||
|
||||
url = '/rowers/sessions/coach/?when={d1}/{d2}'.format(
|
||||
d1=d1,
|
||||
d2=d2,
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
def test_plannedsessions_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/?when={d1}/{d2}'.format(
|
||||
d1=self.ps_trimp.startdate.strftime("%Y-%m%d"),
|
||||
d2=self.ps_trimp.enddate.strftime("%Y-%m%d")
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_plannedsessions_print_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/print/?when={d1}/{d2}'.format(
|
||||
d1=self.ps_trimp.startdate.strftime("%Y-%m%d"),
|
||||
d2=self.ps_trimp.enddate.strftime("%Y-%m%d")
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_plannedsession_manage_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/manage/session/{id}/?when={d1}/{d2}'.format(
|
||||
d1=self.ps_trimp.startdate.strftime("%Y-%m%d"),
|
||||
d2=self.ps_trimp.enddate.strftime("%Y-%m%d"),
|
||||
id=self.ps_trimp.id,
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_plannedsession_edit_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/{id}/edit/'.format(
|
||||
id=self.ps_time.id,
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
form_data = {
|
||||
'startdate': self.w1.startdatetime.date().strftime("%Y-%m-%d"),
|
||||
'enddate': (self.w1.startdatetime+datetime.timedelta(days=5)).date().strftime("%Y-%m-%d"),
|
||||
'preferreddate': self.w1.startdatetime.date().strftime("%Y-%m-%d"),
|
||||
'name': faker.word(),
|
||||
'sessiontype': 'session',
|
||||
'sessionmode': 'distance',
|
||||
'criterium': 'none',
|
||||
'sessionvalue': 13000,
|
||||
'sessionunit': 'm',
|
||||
'course': '',
|
||||
'comment':faker.text(),
|
||||
}
|
||||
|
||||
form = PlannedSessionForm(form_data,instance=self.ps_time)
|
||||
if not form.is_valid():
|
||||
print form.errors
|
||||
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
response = self.c.post(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
|
||||
def test_plannedsession_detach_view(self):
|
||||
|
||||
self.ps_time.startdate = self.w1.date-datetime.timedelta(days=3)
|
||||
self.ps_time.enddate = self.w1.date-datetime.timedelta(days=3)
|
||||
self.ps_time.save()
|
||||
|
||||
self.w1.plannedsession = self.ps_time
|
||||
self.w1.save()
|
||||
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/{psid}/detach/{id}/'.format(
|
||||
psid=self.ps_time.id,
|
||||
id = self.w1.id,
|
||||
)
|
||||
|
||||
response = self.c.get(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_plannedsession_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/{psid}/'.format(
|
||||
psid = self.ps_time.id
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
def test_plannedsession_delete_view(self):
|
||||
login = self.c.login(username=self.u.username, password=self.password)
|
||||
self.assertTrue(login)
|
||||
|
||||
url = '/rowers/sessions/{psid}/delete/'.format(
|
||||
psid = self.ps_time.id
|
||||
)
|
||||
|
||||
response = self.c.get(url)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
response = self.c.post(url,follow=True)
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#from __future__ import print_function
|
||||
from __future__ import print_function
|
||||
from statements import *
|
||||
nu = datetime.datetime.now()
|
||||
|
||||
@@ -262,10 +262,11 @@ class URLTests(TestCase):
|
||||
self.assertTrue(login)
|
||||
response = self.c.get(url,follow=True)
|
||||
if response.status_code != expected:
|
||||
print url
|
||||
print response.status_code
|
||||
print(url )
|
||||
print(response.status_code)
|
||||
|
||||
self.assertEqual(response.status_code,
|
||||
expected)
|
||||
expected)
|
||||
|
||||
html = BeautifulSoup(response.content,'html.parser')
|
||||
urls = [a['href'] for a in html.find_all('a')]
|
||||
@@ -274,10 +275,10 @@ class URLTests(TestCase):
|
||||
if u not in tested and 'rowers' in u and 'http' not in u and 'authorize' not in u and 'import' not in u and 'logout' not in u:
|
||||
response = self.c.get(u)
|
||||
if response.status_code not in [200,302]:
|
||||
print len(tested)
|
||||
print url
|
||||
print u
|
||||
print response.status_code
|
||||
print(len(tested))
|
||||
print(url)
|
||||
print(u)
|
||||
print(response.status_code)
|
||||
tested.append(u)
|
||||
self.assertIn(response.status_code,
|
||||
[200,302])
|
||||
|
||||
98
rowers/tests/testdata/onwater.csv
vendored
Normal file
98
rowers/tests/testdata/onwater.csv
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
,index, lapIdx,TimeStamp (sec), Horizontal (meters),GPS Split,GPS Speed, Cadence (stokes/min), HRCur (bpm),Stroke Count,cum_dist, Stroke500mPace (sec/500m), ElapsedTime (sec), Power (watts), DriveLength (meters), StrokeDistance (meters), DriveTime (ms), DragFactor, StrokeRecoveryTime (ms), AverageDriveForce (lbs), AverageBoatSpeed (m/s), PeakDriveForce (lbs), AverageDriveForce (N), PeakDriveForce (N), WorkoutState, Stroke Number,originalvelo,hr_ut2,hr_ut1,hr_at,hr_tr,hr_an,hr_max,lim_ut2,lim_ut1,lim_at,lim_tr,lim_an,lim_max,pw_ut2,pw_ut1,pw_at,pw_tr,pw_an,pw_max,limpw_ut2,limpw_ut1,limpw_at,limpw_tr,limpw_an
|
||||
0,0,0.0,1469705701.0,3.2,0.0,0.74,35.5,112,1,3.2,695.931477516,0.0,0,0,0,0,0,0,0,0.74,0,0.0,0.0,4,0,0.74,0.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
1,1,0.0,1469705702.6,8.6,0.0,2.07,38.5,113,2,8.6,228.8,1.59999990463,0,0,0,0,0,0,0,2.07,0,0.0,0.0,4,1,2.07,113.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
2,2,0.0,1469705704.5,15.1,0.0,3.36,38.5,115,3,15.1,153.336955279,3.5,0,0,0,0,0,0,0,3.36,0,0.0,0.0,4,3,3.35999999999,115.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
3,3,0.0,1469705705.6,21.4,0.0,4.09,39.0,115,4,21.4,124.977058407,4.59999990463,0,0,0,0,0,0,0,4.09,0,0.0,0.0,4,3,4.09,115.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
4,4,0.0,1469705707.5,28.8,0.0,4.43,38.5,118,5,28.8,112.083019815,6.5,0,0,0,0,0,0,0,4.43,0,0.0,0.0,4,5,4.42999999999,118.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
5,5,0.0,1469705708.8,36.2,0.0,4.64,37.5,125,6,36.2,106.442632632,7.79999995232,0,0,0,0,0,0,0,4.64,0,0.0,0.0,4,5,4.63999999999,125.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
6,6,0.0,1469705710.5,43.1,0.0,4.66,36.0,130,7,43.1,104.628021775,9.5,0,0,0,0,0,0,0,4.66,0,0.0,0.0,4,6,4.66,130.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
7,7,0.0,1469705712.2,52.0,0.0,4.76,34.0,135,8,52.0,106.01911804,11.2000000477,0,0,0,0,0,0,0,4.76,0,0.0,0.0,4,7,4.75999999999,135.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
8,8,0.0,1469705714.0,60.1,0.0,4.71,34.5,142,9,60.1,107.565165936,13.0,0,0,0,0,0,0,0,4.71,0,0.0,0.0,4,8,4.70999999998,142.0,0.0,0.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
9,9,0.0,1469705715.8,68.1,0.0,4.53,33.5,148,10,68.1,108.679681206,14.7999999523,0,0,0,0,0,0,0,4.53,0,0.0,0.0,4,9,4.53000000001,0.0,0.0,148.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
10,10,0.0,1469705717.6,76.3,0.0,4.44,32.5,154,11,76.3,109.466700689,16.5999999046,0,0,0,0,0,0,0,4.44,0,0.0,0.0,4,10,4.43999999998,0.0,0.0,154.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
11,11,0.0,1469705719.5,83.8,0.0,4.44,33.0,156,12,83.8,109.893487851,18.5,0,0,0,0,0,0,0,4.44,0,0.0,0.0,4,11,4.43999999998,0.0,0.0,156.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
12,12,0.0,1469705721.2,92.5,0.0,4.62,33.5,159,13,92.5,110.627456239,20.2000000477,0,0,0,0,0,0,0,4.62,0,0.0,0.0,4,12,4.62,0.0,0.0,159.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
13,13,0.0,1469705723.0,100.8,0.0,4.64,33.5,163,14,100.8,110.362782274,22.0,0,0,0,0,0,0,0,4.64,0,0.0,0.0,4,13,4.63999999999,0.0,0.0,0.0,163.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
14,14,0.0,1469705724.8,109.1,0.0,4.59,32.0,166,15,109.1,109.351182981,23.7999999523,0,0,0,0,0,0,0,4.59,0,0.0,0.0,4,14,4.58999999998,0.0,0.0,0.0,166.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
15,15,0.0,1469705726.8,118.1,0.0,4.52,32.5,168,16,118.1,108.636197885,25.7999999523,0,0,0,0,0,0,0,4.52,0,0.0,0.0,4,15,4.51999999998,0.0,0.0,0.0,0.0,168.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
16,16,0.0,1469705728.5,125.1,0.0,4.5,33.0,169,17,125.1,108.494979894,27.5,0,0,0,0,0,0,0,4.5,0,0.0,0.0,4,16,4.5,0.0,0.0,0.0,0.0,169.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
17,17,0.0,1469705730.4,134.7,0.0,4.66,33.5,171,18,134.7,109.232014911,29.4000000954,0,0,0,0,0,0,0,4.66,0,0.0,0.0,4,17,4.66,0.0,0.0,0.0,0.0,171.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
18,18,0.0,1469705732.2,143.0,0.0,4.66,32.5,172,19,143.0,109.4493854,31.2000000477,0,0,0,0,0,0,0,4.66,0,0.0,0.0,4,18,4.66,0.0,0.0,0.0,0.0,172.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
19,19,0.0,1469705734.0,151.2,0.0,4.58,33.0,172,20,151.2,109.222559423,33.0,0,0,0,0,0,0,0,4.58,0,0.0,0.0,4,19,4.57999999999,0.0,0.0,0.0,0.0,172.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
20,20,0.0,1469705735.8,159.4,0.0,4.52,33.0,173,21,159.4,109.097567302,34.7999999523,0,0,0,0,0,0,0,4.52,0,0.0,0.0,4,20,4.51999999998,0.0,0.0,0.0,0.0,173.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
21,21,0.0,1469705737.5,166.1,0.0,4.47,33.5,175,22,166.1,109.622785185,36.5,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,21,4.47000000001,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
22,22,0.0,1469705739.4,175.7,0.0,4.58,33.5,175,23,175.7,110.908884086,38.4000000954,0,0,0,0,0,0,0,4.58,0,0.0,0.0,4,22,4.57999999999,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
23,23,0.0,1469705741.2,183.8,0.0,4.57,32.5,175,24,183.8,111.571150665,40.2000000477,0,0,0,0,0,0,0,4.57,0,0.0,0.0,4,23,4.57,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
24,24,0.0,1469705743.0,191.8,0.0,4.47,33.0,175,25,191.8,111.781044645,42.0,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,24,4.47000000001,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
25,25,0.0,1469705744.8,199.8,0.0,4.39,32.0,176,26,199.8,111.973606594,43.7999999523,0,0,0,0,0,0,0,4.39,0,0.0,0.0,4,25,4.39,0.0,0.0,0.0,0.0,176.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
26,26,0.0,1469705746.7,207.8,0.0,4.39,32.5,176,27,207.8,112.082434148,45.7000000477,0,0,0,0,0,0,0,4.39,0,0.0,0.0,4,26,4.39,0.0,0.0,0.0,0.0,176.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
27,27,0.0,1469705748.6,216.7,0.0,4.49,33.0,174,28,216.7,112.462053887,47.5999999046,0,0,0,0,0,0,0,4.49,0,0.0,0.0,4,27,4.49000000001,0.0,0.0,0.0,0.0,174.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
28,28,0.0,1469705750.4,224.8,0.0,4.49,32.0,174,29,224.8,110.702820986,49.4000000954,0,0,0,0,0,0,0,4.49,0,0.0,0.0,4,28,4.49000000001,0.0,0.0,0.0,0.0,174.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
29,29,0.0,1469705752.5,232.9,0.0,4.47,33.0,174,30,232.9,111.287510895,51.5,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,30,4.47000000001,0.0,0.0,0.0,0.0,174.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
30,30,0.0,1469705754.0,240.9,0.0,4.48,32.0,175,31,240.9,113.880099386,53.0,0,0,0,0,0,0,0,4.48,0,0.0,0.0,4,30,4.48000000001,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
31,31,0.0,1469705755.8,248.9,0.0,4.43,32.0,175,32,248.9,117.397229535,54.7999999523,0,0,0,0,0,0,0,4.43,0,0.0,0.0,4,31,4.42999999999,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
32,32,0.0,1469705756.2,250.4,0.0,4.43,32.0,175,32,250.4,120.181532945,55.2000000477,0,0,0,0,0,0,0,4.43,0,0.0,0.0,4,32,4.42999999999,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
33,33,1.0,1469705757.6,5.7,0.0,3.62,30.5,160,1,256.1,121.464367621,56.5999999046,0,0,0,0,0,0,0,3.62,0,0.0,0.0,4,32,3.62000000001,0.0,0.0,160.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
34,34,1.0,1469705759.4,13.4,0.0,3.85,33.5,161,2,263.8,121.497391629,58.4000000954,0,0,0,0,0,0,0,3.85,0,0.0,0.0,4,33,3.85,0.0,0.0,0.0,161.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
35,35,1.0,1469705761.2,20.7,0.0,4.2,33.5,162,3,271.1,120.37982782,60.2000000477,0,0,0,0,0,0,0,4.2,0,0.0,0.0,4,34,4.19999999999,0.0,0.0,0.0,162.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
36,36,1.0,1469705763.0,29.2,0.0,4.47,33.5,162,4,279.6,118.387283716,62.0,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,35,4.47000000001,0.0,0.0,0.0,162.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
37,37,1.0,1469705764.8,37.3,0.0,4.47,33.0,164,5,287.7,115.233986774,63.7999999523,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,36,4.47000000001,0.0,0.0,0.0,164.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
38,38,1.0,1469705766.6,45.3,0.0,4.44,33.5,165,6,295.7,111.287510895,65.5999999046,0,0,0,0,0,0,0,4.44,0,0.0,0.0,4,37,4.43999999998,0.0,0.0,0.0,165.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
39,39,1.0,1469705768.5,53.5,0.0,4.42,33.5,165,7,303.9,111.718168135,67.5,0,0,0,0,0,0,0,4.42,0,0.0,0.0,4,38,4.41999999999,0.0,0.0,0.0,165.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
40,40,1.0,1469705770.2,60.7,0.0,4.38,32.0,167,8,311.1,113.471050335,69.2000000477,0,0,0,0,0,0,0,4.38,0,0.0,0.0,4,39,4.37999999998,0.0,0.0,0.0,167.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
41,41,1.0,1469705772.2,70.1,0.0,4.44,32.0,171,9,320.5,115.140584238,71.2000000477,0,0,0,0,0,0,0,4.44,0,0.0,0.0,4,40,4.43999999998,0.0,0.0,0.0,0.0,171.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
42,42,1.0,1469705774.1,77.8,0.0,4.3,32.0,172,10,328.2,116.273396972,73.0999999046,0,0,0,0,0,0,0,4.3,0,0.0,0.0,4,41,4.30000000002,0.0,0.0,0.0,0.0,172.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
43,43,1.0,1469705776.1,85.2,0.0,4.12,31.0,174,11,335.6,117.556791714,75.0999999046,0,0,0,0,0,0,0,4.12,0,0.0,0.0,4,42,4.12,0.0,0.0,0.0,0.0,174.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
44,44,1.0,1469705777.9,93.4,0.0,4.2,31.5,174,12,343.8,119.395508057,76.9000000954,0,0,0,0,0,0,0,4.2,0,0.0,0.0,4,43,4.19999999999,0.0,0.0,0.0,0.0,174.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
45,45,1.0,1469705779.9,101.5,0.0,4.21,32.0,176,13,351.9,121.165219651,78.9000000954,0,0,0,0,0,0,0,4.21,0,0.0,0.0,4,44,4.20999999999,0.0,0.0,0.0,0.0,176.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
46,46,1.0,1469705781.6,108.9,0.0,4.11,30.5,176,14,359.3,122.757318225,80.5999999046,0,0,0,0,0,0,0,4.11,0,0.0,0.0,4,45,4.10999999998,0.0,0.0,0.0,0.0,176.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
47,47,1.0,1469705783.6,116.9,0.0,4.02,32.0,175,15,367.3,123.722400388,82.5999999046,0,0,0,0,0,0,0,4.02,0,0.0,0.0,4,46,4.01999999999,0.0,0.0,0.0,0.0,175.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
48,48,1.0,1469705785.5,124.1,0.0,3.96,30.5,177,16,374.5,123.80237793,84.5,0,0,0,0,0,0,0,3.96,0,0.0,0.0,4,47,3.95999999999,0.0,0.0,0.0,0.0,177.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
49,49,1.0,1469705787.5,132.1,0.0,4.04,32.0,177,17,382.5,123.700282002,86.5,0,0,0,0,0,0,0,4.04,0,0.0,0.0,4,48,4.03999999999,0.0,0.0,0.0,0.0,177.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
50,50,1.0,1469705789.2,139.7,0.0,4.06,32.0,178,18,390.1,122.672370408,88.2000000477,0,0,0,0,0,0,0,4.06,0,0.0,0.0,4,49,4.05999999999,0.0,0.0,0.0,0.0,178.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
51,51,1.0,1469705791.1,146.7,0.0,4.09,33.0,178,19,397.1,121.011418513,90.0999999046,0,0,0,0,0,0,0,4.09,0,0.0,0.0,4,50,4.09,0.0,0.0,0.0,0.0,178.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
52,52,1.0,1469705793.1,155.4,0.0,4.27,31.0,177,20,405.8,119.62256154,92.0999999046,0,0,0,0,0,0,0,4.27,0,0.0,0.0,4,51,4.27000000001,0.0,0.0,0.0,0.0,177.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
53,53,1.0,1469705794.9,163.1,0.0,4.27,32.0,177,21,413.5,118.342215896,93.9000000954,0,0,0,0,0,0,0,4.27,0,0.0,0.0,4,52,4.27000000001,0.0,0.0,0.0,0.0,177.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
54,54,1.0,1469705797.1,171.6,0.0,4.24,31.5,178,22,422.0,117.740696015,96.0999999046,0,0,0,0,0,0,0,4.24,0,0.0,0.0,4,53,4.24,0.0,0.0,0.0,0.0,178.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
55,55,1.0,1469705798.6,179.3,0.0,4.22,32.0,179,23,429.7,117.599973684,97.5999999046,0,0,0,0,0,0,0,4.22,0,0.0,0.0,4,54,4.22000000001,0.0,0.0,0.0,0.0,179.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
56,56,1.0,1469705800.7,187.9,0.0,4.21,30.5,179,24,438.3,117.565167825,99.7000000477,0,0,0,0,0,0,0,4.21,0,0.0,0.0,4,55,4.20999999999,0.0,0.0,0.0,0.0,179.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
57,57,1.0,1469705802.5,195.8,0.0,4.28,30.5,180,25,446.2,117.967332124,101.5,0,0,0,0,0,0,0,4.28,0,0.0,0.0,4,56,4.27999999998,0.0,0.0,0.0,0.0,180.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
58,58,1.0,1469705804.5,204.3,0.0,4.22,30.5,180,26,454.7,118.489957355,103.5,0,0,0,0,0,0,0,4.22,0,0.0,0.0,4,57,4.22000000001,0.0,0.0,0.0,0.0,180.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
59,59,1.0,1469705806.4,212.2,0.0,4.2,30.5,180,27,462.6,118.763530461,105.400000095,0,0,0,0,0,0,0,4.2,0,0.0,0.0,4,58,4.19999999999,0.0,0.0,0.0,0.0,180.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
60,60,1.0,1469705808.5,221.4,0.0,4.26,29.5,180,28,471.8,117.583212735,107.5,0,0,0,0,0,0,0,4.26,0,0.0,0.0,4,59,4.25999999999,0.0,0.0,0.0,0.0,180.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
61,61,1.0,1469705810.4,229.8,0.0,4.17,30.5,180,29,480.2,119.140852815,109.400000095,0,0,0,0,0,0,0,4.17,0,0.0,0.0,4,60,4.16999999999,0.0,0.0,0.0,0.0,180.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
62,62,1.0,1469705812.3,236.6,0.0,4.11,33.5,181,30,487.0,121.480877381,111.299999952,0,0,0,0,0,0,0,4.11,0,0.0,0.0,4,61,4.10999999998,0.0,0.0,0.0,0.0,0.0,181.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
63,63,1.0,1469705814.0,244.8,0.0,4.24,33.5,181,31,495.2,122.38470448,113.0,0,0,0,0,0,0,0,4.24,0,0.0,0.0,4,62,4.24,0.0,0.0,0.0,0.0,0.0,181.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
64,64,1.0,1469705815.4,250.9,0.0,4.24,33.5,181,31,501.3,122.183234979,114.400000095,0,0,0,0,0,0,0,4.24,0,0.0,0.0,4,63,4.24,0.0,0.0,0.0,0.0,0.0,181.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
65,65,2.0,1469705816.3,0.9,0.0,3.66,28.0,158,1,502.2,121.2563172,115.299999952,0,0,0,0,0,0,0,3.66,0,0.0,0.0,4,63,3.66,0.0,0.0,158.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
66,66,2.0,1469705817.8,9.8,0.0,4.12,33.5,160,2,511.1,119.786227655,116.799999952,0,0,0,0,0,0,0,4.12,0,0.0,0.0,4,64,4.12,0.0,0.0,160.0,0.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
67,67,2.0,1469705819.6,18.0,0.0,4.44,32.5,162,3,519.3,117.678039467,118.599999905,0,0,0,0,0,0,0,4.44,0,0.0,0.0,4,65,4.43999999998,0.0,0.0,0.0,162.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
68,68,2.0,1469705821.5,26.1,0.0,4.47,33.0,161,4,527.4,115.319480659,120.5,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,66,4.47000000001,0.0,0.0,0.0,161.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
69,69,2.0,1469705823.4,35.0,0.0,4.43,32.0,164,5,536.3,112.531083761,122.400000095,0,0,0,0,0,0,0,4.43,0,0.0,0.0,4,67,4.42999999999,0.0,0.0,0.0,164.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
70,70,2.0,1469705825.1,41.9,0.0,4.43,33.0,165,6,543.2,109.693981917,124.099999905,0,0,0,0,0,0,0,4.43,0,0.0,0.0,4,68,4.42999999999,0.0,0.0,0.0,165.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
71,71,2.0,1469705827.1,51.5,0.0,4.6,33.5,166,7,552.8,110.111805834,126.099999905,0,0,0,0,0,0,0,4.6,0,0.0,0.0,4,69,4.6,0.0,0.0,0.0,166.0,0.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
72,72,2.0,1469705828.9,59.7,0.0,4.59,33.5,168,8,561.0,110.235734879,127.900000095,0,0,0,0,0,0,0,4.59,0,0.0,0.0,4,70,4.58999999998,0.0,0.0,0.0,0.0,168.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
73,73,2.0,1469705830.7,68.1,0.0,4.53,32.0,171,9,569.4,109.674351541,129.700000048,0,0,0,0,0,0,0,4.53,0,0.0,0.0,4,71,4.53000000001,0.0,0.0,0.0,0.0,171.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
74,74,2.0,1469705832.4,76.4,0.0,4.55,33.0,172,10,577.7,109.081478016,131.400000095,0,0,0,0,0,0,0,4.55,0,0.0,0.0,4,72,4.55,0.0,0.0,0.0,0.0,172.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
75,75,2.0,1469705834.3,84.0,0.0,4.54,32.5,173,11,585.3,108.95736186,133.299999952,0,0,0,0,0,0,0,4.54,0,0.0,0.0,4,73,4.54000000001,0.0,0.0,0.0,0.0,173.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
76,76,2.0,1469705836.0,92.9,0.0,4.63,33.0,174,12,594.2,109.581343074,135.0,0,0,0,0,0,0,0,4.63,0,0.0,0.0,4,74,4.63000000001,0.0,0.0,0.0,0.0,174.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
77,77,2.0,1469705837.9,101.3,0.0,4.61,33.5,176,13,602.6,109.437100452,136.900000095,0,0,0,0,0,0,0,4.61,0,0.0,0.0,4,75,4.61000000001,0.0,0.0,0.0,0.0,176.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
78,78,2.0,1469705839.7,109.6,0.0,4.58,33.5,177,14,610.9,108.898173861,138.700000048,0,0,0,0,0,0,0,4.58,0,0.0,0.0,4,76,4.57999999999,0.0,0.0,0.0,0.0,177.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
79,79,2.0,1469705841.5,118.0,0.0,4.54,33.5,178,15,619.3,108.514739286,140.5,0,0,0,0,0,0,0,4.54,0,0.0,0.0,4,77,4.54000000001,0.0,0.0,0.0,0.0,178.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
80,80,2.0,1469705843.1,125.0,0.0,4.54,34.0,178,16,626.3,108.408891045,142.099999905,0,0,0,0,0,0,0,4.54,0,0.0,0.0,4,78,4.54000000001,0.0,0.0,0.0,0.0,178.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
81,81,2.0,1469705845.1,134.8,0.0,4.69,34.5,179,17,636.1,108.970092917,144.099999905,0,0,0,0,0,0,0,4.69,0,0.0,0.0,4,79,4.69000000002,0.0,0.0,0.0,0.0,179.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
82,82,2.0,1469705846.7,142.2,0.0,4.67,34.0,180,18,643.5,108.943527129,145.700000048,0,0,0,0,0,0,0,4.67,0,0.0,0.0,4,80,4.67000000001,0.0,0.0,0.0,0.0,180.0,0.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
83,83,2.0,1469705848.5,150.6,0.0,4.59,34.5,181,19,651.9,108.491687362,147.5,0,0,0,0,0,0,0,4.59,0,0.0,0.0,4,81,4.58999999998,0.0,0.0,0.0,0.0,0.0,181.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
84,84,2.0,1469705850.3,158.8,0.0,4.52,33.5,181,20,660.1,108.195629805,149.299999952,0,0,0,0,0,0,0,4.52,0,0.0,0.0,4,82,4.51999999998,0.0,0.0,0.0,0.0,0.0,181.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
85,85,2.0,1469705852.1,166.4,0.0,4.52,33.5,181,21,667.7,108.474130564,151.099999905,0,0,0,0,0,0,0,4.52,0,0.0,0.0,4,83,4.51999999998,0.0,0.0,0.0,0.0,0.0,181.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
86,86,2.0,1469705853.9,175.2,0.0,4.68,33.5,182,22,676.5,109.550561798,152.900000095,0,0,0,0,0,0,0,4.68,0,0.0,0.0,4,84,4.67999999998,0.0,0.0,0.0,0.0,0.0,182.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
87,87,2.0,1469705855.7,183.2,0.0,4.65,32.0,182,23,684.5,110.12141592,154.700000048,0,0,0,0,0,0,0,4.65,0,0.0,0.0,4,85,4.65000000002,0.0,0.0,0.0,0.0,0.0,182.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
88,88,2.0,1469705857.5,191.2,0.0,4.51,33.0,182,24,692.5,110.388908617,156.5,0,0,0,0,0,0,0,4.51,0,0.0,0.0,4,86,4.51,0.0,0.0,0.0,0.0,0.0,182.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
89,89,2.0,1469705859.4,200.1,0.0,4.42,32.0,183,25,701.4,111.075438088,158.400000095,0,0,0,0,0,0,0,4.42,0,0.0,0.0,4,87,4.41999999999,0.0,0.0,0.0,0.0,0.0,183.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
90,90,2.0,1469705861.2,207.4,0.0,4.38,32.0,183,26,708.7,112.186192469,160.200000048,0,0,0,0,0,0,0,4.38,0,0.0,0.0,4,88,4.37999999998,0.0,0.0,0.0,0.0,0.0,183.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
91,91,2.0,1469705863.0,216.1,0.0,4.47,32.0,183,27,717.4,113.541324808,162.0,0,0,0,0,0,0,0,4.47,0,0.0,0.0,4,89,4.47000000001,0.0,0.0,0.0,0.0,0.0,183.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
92,92,2.0,1469705865.0,224.7,0.0,4.44,32.5,183,28,726.0,113.933934253,164.0,0,0,0,0,0,0,0,4.44,0,0.0,0.0,4,90,4.43999999998,0.0,0.0,0.0,0.0,0.0,183.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
93,93,2.0,1469705867.1,232.4,0.0,4.34,33.0,184,29,733.7,114.217860585,166.099999905,0,0,0,0,0,0,0,4.34,0,0.0,0.0,4,91,4.34,0.0,0.0,0.0,0.0,0.0,184.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
94,94,2.0,1469705868.6,240.6,0.0,4.35,32.0,184,30,741.9,114.508095643,167.599999905,0,0,0,0,0,0,0,4.35,0,0.0,0.0,4,92,4.34999999999,0.0,0.0,0.0,0.0,0.0,184.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
95,95,2.0,1469705870.7,249.0,0.0,4.34,30.5,184,31,750.3,114.922206507,169.700000048,0,0,0,0,0,0,0,4.34,0,0.0,0.0,4,93,4.34,0.0,0.0,0.0,0.0,0.0,184.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
96,96,2.0,1469705871.0,250.4,0.0,4.34,30.5,184,31,751.7,115.581707376,170.0,0,0,0,0,0,0,0,4.34,0,0.0,0.0,4,93,4.34,0.0,0.0,0.0,0.0,0.0,184.0,142,146,160,167,180,192,0.0,0.0,0.0,0.0,0.0,0.0,124.3,169.5,203.4,237.3,271.2
|
||||
|
BIN
rowers/tests/testdata/testdata.csv.gz
vendored
BIN
rowers/tests/testdata/testdata.csv.gz
vendored
Binary file not shown.
542
rowers/urls.py
542
rowers/urls.py
@@ -7,7 +7,7 @@ from models import Workout,Rower,StrokeData,FavoriteChart
|
||||
from rest_framework import routers, serializers, viewsets,permissions
|
||||
from rest_framework.urlpatterns import format_suffix_patterns
|
||||
from rest_framework.permissions import *
|
||||
from . import views
|
||||
from rowers import views
|
||||
from django.contrib.auth import views as auth_views
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.conf.urls import (
|
||||
@@ -108,198 +108,207 @@ urlpatterns = [
|
||||
url(r'^o/authorize/$', base.AuthorizationView.as_view(), name="authorize"),
|
||||
url(r'^o/token/$', base.TokenView.as_view(), name="token"),
|
||||
url(r'^', include(router.urls)),
|
||||
url(r'^api-docs/$', views.schema_view),
|
||||
url(r'^api-docs/$', views.schema_view,name='schema_view'),
|
||||
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
url(r'^api/workouts/(?P<id>\d+)/strokedata/$',views.strokedatajson),
|
||||
url(r'^500v/$',views.error500_view),
|
||||
url(r'^api/workouts/(?P<id>\d+)/strokedata/$',views.strokedatajson,name='strokedatajson'),
|
||||
url(r'^500v/$',views.error500_view,name='error500_view'),
|
||||
url(r'^502/$', TemplateView.as_view(template_name='502.html'),name='502'),
|
||||
url(r'^500/$', TemplateView.as_view(template_name='500.html'),name='500'),
|
||||
url(r'^404/$', TemplateView.as_view(template_name='404.html'),name='404'),
|
||||
url(r'^400/$', TemplateView.as_view(template_name='400.html'),name='400'),
|
||||
url(r'^403/$', TemplateView.as_view(template_name='403.html'),name='403'),
|
||||
# url(r'^imports/$', views.imports_view),
|
||||
url(r'^exportallworkouts/?/$',views.workouts_summaries_email_view),
|
||||
url(r'^update_empower/$',views.rower_update_empower_view),
|
||||
url(r'^agegroupcp/(?P<age>\d+)/$',views.agegroupcpview),
|
||||
url(r'^agegroupcp/(?P<age>\d+)/(?P<normalize>\d+)/$',views.agegroupcpview),
|
||||
url(r'^exportallworkouts/?/$',views.workouts_summaries_email_view,name='workouts_summaries_email_view'),
|
||||
url(r'^update_empower/$',views.rower_update_empower_view,name='rower_update_empower_view'),
|
||||
url(r'^agegroupcp/(?P<age>\d+)/$',views.agegroupcpview,name='agegroupcpview'),
|
||||
url(r'^agegroupcp/(?P<age>\d+)/(?P<normalize>\d+)/$',views.agegroupcpview,name='agegroupcpview'),
|
||||
url(r'^ajax_agegroup/(?P<age>\d+)/(?P<weightcategory>\w+.*)/(?P<sex>\w+.*)/(?P<userid>\d+)/$',
|
||||
views.ajax_agegrouprecords),
|
||||
url(r'^updatefitness/(?P<mode>\w+.*)/(?P<days>\d+)/$',views.fitness_metric_view),
|
||||
url(r'^updatefitness/(?P<mode>\w+.*)/$',views.fitness_metric_view),
|
||||
url(r'^updatefitness/$',views.fitness_metric_view),
|
||||
views.ajax_agegrouprecords,name='ajax_agegrouprecords'),
|
||||
url(r'^updatefitness/(?P<mode>\w+.*)/(?P<days>\d+)/$',views.fitness_metric_view,name='fitness_metric_view'),
|
||||
url(r'^updatefitness/(?P<mode>\w+.*)/$',views.fitness_metric_view,name='fitness_metric_view'),
|
||||
url(r'^updatefitness/$',views.fitness_metric_view,name='fitness_metric_view'),
|
||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<distance>\d+)m/$',
|
||||
views.agegrouprecordview),
|
||||
views.agegrouprecordview,name='agegrouprecordview'),
|
||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<duration>\d+)min/$',
|
||||
views.agegrouprecordview),
|
||||
views.agegrouprecordview,name='agegrouprecordview'),
|
||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/$',
|
||||
views.agegrouprecordview),
|
||||
url(r'^list-workouts/ranking/$',views.workouts_view,{'rankingonly':True}),
|
||||
url(r'^list-workouts/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view),
|
||||
url(r'^list-workouts/team/(?P<teamid>\d+)/$',views.workouts_view),
|
||||
url(r'^(?P<rowerid>\d+)/list-workouts/$',views.workouts_view),
|
||||
url(r'^(?P<rowerid>\d+)/list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view),
|
||||
url(r'^list-workouts/user/(?P<userid>\d+)/$',views.workouts_view),
|
||||
url(r'^list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.workouts_view),
|
||||
url(r'^list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view),
|
||||
url(r'^virtualevents/$',views.virtualevents_view),
|
||||
url(r'^virtualevent/create/$',views.virtualevent_create_view),
|
||||
url(r'^virtualevent/createindoor/$',views.indoorvirtualevent_create_view),
|
||||
views.agegrouprecordview,name='agegrouprecordview'),
|
||||
url(r'^list-workouts/ranking/$',views.workouts_view,{'rankingonly':True},
|
||||
name='workouts_view'),
|
||||
url(r'^list-workouts/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^list-workouts/team/(?P<teamid>\d+)/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^(?P<rowerid>\d+)/list-workouts/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^(?P<rowerid>\d+)/list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^list-workouts/user/(?P<userid>\d+)/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^list-workouts/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^virtualevents/$',views.virtualevents_view,name='virtualevents_view'),
|
||||
url(r'^virtualevent/create/$',views.virtualevent_create_view,name='virtualevent_create_view'),
|
||||
url(r'^virtualevent/createindoor/$',views.indoorvirtualevent_create_view,name='indoorvirtualevent_create_view'),
|
||||
url(r'^raceregistration/togglenotification/(?P<id>\d+)/$',
|
||||
views.virtualevent_toggle_email_view),
|
||||
views.virtualevent_toggle_email_view,name='virtualevent_toggle_email_view'),
|
||||
url(r'^indoorraceregistration/togglenotification/(?P<id>\d+)/$',
|
||||
views.indoorvirtualevent_toggle_email_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/$',views.virtualevent_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/ranking$',views.virtualevent_ranking_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/edit/$',views.virtualevent_edit_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/editindoor/$',views.indoorvirtualevent_edit_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/register/$',views.virtualevent_register_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/registerindoor/$',views.indoorvirtualevent_register_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/adddiscipline/$',views.virtualevent_addboat_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/withdraw/(?P<recordid>\d+)/$',views.virtualevent_withdraw_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/withdraw/$',views.virtualevent_withdraw_view),
|
||||
views.indoorvirtualevent_toggle_email_view,name='indoorvirtualevent_toggle_email_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/$',views.virtualevent_view,name='virtualevent_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/ranking$',views.virtualevent_ranking_view,name='virtualevent_ranking_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/edit/$',views.virtualevent_edit_view,name='virtualevent_edit_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/editindoor/$',views.indoorvirtualevent_edit_view,name='indoorvirtualevent_edit_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/register/$',views.virtualevent_register_view,name='virtualevent_register_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/registerindoor/$',views.indoorvirtualevent_register_view,name='indoorvirtualevent_register_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/adddiscipline/$',views.virtualevent_addboat_view,name='virtualevent_addboat_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/withdraw/(?P<recordid>\d+)/$',views.virtualevent_withdraw_view,name='virtualevent_withdraw_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/withdraw/$',views.virtualevent_withdraw_view,name='virtualevent_withdraw_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/submit/$',
|
||||
views.virtualevent_submit_result_view),
|
||||
views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/submit/(?P<workoutid>\d+)/$',
|
||||
views.virtualevent_submit_result_view),
|
||||
views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
|
||||
url(r'^virtualevent/(?P<raceid>\d+)/disqualify/(?P<recordid>\d+)/',
|
||||
views.virtualevent_disqualify_view),
|
||||
url(r'^list-workouts/$',views.workouts_view),
|
||||
url(r'^list-courses/$',views.courses_view),
|
||||
url(r'^courses/upload/$',views.course_upload_view),
|
||||
url(r'^workout/addmanual/$',views.addmanual_view),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/user/(?P<userid>\d+)/$',views.team_comparison_select),
|
||||
url(r'^team-compare-select/$',views.team_comparison_select),
|
||||
url(r'^workouts-join-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select),
|
||||
url(r'^workouts-join/$',views.workouts_join_view),
|
||||
url(r'^workouts-join-select/team/(?P<teamid>\d+)/$',views.workouts_join_select),
|
||||
url(r'^workouts-join-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select),
|
||||
url(r'^workouts-join-select/$',views.workouts_join_select),
|
||||
url(r'^user-boxplot-select/user/(?P<userid>\d+)/$',views.user_boxplot_select),
|
||||
url(r'^user-boxplot-select/$',views.user_boxplot_select),
|
||||
url(r'^user-multiflex-select/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.user_multiflex_select),
|
||||
url(r'^user-multiflex-select/user/(?P<userid>\d+)/$',views.user_multiflex_select),
|
||||
url(r'^user-multiflex-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.user_multiflex_select),
|
||||
url(r'^user-multiflex-select/$',views.user_multiflex_select),
|
||||
url(r'^list-jobs/$',views.session_jobs_view),
|
||||
url(r'^jobs-status/$',views.session_jobs_status),
|
||||
views.virtualevent_disqualify_view,name='virtualevent_submit_disqualify_view'),
|
||||
url(r'^list-workouts/$',views.workouts_view,
|
||||
name='workouts_view'),
|
||||
url(r'^list-courses/$',views.courses_view,name='courses_view'),
|
||||
url(r'^courses/upload/$',views.course_upload_view,name='course_upload_view'),
|
||||
url(r'^workout/addmanual/$',views.addmanual_view,name='addmanual_view'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/workout/(?P<id>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/team/(?P<teamid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/user/(?P<userid>\d+)/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^team-compare-select/$',views.team_comparison_select,name='team_comparison_select'),
|
||||
url(r'^workouts-join-select/team/(?P<teamid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
||||
url(r'^workouts-join/$',views.workouts_join_view,name='workouts_join_view'),
|
||||
url(r'^workouts-join-select/team/(?P<teamid>\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
||||
url(r'^workouts-join-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workouts_join_select,name='workouts_join_select'),
|
||||
url(r'^workouts-join-select/$',views.workouts_join_select,name='workouts_join_select'),
|
||||
url(r'^user-boxplot-select/user/(?P<userid>\d+)/$',views.user_boxplot_select,name='user_boxplot_select'),
|
||||
url(r'^user-boxplot-select/$',views.user_boxplot_select,name='user_boxplot_select'),
|
||||
url(r'^user-multiflex-select/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.user_multiflex_select,name='user_multiflex_select'),
|
||||
url(r'^user-multiflex-select/user/(?P<userid>\d+)/$',views.user_multiflex_select,name='user_multiflex_select'),
|
||||
url(r'^user-multiflex-select/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.user_multiflex_select,name='user_multiflex_select'),
|
||||
url(r'^user-multiflex-select/$',views.user_multiflex_select,name='user_multiflex_select'),
|
||||
url(r'^list-jobs/$',views.session_jobs_view,name='session_jobs_view'),
|
||||
url(r'^jobs-status/$',views.session_jobs_status,name='session_jobs_status'),
|
||||
url(r'^job-kill/(?P<id>.*)/$',views.kill_async_job),
|
||||
url(r'^test-job/(?P<aantal>\d+)/$',views.test_job_view),
|
||||
url(r'^test-job2/(?P<aantal>\d+)/$',views.test_job_view2),
|
||||
url(r'^record-progress/(?P<value>\d+)/(?P<id>.*)/$',views.post_progress),
|
||||
url(r'^record-progress/(?P<value>\d+)/(?P<id>.*)/$',views.post_progress,name='post_progress'),
|
||||
url(r'^record-progress/(?P<id>.*)/$',views.post_progress),
|
||||
url(r'^record-progress/$',views.post_progress),
|
||||
url(r'^list-graphs/$',views.graphs_view),
|
||||
url(r'^fitness-progress/$',views.fitnessmetric_view),
|
||||
url(r'^fitness-progress/user/(?P<id>\d+)/$',views.fitnessmetric_view),
|
||||
url(r'^fitness-progress/user/(?P<id>\d+)/(?P<mode>\w+.*)/$',views.fitnessmetric_view),
|
||||
url(r'^ote-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view),
|
||||
url(r'^ote-bests/user/(?P<theuser>\d+)/$',views.rankings_view),
|
||||
url(r'^ote-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view),
|
||||
url(r'^ote-bests/$',views.rankings_view),
|
||||
url(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view),
|
||||
url(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2),
|
||||
url(r'^ote-bests2/user/(?P<theuser>\d+)/$',views.rankings_view2),
|
||||
url(r'^ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2),
|
||||
url(r'^ote-bests2/$',views.rankings_view2),
|
||||
url(r'^otw-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view),
|
||||
url(r'^otw-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view),
|
||||
url(r'^otw-bests/user/(?P<theuser>\d+)/$',views.otwrankings_view),
|
||||
url(r'^otw-bests/$',views.otwrankings_view),
|
||||
url(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view),
|
||||
url(r'^ote-ranking/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view),
|
||||
url(r'^ote-ranking/$',views.oterankings_view),
|
||||
url(r'^ote-ranking/user/(?P<theuser>\d+)/$',views.oterankings_view),
|
||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<theuser>\d+)/$',views.cum_flex),
|
||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cum_flex),
|
||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/$',views.cum_flex),
|
||||
url(r'^flexall/user/(?P<theuser>\d+)/$',views.cum_flex),
|
||||
url(r'^flexall/$',views.cum_flex),
|
||||
url(r'^flexalldata/$',views.cum_flex_data),
|
||||
url(r'^histo/user/(?P<theuser>\d+)/$',views.histo),
|
||||
url(r'^histodata/$',views.histo_data),
|
||||
url(r'^histo/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.histo),
|
||||
url(r'^histo/$',views.histo),
|
||||
url(r'^cumstats/user/(?P<theuser>\d+)/$',views.cumstats),
|
||||
url(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats),
|
||||
url(r'^cumstats/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats),
|
||||
url(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats),
|
||||
url(r'^cumstats/$',views.cumstats),
|
||||
url(r'^graph/(?P<id>\d+)/$',views.graph_show_view),
|
||||
url(r'^list-graphs/$',views.graphs_view,name='graphs_view'),
|
||||
url(r'^fitness-progress/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
||||
url(r'^fitness-progress/user/(?P<id>\d+)/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
||||
url(r'^fitness-progress/user/(?P<id>\d+)/(?P<mode>\w+.*)/$',views.fitnessmetric_view,name='fitnessmetric_view'),
|
||||
url(r'^ote-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'),
|
||||
url(r'^ote-bests/user/(?P<theuser>\d+)/$',views.rankings_view,name='rankings_view'),
|
||||
url(r'^ote-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view,name='rankings_view'),
|
||||
url(r'^ote-bests/$',views.rankings_view,name='rankings_view'),
|
||||
url(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view,name='rankings_view'),
|
||||
url(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'),
|
||||
url(r'^ote-bests2/user/(?P<theuser>\d+)/$',views.rankings_view2,name='rankings_view2'),
|
||||
url(r'^ote-bests2/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.rankings_view2,name='rankings_view2'),
|
||||
url(r'^ote-bests2/$',views.rankings_view2,name='rankings_view2'),
|
||||
url(r'^otw-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
||||
url(r'^otw-bests/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
||||
url(r'^otw-bests/user/(?P<theuser>\d+)/$',views.otwrankings_view,name='otwrankings_view'),
|
||||
url(r'^otw-bests/$',views.otwrankings_view,name='otwrankings_view'),
|
||||
url(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'),
|
||||
url(r'^ote-ranking/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.oterankings_view,name='oterankings_view'),
|
||||
url(r'^ote-ranking/$',views.oterankings_view,name='oterankings_view'),
|
||||
url(r'^ote-ranking/user/(?P<theuser>\d+)/$',views.oterankings_view,name='oterankings_view'),
|
||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/user/(?P<theuser>\d+)/$',views.cum_flex,name='cum_flex'),
|
||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cum_flex,name='cum_flex'),
|
||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/$',views.cum_flex,name='cum_flex'),
|
||||
url(r'^flexall/user/(?P<theuser>\d+)/$',views.cum_flex,name='cum_flex'),
|
||||
url(r'^flexall/$',views.cum_flex,name='cum_flex'),
|
||||
url(r'^flexalldata/$',views.cum_flex_data,name='cum_flex_data'),
|
||||
url(r'^histo/user/(?P<theuser>\d+)/$',views.histo,name='histo'),
|
||||
url(r'^histodata/$',views.histo_data,name='histo_data'),
|
||||
url(r'^histo/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.histo,name='histo'),
|
||||
url(r'^histo/$',views.histo,name='histo'),
|
||||
url(r'^cumstats/user/(?P<theuser>\d+)/$',views.cumstats,name='cumstats'),
|
||||
url(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
||||
url(r'^cumstats/user/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
||||
url(r'^cumstats/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.cumstats,name='cumstats'),
|
||||
url(r'^cumstats/$',views.cumstats,name='cumstats'),
|
||||
url(r'^graph/(?P<id>\d+)/$',views.graph_show_view,name='graph_show_view'),
|
||||
url(r'^graph/(?P<pk>\d+)/delete/$',views.GraphDelete.as_view(),name='graph_delete'),
|
||||
url(r'^workout/(?P<id>\d+)/get-thumbnails/$',views.get_thumbnails),
|
||||
url(r'^workout/(?P<id>\d+)/toggle-ranking/$',views.workout_toggle_ranking),
|
||||
url(r'^workout/(?P<id>\d+)/get-thumbnails/$',views.get_thumbnails,name='get_thumbnails'),
|
||||
url(r'^workout/(?P<id>\d+)/toggle-ranking/$',views.workout_toggle_ranking,name='workout_toggle_ranking'),
|
||||
url(r'^workout/(?P<id>\d+)/get-testscript/$',views.get_testscript),
|
||||
url(r'^workout/upload/team/$',views.team_workout_upload_view),
|
||||
url(r'^workout/upload/team/$',views.team_workout_upload_view,name='team_workout_upload_view'),
|
||||
url(r'^workout/upload/$',views.workout_upload_view,name='workout_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/histo/$',views.workout_histo_view),
|
||||
url(r'^workout/(?P<id>\d+)/histo/$',views.workout_histo_view,name='workout_histo_view'),
|
||||
url(r'^workout/(?P<id>\d+)/task/$',views.workout_test_task_view),
|
||||
url(r'^workout/(?P<id>\d+)/forcecurve/$',views.workout_forcecurve_view),
|
||||
url(r'^workout/(?P<id>\d+)/unsubscribe/$',views.workout_unsubscribe_view),
|
||||
url(r'^workout/(?P<id>\d+)/forcecurve/$',views.workout_forcecurve_view,name='workout_forcecurve_view'),
|
||||
url(r'^workout/(?P<id>\d+)/unsubscribe/$',views.workout_unsubscribe_view,name='workout_unsubscribe_view'),
|
||||
# url(r'^workout/(?P<id>\d+)/export/$',views.workout_export_view),
|
||||
url(r'^workout/(?P<id>\d+)/comment/$',views.workout_comment_view),
|
||||
url(r'^workout/(?P<id>\d+)/emailtcx/$',views.workout_tcxemail_view),
|
||||
url(r'^workout/(?P<id>\d+)/emailgpx/$',views.workout_gpxemail_view),
|
||||
url(r'^workout/(?P<id>\d+)/emailcsv/$',views.workout_csvemail_view),
|
||||
url(r'^workout/(?P<id>\d+)/csvtoadmin/$',views.workout_csvtoadmin_view),
|
||||
url(r'^ergcpdatatoadmin/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otecp_toadmin_view),
|
||||
url(r'^otwcpdatatoadmin/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwcp_toadmin_view),
|
||||
url(r'^workout/(?P<id>\d+)/comment/$',views.workout_comment_view,name='workout_comment_view'),
|
||||
url(r'^workout/(?P<id>\d+)/emailtcx/$',views.workout_tcxemail_view,name='workout_tcxemail_view'),
|
||||
url(r'^workout/(?P<id>\d+)/emailgpx/$',views.workout_gpxemail_view,name='workout_gpxemail_view'),
|
||||
url(r'^workout/(?P<id>\d+)/emailcsv/$',views.workout_csvemail_view,name='workout_csvemail_view'),
|
||||
url(r'^workout/(?P<id>\d+)/csvtoadmin/$',views.workout_csvtoadmin_view,name='workout_csvtoadmin_view'),
|
||||
url(r'^ergcpdatatoadmin/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otecp_toadmin_view,name='otecp_toadmin_view'),
|
||||
url(r'^otwcpdatatoadmin/(?P<theuser>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.otwcp_toadmin_view,name='otwcp_toadmin_view'),
|
||||
# url(r'^workout/compare/(?P<id>\d+)/$',views.workout_comparison_list),
|
||||
# url(r'^workout/compare2/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>\w+.*)/$',views.workout_comparison_view),
|
||||
# url(r'^workout/compare/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workout_comparison_list),
|
||||
url(r'^workout/(?P<id>\d+)/edit/$',views.workout_edit_view,
|
||||
name='workout_edit_view'),
|
||||
url(r'^workout/(?P<id>\d+)/map/$',views.workout_map_view),
|
||||
url(r'^workout/(?P<id>\d+)/map/$',views.workout_map_view,name='workout_map_view'),
|
||||
# url(r'^workout/(?P<id>\d+)/setprivate/$',views.workout_setprivate_view),
|
||||
url(r'^workout/(?P<id>\d+)/updatecp/$',views.workout_update_cp_view),
|
||||
url(r'^workout/(?P<id>\d+)/updatecp/$',views.workout_update_cp_view,name='workout_update_cp_view'),
|
||||
# url(r'^workout/(?P<id>\d+)/makepublic/$',views.workout_makepublic_view),
|
||||
# url(r'^workout/(?P<id>\d+)/geeky/$',views.workout_geeky_view),
|
||||
# url(r'^workout/(?P<id>\d+)/advanced/$',views.workout_advanced_view),
|
||||
url(r'^workout/(?P<id>\d+)/instroke/(?P<metric>\w+.*)/$',views.instroke_chart),
|
||||
url(r'^workout/(?P<id>\d+)/instroke/$',views.instroke_view),
|
||||
url(r'^workout/(?P<id>\d+)/instroke/(?P<metric>\w+.*)/$',views.instroke_chart,name='instroke_chart'),
|
||||
url(r'^workout/(?P<id>\d+)/instroke/$',views.instroke_view,name='instroke_view'),
|
||||
url(r'^workout/(?P<id>\d+)/stats/$',views.workout_stats_view,name='workout_stats_view'),
|
||||
url(r'^workout/(?P<id>\d+)/data/$',views.workout_data_view,
|
||||
name='workout_data_view'),
|
||||
url(r'^workout/(?P<id>\d+)/otwsetpower/$',views.workout_otwsetpower_view),
|
||||
url(r'^workout/(?P<id>\d+)/interactiveotwplot/$',views.workout_otwpowerplot_view),
|
||||
url(r'^workout/(?P<id>\d+)/wind/$',views.workout_wind_view),
|
||||
url(r'^workout/(?P<id>\d+)/image/$',views.workout_uploadimage_view),
|
||||
url(r'^virtualevent/(?P<id>\d+)/compare/$',views.virtualevent_compare_view),
|
||||
url(r'^workout/(?P<id>\d+)/otwsetpower/$',views.workout_otwsetpower_view,name='workout_otwsetpower_view'),
|
||||
url(r'^workout/(?P<id>\d+)/interactiveotwplot/$',views.workout_otwpowerplot_view,name='workout_otwpowerplot_view'),
|
||||
url(r'^workout/(?P<id>\d+)/wind/$',views.workout_wind_view,name='workout_wind_view'),
|
||||
url(r'^workout/(?P<id>\d+)/image/$',views.workout_uploadimage_view,name='workout_uploadimage_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/compare/$',views.virtualevent_compare_view,name='virtualevent_compare_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/image/$',
|
||||
views.virtualevent_uploadimage_view),
|
||||
views.virtualevent_uploadimage_view,name='virtualevent_uploadimage_view'),
|
||||
url(r'^virtualevent/(?P<id>\d+)/setimage/(?P<logoid>\d+)/$',
|
||||
views.virtualevent_setlogo_view),
|
||||
views.virtualevent_setlogo_view,name='virtualevent_setlog_view'),
|
||||
url(r'^logo/(?P<id>\d+)/delete/$',
|
||||
views.logo_delete_view),
|
||||
url(r'^workout/(?P<id>\d+)/darkskywind/$',views.workout_downloadwind_view),
|
||||
url(r'^workout/(?P<id>\d+)/metar/(?P<airportcode>\w+)/$',views.workout_downloadmetar_view),
|
||||
url(r'^workout/(?P<id>\d+)/stream/$',views.workout_stream_view),
|
||||
views.logo_delete_view,name='logo_delete_view'),
|
||||
url(r'^workout/(?P<id>\d+)/darkskywind/$',views.workout_downloadwind_view,name='workout_downloadwind_view'),
|
||||
url(r'^workout/(?P<id>\d+)/metar/(?P<airportcode>\w+)/$',views.workout_downloadmetar_view,name='workout_downloadmetar_view'),
|
||||
url(r'^workout/(?P<id>\d+)/stream/$',views.workout_stream_view,name='workout_stream_view'),
|
||||
# url(r'^workout/(?P<id>\d+)/crewnerdsummary/$',views.workout_crewnerd_summary_view),
|
||||
url(r'^workout/(?P<id>\d+)/editintervals/$',views.workout_summary_edit_view,
|
||||
name='workout_summary_edit_view'),
|
||||
url(r'^workout/(?P<id>\d+)/restore/$',views.workout_summary_restore_view),
|
||||
url(r'^workout/(?P<id>\d+)/split/$',views.workout_split_view),
|
||||
url(r'^workout/(?P<id>\d+)/restore/$',views.workout_summary_restore_view,name='workout_summary_restore_view'),
|
||||
url(r'^workout/(?P<id>\d+)/split/$',views.workout_split_view,name='workout_split_view'),
|
||||
# url(r'^workout/(?P<id>\d+)/interactiveplot/$',views.workout_biginteractive_view),
|
||||
url(r'^workout/(?P<id>\d+)/view/$',views.workout_view),
|
||||
url(r'^workout/(?P<id>\d+)/$',views.workout_view),
|
||||
url(r'^workout/fusion/(?P<id1>\d+)/(?P<id2>\d+)/$',views.workout_fusion_view),
|
||||
url(r'^workout/fusion/(?P<id>\d+)/$',views.workout_fusion_list),
|
||||
url(r'^workout/fusion/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workout_fusion_list),
|
||||
url(r'^workout/(?P<id>\d+)/view/$',views.workout_view,name='workout_view'),
|
||||
url(r'^workout/(?P<id>\d+)/$',views.workout_view,name='workout_view'),
|
||||
url(r'^workout/fusion/(?P<id1>\d+)/(?P<id2>\d+)/$',views.workout_fusion_view,name='workout_fusion_view'),
|
||||
url(r'^workout/fusion/(?P<id>\d+)/$',views.workout_fusion_list,name='workout_fusion_list'),
|
||||
url(r'^workout/fusion/(?P<id>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',views.workout_fusion_list,name='workout_fusion_list'),
|
||||
url(r'^help/$',TemplateView.as_view(
|
||||
template_name='help.html'),name='help'
|
||||
),
|
||||
@@ -308,125 +317,126 @@ urlpatterns = [
|
||||
# keeping the old URLs for retrofit
|
||||
url(r'^workout/(?P<id>\d+)/addtimeplot/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'1'}),
|
||||
{'plotnr':'1'},name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/adddistanceplot/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'2'}),
|
||||
{'plotnr':'2'},name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/addpiechart/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'3'}),
|
||||
{'plotnr':'3'},name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/adddistanceplot2/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'7'}),
|
||||
{'plotnr':'7'},name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/addtimeplot2/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'8'}),
|
||||
{'plotnr':'8'},name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/addotwpowerplot/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'9'}),
|
||||
{'plotnr':'9'},name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/addpowerpiechart/$',
|
||||
views.workout_add_chart_view,
|
||||
{'plotnr':'13'}),
|
||||
{'plotnr':'13'},name='workout_add_chart_view'),
|
||||
# addstatic is the new URL -> need to update in templates
|
||||
url(r'^workout/(?P<id>\d+)/addstatic/(?P<plotnr>\d+)/$',
|
||||
views.workout_add_chart_view),
|
||||
url(r'^workout/(?P<id>\d+)/addstatic/$',views.workout_add_chart_view),
|
||||
views.workout_add_chart_view,name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<id>\d+)/addstatic/$',views.workout_add_chart_view,name='workout_add_chart_view'),
|
||||
url(r'^workout/(?P<pk>\d+)/delete/$',login_required(
|
||||
views.WorkoutDelete.as_view()),
|
||||
name='workout_delete'),
|
||||
url(r'^workout/(?P<id>\d+)/smoothenpace/$',views.workout_smoothenpace_view),
|
||||
url(r'^workout/(?P<id>\d+)/undosmoothenpace/$',views.workout_undo_smoothenpace_view),
|
||||
url(r'^workout/c2import/$',views.workout_c2import_view),
|
||||
url(r'^workout/c2list/$',views.workout_c2import_view),
|
||||
url(r'^workout/c2list/(?P<page>\d+)/$',views.workout_c2import_view),
|
||||
url(r'^workout/c2list/user/(?P<userid>\d+)/$',views.workout_c2import_view),
|
||||
url(r'^workout/c2list/(?P<page>\d+)/user/(?P<userid>\d+)/$',views.workout_c2import_view),
|
||||
url(r'^workout/stravaimport/$',views.workout_stravaimport_view),
|
||||
url(r'^workout/stravaimport/user/(?P<userid>\d+)/$',views.workout_stravaimport_view),
|
||||
url(r'^workout/c2import/all/$',views.workout_getc2workout_all),
|
||||
url(r'^workout/c2import/all/(?P<page>\d+)/$',views.workout_getc2workout_all),
|
||||
url(r'^workout/(?P<source>\w+.*)import/(?P<externalid>\d+)/$',views.workout_getimportview),
|
||||
url(r'^workout/stravaimport/all/$',views.workout_getstravaworkout_all),
|
||||
url(r'^workout/stravaimport/next/$',views.workout_getstravaworkout_next),
|
||||
url(r'^workout/sporttracksimport/$',views.workout_sporttracksimport_view),
|
||||
url(r'^workout/sporttracksimport/user/(?P<userid>\d+)/$',views.workout_sporttracksimport_view),
|
||||
url(r'^workout/sporttracksimport/all/$',views.workout_getsporttracksworkout_all),
|
||||
url(r'^workout/polarimport/$',views.workout_polarimport_view),
|
||||
url(r'^workout/polarimport/user/(?P<userid>\d+)/',views.workout_polarimport_view),
|
||||
url(r'^workout/runkeeperimport/$',views.workout_runkeeperimport_view),
|
||||
url(r'^workout/runkeeperimport/user/(?P<userid>\d+)/$',views.workout_runkeeperimport_view),
|
||||
url(r'^workout/underarmourimport/$',views.workout_underarmourimport_view),
|
||||
url(r'^workout/(?P<id>\d+)/smoothenpace/$',views.workout_smoothenpace_view,name='workout_smoothenpace_view'),
|
||||
url(r'^workout/(?P<id>\d+)/undosmoothenpace/$',views.workout_undo_smoothenpace_view,name='workout_undo_smoothenpace_view'),
|
||||
url(r'^workout/c2import/$',views.workout_c2import_view,name='workout_c2import_view'),
|
||||
url(r'^workout/c2list/$',views.workout_c2import_view,name='workout_c2import_view'),
|
||||
url(r'^workout/c2list/(?P<page>\d+)/$',views.workout_c2import_view,name='workout_c2import_view'),
|
||||
url(r'^workout/c2list/user/(?P<userid>\d+)/$',views.workout_c2import_view,name='workout_c2import_view'),
|
||||
url(r'^workout/c2list/(?P<page>\d+)/user/(?P<userid>\d+)/$',views.workout_c2import_view,name='workout_c2import_view'),
|
||||
url(r'^workout/stravaimport/$',views.workout_stravaimport_view,name='workout_stravaimport_view'),
|
||||
url(r'^workout/stravaimport/user/(?P<userid>\d+)/$',views.workout_stravaimport_view,name='workout_stravaimport_view'),
|
||||
url(r'^workout/c2import/all/$',views.workout_getc2workout_all,name='workout_getc2workout_all'),
|
||||
url(r'^workout/c2import/all/(?P<page>\d+)/$',views.workout_getc2workout_all,name='workout_getc2workout_all'),
|
||||
url(r'^workout/(?P<source>\w+.*)import/(?P<externalid>\d+)/$',views.workout_getimportview,name='workout_getimportview'),
|
||||
url(r'^workout/stravaimport/all/$',views.workout_getstravaworkout_all,name='workout_getstravaworkout_all'),
|
||||
url(r'^workout/stravaimport/next/$',views.workout_getstravaworkout_next,name='workout_getstravaworkout_next'),
|
||||
url(r'^workout/sporttracksimport/$',views.workout_sporttracksimport_view,name='workout_sporttracksimport_view'),
|
||||
url(r'^workout/sporttracksimport/user/(?P<userid>\d+)/$',views.workout_sporttracksimport_view,name='workout_sporttracksimport_view'),
|
||||
url(r'^workout/sporttracksimport/all/$',views.workout_getsporttracksworkout_all,name='workout_getsporttracksworkout_all'),
|
||||
url(r'^workout/polarimport/$',views.workout_polarimport_view,name='workout_polarimport_view'),
|
||||
url(r'^workout/polarimport/user/(?P<userid>\d+)/',views.workout_polarimport_view,name='workout_polarimport_view'),
|
||||
url(r'^workout/runkeeperimport/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'),
|
||||
url(r'^workout/runkeeperimport/user/(?P<userid>\d+)/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'),
|
||||
url(r'^workout/underarmourimport/$',views.workout_underarmourimport_view,name='workout_underarmourimport_view'),
|
||||
# url(r'^workout/(?P<id>\d+)/deleteconfirm/$',views.workout_delete_confirm_view),
|
||||
url(r'^workout/(?P<id>\d+)/c2uploadw/$',views.workout_c2_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/stravauploadw/$',views.workout_strava_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/recalcsummary/$',views.workout_recalcsummary_view),
|
||||
url(r'^workout/(?P<id>\d+)/sporttracksuploadw/$',views.workout_sporttracks_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/runkeeperuploadw/$',views.workout_runkeeper_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/underarmouruploadw/$',views.workout_underarmour_upload_view),
|
||||
url(r'^workout/(?P<id>\d+)/tpuploadw/$',views.workout_tp_upload_view),
|
||||
url(r'^multi-compare/workout/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.multi_compare_view),
|
||||
url(r'^multi-compare/workout/(?P<id>\d+)/$',views.multi_compare_view),
|
||||
url(r'^multi-compare/$',views.multi_compare_view),
|
||||
url(r'^user-boxplot/user/(?P<userid>\d+)/$',views.boxplot_view),
|
||||
url(r'^user-boxplot/$',views.boxplot_view),
|
||||
url(r'^user-boxplot-data/$',views.boxplot_view_data),
|
||||
url(r'^user-multiflex/user/(?P<userid>\d+)/$',views.multiflex_view),
|
||||
url(r'^user-multiflex/$',views.multiflex_view),
|
||||
url(r'^user-multiflex-data/$',views.multiflex_data),
|
||||
url(r'^me/deactivate/$',views.deactivate_user),
|
||||
url(r'^me/delete/$',views.remove_user),
|
||||
url(r'^me/gdpr-optin-confirm/?/$',views.user_gdpr_confirm),
|
||||
url(r'^me/gdpr-optin-confirm/$',views.user_gdpr_confirm),
|
||||
url(r'^me/gdpr-optin/?/$',views.user_gdpr_optin),
|
||||
url(r'^me/gdpr-optin/$',views.user_gdpr_optin),
|
||||
url(r'^me/teams/$',views.rower_teams_view),
|
||||
url(r'^me/calcdps/$',views.rower_calcdps_view),
|
||||
url(r'^me/exportsettings/$',views.rower_exportsettings_view),
|
||||
url(r'^me/exportsettings/user/(?P<userid>\d+)/$',views.rower_exportsettings_view),
|
||||
url(r'^team/(?P<id>\d+)/$',views.team_view),
|
||||
url(r'^team/(?P<id>\d+)/memberstats/$',views.team_members_stats_view),
|
||||
url(r'^team/(?P<id>\d+)/edit/$',views.team_edit_view),
|
||||
url(r'^team/(?P<id>\d+)/leaveconfirm/$',views.team_leaveconfirm_view),
|
||||
url(r'^team/(?P<id>\d+)/leave/$',views.team_leave_view),
|
||||
url(r'^team/(?P<id>\d+)/deleteconfirm/$',views.team_deleteconfirm_view),
|
||||
url(r'^team/(?P<teamid>\d+)/requestmembership/(?P<userid>\d+)/$',views.team_requestmembership_view),
|
||||
url(r'^team/(?P<id>\d+)/delete/$',views.team_delete_view),
|
||||
url(r'^team/create/$',views.team_create_view),
|
||||
url(r'^me/team/(?P<teamid>\d+)/drop/(?P<userid>\d+)/$',views.manager_member_drop_view),
|
||||
url(r'^me/invitation/(?P<id>\d+)/reject/$',views.invitation_reject_view),
|
||||
url(r'^me/invitation/(?P<id>\d+)/revoke/$',views.invitation_revoke_view),
|
||||
url(r'^me/invitation/$',views.rower_invitations_view),
|
||||
url(r'^me/raise500/$',views.raise_500),
|
||||
url(r'^me/invitation/(\w+.*)/$',views.rower_invitations_view),
|
||||
url(r'^me/request/(?P<id>\d+)/revoke/$',views.request_revoke_view),
|
||||
url(r'^me/request/(?P<id>\d+)/reject/$',views.request_reject_view),
|
||||
url(r'^me/request/(\w+.*)/$',views.manager_requests_view),
|
||||
url(r'^me/request/$',views.manager_requests_view),
|
||||
url(r'^me/edit/$',views.rower_edit_view),
|
||||
url(r'^me/edit/user/(?P<userid>\d+)/$',views.rower_edit_view),
|
||||
url(r'^me/preferences/$',views.rower_prefs_view),
|
||||
url(r'^me/transactions/$',views.transactions_view),
|
||||
url(r'^me/preferences/user/(?P<userid>\d+)/$',views.rower_prefs_view),
|
||||
url(r'^me/edit/(.+.*)/$',views.rower_edit_view),
|
||||
url(r'^me/c2authorize/$',views.rower_c2_authorize),
|
||||
url(r'^me/polarauthorize/$',views.rower_polar_authorize),
|
||||
url(r'^me/revokeapp/(?P<id>\d+)/$',views.rower_revokeapp_view),
|
||||
url(r'^me/stravaauthorize/$',views.rower_strava_authorize),
|
||||
url(r'^me/sporttracksauthorize/$',views.rower_sporttracks_authorize),
|
||||
url(r'^me/underarmourauthorize/$',views.rower_underarmour_authorize),
|
||||
url(r'^me/tpauthorize/$',views.rower_tp_authorize),
|
||||
url(r'^me/runkeeperauthorize/$',views.rower_runkeeper_authorize),
|
||||
url(r'^me/sporttracksrefresh/$',views.rower_sporttracks_token_refresh),
|
||||
url(r'^me/underarmourrefresh/$',views.rower_underarmour_token_refresh),
|
||||
url(r'^me/tprefresh/$',views.rower_tp_token_refresh),
|
||||
url(r'^me/c2refresh/$',views.rower_c2_token_refresh),
|
||||
url(r'^me/favoritecharts/$',views.rower_favoritecharts_view),
|
||||
url(r'^me/favoritecharts/user/(?P<userid>\d+)/$',views.rower_favoritecharts_view),
|
||||
url(r'^workout/(?P<id>\d+)/c2uploadw/$',views.workout_c2_upload_view,name='workout_c2_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/stravauploadw/$',views.workout_strava_upload_view,name='workout_strava_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/recalcsummary/$',views.workout_recalcsummary_view,name='workout_recalcsummary_view'),
|
||||
url(r'^workout/(?P<id>\d+)/sporttracksuploadw/$',views.workout_sporttracks_upload_view,name='workout_sporttracks_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/runkeeperuploadw/$',views.workout_runkeeper_upload_view,name='workout_runkeeper_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/underarmouruploadw/$',views.workout_underarmour_upload_view,name='workout_underarmour_upload_view'),
|
||||
url(r'^workout/(?P<id>\d+)/tpuploadw/$',views.workout_tp_upload_view,name='workout_tp_upload_view'),
|
||||
url(r'^multi-compare/workout/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.multi_compare_view,
|
||||
name='multi_compare_view'),
|
||||
url(r'^multi-compare/workout/(?P<id>\d+)/$',views.multi_compare_view,name='multi_compare_view'),
|
||||
url(r'^multi-compare/$',views.multi_compare_view,name='multi_compare_view'),
|
||||
url(r'^user-boxplot/user/(?P<userid>\d+)/$',views.boxplot_view,name='boxplot_view'),
|
||||
url(r'^user-boxplot/$',views.boxplot_view,name='boxplot_view'),
|
||||
url(r'^user-boxplot-data/$',views.boxplot_view_data,name='boxplot_view_data'),
|
||||
url(r'^user-multiflex/user/(?P<userid>\d+)/$',views.multiflex_view,name='multiflex_view'),
|
||||
url(r'^user-multiflex/$',views.multiflex_view,name='multiflex_view'),
|
||||
url(r'^user-multiflex-data/$',views.multiflex_data,name='multiflex_data'),
|
||||
url(r'^me/deactivate/$',views.deactivate_user,name='deactivate_user'),
|
||||
url(r'^me/delete/$',views.remove_user,name='remove_user'),
|
||||
url(r'^me/gdpr-optin-confirm/?/$',views.user_gdpr_confirm,name='user_gdpr_confirm'),
|
||||
url(r'^me/gdpr-optin-confirm/$',views.user_gdpr_confirm,name='user_gdpr_confirm'),
|
||||
url(r'^me/gdpr-optin/?/$',views.user_gdpr_optin,name='user_gdpr_optin'),
|
||||
url(r'^me/gdpr-optin/$',views.user_gdpr_optin,name='user_gdpr_optin'),
|
||||
url(r'^me/teams/$',views.rower_teams_view,name='rower_teams_view'),
|
||||
url(r'^me/calcdps/$',views.rower_calcdps_view,name='rower_calcdps_view'),
|
||||
url(r'^me/exportsettings/$',views.rower_exportsettings_view,name='rower_exportsettings_view'),
|
||||
url(r'^me/exportsettings/user/(?P<userid>\d+)/$',views.rower_exportsettings_view,name='rower_exportsettings_view'),
|
||||
url(r'^team/(?P<id>\d+)/$',views.team_view,name='team_view'),
|
||||
url(r'^team/(?P<id>\d+)/memberstats/$',views.team_members_stats_view,name='team_members_stats_view'),
|
||||
url(r'^team/(?P<id>\d+)/edit/$',views.team_edit_view,name='team_edit_view'),
|
||||
url(r'^team/(?P<id>\d+)/leaveconfirm/$',views.team_leaveconfirm_view,name='team_leaveconfirm_view'),
|
||||
url(r'^team/(?P<id>\d+)/leave/$',views.team_leave_view,name='team_leave_view'),
|
||||
url(r'^team/(?P<id>\d+)/deleteconfirm/$',views.team_deleteconfirm_view,name='team_deleteconfirm_view'),
|
||||
url(r'^team/(?P<teamid>\d+)/requestmembership/(?P<userid>\d+)/$',views.team_requestmembership_view,name='team_requestmembership_view'),
|
||||
url(r'^team/(?P<id>\d+)/delete/$',views.team_delete_view,name='team_delete_view'),
|
||||
url(r'^team/create/$',views.team_create_view,name='team_create_view'),
|
||||
url(r'^me/team/(?P<teamid>\d+)/drop/(?P<userid>\d+)/$',views.manager_member_drop_view,name='manager_member_drop_view'),
|
||||
url(r'^me/invitation/(?P<id>\d+)/reject/$',views.invitation_reject_view,name='invitation_reject_view'),
|
||||
url(r'^me/invitation/(?P<id>\d+)/revoke/$',views.invitation_revoke_view,name='invitation_revoke_view'),
|
||||
url(r'^me/invitation/$',views.rower_invitations_view,name='rower_invitations_view'),
|
||||
url(r'^me/raise500/$',views.raise_500,name='raise_500'),
|
||||
url(r'^me/invitation/(\w+.*)/$',views.rower_invitations_view,name='rower_invitations_view'),
|
||||
url(r'^me/request/(?P<id>\d+)/revoke/$',views.request_revoke_view,name='request_revoke_view'),
|
||||
url(r'^me/request/(?P<id>\d+)/reject/$',views.request_reject_view,name='request_reject_view'),
|
||||
url(r'^me/request/(\w+.*)/$',views.manager_requests_view,name='manager_requests_view'),
|
||||
url(r'^me/request/$',views.manager_requests_view,name='manager_requests_view'),
|
||||
url(r'^me/edit/$',views.rower_edit_view,name='rower_edit_view'),
|
||||
url(r'^me/edit/user/(?P<userid>\d+)/$',views.rower_edit_view,name='rower_edit_view'),
|
||||
url(r'^me/preferences/$',views.rower_prefs_view,name='rower_prefs_view'),
|
||||
url(r'^me/transactions/$',views.transactions_view,name='transactions_view'),
|
||||
url(r'^me/preferences/user/(?P<userid>\d+)/$',views.rower_prefs_view,name='rower_prefs_view'),
|
||||
url(r'^me/edit/(.+.*)/$',views.rower_edit_view,name='rower_edit_view'),
|
||||
url(r'^me/c2authorize/$',views.rower_c2_authorize,name='rower_c2_authorize'),
|
||||
url(r'^me/polarauthorize/$',views.rower_polar_authorize,name='rower_polar_authorize'),
|
||||
url(r'^me/revokeapp/(?P<id>\d+)/$',views.rower_revokeapp_view,name='rower_revokeapp_view'),
|
||||
url(r'^me/stravaauthorize/$',views.rower_strava_authorize,name='rower_strava_authorize'),
|
||||
url(r'^me/sporttracksauthorize/$',views.rower_sporttracks_authorize,name='rower_sporttracks_authorize'),
|
||||
url(r'^me/underarmourauthorize/$',views.rower_underarmour_authorize,name='rower_underarmour_authorize'),
|
||||
url(r'^me/tpauthorize/$',views.rower_tp_authorize,name='rower_tp_authorize'),
|
||||
url(r'^me/runkeeperauthorize/$',views.rower_runkeeper_authorize,name='rower_runkeeper_authorize'),
|
||||
url(r'^me/sporttracksrefresh/$',views.rower_sporttracks_token_refresh,name='rower_sporttracks_token_refresh'),
|
||||
url(r'^me/underarmourrefresh/$',views.rower_underarmour_token_refresh,name='rower_underarmoud_token_refresh'),
|
||||
url(r'^me/tprefresh/$',views.rower_tp_token_refresh,name='rower_tp_token_refresh'),
|
||||
url(r'^me/c2refresh/$',views.rower_c2_token_refresh,name='rower_c2_token_refresh'),
|
||||
url(r'^me/favoritecharts/$',views.rower_favoritecharts_view,name='rower_favoritecharts_view'),
|
||||
url(r'^me/favoritecharts/user/(?P<userid>\d+)/$',views.rower_favoritecharts_view,name='rower_favoritecharts_view'),
|
||||
# url(r'^me/workflowconfig/$',views.workout_workflow_config_view),
|
||||
url(r'^me/workflowconfig2/$',views.workout_workflow_config2_view),
|
||||
url(r'^me/workflowconfig2/user/(?P<userid>\d+)/$',views.workout_workflow_config2_view),
|
||||
url(r'^me/workflowdefault/$',views.workflow_default_view),
|
||||
url(r'^email/send/$', views.sendmail),
|
||||
url(r'^me/workflowconfig2/$',views.workout_workflow_config2_view,name='workout_workflow_config2_view'),
|
||||
url(r'^me/workflowconfig2/user/(?P<userid>\d+)/$',views.workout_workflow_config2_view,name='workout_workflow_config2_view'),
|
||||
url(r'^me/workflowdefault/$',views.workflow_default_view,name='workflow_default_view'),
|
||||
url(r'^email/send/$', views.sendmail,name='sendmail'),
|
||||
url(r'^email/thankyou/$', TemplateView.as_view(template_name='thankyou.html'), name='thankyou'),
|
||||
url(r'^email/$', TemplateView.as_view(template_name='email.html'), name='email'),
|
||||
url(r'^about', TemplateView.as_view(template_name='about_us.html'),name='about'),
|
||||
@@ -440,39 +450,39 @@ urlpatterns = [
|
||||
url(r'^analysis/$', views.analysis_view,name='analysis'),
|
||||
url(r'^laboratory/$', views.laboratory_view,name='laboratory'),
|
||||
url(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'),
|
||||
url(r'^checkout/(?P<planid>\d+)/$',views.payment_confirm_view),
|
||||
url(r'^upgradecheckout/(?P<planid>\d+)/$',views.upgrade_confirm_view),
|
||||
url(r'^downgradecheckout/(?P<planid>\d+)/$',views.downgrade_confirm_view),
|
||||
url(r'^checkout/(?P<planid>\d+)/$',views.payment_confirm_view,name='payment_confirm_view'),
|
||||
url(r'^upgradecheckout/(?P<planid>\d+)/$',views.upgrade_confirm_view,name='upgrade_confirm_view'),
|
||||
url(r'^downgradecheckout/(?P<planid>\d+)/$',views.downgrade_confirm_view,name='downgrade_confirm_view'),
|
||||
url(r'^billing/$',views.billing_view,name='billing'),
|
||||
url(r'^upgrade/$',views.upgrade_view,name='upgrade'),
|
||||
url(r'^downgrade/$',views.downgrade_view,name='downgrade'),
|
||||
url(r'^paymentcompleted/$',views.payment_completed_view),
|
||||
url(r'^downgradecompleted/$',views.downgrade_completed_view),
|
||||
url(r'^paymentcompleted/$',views.payment_completed_view,name='payment_completed_view'),
|
||||
url(r'^downgradecompleted/$',views.downgrade_completed_view,name='downgrade_completed_view'),
|
||||
url(r'^paidplans/$',views.paidplans_view,name='paidplans'),
|
||||
url(r'^me/cancelsubscriptions/$',views.plan_stop_view),
|
||||
url(r'^me/cancelsubscription/(?P<id>[\w\ ]+.*)/$',views.plan_tobasic_view),
|
||||
url(r'^me/cancelsubscriptions/$',views.plan_stop_view,name='plan_stop_view'),
|
||||
url(r'^me/cancelsubscription/(?P<id>[\w\ ]+.*)/$',views.plan_tobasic_view,name='plan_tobasic_view'),
|
||||
url(r'^checkouts/$',views.checkouts_view,name='checkouts'),
|
||||
url(r'^upgradecheckouts/$',views.upgrade_checkouts_view,name='upgrade_checkouts'),
|
||||
url(r'^downgradecheckouts/$',views.downgrade_checkouts_view,name='downgrade_checkouts'),
|
||||
url(r'^planrequired/',views.planrequired_view),
|
||||
url(r'^starttrial/$',views.start_trial_view),
|
||||
url(r'^startplantrial/$',views.start_plantrial_view),
|
||||
url(r'^planrequired/',views.planrequired_view,name='planrequired_view'),
|
||||
url(r'^starttrial/$',views.start_trial_view,name='start_trial_view'),
|
||||
url(r'^startplantrial/$',views.start_plantrial_view,name='start_plantrial_view'),
|
||||
# url(r'^planmembership', TemplateView.as_view(template_name='planmembership.html'),name='planmembership'),
|
||||
# url(r'^paypaltest', TemplateView.as_view(template_name='paypaltest.html'),name='paypaltest'),
|
||||
url(r'^legal', TemplateView.as_view(template_name='legal.html'),name='legal'),
|
||||
url(r'^register/$',views.rower_register_view),
|
||||
url(r'^register/$',views.rower_register_view,name='rower_register_view'),
|
||||
url(r'^register/thankyou/$', TemplateView.as_view(template_name='registerthankyou.html'), name='registerthankyou'),
|
||||
url(r'^workout/(?P<id>\d+)/workflow/$',views.workout_workflow_view,
|
||||
name='workout_workflow_view'),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>[\w\ ]+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)/$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/$',views.workout_flexchart3_view),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>[\w\ ]+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view,name='workout_flexchart3_view'),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)/$',views.workout_flexchart3_view,name='workout_flexchart3_view'),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/$',views.workout_flexchart3_view,name='workout_flexchart3_view'),
|
||||
url(r'^workout/(?P<id>\d+)/flexchart/$',views.workout_flexchart3_view,name='workout_flexchart3_view'),
|
||||
# url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/(?P<plottype>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||
# url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||
url(r'^test\_callback',views.rower_process_testcallback),
|
||||
url(r'^createplan/$',views.rower_create_trainingplan),
|
||||
url(r'^createplan/user/(?P<userid>\d+)/$',views.rower_create_trainingplan),
|
||||
url(r'^test\_callback',views.rower_process_testcallback,name='rower_process_testcallback'),
|
||||
url(r'^createplan/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
|
||||
url(r'^createplan/user/(?P<userid>\d+)/$',views.rower_create_trainingplan,name='rower_create_trainingplan'),
|
||||
url(r'^deleteplan/(?P<pk>\d+)/$',login_required(
|
||||
views.TrainingPlanDelete.as_view())),
|
||||
url(r'^deletemicrocycle/(?P<pk>\d+)/$',login_required(
|
||||
|
||||
@@ -468,3 +468,17 @@ def get_strava_stream(r,metric,stravaid,series_type='time',fetchresolution='high
|
||||
s = requests.get(url,headers=headers)
|
||||
|
||||
return s
|
||||
|
||||
def allmonths(startdate,enddate):
|
||||
d = startdate
|
||||
while d<enddate:
|
||||
yield d
|
||||
d = datetime.date(d.year+(d.month / 12),((d.month % 12) + 1),1)
|
||||
|
||||
def allsundays(startdate,enddate):
|
||||
d = startdate
|
||||
d += datetime.timedelta(days = 6 - d.weekday()) # first Sunday
|
||||
while d<=enddate:
|
||||
yield d
|
||||
d += datetime.timedelta(days=7)
|
||||
|
||||
|
||||
12
rowers/views/__init__.py
Normal file
12
rowers/views/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from .analysisviews import *
|
||||
from .apiviews import *
|
||||
from .errorviews import *
|
||||
from .exportviews import *
|
||||
from .importviews import *
|
||||
from .otherviews import *
|
||||
from .paymentviews import *
|
||||
from .planviews import *
|
||||
from .racesviews import *
|
||||
from .teamviews import *
|
||||
from .userviews import *
|
||||
from .workoutviews import *
|
||||
3543
rowers/views/analysisviews.py
Normal file
3543
rowers/views/analysisviews.py
Normal file
File diff suppressed because it is too large
Load Diff
182
rowers/views/apiviews.py
Normal file
182
rowers/views/apiviews.py
Normal file
@@ -0,0 +1,182 @@
|
||||
from statements import *
|
||||
|
||||
|
||||
# Stroke data form to test API upload
|
||||
@login_required()
|
||||
def strokedataform(request,id=0):
|
||||
|
||||
try:
|
||||
id=int(id)
|
||||
except ValueError:
|
||||
id = 0
|
||||
|
||||
try:
|
||||
w = Workout.objects.get(id=id)
|
||||
except Workout.DoesNotExist:
|
||||
raise Http404("Workout doesn't exist")
|
||||
|
||||
if request.method == 'GET':
|
||||
form = StrokeDataForm()
|
||||
return render(request, 'strokedata_form.html',
|
||||
{
|
||||
'form':form,
|
||||
'teams':get_my_teams(request.user),
|
||||
'id':id,
|
||||
'workout':w,
|
||||
})
|
||||
elif request.method == 'POST':
|
||||
form = StrokeDataForm()
|
||||
|
||||
return render(request, 'strokedata_form.html',
|
||||
{
|
||||
'form':form,
|
||||
'teams':get_my_teams(request.user),
|
||||
'id':id,
|
||||
'workout':w,
|
||||
})
|
||||
|
||||
# Process the POSTed stroke data according to the API definition
|
||||
# Return the GET stroke data according to the API definition
|
||||
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
|
||||
|
||||
@csrf_exempt
|
||||
@login_required()
|
||||
@api_view(['GET','POST'])
|
||||
def strokedatajson(request,id):
|
||||
"""
|
||||
POST: Add Stroke data to workout
|
||||
GET: Get stroke data of workout
|
||||
"""
|
||||
row = get_workout_permitted(request.user,id)
|
||||
|
||||
try:
|
||||
id = int(id)
|
||||
except ValueError:
|
||||
return HttpResponse("Not a valid workout number",status=400)
|
||||
|
||||
|
||||
if request.method == 'GET':
|
||||
# currently only returns a subset.
|
||||
columns = ['spm','time','hr','pace','power','distance']
|
||||
datadf = dataprep.getsmallrowdata_db(columns,ids=[id])
|
||||
with open('media/apilog.log','a') as logfile:
|
||||
logfile.write(str(timezone.now())+": ")
|
||||
logfile.write(request.user.username+"(GET) \n")
|
||||
return JSONResponse(datadf)
|
||||
|
||||
if request.method == 'POST':
|
||||
checkdata,r = dataprep.getrowdata_db(id=row.id)
|
||||
if not checkdata.empty:
|
||||
return HttpResponse("Duplicate Error",409)
|
||||
# strokedata = request.POST['strokedata']
|
||||
# checking/validating and cleaning
|
||||
try:
|
||||
strokedata = json.loads(request.POST['strokedata'])
|
||||
except:
|
||||
return HttpResponse("No JSON object could be decoded",400)
|
||||
|
||||
df = pd.DataFrame(strokedata)
|
||||
df.index = df.index.astype(int)
|
||||
df.sort_index(inplace=True)
|
||||
# time, hr, pace, spm, power, drivelength, distance, drivespeed, dragfactor, strokerecoverytime, averagedriveforce, peakdriveforce, lapidx
|
||||
try:
|
||||
time = df['time']/1.e3
|
||||
except KeyError:
|
||||
return HttpResponse("There must be time values",status=400)
|
||||
aantal = len(time)
|
||||
pace = df['pace']/1.e3
|
||||
if len(pace) != aantal:
|
||||
return HttpResponse("Pace array has incorrect length",status=400)
|
||||
distance = df['distance']
|
||||
if len(distance) != aantal:
|
||||
return HttpResponse("Distance array has incorrect length",status=400)
|
||||
|
||||
spm = df['spm']
|
||||
if len(spm) != aantal:
|
||||
return HttpResponse("SPM array has incorrect length",status=400)
|
||||
|
||||
res = dataprep.testdata(time,distance,pace,spm)
|
||||
if not res:
|
||||
return HttpResponse("Data are not numerical",status=400)
|
||||
|
||||
power = trydf(df,aantal,'power')
|
||||
drivelength = trydf(df,aantal,'drivelength')
|
||||
drivespeed = trydf(df,aantal,'drivespeed')
|
||||
dragfactor = trydf(df,aantal,'dragfactor')
|
||||
drivetime = trydf(df,aantal,'drivetime')
|
||||
strokerecoverytime = trydf(df,aantal,'strokerecoverytime')
|
||||
averagedriveforce = trydf(df,aantal,'averagedriveforce')
|
||||
peakdriveforce = trydf(df,aantal,'peakdriveforce')
|
||||
wash = trydf(df,aantal,'wash')
|
||||
catch = trydf(df,aantal,'catch')
|
||||
finish = trydf(df,aantal,'finish')
|
||||
peakforceangle = trydf(df,aantal,'peakforceangle')
|
||||
driveenergy = trydf(df,aantal,'driveenergy')
|
||||
slip = trydf(df,aantal,'slip')
|
||||
lapidx = trydf(df,aantal,'lapidx')
|
||||
hr = trydf(df,aantal,'hr')
|
||||
|
||||
starttime = totimestamp(row.startdatetime)+time[0]
|
||||
unixtime = starttime+time
|
||||
|
||||
with open('media/apilog.log','a') as logfile:
|
||||
logfile.write(str(starttime)+": ")
|
||||
logfile.write(request.user.username+"(POST) \r\n")
|
||||
|
||||
data = pd.DataFrame({'TimeStamp (sec)':unixtime,
|
||||
' Horizontal (meters)': distance,
|
||||
' Cadence (stokes/min)':spm,
|
||||
' HRCur (bpm)':hr,
|
||||
' DragFactor':dragfactor,
|
||||
' Stroke500mPace (sec/500m)':pace,
|
||||
' Power (watts)':power,
|
||||
' DriveLength (meters)':drivelength,
|
||||
' DriveTime (ms)':drivetime,
|
||||
' StrokeRecoveryTime (ms)':strokerecoverytime,
|
||||
' AverageDriveForce (lbs)':averagedriveforce,
|
||||
' PeakDriveForce (lbs)':peakdriveforce,
|
||||
' lapIdx':lapidx,
|
||||
' ElapsedTime (sec)':time,
|
||||
'catch':catch,
|
||||
'slip':slip,
|
||||
'finish':finish,
|
||||
'wash':wash,
|
||||
'driveenergy':driveenergy,
|
||||
'peakforceangle':peakforceangle,
|
||||
})
|
||||
|
||||
# Following part should be replaced with dataprep.new_workout_from_df
|
||||
|
||||
r = getrower(request.user)
|
||||
|
||||
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
|
||||
csvfilename ='media/Import_'+timestr+'.csv'
|
||||
|
||||
res = data.to_csv(csvfilename+'.gz',index_label='index',
|
||||
compression='gzip')
|
||||
row.csvfilename = csvfilename
|
||||
row.save()
|
||||
|
||||
powerperc = 100*np.array([r.pw_ut2,
|
||||
r.pw_ut1,
|
||||
r.pw_at,
|
||||
r.pw_tr,r.pw_an])/r.ftp
|
||||
|
||||
ftp = float(r.ftp)
|
||||
if row.workouttype in mytypes.otwtypes:
|
||||
ftp = ftp*(100.-r.otwslack)/100.
|
||||
|
||||
rr = rrower(hrmax=r.max,hrut2=r.ut2,
|
||||
hrut1=r.ut1,hrat=r.at,
|
||||
hrtr=r.tr,hran=r.an,ftp=ftp,
|
||||
powerperc=powerperc,powerzones=r.powerzones)
|
||||
rowdata = rdata(row.csvfilename,rower=rr).df
|
||||
|
||||
datadf = dataprep.dataprep(rowdata,id=row.id,bands=True,barchart=True,otwpower=True,empower=True)
|
||||
# mangling
|
||||
|
||||
#
|
||||
return HttpResponse(row.id,status=201)
|
||||
|
||||
#Method not supported
|
||||
return HttpResponseNotAllowed("Method not supported")
|
||||
30
rowers/views/errorviews.py
Normal file
30
rowers/views/errorviews.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from statements import *
|
||||
|
||||
# Custom error pages with Rowsandall headers
|
||||
def error500_view(request):
|
||||
response = render_to_response('500.html', {},
|
||||
context_instance = RequestContext(request))
|
||||
|
||||
response.status_code = 500
|
||||
return response
|
||||
|
||||
def error404_view(request):
|
||||
response = render_to_response('404.html', {},
|
||||
context_instance = RequestContext(request))
|
||||
|
||||
response.status_code = 404
|
||||
return response
|
||||
|
||||
def error400_view(request):
|
||||
response = render_to_response('400.html', {},
|
||||
context_instance = RequestContext(request))
|
||||
|
||||
response.status_code = 400
|
||||
return response
|
||||
|
||||
def error403_view(request):
|
||||
response = render_to_response('403.html', {},
|
||||
context_instance = RequestContext(request))
|
||||
|
||||
response.status_code = 403
|
||||
return response
|
||||
220
rowers/views/exportviews.py
Normal file
220
rowers/views/exportviews.py
Normal file
@@ -0,0 +1,220 @@
|
||||
from statements import *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Export workout to TCX and send to user's email address
|
||||
@login_required()
|
||||
def workout_tcxemail_view(request,id=0):
|
||||
r = getrower(request.user)
|
||||
w = get_workout(id)
|
||||
|
||||
if not checkworkoutuser(request.user,w):
|
||||
raise PermissionDenied("Access denied")
|
||||
|
||||
|
||||
row = rdata(w.csvfilename)
|
||||
|
||||
code = str(uuid4())
|
||||
tcxfilename = code+'.tcx'
|
||||
|
||||
row.exporttotcx(tcxfilename)
|
||||
|
||||
with open(tcxfilename,'r') as f:
|
||||
response = HttpResponse(f)
|
||||
response['Content-Disposition'] = 'attachment; filename="%s"' % tcxfilename
|
||||
response['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
os.remove(tcxfilename)
|
||||
return response
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@login_required()
|
||||
def plannedsessions_icsemail_view(request,userid=0):
|
||||
r = getrequestrower(request,userid=userid)
|
||||
startdate,enddate = get_dates_timeperiod(request)
|
||||
|
||||
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
||||
|
||||
cal = Calendar()
|
||||
cal.add('prodid','rowsandall')
|
||||
cal.add('version','1.0')
|
||||
|
||||
for ps in sps:
|
||||
event = Event()
|
||||
comment = '{d} {u} {c}'.format(
|
||||
d=ps.sessionvalue,
|
||||
u = ps.sessionunit,
|
||||
c = ps.criterium)
|
||||
event.add('summary',ps.name)
|
||||
event.add('dtstart',ps.preferreddate)
|
||||
event.add('dtend',ps.preferreddate)
|
||||
event['uid'] = 'plannedsession_'+str(ps.id)
|
||||
event.add('description',ps.comment)
|
||||
event.add('comment',comment)
|
||||
cal.add_component(event)
|
||||
|
||||
|
||||
response = HttpResponse(cal.to_ical())
|
||||
response['Content-Disposition'] = 'attachment; filename="training_plan_{u}_{d1}_{d2}.ics"'.format(
|
||||
u = request.user.username,
|
||||
d1 = startdate.strftime("%Y%m%d"),
|
||||
d2 = enddate.strftime("%Y%m%d"),
|
||||
)
|
||||
|
||||
response['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@login_required()
|
||||
def course_kmldownload_view(request,id=0):
|
||||
r = getrower(request.user)
|
||||
if r.emailbounced:
|
||||
message = "Please check your email address first. Email to this address bounced."
|
||||
messages.error(request,message)
|
||||
return HttpResponseRedirect(
|
||||
reverse(course_view,
|
||||
kwargs = {
|
||||
'id':str(id),
|
||||
})
|
||||
)
|
||||
|
||||
course = GeoCourse.objects.get(id=id)
|
||||
|
||||
kmlstring = courses.coursetokml(course)
|
||||
|
||||
kmlfilename = 'course_{id}.kml'.format(id=id)
|
||||
|
||||
response = HttpResponse(kmlstring)
|
||||
response['Content-Disposition'] = 'attachment; filename="{filename}"'.format(filename=kmlfilename)
|
||||
response['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
return response
|
||||
|
||||
|
||||
|
||||
# Export workout to GPX and send to user's email address
|
||||
@login_required()
|
||||
def workout_gpxemail_view(request,id=0):
|
||||
r = getrower(request.user)
|
||||
w = get_workout(id)
|
||||
|
||||
if not checkworkoutuser(request.user,w):
|
||||
raise PermissionDenied("Access denied")
|
||||
|
||||
|
||||
row = rdata(w.csvfilename)
|
||||
|
||||
code = str(uuid4())
|
||||
gpxfilename = code+'.gpx'
|
||||
|
||||
row.exporttogpx(gpxfilename)
|
||||
|
||||
with open(gpxfilename,'r') as f:
|
||||
response = HttpResponse(f)
|
||||
response['Content-Disposition'] = 'attachment; filename="%s"' % gpxfilename
|
||||
response['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
os.remove(gpxfilename)
|
||||
return response
|
||||
|
||||
# Get Workout summary CSV file
|
||||
@login_required()
|
||||
def workouts_summaries_email_view(request):
|
||||
r = getrower(request.user)
|
||||
if r.emailbounced:
|
||||
message = "Please check your email address first. Email to this address bounced."
|
||||
messages.error(request, message)
|
||||
return HttpResponseRedirect(
|
||||
reverse(r.defaultlandingpage,
|
||||
kwargs = {
|
||||
'id':str(w.id),
|
||||
})
|
||||
)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = DateRangeForm(request.POST)
|
||||
if form.is_valid():
|
||||
startdate = form.cleaned_data['startdate']
|
||||
enddate = form.cleaned_data['enddate']
|
||||
filename = 'rowsandall_workouts_{first}_{last}.csv'.format(
|
||||
first=startdate,
|
||||
last=enddate
|
||||
)
|
||||
df = dataprep.workout_summary_to_df(r,startdate=startdate,enddate=enddate)
|
||||
df.to_csv(filename,encoding='utf-8')
|
||||
res = myqueue(queuehigh,handle_sendemailsummary,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
r.user.email,
|
||||
filename,
|
||||
emailbounced = r.emailbounced
|
||||
)
|
||||
messages.info(request,'The summary CSV file was sent to you per email')
|
||||
else:
|
||||
form = DateRangeForm()
|
||||
|
||||
return render(request,"export_workouts.html",
|
||||
{
|
||||
'form':form
|
||||
})
|
||||
|
||||
|
||||
# Get Workout CSV file and send it to user's email address
|
||||
@login_required()
|
||||
def workout_csvemail_view(request,id=0):
|
||||
r = getrower(request.user)
|
||||
|
||||
w = get_workout(id)
|
||||
|
||||
if not checkworkoutuser(request.user,w):
|
||||
raise PermissionDenied("Access denied")
|
||||
|
||||
rowdata = rdata(w.csvfilename)
|
||||
code = str(uuid4())
|
||||
filename = code+'.csv'
|
||||
|
||||
rowdate = rowdata.rowdatetime
|
||||
starttimeunix = arrow.get(rowdate).timestamp
|
||||
df = rowdata.df
|
||||
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
|
||||
df['TimeStamp (sec)'] = df['TimeStamp (sec)'] + starttimeunix
|
||||
|
||||
response = HttpResponse(df.to_csv())
|
||||
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||
response['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
return response
|
||||
|
||||
|
||||
# Get Workout CSV file and send it to user's email address
|
||||
@login_required()
|
||||
def workout_csvtoadmin_view(request,id=0):
|
||||
message = ""
|
||||
r = getrower(request.user)
|
||||
w = get_workout(id)
|
||||
|
||||
|
||||
csvfile = w.csvfilename
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemailcsv,
|
||||
'Sander',
|
||||
'Roosendaal',
|
||||
'roosendaalsander@gmail.com',
|
||||
csvfile)
|
||||
|
||||
successmessage = "The CSV file was sent to the site admin per email"
|
||||
messages.info(request,successmessage)
|
||||
url = reverse(workout_view,
|
||||
kwargs = {
|
||||
'id':str(w.id),
|
||||
})
|
||||
response = HttpResponseRedirect(url)
|
||||
|
||||
return response
|
||||
1604
rowers/views/importviews.py
Normal file
1604
rowers/views/importviews.py
Normal file
File diff suppressed because it is too large
Load Diff
142
rowers/views/otherviews.py
Normal file
142
rowers/views/otherviews.py
Normal file
@@ -0,0 +1,142 @@
|
||||
from statements import *
|
||||
|
||||
|
||||
@login_required()
|
||||
def deactivate_user(request):
|
||||
pk = request.user.id
|
||||
user = User.objects.get(pk=pk)
|
||||
user_form = DeactivateUserForm(instance=user)
|
||||
if request.user.is_authenticated() and request.user.id == user.id:
|
||||
if request.method == "POST":
|
||||
user_form = DeactivateUserForm(request.POST, instance=user)
|
||||
if user_form.is_valid():
|
||||
if not user_form.cleaned_data['is_active']:
|
||||
r = Rower.objects.get(user=user)
|
||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||
try:
|
||||
subscriptions = braintreestuff.find_subscriptions(r)
|
||||
for subscription in subscriptions:
|
||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||
for message in themessages:
|
||||
messages.info(request,message)
|
||||
except ProcessorCustomerError:
|
||||
pass
|
||||
|
||||
r.paidplan = None
|
||||
r.teamplanexpires = timezone.now()
|
||||
r.planexpires = timezone.now()
|
||||
r.clubsize = 0
|
||||
r.rowerplan = 'basic'
|
||||
r.save()
|
||||
|
||||
deactivate_user = user_form.save(commit=False)
|
||||
user.is_active = False
|
||||
user.save()
|
||||
deactivate_user.save()
|
||||
# url = reverse(auth_views.logout_then_login)
|
||||
url = '/logout/?next=/login'
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
return render(request, "userprofile_deactivate.html", {
|
||||
"user_form": user_form,
|
||||
})
|
||||
else:
|
||||
raise PermissionDenied
|
||||
|
||||
@login_required()
|
||||
def user_gdpr_optin(request):
|
||||
r = getrower(request.user)
|
||||
r.gdproptin = False
|
||||
r.gdproptindate = None
|
||||
r.save()
|
||||
nexturl = request.GET.get('next','/rowers/list-workouts/')
|
||||
if r.gdproptin:
|
||||
return HttpResponseRedirect(nexturl)
|
||||
|
||||
return render(request,'gdpr_optin.html',{
|
||||
"next": nexturl
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def user_gdpr_confirm(request):
|
||||
r = getrower(request.user)
|
||||
r.gdproptin = True
|
||||
r.gdproptindate = timezone.now()
|
||||
r.save()
|
||||
|
||||
nexturl = request.GET.get('next','/rowers/list-workouts/')
|
||||
|
||||
return HttpResponseRedirect(nexturl)
|
||||
|
||||
|
||||
|
||||
@login_required()
|
||||
def remove_user(request):
|
||||
pk = request.user.id
|
||||
user = User.objects.get(pk=pk)
|
||||
user_form = DeleteUserForm(instance=user)
|
||||
if request.user.is_authenticated() and request.user.id == user.id:
|
||||
if request.method == "POST":
|
||||
user_form = DeleteUserForm(request.POST,instance=user)
|
||||
if user_form.is_valid():
|
||||
cd = user_form.cleaned_data
|
||||
name = user.first_name+' '+user.last_name
|
||||
email = user.email
|
||||
|
||||
r = Rower.objects.get(user=user)
|
||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||
try:
|
||||
subscriptions = braintreestuff.find_subscriptions(r)
|
||||
for subscription in subscriptions:
|
||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||
for message in themessages:
|
||||
messages.info(request,message)
|
||||
except ProcessorCustomerError:
|
||||
pass
|
||||
|
||||
if cd['delete_user']:
|
||||
user.delete()
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_userdeleted,
|
||||
name, email)
|
||||
|
||||
url = '/logout/?next=/login'
|
||||
# url = reverse(auth_views.logout_then_login)
|
||||
return HttpResponseRedirect(url)
|
||||
return render(request, "userprofile_delete.html", {
|
||||
"user_form": user_form,
|
||||
})
|
||||
else:
|
||||
raise PermissionDenied
|
||||
|
||||
|
||||
|
||||
# Shows analysis page
|
||||
@login_required()
|
||||
def analysis_view(request,userid=0):
|
||||
r = getrequestrower(request,userid=userid)
|
||||
return render(request,
|
||||
"analysis.html",
|
||||
{
|
||||
'active':'nav-analysis',
|
||||
'rower':r,
|
||||
}
|
||||
)
|
||||
|
||||
# Shows laboratory page
|
||||
@login_required()
|
||||
def laboratory_view(request,userid=0):
|
||||
r = getrequestrower(request,userid=userid)
|
||||
return render(request,
|
||||
"laboratory.html",
|
||||
{
|
||||
'active':'nav-analysis',
|
||||
'rower':r,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
590
rowers/views/paymentviews.py
Normal file
590
rowers/views/paymentviews.py
Normal file
@@ -0,0 +1,590 @@
|
||||
|
||||
from statements import *
|
||||
|
||||
def paidplans_view(request):
|
||||
if not request.user.is_anonymous():
|
||||
r = getrequestrower(request)
|
||||
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')
|
||||
else:
|
||||
r = None
|
||||
|
||||
|
||||
|
||||
return render(request,
|
||||
'paidplans.html',
|
||||
{'rower':r})
|
||||
|
||||
@login_required()
|
||||
def billing_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
if payments.is_existing_customer(r):
|
||||
url = reverse(upgrade_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
if request.method == 'POST':
|
||||
billingaddressform = RowerBillingAddressForm(request.POST)
|
||||
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
|
||||
if billingaddressform.is_valid():
|
||||
cd = billingaddressform.cleaned_data
|
||||
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']
|
||||
try:
|
||||
customer_id = braintreestuff.create_customer(r)
|
||||
except ProcessorCustomerError:
|
||||
messages.error(request,"Something went wrong registering you as a customer.")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
url = reverse(payment_confirm_view,
|
||||
kwargs={
|
||||
'planid':plan.id
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
else:
|
||||
billingaddressform = RowerBillingAddressForm(instance=r)
|
||||
planselectform = PlanSelectForm(paymentprocessor='braintree')
|
||||
|
||||
return render(request,
|
||||
'billing.html',
|
||||
{'rower':r,
|
||||
'billingaddressform':billingaddressform,
|
||||
'planselectform':planselectform,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def upgrade_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
if r.subscription_id is None or r.subscription_id == '':
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
if request.method == 'POST':
|
||||
billingaddressform = RowerBillingAddressForm(request.POST)
|
||||
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
|
||||
if billingaddressform.is_valid():
|
||||
cd = billingaddressform.cleaned_data
|
||||
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():
|
||||
url = reverse(upgrade_confirm_view,
|
||||
kwargs={
|
||||
'planid':plan.id
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
else:
|
||||
billingaddressform = RowerBillingAddressForm(instance=r)
|
||||
planselectform = PlanSelectForm(paymentprocessor='braintree',
|
||||
rower=r)
|
||||
|
||||
return render(request,
|
||||
'upgrade.html',
|
||||
{'rower':r,
|
||||
'billingaddressform':billingaddressform,
|
||||
'planselectform':planselectform,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def downgrade_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
if r.subscription_id is None or r.subscription_id == '':
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
if request.method == 'POST':
|
||||
billingaddressform = RowerBillingAddressForm(request.POST)
|
||||
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
|
||||
if billingaddressform.is_valid():
|
||||
cd = billingaddressform.cleaned_data
|
||||
for attr, value in cd.items():
|
||||
setattr(r, attr, value)
|
||||
r.save()
|
||||
|
||||
if planselectform.is_valid():
|
||||
plan = planselectform.cleaned_data['plan']
|
||||
|
||||
if plan.price > r.paidplan.price:
|
||||
nextview = upgrade_confirm_view
|
||||
elif plan.price == r.paidplan.price:
|
||||
messages.info(request,'You did not select a new plan')
|
||||
url = reverse(downgrade_view)
|
||||
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',
|
||||
rower=r,includeall=True, initial={'plan':r.paidplan})
|
||||
|
||||
return render(request,
|
||||
'downgrade.html',
|
||||
{'rower':r,
|
||||
'billingaddressform':billingaddressform,
|
||||
'planselectform':planselectform,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def plan_stop_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||
try:
|
||||
subscriptions = braintreestuff.find_subscriptions(r)
|
||||
except ProcessorCustomerError:
|
||||
r.paymentprocessor = None
|
||||
r.save()
|
||||
|
||||
|
||||
|
||||
return render(request,
|
||||
'subscriptions_cancel.html',
|
||||
{'rower':r,
|
||||
'subscriptions':subscriptions
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def plan_tobasic_view(request,id=0):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
if r.paidplan.paymentprocessor == 'braintree':
|
||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||
for message in themessages:
|
||||
messages.info(request,message)
|
||||
|
||||
for message in errormessages:
|
||||
messages.error(request,message)
|
||||
|
||||
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:
|
||||
messages.error(request,"Something went wrong. Please try again.")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
client_token = braintreestuff.get_client_token(r)
|
||||
|
||||
return render(request,
|
||||
"upgradeconfirm.html",
|
||||
{
|
||||
'plan':plan,
|
||||
'client_token':client_token,
|
||||
'rower':r,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
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:
|
||||
messages.error(request,"Something went wrong. Please try again.")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
client_token = braintreestuff.get_client_token(r)
|
||||
|
||||
return render(request,
|
||||
"downgradeconfirm.html",
|
||||
{
|
||||
'plan':plan,
|
||||
'client_token':client_token,
|
||||
'rower':r,
|
||||
})
|
||||
|
||||
|
||||
@login_required()
|
||||
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:
|
||||
messages.error(request,"Something went wrong. Please try again.")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
client_token = braintreestuff.get_client_token(r)
|
||||
|
||||
return render(request,
|
||||
"paymentconfirm.html",
|
||||
{
|
||||
'plan':plan,
|
||||
'client_token':client_token,
|
||||
'rower':r,
|
||||
})
|
||||
|
||||
|
||||
@login_required()
|
||||
def checkouts_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
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')
|
||||
|
||||
if request.method != 'POST':
|
||||
url = reverse(paidplans_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
form = BillingForm(request.POST)
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
success,amount = braintreestuff.create_subscription(r,data)
|
||||
if success:
|
||||
messages.info(request,"Your payment has succeeded and your plan has been updated")
|
||||
url = "{baseurl}?amount={amount:.2f}".format(
|
||||
baseurl = reverse(payment_completed_view),
|
||||
amount = amount)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
messages.error(request,"There was a problem with your payment")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
elif 'tac' not in request.POST:
|
||||
try:
|
||||
planid = int(request.POST['plan'])
|
||||
url = reverse('payment_confirm_view',kwargs={'planid':planid})
|
||||
messages.error(request,"You must review and acknowledge the terms and conditions")
|
||||
return HttpResponseRedirect(url)
|
||||
except IndexError:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse('billing_view')
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
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 = getrequestrower(request)
|
||||
|
||||
if request.method != 'POST':
|
||||
url = reverse(paidplans_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
form = BillingForm(request.POST)
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
success,amount = braintreestuff.update_subscription(r,data)
|
||||
if success:
|
||||
messages.info(request,"Your payment has succeeded and your plan has been updated")
|
||||
url = "{baseurl}?amount={amount:.2f}".format(
|
||||
baseurl = reverse(payment_completed_view),
|
||||
amount = amount)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
messages.error(request,"There was a problem with your payment")
|
||||
url = reverse(upgrade_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
elif 'tac' not in request.POST:
|
||||
try:
|
||||
planid = int(request.POST['plan'])
|
||||
url = reverse('upgrade_confirm_view',kwargs={'planid':planid})
|
||||
messages.error(request,"You must review and acknowledge the terms and conditions")
|
||||
return HttpResponseRedirect(url)
|
||||
except IndexError:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse('billing_view')
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse(upgrade_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
url = reverse(paidplans_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@login_required()
|
||||
def downgrade_checkouts_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
if request.method != 'POST':
|
||||
url = reverse(paidplans_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
form = BillingForm(request.POST)
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
success = braintreestuff.update_subscription(r,data,method='down')
|
||||
if success:
|
||||
messages.info(request,"Your plan has been updated")
|
||||
url = reverse(downgrade_completed_view)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
messages.error(request,"There was a problem with your transaction")
|
||||
url = reverse(upgrade_view)
|
||||
return HttpResponseRedirect(url)
|
||||
elif 'tac' not in request.POST:
|
||||
try:
|
||||
planid = int(request.POST['plan'])
|
||||
url = reverse('downgrade_confirm_view',kwargs={'planid':planid})
|
||||
messages.error(request,"You must review and acknowledge the terms and conditions")
|
||||
return HttpResponseRedirect(url)
|
||||
except IndexError:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse('billing_view')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
else:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse(upgrade_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
url = reverse(paidplans_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
@login_required()
|
||||
def payment_completed_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
amount = request.GET.get('amount',0)
|
||||
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
return render(request,
|
||||
"payment_completed.html",
|
||||
{
|
||||
'rower':r,
|
||||
'amount':amount,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def downgrade_completed_view(request):
|
||||
if not PAYMENT_PROCESSING_ON:
|
||||
url = reverse('promembership')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
return render(request,
|
||||
"downgrade_completed.html",
|
||||
{
|
||||
'rower':r
|
||||
})
|
||||
|
||||
# User registration
|
||||
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)
|
||||
if form.is_valid():
|
||||
first_name = form.cleaned_data['first_name']
|
||||
last_name = form.cleaned_data['last_name']
|
||||
email = form.cleaned_data['email']
|
||||
password = form.cleaned_data['password1']
|
||||
username = form.cleaned_data['username']
|
||||
sex = form.cleaned_data['sex']
|
||||
birthdate = form.cleaned_data['birthdate']
|
||||
weightcategory = form.cleaned_data['weightcategory']
|
||||
adaptiveclass = form.cleaned_data['adaptiveclass']
|
||||
nextpage = request.POST['next']
|
||||
theuser = User.objects.create_user(username,password=password)
|
||||
theuser.first_name = first_name
|
||||
theuser.last_name = last_name
|
||||
theuser.email = email
|
||||
theuser.save()
|
||||
|
||||
birthdate = birthdate.replace(tzinfo=None)
|
||||
|
||||
therower = Rower(user=theuser,sex=sex,birthdate=birthdate,
|
||||
weightcategory=weightcategory,
|
||||
adaptiveclass=adaptiveclass)
|
||||
|
||||
therower.save()
|
||||
|
||||
# create default favorite charts
|
||||
add_defaultfavorites(therower)
|
||||
|
||||
# Create Sample workout
|
||||
f = 'media/testdata.csv.gz'
|
||||
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')
|
||||
newworkoutid = response[0]
|
||||
w = Workout.objects.get(id=newworkoutid)
|
||||
w.startdatetime = timezone.now()
|
||||
w.save()
|
||||
|
||||
# Create and send email
|
||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||
subject = "Thank you for registering on rowsandall.com"
|
||||
from_address = 'Sander Roosendaal <info@rowsandall.com>'
|
||||
|
||||
d = {'first_name':theuser.first_name}
|
||||
|
||||
send_template_email(from_address,[fullemail],
|
||||
subject,'registeremail.html',d)
|
||||
|
||||
|
||||
subject2 = "New User"
|
||||
message2 = "New user registered.\n"
|
||||
message2 += fullemail + "\n"
|
||||
message2 += "User name: "+username
|
||||
|
||||
send_mail(subject2, message2,
|
||||
'Rowsandall Server <info@rowsandall.com>',
|
||||
['roosendaalsander@gmail.com'])
|
||||
|
||||
theuser = authenticate(username=username,password=password)
|
||||
login(request,theuser)
|
||||
|
||||
return HttpResponseRedirect(nextpage)
|
||||
# '/rowers/register/thankyou/')
|
||||
|
||||
else:
|
||||
return render(request,
|
||||
"registration_form.html",
|
||||
{'form':form,
|
||||
'next':nextpage,})
|
||||
else:
|
||||
form = RegistrationFormSex()
|
||||
return render(request,
|
||||
"registration_form.html",
|
||||
{'form':form,
|
||||
'next':nextpage,})
|
||||
|
||||
@login_required()
|
||||
def transactions_view(request):
|
||||
if not request.user.is_staff:
|
||||
raise PermissionDenied("Not Allowed")
|
||||
|
||||
if request.method == 'POST':
|
||||
dateform = DateRangeForm(request.POST)
|
||||
if dateform.is_valid():
|
||||
startdate = dateform.cleaned_data['startdate']
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
|
||||
df = braintreestuff.get_transactions(startdate,enddate)
|
||||
filename="transactions_{s}_{e}.csv".format(s = startdate, e = enddate)
|
||||
response = HttpResponse(df.to_csv())
|
||||
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||
response['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
return response
|
||||
|
||||
else:
|
||||
dateform = DateRangeForm()
|
||||
|
||||
return render(request,
|
||||
'transactions.html',
|
||||
{
|
||||
'dateform':dateform
|
||||
})
|
||||
|
||||
2577
rowers/views/planviews.py
Normal file
2577
rowers/views/planviews.py
Normal file
File diff suppressed because it is too large
Load Diff
2305
rowers/views/racesviews.py
Normal file
2305
rowers/views/racesviews.py
Normal file
File diff suppressed because it is too large
Load Diff
1184
rowers/views/statements.py
Normal file
1184
rowers/views/statements.py
Normal file
File diff suppressed because it is too large
Load Diff
536
rowers/views/teamviews.py
Normal file
536
rowers/views/teamviews.py
Normal file
@@ -0,0 +1,536 @@
|
||||
from statements import *
|
||||
|
||||
|
||||
@login_required()
|
||||
def team_view(request,id=0,userid=0):
|
||||
ismember = 0
|
||||
hasrequested = 0
|
||||
r = getrequestrower(request,userid=userid)
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
teams.remove_expired_invites()
|
||||
|
||||
|
||||
try:
|
||||
t = Team.objects.get(id=id)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("Team doesn't exist")
|
||||
|
||||
|
||||
if request.method == 'POST' and request.user == t.manager:
|
||||
inviteform = TeamInviteForm(request.POST)
|
||||
inviteform.fields['user'].queryset = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
|
||||
if inviteform.is_valid():
|
||||
cd = inviteform.cleaned_data
|
||||
newmember = cd['user']
|
||||
email = cd['email']
|
||||
inviteid,text = teams.create_invite(t,t.manager,
|
||||
user=newmember,
|
||||
email=email)
|
||||
if inviteid:
|
||||
teams.send_invite_email(inviteid)
|
||||
successmessage = text
|
||||
messages.info(request,successmessage)
|
||||
else:
|
||||
message = text
|
||||
messages.error(request,message)
|
||||
|
||||
elif request.user == t.manager:
|
||||
inviteform = TeamInviteForm()
|
||||
inviteform.fields['user'].queryset = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
|
||||
else:
|
||||
inviteform = ''
|
||||
|
||||
members = Rower.objects.filter(team=t).order_by('user__last_name','user__first_name')
|
||||
thisteammyrequests = TeamRequest.objects.filter(team=t,user=request.user)
|
||||
if len(thisteammyrequests):
|
||||
hasrequested = 1
|
||||
|
||||
if r in members:
|
||||
ismember = 1
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_view,kwargs={'id':id}),
|
||||
'name': t.name
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
return render(request, 'team.html',
|
||||
{
|
||||
'team':t,
|
||||
'teams':get_my_teams(request.user),
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'members':members,
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'active':'nav-teams',
|
||||
'inviteform':inviteform,
|
||||
'ismember':ismember,
|
||||
'hasrequested':hasrequested,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def team_leaveconfirm_view(request,id=0):
|
||||
try:
|
||||
t = Team.objects.get(id=id)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("Team doesn't exist")
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_view,kwargs={'id':id}),
|
||||
'name': t.name
|
||||
},
|
||||
{
|
||||
'url':reverse(team_leaveconfirm_view,kwargs={'id':id}),
|
||||
'name': 'Leave'
|
||||
}
|
||||
]
|
||||
return render(request,'teamleaveconfirm.html',
|
||||
{
|
||||
'team':t,
|
||||
'teams':get_my_teams(request.user),
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'otherteams':otherteams,
|
||||
'active':'nav-teams',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def rower_calcdps_view(request):
|
||||
r = getrower(request.user)
|
||||
|
||||
ws = [(w.id,w.csvfilename) for w in Workout.objects.filter(user=r)]
|
||||
res = myqueue(queue,handle_updatedps,r.user.email,ws,debug=False,
|
||||
emailbounced=r.emailbounced)
|
||||
|
||||
messages.info(request,"Your workouts are being updated in the background. You will receive email when this is done.")
|
||||
|
||||
url = reverse('workouts_view')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@login_required()
|
||||
def team_leave_view(request,id=0):
|
||||
r = getrower(request.user)
|
||||
teams.remove_member(id,r)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
response = HttpResponseRedirect(url)
|
||||
return response
|
||||
|
||||
from rowers.forms import TeamInviteCodeForm
|
||||
|
||||
def get_teams(request):
|
||||
r = Rower.objects.get(user=request.user)
|
||||
|
||||
myteams = Team.objects.filter(
|
||||
manager=request.user).order_by('name')
|
||||
memberteams = Team.objects.filter(
|
||||
rower=r).exclude(manager=request.user).order_by('name')
|
||||
otherteams = Team.objects.filter(
|
||||
private='open').exclude(
|
||||
rower=r).exclude(manager=request.user).order_by('name')
|
||||
|
||||
return myteams, memberteams, otherteams
|
||||
|
||||
@login_required()
|
||||
def rower_teams_view(request,message='',successmessage=''):
|
||||
if request.method == 'POST':
|
||||
form = TeamInviteCodeForm(request.POST)
|
||||
if form.is_valid():
|
||||
code = form.cleaned_data['code']
|
||||
res,text = teams.process_invite_code(request.user,code)
|
||||
if res:
|
||||
successmessage = text
|
||||
else:
|
||||
message = text
|
||||
else:
|
||||
form = TeamInviteCodeForm()
|
||||
|
||||
r = getrower(request.user)
|
||||
ts = Team.objects.filter(rower=r)
|
||||
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
teams.remove_expired_invites()
|
||||
|
||||
|
||||
invites = TeamInvite.objects.filter(user=request.user)
|
||||
requests = TeamRequest.objects.filter(user=request.user)
|
||||
myrequests = TeamRequest.objects.filter(team__in=myteams)
|
||||
myinvites = TeamInvite.objects.filter(team__in=myteams)
|
||||
clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
|
||||
max_clubsize = r.clubsize
|
||||
|
||||
messages.info(request,successmessage)
|
||||
messages.error(request,message)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
}
|
||||
]
|
||||
|
||||
return render(request, 'teams.html',
|
||||
{
|
||||
'teams':ts,
|
||||
'active':'nav-teams',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'clubsize':clubsize,
|
||||
'max_clubsize':max_clubsize,
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'invites':invites,
|
||||
'otherteams':otherteams,
|
||||
'requests':requests,
|
||||
'myrequests':myrequests,
|
||||
'form':form,
|
||||
'myinvites':myinvites,
|
||||
})
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def invitation_revoke_view(request,id):
|
||||
res,text = teams.revoke_invite(request.user,id)
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
successmessage = text
|
||||
else:
|
||||
message = text
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def manager_member_drop_view(request,teamid,userid,
|
||||
message='',successmessage=''):
|
||||
rower = Rower.objects.get(user__id=userid)
|
||||
res, text = teams.mgr_remove_member(teamid,request.user,rower)
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
else:
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def manager_requests_view(request,code=None,message='',successmessage=''):
|
||||
if code:
|
||||
res,text = teams.process_request_code(request.user,code)
|
||||
if res:
|
||||
successmessage = text
|
||||
message = ''
|
||||
else:
|
||||
message = text
|
||||
successmessage = ''
|
||||
|
||||
messages.info(request,successmessage)
|
||||
messages.error(request,message)
|
||||
url = reverse(rower_teams_view,kwargs={
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
@login_required()
|
||||
def team_requestmembership_view(request,teamid,userid):
|
||||
try:
|
||||
t = Team.objects.get(id=teamid)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("Team doesn't exist")
|
||||
|
||||
res,text = teams.create_request(t,userid)
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
else:
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(team_view,kwargs={
|
||||
'id':int(teamid),
|
||||
})
|
||||
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@login_required()
|
||||
def request_revoke_view(request,id=0):
|
||||
res,text = teams.revoke_request(request.user,id)
|
||||
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
|
||||
else:
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def request_reject_view(request,id=0):
|
||||
res,text = teams.reject_request(request.user,id)
|
||||
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
else:
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def invitation_reject_view(request,id=0):
|
||||
res,text = teams.reject_invitation(request.user,id)
|
||||
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
else:
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@login_required()
|
||||
def rower_invitations_view(request,code=None,message='',successmessage=''):
|
||||
|
||||
if code:
|
||||
teams.remove_expired_invites()
|
||||
res,text = teams.process_invite_code(request.user,code)
|
||||
if res:
|
||||
messages.info(request,text)
|
||||
teamid=res
|
||||
url = reverse(team_view,kwargs={
|
||||
'id':teamid,
|
||||
})
|
||||
else:
|
||||
messages.error(request,text)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
url = reverse(rower_teams_view,kwargs={
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def team_edit_view(request,id=0):
|
||||
try:
|
||||
t = Team.objects.get(id=id)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("Team does not exist")
|
||||
|
||||
if request.method == 'POST':
|
||||
teamcreateform = TeamForm(request.POST,instance=t)
|
||||
if teamcreateform.is_valid():
|
||||
cd = teamcreateform.cleaned_data
|
||||
name = cd['name']
|
||||
notes = cd['notes']
|
||||
manager = request.user
|
||||
private = cd['private']
|
||||
viewing = cd['viewing']
|
||||
res,message=teams.update_team(t,name,manager,private,notes,
|
||||
viewing)
|
||||
if res:
|
||||
messages.info(request,message)
|
||||
else:
|
||||
messages.error(request,message)
|
||||
|
||||
url = reverse(team_view,
|
||||
kwargs={
|
||||
'id':int(id),
|
||||
}
|
||||
)
|
||||
|
||||
response = HttpResponseRedirect(url)
|
||||
return response
|
||||
|
||||
else:
|
||||
teamcreateform = TeamForm(instance=t)
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_view,kwargs={'id':id}),
|
||||
'name': t.name
|
||||
},
|
||||
{
|
||||
'url':reverse(team_edit_view,kwargs={'id':id}),
|
||||
'name': 'Edit'
|
||||
}
|
||||
]
|
||||
|
||||
return render(request,'teamedit.html',
|
||||
{
|
||||
'form':teamcreateform,
|
||||
'teams':get_my_teams(request.user),
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'otherteams':otherteams,
|
||||
'active':'nav-teams',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'team':t,
|
||||
})
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def team_create_view(request):
|
||||
if request.method == 'POST':
|
||||
teamcreateform = TeamForm(request.POST)
|
||||
if teamcreateform.is_valid():
|
||||
cd = teamcreateform.cleaned_data
|
||||
name = cd['name']
|
||||
notes = cd['notes']
|
||||
manager = request.user
|
||||
private = cd['private']
|
||||
viewing = cd['viewing']
|
||||
res,message=teams.create_team(name,manager,private,notes,
|
||||
viewing)
|
||||
url = reverse(rower_teams_view)
|
||||
response = HttpResponseRedirect(url)
|
||||
return response
|
||||
|
||||
else:
|
||||
teamcreateform = TeamForm()
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_create_view),
|
||||
'name': "New Team"
|
||||
},
|
||||
]
|
||||
return render(request,'teamcreate.html',
|
||||
{
|
||||
'teams':get_my_teams(request.user),
|
||||
'form':teamcreateform,
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'otherteams':otherteams,
|
||||
'active':'nav-teams',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
})
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def team_deleteconfirm_view(request,id):
|
||||
r = getrower(request.user)
|
||||
try:
|
||||
t = Team.objects.get(id=id)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("This team doesn't exist")
|
||||
if t.manager != request.user:
|
||||
raise PermissionDenied("You are not allowed to delete this team")
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_view,kwargs={'id':id}),
|
||||
'name': t.name
|
||||
},
|
||||
{
|
||||
'url':reverse(team_deleteconfirm_view,kwargs={'id':id}),
|
||||
'name': 'Leave'
|
||||
}
|
||||
]
|
||||
return render(request,'teamdeleteconfirm.html',
|
||||
{
|
||||
'teams':get_my_teams(request.user),
|
||||
'team':t,
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'otherteams':otherteams,
|
||||
'active':'nav-teams',
|
||||
})
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def team_delete_view(request,id):
|
||||
r = getrower(request.user)
|
||||
try:
|
||||
t = Team.objects.get(id=id)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("This team doesn't exist")
|
||||
if t.manager != request.user:
|
||||
raise PermissionDenied("You are not allowed to delete this team")
|
||||
|
||||
teams.remove_team(t.id)
|
||||
|
||||
url = reverse(rower_teams_view)
|
||||
response = HttpResponseRedirect(url)
|
||||
return response
|
||||
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
|
||||
def team_members_stats_view(request,id):
|
||||
r = getrower(request.user)
|
||||
try:
|
||||
t = Team.objects.get(id=id)
|
||||
except Team.DoesNotExist:
|
||||
raise Http404("This team doesn't exist")
|
||||
if t.manager != request.user:
|
||||
raise PermissionDenied("You are not allowed to see this page")
|
||||
|
||||
members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")
|
||||
|
||||
theusers = [member.user for member in members]
|
||||
|
||||
myteams, memberteams, otherteams = get_teams(request)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':reverse(rower_teams_view),
|
||||
'name': 'Teams'
|
||||
},
|
||||
{
|
||||
'url':reverse(team_view,kwargs={'id':id}),
|
||||
'name': t.name
|
||||
},
|
||||
{
|
||||
'url':reverse(team_members_stats_view,kwargs={'id':id}),
|
||||
'name': 'Members Stats'
|
||||
}
|
||||
]
|
||||
|
||||
response = render(request,'teamstats.html',
|
||||
{
|
||||
'teams':get_my_teams(request.user),
|
||||
'myteams':myteams,
|
||||
'memberteams':memberteams,
|
||||
'otherteams':otherteams,
|
||||
'active':'nav-teams',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'team':t,
|
||||
'theusers':theusers,
|
||||
})
|
||||
|
||||
return response
|
||||
485
rowers/views/userviews.py
Normal file
485
rowers/views/userviews.py
Normal file
@@ -0,0 +1,485 @@
|
||||
from statements import *
|
||||
|
||||
@login_required()
|
||||
def start_trial_view(request):
|
||||
r = getrower(request.user)
|
||||
|
||||
if r.protrialexpires is not None:
|
||||
messages.error(request,'You do not qualify for a trial')
|
||||
url = '/rowers/paidplans'
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
|
||||
r.save()
|
||||
|
||||
url = reverse(workouts_view)
|
||||
|
||||
messages.info(request,'We have started your 14 day trial period')
|
||||
|
||||
subject2 = "User started Pro Trial"
|
||||
message2 = "User Started Pro Trial.\n"
|
||||
message2 += request.user.email + "\n"
|
||||
message2 += "User name: "+request.user.username
|
||||
|
||||
send_mail(subject2, message2,
|
||||
'Rowsandall Server <info@rowsandall.com>',
|
||||
['roosendaalsander@gmail.com'])
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@login_required()
|
||||
def start_plantrial_view(request):
|
||||
r = getrower(request.user)
|
||||
|
||||
if r.plantrialexpires is not None:
|
||||
messages.error(request,'You do not qualify for a trial')
|
||||
url = '/rowers/paidplans'
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
r.plantrialexpires = datetime.date.today()+datetime.timedelta(13)
|
||||
r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
|
||||
r.save()
|
||||
|
||||
url = reverse(workouts_view)
|
||||
|
||||
messages.info(request,'We have started your 14 day trial period')
|
||||
|
||||
subject2 = "User started Plan Trial"
|
||||
message2 = "User Started Plan Trial.\n"
|
||||
message2 += request.user.email + "\n"
|
||||
message2 += "User name: "+request.user.username
|
||||
|
||||
send_mail(subject2, message2,
|
||||
'Rowsandall Server <info@rowsandall.com>',
|
||||
['roosendaalsander@gmail.com'])
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# Page where user can manage his favorite charts
|
||||
@login_required()
|
||||
def rower_favoritecharts_view(request,userid=0):
|
||||
message = ''
|
||||
successmessage = ''
|
||||
r = getrequestrower(request,userid=userid,notpermanent=True)
|
||||
favorites = FavoriteChart.objects.filter(user=r).order_by('id')
|
||||
aantal = len(favorites)
|
||||
favorites_data = [{'yparam1':f.yparam1,
|
||||
'yparam2':f.yparam2,
|
||||
'xparam':f.xparam,
|
||||
'plottype':f.plottype,
|
||||
'workouttype':f.workouttype,
|
||||
'reststrokes':f.reststrokes,
|
||||
'notes':f.notes,}
|
||||
for f in favorites]
|
||||
FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=0)
|
||||
if aantal==0:
|
||||
FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1)
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
favorites_formset = FavoriteChartFormSet(request.POST)
|
||||
if favorites_formset.is_valid():
|
||||
new_instances = []
|
||||
for favorites_form in favorites_formset:
|
||||
yparam1 = favorites_form.cleaned_data.get('yparam1')
|
||||
yparam2 = favorites_form.cleaned_data.get('yparam2')
|
||||
xparam = favorites_form.cleaned_data.get('xparam')
|
||||
plottype = favorites_form.cleaned_data.get('plottype')
|
||||
workouttype = favorites_form.cleaned_data.get('workouttype')
|
||||
reststrokes = favorites_form.cleaned_data.get('reststrokes')
|
||||
notes = favorites_form.cleaned_data.get('notes')
|
||||
new_instances.append(FavoriteChart(user=r,
|
||||
yparam1=yparam1,
|
||||
yparam2=yparam2,
|
||||
xparam=xparam,
|
||||
plottype=plottype,
|
||||
notes=notes,
|
||||
workouttype=workouttype,
|
||||
reststrokes=reststrokes))
|
||||
try:
|
||||
with transaction.atomic():
|
||||
FavoriteChart.objects.filter(user=r).delete()
|
||||
FavoriteChart.objects.bulk_create(new_instances)
|
||||
successmessage = "You have updated your favorites"
|
||||
messages.info(request,message)
|
||||
if len(new_instances)==0:
|
||||
FavoriteChartFormSet=formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1)
|
||||
favorites_formset = FavoriteChartFormSet()
|
||||
except IntegrityError:
|
||||
message = "something went wrong"
|
||||
messages.error(request,message)
|
||||
else:
|
||||
favorites_formset = FavoriteChartFormSet(initial=favorites_data)
|
||||
|
||||
|
||||
context = {
|
||||
'favorites_formset':favorites_formset,
|
||||
'teams':get_my_teams(request.user),
|
||||
'rower':r,
|
||||
}
|
||||
|
||||
|
||||
|
||||
return render(request,'favoritecharts.html',context)
|
||||
|
||||
# page where user sets his export settings
|
||||
@login_required()
|
||||
def rower_exportsettings_view(request,userid=0):
|
||||
r = getrequestrower(request,userid=userid)
|
||||
if request.method == 'POST':
|
||||
form = RowerExportForm(request.POST)
|
||||
if form.is_valid():
|
||||
cd = form.cleaned_data
|
||||
|
||||
for attr, value in cd.items():
|
||||
setattr(r, attr, value)
|
||||
|
||||
r.save()
|
||||
messages.info(request,'Settings saved')
|
||||
else:
|
||||
form = RowerExportForm(instance=r)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/me/edit/',
|
||||
'name': 'Profile'
|
||||
},
|
||||
{
|
||||
'url': reverse(rower_exportsettings_view),
|
||||
'name': 'Export Settings'
|
||||
}
|
||||
]
|
||||
|
||||
return render(request, 'rower_exportsettings.html',
|
||||
{'form':form,
|
||||
'rower':r,
|
||||
'breadcrumbs': breadcrumbs,
|
||||
})
|
||||
|
||||
|
||||
# Page where user can set his details
|
||||
# Add email address to form so user can change his email address
|
||||
@login_required()
|
||||
def rower_edit_view(request,rowerid=0,userid=0,message=""):
|
||||
r = getrequestrower(request,rowerid=rowerid,userid=userid,notpermanent=True)
|
||||
|
||||
rowerid = r.id
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/me/edit/',
|
||||
'name': 'Profile'
|
||||
},
|
||||
{
|
||||
'url': reverse(rower_edit_view),
|
||||
'name': 'Account Settings'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
accountform = AccountRowerForm(request.POST)
|
||||
userform = UserForm(request.POST,instance=r.user)
|
||||
|
||||
if accountform.is_valid() and userform.is_valid():
|
||||
# process
|
||||
cd = accountform.cleaned_data
|
||||
ucd = userform.cleaned_data
|
||||
|
||||
first_name = ucd['first_name']
|
||||
last_name = ucd['last_name']
|
||||
email = ucd['email']
|
||||
sex = cd['sex']
|
||||
adaptiveclass = cd['adaptiveclass']
|
||||
defaultlandingpage = cd['defaultlandingpage']
|
||||
weightcategory = cd['weightcategory']
|
||||
birthdate = cd['birthdate']
|
||||
showfavoritechartnotes = cd['showfavoritechartnotes']
|
||||
getemailnotifications = cd['getemailnotifications']
|
||||
getimportantemails = cd['getimportantemails']
|
||||
defaulttimezone=cd['defaulttimezone']
|
||||
u = r.user
|
||||
if u.email != email and len(email):
|
||||
resetbounce = True
|
||||
else:
|
||||
resetbounce = False
|
||||
if len(first_name):
|
||||
u.first_name = first_name
|
||||
u.last_name = last_name
|
||||
if len(email): ## and check_email_freeforuse(u,email):
|
||||
u.email = email
|
||||
resetbounce = True
|
||||
|
||||
|
||||
u.save()
|
||||
r.defaulttimezone=defaulttimezone
|
||||
r.weightcategory = weightcategory
|
||||
r.adaptiveclass = adaptiveclass
|
||||
r.getemailnotifications = getemailnotifications
|
||||
r.getimportantemails = getimportantemails
|
||||
r.defaultlandingpage = defaultlandingpage
|
||||
r.showfavoritechartnotes = showfavoritechartnotes
|
||||
r.sex = sex
|
||||
r.birthdate = birthdate
|
||||
|
||||
if resetbounce and r.emailbounced:
|
||||
r.emailbounced = False
|
||||
r.save()
|
||||
|
||||
accountform = AccountRowerForm(instance=r)
|
||||
userform = UserForm(instance=u)
|
||||
successmessage = 'Account Information changed'
|
||||
messages.info(request,successmessage)
|
||||
else:
|
||||
accountform = AccountRowerForm(instance=r)
|
||||
userform = UserForm(instance=r.user)
|
||||
|
||||
|
||||
grants = AccessToken.objects.filter(user=request.user)
|
||||
return render(request, 'rower_form.html',
|
||||
{
|
||||
'teams':get_my_teams(request.user),
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'grants':grants,
|
||||
'userform':userform,
|
||||
'accountform':accountform,
|
||||
'rower':r,
|
||||
})
|
||||
|
||||
|
||||
# Page where user can set his details
|
||||
# Add email address to form so user can change his email address
|
||||
@login_required()
|
||||
def rower_prefs_view(request,userid=0,message=""):
|
||||
r = getrequestrower(request,userid=userid,notpermanent=True)
|
||||
|
||||
rowerid = r.id
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/me/edit/',
|
||||
'name': 'Profile'
|
||||
},
|
||||
{
|
||||
'url': reverse(rower_prefs_view),
|
||||
'name': 'Zones'
|
||||
}
|
||||
]
|
||||
|
||||
form = RowerForm(instance=r)
|
||||
powerform = RowerPowerForm(instance=r)
|
||||
powerzonesform = RowerPowerZonesForm(instance=r)
|
||||
|
||||
if request.method == 'POST' and "ut2" in request.POST:
|
||||
form = RowerForm(request.POST)
|
||||
if form.is_valid():
|
||||
# something
|
||||
cd = form.cleaned_data
|
||||
hrmax = cd['max']
|
||||
ut2 = cd['ut2']
|
||||
ut1 = cd['ut1']
|
||||
at = cd['at']
|
||||
tr = cd['tr']
|
||||
an = cd['an']
|
||||
rest = cd['rest']
|
||||
|
||||
r.max = max(min(hrmax,250),10)
|
||||
r.ut2 = max(min(ut2,250),10)
|
||||
r.ut1 = max(min(ut1,250),10)
|
||||
r.at = max(min(at,250),10)
|
||||
r.tr = max(min(tr,250),10)
|
||||
r.an = max(min(an,250),10)
|
||||
r.rest = max(min(rest,250),10)
|
||||
r.save()
|
||||
successmessage = "Your Heart Rate data were changed"
|
||||
messages.info(request,successmessage)
|
||||
elif request.method == 'POST' and "ftp" in request.POST:
|
||||
powerform = RowerPowerForm(request.POST)
|
||||
if powerform.is_valid():
|
||||
cd = powerform.cleaned_data
|
||||
hrftp = cd['hrftp']
|
||||
if hrftp == 0:
|
||||
hrftp = int((r.an+r.tr)/2.)
|
||||
ftp = cd['ftp']
|
||||
otwslack = cd['otwslack']
|
||||
|
||||
powerfrac = 100*np.array([r.pw_ut2,
|
||||
r.pw_ut1,
|
||||
r.pw_at,
|
||||
r.pw_tr,r.pw_an])/r.ftp
|
||||
r.ftp = max(min(ftp,650),50)
|
||||
r.otwslack = max(min(otwslack,50),0)
|
||||
ut2,ut1,at,tr,an = (r.ftp*powerfrac/100.).astype(int)
|
||||
r.pw_ut2 = ut2
|
||||
r.pw_ut1 = ut1
|
||||
r.pw_at = at
|
||||
r.pw_tr = tr
|
||||
r.pw_an = an
|
||||
r.hrftp = hrftp
|
||||
r.save()
|
||||
message = "FTP and/or OTW slack values changed."
|
||||
messages.info(request,message)
|
||||
|
||||
elif request.method == 'POST' and "ut3name" in request.POST:
|
||||
powerzonesform = RowerPowerZonesForm(request.POST)
|
||||
if powerzonesform.is_valid():
|
||||
cd = powerzonesform.cleaned_data
|
||||
pw_ut2 = cd['pw_ut2']
|
||||
pw_ut1 = cd['pw_ut1']
|
||||
pw_at = cd['pw_at']
|
||||
pw_tr = cd['pw_tr']
|
||||
pw_an = cd['pw_an']
|
||||
ut3name = cd['ut3name']
|
||||
ut2name = cd['ut2name']
|
||||
ut1name = cd['ut1name']
|
||||
atname = cd['atname']
|
||||
trname = cd['trname']
|
||||
anname = cd['anname']
|
||||
powerzones = [ut3name,ut2name,ut1name,atname,trname,anname]
|
||||
|
||||
r.pw_ut2 = pw_ut2
|
||||
r.pw_ut1 = pw_ut1
|
||||
r.pw_at = pw_at
|
||||
r.pw_tr = pw_tr
|
||||
r.pw_an = pw_an
|
||||
r.powerzones = powerzones
|
||||
r.save()
|
||||
successmessage = "Your Power Zone data were changed"
|
||||
messages.info(request,successmessage)
|
||||
|
||||
return render(request, 'rower_preferences.html',
|
||||
{
|
||||
'form':form,
|
||||
'teams':get_my_teams(request.user),
|
||||
'powerform':powerform,
|
||||
'powerzonesform':powerzonesform,
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'rower':r,
|
||||
})
|
||||
|
||||
|
||||
# Revoke an app that you granted access through the API.
|
||||
# this views is called when you press a button on the User edit page
|
||||
# the button is only there when you have granted access to an app
|
||||
@login_required()
|
||||
def rower_revokeapp_view(request,id=0):
|
||||
try:
|
||||
tokens = AccessToken.objects.filter(user=request.user,application=id)
|
||||
refreshtokens = AccessToken.objects.filter(user=request.user,application=id)
|
||||
for token in tokens:
|
||||
token.revoke()
|
||||
for token in refreshtokens:
|
||||
token.revoke()
|
||||
|
||||
r = getrower(request.user)
|
||||
form = RowerForm(instance=r)
|
||||
powerform = RowerPowerForm(instance=r)
|
||||
grants = AccessToken.objects.filter(user=request.user)
|
||||
url = reverse(rower_edit_view)
|
||||
return HttpResponseRedirect(url)
|
||||
except AccessToken.DoesNotExist:
|
||||
raise Http404("Access token doesn't exist")
|
||||
|
||||
|
||||
@login_required()
|
||||
def rower_update_empower_view(
|
||||
request,
|
||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||
enddate=timezone.now()
|
||||
):
|
||||
try:
|
||||
r = getrower(request.user)
|
||||
except Rower.DoesNotExist:
|
||||
raise Http404("Rower doesn't exist")
|
||||
|
||||
if request.method == 'POST' and 'daterange' in request.POST:
|
||||
dateform = DateRangeForm(request.POST)
|
||||
if dateform.is_valid():
|
||||
startdate = dateform.cleaned_data['startdate']
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||
request.session['startdate'] = startdatestring
|
||||
request.session['enddate'] = enddatestring
|
||||
else:
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate':startdate,
|
||||
'enddate':enddate,
|
||||
})
|
||||
|
||||
|
||||
if request.method == 'POST' and 'workouts' in request.POST:
|
||||
form = WorkoutMultipleCompareForm(request.POST)
|
||||
if form.is_valid():
|
||||
cd = form.cleaned_data
|
||||
workouts = cd['workouts']
|
||||
workoutdicts = []
|
||||
|
||||
for w in workouts:
|
||||
if w.user != r:
|
||||
message = "You can only alter your own workouts"
|
||||
messages.error(request,message)
|
||||
if 'x' in w.boattype and w.oarlength is not None and w.oarlength > 3.30:
|
||||
message = "Oarlength and boat type mismatch for workout "+str(w.id)+". Skipping workout"
|
||||
messages.error(request,message)
|
||||
elif 'x' not in w.boattype and w.oarlength is not None and w.oarlength <= 3.30:
|
||||
message = "Oarlength and boat type mismatch for workout "+str(w.id)+". Skipping workout"
|
||||
messages.error(request,message)
|
||||
elif w.oarlength is None:
|
||||
message = "Incorrect oarlength in workout "+str(w.id)+". Skipping workout"
|
||||
messages.error(request,message)
|
||||
else:
|
||||
|
||||
|
||||
workoutdict = {
|
||||
'id':w.id,
|
||||
'boattype':w.boattype,
|
||||
'filename':w.csvfilename,
|
||||
'inboard':w.inboard,
|
||||
'oarlength':w.oarlength
|
||||
}
|
||||
|
||||
workoutdicts.append(workoutdict)
|
||||
|
||||
w.workoutsource = 'speedcoach2corrected'
|
||||
w.save()
|
||||
|
||||
|
||||
job = myqueue(queuelow,handle_update_empower,
|
||||
request.user.email,workoutdicts,
|
||||
debug=False,
|
||||
emailbounced=r.emailbounced)
|
||||
|
||||
try:
|
||||
request.session['async_tasks'] += [(job.id,'update_empower')]
|
||||
except KeyError:
|
||||
request.session['async_tasks'] = [(job.id,'update_empower')]
|
||||
|
||||
successmessage = 'Your workouts are being updated in the background. You will receive email when this is done. You can check the status of your calculations <a href="/rowers/jobs-status" target="_blank">here</a>'
|
||||
|
||||
messages.info(request,successmessage)
|
||||
|
||||
url = reverse(workouts_view)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
|
||||
workouts = Workout.objects.filter(
|
||||
startdatetime__gte=startdate,
|
||||
startdatetime__lte=enddate,
|
||||
workoutsource='speedcoach2',
|
||||
user=r,
|
||||
).order_by("-date","-starttime")
|
||||
|
||||
form = WorkoutMultipleCompareForm()
|
||||
form.fields["workouts"].queryset = workouts
|
||||
# GET request = prepare form
|
||||
|
||||
return render(request, 'empower_fix.html',
|
||||
{'workouts':workouts,
|
||||
'active': 'nav-workouts',
|
||||
'dateform':dateform,
|
||||
'form':form,
|
||||
'rower':r
|
||||
})
|
||||
|
||||
|
||||
5202
rowers/views/workoutviews.py
Normal file
5202
rowers/views/workoutviews.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1757,35 +1757,35 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
|
||||
|
||||
unixtime = cum_time+starttimeunix
|
||||
# unixtime[0] = starttimeunix
|
||||
seconds = 0.1*strokedata.ix[:,'t']
|
||||
seconds = 0.1*strokedata.loc[:,'t']
|
||||
|
||||
nr_rows = len(unixtime)
|
||||
|
||||
try:
|
||||
latcoord = strokedata.ix[:,'lat']
|
||||
loncoord = strokedata.ix[:,'lon']
|
||||
latcoord = strokedata.loc[:,'lat']
|
||||
loncoord = strokedata.loc[:,'lon']
|
||||
except:
|
||||
latcoord = np.zeros(nr_rows)
|
||||
loncoord = np.zeros(nr_rows)
|
||||
|
||||
|
||||
try:
|
||||
strokelength = strokedata.ix[:,'strokelength']
|
||||
strokelength = strokedata.loc[:,'strokelength']
|
||||
except:
|
||||
strokelength = np.zeros(nr_rows)
|
||||
|
||||
dist2 = 0.1*strokedata.ix[:,'d']
|
||||
dist2 = 0.1*strokedata.loc[:,'d']
|
||||
|
||||
try:
|
||||
spm = strokedata.ix[:,'spm']
|
||||
spm = strokedata.loc[:,'spm']
|
||||
except KeyError:
|
||||
spm = 0*dist2
|
||||
|
||||
try:
|
||||
hr = strokedata.ix[:,'hr']
|
||||
hr = strokedata.loc[:,'hr']
|
||||
except KeyError:
|
||||
hr = 0*spm
|
||||
pace = strokedata.ix[:,'p']/10.
|
||||
pace = strokedata.loc[:,'p']/10.
|
||||
pace = np.clip(pace,0,1e4)
|
||||
pace = pace.replace(0,300)
|
||||
|
||||
@@ -7967,7 +7967,7 @@ def workout_downloadwind_view(request,id=0,
|
||||
return HttpResponse("Error: CSV Data File Not Found")
|
||||
|
||||
try:
|
||||
bearing = rowdata.df.ix[:,'bearing'].values
|
||||
bearing = rowdata.df.loc[:,'bearing'].values
|
||||
except KeyError:
|
||||
rowdata.add_bearing()
|
||||
rowdata.write_csv(f1,gzip=True)
|
||||
@@ -7976,7 +7976,7 @@ def workout_downloadwind_view(request,id=0,
|
||||
try:
|
||||
avglat = rowdata.df[' latitude'].mean()
|
||||
avglon = rowdata.df[' longitude'].mean()
|
||||
avgtime = int(rowdata.df['TimeStamp (sec)'].mean()-rowdata.df.ix[0,'TimeStamp (sec)'])
|
||||
avgtime = int(rowdata.df['TimeStamp (sec)'].mean()-rowdata.df.loc[:,'TimeStamp (sec)'].iloc[0])
|
||||
startdatetime = dateutil.parser.parse("{}, {}".format(row.date,
|
||||
row.starttime))
|
||||
|
||||
@@ -8033,7 +8033,7 @@ def workout_downloadmetar_view(request,id=0,
|
||||
return HttpResponse("Error: CSV Data File Not Found")
|
||||
|
||||
try:
|
||||
bearing = rowdata.df.ix[:,'bearing'].values
|
||||
bearing = rowdata.df.loc[:,'bearing'].values
|
||||
except KeyError:
|
||||
rowdata.add_bearing()
|
||||
rowdata.write_csv(f1,gzip=True)
|
||||
@@ -8043,7 +8043,7 @@ def workout_downloadmetar_view(request,id=0,
|
||||
avglat = rowdata.df[' latitude'].mean()
|
||||
avglon = rowdata.df[' longitude'].mean()
|
||||
airportcode = get_airport_code(avglat,avglon)[0]
|
||||
avgtime = int(rowdata.df['TimeStamp (sec)'].mean()-rowdata.df.ix[0,'TimeStamp (sec)'])
|
||||
avgtime = int(rowdata.df['TimeStamp (sec)'].mean()-rowdata.df.loc[:,'TimeStamp (sec)'].iloc[0])
|
||||
startdatetime = dateutil.parser.parse("{}, {}".format(row.date,
|
||||
row.starttime))
|
||||
|
||||
@@ -8121,7 +8121,7 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
|
||||
|
||||
hascoordinates = 1
|
||||
try:
|
||||
latitude = rowdata.df.ix[:,' latitude']
|
||||
latitude = rowdata.df.loc[:,' latitude']
|
||||
except KeyError:
|
||||
hascoordinates = 0
|
||||
|
||||
@@ -8129,7 +8129,7 @@ def workout_wind_view(request,id=0,message="",successmessage=""):
|
||||
hascoordinates = 0
|
||||
|
||||
try:
|
||||
bearing = rowdata.df.ix[:,'bearing'].values
|
||||
bearing = rowdata.df.loc[:,'bearing'].values
|
||||
except KeyError:
|
||||
rowdata.add_bearing()
|
||||
rowdata.write_csv(f1,gzip=True)
|
||||
@@ -8811,7 +8811,7 @@ def cumstats(request,theuser=0,
|
||||
thedict = {}
|
||||
for field2,verbosename in fielddict.iteritems():
|
||||
try:
|
||||
thedict[field2] = cor.ix[field1,field2]
|
||||
thedict[field2] = cor.loc[field1,field2]
|
||||
except KeyError:
|
||||
thedict[field2] = 0
|
||||
|
||||
@@ -9030,7 +9030,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||
thedict = {}
|
||||
for field2,verbosename in fielddict.iteritems():
|
||||
try:
|
||||
thedict[field2] = cor.ix[field1,field2]
|
||||
thedict[field2] = cor.loc[field1,field2]
|
||||
except KeyError:
|
||||
thedict[field2] = 0
|
||||
|
||||
@@ -14167,6 +14167,7 @@ def plannedsession_create_view(request,
|
||||
enddatestring=enddatestring)
|
||||
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
sessioncreateform = PlannedSessionForm(request.POST)
|
||||
if sessioncreateform.is_valid():
|
||||
@@ -14439,7 +14440,8 @@ def plannedsession_teamcreate_view(request,
|
||||
sessioncreateform = PlannedSessionForm(request.POST)
|
||||
sessionteamselectform = PlannedSessionTeamForm(
|
||||
request.user,request.POST
|
||||
)
|
||||
)
|
||||
|
||||
if sessioncreateform.is_valid() and sessionteamselectform.is_valid():
|
||||
cd = sessioncreateform.cleaned_data
|
||||
startdate = cd['startdate']
|
||||
@@ -18412,12 +18414,7 @@ class TrainingTargetUpdate(UpdateView):
|
||||
|
||||
return obj
|
||||
|
||||
def allsundays(startdate,enddate):
|
||||
d = startdate
|
||||
d += timedelta(days = 6 - d.weekday()) # first Sunday
|
||||
while d<=enddate:
|
||||
yield d
|
||||
d += timedelta(days=7)
|
||||
from rowers.utils import allsundays
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
||||
message="This functionality requires a Coach or Self-Coach plan",
|
||||
@@ -18472,12 +18469,7 @@ def planmesocyclebyweek(request,id=0,userid=0):
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
def allmonths(startdate,enddate):
|
||||
d = startdate
|
||||
while d<enddate:
|
||||
yield d
|
||||
d = datetime.date(d.year+(d.month / 12),((d.month % 12) + 1),1)
|
||||
from rowers.utils import allmonths
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
||||
message="This functionality requires a Coach or Self-Coach plan",
|
||||
Reference in New Issue
Block a user