diff --git a/2a1bfe9f-acd8-4fbc-9b75-8caf203e4fcf.gpx b/2a1bfe9f-acd8-4fbc-9b75-8caf203e4fcf.gpx
new file mode 100644
index 00000000..462f2508
--- /dev/null
+++ b/2a1bfe9f-acd8-4fbc-9b75-8caf203e4fcf.gpx
@@ -0,0 +1,574 @@
+Garmin International 2016-05-20T15:41:26 Export by rowingdata
+ 2016-05-20T13:41:26+00:00
+
+
+ 2016-05-20T13:41:29.238150+00:00
+
+
+ 2016-05-20T13:41:32.148290+00:00
+
+
+ 2016-05-20T13:41:35.269000+00:00
+
+
+ 2016-05-20T13:41:38.152180+00:00
+
+
+ 2016-05-20T13:41:41.148270+00:00
+
+
+ 2016-05-20T13:41:44.148910+00:00
+
+
+ 2016-05-20T13:41:46.908250+00:00
+
+
+ 2016-05-20T13:41:49.819010+00:00
+
+
+ 2016-05-20T13:41:52.942510+00:00
+
+
+ 2016-05-20T13:41:55.639670+00:00
+
+
+ 2016-05-20T13:41:58.370000+00:00
+
+
+ 2016-05-20T13:42:01.188270+00:00
+
+
+ 2016-05-20T13:42:04.008300+00:00
+
+
+ 2016-05-20T13:42:06.888990+00:00
+
+
+ 2016-05-20T13:42:09.678900+00:00
+
+
+ 2016-05-20T13:42:12.469140+00:00
+
+
+ 2016-05-20T13:42:15.199010+00:00
+
+
+ 2016-05-20T13:42:17.963080+00:00
+
+
+ 2016-05-20T13:42:20.658340+00:00
+
+
+ 2016-05-20T13:42:23.538800+00:00
+
+
+ 2016-05-20T13:42:26.269790+00:00
+
+
+ 2016-05-20T13:42:28.848350+00:00
+
+
+ 2016-05-20T13:42:31.729550+00:00
+
+
+ 2016-05-20T13:42:34.398400+00:00
+
+
+ 2016-05-20T13:42:37.038360+00:00
+
+
+ 2016-05-20T13:42:39.499250+00:00
+
+
+ 2016-05-20T13:42:42.349070+00:00
+
+
+ 2016-05-20T13:42:45.079070+00:00
+
+
+ 2016-05-20T13:42:47.752890+00:00
+
+
+ 2016-05-20T13:42:50.452350+00:00
+
+
+ 2016-05-20T13:42:53.182630+00:00
+
+
+ 2016-05-20T13:42:55.789410+00:00
+
+
+ 2016-05-20T13:42:58.671890+00:00
+
+
+ 2016-05-20T13:43:01.338860+00:00
+
+
+ 2016-05-20T13:43:04.068490+00:00
+
+
+ 2016-05-20T13:43:06.862620+00:00
+
+
+ 2016-05-20T13:43:09.618500+00:00
+
+
+ 2016-05-20T13:43:12.379160+00:00
+
+
+ 2016-05-20T13:43:15.229200+00:00
+
+
+ 2016-05-20T13:43:17.963150+00:00
+
+
+ 2016-05-20T13:43:20.692490+00:00
+
+
+ 2016-05-20T13:43:23.628520+00:00
+
+
+ 2016-05-20T13:43:26.329210+00:00
+
+
+ 2016-05-20T13:43:29.148960+00:00
+
+
+ 2016-05-20T13:43:31.668570+00:00
+
+
+ 2016-05-20T13:43:34.490920+00:00
+
+
+ 2016-05-20T13:43:37.369250+00:00
+
+
+ 2016-05-20T13:43:40.189230+00:00
+
+
+ 2016-05-20T13:43:42.798860+00:00
+
+
+ 2016-05-20T13:43:45.708750+00:00
+
+
+ 2016-05-20T13:43:48.318590+00:00
+
+
+ 2016-05-20T13:43:51.199500+00:00
+
+
+ 2016-05-20T13:43:53.869290+00:00
+
+
+ 2016-05-20T13:43:56.572490+00:00
+
+
+ 2016-05-20T13:43:59.212410+00:00
+
+
+ 2016-05-20T13:44:01.912890+00:00
+
+
+ 2016-05-20T13:44:04.459350+00:00
+
+
+ 2016-05-20T13:44:07.249360+00:00
+
+
+ 2016-05-20T13:44:09.949930+00:00
+
+
+ 2016-05-20T13:44:12.619870+00:00
+
+
+ 2016-05-20T13:44:15.378800+00:00
+
+
+ 2016-05-20T13:44:18.049420+00:00
+
+
+ 2016-05-20T13:44:20.719440+00:00
+
+
+ 2016-05-20T13:44:23.298970+00:00
+
+
+ 2016-05-20T13:44:26.178820+00:00
+
+
+ 2016-05-20T13:44:28.669980+00:00
+
+
+ 2016-05-20T13:44:31.429270+00:00
+
+
+ 2016-05-20T13:44:34.042790+00:00
+
+
+ 2016-05-20T13:44:36.589070+00:00
+
+
+ 2016-05-20T13:44:39.412800+00:00
+
+
+ 2016-05-20T13:44:42.078870+00:00
+
+
+ 2016-05-20T13:44:44.783760+00:00
+
+
+ 2016-05-20T13:44:47.450710+00:00
+
+
+ 2016-05-20T13:44:50.149400+00:00
+
+
+ 2016-05-20T13:44:52.789720+00:00
+
+
+ 2016-05-20T13:44:55.429750+00:00
+
+
+ 2016-05-20T13:44:58.069700+00:00
+
+
+ 2016-05-20T13:45:00.742790+00:00
+
+
+ 2016-05-20T13:45:03.442700+00:00
+
+
+ 2016-05-20T13:45:06.139610+00:00
+
+
+ 2016-05-20T13:45:08.689490+00:00
+
+
+ 2016-05-20T13:45:11.479530+00:00
+
+
+ 2016-05-20T13:45:14.119610+00:00
+
+
+ 2016-05-20T13:45:16.792860+00:00
+
+
+ 2016-05-20T13:45:19.368950+00:00
+
+
+ 2016-05-20T13:45:22.158960+00:00
+
+
+ 2016-05-20T13:45:24.889580+00:00
+
+
+ 2016-05-20T13:45:27.558940+00:00
+
+
+ 2016-05-20T13:45:30.469760+00:00
+
+
+ 2016-05-20T13:45:33.259860+00:00
+
+
+ 2016-05-20T13:45:36.079590+00:00
+
+
+ 2016-05-20T13:45:38.899560+00:00
+
+
+ 2016-05-20T13:45:41.689980+00:00
+
+
+ 2016-05-20T13:45:44.568940+00:00
+
+
+ 2016-05-20T13:45:47.329670+00:00
+
+
+ 2016-05-20T13:45:50.149560+00:00
+
+
+ 2016-05-20T13:45:52.969660+00:00
+
+
+ 2016-05-20T13:45:55.879910+00:00
+
+
+ 2016-05-20T13:45:58.789690+00:00
+
+
+ 2016-05-20T13:46:01.729660+00:00
+
+
+ 2016-05-20T13:46:04.669610+00:00
+
+
+ 2016-05-20T13:46:07.549730+00:00
+
+
+ 2016-05-20T13:46:10.458930+00:00
+
+
+ 2016-05-20T13:46:13.488980+00:00
+
+
+ 2016-05-20T13:46:16.429320+00:00
+
+
+ 2016-05-20T13:46:19.519650+00:00
+
+
+ 2016-05-20T13:46:22.459630+00:00
+
+
+ 2016-05-20T13:46:25.338880+00:00
+
+
+ 2016-05-20T13:46:28.459530+00:00
+
+
+ 2016-05-20T13:46:31.401590+00:00
+
+
+ 2016-05-20T13:46:34.339560+00:00
+
+
+ 2016-05-20T13:46:37.309450+00:00
+
+
+ 2016-05-20T13:46:40.098920+00:00
+
+
+ 2016-05-20T13:46:43.039950+00:00
+
+
+ 2016-05-20T13:46:46.039490+00:00
+
+
+ 2016-05-20T13:46:48.979630+00:00
+
+
+ 2016-05-20T13:46:51.949590+00:00
+
+
+ 2016-05-20T13:46:54.709590+00:00
+
+
+ 2016-05-20T13:46:57.589710+00:00
+
+
+ 2016-05-20T13:47:00.503120+00:00
+
+
+ 2016-05-20T13:47:03.408950+00:00
+
+
+ 2016-05-20T13:47:06.323410+00:00
+
+
+ 2016-05-20T13:47:09.229670+00:00
+
+
+ 2016-05-20T13:47:12.198960+00:00
+
+
+ 2016-05-20T13:47:15.079930+00:00
+
+
+ 2016-05-20T13:47:17.989660+00:00
+
+
+ 2016-05-20T13:47:20.959680+00:00
+
+
+ 2016-05-20T13:47:23.869730+00:00
+
+
+ 2016-05-20T13:47:26.782970+00:00
+
+
+ 2016-05-20T13:47:29.688910+00:00
+
+
+ 2016-05-20T13:47:32.539570+00:00
+
+
+ 2016-05-20T13:47:35.449720+00:00
+
+
+ 2016-05-20T13:47:38.329080+00:00
+
+
+ 2016-05-20T13:47:41.148960+00:00
+
+
+ 2016-05-20T13:47:44.088880+00:00
+
+
+ 2016-05-20T13:47:47.150600+00:00
+
+
+ 2016-05-20T13:47:50.029750+00:00
+
+
+ 2016-05-20T13:47:52.998850+00:00
+
+
+ 2016-05-20T13:47:55.880360+00:00
+
+
+ 2016-05-20T13:47:58.789400+00:00
+
+
+ 2016-05-20T13:48:01.639760+00:00
+
+
+ 2016-05-20T13:48:04.492770+00:00
+
+
+ 2016-05-20T13:48:07.429530+00:00
+
+
+ 2016-05-20T13:48:10.373270+00:00
+
+
+ 2016-05-20T13:48:13.309500+00:00
+
+
+ 2016-05-20T13:48:16.279570+00:00
+
+
+ 2016-05-20T13:48:19.160740+00:00
+
+
+ 2016-05-20T13:48:21.948820+00:00
+
+
+ 2016-05-20T13:48:25.039520+00:00
+
+
+ 2016-05-20T13:48:27.949340+00:00
+
+
+ 2016-05-20T13:48:30.890880+00:00
+
+
+ 2016-05-20T13:48:33.648790+00:00
+
+
+ 2016-05-20T13:48:36.770050+00:00
+
+
+ 2016-05-20T13:48:39.499600+00:00
+
+
+ 2016-05-20T13:48:42.559140+00:00
+
+
+ 2016-05-20T13:48:45.439020+00:00
+
+
+ 2016-05-20T13:48:48.439810+00:00
+
+
+ 2016-05-20T13:48:51.379570+00:00
+
+
+ 2016-05-20T13:48:54.259600+00:00
+
+
+ 2016-05-20T13:48:57.139300+00:00
+
+
+ 2016-05-20T13:49:00.049550+00:00
+
+
+ 2016-05-20T13:49:02.838790+00:00
+
+
+ 2016-05-20T13:49:05.839540+00:00
+
+
+ 2016-05-20T13:49:08.749400+00:00
+
+
+ 2016-05-20T13:49:11.689540+00:00
+
+
+ 2016-05-20T13:49:14.538900+00:00
+
+
+ 2016-05-20T13:49:17.389440+00:00
+
+
+ 2016-05-20T13:49:20.058880+00:00
+
+
+ 2016-05-20T13:49:23.059530+00:00
+
+
+ 2016-05-20T13:49:25.880610+00:00
+
+
+ 2016-05-20T13:49:28.608730+00:00
+
+
+ 2016-05-20T13:49:31.582600+00:00
+
+
+ 2016-05-20T13:49:34.278700+00:00
+
+
+ 2016-05-20T13:49:37.068660+00:00
+
+
+ 2016-05-20T13:49:40.039460+00:00
+
+
+ 2016-05-20T13:49:42.889790+00:00
+
+
+ 2016-05-20T13:49:45.772580+00:00
+
+
+ 2016-05-20T13:49:48.708690+00:00
+
+
+ 2016-05-20T13:49:51.679450+00:00
+
+
+ 2016-05-20T13:49:54.499470+00:00
+
+
+ 2016-05-20T13:49:57.409440+00:00
+
+
+ 2016-05-20T13:50:00.439330+00:00
+
+
+ 2016-05-20T13:50:03.408680+00:00
+
+
+ 2016-05-20T13:50:06.378680+00:00
+
+
+ 2016-05-20T13:50:09.168860+00:00
+
+
+ 2016-05-20T13:50:12.229650+00:00
+
+
+ 2016-05-20T13:50:15.138650+00:00
+
+
+ 2016-05-20T13:50:18.049470+00:00
+
+
+ 2016-05-20T13:50:20.959460+00:00
+
+
+ 2016-05-20T13:50:23.242360+00:00
+
+
\ No newline at end of file
diff --git a/rowers/__init__.py b/rowers/__init__.py
index 66cd71ed..03d28f5e 100644
--- a/rowers/__init__.py
+++ b/rowers/__init__.py
@@ -1,3 +1,5 @@
from __future__ import absolute_import
from .tasks import app as celery_app
+
+
diff --git a/rowers/dataprep.py b/rowers/dataprep.py
index 16da3650..fb5de97e 100644
--- a/rowers/dataprep.py
+++ b/rowers/dataprep.py
@@ -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.
diff --git a/rowers/datautils.py b/rowers/datautils.py
index a18bc3dc..4048fd24 100644
--- a/rowers/datautils.py
+++ b/rowers/datautils.py
@@ -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:
diff --git a/rowers/forms.py b/rowers/forms.py
index ffef4328..88ce4888 100644
--- a/rowers/forms.py
+++ b/rowers/forms.py
@@ -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
diff --git a/rowers/models.py b/rowers/models.py
index 76a535bd..e5947fb1 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -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):
diff --git a/rowers/templates/billing.html b/rowers/templates/billing.html
index d6035180..ef442cb3 100644
--- a/rowers/templates/billing.html
+++ b/rowers/templates/billing.html
@@ -22,7 +22,8 @@
as a price per year. You can downgrade or cancel your
plan at any time, through the settings page .
Please refer to our terms and conditions for our
- payments and refunds policy. Accepted payment methods are the payment methods offered
+ payments and refunds policy .
+ Accepted payment methods are the payment methods offered
by
Braintree
through us. If you have any questions about our payments and refunds policy, please contact
diff --git a/rowers/templates/downgradeconfirm.html b/rowers/templates/downgradeconfirm.html
index 1e027c34..4b76a6d9 100644
--- a/rowers/templates/downgradeconfirm.html
+++ b/rowers/templates/downgradeconfirm.html
@@ -72,6 +72,11 @@
+
+ I have taken note of the
+ Refund and Cancellation
+ Policy and agree with the Terms of Service .
+
{% csrf_token %}
Downgrade to the € {{ plan.price|currency }} plan
diff --git a/rowers/templates/legal.html b/rowers/templates/legal.html
index 037e3253..66bc90fa 100644
--- a/rowers/templates/legal.html
+++ b/rowers/templates/legal.html
@@ -3,6 +3,52 @@
{% block title %}Legal{% endblock title %}
{% block main %}
+Welcome to Rowsandall
+
+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:
+
+
+
+
+
+
Terms and Conditions
Credit
@@ -32,7 +78,12 @@
-Acceptable use
+Acceptable use
+
+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.
+
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.
@@ -51,7 +102,7 @@
rowsandall.com may disable your user ID and password in rowsandall.com’s sole discretion without notice or explanation.
-User content
+User content
In these terms and conditions, your user content means material (including without limitation text, images, audio material, video material and audio-visual material) that you submit to this website, for whatever purpose.
@@ -78,7 +129,7 @@
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.
-Limitations of liability
+Limitations of liability
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 @@
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.
+Termination
+
+
+ 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.
+
+
Entire agreement
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.
@@ -145,7 +217,7 @@
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.
-rowsandall.com’s details
+
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)
@@ -156,7 +228,7 @@
{% include "refunds.html" %}
-Privacy Policy
+Privacy Policy
{% include "privacypolicy.html" %}
diff --git a/rowers/templates/paidplans.html b/rowers/templates/paidplans.html
index cd174ccd..0b2f55cb 100644
--- a/rowers/templates/paidplans.html
+++ b/rowers/templates/paidplans.html
@@ -302,7 +302,11 @@
Terms and Conditions, Contact Information
- Our paid plans follow the Terms and Conditions .
+
+ Before purchasing any of our paid plans, you must
+ review and acknowledge our Terms and Conditions ,
+ and Refunds and Returns Policy
+
Payments are made to "Rowsandall s.r.o.", with the following contact information:
Rowsandall s.r.o.
diff --git a/rowers/templates/payment_completed.html b/rowers/templates/payment_completed.html
index dbfc9c9a..653907dc 100644
--- a/rowers/templates/payment_completed.html
+++ b/rowers/templates/payment_completed.html
@@ -24,7 +24,8 @@
as a price per year. You can downgrade or cancel your
plan at any time, through the settings page .
Please refer to our terms and conditions for our
- payments and refunds policy. Accepted payment methods are the payment methods offered
+ payments and refunds policy .
+ Accepted payment methods are the payment methods offered
by
Braintree
through us. If you have any questions about our payments and refunds policy, please contact
diff --git a/rowers/templates/paymentconfirm.html b/rowers/templates/paymentconfirm.html
index 149a1355..1f616834 100644
--- a/rowers/templates/paymentconfirm.html
+++ b/rowers/templates/paymentconfirm.html
@@ -20,7 +20,7 @@
- Payments will be procesed by Braintree (A PayPal service):
+ Payments will be processed by Braintree (A PayPal service):
@@ -93,6 +93,11 @@
+
+ I have taken note of the
+ Refund and Cancellation
+ Policy and agree with the Terms of Service .
+
{% csrf_token %}
Pay € {{ plan.price|currency }}
@@ -101,7 +106,6 @@
{% include 'braintreedropin.html' %}
-
{% endblock %}
{% block sidebar %}
diff --git a/rowers/templates/plannedsession_multicreate.html b/rowers/templates/plannedsession_multicreate.html
index 3c76bda1..2981a7b0 100644
--- a/rowers/templates/plannedsession_multicreate.html
+++ b/rowers/templates/plannedsession_multicreate.html
@@ -73,7 +73,7 @@
Clone multiple sessions
- Submit
+ Submit
diff --git a/rowers/templates/plannedsessions_multiclone_select.html b/rowers/templates/plannedsessions_multiclone_select.html
index 9f86cfa0..cfbddce6 100644
--- a/rowers/templates/plannedsessions_multiclone_select.html
+++ b/rowers/templates/plannedsessions_multiclone_select.html
@@ -114,7 +114,7 @@
{{ dateshiftform.as_table }}
-
+
You can use the date and search forms above to search through all
sessions.
diff --git a/rowers/templates/plannedsessionteamedit.html b/rowers/templates/plannedsessionteamedit.html
index a688d92b..5bec388a 100644
--- a/rowers/templates/plannedsessionteamedit.html
+++ b/rowers/templates/plannedsessionteamedit.html
@@ -67,7 +67,7 @@
Clone
-
+
diff --git a/rowers/templates/privacypolicy.html b/rowers/templates/privacypolicy.html
index 944660ed..d90051f8 100644
--- a/rowers/templates/privacypolicy.html
+++ b/rowers/templates/privacypolicy.html
@@ -116,7 +116,7 @@
posts.
-
Data Deletion
+
Membership Cancellation and Data Deletion
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.
@@ -274,6 +274,7 @@
has suitable GDPR compliant measures in place.
+
Inactive Users - accounts are deleted after 18 months
diff --git a/rowers/templates/refunds.html b/rowers/templates/refunds.html
index faf7140d..ff8cb547 100644
--- a/rowers/templates/refunds.html
+++ b/rowers/templates/refunds.html
@@ -1,5 +1,5 @@
-
Thank you for shopping at Rowsandall.
+
Thank you for shopping at Rowsandall.
Digital products
@@ -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.
-
We do not issue refunds for digital products once the order is
- confirmed and the product is sent.
+
If you are not 100% satisfied with your purchase, you can get a refund or
+ exhchange the product for another one.
+
+
+
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.
+
We recommend contacting us for assistance if you experience any issues receiving
our products.
-
Upgrades and Downgrades
+
Upgrades and Downgrades, Cancellations
-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.
+
+ 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.
+
+
+
+ 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.
+
Contact us
diff --git a/rowers/templates/upgradeconfirm.html b/rowers/templates/upgradeconfirm.html
index 2427117a..ec4221c3 100644
--- a/rowers/templates/upgradeconfirm.html
+++ b/rowers/templates/upgradeconfirm.html
@@ -20,7 +20,7 @@
- Payments will be procesed by Braintree (A PayPal service):
+ Payments will be processed by Braintree (A PayPal service):
@@ -93,6 +93,11 @@
+
+ I have taken note of the
+ Refund and Cancellation
+ Policy and agree with the Terms of Service .
+
{% csrf_token %}
Upgrade to the € {{ plan.price|currency }} plan
diff --git a/rowers/templates/workout_comments.html b/rowers/templates/workout_comments.html
index 1eae9f00..0260a7ea 100644
--- a/rowers/templates/workout_comments.html
+++ b/rowers/templates/workout_comments.html
@@ -61,7 +61,7 @@
{{ form.as_table }}
{% csrf_token %}
-
+
{% for graph in graphs %}
diff --git a/rowers/tests/statements.py b/rowers/tests/statements.py
index a84f22a5..0b9aaf47 100644
--- a/rowers/tests/statements.py
+++ b/rowers/tests/statements.py
@@ -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,
diff --git a/rowers/tests/test_aworkouts.py b/rowers/tests/test_aworkouts.py
new file mode 100644
index 00000000..cd936992
--- /dev/null
+++ b/rowers/tests/test_aworkouts.py
@@ -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)
+
diff --git a/rowers/tests/test_payments.py b/rowers/tests/test_payments.py
index 61a9e5c6..ab67cfb7 100644
--- a/rowers/tests/test_payments.py
+++ b/rowers/tests/test_payments.py
@@ -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)
+
diff --git a/rowers/tests/test_plans.py b/rowers/tests/test_plans.py
index d75f848c..6b818c3d 100644
--- a/rowers/tests/test_plans.py
+++ b/rowers/tests/test_plans.py
@@ -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)
diff --git a/rowers/tests/test_urls.py b/rowers/tests/test_urls.py
index b59f6cd2..f0f2596d 100644
--- a/rowers/tests/test_urls.py
+++ b/rowers/tests/test_urls.py
@@ -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])
diff --git a/rowers/tests/testdata/onwater.csv b/rowers/tests/testdata/onwater.csv
new file mode 100644
index 00000000..1a07204c
--- /dev/null
+++ b/rowers/tests/testdata/onwater.csv
@@ -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
diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz
index 1c59396d..b9981412 100644
Binary files a/rowers/tests/testdata/testdata.csv.gz and b/rowers/tests/testdata/testdata.csv.gz differ
diff --git a/rowers/urls.py b/rowers/urls.py
index 3972e842..63174c62 100644
--- a/rowers/urls.py
+++ b/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\d+)/strokedata/$',views.strokedatajson),
- url(r'^500v/$',views.error500_view),
+ url(r'^api/workouts/(?P\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\d+)/$',views.agegroupcpview),
- url(r'^agegroupcp/(?P\d+)/(?P\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\d+)/$',views.agegroupcpview,name='agegroupcpview'),
+ url(r'^agegroupcp/(?P\d+)/(?P\d+)/$',views.agegroupcpview,name='agegroupcpview'),
url(r'^ajax_agegroup/(?P\d+)/(?P\w+.*)/(?P\w+.*)/(?P\d+)/$',
- views.ajax_agegrouprecords),
- url(r'^updatefitness/(?P\w+.*)/(?P\d+)/$',views.fitness_metric_view),
- url(r'^updatefitness/(?P\w+.*)/$',views.fitness_metric_view),
- url(r'^updatefitness/$',views.fitness_metric_view),
+ views.ajax_agegrouprecords,name='ajax_agegrouprecords'),
+ url(r'^updatefitness/(?P\w+.*)/(?P\d+)/$',views.fitness_metric_view,name='fitness_metric_view'),
+ url(r'^updatefitness/(?P\w+.*)/$',views.fitness_metric_view,name='fitness_metric_view'),
+ url(r'^updatefitness/$',views.fitness_metric_view,name='fitness_metric_view'),
url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)m/$',
- views.agegrouprecordview),
+ views.agegrouprecordview,name='agegrouprecordview'),
url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)min/$',
- views.agegrouprecordview),
+ views.agegrouprecordview,name='agegrouprecordview'),
url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/$',
- views.agegrouprecordview),
- url(r'^list-workouts/ranking/$',views.workouts_view,{'rankingonly':True}),
- url(r'^list-workouts/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.workouts_view),
- url(r'^list-workouts/team/(?P\d+)/$',views.workouts_view),
- url(r'^(?P\d+)/list-workouts/$',views.workouts_view),
- url(r'^(?P\d+)/list-workouts/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.workouts_view),
- url(r'^list-workouts/user/(?P\d+)/$',views.workouts_view),
- url(r'^list-workouts/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.workouts_view),
- url(r'^list-workouts/(?P\d+-\d+-\d+)/(?P\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\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.workouts_view,
+ name='workouts_view'),
+ url(r'^list-workouts/team/(?P\d+)/$',views.workouts_view,
+ name='workouts_view'),
+ url(r'^(?P\d+)/list-workouts/$',views.workouts_view,
+ name='workouts_view'),
+ url(r'^(?P\d+)/list-workouts/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.workouts_view,
+ name='workouts_view'),
+ url(r'^list-workouts/user/(?P\d+)/$',views.workouts_view,
+ name='workouts_view'),
+ url(r'^list-workouts/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.workouts_view,
+ name='workouts_view'),
+ url(r'^list-workouts/(?P\d+-\d+-\d+)/(?P\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\d+)/$',
- views.virtualevent_toggle_email_view),
+ views.virtualevent_toggle_email_view,name='virtualevent_toggle_email_view'),
url(r'^indoorraceregistration/togglenotification/(?P\d+)/$',
- views.indoorvirtualevent_toggle_email_view),
- url(r'^virtualevent/(?P\d+)/$',views.virtualevent_view),
- url(r'^virtualevent/(?P\d+)/ranking$',views.virtualevent_ranking_view),
- url(r'^virtualevent/(?P\d+)/edit/$',views.virtualevent_edit_view),
- url(r'^virtualevent/(?P\d+)/editindoor/$',views.indoorvirtualevent_edit_view),
- url(r'^virtualevent/(?P\d+)/register/$',views.virtualevent_register_view),
- url(r'^virtualevent/(?P\d+)/registerindoor/$',views.indoorvirtualevent_register_view),
- url(r'^virtualevent/(?P\d+)/adddiscipline/$',views.virtualevent_addboat_view),
- url(r'^virtualevent/(?P\d+)/withdraw/(?P\d+)/$',views.virtualevent_withdraw_view),
- url(r'^virtualevent/(?P\d+)/withdraw/$',views.virtualevent_withdraw_view),
+ views.indoorvirtualevent_toggle_email_view,name='indoorvirtualevent_toggle_email_view'),
+ url(r'^virtualevent/(?P\d+)/$',views.virtualevent_view,name='virtualevent_view'),
+ url(r'^virtualevent/(?P\d+)/ranking$',views.virtualevent_ranking_view,name='virtualevent_ranking_view'),
+ url(r'^virtualevent/(?P\d+)/edit/$',views.virtualevent_edit_view,name='virtualevent_edit_view'),
+ url(r'^virtualevent/(?P\d+)/editindoor/$',views.indoorvirtualevent_edit_view,name='indoorvirtualevent_edit_view'),
+ url(r'^virtualevent/(?P\d+)/register/$',views.virtualevent_register_view,name='virtualevent_register_view'),
+ url(r'^virtualevent/(?P\d+)/registerindoor/$',views.indoorvirtualevent_register_view,name='indoorvirtualevent_register_view'),
+ url(r'^virtualevent/(?P\d+)/adddiscipline/$',views.virtualevent_addboat_view,name='virtualevent_addboat_view'),
+ url(r'^virtualevent/(?P\d+)/withdraw/(?P\d+)/$',views.virtualevent_withdraw_view,name='virtualevent_withdraw_view'),
+ url(r'^virtualevent/(?P\d+)/withdraw/$',views.virtualevent_withdraw_view,name='virtualevent_withdraw_view'),
url(r'^virtualevent/(?P\d+)/submit/$',
- views.virtualevent_submit_result_view),
+ views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
url(r'^virtualevent/(?P\d+)/submit/(?P\d+)/$',
- views.virtualevent_submit_result_view),
+ views.virtualevent_submit_result_view,name='virtualevent_submit_result_view'),
url(r'^virtualevent/(?P\d+)/disqualify/(?P\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\d+)/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/workout/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/team/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/user/(?P\d+)/$',views.team_comparison_select),
- url(r'^team-compare-select/$',views.team_comparison_select),
- url(r'^workouts-join-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.workouts_join_select),
- url(r'^workouts-join/$',views.workouts_join_view),
- url(r'^workouts-join-select/team/(?P\d+)/$',views.workouts_join_select),
- url(r'^workouts-join-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.workouts_join_select),
- url(r'^workouts-join-select/$',views.workouts_join_select),
- url(r'^user-boxplot-select/user/(?P\d+)/$',views.user_boxplot_select),
- url(r'^user-boxplot-select/$',views.user_boxplot_select),
- url(r'^user-multiflex-select/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.user_multiflex_select),
- url(r'^user-multiflex-select/user/(?P\d+)/$',views.user_multiflex_select),
- url(r'^user-multiflex-select/(?P\d+-\d+-\d+)/(?P\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\d+)/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/team/(?P\d+)/user/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/workout/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/team/(?P\d+)/$',views.team_comparison_select,name='team_comparison_select'),
+ url(r'^team-compare-select/user/(?P\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\d+)/(?P\d+-\d+-\d+)/(?P\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\d+)/$',views.workouts_join_select,name='workouts_join_select'),
+ url(r'^workouts-join-select/(?P\d+-\d+-\d+)/(?P\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\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\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.user_multiflex_select,name='user_multiflex_select'),
+ url(r'^user-multiflex-select/user/(?P\d+)/$',views.user_multiflex_select,name='user_multiflex_select'),
+ url(r'^user-multiflex-select/(?P\d+-\d+-\d+)/(?P\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.*)/$',views.kill_async_job),
url(r'^test-job/(?P\d+)/$',views.test_job_view),
url(r'^test-job2/(?P\d+)/$',views.test_job_view2),
- url(r'^record-progress/(?P\d+)/(?P.*)/$',views.post_progress),
+ url(r'^record-progress/(?P\d+)/(?P.*)/$',views.post_progress,name='post_progress'),
url(r'^record-progress/(?P.*)/$',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\d+)/$',views.fitnessmetric_view),
- url(r'^fitness-progress/user/(?P\d+)/(?P\w+.*)/$',views.fitnessmetric_view),
- url(r'^ote-bests/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view),
- url(r'^ote-bests/user/(?P\d+)/$',views.rankings_view),
- url(r'^ote-bests/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view),
- url(r'^ote-bests/$',views.rankings_view),
- url(r'^(?P\d+)/ote-bests/$',views.rankings_view),
- url(r'^(?P\d+)/ote-bests2/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view2),
- url(r'^ote-bests2/user/(?P\d+)/$',views.rankings_view2),
- url(r'^ote-bests2/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.rankings_view2),
- url(r'^ote-bests2/$',views.rankings_view2),
- url(r'^otw-bests/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.otwrankings_view),
- url(r'^otw-bests/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.otwrankings_view),
- url(r'^otw-bests/user/(?P\d+)/$',views.otwrankings_view),
- url(r'^otw-bests/$',views.otwrankings_view),
- url(r'^ote-ranking/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.oterankings_view),
- url(r'^ote-ranking/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.oterankings_view),
- url(r'^ote-ranking/$',views.oterankings_view),
- url(r'^ote-ranking/user/(?P\d+)/$',views.oterankings_view),
- url(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/user/(?P\d+)/$',views.cum_flex),
- url(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.cum_flex),
- url(r'^flexall/(?P\w+.*)/(?P\w+.*)/(?P\w+.*)/$',views.cum_flex),
- url(r'^flexall/user/(?P\d+)/$',views.cum_flex),
- url(r'^flexall/$',views.cum_flex),
- url(r'^flexalldata/$',views.cum_flex_data),
- url(r'^histo/user/(?P\d+)/$',views.histo),
- url(r'^histodata/$',views.histo_data),
- url(r'^histo/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.histo),
- url(r'^histo/$',views.histo),
- url(r'^cumstats/user/(?P\d+)/$',views.cumstats),
- url(r'^cumstats/(?P\d+-\d+-\d+)/(?P