diff --git a/.gitignore b/.gitignore
index 8b1d4df3..665c5589 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,11 @@
/htmlcov/
.coverage
+# pytest stuff
+/.pytest_cache/
+pytest.ini
+conftest.py
+
# CSV files
/media/
diff --git a/rowers/celery.py b/rowers/celery.py
index 8ecc91a9..77d84ba3 100644
--- a/rowers/celery.py
+++ b/rowers/celery.py
@@ -30,7 +30,7 @@ app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
database_url = 'sqlite:///db.sqlite3'
-@app.task(bind=True)
-def debug_task(self):
- print('Request: {0!r}'.format(self.request))
+#@app.task(bind=True)
+#def debug_task(self):
+# print('Request: {0!r}'.format(self.request))
diff --git a/rowers/forms.py b/rowers/forms.py
index 8599496b..ffef4328 100644
--- a/rowers/forms.py
+++ b/rowers/forms.py
@@ -746,7 +746,8 @@ class PlanSelectForm(forms.Form):
self.fields['plan'].empty_label = None
if paymentprocessor:
self.fields['plan'].queryset = PaidPlan.objects.filter(
- paymentprocessor=paymentprocessor
+ paymentprocessor=paymentprocessor,
+ active=True
).exclude(
shortname="basic"
).order_by(
@@ -758,7 +759,8 @@ class PlanSelectForm(forms.Form):
except AttributeError:
amount = 0
self.fields['plan'].queryset = PaidPlan.objects.filter(
- paymentprocessor=rower.paymentprocessor
+ paymentprocessor=rower.paymentprocessor,
+ active=True
).exclude(
price__lte=amount
).order_by(
diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py
index d1b88a42..2efc1487 100644
--- a/rowers/interactiveplots.py
+++ b/rowers/interactiveplots.py
@@ -673,6 +673,9 @@ def fitnessmetric_chart(fitnessmetrics,user,workoutmode='rower'):
dates = [m.date for m in fitnessmetrics]
mode = [m.workoutmode for m in fitnessmetrics]
+ if len(power4min) == 0:
+ return ['','']
+
df = pd.DataFrame(
{'power4min':power4min,
'power2k':power2k,
diff --git a/rowers/mailprocessing.py b/rowers/mailprocessing.py
index ee8b23a1..95077670 100644
--- a/rowers/mailprocessing.py
+++ b/rowers/mailprocessing.py
@@ -9,8 +9,8 @@ from rowers.tasks import (
)
from django_mailbox.models import Message, MessageAttachment,Mailbox
-workoutmailbox = Mailbox.objects.get(name='workouts')
-failedmailbox = Mailbox.objects.get(name='Failed')
+#workoutmailbox = Mailbox.objects.get(name='workouts')
+#failedmailbox = Mailbox.objects.get(name='Failed')
from rowers.models import User, Rower, RowerForm
diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py
index 36f3553c..23b640b7 100644
--- a/rowers/management/commands/processemail.py
+++ b/rowers/management/commands/processemail.py
@@ -98,7 +98,7 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
imagename=imagename
)
try:
- if workoutid:
+ if workoutid and not testing:
if rower.getemailnotifications and not rower.emailbounced:
email_sent = send_confirm(
rower.user, title, link,
@@ -196,18 +196,23 @@ class Command(BaseCommand):
rowers = []
for rower in rowers:
if extension == 'zip':
- zip_file = zipfile.ZipFile(attachment.document)
- for id,filename in enumerate(zip_file.namelist()):
- datafile = zip_file.extract(filename, path='media/')
- if id>0:
- title = name+' ('+str(id+1)+')'
- else:
- title = name
+ try:
+ zip_file = zipfile.ZipFile(attachment.document)
+ for id,filename in enumerate(zip_file.namelist()):
+ datafile = zip_file.extract(
+ filename, path='media/')
+ if id>0:
+ title = name+' ('+str(id+1)+')'
+ else:
+ title = name
- workoutid = processattachment(
- rower, datafile, title, uploadoptions,
- testing=testing
- )
+ workoutid = processattachment(
+ rower, datafile, title, uploadoptions,
+ testing=testing
+ )
+ except:
+ print "Bad ZIP file"
+ print attachment.document.name
else:
# move attachment and make workout
if testing:
diff --git a/rowers/models.py b/rowers/models.py
index ab8f822f..29322052 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -568,6 +568,8 @@ class PaidPlan(models.Model):
choices=paymenttypes,
)
+ active = models.BooleanField(default=True)
+
clubsize = models.IntegerField(default=0)
def __unicode__(self):
diff --git a/rowers/payments.py b/rowers/payments.py
index bbeb12f4..1e4304fa 100644
--- a/rowers/payments.py
+++ b/rowers/payments.py
@@ -10,30 +10,30 @@ def planstopaypal():
plan.external_id = None
plan.save()
-def initiaterowerplans():
- rowers = Rower.objects.filter(paymenttype = 'recurring',paidplan = None)
- for r in rowers:
- r.paymentprocessor = 'paypal'
- r.save()
+#def initiaterowerplans():
+# rowers = Rower.objects.filter(paymenttype = 'recurring',paidplan = None)
+# for r in rowers:
+# r.paymentprocessor = 'paypal'
+# r.save()
-def setrowerplans():
- rowers = Rower.objects.all()
+#def setrowerplans():
+# rowers = Rower.objects.all()
- for r in rowers:
- paidplans = PaidPlan.objects.filter(
- shortname = r.rowerplan,
- paymenttype = r.paymenttype,
- clubsize = r.clubsize,
- paymentprocessor=r.paymentprocessor)
+# for r in rowers:
+# paidplans = PaidPlan.objects.filter(
+# shortname = r.rowerplan,
+# paymenttype = r.paymenttype,
+# clubsize = r.clubsize,
+# paymentprocessor=r.paymentprocessor)
- if paidplans:
- r.paidplan = paidplans[0]
- r.save()
- else:
- try:
- print 'Could not set plan for ',r.user.username
- except:
- pass
+# if paidplans:
+# r.paidplan = paidplans[0]
+# r.save()
+# else:
+# try:
+# print 'Could not set plan for ',r.user.username
+# except:
+# pass
def is_existing_customer(rower):
if rower.country is not None and rower.customer_id is not None and rower.country != '':
diff --git a/rowers/plots.py b/rowers/plots.py
index b57d263e..948ddd94 100644
--- a/rowers/plots.py
+++ b/rowers/plots.py
@@ -6,10 +6,10 @@ from rows import format_pace_tick, format_pace, format_time, format_time_tick
# Formatting the distance tick marks
-def format_dist_tick(x,pos=None):
- km = x/1000.
- template='%6.3f'
- return template % (km)
+#def format_dist_tick(x,pos=None):
+# km = x/1000.
+# template='%6.3f'
+# return template % (km)
# Utility to select reasonable y axis range
diff --git a/rowers/templates/about_us.html b/rowers/templates/about_us.html
index 1d64d9b4..c178aa32 100644
--- a/rowers/templates/about_us.html
+++ b/rowers/templates/about_us.html
@@ -93,7 +93,7 @@ and inspired by the RowPro Dan Burpee spreadsheet
We offer three plans. Click on the name of the plan to find out more:
- Pro Membership ,
+ Pro Membership ,
offering additional rowing metrics and analysis
tools for individual rowers.
Self-Coach Membership ,
diff --git a/rowers/templates/advancededit.html b/rowers/templates/advancededit.html
index d0d4feaf..5ab7140b 100644
--- a/rowers/templates/advancededit.html
+++ b/rowers/templates/advancededit.html
@@ -16,7 +16,7 @@
{{ workout.name }} - Advanced
{% if user.rower.rowerplan == 'basic' %}
Functionality marked with an asterisk (*) is limited to the paid plans. See
- the page about Pro membership
+ the page about Pro membership
for more information and to sign up for Pro Membership
{% endif %}
@@ -62,7 +62,7 @@
{% if user|is_promember %}
Compare Workouts
{% else %}
- Compare Workouts*
+ Compare Workouts*
{% endif %}
Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts.
@@ -82,7 +82,7 @@
{% if user|is_promember %}
Edit Intervals
{% else %}
- Edit Intervals*
+ Edit Intervals*
{% endif %}
Enter or change the interval and summary data for your workout
@@ -98,7 +98,7 @@
{% if user|is_promember %}
Dist Metrics Plot
{% else %}
- Dist Metrics Plot*
+ Dist Metrics Plot*
{% endif %}
@@ -110,7 +110,7 @@
{% if user|is_promember %}
Time Metrics Plot
{% else %}
- Time Metrics Plot*
+ Time Metrics Plot*
{% endif %}
@@ -122,7 +122,7 @@
{% if user|is_promember %}
Power Histogram
{% else %}
- Power Histogram*
+ Power Histogram*
{% endif %}
@@ -136,7 +136,7 @@
{% if user|is_promember %}
Glue
{% else %}
- Glue*
+ Glue*
{% endif %}
@@ -149,7 +149,7 @@
{% if user|is_promember %}
Sensor Fusion
{% else %}
- Sensor Fusion*
+ Sensor Fusion*
{% endif %}
@@ -161,7 +161,7 @@
{% if user|is_promember %}
Split Workout
{% else %}
- Split Workout*
+ Split Workout*
{% endif %}
diff --git a/rowers/templates/advancedotw.html b/rowers/templates/advancedotw.html
index 4e8c0924..56d5a322 100644
--- a/rowers/templates/advancedotw.html
+++ b/rowers/templates/advancedotw.html
@@ -16,7 +16,7 @@
{{ workout.name }} - Advanced OTW
{% if user.rower.rowerplan == 'basic' %}
Functionality marked with an asterisk (*) is limited to the paid plans. See
- the page about Pro membership
+ the page about Pro membership
for more information and to sign up for Pro Membership
{% endif %}
@@ -60,7 +60,7 @@
{% if user|is_promember %}
Compare Workouts
{% else %}
-
Compare Workouts*
+
Compare Workouts*
{% endif %}
@@ -82,7 +82,7 @@
{% if user|is_promember %}
Edit Intervals
{% else %}
- Edit Intervals*
+ Edit Intervals*
{% endif %}
Enter or change the interval and summary data for your workout
@@ -99,7 +99,7 @@
{% if user|is_promember %}
CrewNerd Summary
{% else %}
-
CrewNerd Summary*
+
CrewNerd Summary*
{% endif %}
@@ -113,7 +113,7 @@
{% if user|is_promember %}
Stroke Profile (Empower)
{% else %}
-
Stroke Profile (Empower)*
+
Stroke Profile (Empower)*
{% endif %}
Analyze your stroke force profile (need Empower Oarlock data)
@@ -126,7 +126,7 @@
{% if user|is_promember %}
OTW Power Plot
{% else %}
- OTW Power Plot*
+ OTW Power Plot*
{% endif %}
Note: You must run the OTW calculations under Geeky Stuff first. Otherwise the plot will be empty
@@ -146,7 +146,7 @@
{% if user|is_promember %}
Geeky Stuff
{% else %}
-
Geeky Stuff*
+
Geeky Stuff*
{% endif %}
@@ -161,7 +161,7 @@
{% if user|is_promember %}
Smooth out Pace Data
{% else %}
-
Smooth out Pace Data*
+
Smooth out Pace Data*
{% endif %}
@@ -178,7 +178,7 @@
{% if user|is_promember %}
Raw Data
{% else %}
-
Reset Smoothing*
+
Reset Smoothing*
{% endif %}
@@ -193,7 +193,7 @@
{% if user|is_promember %}
Glue
{% else %}
- Glue*
+ Glue*
{% endif %}
@@ -205,7 +205,7 @@
{% if user|is_promember %}
Sensor Fusion
{% else %}
- Sensor Fusion*
+ Sensor Fusion*
{% endif %}
@@ -217,7 +217,7 @@
{% if user|is_promember %}
Split Workout
{% else %}
- Split Workout*
+ Split Workout*
{% endif %}
diff --git a/rowers/templates/basebase.html b/rowers/templates/basebase.html
index 41dd1dfb..98f30743 100644
--- a/rowers/templates/basebase.html
+++ b/rowers/templates/basebase.html
@@ -98,7 +98,7 @@
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
Pro Member
{% else %}
-
+
{% endif %}
diff --git a/rowers/templates/billing.html b/rowers/templates/billing.html
index 1d16238a..0aacc77e 100644
--- a/rowers/templates/billing.html
+++ b/rowers/templates/billing.html
@@ -19,7 +19,8 @@
Unless specified otherwise, the payments on the
recurring payment plans are annual. The prices are specified
- as a price per year.
+ as a price per year. You can downgrade or cancel your
+ plan at any time in your settings .
diff --git a/rowers/templates/comparisonchart2.html b/rowers/templates/comparisonchart2.html
index 1fd119fe..93a996b8 100644
--- a/rowers/templates/comparisonchart2.html
+++ b/rowers/templates/comparisonchart2.html
@@ -74,7 +74,7 @@
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
- {{ value }}
+ {{ value }}
{% endfor %}
{% endif %}
@@ -98,7 +98,7 @@
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
- {{ value }} (Pro)
+ {{ value }} (Pro)
{% endif %}
{% endfor %}
{% endif %}
diff --git a/rowers/templates/downgrade.html b/rowers/templates/downgrade.html
index bf2e7bc7..7e5fe130 100644
--- a/rowers/templates/downgrade.html
+++ b/rowers/templates/downgrade.html
@@ -1,3 +1,4 @@
+
{% extends "newbase.html" %}
{% block title %}Rowsandall Paid Membership{% endblock title %}
{% load rowerfilters %}
diff --git a/rowers/templates/downgradeconfirm.html b/rowers/templates/downgradeconfirm.html
index 9bb0aee0..1e027c34 100644
--- a/rowers/templates/downgradeconfirm.html
+++ b/rowers/templates/downgradeconfirm.html
@@ -56,7 +56,7 @@
Change Downgrade
-
-
-
+
{% csrf_token %}
{{ chartform.as_table }}
diff --git a/rowers/templates/paidplans.html b/rowers/templates/paidplans.html
index 4550c0d7..331792e9 100644
--- a/rowers/templates/paidplans.html
+++ b/rowers/templates/paidplans.html
@@ -12,6 +12,11 @@
hosting costs, we have created paid plans offering extended
functionality.
+
+ All plans are valid for a year. Recurring payment plans will automatically
+ bill you at the start of a new 12 month period. You can stop your plan
+ at any time in your settings .
+
diff --git a/rowers/templates/paymentconfirm.html b/rowers/templates/paymentconfirm.html
index 10fba5ad..35b94715 100644
--- a/rowers/templates/paymentconfirm.html
+++ b/rowers/templates/paymentconfirm.html
@@ -65,7 +65,7 @@
Change Order
-
diff --git a/rowers/templates/payments.html b/rowers/templates/payments.html
index 9c248bcb..dd32cfbf 100644
--- a/rowers/templates/payments.html
+++ b/rowers/templates/payments.html
@@ -235,7 +235,7 @@
BrainTree Experimental Corner
-
diff --git a/rowers/templates/rankings.html b/rowers/templates/rankings.html
index bfffd7e4..ee1bc30b 100644
--- a/rowers/templates/rankings.html
+++ b/rowers/templates/rankings.html
@@ -90,7 +90,7 @@
Missing your best pieces? Upload stroke data of any Concept2
ranking piece and they will be automatically added to this page.
Don't have stroke data for official Concept2 ranking pieces?
- The PRO membership ranking piece functionality
+ The PRO membership ranking piece functionality
allows you to include your best non ranking pieces and even use
parts of workouts for improved calculation accuracy.
@@ -114,7 +114,7 @@
{% csrf_token %}
/
diff --git a/rowers/templates/registeremail.html b/rowers/templates/registeremail.html
index d427b5a7..c516f592 100644
--- a/rowers/templates/registeremail.html
+++ b/rowers/templates/registeremail.html
@@ -39,7 +39,7 @@
If you find it to be useful, please help us cover
our hosting costs and gain access to additional functionality
by signing on as a Pro member:
- https://rowsandall.com/rowers/promembership
+ https://rowsandall.com/rowers/paidplans
diff --git a/rowers/templates/splitworkout.html b/rowers/templates/splitworkout.html
index 86756bc8..5ab8a668 100644
--- a/rowers/templates/splitworkout.html
+++ b/rowers/templates/splitworkout.html
@@ -12,7 +12,7 @@
-
+
diff --git a/rowers/templates/strokedata_form.html b/rowers/templates/strokedata_form.html
index 21e39da9..a34ee316 100644
--- a/rowers/templates/strokedata_form.html
+++ b/rowers/templates/strokedata_form.html
@@ -8,7 +8,7 @@
{% endif %}
Stroke Data for workout
-
+
diff --git a/rowers/templates/summary_edit.html b/rowers/templates/summary_edit.html
index 5d61d6bf..32d7b067 100644
--- a/rowers/templates/summary_edit.html
+++ b/rowers/templates/summary_edit.html
@@ -38,7 +38,7 @@
See the how-to at the bottom of this page for details on how to use this form.
-
+
@@ -73,7 +73,7 @@
Updated Summary
-
+
{% csrf_token %}
@@ -101,7 +101,7 @@
Detailed Summary Edit
This is still experimental and there are known bugs. Use at your own risk. Nothing is stored permanently until you hit Save in the Updated Summary section. You can use the restore original button to restore the original values.
-
+
diff --git a/rowers/templates/upgrade.html b/rowers/templates/upgrade.html
index 9f21c889..f224f7dd 100644
--- a/rowers/templates/upgrade.html
+++ b/rowers/templates/upgrade.html
@@ -20,7 +20,8 @@
Unless specified otherwise, the payments on the
recurring payment plans are annual. The prices are specified
- as a price per year.
+ as a price per year. You can downgrade or cancel your
+ plan at any time in your settings .
diff --git a/rowers/templates/upgradeconfirm.html b/rowers/templates/upgradeconfirm.html
index 92c28ccd..b42c4459 100644
--- a/rowers/templates/upgradeconfirm.html
+++ b/rowers/templates/upgradeconfirm.html
@@ -65,7 +65,7 @@
Change Upgrade
-
diff --git a/rowers/templates/user_boxplot_select.html b/rowers/templates/user_boxplot_select.html
index ba2ff67b..f29d3fda 100644
--- a/rowers/templates/user_boxplot_select.html
+++ b/rowers/templates/user_boxplot_select.html
@@ -80,7 +80,7 @@
-
+
{% if workouts %}
diff --git a/rowers/templates/user_multiflex_select.html b/rowers/templates/user_multiflex_select.html
index 0566ad12..9b4478fa 100644
--- a/rowers/templates/user_multiflex_select.html
+++ b/rowers/templates/user_multiflex_select.html
@@ -103,7 +103,7 @@
-
+
{% if workouts %}
Toggle All
diff --git a/rowers/templates/workout_comments.html b/rowers/templates/workout_comments.html
index c858c8b7..4f593026 100644
--- a/rowers/templates/workout_comments.html
+++ b/rowers/templates/workout_comments.html
@@ -54,7 +54,7 @@
{% endfor %}
-
+
diff --git a/rowers/templates/workout_join_select.html b/rowers/templates/workout_join_select.html
index a6f2649e..7267ee91 100644
--- a/rowers/templates/workout_join_select.html
+++ b/rowers/templates/workout_join_select.html
@@ -70,7 +70,7 @@
-
+
{% if workouts %}
Toggle All
@@ -127,10 +127,10 @@
{% if team %}
-
{% else %}
-
{% endif %}
{{ searchform }}
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index 253ced99..207363ce 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -493,21 +493,26 @@ def micromacroid(id):
@register.filter
def nextworkout(workout,user):
if user.rower == workout.user:
- ws = Workout.objects.filter(
- startdatetime__gte=workout.startdatetime,
- user=workout.user
- ).order_by(
- "startdatetime"
- ).exclude(id=workout.id)
+ try:
+ ws = Workout.objects.filter(
+ startdatetime__gte=workout.startdatetime,
+ user=workout.user
+ ).order_by(
+ "startdatetime"
+ ).exclude(id=workout.id)
+ except ValueError:
+ return 0
else:
- ws = Workout.objects.filter(
- startdatetime__gte=workout.startdatetime,
- user=workout.user,privacy='visible'
- ).order_by(
- "startdatetime"
- ).exclude(id=workout.id)
-
-
+ try:
+ ws = Workout.objects.filter(
+ startdatetime__gte=workout.startdatetime,
+ user=workout.user,privacy='visible'
+ ).order_by(
+ "startdatetime"
+ ).exclude(id=workout.id)
+ except ValueError:
+ return 0
+
if ws:
return ws[0].id
else:
@@ -518,19 +523,25 @@ def nextworkout(workout,user):
@register.filter
def previousworkout(workout,user):
if user.rower == workout.user:
- ws = Workout.objects.filter(
- startdatetime__lte=workout.startdatetime,
- user=workout.user
- ).order_by(
+ try:
+ ws = Workout.objects.filter(
+ startdatetime__lte=workout.startdatetime,
+ user=workout.user
+ ).order_by(
"-startdatetime"
- ).exclude(id=workout.id)
+ ).exclude(id=workout.id)
+ except ValueError:
+ return 0
else:
- ws = Workout.objects.filter(
- startdatetime__lte=workout.startdatetime,
- user=workout.user,privacy='visible'
- ).order_by(
- "-startdatetime"
- ).exclude(id=workout.id)
+ try:
+ ws = Workout.objects.filter(
+ startdatetime__lte=workout.startdatetime,
+ user=workout.user,privacy='visible'
+ ).order_by(
+ "-startdatetime"
+ ).exclude(id=workout.id)
+ except ValueError:
+ return 0
if ws:
diff --git a/rowers/tests/__init__.py b/rowers/tests/__init__.py
index 613de3e3..8fd9adf2 100644
--- a/rowers/tests/__init__.py
+++ b/rowers/tests/__init__.py
@@ -1,21 +1,21 @@
pkg_mox = None
-def setUpPackage():
- global pkg_mox
- import urllib
- import urllib2
- import mox
- import requests
- pkg_mox = mox.Mox()
- pkg_mox.StubOutWithMock(requests.api.sessions.Session, 'send')
- pkg_mox.StubOutWithMock(urllib.URLopener, 'open')
- pkg_mox.StubOutWithMock(urllib2.OpenerDirector, 'open')
- pkg_mox.ReplayAll()
+# def setUpPackage():
+# global pkg_mox
+# import urllib
+# import urllib2
+# import mox
+# import requests
+# pkg_mox = mox.Mox()
+# pkg_mox.StubOutWithMock(requests.api.sessions.Session, 'send')
+# pkg_mox.StubOutWithMock(urllib.URLopener, 'open')
+# pkg_mox.StubOutWithMock(urllib2.OpenerDirector, 'open')
+# pkg_mox.ReplayAll()
-def tearDownPackage():
- pkg_mox.VerifyAll()
- pkg_mox.UnsetStubs()
+#def tearDownPackage():
+# pkg_mox.VerifyAll()
+# pkg_mox.UnsetStubs()
from tests import *
diff --git a/rowers/tests/donottest_ajax.py b/rowers/tests/donottest_ajax.py
new file mode 100644
index 00000000..92d223de
--- /dev/null
+++ b/rowers/tests/donottest_ajax.py
@@ -0,0 +1,82 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+from rowers.views import checkworkoutuser,c2_open
+from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
+from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
+import rowers.plots as plots
+import rowers.interactiveplots as iplots
+import datetime
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+from django.utils import timezone
+from rowers.rows import handle_uploaded_file
+from django.core.files.uploadedfile import SimpleUploadedFile
+from time import strftime,strptime,mktime,time,daylight
+import os
+from rowers.tasks import handle_makeplot
+from rowers.utils import serialize_list,deserialize_list
+from rowers.utils import NoTokenError
+from shutil import copyfile
+from nose.tools import assert_true
+from mock import Mock, patch
+from minimocktest import MockTestCase
+import pandas as pd
+import rowers.c2stuff as c2stuff
+
+import json
+import numpy as np
+
+from rowers import urls
+from rowers.views import error500_view,error404_view,error400_view,error403_view
+
+from rowers.dataprep import delete_strokedata
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+class AjaxTests(TestCase):
+ def setUp(self):
+ redis_connection.publish('tasks','KILL')
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ r = Rower.objects.create(user=u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+ self.nu = datetime.datetime.now()
+
+ self.filename = 'rowers/tests/testdata/testdata.csv'
+ self.wotw = Workout.objects.create(name='testworkout',
+ workouttype='water',
+ user=r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=self.nu.strftime('%H:%M:%S'),
+ duration="0:55:00",distance=8000,
+ csvfilename=self.filename)
+
+ self.wote = Workout.objects.create(name='testworkout',
+ workouttype='Indoor Rower',
+ user=r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=self.nu.strftime('%H:%M:%S'),
+ duration="0:55:00",distance=8000,
+ csvfilename=self.filename)
+
+
+ self.c = Client()
+
+ def test_toggle_ranking(self):
+ response = self.c.get(
+ '/rowers/workout/1/toggle-ranking/',
+ **{'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'})
+
+ jsondata = json.loads(response.json())
+ self.assertIn('result',jsondata)
diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py
new file mode 100644
index 00000000..6937e41c
--- /dev/null
+++ b/rowers/tests/mocks.py
@@ -0,0 +1,513 @@
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+from rowers.views import checkworkoutuser,c2_open
+from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
+from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
+import rowers.plots as plots
+import rowers.interactiveplots as iplots
+import datetime
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+from django.utils import timezone
+from rowers.rows import handle_uploaded_file
+from django.core.files.uploadedfile import SimpleUploadedFile
+from time import strftime,strptime,mktime,time,daylight
+import os
+from rowers.tasks import handle_makeplot
+from rowers.utils import serialize_list,deserialize_list
+from rowers.utils import NoTokenError
+from shutil import copyfile
+from nose.tools import assert_true
+from mock import Mock, patch
+from minimocktest import MockTestCase
+import pandas as pd
+import rowers.c2stuff as c2stuff
+
+import json
+import numpy as np
+from rowingdata import rowingdata, figure
+
+from rowers import urls
+from rowers.views import (
+ error500_view,error404_view,error400_view,error403_view
+ )
+
+from rowers.dataprep import delete_strokedata
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+from django_mailbox.models import Mailbox,MessageAttachment,Message
+
+def mocked_sqlalchemy(*args, **kwargs):
+ # return object with method
+
+ class MockEngine:
+ def connect(self):
+ return MockConnection()
+
+ def dispose(self):
+ return True
+
+ def raw_connection(self):
+ return True
+
+ class MockConnection:
+ def begin(self):
+ return True
+
+ def execute(self):
+ return True
+
+ def execute(self):
+ return True
+
+ def close(self):
+ return True
+
+ def __exit__(self, *args, **kwargs):
+ return True
+
+ def __enter__(self, *args, **kwargs):
+ return True
+
+ return MockEngine()
+
+#@pytest.mark.django_db
+class DjangoTestCase(TestCase, MockTestCase):
+ def _pre_setup(self):
+ MockTestCase.setUp(self)
+ TestCase._pre_setup(self)
+ self.client = Client()
+
+ def _post_teardown(self):
+ TestCase._post_teardown(self)
+ MockTestCase.tearDown(self)
+ # delete_strokedata(1)
+
+def mocked_tcx_parser(*args, **kwargs):
+ df = pd.read_csv('rowers/tests/testdata/fake_strokedata.csv')
+
+ return rowingdata(df=df)
+
+def mocked_polar_notifications(*args, **kwargs):
+ return []
+
+
+class mocked_canvas():
+ def print_figure(*args, **kwargs):
+ return True
+
+import pandas as pd
+def mocked_read_df_sql(id):
+ df = pd.read_csv('rowers/tests/testdata/fake_strokedata.csv')
+
+ return df
+
+
+def mocked_getsmallrowdata_db(*args, **kwargs):
+ df = pd.read_csv('rowers/tests/testdata/colsfromdb.csv')
+
+ return df
+
+def mocked_read_df_cols_sql(ids, columns, convertnewtons=True):
+ df = pd.read_csv('rowers/tests/testdata/fake_strokedata.csv')
+ extracols = []
+
+ return df, extracols
+
+def mocked_stravaexport(f2,workoutname,stravatoken,description='',
+ activity_type='Rowing'):
+ print "this is mocked strava export"
+ return 1,'success'
+
+def StravaActivity():
+ def wait(*args, **kwargs):
+ return 1
+
+class MockStravalibClient():
+ def upload_activity(*args, **kwargs):
+ return StravaActivity()
+
+ def update_activity(*args, **kwargs):
+ return StravaActivity()
+
+
+class mocked_rowingdata(rowingdata):
+ def __init__(self, *args, **kwargs):
+ super(mocked_rowingdata).__init__(*args, **kwargs)
+
+ def get_metersplot_erg(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_timeplot_erg(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_piechart(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_timeplot_otwempower(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_timeplot_otw(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_metersplot_otwempower(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_metersplot_erg2(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_timeplot_erg2(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_time_otwpower(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+ def get_power_piechart(self, title):
+ fig1 = figure.Figure(figsize(12,10))
+ return fig1
+
+
+# to be done add polar mocks (for email processing)
+def mocked_requests(*args, **kwargs):
+ with open('rowers/tests/testdata/c2jsonworkoutdata.txt','r') as infile:
+ c2workoutdata = json.load(infile)
+
+ with open('rowers/tests/testdata/c2jsonstrokedata.txt','r') as infile:
+ c2strokedata = json.load(infile)
+
+ polar_json = {
+ 'available-user-data': []
+ }
+
+ c2workoutlist = json.load(open('rowers/tests/testdata/c2workoutlist.txt'))
+
+ c2uploadjson = {
+ "data": {
+ "id": 339,
+ "user_id": 1,
+ "date": "2015-08-05 13:15:41",
+ "timezone": "Europe/London",
+ "date_utc": "2015-08-05 12:15:41",
+ "distance": 5649,
+ "type": "rower",
+ "time": 8649,
+ "time_formatted": "14:24.9",
+ "workout_type": "JustRow",
+ "source": "ErgData",
+ "weight_class": "H",
+ "verified": True,
+ "ranked": False
+ }
+ }
+
+ stravaworkoutlist = json.load(open('rowers/tests/testdata/stravaworkoutlist.txt'))
+ sporttracksworkoutlist = json.load(open('rowers/tests/testdata/sporttracksworkouts.txt'))
+
+ rkworkoutlistjson = json.load(open('rowers/tests/testdata/rkworkoutslist.txt','r'))
+ uaworkoutlistjson = json.load(open('rowers/tests/testdata/uaworkoutlist.txt','r'))
+
+ stravasummaryjson = json.load(open('rowers/tests/testdata/stravaworkoutsummary.txt','r'))
+
+ stravatimejson = json.load(open('rowers/tests/testdata/stravatimetestdata.txt','r'))
+ stravavelojson = json.load(open('rowers/tests/testdata/stravavelotestdata.txt','r'))
+
+ stravapowerjson = json.load(open('rowers/tests/testdata/stravapowertestdata.txt','r'))
+
+ stravadistancejson = json.load(open('rowers/tests/testdata/stravadistancetestdata.txt','r'))
+ stravalatlongjson = json.load(open('rowers/tests/testdata/stravalatlongtestdata.txt','r'))
+ stravahrjson = json.load(open('rowers/tests/testdata/stravahrtestdata.txt','r'))
+ stravaspmjson = json.load(open('rowers/tests/testdata/stravaspmtestdata.txt','r'))
+
+ uapostworkoutjson = json.load(open('rowers/tests/testdata/uapostworkoutresponse.txt','r'))
+
+ tpuploadresponse = json.load(open('rowers/tests/testdata/tpuploadresponse.txt','r'))
+
+ stravastreamjson = {
+ 'time':stravatimejson,
+ 'velocity_smooth':stravavelojson,
+ 'distance':stravadistancejson,
+ 'latlng':stravalatlongjson,
+ 'heartrate':stravahrjson,
+ 'cadence':stravaspmjson,
+ 'power':stravapowerjson,
+ }
+
+ ststrokesjson = json.load(open('rowers/tests/testdata/sporttracksstrokedata.txt','r'))
+
+ rkstrokesjson = json.load(open('rowers/tests/testdata/rkstrokes.txt','r'))
+
+ uastrokesjson = json.load(open('rowers/tests/testdata/uastrokes.txt','r'))
+ uauserjson = json.load(open('rowers/tests/testdata/uauser.txt','r'))
+
+ class MockResponse:
+ def __init__(self, json_data, status_code):
+ self.json_data = json_data
+ self.status_code = status_code
+
+ def json(self):
+ return self.json_data
+
+
+ class MockHeaderResponse:
+ def __init__(self, header_data, status_code):
+ self.headers = header_data
+ self.status_code = status_code
+
+ class MockSession:
+ def send(self,prepped):
+ # prepped.url
+ # prepped.body (post data)
+ # prepped.headers
+ # prepped.method
+
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+
+ return MockResponse(json_data,200)
+
+
+ if not args:
+ return MockSession()
+
+ polartester = re.compile('.*?polaraccesslink\.com')
+ c2tester = re.compile('.*?log\.concept2\.com')
+ stravatester = re.compile('.*?strava\.com')
+ sttester = re.compile('.*?sporttracks\.mobi')
+ rktester = re.compile('.*?runkeeper\.com')
+ uatester = re.compile('.*?mapmyfitness\.com')
+ tptester = re.compile('.*?trainingpeaks\.com')
+
+ c2importregex = '.*?concept2.com\/api\/users\/me\/results\/\d+'
+ c2importtester = re.compile(c2importregex)
+
+ c2uploadregex = '.*?concept2.com\/api\/users\/\d+\/results$'
+ c2uploadtester = re.compile(c2uploadregex)
+
+ c2strokesregex = '.*?concept2.com\/api\/users\/me\/results\/\d+\/strokes'
+ c2strokestester = re.compile(c2strokesregex)
+
+ c2workoutlistregex = '.*?concept2\.com\/api\/users\/me\/results\?page=\d'
+ c2workoutlisttester = re.compile(c2workoutlistregex)
+
+ stravaworkoutlistregex = '.*?strava\.com\/api\/v3\/athlete\/activities'
+ stravaworkoutlisttester = re.compile(stravaworkoutlistregex)
+
+ stravastreamregex = '.*?strava\.com\/api\/v3\/activities\/\d+\/streams\/(\w.*?)\?'
+ stravastreamtester = re.compile(stravastreamregex)
+
+ stravasummaryregex = '.*?strava\.com\/api\/v3\/activities\/\d+$'
+ stravasummarytester = re.compile(stravasummaryregex)
+
+ stuploadregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities.json$'
+ stuploadtester = re.compile(stuploadregex)
+
+ stworkoutlistregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities$'
+ stworkoutlisttester = re.compile(stworkoutlistregex)
+
+ ststrokesregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities/\d+$'
+ ststrokestester = re.compile(ststrokesregex)
+
+ rkuploadregex = '.*?api\.runkeeper\.com\/fitnessActivities$'
+ rkuploadtester = re.compile(rkuploadregex)
+ rkuserregex = '.*?api\.runkeeper\.com\/user$'
+ rkusertester = re.compile(rkuserregex)
+ rkstrokesregex = '.*?api\.runkeeper\.com\/fitnessActivities/\d+$'
+ rkstrokestester = re.compile(rkstrokesregex)
+
+ uaapiregex = '.*?api\.ua\.com'
+ uaapitester = re.compile(uaapiregex)
+
+ uauploadregex = '.*?api\.ua\.com\/v7.1\/workout\/$'
+ uauploadtester = re.compile(uauploadregex)
+
+ uastrokesregex = '.*?api\.ua\.com\/v7.1\/workout\/\d+'
+ uastrokestester = re.compile(uastrokesregex)
+
+ ualistregex = '.*?api\.ua\.com\/v7.1\/workout\/\?user'
+ ualisttester = re.compile(ualistregex)
+
+ uauserregex = '.*?api\.ua\.com\/v7.1\/user\/self\/'
+ uausertester = re.compile(uauserregex)
+
+ tpuploadregex = '.*?trainingpeaks\.com\/v1\/file'
+ tpuploadtester = re.compile(tpuploadregex)
+
+ if polartester.match(args[0]):
+ json_data = polar_json
+ return MockResponse(json_data,200)
+
+ if tptester.match(args[0]):
+ if 'token' in args[0]:
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+ return MockResponse(json_data,200)
+ elif tpuploadtester.match(args[0]):
+ return MockResponse(tpuploadresponse,200)
+
+ if uaapitester.match(args[0]):
+ if 'access_token' in args[0]:
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+ return MockResponse(json_data,200)
+ elif uauploadtester.match(args[0]):
+ if 'data' in kwargs:
+ return MockResponse(uapostworkoutjson,200)
+ elif uastrokestester.match(args[0]):
+ return MockResponse(uastrokesjson,200)
+ elif ualisttester.match(args[0]):
+ return MockResponse(uaworkoutlistjson,200)
+ elif uausertester.match(args[0]):
+ return MockResponse(uauserjson,200)
+
+
+ if uatester.match(args[0]):
+ if 'access_token' in args[0]:
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+ return MockResponse(json_data,200)
+
+
+ if rktester.match(args[0]):
+ if 'token' in args[0]:
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+ return MockResponse(json_data,200)
+ elif rkuploadtester.match(args[0]):
+ if 'data' in kwargs:
+ # post
+ header_data = {
+ 'Location': '/fitnessActivities/12'
+ }
+ return MockHeaderResponse(header_data,200)
+ else:
+ json_data = rkworkoutlistjson
+ return MockResponse(json_data,200)
+ elif rkusertester.match(args[0]):
+ json_data = {
+ "userID": 1234567890,
+ "profile": "/profile",
+ "settings": "/settings",
+ "fitness_activities": "/fitnessActivities",
+ "strength_training_activities": "/strengthTrainingActivities",
+ "background_activities": "/backgroundActivities",
+ "sleep": "/sleep",
+ "nutrition": "/nutrition",
+ "weight": "/weight",
+ "general_measurements": "/generalMeasurements",
+ "diabetes": "/diabetes",
+ "records": "/records",
+ "team": "/team"
+ }
+ return MockResponse(json_data, 200)
+ elif rkstrokestester.match(args[0]):
+ return MockResponse(rkstrokesjson,200)
+
+ if sttester.match(args[0]):
+ if 'oauth2/token' in args[0]:
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+ return MockResponse(json_data,200)
+ if ststrokestester.match(args[0]):
+ return MockResponse(ststrokesjson,200)
+ if stuploadtester.match(args[0]):
+ json_data = {
+ "uris": [
+ "https://api.sporttracks.mobi/api/v2/fitnessActivities/123456.json"
+ ]
+ }
+ return MockResponse(json_data, 200)
+ if stworkoutlisttester.match(args[0]):
+ return MockResponse(sporttracksworkoutlist,200)
+
+
+ if stravatester.match(args[0]):
+ if stravaworkoutlisttester.match(args[0]):
+ return MockResponse(stravaworkoutlist,200)
+ if stravastreamtester.match(args[0]):
+ metric = stravastreamtester.match(args[0]).group(1)
+ json_data = stravastreamjson[metric]
+ return MockResponse(json_data,200)
+ elif stravasummarytester.match(args[0]):
+ return MockResponse(stravasummaryjson,200)
+ elif 'token' in args[0]:
+ json_data = {
+ "token_type": "Bearer",
+ "access_token": "987654321234567898765432123456789",
+ "refresh_token": "1234567898765432112345678987654321",
+ "expires_at": 1531385304
+ }
+ return MockResponse(json_data,200)
+
+
+ if c2tester.match(args[0]):
+ if c2uploadtester.match(args[0]):
+ return MockResponse(c2uploadjson,201)
+ if c2strokestester.match(args[0]):
+ return MockResponse(c2strokedata,200)
+ elif c2importtester.match(args[0]):
+ return MockResponse(c2workoutdata,200)
+ elif c2workoutlisttester.match(args[0]):
+ return MockResponse(c2workoutlist,200)
+ elif 'access_token' in args[0]:
+ json_data = {
+ 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
+ 'expires_in': 604800,
+ 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
+ }
+ return MockResponse(json_data,200)
+ elif 'users/me' in args[0]:
+ json_data = {
+ 'data': {
+ 'username': 'john',
+ 'id': 1234,
+ }
+ }
+ return MockResponse(json_data,200)
+ elif 'results' in args[0]:
+ json_data = {
+ 'data': {
+ 'id': 1223,
+ }
+ }
+ else:
+ return MockResponse(c2workoutdata,200)
+
+ return MockResponse(None,404)
diff --git a/rowers/tests/test_admin.py b/rowers/tests/test_admin.py
new file mode 100644
index 00000000..230c6221
--- /dev/null
+++ b/rowers/tests/test_admin.py
@@ -0,0 +1,47 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+import datetime
+
+import json
+import numpy as np
+
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+from rowers.models import User,Rower
+
+@pytest.mark.django_db
+class AdminTests(TestCase):
+ def setUp(self):
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ r = Rower.objects.create(user=u)
+ my_admin = User.objects.create_superuser('myuser',
+ 'myemail@test.com',
+ 'apensstaart')
+
+ self.c = Client()
+ self.c.login(username='myuser',password='apensstaart')
+
+ def test_admin(self):
+ response = self.c.get('/admin',follow=True)
+ self.assertEqual(response.status_code,200)
+
+
+ response = self.c.get('/admin/auth/user/',follow=True)
+ self.assertEqual(response.status_code,200)
+
+ response = self.c.get('/admin/auth/user/77/change/',follow=True)
+ self.assertEqual(response.status_code,200)
diff --git a/rowers/tests/test_fakers.py b/rowers/tests/test_fakers.py
new file mode 100644
index 00000000..04969fb4
--- /dev/null
+++ b/rowers/tests/test_fakers.py
@@ -0,0 +1,177 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings, RequestFactory
+
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+from rowers.views import checkworkoutuser,c2_open, multi_compare_view
+
+from rowers.forms import (
+ DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail,
+ ChartParamChoiceForm,WorkoutMultipleCompareForm)
+import rowers.plots as plots
+import rowers.interactiveplots as iplots
+import datetime
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+from django.utils import timezone
+from rowers.rows import handle_uploaded_file
+from django.core.files.uploadedfile import SimpleUploadedFile
+from time import strftime,strptime,mktime,time,daylight
+import os
+from rowers.tasks import handle_makeplot
+from rowers.utils import serialize_list,deserialize_list
+from rowers.utils import NoTokenError
+from shutil import copyfile
+from nose.tools import assert_true
+from mock import Mock, patch
+from minimocktest import MockTestCase
+import pandas as pd
+import rowers.c2stuff as c2stuff
+
+import json
+import numpy as np
+
+from rowers import urls
+from rowers.views import (
+ error500_view,error404_view,error400_view,error403_view
+ )
+
+from rowers.dataprep import delete_strokedata
+from django.contrib.sessions.middleware import SessionMiddleware
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+from django_mailbox.models import Mailbox,MessageAttachment,Message
+
+from rowers.tests.mocks import *
+
+from rowers.models import *
+from rowers.tests.mocks import *
+import factory
+from faker import Factory
+
+faker = Factory.create()
+
+filename = 'rowers/tests/testdata/testdata.csv'
+
+row = rdata(filename)
+totaldist = row.df['cum_dist'].max()
+totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+hours = int(totaltime/3600.)
+minutes = int((totaltime - 3600.*hours)/60.)
+seconds = int(totaltime - 3600.*hours - 60.*minutes)
+tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+duration = datetime.time(hour=hours,minute=minutes,second=seconds)
+
+workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+nu = datetime.datetime.now()
+
+class UserFactory(factory.DjangoModelFactory):
+ class Meta:
+ model = User
+
+ email = faker.email()
+ username = faker.profile()['username']
+
+ first_name = faker.name().split(' ')[0]
+ last_name = faker.name().split(' ')[0]
+
+class WorkoutFactory(factory.DjangoModelFactory):
+ class Meta:
+ model = Workout
+
+ name = factory.LazyAttribute(lambda _: faker.word())
+ notes = faker.text()
+ startdatetime = row.rowdatetime
+ starttime = workoutstarttime
+ workouttype='water'
+ date=timezone.now().date()
+ duration=duration
+ distance=totaldist
+ csvfilename=filename
+
+class ModelObjectsTest(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()
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.getsmallrowdata_db')
+ def test_workouts_compare(self, mocked_sqlalchemy,
+ mocked_getsmallrowdata_db):
+
+ login = self.c.login(username=self.u.username, password=self.password)
+ self.assertTrue(login)
+
+ url = '/rowers/team-compare-select/workout/1/team/0/user/1/'
+
+ response = self.c.get(url)
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.getsmallrowdata_db')
+ def test_workouts_compare_submit(self, mocked_sqlalchemy,
+ mocked_getsmallrowdata_db):
+
+ login = self.c.login(username=self.u.username,password=self.password)
+ self.assertTrue(login)
+
+ form_data = {
+ 'chartform':'Compare',
+ 'plottype':'scatter',
+ 'teamid':0,
+ 'workouts':['1','2','3'],
+ 'xparam':'distance',
+ 'yparam':'hr',
+ }
+
+ form = WorkoutMultipleCompareForm(form_data)
+ chartform = ChartParamChoiceForm(form_data)
+ self.assertTrue(form.is_valid)
+ self.assertTrue(chartform.is_valid)
+
+# request = self.factory.post('/rowers/multi-compare/')
+# request.user = self.u
+# request.POST = form_data
+
+# SessionMiddleware().process_request(request)
+
+# request.session['ids'] = []
+
+# response = multi_compare_view(request)
+
+# self.assertEqual(response.status_code, 200)
+
+ response = self.c.post('/rowers/multi-compare/',form_data)
+
+ self.assertEqual(response.status_code,200)
+
+
diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py
new file mode 100644
index 00000000..115484f9
--- /dev/null
+++ b/rowers/tests/test_imports.py
@@ -0,0 +1,820 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings, modify_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+from rowers.views import checkworkoutuser,c2_open
+from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
+from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
+import rowers.plots as plots
+import rowers.interactiveplots as iplots
+import datetime
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+from django.utils import timezone
+from rowers.rows import handle_uploaded_file
+from django.core.files.uploadedfile import SimpleUploadedFile
+from time import strftime,strptime,mktime,time,daylight
+import os
+from rowers.tasks import handle_makeplot
+from rowers.utils import serialize_list,deserialize_list
+from rowers.utils import NoTokenError
+from shutil import copyfile
+from nose.tools import assert_true
+from mock import Mock, patch
+from minimocktest import MockTestCase
+import pandas as pd
+import rowers.c2stuff as c2stuff
+
+import json
+import numpy as np
+
+import rowers
+
+from rowers import urls
+from rowers.views import (
+ error500_view,error404_view,error400_view,error403_view
+ )
+
+from rowers.dataprep import delete_strokedata
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+from django_mailbox.models import Mailbox,MessageAttachment,Message
+
+from rowers.tests.mocks import *
+
+@pytest.mark.django_db
+class C2Objects(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+ self.r.c2token = '12'
+ self.r.c2refreshtoken = 'ab'
+ self.r.tokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
+ self.r.save()
+ self.c.login(username='john',password='koeinsloot')
+
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+
+ @patch('rowers.c2stuff.Session', side_effect=mocked_requests)
+ def test_c2_callback(self, mock_Session):
+ response = self.c.get('/call_back?code=dsdoij232s',follow=True)
+
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.c2stuff.Session', side_effect=mocked_requests)
+ def test_c2_token_refresh(self, mock_Session):
+ response = self.c.get('/rowers/me/c2refresh/',follow=True)
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
+ def test_c2_upload(self, mock_get, mock_post):
+ response = self.c.get('/rowers/workout/1/c2uploadw/')
+
+ self.assertRedirects(response,
+ expected_url = '/rowers/workout/1/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.url, '/rowers/workout/1/edit/')
+ self.assertEqual(response.status_code, 302)
+
+ @patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
+ def test_c2_list(self, mock_get, mock_post):
+ response = self.c.get('/rowers/workout/c2list',follow=True)
+
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
+ @patch('rowers.dataprep.create_engine')
+ def test_c2_import(self, mock_get, mocked_sqlalchemy):
+
+ response = self.c.get('/rowers/workout/c2import/12/',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/2/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.dataprep.create_engine')
+ def test_strokedata(self, mocked_sqlalchemy):
+ with open('rowers/tests/testdata/c2stroketestdata.txt','r') as infile:
+ res = json.load(infile)
+
+ strokedata = pd.DataFrame.from_dict(res['data'])
+
+ with open('rowers/tests/testdata/c2testdata.txt','r') as infile:
+ res = json.load(infile)
+
+ data = res['data']
+
+ from rowers.views import add_workout_from_strokedata
+
+ res = add_workout_from_strokedata(self.u,1,data,strokedata,source='c2')
+
+ @patch('rowers.dataprep.create_engine')
+ def test_strokedatanohr(self, mocked_sqlalchemy):
+ with open('rowers/tests/testdata/c2strokedatanohr.txt','r') as infile:
+ res = json.load(infile)
+
+ strokedata = pd.DataFrame.from_dict(res['data'])
+
+ with open('rowers/tests/testdata/c2testdata.txt','r') as infile:
+ res = json.load(infile)
+
+ data = res['data']
+
+ from rowers.views import add_workout_from_strokedata
+
+
+ res = add_workout_from_strokedata(self.u,1,data,strokedata,source='c2')
+
+class C2ObjectsTokenExpired(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+ self.r.c2token = '12'
+ self.r.c2refreshtoken = 'ab'
+ self.r.tokenexpirydate = datetime.datetime.now()-datetime.timedelta(days=1)
+ self.r.save()
+ self.c.login(username='john',password='koeinsloot')
+
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+
+
+ @patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
+ @patch('rowers.c2stuff.Session',side_effect=mocked_requests)
+ def test_c2_list(self, mock_get, mock_post, mock_Session):
+ response = self.c.get('/rowers/workout/c2list',follow=True)
+
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
+ @patch('rowers.dataprep.create_engine')
+ def test_c2_import(self, mock_get, mocked_sqlalchemy):
+
+ response = self.c.get('/rowers/workout/c2import/12/',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/list-workouts/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+
+
+#@pytest.mark.django_db
+class StravaObjects(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+ self.r.stravatoken = '12'
+ self.r.stravarefreshtoken = '123'
+
+ self.r.save()
+ self.c.login(username='john',password='koeinsloot')
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+
+# @patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
+# @patch('rowers.views.stravastuff.handle_stravaexport')
+ #@patch('rowers.dataprep.getsmallrowdata_db')
+ #def test_strava_upload(self, mock_post,MockStravalibClient,
+ # mocked_getsmallrowdata_db):
+ # def test_strava_upload(self,mock_post, mocked_stravaexport):
+ # response = self.c.get('/rowers/workout/1/stravauploadw/')
+
+ # self.assertRedirects(response,
+ # expected_url = '/rowers/workout/1/edit/',
+ # status_code=302,target_status_code=200)
+
+ # self.assertEqual(response.url, '/rowers/workout/1/edit/')
+ # self.assertEqual(response.status_code, 302)
+
+ @patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
+ def test_strava_list(self, mock_get):
+ response = self.c.get('/rowers/workout/stravaimport/',follow=True)
+
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.utils.requests.get', side_effect=mocked_requests)
+ @patch('rowers.dataprep.getsmallrowdata_db')
+ def test_strava_import(self, mock_get,
+ mocked_getsmallrowdata_db):
+
+ response = self.c.get('/rowers/workout/stravaimport/12',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/2/edit/',
+ status_code=301,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+ @patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
+ def test_strava_callback(self, mock_post):
+ response = self.c.get('/stravacall_back?code=absdef23',follow=True)
+ self.assertEqual(response.status_code, 200)
+
+ @patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
+ def test_strava_token_refresh(self, mock_post):
+ result = rowers.stravastuff.rower_strava_token_refresh(self.u)
+ self.assertEqual(result,"987654321234567898765432123456789")
+
+
+
+#@pytest.mark.django_db
+class STObjects(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+
+ self.r.sporttrackstoken = '12'
+ self.r.sporttracksrefreshtoken = '12'
+ self.r.sporttrackstokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
+ self.r.save()
+
+ self.c.login(username='john',password='koeinsloot')
+
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+ @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests)
+ def test_sporttracks_callback(self, mock_post):
+ response = self.c.get('/sporttracks_callback?code=dsdoij232s',follow=True)
+
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests)
+ def test_sporttracks_token_refresh(self, mock_post):
+ response = self.c.get('/rowers/me/sporttracksrefresh/',follow=True)
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.sporttracksstuff.requests.get', side_effect=mocked_requests)
+ def test_sporttracks_upload(self, mock_get, mock_post):
+ response = self.c.get('/rowers/workout/1/sporttracksuploadw/')
+
+ self.assertRedirects(response,
+ expected_url = '/rowers/workout/1/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.url, '/rowers/workout/1/edit/')
+ self.assertEqual(response.status_code, 302)
+
+ @patch('rowers.sporttracksstuff.requests.get', side_effect=mocked_requests)
+ def test_sporttracks_list(self, mock_get):
+ response = self.c.get('/rowers/workout/sporttracksimport',follow=True)
+
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.imports.requests.get', side_effect=mocked_requests)
+ def test_sporttracks_import(self, mock_get):
+
+ response = self.c.get('/rowers/workout/sporttracksimport/12/',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/2/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+ @patch('rowers.dataprep.create_engine')
+ def test_strokedata(self, mocked_sqlalchemy):
+ with open('rowers/tests/testdata/sporttrackstestdata.txt','r') as infile:
+ data = json.load(infile)
+
+ from rowers.sporttracksstuff import add_workout_from_data
+
+ res = add_workout_from_data(self.u,1,data,data)
+
+ @patch('rowers.dataprep.create_engine')
+ def test_strokedatanohr(self, mocked_sqlalchemy):
+ with open('rowers/tests/testdata/sporttrackstestnohr.txt','r') as infile:
+ data = json.load(infile)
+
+ from rowers.sporttracksstuff import add_workout_from_data
+
+
+
+ res = add_workout_from_data(self.u,1,data,data)
+
+#@pytest.mark.django_db
+class RunKeeperObjects(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+
+ self.r.runkeepertoken = '12'
+
+ self.r.save()
+
+ self.c.login(username='john',password='koeinsloot')
+
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+ @patch('rowers.runkeeperstuff.requests.post', side_effect=mocked_requests)
+ def test_runkeeper_callback(self, mock_post):
+ response = self.c.get('/runkeeper_callback?code=dsdoij232s',follow=True)
+
+ self.assertEqual(response.status_code, 200)
+
+ @patch('rowers.runkeeperstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.runkeeperstuff.requests.get', side_effect=mocked_requests)
+ def test_runkeeper_upload(self, mock_get, mock_post):
+ response = self.c.get('/rowers/workout/1/runkeeperuploadw/')
+
+ self.assertRedirects(response,
+ expected_url = '/rowers/workout/1/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.url, '/rowers/workout/1/edit/')
+ self.assertEqual(response.status_code, 302)
+
+ @patch('rowers.runkeeperstuff.requests.get', side_effect=mocked_requests)
+ def test_runkeeper_list(self, mock_get):
+ response = self.c.get('/rowers/workout/runkeeperimport',follow=True)
+
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.imports.requests.get', side_effect=mocked_requests)
+ def test_runkeeper_import(self, mock_get):
+
+ response = self.c.get('/rowers/workout/runkeeperimport/12/',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/2/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+
+
+@pytest.mark.django_db
+class UAObjects(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+
+ self.r.underarmourtoken = '12'
+ self.r.underarmourrefreshtoken = '12'
+ self.r.underarmourtokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
+ self.r.save()
+
+ self.c.login(username='john',password='koeinsloot')
+
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+ @patch('rowers.imports.requests.post', side_effect=mocked_requests)
+ def test_underarmour_callback(self, mock_post):
+ response = self.c.get('/underarmour_callback?code=dsdoij232s',follow=True)
+
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.underarmourstuff.requests.post', side_effect=mocked_requests)
+ def test_underarmour_token_refresh(self, mock_post):
+ response = self.c.get('/rowers/me/underarmourrefresh/',follow=True)
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.underarmourstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.underarmourstuff.requests.get', side_effect=mocked_requests)
+ def test_underarmour_upload(self, mock_get, mock_post):
+ response = self.c.get('/rowers/workout/1/underarmouruploadw/')
+
+ self.assertRedirects(response,
+ expected_url = '/rowers/workout/1/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.url, '/rowers/workout/1/edit/')
+ self.assertEqual(response.status_code, 302)
+
+ @patch('rowers.underarmourstuff.requests.get', side_effect=mocked_requests)
+ def test_underarmour_list(self, mock_get):
+ response = self.c.get('/rowers/workout/underarmourimport',follow=True)
+
+ self.assertEqual(response.status_code,200)
+
+ @patch('rowers.imports.requests.get', side_effect=mocked_requests)
+ @patch('rowers.dataprep.create_engine')
+ def test_underarmour_import(self, mock_get, mocked_sqlalchemy):
+
+ response = self.c.get('/rowers/workout/underarmourimport/12/',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/2/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+
+#@pytest.mark.django_db
+class TPObjects(DjangoTestCase):
+ def setUp(self):
+ self.c = Client()
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'John'
+ self.u.last_name = 'Sander'
+ self.u.save()
+ self.r = Rower.objects.create(user=self.u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+
+ self.r.tptoken = '12'
+ self.r.tprefreshtoken = '12'
+ self.r.tptokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
+ self.r.save()
+
+ self.c.login(username='john',password='koeinsloot')
+
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+ @patch('rowers.imports.requests.post', side_effect=mocked_requests)
+ def test_tp_callback(self, mock_post):
+ response = self.c.get('/tp_callback?code=dsdoij232s',follow=True)
+
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests)
+ def test_tp_token_refresh(self, mock_post):
+ response = self.c.get('/rowers/me/tprefresh/',follow=True)
+
+ self.assertEqual(response.status_code, 200)
+
+
+ @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.tpstuff.requests.get', side_effect=mocked_requests)
+ def test_tp_upload(self, mock_get, mock_post):
+ response = self.c.get('/rowers/workout/1/tpuploadw/')
+
+ self.assertRedirects(response,
+ expected_url = '/rowers/workout/1/edit/',
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.url, '/rowers/workout/1/edit/')
+ self.assertEqual(response.status_code, 302)
+
+
+#@pytest.mark.django_db
+class AutoExportTests(TestCase):
+ def setUp(self):
+ redis_connection.publish('tasks','KILL')
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ r = Rower.objects.create(user=u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+ r.c2_auto_export = True
+ r.sporttracks_auto_export = True
+ r.mapmyfitness_auto_export = True
+ r.trainingpeaks_auto_export = True
+
+ r.save()
+
+ nu = datetime.datetime.now()
+ workoutsbox = Mailbox.objects.create(name='workouts')
+ workoutsbox.save()
+ failbox = Mailbox.objects.create(name='Failed')
+ failbox.save()
+
+ filename = 'testdata.csv'
+
+ m = Message(mailbox=workoutsbox,
+ from_header = u.email,
+ subject = filename,
+ body="""
+---
+workouttype: water
+boattype: 2x
+...
+ """)
+ m.save()
+ a2 = 'media/mailbox_attachments/'+filename
+ copyfile('rowers/tests/testdata/'+filename,a2)
+ a = MessageAttachment(message=m,document=a2[6:])
+ a.save()
+
+ def tearDown(self):
+ for filename in os.listdir('media/mailbox_attachments'):
+ path = os.path.join('media/mailbox_attachments/',filename)
+ if not os.path.isdir(path):
+ try:
+ os.remove(path)
+ except WindowsError:
+ pass
+
+ @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.tpstuff.requests.get', side_effect=mocked_requests)
+ def test_emailprocessing(self, mock_post, mock_get):
+ out = StringIO()
+ call_command('processemail', stdout=out, testing=True)
+ self.assertIn('Successfully processed email attachments',out.getvalue())
diff --git a/rowers/tests/test_models.py b/rowers/tests/test_models.py
new file mode 100644
index 00000000..a054bbb7
--- /dev/null
+++ b/rowers/tests/test_models.py
@@ -0,0 +1,48 @@
+from django.test import TestCase
+from rowers.models import *
+
+class FormTests(TestCase):
+ def setUp(self):
+ self.u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ r = Rower.objects.create(user=self.u)
+
+
+ def test_form(self):
+ form = TeamInviteForm()
+
+
+class ModelTests(TestCase):
+ def setUp(self):
+ self.u = User.objects.create_user('john',
+ 'Sander@ds.ds',
+ 'koeinsloot')
+
+ self.u.first_name = 'Sander'
+ self.u.last_name = 'Roosendaal'
+ self.u.save()
+
+ self.r = Rower.objects.create(user=self.u)
+
+ def create_team(self):
+ return Team.objects.create(
+ name = 'test team',
+ manager = self.u,
+ )
+
+ def create_paidplan(self):
+ return PaidPlan.objects.create(
+ name = 'test plan',
+ shortname = 'pro',
+ price = 15.0,
+ )
+
+ def test_models(self):
+ pp = self.create_paidplan()
+ team = self.create_team()
+ self.assertEqual(u'%s' % pp,u'test plan - pro at 15.00 EURO (single payment)')
+ self.assertEqual(u'%s' % self.r, u'Sander Roosendaal')
+ self.assertEqual('%s' % self.r, 'Sander Roosendaal')
+ self.assertEqual(self.r.clean_email(),'sander@ds.ds')
diff --git a/rowers/tests/test_urls.py b/rowers/tests/test_urls.py
new file mode 100644
index 00000000..6d568e3f
--- /dev/null
+++ b/rowers/tests/test_urls.py
@@ -0,0 +1,301 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+from rowers.views import checkworkoutuser,c2_open
+from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
+from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
+import rowers.plots as plots
+import rowers.interactiveplots as iplots
+import datetime
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+from django.utils import timezone
+from rowers.rows import handle_uploaded_file
+from django.core.files.uploadedfile import SimpleUploadedFile
+from time import strftime,strptime,mktime,time,daylight
+import os
+from rowers.tasks import handle_makeplot
+from rowers.utils import serialize_list,deserialize_list
+from rowers.utils import NoTokenError
+from shutil import copyfile
+from nose.tools import assert_true
+from mock import Mock, patch
+from minimocktest import MockTestCase
+import pandas as pd
+import rowers.c2stuff as c2stuff
+
+import json
+import numpy as np
+
+from rowers import urls
+from rowers.views import error500_view,error404_view,error400_view,error403_view
+
+from rowers.dataprep import delete_strokedata
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+
+#@pytest.mark.django_db
+class URLTests(TestCase):
+ def setUp(self):
+ redis_connection.publish('tasks','KILL')
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot',
+ )
+ r = Rower.objects.create(user=u,rowerplan='coach',gdproptin=True,
+ gdproptindate=timezone.now())
+ self.c = Client()
+
+ self.nu = datetime.datetime.now()
+ filename = 'rowers/tests/testdata/testdata.csv'
+ self.wotw = Workout.objects.create(name='testworkout',
+ workouttype='water',
+ user=r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=self.nu.strftime('%H:%M:%S'),
+ duration="0:55:00",distance=8000,
+ csvfilename=filename)
+
+ self.wote = Workout.objects.create(name='testworkout',
+ workouttype='Indoor Rower',
+ user=r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=self.nu.strftime('%H:%M:%S'),
+ duration="0:55:00",distance=8000,
+ csvfilename=filename)
+
+ powerperc = 100*np.array([r.pw_ut2,
+ r.pw_ut1,
+ r.pw_at,
+ r.pw_tr,r.pw_an])/r.ftp
+
+
+ self.hrdata = {
+ 'hrmax':r.max,
+ 'hrut2':r.ut2,
+ 'hrut1':r.ut1,
+ 'hrat':r.at,
+ 'hrtr':r.tr,
+ 'hran':r.an,
+ 'ftp':r.ftp,
+ 'powerperc':serialize_list(powerperc),
+ 'powerzones':serialize_list(r.powerzones),
+ }
+
+ urlstotest = [
+ '/rowers/400/',
+ '/rowers/403/',
+ '/rowers/404/',
+ '/rowers/500/',
+ '/rowers/502/',
+ '/rowers/1/list-workouts/',
+ '/rowers/1/list-workouts/2016-01-01/2016-12-31/',
+ '/rowers/1/ote-bests/',
+ '/rowers/1/ote-bests2/2016-01-01/2016-12-31/',
+ '/rowers/about/',
+ '/rowers/workout/addmanual/',
+ '/rowers/agegroupcp/30/',
+ '/rowers/agegroupcp/30/1/',
+ '/rowers/agegrouprecords/male/hwt/',
+ '/rowers/agegrouprecords/male/hwt/2000m/',
+ '/rowers/agegrouprecords/male/hwt/2000min/',
+ '/rowers/ajax_agegroup/45/hwt/male/1/',
+ '/rowers/analysis/',
+ '/rowers/analysis/user/1/',
+ '/rowers/brochure/',
+ '/rowers/courses/upload/',
+ '/rowers/createplan/',
+ '/rowers/createplan/user/1/',
+ '/rowers/cumstats/',
+ '/rowers/cumstats/2016-01-01/2016-12-31/',
+ '/rowers/cumstats/user/1/',
+ '/rowers/cumstats/user/1/2016-01-01/2016-12-31/',
+ '/rowers/developers/',
+ '/rowers/email/',
+ '/rowers/email/thankyou/',
+ '/rowers/fitness-progress/',
+ '/rowers/fitness-progress/user/1/',
+ '/rowers/fitness-progress/user/1/rower/',
+ '/rowers/flexall/',
+ '/rowers/flexall/spm/hr/None/',
+ '/rowers/flexall/spm/hr/None/2016-01-01/2016-12-31/',
+ '/rowers/flexall/spm/hr/None/2016-01-01/2016-12-31/user/1/',
+ '/rowers/flexall/user/1/',
+ '/rowers/flexalldata/',
+ '/rowers/help/',
+ '/rowers/histo/',
+ '/rowers/histo/user/1/',
+ '/rowers/histo/user/1/2016-01-01/2016-12-31/',
+ '/rowers/histodata/',
+ '/rowers/job-kill/1/',
+ '/rowers/jobs-status/',
+ '/rowers/laboratory/',
+ '/rowers/laboratory/user/1/',
+ '/rowers/legal/',
+ '/rowers/list-courses/',
+ '/rowers/list-graphs/',
+ '/rowers/list-jobs/',
+ '/rowers/list-workouts/',
+ '/rowers/list-workouts/2016-01-01/2016-12-31/',
+ '/rowers/list-workouts/2016-01-01/2016-12-31/user/1/',
+ '/rowers/list-workouts/ranking/',
+ '/rowers/list-workouts/user/1/',
+ '/rowers/me/calcdps/',
+ '/rowers/me/edit/',
+ '/rowers/me/edit/user/1/',
+ '/rowers/me/exportsettings/',
+ '/rowers/me/exportsettings/user/1/',
+ '/rowers/me/favoritecharts/',
+ '/rowers/me/favoritecharts/user/1/',
+ '/rowers/me/invitation/',
+ '/rowers/me/preferences/',
+ '/rowers/me/preferences/user/1/',
+ '/rowers/me/request/',
+ '/rowers/me/teams/',
+ '/rowers/me/workflowconfig2/',
+ '/rowers/me/workflowconfig2/user/1/',
+ '/rowers/me/workflowdefault/',
+# '/rowers/multi-compare/',
+ '/rowers/ote-bests/',
+ '/rowers/ote-bests/2016-01-01/2016-12-31/',
+ '/rowers/ote-bests/user/1/',
+ '/rowers/ote-bests/user/1/2016-01-01/2016-12-31/',
+ '/rowers/ote-bests2/',
+ '/rowers/ote-bests2/2016-01-01/2016-12-31/',
+ '/rowers/ote-bests2/user/1/',
+ '/rowers/ote-ranking/',
+ '/rowers/ote-ranking/2016-01-01/2016-12-31/',
+ '/rowers/ote-ranking/user/1/',
+ '/rowers/ote-ranking/user/1/2016-01-01/2016-12-31/',
+ '/rowers/otw-bests/',
+ '/rowers/otw-bests/2016-01-01/2016-12-31/',
+ '/rowers/otw-bests/user/1/2016-01-01/2016-12-31/',
+ '/rowers/partners/',
+ '/rowers/physics/',
+ '/rowers/planrequired/',
+ '/rowers/promembership/',
+ '/rowers/register/',
+ '/rowers/register/thankyou/',
+ '/rowers/sessions/',
+ '/rowers/sessions/2016-01-01/2016-12-31/',
+ '/rowers/sessions/2016-01-01/2016-12-31/user/1/',
+ '/rowers/sessions/coach/',
+ '/rowers/sessions/coach/user/1/',
+ '/rowers/sessions/create/',
+ '/rowers/sessions/create/user/1/',
+ '/rowers/sessions/manage/',
+ '/rowers/sessions/manage/user/1/',
+ '/rowers/sessions/multiclone/',
+ '/rowers/sessions/multiclone/user/1/',
+ '/rowers/sessions/multicreate/',
+ '/rowers/sessions/multicreate/user/1/',
+ '/rowers/sessions/print/',
+ '/rowers/sessions/print/user/1/',
+ '/rowers/sessions/teamcreate/',
+ '/rowers/sessions/user/1/',
+ '/rowers/team-compare-select/',
+ '/rowers/team-compare-select/workout/1/',
+ '/rowers/team-compare-select/2016-01-01/2016-12-31/',
+ '/rowers/test-job/2/',
+ '/rowers/test-job2/2/',
+# '/rowers/test_callback/',
+# '/rowers/updatefitness/',
+# '/rowers/updatefitness/rower/',
+# '/rowers/updatefitness/rower/50/',
+# '/rowers/user-boxplot/',
+# '/rowers/user-boxplot-data/',
+# '/rowers/user-boxplot-select/',
+# '/rowers/user-boxplot-select/user/1/',
+# '/rowers/user-boxplot/user/1/',
+# '/rowers/user-multiflex-data/',
+# '/rowers/user-multiflex-select/',
+# '/rowers/user-multiflex-select/2016-01-01/2016-12-31/',
+# '/rowers/user-multiflex-select/user/1/',
+# '/rowers/user-multiflex-select/user/1/2016-01-01/2016-12-31/',
+# '/rowers/user-multiflex/',
+# '/rowers/user-multiflex/user/1/',
+ '/rowers/workout/1/',
+ '/rowers/workout/1/adddistanceplot/',
+ '/rowers/workout/1/adddistanceplot2/',
+ '/rowers/workout/1/addotwpowerplot/',
+ '/rowers/workout/1/addpiechart/',
+ '/rowers/workout/1/addpowerpiechart/',
+ '/rowers/workout/1/addstatic/',
+ '/rowers/workout/1/addstatic/3/',
+ '/rowers/workout/1/addtimeplot/',
+ '/rowers/workout/1/addtimeplot2/',
+ '/rowers/workout/1/comment/',
+ '/rowers/workout/1/darkskywind/',
+ '/rowers/workout/1/data/',
+ '/rowers/workout/1/edit/',
+ '/rowers/workout/1/editintervals/',
+ '/rowers/workout/1/flexchart/',
+ '/rowers/workout/1/forcecurve/',
+ '/rowers/workout/1/get-testscript/',
+ '/rowers/workout/1/get-thumbnails/',
+ '/rowers/workout/1/histo/',
+ '/rowers/workout/1/image/',
+ '/rowers/workout/1/instroke/',
+ '/rowers/workout/1/interactiveotwplot/',
+ '/rowers/workout/1/map/',
+ '/rowers/workout/1/otwsetpower/',
+ '/rowers/workout/1/recalcsummary/',
+ '/rowers/workout/1/restore/',
+ '/rowers/workout/1/smoothenpace/',
+ '/rowers/workout/1/split/',
+ '/rowers/workout/1/stats/',
+ '/rowers/workout/1/stream/',
+ '/rowers/workout/1/task/',
+ '/rowers/workout/1/test_strokedata/',
+ '/rowers/workout/1/toggle-ranking/',
+ '/rowers/workout/1/undosmoothenpace/',
+ '/rowers/workout/1/unsubscribe/',
+ '/rowers/workout/1/updatecp/',
+ '/rowers/workout/1/view/',
+ '/rowers/workout/1/wind/',
+ '/rowers/workout/1/workflow/',
+ '/rowers/workout/compare/1/2016-01-01/2016-12-31/',
+ '/rowers/workout/fusion/1/',
+ '/rowers/workout/fusion/1/2016-01-01/2016-12-31/',
+ '/rowers/workout/upload/',
+ '/rowers/workout/upload/team/',
+ '/rowers/workouts-join/',
+ '/rowers/workouts-join-select/',
+ '/rowers/workouts-join-select/2016-01-01/2016-12-31/',
+ ]
+
+ # urlstotest = ['/rowers/createplan/user/1/']
+
+ lijst = []
+ for url in urlstotest:
+ lijst.append(
+ (url,200)
+ )
+
+ @parameterized.expand(lijst)
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ @patch('rowers.dataprep.getsmallrowdata_db')
+ def test_url_generator(self,url,expected,
+ mocked_sqlalchemy,
+ mocked_read_df_sql,
+ mocked_getsmallrowdata_db):
+ login = self.c.login(username='john',password='koeinsloot')
+ self.assertTrue(login)
+ response = self.c.get(url,follow=True)
+ if response.status_code != expected:
+ print url
+ print response.status_code
+ self.assertEqual(response.status_code,
+ expected)
+
+
diff --git a/rowers/tests/test_user.py b/rowers/tests/test_user.py
new file mode 100644
index 00000000..e7426321
--- /dev/null
+++ b/rowers/tests/test_user.py
@@ -0,0 +1,88 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+import datetime
+from django.utils import timezone
+
+import json
+import numpy as np
+import rowers.dataprep as dataprep
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+
+from rowers.models import User,Rower, Workout
+
+class UserMiddleWareTest(TestCase):
+ def setUp(self):
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ self.r = Rower.objects.create(user=u)
+
+ self.c = Client()
+ self.c.login(username='john',password='koeinsloot')
+ self.nu = datetime.datetime.now()
+
+ filename = 'rowers/tests/testdata/testdata.csv'
+
+ rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
+ hrut1=self.r.ut1,hrat=self.r.at,
+ hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
+ row = rdata(filename,rower=rr)
+ totaldist = row.df['cum_dist'].max()
+ totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
+ totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
+
+
+ hours = int(totaltime/3600.)
+ minutes = int((totaltime - 3600.*hours)/60.)
+ seconds = int(totaltime - 3600.*hours - 60.*minutes)
+ tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
+
+ duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
+
+
+ workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
+ workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
+
+ self.w = Workout.objects.create(
+ name='testworkout',workouttype='water',
+ user=self.r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=workoutstarttime,
+ startdatetime=row.rowdatetime,
+ duration=duration,distance=totaldist,
+ csvfilename=filename
+ )
+
+
+ def test_middleware(self):
+ response = self.c.get('/rowers/list-workouts',follow=True)
+ self.assertEqual(response.status_code,200)
+
+
+class UserTestsNoRower(TestCase):
+ def setUp(self):
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+
+ self.c = Client()
+ self.c.login(username='john',password='koeinsloot')
+
+
+ def test_user(self):
+ response = self.c.get('/rowers/list-workouts',follow=True)
+ self.assertEqual(response.status_code,200)
+
diff --git a/rowers/tests/test_zemails.py b/rowers/tests/test_zemails.py
new file mode 100644
index 00000000..bed7a8ec
--- /dev/null
+++ b/rowers/tests/test_zemails.py
@@ -0,0 +1,163 @@
+#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+from bs4 import BeautifulSoup
+import re
+from nose_parameterized import parameterized
+from django.test import TestCase, Client,override_settings
+from django.core.management import call_command
+from django.utils.six import StringIO
+from django.test.client import RequestFactory
+from rowers.views import checkworkoutuser,c2_open
+from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
+from rowers.forms import DocumentsForm,CNsummaryForm,RegistrationFormUniqueEmail
+import rowers.plots as plots
+import rowers.interactiveplots as iplots
+import datetime
+from rowingdata import rowingdata as rdata
+from rowingdata import rower as rrower
+from django.utils import timezone
+from rowers.rows import handle_uploaded_file
+from django.core.files.uploadedfile import SimpleUploadedFile
+from time import strftime,strptime,mktime,time,daylight
+import os
+from rowers.tasks import handle_makeplot
+from rowers.utils import serialize_list,deserialize_list
+from rowers.utils import NoTokenError
+from shutil import copyfile
+from nose.tools import assert_true
+from mock import Mock, patch
+from minimocktest import MockTestCase
+import pandas as pd
+import rowers.c2stuff as c2stuff
+
+import json
+import numpy as np
+
+from rowers import urls
+from rowers.views import error500_view,error404_view,error400_view,error403_view
+
+from rowers.dataprep import delete_strokedata
+
+from redis import StrictRedis
+redis_connection = StrictRedis()
+
+from rowers.tests.test_imports import mocked_requests
+
+
+from django_mailbox.models import Mailbox,MessageAttachment,Message
+
+from rowers.tests.mocks import mocked_sqlalchemy
+
+
+@pytest.mark.django_db
+class UploadTests(TestCase):
+ def setUp(self):
+ redis_connection.publish('tasks','KILL')
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ r = Rower.objects.create(user=u,gdproptin=True,
+ gdproptindate=timezone.now(),
+ getemailnotifications = False,
+ )
+
+ nu = datetime.datetime.now()
+ workoutsbox = Mailbox.objects.create(name='workouts')
+ workoutsbox.save()
+ failbox = Mailbox.objects.create(name='Failed')
+ failbox.save()
+ m = Message(mailbox=workoutsbox,
+ from_header = u.email,
+ subject = "3x(5min/2min)/r2 \r2",
+ body = """
+workout run
+ """)
+ m.save()
+ a2 = 'media/mailbox_attachments/colin2.csv'
+ copyfile('rowers/tests/testdata/emails/colin.csv',a2)
+ a = MessageAttachment(message=m,document=a2[6:])
+ a.save()
+
+ def tearDown(self):
+ for filename in os.listdir('media/mailbox_attachments'):
+ path = os.path.join('media/mailbox_attachments/',filename)
+ if not os.path.isdir(path):
+ try:
+ os.remove(path)
+ except (IOError,WindowsError):
+ pass
+
+ @patch('requests.get', side_effect=mocked_requests)
+ def test_email_workouttype(self, mock_get):
+ out = StringIO()
+ call_command('processemail', stdout=out, testing=True)
+ w = Workout.objects.get(id=1)
+ self.assertEqual(w.workouttype,'Run')
+
+#@pytest.mark.django_db
+class EmailTests(TestCase):
+ def setUp(self):
+ redis_connection.publish('tasks','KILL')
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ r = Rower.objects.create(user=u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+
+ nu = datetime.datetime.now()
+ workoutsbox = Mailbox.objects.create(name='workouts')
+ workoutsbox.save()
+ failbox = Mailbox.objects.create(name='Failed')
+ failbox.save()
+
+ for filename in os.listdir(u'rowers/tests/testdata/emails'):
+ m = Message(mailbox=workoutsbox,
+ from_header = u.email,
+ subject = filename,
+ body="""
+---
+workouttype: water
+boattype: 4x
+...
+ """)
+ m.save()
+ a2 = 'media/mailbox_attachments/'+filename
+ copyfile(u'rowers/tests/testdata/emails/'+filename,a2)
+ a = MessageAttachment(message=m,document=a2[6:])
+ a.save()
+
+ m = Message(mailbox=workoutsbox,
+ from_header = u.email,
+ subject = "3x(5min/2min)/r2 \r2",
+ body = """
+workout water
+ """)
+ m.save()
+ a2 = 'media/mailbox_attachments/colin2.csv'
+ copyfile('rowers/tests/testdata/emails/colin.csv',a2)
+ a = MessageAttachment(message=m,document=a2[6:])
+ a.save()
+
+
+ def tearDown(self):
+ for filename in os.listdir('media/mailbox_attachments'):
+ path = os.path.join('media/mailbox_attachments/',filename)
+ if not os.path.isdir(path):
+ try:
+ os.remove(path)
+ except (IOError,WindowsError):
+ pass
+
+ @patch('requests.get', side_effect=mocked_requests)
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.polarstuff.get_polar_notifications')
+ def test_emailprocessing(
+ self, mock_get, mocked_sqlalchemy,mocked_polar_notifications):
+ out = StringIO()
+ call_command('processemail', stdout=out,testing=True)
+ self.assertIn('Successfully processed email attachments',out.getvalue())
+
diff --git a/rowers/tests/testdata/colsfromdb.csv b/rowers/tests/testdata/colsfromdb.csv
new file mode 100644
index 00000000..e87e0ee6
--- /dev/null
+++ b/rowers/tests/testdata/colsfromdb.csv
@@ -0,0 +1,1399 @@
+,distance,fpace,workoutid,hr,pace,ftime,spm,time,workoutstate
+3,80,03:30.6,1,127.2857143,210600,01:02.5,18.89142857,62500,4
+4,100,03:25.9,1,132.5142857,205900,01:10.8,18.57714286,70799.99995,4
+5,120,03:00.5,1,135.2571429,180500,01:18.0,21.22571429,78000,4
+6,140,02:32.0,1,140,152000,01:24.1,24.74857143,84099.9999,4
+7,160,02:13.2,1,146.0857143,133200,01:29.4,27.41714286,89400.0001,4
+8,180,02:15.6,1,151.9142857,135600,01:34.8,27.46857143,94799.99995,4
+9,200,02:16.0,1,155.6571429,136000,01:40.3,27.24857143,100300,4
+10,220,02:23.8,1,157.1714286,143800,01:46.0,27.2,106000,4
+11,240,02:15.6,1,158.2571429,135600,01:51.4,27.46285714,111400.0001,4
+12,260,02:24.2,1,159.7428571,144200,01:57.2,27.71428571,117200,4
+13,280,02:11.7,1,161.1714286,131700,02:02.5,27.48285714,122500,4
+14,300,02:22.6,1,161.7428571,142600,02:08.2,27.20857143,128200,4
+15,320,02:18.7,1,162.2571429,138700,02:13.7,26.65142857,133700,4
+16,340,02:28.5,1,162.9142857,148500,02:19.6,26.58285714,139599.9999,4
+17,360,02:32.7,1,164,152700,02:25.8,26.19142857,145800,4
+18,380,02:26.9,1,165.0857143,146900,02:31.6,25.69428571,151599.9999,4
+19,400,02:31.6,1,165.8285714,151600,02:37.7,25.55714286,157700,4
+20,420,02:21.0,1,166.0857143,141000,02:43.3,25.83142857,163300,4
+21,440,02:33.5,1,166,153500,02:49.5,26.14857143,169500,4
+22,460,02:35.1,1,165.9142857,155100,02:55.7,26.13714286,175700,4
+23,480,02:25.3,1,166.2571429,145300,03:01.5,26.7,181500,4
+24,500,02:34.7,1,166.7428571,154700,03:07.7,26.58571429,187700,4
+25,520,02:34.7,1,167,154700,03:13.9,26.28857143,193900.0001,4
+26,540,02:32.0,1,167.2571429,152000,03:19.9,25.54,199900.0001,4
+27,560,02:41.0,1,167.6571429,161000,03:26.4,25.30571429,206400.0001,4
+28,580,02:35.1,1,168.3428571,155100,03:32.6,25.35142857,212599.9999,4
+29,600,02:29.2,1,168.8285714,149200,03:38.6,25.90571429,218599.9999,4
+30,620,02:33.1,1,168.7428571,153100,03:44.7,25.97142857,224700,4
+31,640,02:30.4,1,168.6,150400,03:50.7,25.86571429,230700,4
+32,660,02:29.6,1,168.4,149600,03:56.7,25.81142857,236700,4
+33,680,02:28.1,1,168.3428571,148100,04:02.6,25.72571429,242599.9999,4
+34,700,02:27.7,1,167.8285714,147700,04:08.5,25.31714286,248500,4
+35,720,02:30.0,1,168.2571429,150000,04:14.5,25.11714286,254500,4
+36,740,02:28.1,1,168.7428571,148100,04:20.4,25.24285714,260400.0001,4
+37,760,02:34.3,1,169.0857143,154300,04:26.6,25.32857143,266599.9999,4
+38,780,02:23.0,1,169,143000,04:32.3,25.67428571,272300,4
+39,800,02:26.1,1,169,146100,04:38.2,26.05142857,278200,4
+40,820,02:23.4,1,168.9142857,143400,04:43.9,26.58,283900.0001,4
+41,840,02:31.2,1,169.2571429,151200,04:49.9,26.56,289900.0001,4
+42,860,02:23.0,1,169.7428571,143000,04:55.7,26.81714286,295700,4
+43,880,02:30.0,1,170.0857143,150000,05:01.7,27.07714286,301700,4
+44,900,02:26.5,1,170,146500,05:07.5,27.39428571,307500,4
+45,920,02:20.6,1,170,140600,05:13.1,27.06285714,313099.9999,4
+46,940,02:24.2,1,170,144200,05:18.9,26.73714286,318900.0001,4
+47,960,02:18.3,1,170,138300,05:24.4,26.76,324400.0001,4
+48,980,02:19.9,1,170,139900,05:30.0,26.83428571,330000,4
+49,1000,02:16.7,1,169.9142857,136700,05:35.5,27.01714286,335500,4
+50,1020,02:22.2,1,170.2571429,142200,05:41.2,27.38857143,341200,4
+51,1040,02:23.4,1,170.7428571,143400,05:46.9,27.62857143,346900.0001,4
+52,1060,02:15.6,1,171,135600,05:52.3,27.37142857,352300,4
+53,1080,02:18.3,1,171.2571429,138300,05:57.9,27.40285714,357900.0001,4
+54,1100,02:16.7,1,171.7428571,136700,06:03.3,27.36571429,363300,4
+55,1120,02:24.9,1,172.0857143,144900,06:09.1,27.08285714,369099.9999,4
+56,1140,02:18.7,1,172,138700,06:14.7,26.83142857,374700,4
+57,1160,02:21.8,1,172.0857143,141800,06:20.4,26.92285714,380400.0001,4
+58,1180,02:14.4,1,171.7428571,134400,06:25.7,27.00285714,385700,4
+59,1200,02:18.7,1,171.2571429,138700,06:31.3,27.36857143,391300,4
+60,1220,02:10.5,1,170.9142857,130500,06:36.5,27.42571429,396500,4
+61,1240,02:10.9,1,170.9142857,130900,06:41.7,26.94571429,401700,4
+62,1260,02:15.6,1,171.2571429,135600,06:47.2,26.62857143,407200,4
+63,1280,02:12.4,1,171.7428571,132400,06:52.5,26.80285714,412500,4
+64,1300,02:13.2,1,172.0857143,133200,06:57.8,27.13714286,417800,4
+65,1320,02:09.3,1,172,129300,07:03.0,27.50857143,423000,4
+66,1340,02:06.2,1,171.9142857,126200,07:08.0,27.71142857,428000,4
+67,1360,02:16.0,1,172.2571429,136000,07:13.4,27.73142857,433400.0001,4
+68,1380,02:10.9,1,172.7428571,130900,07:18.7,27.68857143,438700,4
+69,1400,02:20.2,1,173.0857143,140200,07:24.3,27.54857143,444300,4
+70,1420,02:09.3,1,173,129300,07:29.5,27.03428571,449500,4
+71,1440,02:06.2,1,172.9142857,126200,07:34.5,26.83714286,454500,4
+72,1460,02:16.0,1,173.2571429,136000,07:39.9,26.74285714,459900.0001,4
+73,1480,02:10.9,1,173.7428571,130900,07:45.2,26.92571429,465200,4
+74,1500,02:10.5,1,174.0857143,130500,07:50.4,26.86571429,470400.0001,4
+75,1520,02:15.6,1,173.9142857,135600,07:55.8,26.92285714,475800,4
+76,1540,02:16.0,1,174.2571429,136000,08:01.3,26.84857143,481300,4
+77,1560,02:20.2,1,174.7428571,140200,08:06.9,26.97428571,486900.0001,4
+78,1580,02:18.3,1,175.0857143,138300,08:12.4,26.74857143,492400.0001,4
+79,1600,02:25.3,1,175.0857143,145300,08:18.2,26.52857143,498200,4
+80,1620,02:28.1,1,174.7428571,148100,08:24.1,26.40571429,504099.9999,4
+81,1640,02:19.9,1,174.2571429,139900,08:29.7,26.29142857,509700,4
+82,1660,02:12.0,1,173.9142857,132000,08:35.0,26.10857143,515000,4
+83,1680,02:20.2,1,174,140200,08:40.6,26.52285714,520599.9999,4
+84,1700,02:18.3,1,174,138300,08:46.1,26.82285714,526099.9999,4
+85,1720,02:24.9,1,174,144900,08:51.9,26.70571429,531900.0001,4
+86,1740,02:17.9,1,174,137900,08:57.5,26.29142857,537500,4
+87,1760,02:26.9,1,174,146900,09:03.3,26.23142857,543300,4
+88,1780,02:23.4,1,173.9142857,143400,09:09.1,26.46285714,549099.9999,4
+89,1800,02:26.9,1,174.2571429,146900,09:14.9,26.78,554900.0001,4
+90,1820,02:28.1,1,174.7428571,148100,09:20.9,26.66285714,560900.0001,4
+91,1840,02:20.2,1,175.0857143,140200,09:26.5,26.38285714,566500,4
+92,1860,02:15.2,1,175,135200,09:31.9,26.30285714,571900.0001,4
+93,1880,02:20.6,1,174.9142857,140600,09:37.5,26.46,577500,4
+94,1900,02:13.2,1,175.3428571,133200,09:42.8,26.49142857,582800,4
+95,1920,02:19.1,1,175.4,139100,09:48.4,26.88571429,588400.0001,4
+96,1940,02:10.5,1,175.6,130500,09:53.6,27.38285714,593599.9999,4
+97,1960,02:14.8,1,175.6571429,134800,09:59.0,27.04,599000,4
+98,1980,02:16.7,1,176.0857143,136700,10:04.5,26.7,604500,4
+99,2000,02:16.7,1,176,136700,10:09.9,26.51142857,609900.0001,4
+100,2020,02:18.3,1,176,138300,10:15.5,26.86571429,615500,4
+101,2040,02:13.2,1,176,133200,10:20.8,27.09142857,620800,4
+102,2060,02:21.0,1,175.9142857,141000,10:26.4,27.39428571,626400.0001,4
+103,2080,02:18.7,1,176.3428571,138700,10:32.0,27.6,632000,4
+104,2100,02:22.2,1,176.4,142200,10:37.7,27.51714286,637700,4
+105,2120,02:15.6,1,176.6,135600,10:43.1,27.26857143,643099.9999,4
+106,2140,02:19.5,1,176.6571429,139500,10:48.7,27.10571429,648700,4
+107,2160,02:14.0,1,177.0857143,134000,10:54.0,27.24285714,654000,4
+108,2180,02:16.3,1,177,136300,10:59.5,27.28571429,659500,4
+109,2200,02:07.7,1,177,127700,11:04.6,27.29428571,664599.9999,4
+110,2220,02:14.0,1,177,134000,11:10.0,27.52857143,670000,4
+111,2240,02:09.7,1,176.9142857,129700,11:15.1,28.00571429,675099.9999,4
+112,2260,02:15.2,1,177.2571429,135200,11:20.6,28.47142857,680599.9999,4
+113,2280,02:09.7,1,177.7428571,129700,11:25.7,28.77428571,685700,4
+114,2300,02:20.6,1,178.0857143,140600,11:31.4,28.68571429,691400.0001,4
+115,2320,02:20.2,1,177.9142857,140200,11:37.0,28.40571429,697000,4
+116,2340,02:19.9,1,178.2571429,139900,11:42.6,28.06857143,702599.9999,4
+117,2360,02:26.1,1,178.7428571,146100,11:48.4,27.66571429,708400.0001,4
+118,2380,02:15.2,1,179.0857143,135200,11:53.8,27.4,713800,4
+119,2400,02:16.3,1,179,136300,11:59.3,27.36857143,719300,4
+120,2420,02:09.7,1,179,129700,12:04.5,27.51428571,724500,4
+121,2440,02:14.4,1,179,134400,12:09.8,27.82857143,729800,4
+122,2460,02:13.6,1,179,133600,12:15.2,27.65714286,735200,4
+123,2480,02:28.5,1,178.9142857,148500,12:21.1,28.05142857,741099.9999,4
+124,2500,02:25.7,1,179.3428571,145700,12:26.9,28.2,746900.0001,4
+125,2520,02:18.7,1,179.4857143,138700,12:32.5,27.49142857,752500,4
+126,2540,02:30.8,1,179.4285714,150800,12:38.5,26.26285714,758500,4
+127,2560,02:25.7,1,178.5714286,145700,12:44.4,25.65428571,764400.0001,4
+128,2580,02:35.9,1,178.6,155900,12:50.6,25.76,770599.9999,4
+129,2600,02:29.2,1,178.4,149200,12:56.6,25.66857143,776599.9999,4
+130,2620,02:26.5,1,178.3428571,146500,13:02.4,25.59142857,782400.0001,4
+131,2640,02:24.9,1,177.9142857,144900,13:08.2,25.26,788200,4
+132,2660,02:30.0,1,178,150000,13:14.2,25.70571429,794200,4
+133,2680,02:25.3,1,178,145300,13:20.0,26.26571429,800000,4
+134,2700,02:22.6,1,178,142600,13:25.7,26.32,805700,4
+135,2720,02:32.0,1,178,152000,13:31.8,25.91714286,811800,4
+136,2740,02:26.1,1,178,146100,13:37.6,25.96857143,817599.9999,4
+137,2760,02:29.2,1,178,149200,13:43.6,26.02,823599.9999,4
+138,2780,02:23.4,1,178.0857143,143400,13:49.4,26.26571429,829400.0001,4
+139,2800,02:26.5,1,177.6571429,146500,13:55.2,26.35142857,835200,4
+140,2820,02:19.1,1,177.5142857,139100,14:00.8,26.14857143,840800,4
+141,2840,02:25.7,1,177.6571429,145700,14:06.6,26.26857143,846599.9999,4
+142,2860,02:18.7,1,178.0857143,138700,14:12.1,27.1,852099.9999,4
+143,2880,02:19.5,1,178,139500,14:17.7,28.33142857,857700,4
+144,2900,02:28.8,1,178,148800,14:23.7,28.55714286,863700,4
+145,2920,02:32.4,1,178,152400,14:29.8,28.26571429,869800,4
+146,2940,02:21.0,1,178,141000,14:35.4,27.36,875400.0001,4
+147,2960,02:23.0,1,178,143000,14:41.1,27.18571429,881099.9999,4
+148,2980,02:30.8,1,177.9142857,150800,14:47.2,27.18285714,887200,4
+149,3000,02:27.7,1,178.3428571,147700,14:53.1,27.18571429,893099.9999,4
+150,3020,02:25.7,1,178.4,145700,14:58.9,26.68285714,898900.0001,4
+151,3040,02:23.0,1,178.6857143,143000,15:04.6,26.50285714,904599.9999,4
+152,3060,02:23.8,1,178.4,143800,15:10.4,26.31142857,910400.0001,4
+153,3080,02:17.1,1,178.3428571,137100,15:15.9,26.28,915900.0001,4
+154,3100,02:23.8,1,177.9142857,143800,15:21.6,26.49142857,921599.9999,4
+155,3120,02:17.1,1,178,137100,15:27.1,26.78857143,927099.9999,4
+156,3140,02:21.4,1,178,141400,15:32.7,26.59142857,932700,4
+157,3160,02:19.5,1,178,139500,15:38.3,26.32857143,938300,4
+158,3180,02:24.2,1,178,144200,15:44.1,26.28,944099.9999,4
+159,3200,02:17.9,1,177.9142857,137900,15:49.6,26.52857143,949599.9999,4
+160,3220,02:23.0,1,178.3428571,143000,15:55.3,26.70571429,955300,4
+161,3240,02:23.8,1,178.4857143,143800,16:01.1,26.63142857,961099.9999,4
+162,3260,02:31.6,1,178.4285714,151600,16:07.1,26.42857143,967099.9999,4
+163,3280,02:28.8,1,177.6571429,148800,16:13.1,26.63428571,973099.9999,4
+164,3300,02:23.4,1,177.2571429,143400,16:18.8,26.91142857,978800,4
+165,3320,02:29.6,1,176.8285714,149600,16:24.8,27.17428571,984800,4
+166,3340,02:19.9,1,177.2571429,139900,16:30.4,26.91428571,990400.0001,4
+167,3360,02:19.1,1,177.7428571,139100,16:36.0,26.72571429,996000,4
+168,3380,02:20.2,1,178.0857143,140200,16:41.6,26.74857143,1001600,4
+169,3400,02:22.6,1,177.9142857,142600,16:47.3,27.23142857,1007300,4
+170,3420,02:24.5,1,178.3428571,144500,16:53.1,27.3,1013100,4
+171,3440,02:19.5,1,178.4857143,139500,16:58.6,27,1018600,4
+172,3460,02:25.7,1,178.3428571,145700,17:04.5,26.54,1024500,4
+173,3480,02:13.6,1,177.9142857,133600,17:09.8,26.55714286,1029800,4
+174,3500,02:18.3,1,178,138300,17:15.3,26.65714286,1035300,4
+175,3520,02:16.0,1,178,136000,17:20.8,26.85714286,1040800,4
+176,3540,02:16.0,1,178,136000,17:26.2,26.88,1046200,4
+177,3560,02:22.6,1,178,142600,17:31.9,27.08285714,1051900,4
+178,3580,02:21.8,1,177.9142857,141800,17:37.6,27.36285714,1057600,4
+179,3600,02:17.1,1,178.2571429,137100,17:43.1,27.56,1063100,4
+180,3620,02:20.2,1,178.7428571,140200,17:48.7,27.68,1068700,4
+181,3640,02:16.3,1,179.0857143,136300,17:54.1,27.63142857,1074100,4
+182,3660,02:20.6,1,179,140600,17:59.8,27.75142857,1079800,4
+183,3680,02:17.9,1,179,137900,18:05.3,27.38571429,1085300,4
+184,3700,02:21.0,1,179,141000,18:10.9,27.30285714,1090900,4
+185,3720,02:16.3,1,179,136300,18:16.4,27.20571429,1096400,4
+186,3740,02:26.9,1,179,146900,18:22.2,27.24,1102200,4
+187,3760,02:32.4,1,179,152400,18:28.3,26.96571429,1108300,4
+188,3780,02:27.7,1,179,147700,18:34.2,26.4,1114200,4
+189,3800,02:33.5,1,178.9142857,153500,18:40.4,26.11428571,1120400,4
+190,3820,02:22.2,1,179.2571429,142200,18:46.1,26.40857143,1126100,4
+191,3840,02:22.2,1,179.7428571,142200,18:51.8,26.98285714,1131800,4
+192,3860,02:30.4,1,180.1714286,150400,18:57.8,27.06285714,1137800,4
+193,3880,02:22.6,1,179.7428571,142600,19:03.5,26.66571429,1143500,4
+194,3900,02:33.5,1,179.2571429,153500,19:09.6,26.30857143,1149600,4
+195,3920,02:29.2,1,178.8285714,149200,19:15.6,26.57714286,1155600,4
+196,3940,02:24.5,1,179.2571429,144500,19:21.4,27.16571429,1161400,4
+197,3960,02:23.4,1,179.7428571,143400,19:27.1,27.26285714,1167100,4
+198,3980,02:17.5,1,180.0857143,137500,19:32.6,27.38571429,1172600,4
+199,4000,02:18.7,1,179.9142857,138700,19:38.2,28.15714286,1178200,4
+200,4020,02:21.4,1,180.2571429,141400,19:43.8,28.81428571,1183800,4
+201,4040,02:18.7,1,180.7428571,138700,19:49.4,29.13714286,1189400,4
+202,4060,02:23.0,1,181.0857143,143000,19:55.1,28.86857143,1195100,4
+203,4080,02:19.5,1,181,139500,20:00.7,28.32857143,1200700,4
+204,4100,02:12.0,1,181,132000,20:05.9,28.18857143,1205900,4
+205,4120,02:14.4,1,181,134400,20:11.3,28.54571429,1211300,4
+206,4140,02:10.1,1,181,130100,20:16.5,27.95714286,1216500,4
+207,4160,02:17.9,1,181,137900,20:22.0,27.20857143,1222000,4
+208,4180,02:10.9,1,180.9142857,130900,20:27.3,27.03142857,1227300,4
+209,4200,02:16.7,1,182.2,136700,20:32.7,27.56285714,1232700,4
+210,4220,02:15.2,1,177.9714286,135200,20:38.1,27.39428571,1238100,4
+211,4240,02:23.4,1,176.7428571,143400,20:43.9,27.29714286,1243900,4
+212,4260,02:14.0,1,178.2285714,134000,20:49.2,27.35714286,1249200,4
+213,4280,02:20.6,1,182.9428571,140600,20:54.9,27.64,1254900,4
+214,4300,02:16.0,1,182,136000,21:00.3,27.76857143,1260300,4
+215,4320,02:19.1,1,182,139100,21:05.9,27.76571429,1265900,4
+216,4340,02:16.0,1,182,136000,21:11.3,27.46285714,1271300,4
+217,4360,02:18.3,1,182,138300,21:16.8,27.41714286,1276800,4
+218,4380,02:12.0,1,182,132000,21:22.1,27.64285714,1282100,4
+219,4400,02:17.5,1,182,137500,21:27.6,28.02857143,1287600,4
+220,4420,02:12.8,1,182,132800,21:32.9,27.86285714,1292900,4
+221,4440,02:19.5,1,182,139500,21:38.5,27.75428571,1298500,4
+222,4460,02:17.9,1,182,137900,21:44.0,27.56285714,1304000,4
+223,4480,02:13.6,1,182,133600,21:49.4,27.65428571,1309400,4
+224,4500,02:17.1,1,182,137100,21:54.8,27.64571429,1314800,4
+225,4520,02:16.3,1,181.9142857,136300,22:00.3,27.66857143,1320300,4
+226,4540,02:20.2,1,182.2571429,140200,22:05.9,27.82,1300.0001,4
+227,4560,02:14.4,1,182.7428571,134400,22:11.3,27.80857143,1331300,4
+228,4580,02:18.7,1,183.0857143,138700,22:16.8,27.68285714,1336800,4
+229,4600,02:12.4,1,183,132400,22:22.1,27.39428571,1342100,4
+230,4620,02:19.1,1,183,139100,22:27.7,27.61428571,1347700,4
+231,4640,02:11.7,1,183,131700,22:32.9,27.66,1352900,4
+232,4660,02:15.2,1,183,135200,22:38.4,27.98285714,1358400,4
+233,4680,02:10.9,1,183,130900,22:43.6,27.84,1363600,4
+234,4700,02:12.8,1,182.9142857,132800,22:48.9,27.81714286,1368900,4
+235,4720,02:13.6,1,183.2571429,133600,22:54.2,27.81428571,1374200,4
+236,4740,02:13.6,1,183.7428571,133600,22:59.6,27.78571429,1379600,4
+237,4760,02:18.7,1,184.0857143,138700,23:05.1,27.76,1385100,4
+238,4780,02:18.3,1,184,138300,23:10.7,27.95142857,1390700,4
+239,4800,02:07.7,1,184,127700,23:15.8,28.25714286,1395800,4
+240,4820,02:11.3,1,184,131300,23:21.0,28.85142857,1401000,4
+241,4840,02:09.3,1,183.9142857,129300,23:26.2,29.72285714,1406200,4
+242,4860,02:09.3,1,184.2571429,129300,23:31.4,30.53142857,1411400,4
+243,4880,02:03.1,1,184.8285714,123100,23:36.3,31.17142857,1416300,4
+244,4900,02:12.8,1,185.1714286,132800,23:41.6,28.64857143,1421600,4
+245,4920,03:32.5,1,183.5714286,212500,23:50.1,23.55428571,1430100,4
+246,4940,04:06.5,1,181.4571429,246500,24:00.0,17.26571429,1440000,4
+247,4960,04:53.0,1,172.3142857,293000,24:11.7,14.90285714,1451700,4
+249,5000,03:50.9,1,152.7714286,230900,24:33.6,18.27714286,1473600,4
+250,5020,03:38.8,1,150.2857143,218800,24:42.3,20.19142857,1482300,4
+251,5040,02:58.5,1,146.8,178500,24:49.5,18.47142857,1489500,4
+252,5060,03:29.0,1,146.4571429,209000,24:57.8,18.4,1497800,4
+253,5080,02:51.1,1,145.5428571,171100,25:04.7,17.55714286,1504700,4
+254,5100,03:15.7,1,144.6,195700,25:12.5,19.71714286,1512500,4
+255,5120,02:49.2,1,143.3428571,169200,25:19.3,20.26571429,1519300,4
+256,5140,02:45.2,1,143.4857143,165200,25:25.9,21.81714286,1525900,4
+257,5160,03:00.5,1,143.1714286,180500,25:33.1,21.63714286,1533100,4
+258,5180,02:47.2,1,141.9142857,167200,25:39.8,21.34,1539800,4
+259,5200,02:57.7,1,141.1714286,177700,25:46.9,21.07714286,1546900,4
+260,5220,02:53.5,1,141.3428571,173500,25:53.8,21.40285714,1553800,4
+261,5240,03:00.9,1,139.5428571,180900,26:01.1,20.84571429,1561100,4
+263,5280,04:33.1,1,136.4571429,273100,26:25.6,21.45714286,1585600,4
+264,5300,03:21.6,1,135.3428571,201600,26:33.7,20.42857143,1593700,4
+265,5320,03:02.0,1,133.3428571,182000,26:41.0,18.96857143,1601000,4
+266,5340,02:43.7,1,134.0857143,163700,26:47.5,20.21428571,1607500,4
+267,5360,02:39.0,1,135.5714286,159000,26:53.9,20.88857143,1613900,4
+268,5380,02:36.3,1,136.0857143,156300,27:00.1,20.68285714,1620100,4
+269,5400,02:37.8,1,136.2571429,157800,27:06.4,20.77142857,1626400,4
+270,5420,02:33.1,1,136.6571429,153100,27:12.6,20.93714286,1639.9999,4
+271,5440,02:36.7,1,137.2571429,156700,27:18.8,20.66,1638800,4
+272,5460,02:44.9,1,138,164900,27:25.4,20.41714286,1645400,4
+273,5480,02:42.1,1,138.7428571,162100,27:31.9,20.78,1651900,4
+274,5500,02:43.7,1,139.1714286,163700,27:38.5,21.37714286,1658500,4
+275,5520,02:36.7,1,140.1714286,156700,27:44.7,20.03142857,1664700,4
+276,5540,02:49.5,1,141.8285714,169500,27:51.5,19.53142857,1671500,4
+277,5560,02:52.7,1,142.9142857,172700,27:58.4,19.91142857,1678400,4
+278,5580,02:44.1,1,143.0857143,164100,28:05.0,21.20571429,1685000,4
+279,5600,02:44.5,1,143,164500,28:11.5,20.60857143,1691500,4
+280,5620,02:53.1,1,143.0857143,173100,28:18.5,20.82,1698500,4
+281,5640,02:40.6,1,142.8285714,160600,28:24.9,20.61714286,1704900,4
+282,5660,03:00.1,1,142.0857143,180100,28:32.1,19.02285714,1712100,4
+283,5680,03:15.3,1,141,195300,28:39.9,17.61714286,1719900,4
+284,5700,03:25.5,1,140.0857143,205500,28:48.1,18.15714286,1728100,4
+285,5720,03:13.0,1,138.7428571,193000,28:55.8,19.87142857,1735800,4
+286,5740,03:05.2,1,137.2571429,185200,29:03.2,19.95142857,1743200,4
+287,5760,02:55.0,1,135.8285714,175000,29:10.2,19.34,1750200,4
+288,5780,03:13.8,1,135.1714286,193800,29:18.0,19.10857143,1758000,4
+289,5800,03:05.2,1,135,185200,29:25.4,19.75428571,1765400,4
+290,5820,02:47.6,1,134.7428571,167600,29:32.1,19.80857143,1772100,4
+291,5840,02:57.7,1,134.1714286,177700,29:39.2,19.02285714,1779200,4
+292,5860,03:04.8,1,134.2571429,184800,29:46.6,17.70571429,1786600,4
+293,5880,03:01.7,1,134.4857143,181700,29:53.9,16.57714286,1793900,4
+294,5900,03:25.5,1,134.1714286,205500,30:02.1,17.24857143,1802100,4
+295,5920,02:58.9,1,134.4285714,178900,30:09.2,17.98857143,1809200,4
+296,5940,02:35.1,1,135.4857143,155100,30:15.5,19.07714286,1815500,4
+297,5960,02:29.6,1,136.0857143,149600,30:21.4,17.96285714,1821400,4
+298,5980,02:36.7,1,136.2571429,156700,30:27.7,18.49714286,1827700,4
+299,6000,03:03.6,1,136.7428571,183600,30:35.0,15.02857143,1835000,4
+300,6020,03:22.7,1,137.1714286,202700,30:43.2,13.74285714,1843200,4
+301,6040,03:20.4,1,136.7428571,200400,30:51.2,15.00571429,1851200,4
+302,6060,02:53.8,1,136.1714286,173800,30:58.1,19.22285714,1858100,4
+303,6080,02:38.2,1,136,158200,31:04.5,20.82,1864500,4
+304,6100,02:30.0,1,137.1714286,150000,31:10.5,20.95428571,1870500,4
+305,6120,02:29.6,1,138.6571429,149600,31:16.4,21.24857143,1876400,4
+306,6140,02:28.5,1,140.3428571,148500,31:22.4,21.18857143,1882400,4
+307,6160,02:27.3,1,141.9142857,147300,31:28.3,21.90857143,1888300,4
+308,6180,02:41.3,1,142.5714286,161300,31:34.7,17.56571429,1894700,4
+309,6200,03:59.9,1,142.6,239900,31:44.3,15.94,1904300,4
+310,6220,03:55.2,1,142.7428571,235200,31:53.7,17.42285714,1913700,4
+311,6240,02:41.7,1,142.8285714,161700,32:00.2,22.17142857,1920200,4
+312,6260,02:26.9,1,143.6285714,146900,32:06.1,22.28571429,1926100,4
+313,6280,03:09.1,1,138.0571429,189100,32:13.6,19.39714286,1933600,4
+315,6320,04:54.2,1,122.2285714,294200,32:51.5,14.22,1971500,4
+316,6340,04:40.1,1,123.2571429,280100,33:02.7,16.01428571,1982700,4
+317,6360,03:45.4,1,124.2285714,225400,33:11.7,16.48,1991700,4
+318,6380,03:25.9,1,125.8571429,205900,33:19.9,16.66571429,1999900,4
+319,6400,03:41.5,1,127.6571429,221500,33:28.8,16.66285714,2008800,4
+320,6420,03:34.5,1,128.4,214500,33:37.3,17.29142857,2017300,4
+321,6440,03:30.2,1,127.6857143,210200,33:45.8,16.38285714,2025800,4
+322,6460,03:04.8,1,128,184800,33:53.1,16.24,2033100,4
+323,6480,02:45.2,1,130,165200,33:59.8,17.13142857,2039800,4
+324,6500,04:58.8,1,130.7428571,298800,34:11.7,17.76857143,2051700,4
+325,6520,04:37.0,1,128.6571429,277000,34:22.8,17.44857143,2062800,4
+326,6540,04:17.0,1,125.6,257000,34:33.1,15.90571429,2073100,4
+327,6560,03:42.3,1,123.6571429,222300,34:42.0,17.48,2082000,4
+328,6580,03:22.4,1,124.4285714,202400,34:50.0,19.24285714,2090000,4
+329,6600,02:48.4,1,126.8285714,168400,34:56.8,20.73428571,2096800,4
+330,6620,02:51.5,1,129.7428571,171500,35:03.6,21.06,2103600,4
+331,6640,02:35.9,1,132.6857143,155900,35:09.9,24.12,2109900,4
+332,6660,02:42.5,1,133.7142857,162500,35:16.4,15.77428571,2116400,4
+334,6700,04:07.3,1,134.2285714,247300,35:34.6,11.19142857,2134600,4
+335,6720,03:03.6,1,134.0857143,183600,35:42.0,20.16,2142000,4
+336,6740,03:04.8,1,131.8285714,184800,35:49.4,19.37714286,2149400,4
+337,6760,03:04.8,1,130.7714286,184800,35:56.8,18.00571429,2156800,4
+338,6780,03:08.7,1,130.0571429,188700,36:04.3,17.85428571,2164300,4
+339,6800,03:06.0,1,129.5142857,186000,36:11.7,18.40571429,2171700,4
+340,6820,03:01.7,1,129.0857143,181700,36:19.0,19.38285714,2179000,4
+341,6840,02:51.5,1,129.7428571,171500,36:25.9,18.68571429,2185900,4
+342,6860,02:54.2,1,130.1714286,174200,36:32.8,18.47142857,2192800,4
+343,6880,02:55.0,1,129.7428571,175000,36:39.8,18.82285714,2199800,4
+344,6900,03:43.8,1,129.1714286,223800,36:48.8,17.32285714,2208800,4
+345,6920,03:35.6,1,129.3428571,215600,36:57.4,16.45428571,2217400,4
+346,6940,03:09.9,1,129.3142857,189900,37:05.0,16.78571429,2225000,4
+347,6960,03:14.2,1,128.2571429,194200,37:12.8,18.57428571,2232800,4
+348,6980,03:18.8,1,127.3428571,198800,37:20.7,18.82,2240700,4
+349,7000,03:27.4,1,127.7428571,207400,37:29.0,18.33428571,2249000,4
+350,7020,03:06.0,1,127.9142857,186000,37:36.5,16.97142857,2256500,4
+351,7040,03:07.5,1,127,187500,37:44.0,17.31428571,2264000,4
+352,7060,03:05.2,1,126.0857143,185200,37:51.4,15.52857143,2271400,4
+353,7080,03:42.7,1,126.1714286,222700,38:00.3,15.28285714,2280300,4
+354,7100,03:29.4,1,126.8285714,209400,38:08.6,16.79714286,2288600,4
+355,7120,03:10.2,1,126.5714286,190200,38:16.3,18.70571429,2296300,4
+356,7140,03:19.2,1,126.9428571,199200,38:24.2,17.78285714,2304200,4
+357,7160,02:56.2,1,128.4857143,176200,38:31.3,18.33142857,2311300,4
+358,7180,02:53.8,1,129.7428571,173800,38:38.2,20.31714286,2318200,4
+359,7200,02:55.8,1,129.1714286,175800,38:45.3,20.25714286,2325300,4
+360,7220,02:43.7,1,129.3428571,163700,38:51.8,20.09714286,2331800,4
+361,7240,02:42.9,1,130.6571429,162900,38:58.3,20.16571429,2338300,4
+362,7260,02:39.4,1,132.1714286,159400,39:04.7,20.67142857,2344700,4
+363,7280,02:35.9,1,132.5714286,155900,39:10.9,21.14857143,2350900,4
+364,7300,02:41.3,1,133.6857143,161300,39:17.4,20.89142857,2357400,4
+365,7320,02:35.9,1,135.6571429,155900,39:23.6,20.22285714,2363600,4
+366,7340,02:37.8,1,137.9142857,157800,39:29.9,20.23428571,2369900,4
+367,7360,02:37.0,1,139.0857143,157000,39:36.2,20.97142857,2376200,4
+368,7380,02:36.7,1,140,156700,39:42.5,20.93714286,2382500,4
+369,7400,02:35.1,1,141.1714286,155100,39:48.7,20.72571429,2388700,4
+370,7420,02:43.3,1,141.5714286,163300,39:55.2,19.34571429,2395200,4
+371,7440,02:59.3,1,141.3428571,179300,40:02.4,19.09714286,2402400,4
+372,7460,03:03.6,1,140.9142857,183600,40:09.7,19.59142857,2409700,4
+373,7480,02:40.6,1,140.9142857,160600,40:16.1,21.23142857,2416100,4
+374,7500,02:48.8,1,141.2571429,168800,40:22.9,21.16571429,2422900,4
+375,7520,02:39.0,1,141.8285714,159000,40:29.3,21.35428571,2429300,4
+376,7540,02:33.9,1,141.9142857,153900,40:35.4,21.19142857,2435400,4
+377,7560,02:47.6,1,141.0857143,167600,40:42.1,20.27428571,2442100,4
+378,7580,03:02.0,1,140.1714286,182000,40:49.4,19.01714286,2449400,4
+379,7600,03:09.5,1,138.4857143,189500,40:57.0,16.88,2457000,4
+380,7620,03:34.9,1,136.6,214900,41:05.6,14.68,2465600,4
+381,7640,03:27.4,1,134.5714286,207400,41:13.9,15.78285714,2473900,4
+382,7660,03:04.8,1,133.3428571,184800,41:21.3,18.14857143,2481300,4
+383,7680,03:11.8,1,131.8285714,191800,41:28.9,18.93428571,2488900,4
+384,7700,03:24.3,1,129.8285714,204300,41:37.1,20.09714286,2497100,4
+385,7720,03:25.9,1,127.2571429,205900,41:45.3,22.05428571,2505300,4
+386,7740,03:39.2,1,124.7428571,219200,41:54.1,20.40571429,2514100,4
+387,7760,04:09.6,1,123.3428571,249600,42:04.1,17.76,2524100,4
+388,7780,03:13.8,1,122.8285714,193800,42:11.8,17.50857143,2531800,4
+389,7800,03:03.2,1,122.7428571,183200,42:19.2,18.88571429,2539200,4
+390,7820,02:44.5,1,123.6857143,164500,42:25.7,19.37142857,2545700,4
+391,7840,02:35.5,1,125.5714286,155500,42:32.0,19.36,2552000,4
+392,7860,02:46.4,1,126.6571429,166400,42:38.6,18.94571429,2558600,4
+393,7880,02:53.1,1,126.5142857,173100,42:45.5,18.05714286,2565500,4
+394,7900,02:58.5,1,127,178500,42:52.7,18.42571429,2572700,4
+395,7920,02:50.7,1,127.5714286,170700,42:59.5,19.13428571,2579500,4
+396,7940,03:16.1,1,127.4285714,196100,43:07.3,18.88857143,2587300,4
+397,7960,03:12.6,1,126.6571429,192600,43:15.0,17.72285714,2595000,4
+398,7980,03:09.9,1,127.4571429,189900,43:22.6,17.56571429,2602600,4
+399,8000,03:21.2,1,120.9428571,201200,43:30.7,17.82571429,2610700,4
+400,8020,03:07.1,1,119.8,187100,43:38.2,17.67142857,2618200,4
+401,8040,02:55.0,1,122.6,175000,43:45.2,17.52571429,2625200,4
+402,8060,03:00.5,1,128.0285714,180500,43:52.4,19.36571429,2632400,4
+404,8100,03:02.8,1,125.4,182800,44:11.9,19.29714286,2651900,4
+405,8120,02:57.0,1,125,177000,44:19.0,18.31428571,2659000,4
+406,8140,03:05.6,1,124.5142857,185600,44:26.4,18.44285714,2666400,4
+407,8160,03:12.6,1,124.5714286,192600,44:34.1,18.39142857,2674100,4
+408,8180,03:02.0,1,123.8285714,182000,44:41.4,15.79714286,2681400,4
+409,8200,03:57.5,1,122.3428571,237500,44:50.9,15.76,2690900,4
+410,8220,03:24.3,1,122.0857143,204300,44:59.1,17.60571429,2699100,4
+411,8240,03:09.9,1,122.5714286,189900,45:06.7,19.90857143,2706700,4
+412,8260,02:55.4,1,123.3428571,175400,45:13.7,19.60857143,2713700,4
+413,8280,02:48.8,1,125.1714286,168800,45:20.5,20.53428571,2720500,4
+414,8300,02:45.6,1,127.5714286,165600,45:27.1,21.03714286,2727100,4
+415,8320,02:48.8,1,129.0857143,168800,45:33.8,20.94,2733800,4
+416,8340,02:45.2,1,130.3428571,165200,45:40.4,20.74285714,2740400,4
+417,8360,02:44.5,1,131.4857143,164500,45:47.0,21.22285714,2747000,4
+418,8380,02:44.1,1,132.4285714,164100,45:53.6,20.41428571,2753600,4
+419,8400,02:46.8,1,132.5714286,166800,46:00.3,20.10857143,2760300,4
+420,8420,02:39.4,1,133.6857143,159400,46:06.6,20.84,2766600,4
+421,8440,02:49.9,1,134.2285714,169900,46:13.4,19.14857143,2773400,4
+422,8460,03:00.9,1,134.4285714,180900,46:20.7,18.04285714,2780700,4
+423,8480,02:56.6,1,134.0857143,176600,46:27.7,17.96285714,2787700,4
+424,8500,02:55.0,1,133.4857143,175000,46:34.7,19.39428571,2794700,4
+425,8520,02:56.2,1,132.5142857,176200,46:41.8,19.5,2801800,4
+426,8540,02:53.8,1,131.7428571,173800,46:48.7,19.76285714,2808700,4
+427,8560,02:46.4,1,132.4285714,166400,46:55.4,19.37714286,2815400,4
+428,8580,02:42.5,1,132.3142857,162500,47:01.9,19.22571429,2821900,4
+429,8600,02:57.0,1,131.3428571,177000,47:09.0,19.37428571,2829000,4
+430,8620,03:09.9,1,130,189900,47:16.5,19.66571429,2836500,4
+431,8640,02:49.9,1,130.3428571,169900,47:23.3,18.85714286,2843300,4
+432,8660,02:46.4,1,130.4,166400,47:30.0,19.05714286,2850000,4
+433,8680,02:50.3,1,129.0857143,170300,47:36.8,17.12285714,2856800,4
+434,8700,02:58.1,1,127.4285714,178100,47:43.9,17.06571429,2863900,4
+435,8720,03:07.9,1,126.4857143,187900,47:51.5,17.68,2871500,4
+436,8740,02:58.1,1,126.4285714,178100,47:58.6,20.31428571,2878600,4
+437,8760,02:55.4,1,127,175400,48:05.6,18.96857143,2885600,4
+438,8780,03:12.6,1,127.4857143,192600,48:13.3,18.59714286,2893300,4
+439,8800,03:05.2,1,127.2571429,185200,48:20.7,19.44,2900700,4
+440,8820,02:58.9,1,128.8571429,178900,48:27.9,21.48857143,2907900,4
+441,8840,02:45.6,1,130.6285714,165600,48:34.5,18.81714286,2914500,4
+442,8860,03:02.4,1,130.7714286,182400,48:41.8,16.06,2921800,4
+443,8880,03:28.6,1,128.5714286,208600,48:50.1,15.00857143,2930100,4
+444,8900,03:20.8,1,127.4285714,200800,48:58.2,17.34571429,2938200,4
+445,8920,02:52.7,1,126.8285714,172700,49:05.1,18.52571429,2945100,4
+446,8940,02:50.3,1,127,170300,49:11.9,19.74857143,2951900,4
+447,8960,02:54.6,1,127,174600,49:18.9,20.26571429,2958900,4
+448,8980,02:47.6,1,126.8285714,167600,49:25.6,20.20571429,2965600,4
+449,9000,02:43.7,1,127.2571429,163700,49:32.1,19.37142857,2972100,4
+450,9020,02:46.0,1,129.0857143,166000,49:38.8,19.47142857,2978800,4
+451,9040,02:57.0,1,131.8285714,177000,49:45.8,20.43714286,2985800,4
+452,9060,02:35.5,1,133.8285714,155500,49:52.1,20.92857143,2992100,4
+453,9080,02:28.8,1,135.3428571,148800,49:58.0,20.89714286,2998000,4
+454,9100,02:30.4,1,136.7428571,150400,50:04.0,21.40285714,3004000,4
+455,9120,02:26.5,1,138.0857143,146500,50:09.9,22.31142857,3009900,4
+456,9140,02:26.9,1,138.9142857,146900,50:15.8,22.7,3015800,4
+457,9160,02:36.7,1,140.2571429,156700,50:22.0,22.59428571,3022000,4
+458,9180,02:30.0,1,141.7428571,150000,50:28.0,22.43142857,3028000,4
+459,9200,02:29.2,1,143.0857143,149200,50:34.0,22.20857143,3034000,4
+460,9220,02:27.3,1,144.2571429,147300,50:39.9,21.71142857,3039900,4
+461,9240,02:35.5,1,146.0285714,155500,50:46.1,23.12857143,3046100,4
+462,9260,03:08.3,1,138.9714286,188300,50:53.6,22.98857143,3053600,4
+463,9280,04:01.4,1,126.3428571,241400,51:03.3,13.11142857,3063300,4
+465,9320,03:36.4,1,117.5714286,216400,51:25.0,11.70571429,3085000,4
+466,9340,03:51.3,1,119.9142857,231300,51:34.3,19.73714286,3094300,4
+467,9360,03:22.0,1,122.0857143,202000,51:42.3,18.46857143,3102300,4
+468,9380,03:16.1,1,125.7142857,196100,51:50.2,15.80285714,3110200,4
+469,9400,03:25.9,1,118.5714286,205900,51:58.4,16.25428571,3118400,4
+471,9440,03:14.2,1,110.0285714,194200,52:23.5,20.32285714,3143500,4
+472,9460,02:58.9,1,118.1428571,178900,52:30.7,19.28285714,3150700,4
+473,9480,02:50.3,1,122.3142857,170300,52:37.5,17.68,3157500,4
+474,9500,04:10.0,1,127.4571429,250000,52:47.5,17.38,3167500,4
+475,9520,03:45.0,1,126.8857143,225000,52:56.5,16.28,3176500,4
+479,80,03:30.6,2,127.2857143,210600,01:02.5,18.89142857,62500,4
+480,100,03:25.9,2,132.5142857,205900,01:10.8,18.57714286,70799.99995,4
+481,120,03:00.5,2,135.2571429,180500,01:18.0,21.22571429,78000,4
+482,140,02:32.0,2,140,152000,01:24.1,24.74857143,84099.9999,4
+483,160,02:13.2,2,146.0857143,133200,01:29.4,27.41714286,89400.0001,4
+484,180,02:15.6,2,151.9142857,135600,01:34.8,27.46857143,94799.99995,4
+485,200,02:16.0,2,155.6571429,136000,01:40.3,27.24857143,100300,4
+486,220,02:23.8,2,157.1714286,143800,01:46.0,27.2,106000,4
+487,240,02:15.6,2,158.2571429,135600,01:51.4,27.46285714,111400.0001,4
+488,260,02:24.2,2,159.7428571,144200,01:57.2,27.71428571,117200,4
+489,280,02:11.7,2,161.1714286,131700,02:02.5,27.48285714,122500,4
+490,300,02:22.6,2,161.7428571,142600,02:08.2,27.20857143,128200,4
+491,320,02:18.7,2,162.2571429,138700,02:13.7,26.65142857,133700,4
+492,340,02:28.5,2,162.9142857,148500,02:19.6,26.58285714,139599.9999,4
+493,360,02:32.7,2,164,152700,02:25.8,26.19142857,145800,4
+494,380,02:26.9,2,165.0857143,146900,02:31.6,25.69428571,151599.9999,4
+495,400,02:31.6,2,165.8285714,151600,02:37.7,25.55714286,157700,4
+496,420,02:21.0,2,166.0857143,141000,02:43.3,25.83142857,163300,4
+497,440,02:33.5,2,166,153500,02:49.5,26.14857143,169500,4
+498,460,02:35.1,2,165.9142857,155100,02:55.7,26.13714286,175700,4
+499,480,02:25.3,2,166.2571429,145300,03:01.5,26.7,181500,4
+500,500,02:34.7,2,166.7428571,154700,03:07.7,26.58571429,187700,4
+501,520,02:34.7,2,167,154700,03:13.9,26.28857143,193900.0001,4
+502,540,02:32.0,2,167.2571429,152000,03:19.9,25.54,199900.0001,4
+503,560,02:41.0,2,167.6571429,161000,03:26.4,25.30571429,206400.0001,4
+504,580,02:35.1,2,168.3428571,155100,03:32.6,25.35142857,212599.9999,4
+505,600,02:29.2,2,168.8285714,149200,03:38.6,25.90571429,218599.9999,4
+506,620,02:33.1,2,168.7428571,153100,03:44.7,25.97142857,224700,4
+507,640,02:30.4,2,168.6,150400,03:50.7,25.86571429,230700,4
+508,660,02:29.6,2,168.4,149600,03:56.7,25.81142857,236700,4
+509,680,02:28.1,2,168.3428571,148100,04:02.6,25.72571429,242599.9999,4
+510,700,02:27.7,2,167.8285714,147700,04:08.5,25.31714286,248500,4
+511,720,02:30.0,2,168.2571429,150000,04:14.5,25.11714286,254500,4
+512,740,02:28.1,2,168.7428571,148100,04:20.4,25.24285714,260400.0001,4
+513,760,02:34.3,2,169.0857143,154300,04:26.6,25.32857143,266599.9999,4
+514,780,02:23.0,2,169,143000,04:32.3,25.67428571,272300,4
+515,800,02:26.1,2,169,146100,04:38.2,26.05142857,278200,4
+516,820,02:23.4,2,168.9142857,143400,04:43.9,26.58,283900.0001,4
+517,840,02:31.2,2,169.2571429,151200,04:49.9,26.56,289900.0001,4
+518,860,02:23.0,2,169.7428571,143000,04:55.7,26.81714286,295700,4
+519,880,02:30.0,2,170.0857143,150000,05:01.7,27.07714286,301700,4
+520,900,02:26.5,2,170,146500,05:07.5,27.39428571,307500,4
+521,920,02:20.6,2,170,140600,05:13.1,27.06285714,313099.9999,4
+522,940,02:24.2,2,170,144200,05:18.9,26.73714286,318900.0001,4
+523,960,02:18.3,2,170,138300,05:24.4,26.76,324400.0001,4
+524,980,02:19.9,2,170,139900,05:30.0,26.83428571,330000,4
+525,1000,02:16.7,2,169.9142857,136700,05:35.5,27.01714286,335500,4
+526,1020,02:22.2,2,170.2571429,142200,05:41.2,27.38857143,341200,4
+527,1040,02:23.4,2,170.7428571,143400,05:46.9,27.62857143,346900.0001,4
+528,1060,02:15.6,2,171,135600,05:52.3,27.37142857,352300,4
+529,1080,02:18.3,2,171.2571429,138300,05:57.9,27.40285714,357900.0001,4
+530,1100,02:16.7,2,171.7428571,136700,06:03.3,27.36571429,363300,4
+531,1120,02:24.9,2,172.0857143,144900,06:09.1,27.08285714,369099.9999,4
+532,1140,02:18.7,2,172,138700,06:14.7,26.83142857,374700,4
+533,1160,02:21.8,2,172.0857143,141800,06:20.4,26.92285714,380400.0001,4
+534,1180,02:14.4,2,171.7428571,134400,06:25.7,27.00285714,385700,4
+535,1200,02:18.7,2,171.2571429,138700,06:31.3,27.36857143,391300,4
+536,1220,02:10.5,2,170.9142857,130500,06:36.5,27.42571429,396500,4
+537,1240,02:10.9,2,170.9142857,130900,06:41.7,26.94571429,401700,4
+538,1260,02:15.6,2,171.2571429,135600,06:47.2,26.62857143,407200,4
+539,1280,02:12.4,2,171.7428571,132400,06:52.5,26.80285714,412500,4
+540,1300,02:13.2,2,172.0857143,133200,06:57.8,27.13714286,417800,4
+541,1320,02:09.3,2,172,129300,07:03.0,27.50857143,423000,4
+542,1340,02:06.2,2,171.9142857,126200,07:08.0,27.71142857,428000,4
+543,1360,02:16.0,2,172.2571429,136000,07:13.4,27.73142857,433400.0001,4
+544,1380,02:10.9,2,172.7428571,130900,07:18.7,27.68857143,438700,4
+545,1400,02:20.2,2,173.0857143,140200,07:24.3,27.54857143,444300,4
+546,1420,02:09.3,2,173,129300,07:29.5,27.03428571,449500,4
+547,1440,02:06.2,2,172.9142857,126200,07:34.5,26.83714286,454500,4
+548,1460,02:16.0,2,173.2571429,136000,07:39.9,26.74285714,459900.0001,4
+549,1480,02:10.9,2,173.7428571,130900,07:45.2,26.92571429,465200,4
+550,1500,02:10.5,2,174.0857143,130500,07:50.4,26.86571429,470400.0001,4
+551,1520,02:15.6,2,173.9142857,135600,07:55.8,26.92285714,475800,4
+552,1540,02:16.0,2,174.2571429,136000,08:01.3,26.84857143,481300,4
+553,1560,02:20.2,2,174.7428571,140200,08:06.9,26.97428571,486900.0001,4
+554,1580,02:18.3,2,175.0857143,138300,08:12.4,26.74857143,492400.0001,4
+555,1600,02:25.3,2,175.0857143,145300,08:18.2,26.52857143,498200,4
+556,1620,02:28.1,2,174.7428571,148100,08:24.1,26.40571429,504099.9999,4
+557,1640,02:19.9,2,174.2571429,139900,08:29.7,26.29142857,509700,4
+558,1660,02:12.0,2,173.9142857,132000,08:35.0,26.10857143,515000,4
+559,1680,02:20.2,2,174,140200,08:40.6,26.52285714,520599.9999,4
+560,1700,02:18.3,2,174,138300,08:46.1,26.82285714,526099.9999,4
+561,1720,02:24.9,2,174,144900,08:51.9,26.70571429,531900.0001,4
+562,1740,02:17.9,2,174,137900,08:57.5,26.29142857,537500,4
+563,1760,02:26.9,2,174,146900,09:03.3,26.23142857,543300,4
+564,1780,02:23.4,2,173.9142857,143400,09:09.1,26.46285714,549099.9999,4
+565,1800,02:26.9,2,174.2571429,146900,09:14.9,26.78,554900.0001,4
+566,1820,02:28.1,2,174.7428571,148100,09:20.9,26.66285714,560900.0001,4
+567,1840,02:20.2,2,175.0857143,140200,09:26.5,26.38285714,566500,4
+568,1860,02:15.2,2,175,135200,09:31.9,26.30285714,571900.0001,4
+569,1880,02:20.6,2,174.9142857,140600,09:37.5,26.46,577500,4
+570,1900,02:13.2,2,175.3428571,133200,09:42.8,26.49142857,582800,4
+571,1920,02:19.1,2,175.4,139100,09:48.4,26.88571429,588400.0001,4
+572,1940,02:10.5,2,175.6,130500,09:53.6,27.38285714,593599.9999,4
+573,1960,02:14.8,2,175.6571429,134800,09:59.0,27.04,599000,4
+574,1980,02:16.7,2,176.0857143,136700,10:04.5,26.7,604500,4
+575,2000,02:16.7,2,176,136700,10:09.9,26.51142857,609900.0001,4
+576,2020,02:18.3,2,176,138300,10:15.5,26.86571429,615500,4
+577,2040,02:13.2,2,176,133200,10:20.8,27.09142857,620800,4
+578,2060,02:21.0,2,175.9142857,141000,10:26.4,27.39428571,626400.0001,4
+579,2080,02:18.7,2,176.3428571,138700,10:32.0,27.6,632000,4
+580,2100,02:22.2,2,176.4,142200,10:37.7,27.51714286,637700,4
+581,2120,02:15.6,2,176.6,135600,10:43.1,27.26857143,643099.9999,4
+582,2140,02:19.5,2,176.6571429,139500,10:48.7,27.10571429,648700,4
+583,2160,02:14.0,2,177.0857143,134000,10:54.0,27.24285714,654000,4
+584,2180,02:16.3,2,177,136300,10:59.5,27.28571429,659500,4
+585,2200,02:07.7,2,177,127700,11:04.6,27.29428571,664599.9999,4
+586,2220,02:14.0,2,177,134000,11:10.0,27.52857143,670000,4
+587,2240,02:09.7,2,176.9142857,129700,11:15.1,28.00571429,675099.9999,4
+588,2260,02:15.2,2,177.2571429,135200,11:20.6,28.47142857,680599.9999,4
+589,2280,02:09.7,2,177.7428571,129700,11:25.7,28.77428571,685700,4
+590,2300,02:20.6,2,178.0857143,140600,11:31.4,28.68571429,691400.0001,4
+591,2320,02:20.2,2,177.9142857,140200,11:37.0,28.40571429,697000,4
+592,2340,02:19.9,2,178.2571429,139900,11:42.6,28.06857143,702599.9999,4
+593,2360,02:26.1,2,178.7428571,146100,11:48.4,27.66571429,708400.0001,4
+594,2380,02:15.2,2,179.0857143,135200,11:53.8,27.4,713800,4
+595,2400,02:16.3,2,179,136300,11:59.3,27.36857143,719300,4
+596,2420,02:09.7,2,179,129700,12:04.5,27.51428571,724500,4
+597,2440,02:14.4,2,179,134400,12:09.8,27.82857143,729800,4
+598,2460,02:13.6,2,179,133600,12:15.2,27.65714286,735200,4
+599,2480,02:28.5,2,178.9142857,148500,12:21.1,28.05142857,741099.9999,4
+600,2500,02:25.7,2,179.3428571,145700,12:26.9,28.2,746900.0001,4
+601,2520,02:18.7,2,179.4857143,138700,12:32.5,27.49142857,752500,4
+602,2540,02:30.8,2,179.4285714,150800,12:38.5,26.26285714,758500,4
+603,2560,02:25.7,2,178.5714286,145700,12:44.4,25.65428571,764400.0001,4
+604,2580,02:35.9,2,178.6,155900,12:50.6,25.76,770599.9999,4
+605,2600,02:29.2,2,178.4,149200,12:56.6,25.66857143,776599.9999,4
+606,2620,02:26.5,2,178.3428571,146500,13:02.4,25.59142857,782400.0001,4
+607,2640,02:24.9,2,177.9142857,144900,13:08.2,25.26,788200,4
+608,2660,02:30.0,2,178,150000,13:14.2,25.70571429,794200,4
+609,2680,02:25.3,2,178,145300,13:20.0,26.26571429,800000,4
+610,2700,02:22.6,2,178,142600,13:25.7,26.32,805700,4
+611,2720,02:32.0,2,178,152000,13:31.8,25.91714286,811800,4
+612,2740,02:26.1,2,178,146100,13:37.6,25.96857143,817599.9999,4
+613,2760,02:29.2,2,178,149200,13:43.6,26.02,823599.9999,4
+614,2780,02:23.4,2,178.0857143,143400,13:49.4,26.26571429,829400.0001,4
+615,2800,02:26.5,2,177.6571429,146500,13:55.2,26.35142857,835200,4
+616,2820,02:19.1,2,177.5142857,139100,14:00.8,26.14857143,840800,4
+617,2840,02:25.7,2,177.6571429,145700,14:06.6,26.26857143,846599.9999,4
+618,2860,02:18.7,2,178.0857143,138700,14:12.1,27.1,852099.9999,4
+619,2880,02:19.5,2,178,139500,14:17.7,28.33142857,857700,4
+620,2900,02:28.8,2,178,148800,14:23.7,28.55714286,863700,4
+621,2920,02:32.4,2,178,152400,14:29.8,28.26571429,869800,4
+622,2940,02:21.0,2,178,141000,14:35.4,27.36,875400.0001,4
+623,2960,02:23.0,2,178,143000,14:41.1,27.18571429,881099.9999,4
+624,2980,02:30.8,2,177.9142857,150800,14:47.2,27.18285714,887200,4
+625,3000,02:27.7,2,178.3428571,147700,14:53.1,27.18571429,893099.9999,4
+626,3020,02:25.7,2,178.4,145700,14:58.9,26.68285714,898900.0001,4
+627,3040,02:23.0,2,178.6857143,143000,15:04.6,26.50285714,904599.9999,4
+628,3060,02:23.8,2,178.4,143800,15:10.4,26.31142857,910400.0001,4
+629,3080,02:17.1,2,178.3428571,137100,15:15.9,26.28,915900.0001,4
+630,3100,02:23.8,2,177.9142857,143800,15:21.6,26.49142857,921599.9999,4
+631,3120,02:17.1,2,178,137100,15:27.1,26.78857143,927099.9999,4
+632,3140,02:21.4,2,178,141400,15:32.7,26.59142857,932700,4
+633,3160,02:19.5,2,178,139500,15:38.3,26.32857143,938300,4
+634,3180,02:24.2,2,178,144200,15:44.1,26.28,944099.9999,4
+635,3200,02:17.9,2,177.9142857,137900,15:49.6,26.52857143,949599.9999,4
+636,3220,02:23.0,2,178.3428571,143000,15:55.3,26.70571429,955300,4
+637,3240,02:23.8,2,178.4857143,143800,16:01.1,26.63142857,961099.9999,4
+638,3260,02:31.6,2,178.4285714,151600,16:07.1,26.42857143,967099.9999,4
+639,3280,02:28.8,2,177.6571429,148800,16:13.1,26.63428571,973099.9999,4
+640,3300,02:23.4,2,177.2571429,143400,16:18.8,26.91142857,978800,4
+641,3320,02:29.6,2,176.8285714,149600,16:24.8,27.17428571,984800,4
+642,3340,02:19.9,2,177.2571429,139900,16:30.4,26.91428571,990400.0001,4
+643,3360,02:19.1,2,177.7428571,139100,16:36.0,26.72571429,996000,4
+644,3380,02:20.2,2,178.0857143,140200,16:41.6,26.74857143,1001600,4
+645,3400,02:22.6,2,177.9142857,142600,16:47.3,27.23142857,1007300,4
+646,3420,02:24.5,2,178.3428571,144500,16:53.1,27.3,1013100,4
+647,3440,02:19.5,2,178.4857143,139500,16:58.6,27,1018600,4
+648,3460,02:25.7,2,178.3428571,145700,17:04.5,26.54,1024500,4
+649,3480,02:13.6,2,177.9142857,133600,17:09.8,26.55714286,1029800,4
+650,3500,02:18.3,2,178,138300,17:15.3,26.65714286,1035300,4
+651,3520,02:16.0,2,178,136000,17:20.8,26.85714286,1040800,4
+652,3540,02:16.0,2,178,136000,17:26.2,26.88,1046200,4
+653,3560,02:22.6,2,178,142600,17:31.9,27.08285714,1051900,4
+654,3580,02:21.8,2,177.9142857,141800,17:37.6,27.36285714,1057600,4
+655,3600,02:17.1,2,178.2571429,137100,17:43.1,27.56,1063100,4
+656,3620,02:20.2,2,178.7428571,140200,17:48.7,27.68,1068700,4
+657,3640,02:16.3,2,179.0857143,136300,17:54.1,27.63142857,1074100,4
+658,3660,02:20.6,2,179,140600,17:59.8,27.75142857,1079800,4
+659,3680,02:17.9,2,179,137900,18:05.3,27.38571429,1085300,4
+660,3700,02:21.0,2,179,141000,18:10.9,27.30285714,1090900,4
+661,3720,02:16.3,2,179,136300,18:16.4,27.20571429,1096400,4
+662,3740,02:26.9,2,179,146900,18:22.2,27.24,1102200,4
+663,3760,02:32.4,2,179,152400,18:28.3,26.96571429,1108300,4
+664,3780,02:27.7,2,179,147700,18:34.2,26.4,1114200,4
+665,3800,02:33.5,2,178.9142857,153500,18:40.4,26.11428571,1120400,4
+666,3820,02:22.2,2,179.2571429,142200,18:46.1,26.40857143,1126100,4
+667,3840,02:22.2,2,179.7428571,142200,18:51.8,26.98285714,1131800,4
+668,3860,02:30.4,2,180.1714286,150400,18:57.8,27.06285714,1137800,4
+669,3880,02:22.6,2,179.7428571,142600,19:03.5,26.66571429,1143500,4
+670,3900,02:33.5,2,179.2571429,153500,19:09.6,26.30857143,1149600,4
+671,3920,02:29.2,2,178.8285714,149200,19:15.6,26.57714286,1155600,4
+672,3940,02:24.5,2,179.2571429,144500,19:21.4,27.16571429,1161400,4
+673,3960,02:23.4,2,179.7428571,143400,19:27.1,27.26285714,1167100,4
+674,3980,02:17.5,2,180.0857143,137500,19:32.6,27.38571429,1172600,4
+675,4000,02:18.7,2,179.9142857,138700,19:38.2,28.15714286,1178200,4
+676,4020,02:21.4,2,180.2571429,141400,19:43.8,28.81428571,1183800,4
+677,4040,02:18.7,2,180.7428571,138700,19:49.4,29.13714286,1189400,4
+678,4060,02:23.0,2,181.0857143,143000,19:55.1,28.86857143,1195100,4
+679,4080,02:19.5,2,181,139500,20:00.7,28.32857143,1200700,4
+680,4100,02:12.0,2,181,132000,20:05.9,28.18857143,1205900,4
+681,4120,02:14.4,2,181,134400,20:11.3,28.54571429,1211300,4
+682,4140,02:10.1,2,181,130100,20:16.5,27.95714286,1216500,4
+683,4160,02:17.9,2,181,137900,20:22.0,27.20857143,1222000,4
+684,4180,02:10.9,2,180.9142857,130900,20:27.3,27.03142857,1227300,4
+685,4200,02:16.7,2,182.2,136700,20:32.7,27.56285714,1232700,4
+686,4220,02:15.2,2,177.9714286,135200,20:38.1,27.39428571,1238100,4
+687,4240,02:23.4,2,176.7428571,143400,20:43.9,27.29714286,1243900,4
+688,4260,02:14.0,2,178.2285714,134000,20:49.2,27.35714286,1249200,4
+689,4280,02:20.6,2,182.9428571,140600,20:54.9,27.64,1254900,4
+690,4300,02:16.0,2,182,136000,21:00.3,27.76857143,1260300,4
+691,4320,02:19.1,2,182,139100,21:05.9,27.76571429,1265900,4
+692,4340,02:16.0,2,182,136000,21:11.3,27.46285714,1271300,4
+693,4360,02:18.3,2,182,138300,21:16.8,27.41714286,1276800,4
+694,4380,02:12.0,2,182,132000,21:22.1,27.64285714,1282100,4
+695,4400,02:17.5,2,182,137500,21:27.6,28.02857143,1287600,4
+696,4420,02:12.8,2,182,132800,21:32.9,27.86285714,1292900,4
+697,4440,02:19.5,2,182,139500,21:38.5,27.75428571,1298500,4
+698,4460,02:17.9,2,182,137900,21:44.0,27.56285714,1304000,4
+699,4480,02:13.6,2,182,133600,21:49.4,27.65428571,1309400,4
+700,4500,02:17.1,2,182,137100,21:54.8,27.64571429,1314800,4
+701,4520,02:16.3,2,181.9142857,136300,22:00.3,27.66857143,1320300,4
+702,4540,02:20.2,2,182.2571429,140200,22:05.9,27.82,1300.0001,4
+703,4560,02:14.4,2,182.7428571,134400,22:11.3,27.80857143,1331300,4
+704,4580,02:18.7,2,183.0857143,138700,22:16.8,27.68285714,1336800,4
+705,4600,02:12.4,2,183,132400,22:22.1,27.39428571,1342100,4
+706,4620,02:19.1,2,183,139100,22:27.7,27.61428571,1347700,4
+707,4640,02:11.7,2,183,131700,22:32.9,27.66,1352900,4
+708,4660,02:15.2,2,183,135200,22:38.4,27.98285714,1358400,4
+709,4680,02:10.9,2,183,130900,22:43.6,27.84,1363600,4
+710,4700,02:12.8,2,182.9142857,132800,22:48.9,27.81714286,1368900,4
+711,4720,02:13.6,2,183.2571429,133600,22:54.2,27.81428571,1374200,4
+712,4740,02:13.6,2,183.7428571,133600,22:59.6,27.78571429,1379600,4
+713,4760,02:18.7,2,184.0857143,138700,23:05.1,27.76,1385100,4
+714,4780,02:18.3,2,184,138300,23:10.7,27.95142857,1390700,4
+715,4800,02:07.7,2,184,127700,23:15.8,28.25714286,1395800,4
+716,4820,02:11.3,2,184,131300,23:21.0,28.85142857,1401000,4
+717,4840,02:09.3,2,183.9142857,129300,23:26.2,29.72285714,1406200,4
+718,4860,02:09.3,2,184.2571429,129300,23:31.4,30.53142857,1411400,4
+719,4880,02:03.1,2,184.8285714,123100,23:36.3,31.17142857,1416300,4
+720,4900,02:12.8,2,185.1714286,132800,23:41.6,28.64857143,1421600,4
+721,4920,03:32.5,2,183.5714286,212500,23:50.1,23.55428571,1430100,4
+722,4940,04:06.5,2,181.4571429,246500,24:00.0,17.26571429,1440000,4
+723,4960,04:53.0,2,172.3142857,293000,24:11.7,14.90285714,1451700,4
+725,5000,03:50.9,2,152.7714286,230900,24:33.6,18.27714286,1473600,4
+726,5020,03:38.8,2,150.2857143,218800,24:42.3,20.19142857,1482300,4
+727,5040,02:58.5,2,146.8,178500,24:49.5,18.47142857,1489500,4
+728,5060,03:29.0,2,146.4571429,209000,24:57.8,18.4,1497800,4
+729,5080,02:51.1,2,145.5428571,171100,25:04.7,17.55714286,1504700,4
+730,5100,03:15.7,2,144.6,195700,25:12.5,19.71714286,1512500,4
+731,5120,02:49.2,2,143.3428571,169200,25:19.3,20.26571429,1519300,4
+732,5140,02:45.2,2,143.4857143,165200,25:25.9,21.81714286,1525900,4
+733,5160,03:00.5,2,143.1714286,180500,25:33.1,21.63714286,1533100,4
+734,5180,02:47.2,2,141.9142857,167200,25:39.8,21.34,1539800,4
+735,5200,02:57.7,2,141.1714286,177700,25:46.9,21.07714286,1546900,4
+736,5220,02:53.5,2,141.3428571,173500,25:53.8,21.40285714,1553800,4
+737,5240,03:00.9,2,139.5428571,180900,26:01.1,20.84571429,1561100,4
+739,5280,04:33.1,2,136.4571429,273100,26:25.6,21.45714286,1585600,4
+740,5300,03:21.6,2,135.3428571,201600,26:33.7,20.42857143,1593700,4
+741,5320,03:02.0,2,133.3428571,182000,26:41.0,18.96857143,1601000,4
+742,5340,02:43.7,2,134.0857143,163700,26:47.5,20.21428571,1607500,4
+743,5360,02:39.0,2,135.5714286,159000,26:53.9,20.88857143,1613900,4
+744,5380,02:36.3,2,136.0857143,156300,27:00.1,20.68285714,1620100,4
+745,5400,02:37.8,2,136.2571429,157800,27:06.4,20.77142857,1626400,4
+746,5420,02:33.1,2,136.6571429,153100,27:12.6,20.93714286,1639.9999,4
+747,5440,02:36.7,2,137.2571429,156700,27:18.8,20.66,1638800,4
+748,5460,02:44.9,2,138,164900,27:25.4,20.41714286,1645400,4
+749,5480,02:42.1,2,138.7428571,162100,27:31.9,20.78,1651900,4
+750,5500,02:43.7,2,139.1714286,163700,27:38.5,21.37714286,1658500,4
+751,5520,02:36.7,2,140.1714286,156700,27:44.7,20.03142857,1664700,4
+752,5540,02:49.5,2,141.8285714,169500,27:51.5,19.53142857,1671500,4
+753,5560,02:52.7,2,142.9142857,172700,27:58.4,19.91142857,1678400,4
+754,5580,02:44.1,2,143.0857143,164100,28:05.0,21.20571429,1685000,4
+755,5600,02:44.5,2,143,164500,28:11.5,20.60857143,1691500,4
+756,5620,02:53.1,2,143.0857143,173100,28:18.5,20.82,1698500,4
+757,5640,02:40.6,2,142.8285714,160600,28:24.9,20.61714286,1704900,4
+758,5660,03:00.1,2,142.0857143,180100,28:32.1,19.02285714,1712100,4
+759,5680,03:15.3,2,141,195300,28:39.9,17.61714286,1719900,4
+760,5700,03:25.5,2,140.0857143,205500,28:48.1,18.15714286,1728100,4
+761,5720,03:13.0,2,138.7428571,193000,28:55.8,19.87142857,1735800,4
+762,5740,03:05.2,2,137.2571429,185200,29:03.2,19.95142857,1743200,4
+763,5760,02:55.0,2,135.8285714,175000,29:10.2,19.34,1750200,4
+764,5780,03:13.8,2,135.1714286,193800,29:18.0,19.10857143,1758000,4
+765,5800,03:05.2,2,135,185200,29:25.4,19.75428571,1765400,4
+766,5820,02:47.6,2,134.7428571,167600,29:32.1,19.80857143,1772100,4
+767,5840,02:57.7,2,134.1714286,177700,29:39.2,19.02285714,1779200,4
+768,5860,03:04.8,2,134.2571429,184800,29:46.6,17.70571429,1786600,4
+769,5880,03:01.7,2,134.4857143,181700,29:53.9,16.57714286,1793900,4
+770,5900,03:25.5,2,134.1714286,205500,30:02.1,17.24857143,1802100,4
+771,5920,02:58.9,2,134.4285714,178900,30:09.2,17.98857143,1809200,4
+772,5940,02:35.1,2,135.4857143,155100,30:15.5,19.07714286,1815500,4
+773,5960,02:29.6,2,136.0857143,149600,30:21.4,17.96285714,1821400,4
+774,5980,02:36.7,2,136.2571429,156700,30:27.7,18.49714286,1827700,4
+775,6000,03:03.6,2,136.7428571,183600,30:35.0,15.02857143,1835000,4
+776,6020,03:22.7,2,137.1714286,202700,30:43.2,13.74285714,1843200,4
+777,6040,03:20.4,2,136.7428571,200400,30:51.2,15.00571429,1851200,4
+778,6060,02:53.8,2,136.1714286,173800,30:58.1,19.22285714,1858100,4
+779,6080,02:38.2,2,136,158200,31:04.5,20.82,1864500,4
+780,6100,02:30.0,2,137.1714286,150000,31:10.5,20.95428571,1870500,4
+781,6120,02:29.6,2,138.6571429,149600,31:16.4,21.24857143,1876400,4
+782,6140,02:28.5,2,140.3428571,148500,31:22.4,21.18857143,1882400,4
+783,6160,02:27.3,2,141.9142857,147300,31:28.3,21.90857143,1888300,4
+784,6180,02:41.3,2,142.5714286,161300,31:34.7,17.56571429,1894700,4
+785,6200,03:59.9,2,142.6,239900,31:44.3,15.94,1904300,4
+786,6220,03:55.2,2,142.7428571,235200,31:53.7,17.42285714,1913700,4
+787,6240,02:41.7,2,142.8285714,161700,32:00.2,22.17142857,1920200,4
+788,6260,02:26.9,2,143.6285714,146900,32:06.1,22.28571429,1926100,4
+789,6280,03:09.1,2,138.0571429,189100,32:13.6,19.39714286,1933600,4
+791,6320,04:54.2,2,122.2285714,294200,32:51.5,14.22,1971500,4
+792,6340,04:40.1,2,123.2571429,280100,33:02.7,16.01428571,1982700,4
+793,6360,03:45.4,2,124.2285714,225400,33:11.7,16.48,1991700,4
+794,6380,03:25.9,2,125.8571429,205900,33:19.9,16.66571429,1999900,4
+795,6400,03:41.5,2,127.6571429,221500,33:28.8,16.66285714,2008800,4
+796,6420,03:34.5,2,128.4,214500,33:37.3,17.29142857,2017300,4
+797,6440,03:30.2,2,127.6857143,210200,33:45.8,16.38285714,2025800,4
+798,6460,03:04.8,2,128,184800,33:53.1,16.24,2033100,4
+799,6480,02:45.2,2,130,165200,33:59.8,17.13142857,2039800,4
+800,6500,04:58.8,2,130.7428571,298800,34:11.7,17.76857143,2051700,4
+801,6520,04:37.0,2,128.6571429,277000,34:22.8,17.44857143,2062800,4
+802,6540,04:17.0,2,125.6,257000,34:33.1,15.90571429,2073100,4
+803,6560,03:42.3,2,123.6571429,222300,34:42.0,17.48,2082000,4
+804,6580,03:22.4,2,124.4285714,202400,34:50.0,19.24285714,2090000,4
+805,6600,02:48.4,2,126.8285714,168400,34:56.8,20.73428571,2096800,4
+806,6620,02:51.5,2,129.7428571,171500,35:03.6,21.06,2103600,4
+807,6640,02:35.9,2,132.6857143,155900,35:09.9,24.12,2109900,4
+808,6660,02:42.5,2,133.7142857,162500,35:16.4,15.77428571,2116400,4
+810,6700,04:07.3,2,134.2285714,247300,35:34.6,11.19142857,2134600,4
+811,6720,03:03.6,2,134.0857143,183600,35:42.0,20.16,2142000,4
+812,6740,03:04.8,2,131.8285714,184800,35:49.4,19.37714286,2149400,4
+813,6760,03:04.8,2,130.7714286,184800,35:56.8,18.00571429,2156800,4
+814,6780,03:08.7,2,130.0571429,188700,36:04.3,17.85428571,2164300,4
+815,6800,03:06.0,2,129.5142857,186000,36:11.7,18.40571429,2171700,4
+816,6820,03:01.7,2,129.0857143,181700,36:19.0,19.38285714,2179000,4
+817,6840,02:51.5,2,129.7428571,171500,36:25.9,18.68571429,2185900,4
+818,6860,02:54.2,2,130.1714286,174200,36:32.8,18.47142857,2192800,4
+819,6880,02:55.0,2,129.7428571,175000,36:39.8,18.82285714,2199800,4
+820,6900,03:43.8,2,129.1714286,223800,36:48.8,17.32285714,2208800,4
+821,6920,03:35.6,2,129.3428571,215600,36:57.4,16.45428571,2217400,4
+822,6940,03:09.9,2,129.3142857,189900,37:05.0,16.78571429,2225000,4
+823,6960,03:14.2,2,128.2571429,194200,37:12.8,18.57428571,2232800,4
+824,6980,03:18.8,2,127.3428571,198800,37:20.7,18.82,2240700,4
+825,7000,03:27.4,2,127.7428571,207400,37:29.0,18.33428571,2249000,4
+826,7020,03:06.0,2,127.9142857,186000,37:36.5,16.97142857,2256500,4
+827,7040,03:07.5,2,127,187500,37:44.0,17.31428571,2264000,4
+828,7060,03:05.2,2,126.0857143,185200,37:51.4,15.52857143,2271400,4
+829,7080,03:42.7,2,126.1714286,222700,38:00.3,15.28285714,2280300,4
+830,7100,03:29.4,2,126.8285714,209400,38:08.6,16.79714286,2288600,4
+831,7120,03:10.2,2,126.5714286,190200,38:16.3,18.70571429,2296300,4
+832,7140,03:19.2,2,126.9428571,199200,38:24.2,17.78285714,2304200,4
+833,7160,02:56.2,2,128.4857143,176200,38:31.3,18.33142857,2311300,4
+834,7180,02:53.8,2,129.7428571,173800,38:38.2,20.31714286,2318200,4
+835,7200,02:55.8,2,129.1714286,175800,38:45.3,20.25714286,2325300,4
+836,7220,02:43.7,2,129.3428571,163700,38:51.8,20.09714286,2331800,4
+837,7240,02:42.9,2,130.6571429,162900,38:58.3,20.16571429,2338300,4
+838,7260,02:39.4,2,132.1714286,159400,39:04.7,20.67142857,2344700,4
+839,7280,02:35.9,2,132.5714286,155900,39:10.9,21.14857143,2350900,4
+840,7300,02:41.3,2,133.6857143,161300,39:17.4,20.89142857,2357400,4
+841,7320,02:35.9,2,135.6571429,155900,39:23.6,20.22285714,2363600,4
+842,7340,02:37.8,2,137.9142857,157800,39:29.9,20.23428571,2369900,4
+843,7360,02:37.0,2,139.0857143,157000,39:36.2,20.97142857,2376200,4
+844,7380,02:36.7,2,140,156700,39:42.5,20.93714286,2382500,4
+845,7400,02:35.1,2,141.1714286,155100,39:48.7,20.72571429,2388700,4
+846,7420,02:43.3,2,141.5714286,163300,39:55.2,19.34571429,2395200,4
+847,7440,02:59.3,2,141.3428571,179300,40:02.4,19.09714286,2402400,4
+848,7460,03:03.6,2,140.9142857,183600,40:09.7,19.59142857,2409700,4
+849,7480,02:40.6,2,140.9142857,160600,40:16.1,21.23142857,2416100,4
+850,7500,02:48.8,2,141.2571429,168800,40:22.9,21.16571429,2422900,4
+851,7520,02:39.0,2,141.8285714,159000,40:29.3,21.35428571,2429300,4
+852,7540,02:33.9,2,141.9142857,153900,40:35.4,21.19142857,2435400,4
+853,7560,02:47.6,2,141.0857143,167600,40:42.1,20.27428571,2442100,4
+854,7580,03:02.0,2,140.1714286,182000,40:49.4,19.01714286,2449400,4
+855,7600,03:09.5,2,138.4857143,189500,40:57.0,16.88,2457000,4
+856,7620,03:34.9,2,136.6,214900,41:05.6,14.68,2465600,4
+857,7640,03:27.4,2,134.5714286,207400,41:13.9,15.78285714,2473900,4
+858,7660,03:04.8,2,133.3428571,184800,41:21.3,18.14857143,2481300,4
+859,7680,03:11.8,2,131.8285714,191800,41:28.9,18.93428571,2488900,4
+860,7700,03:24.3,2,129.8285714,204300,41:37.1,20.09714286,2497100,4
+861,7720,03:25.9,2,127.2571429,205900,41:45.3,22.05428571,2505300,4
+862,7740,03:39.2,2,124.7428571,219200,41:54.1,20.40571429,2514100,4
+863,7760,04:09.6,2,123.3428571,249600,42:04.1,17.76,2524100,4
+864,7780,03:13.8,2,122.8285714,193800,42:11.8,17.50857143,2531800,4
+865,7800,03:03.2,2,122.7428571,183200,42:19.2,18.88571429,2539200,4
+866,7820,02:44.5,2,123.6857143,164500,42:25.7,19.37142857,2545700,4
+867,7840,02:35.5,2,125.5714286,155500,42:32.0,19.36,2552000,4
+868,7860,02:46.4,2,126.6571429,166400,42:38.6,18.94571429,2558600,4
+869,7880,02:53.1,2,126.5142857,173100,42:45.5,18.05714286,2565500,4
+870,7900,02:58.5,2,127,178500,42:52.7,18.42571429,2572700,4
+871,7920,02:50.7,2,127.5714286,170700,42:59.5,19.13428571,2579500,4
+872,7940,03:16.1,2,127.4285714,196100,43:07.3,18.88857143,2587300,4
+873,7960,03:12.6,2,126.6571429,192600,43:15.0,17.72285714,2595000,4
+874,7980,03:09.9,2,127.4571429,189900,43:22.6,17.56571429,2602600,4
+875,8000,03:21.2,2,120.9428571,201200,43:30.7,17.82571429,2610700,4
+876,8020,03:07.1,2,119.8,187100,43:38.2,17.67142857,2618200,4
+877,8040,02:55.0,2,122.6,175000,43:45.2,17.52571429,2625200,4
+878,8060,03:00.5,2,128.0285714,180500,43:52.4,19.36571429,2632400,4
+880,8100,03:02.8,2,125.4,182800,44:11.9,19.29714286,2651900,4
+881,8120,02:57.0,2,125,177000,44:19.0,18.31428571,2659000,4
+882,8140,03:05.6,2,124.5142857,185600,44:26.4,18.44285714,2666400,4
+883,8160,03:12.6,2,124.5714286,192600,44:34.1,18.39142857,2674100,4
+884,8180,03:02.0,2,123.8285714,182000,44:41.4,15.79714286,2681400,4
+885,8200,03:57.5,2,122.3428571,237500,44:50.9,15.76,2690900,4
+886,8220,03:24.3,2,122.0857143,204300,44:59.1,17.60571429,2699100,4
+887,8240,03:09.9,2,122.5714286,189900,45:06.7,19.90857143,2706700,4
+888,8260,02:55.4,2,123.3428571,175400,45:13.7,19.60857143,2713700,4
+889,8280,02:48.8,2,125.1714286,168800,45:20.5,20.53428571,2720500,4
+890,8300,02:45.6,2,127.5714286,165600,45:27.1,21.03714286,2727100,4
+891,8320,02:48.8,2,129.0857143,168800,45:33.8,20.94,2733800,4
+892,8340,02:45.2,2,130.3428571,165200,45:40.4,20.74285714,2740400,4
+893,8360,02:44.5,2,131.4857143,164500,45:47.0,21.22285714,2747000,4
+894,8380,02:44.1,2,132.4285714,164100,45:53.6,20.41428571,2753600,4
+895,8400,02:46.8,2,132.5714286,166800,46:00.3,20.10857143,2760300,4
+896,8420,02:39.4,2,133.6857143,159400,46:06.6,20.84,2766600,4
+897,8440,02:49.9,2,134.2285714,169900,46:13.4,19.14857143,2773400,4
+898,8460,03:00.9,2,134.4285714,180900,46:20.7,18.04285714,2780700,4
+899,8480,02:56.6,2,134.0857143,176600,46:27.7,17.96285714,2787700,4
+900,8500,02:55.0,2,133.4857143,175000,46:34.7,19.39428571,2794700,4
+901,8520,02:56.2,2,132.5142857,176200,46:41.8,19.5,2801800,4
+902,8540,02:53.8,2,131.7428571,173800,46:48.7,19.76285714,2808700,4
+903,8560,02:46.4,2,132.4285714,166400,46:55.4,19.37714286,2815400,4
+904,8580,02:42.5,2,132.3142857,162500,47:01.9,19.22571429,2821900,4
+905,8600,02:57.0,2,131.3428571,177000,47:09.0,19.37428571,2829000,4
+906,8620,03:09.9,2,130,189900,47:16.5,19.66571429,2836500,4
+907,8640,02:49.9,2,130.3428571,169900,47:23.3,18.85714286,2843300,4
+908,8660,02:46.4,2,130.4,166400,47:30.0,19.05714286,2850000,4
+909,8680,02:50.3,2,129.0857143,170300,47:36.8,17.12285714,2856800,4
+910,8700,02:58.1,2,127.4285714,178100,47:43.9,17.06571429,2863900,4
+911,8720,03:07.9,2,126.4857143,187900,47:51.5,17.68,2871500,4
+912,8740,02:58.1,2,126.4285714,178100,47:58.6,20.31428571,2878600,4
+913,8760,02:55.4,2,127,175400,48:05.6,18.96857143,2885600,4
+914,8780,03:12.6,2,127.4857143,192600,48:13.3,18.59714286,2893300,4
+915,8800,03:05.2,2,127.2571429,185200,48:20.7,19.44,2900700,4
+916,8820,02:58.9,2,128.8571429,178900,48:27.9,21.48857143,2907900,4
+917,8840,02:45.6,2,130.6285714,165600,48:34.5,18.81714286,2914500,4
+918,8860,03:02.4,2,130.7714286,182400,48:41.8,16.06,2921800,4
+919,8880,03:28.6,2,128.5714286,208600,48:50.1,15.00857143,2930100,4
+920,8900,03:20.8,2,127.4285714,200800,48:58.2,17.34571429,2938200,4
+921,8920,02:52.7,2,126.8285714,172700,49:05.1,18.52571429,2945100,4
+922,8940,02:50.3,2,127,170300,49:11.9,19.74857143,2951900,4
+923,8960,02:54.6,2,127,174600,49:18.9,20.26571429,2958900,4
+924,8980,02:47.6,2,126.8285714,167600,49:25.6,20.20571429,2965600,4
+925,9000,02:43.7,2,127.2571429,163700,49:32.1,19.37142857,2972100,4
+926,9020,02:46.0,2,129.0857143,166000,49:38.8,19.47142857,2978800,4
+927,9040,02:57.0,2,131.8285714,177000,49:45.8,20.43714286,2985800,4
+928,9060,02:35.5,2,133.8285714,155500,49:52.1,20.92857143,2992100,4
+929,9080,02:28.8,2,135.3428571,148800,49:58.0,20.89714286,2998000,4
+930,9100,02:30.4,2,136.7428571,150400,50:04.0,21.40285714,3004000,4
+931,9120,02:26.5,2,138.0857143,146500,50:09.9,22.31142857,3009900,4
+932,9140,02:26.9,2,138.9142857,146900,50:15.8,22.7,3015800,4
+933,9160,02:36.7,2,140.2571429,156700,50:22.0,22.59428571,3022000,4
+934,9180,02:30.0,2,141.7428571,150000,50:28.0,22.43142857,3028000,4
+935,9200,02:29.2,2,143.0857143,149200,50:34.0,22.20857143,3034000,4
+936,9220,02:27.3,2,144.2571429,147300,50:39.9,21.71142857,3039900,4
+937,9240,02:35.5,2,146.0285714,155500,50:46.1,23.12857143,3046100,4
+938,9260,03:08.3,2,138.9714286,188300,50:53.6,22.98857143,3053600,4
+939,9280,04:01.4,2,126.3428571,241400,51:03.3,13.11142857,3063300,4
+941,9320,03:36.4,2,117.5714286,216400,51:25.0,11.70571429,3085000,4
+942,9340,03:51.3,2,119.9142857,231300,51:34.3,19.73714286,3094300,4
+943,9360,03:22.0,2,122.0857143,202000,51:42.3,18.46857143,3102300,4
+944,9380,03:16.1,2,125.7142857,196100,51:50.2,15.80285714,3110200,4
+945,9400,03:25.9,2,118.5714286,205900,51:58.4,16.25428571,3118400,4
+947,9440,03:14.2,2,110.0285714,194200,52:23.5,20.32285714,3143500,4
+948,9460,02:58.9,2,118.1428571,178900,52:30.7,19.28285714,3150700,4
+949,9480,02:50.3,2,122.3142857,170300,52:37.5,17.68,3157500,4
+950,9500,04:10.0,2,127.4571429,250000,52:47.5,17.38,3167500,4
+951,9520,03:45.0,2,126.8857143,225000,52:56.5,16.28,3176500,4
+955,80,03:30.6,3,127.2857143,210600,01:02.5,18.89142857,62500,4
+956,100,03:25.9,3,132.5142857,205900,01:10.8,18.57714286,70799.99995,4
+957,120,03:00.5,3,135.2571429,180500,01:18.0,21.22571429,78000,4
+958,140,02:32.0,3,140,152000,01:24.1,24.74857143,84099.9999,4
+959,160,02:13.2,3,146.0857143,133200,01:29.4,27.41714286,89400.0001,4
+960,180,02:15.6,3,151.9142857,135600,01:34.8,27.46857143,94799.99995,4
+961,200,02:16.0,3,155.6571429,136000,01:40.3,27.24857143,100300,4
+962,220,02:23.8,3,157.1714286,143800,01:46.0,27.2,106000,4
+963,240,02:15.6,3,158.2571429,135600,01:51.4,27.46285714,111400.0001,4
+964,260,02:24.2,3,159.7428571,144200,01:57.2,27.71428571,117200,4
+965,280,02:11.7,3,161.1714286,131700,02:02.5,27.48285714,122500,4
+966,300,02:22.6,3,161.7428571,142600,02:08.2,27.20857143,128200,4
+967,320,02:18.7,3,162.2571429,138700,02:13.7,26.65142857,133700,4
+968,340,02:28.5,3,162.9142857,148500,02:19.6,26.58285714,139599.9999,4
+969,360,02:32.7,3,164,152700,02:25.8,26.19142857,145800,4
+970,380,02:26.9,3,165.0857143,146900,02:31.6,25.69428571,151599.9999,4
+971,400,02:31.6,3,165.8285714,151600,02:37.7,25.55714286,157700,4
+972,420,02:21.0,3,166.0857143,141000,02:43.3,25.83142857,163300,4
+973,440,02:33.5,3,166,153500,02:49.5,26.14857143,169500,4
+974,460,02:35.1,3,165.9142857,155100,02:55.7,26.13714286,175700,4
+975,480,02:25.3,3,166.2571429,145300,03:01.5,26.7,181500,4
+976,500,02:34.7,3,166.7428571,154700,03:07.7,26.58571429,187700,4
+977,520,02:34.7,3,167,154700,03:13.9,26.28857143,193900.0001,4
+978,540,02:32.0,3,167.2571429,152000,03:19.9,25.54,199900.0001,4
+979,560,02:41.0,3,167.6571429,161000,03:26.4,25.30571429,206400.0001,4
+980,580,02:35.1,3,168.3428571,155100,03:32.6,25.35142857,212599.9999,4
+981,600,02:29.2,3,168.8285714,149200,03:38.6,25.90571429,218599.9999,4
+982,620,02:33.1,3,168.7428571,153100,03:44.7,25.97142857,224700,4
+983,640,02:30.4,3,168.6,150400,03:50.7,25.86571429,230700,4
+984,660,02:29.6,3,168.4,149600,03:56.7,25.81142857,236700,4
+985,680,02:28.1,3,168.3428571,148100,04:02.6,25.72571429,242599.9999,4
+986,700,02:27.7,3,167.8285714,147700,04:08.5,25.31714286,248500,4
+987,720,02:30.0,3,168.2571429,150000,04:14.5,25.11714286,254500,4
+988,740,02:28.1,3,168.7428571,148100,04:20.4,25.24285714,260400.0001,4
+989,760,02:34.3,3,169.0857143,154300,04:26.6,25.32857143,266599.9999,4
+990,780,02:23.0,3,169,143000,04:32.3,25.67428571,272300,4
+991,800,02:26.1,3,169,146100,04:38.2,26.05142857,278200,4
+992,820,02:23.4,3,168.9142857,143400,04:43.9,26.58,283900.0001,4
+993,840,02:31.2,3,169.2571429,151200,04:49.9,26.56,289900.0001,4
+994,860,02:23.0,3,169.7428571,143000,04:55.7,26.81714286,295700,4
+995,880,02:30.0,3,170.0857143,150000,05:01.7,27.07714286,301700,4
+996,900,02:26.5,3,170,146500,05:07.5,27.39428571,307500,4
+997,920,02:20.6,3,170,140600,05:13.1,27.06285714,313099.9999,4
+998,940,02:24.2,3,170,144200,05:18.9,26.73714286,318900.0001,4
+999,960,02:18.3,3,170,138300,05:24.4,26.76,324400.0001,4
+1000,980,02:19.9,3,170,139900,05:30.0,26.83428571,330000,4
+1001,1000,02:16.7,3,169.9142857,136700,05:35.5,27.01714286,335500,4
+1002,1020,02:22.2,3,170.2571429,142200,05:41.2,27.38857143,341200,4
+1003,1040,02:23.4,3,170.7428571,143400,05:46.9,27.62857143,346900.0001,4
+1004,1060,02:15.6,3,171,135600,05:52.3,27.37142857,352300,4
+1005,1080,02:18.3,3,171.2571429,138300,05:57.9,27.40285714,357900.0001,4
+1006,1100,02:16.7,3,171.7428571,136700,06:03.3,27.36571429,363300,4
+1007,1120,02:24.9,3,172.0857143,144900,06:09.1,27.08285714,369099.9999,4
+1008,1140,02:18.7,3,172,138700,06:14.7,26.83142857,374700,4
+1009,1160,02:21.8,3,172.0857143,141800,06:20.4,26.92285714,380400.0001,4
+1010,1180,02:14.4,3,171.7428571,134400,06:25.7,27.00285714,385700,4
+1011,1200,02:18.7,3,171.2571429,138700,06:31.3,27.36857143,391300,4
+1012,1220,02:10.5,3,170.9142857,130500,06:36.5,27.42571429,396500,4
+1013,1240,02:10.9,3,170.9142857,130900,06:41.7,26.94571429,401700,4
+1014,1260,02:15.6,3,171.2571429,135600,06:47.2,26.62857143,407200,4
+1015,1280,02:12.4,3,171.7428571,132400,06:52.5,26.80285714,412500,4
+1016,1300,02:13.2,3,172.0857143,133200,06:57.8,27.13714286,417800,4
+1017,1320,02:09.3,3,172,129300,07:03.0,27.50857143,423000,4
+1018,1340,02:06.2,3,171.9142857,126200,07:08.0,27.71142857,428000,4
+1019,1360,02:16.0,3,172.2571429,136000,07:13.4,27.73142857,433400.0001,4
+1020,1380,02:10.9,3,172.7428571,130900,07:18.7,27.68857143,438700,4
+1021,1400,02:20.2,3,173.0857143,140200,07:24.3,27.54857143,444300,4
+1022,1420,02:09.3,3,173,129300,07:29.5,27.03428571,449500,4
+1023,1440,02:06.2,3,172.9142857,126200,07:34.5,26.83714286,454500,4
+1024,1460,02:16.0,3,173.2571429,136000,07:39.9,26.74285714,459900.0001,4
+1025,1480,02:10.9,3,173.7428571,130900,07:45.2,26.92571429,465200,4
+1026,1500,02:10.5,3,174.0857143,130500,07:50.4,26.86571429,470400.0001,4
+1027,1520,02:15.6,3,173.9142857,135600,07:55.8,26.92285714,475800,4
+1028,1540,02:16.0,3,174.2571429,136000,08:01.3,26.84857143,481300,4
+1029,1560,02:20.2,3,174.7428571,140200,08:06.9,26.97428571,486900.0001,4
+1030,1580,02:18.3,3,175.0857143,138300,08:12.4,26.74857143,492400.0001,4
+1031,1600,02:25.3,3,175.0857143,145300,08:18.2,26.52857143,498200,4
+1032,1620,02:28.1,3,174.7428571,148100,08:24.1,26.40571429,504099.9999,4
+1033,1640,02:19.9,3,174.2571429,139900,08:29.7,26.29142857,509700,4
+1034,1660,02:12.0,3,173.9142857,132000,08:35.0,26.10857143,515000,4
+1035,1680,02:20.2,3,174,140200,08:40.6,26.52285714,520599.9999,4
+1036,1700,02:18.3,3,174,138300,08:46.1,26.82285714,526099.9999,4
+1037,1720,02:24.9,3,174,144900,08:51.9,26.70571429,531900.0001,4
+1038,1740,02:17.9,3,174,137900,08:57.5,26.29142857,537500,4
+1039,1760,02:26.9,3,174,146900,09:03.3,26.23142857,543300,4
+1040,1780,02:23.4,3,173.9142857,143400,09:09.1,26.46285714,549099.9999,4
+1041,1800,02:26.9,3,174.2571429,146900,09:14.9,26.78,554900.0001,4
+1042,1820,02:28.1,3,174.7428571,148100,09:20.9,26.66285714,560900.0001,4
+1043,1840,02:20.2,3,175.0857143,140200,09:26.5,26.38285714,566500,4
+1044,1860,02:15.2,3,175,135200,09:31.9,26.30285714,571900.0001,4
+1045,1880,02:20.6,3,174.9142857,140600,09:37.5,26.46,577500,4
+1046,1900,02:13.2,3,175.3428571,133200,09:42.8,26.49142857,582800,4
+1047,1920,02:19.1,3,175.4,139100,09:48.4,26.88571429,588400.0001,4
+1048,1940,02:10.5,3,175.6,130500,09:53.6,27.38285714,593599.9999,4
+1049,1960,02:14.8,3,175.6571429,134800,09:59.0,27.04,599000,4
+1050,1980,02:16.7,3,176.0857143,136700,10:04.5,26.7,604500,4
+1051,2000,02:16.7,3,176,136700,10:09.9,26.51142857,609900.0001,4
+1052,2020,02:18.3,3,176,138300,10:15.5,26.86571429,615500,4
+1053,2040,02:13.2,3,176,133200,10:20.8,27.09142857,620800,4
+1054,2060,02:21.0,3,175.9142857,141000,10:26.4,27.39428571,626400.0001,4
+1055,2080,02:18.7,3,176.3428571,138700,10:32.0,27.6,632000,4
+1056,2100,02:22.2,3,176.4,142200,10:37.7,27.51714286,637700,4
+1057,2120,02:15.6,3,176.6,135600,10:43.1,27.26857143,643099.9999,4
+1058,2140,02:19.5,3,176.6571429,139500,10:48.7,27.10571429,648700,4
+1059,2160,02:14.0,3,177.0857143,134000,10:54.0,27.24285714,654000,4
+1060,2180,02:16.3,3,177,136300,10:59.5,27.28571429,659500,4
+1061,2200,02:07.7,3,177,127700,11:04.6,27.29428571,664599.9999,4
+1062,2220,02:14.0,3,177,134000,11:10.0,27.52857143,670000,4
+1063,2240,02:09.7,3,176.9142857,129700,11:15.1,28.00571429,675099.9999,4
+1064,2260,02:15.2,3,177.2571429,135200,11:20.6,28.47142857,680599.9999,4
+1065,2280,02:09.7,3,177.7428571,129700,11:25.7,28.77428571,685700,4
+1066,2300,02:20.6,3,178.0857143,140600,11:31.4,28.68571429,691400.0001,4
+1067,2320,02:20.2,3,177.9142857,140200,11:37.0,28.40571429,697000,4
+1068,2340,02:19.9,3,178.2571429,139900,11:42.6,28.06857143,702599.9999,4
+1069,2360,02:26.1,3,178.7428571,146100,11:48.4,27.66571429,708400.0001,4
+1070,2380,02:15.2,3,179.0857143,135200,11:53.8,27.4,713800,4
+1071,2400,02:16.3,3,179,136300,11:59.3,27.36857143,719300,4
+1072,2420,02:09.7,3,179,129700,12:04.5,27.51428571,724500,4
+1073,2440,02:14.4,3,179,134400,12:09.8,27.82857143,729800,4
+1074,2460,02:13.6,3,179,133600,12:15.2,27.65714286,735200,4
+1075,2480,02:28.5,3,178.9142857,148500,12:21.1,28.05142857,741099.9999,4
+1076,2500,02:25.7,3,179.3428571,145700,12:26.9,28.2,746900.0001,4
+1077,2520,02:18.7,3,179.4857143,138700,12:32.5,27.49142857,752500,4
+1078,2540,02:30.8,3,179.4285714,150800,12:38.5,26.26285714,758500,4
+1079,2560,02:25.7,3,178.5714286,145700,12:44.4,25.65428571,764400.0001,4
+1080,2580,02:35.9,3,178.6,155900,12:50.6,25.76,770599.9999,4
+1081,2600,02:29.2,3,178.4,149200,12:56.6,25.66857143,776599.9999,4
+1082,2620,02:26.5,3,178.3428571,146500,13:02.4,25.59142857,782400.0001,4
+1083,2640,02:24.9,3,177.9142857,144900,13:08.2,25.26,788200,4
+1084,2660,02:30.0,3,178,150000,13:14.2,25.70571429,794200,4
+1085,2680,02:25.3,3,178,145300,13:20.0,26.26571429,800000,4
+1086,2700,02:22.6,3,178,142600,13:25.7,26.32,805700,4
+1087,2720,02:32.0,3,178,152000,13:31.8,25.91714286,811800,4
+1088,2740,02:26.1,3,178,146100,13:37.6,25.96857143,817599.9999,4
+1089,2760,02:29.2,3,178,149200,13:43.6,26.02,823599.9999,4
+1090,2780,02:23.4,3,178.0857143,143400,13:49.4,26.26571429,829400.0001,4
+1091,2800,02:26.5,3,177.6571429,146500,13:55.2,26.35142857,835200,4
+1092,2820,02:19.1,3,177.5142857,139100,14:00.8,26.14857143,840800,4
+1093,2840,02:25.7,3,177.6571429,145700,14:06.6,26.26857143,846599.9999,4
+1094,2860,02:18.7,3,178.0857143,138700,14:12.1,27.1,852099.9999,4
+1095,2880,02:19.5,3,178,139500,14:17.7,28.33142857,857700,4
+1096,2900,02:28.8,3,178,148800,14:23.7,28.55714286,863700,4
+1097,2920,02:32.4,3,178,152400,14:29.8,28.26571429,869800,4
+1098,2940,02:21.0,3,178,141000,14:35.4,27.36,875400.0001,4
+1099,2960,02:23.0,3,178,143000,14:41.1,27.18571429,881099.9999,4
+1100,2980,02:30.8,3,177.9142857,150800,14:47.2,27.18285714,887200,4
+1101,3000,02:27.7,3,178.3428571,147700,14:53.1,27.18571429,893099.9999,4
+1102,3020,02:25.7,3,178.4,145700,14:58.9,26.68285714,898900.0001,4
+1103,3040,02:23.0,3,178.6857143,143000,15:04.6,26.50285714,904599.9999,4
+1104,3060,02:23.8,3,178.4,143800,15:10.4,26.31142857,910400.0001,4
+1105,3080,02:17.1,3,178.3428571,137100,15:15.9,26.28,915900.0001,4
+1106,3100,02:23.8,3,177.9142857,143800,15:21.6,26.49142857,921599.9999,4
+1107,3120,02:17.1,3,178,137100,15:27.1,26.78857143,927099.9999,4
+1108,3140,02:21.4,3,178,141400,15:32.7,26.59142857,932700,4
+1109,3160,02:19.5,3,178,139500,15:38.3,26.32857143,938300,4
+1110,3180,02:24.2,3,178,144200,15:44.1,26.28,944099.9999,4
+1111,3200,02:17.9,3,177.9142857,137900,15:49.6,26.52857143,949599.9999,4
+1112,3220,02:23.0,3,178.3428571,143000,15:55.3,26.70571429,955300,4
+1113,3240,02:23.8,3,178.4857143,143800,16:01.1,26.63142857,961099.9999,4
+1114,3260,02:31.6,3,178.4285714,151600,16:07.1,26.42857143,967099.9999,4
+1115,3280,02:28.8,3,177.6571429,148800,16:13.1,26.63428571,973099.9999,4
+1116,3300,02:23.4,3,177.2571429,143400,16:18.8,26.91142857,978800,4
+1117,3320,02:29.6,3,176.8285714,149600,16:24.8,27.17428571,984800,4
+1118,3340,02:19.9,3,177.2571429,139900,16:30.4,26.91428571,990400.0001,4
+1119,3360,02:19.1,3,177.7428571,139100,16:36.0,26.72571429,996000,4
+1120,3380,02:20.2,3,178.0857143,140200,16:41.6,26.74857143,1001600,4
+1121,3400,02:22.6,3,177.9142857,142600,16:47.3,27.23142857,1007300,4
+1122,3420,02:24.5,3,178.3428571,144500,16:53.1,27.3,1013100,4
+1123,3440,02:19.5,3,178.4857143,139500,16:58.6,27,1018600,4
+1124,3460,02:25.7,3,178.3428571,145700,17:04.5,26.54,1024500,4
+1125,3480,02:13.6,3,177.9142857,133600,17:09.8,26.55714286,1029800,4
+1126,3500,02:18.3,3,178,138300,17:15.3,26.65714286,1035300,4
+1127,3520,02:16.0,3,178,136000,17:20.8,26.85714286,1040800,4
+1128,3540,02:16.0,3,178,136000,17:26.2,26.88,1046200,4
+1129,3560,02:22.6,3,178,142600,17:31.9,27.08285714,1051900,4
+1130,3580,02:21.8,3,177.9142857,141800,17:37.6,27.36285714,1057600,4
+1131,3600,02:17.1,3,178.2571429,137100,17:43.1,27.56,1063100,4
+1132,3620,02:20.2,3,178.7428571,140200,17:48.7,27.68,1068700,4
+1133,3640,02:16.3,3,179.0857143,136300,17:54.1,27.63142857,1074100,4
+1134,3660,02:20.6,3,179,140600,17:59.8,27.75142857,1079800,4
+1135,3680,02:17.9,3,179,137900,18:05.3,27.38571429,1085300,4
+1136,3700,02:21.0,3,179,141000,18:10.9,27.30285714,1090900,4
+1137,3720,02:16.3,3,179,136300,18:16.4,27.20571429,1096400,4
+1138,3740,02:26.9,3,179,146900,18:22.2,27.24,1102200,4
+1139,3760,02:32.4,3,179,152400,18:28.3,26.96571429,1108300,4
+1140,3780,02:27.7,3,179,147700,18:34.2,26.4,1114200,4
+1141,3800,02:33.5,3,178.9142857,153500,18:40.4,26.11428571,1120400,4
+1142,3820,02:22.2,3,179.2571429,142200,18:46.1,26.40857143,1126100,4
+1143,3840,02:22.2,3,179.7428571,142200,18:51.8,26.98285714,1131800,4
+1144,3860,02:30.4,3,180.1714286,150400,18:57.8,27.06285714,1137800,4
+1145,3880,02:22.6,3,179.7428571,142600,19:03.5,26.66571429,1143500,4
+1146,3900,02:33.5,3,179.2571429,153500,19:09.6,26.30857143,1149600,4
+1147,3920,02:29.2,3,178.8285714,149200,19:15.6,26.57714286,1155600,4
+1148,3940,02:24.5,3,179.2571429,144500,19:21.4,27.16571429,1161400,4
+1149,3960,02:23.4,3,179.7428571,143400,19:27.1,27.26285714,1167100,4
+1150,3980,02:17.5,3,180.0857143,137500,19:32.6,27.38571429,1172600,4
+1151,4000,02:18.7,3,179.9142857,138700,19:38.2,28.15714286,1178200,4
+1152,4020,02:21.4,3,180.2571429,141400,19:43.8,28.81428571,1183800,4
+1153,4040,02:18.7,3,180.7428571,138700,19:49.4,29.13714286,1189400,4
+1154,4060,02:23.0,3,181.0857143,143000,19:55.1,28.86857143,1195100,4
+1155,4080,02:19.5,3,181,139500,20:00.7,28.32857143,1200700,4
+1156,4100,02:12.0,3,181,132000,20:05.9,28.18857143,1205900,4
+1157,4120,02:14.4,3,181,134400,20:11.3,28.54571429,1211300,4
+1158,4140,02:10.1,3,181,130100,20:16.5,27.95714286,1216500,4
+1159,4160,02:17.9,3,181,137900,20:22.0,27.20857143,1222000,4
+1160,4180,02:10.9,3,180.9142857,130900,20:27.3,27.03142857,1227300,4
+1161,4200,02:16.7,3,182.2,136700,20:32.7,27.56285714,1232700,4
+1162,4220,02:15.2,3,177.9714286,135200,20:38.1,27.39428571,1238100,4
+1163,4240,02:23.4,3,176.7428571,143400,20:43.9,27.29714286,1243900,4
+1164,4260,02:14.0,3,178.2285714,134000,20:49.2,27.35714286,1249200,4
+1165,4280,02:20.6,3,182.9428571,140600,20:54.9,27.64,1254900,4
+1166,4300,02:16.0,3,182,136000,21:00.3,27.76857143,1260300,4
+1167,4320,02:19.1,3,182,139100,21:05.9,27.76571429,1265900,4
+1168,4340,02:16.0,3,182,136000,21:11.3,27.46285714,1271300,4
+1169,4360,02:18.3,3,182,138300,21:16.8,27.41714286,1276800,4
+1170,4380,02:12.0,3,182,132000,21:22.1,27.64285714,1282100,4
+1171,4400,02:17.5,3,182,137500,21:27.6,28.02857143,1287600,4
+1172,4420,02:12.8,3,182,132800,21:32.9,27.86285714,1292900,4
+1173,4440,02:19.5,3,182,139500,21:38.5,27.75428571,1298500,4
+1174,4460,02:17.9,3,182,137900,21:44.0,27.56285714,1304000,4
+1175,4480,02:13.6,3,182,133600,21:49.4,27.65428571,1309400,4
+1176,4500,02:17.1,3,182,137100,21:54.8,27.64571429,1314800,4
+1177,4520,02:16.3,3,181.9142857,136300,22:00.3,27.66857143,1320300,4
+1178,4540,02:20.2,3,182.2571429,140200,22:05.9,27.82,1300.0001,4
+1179,4560,02:14.4,3,182.7428571,134400,22:11.3,27.80857143,1331300,4
+1180,4580,02:18.7,3,183.0857143,138700,22:16.8,27.68285714,1336800,4
+1181,4600,02:12.4,3,183,132400,22:22.1,27.39428571,1342100,4
+1182,4620,02:19.1,3,183,139100,22:27.7,27.61428571,1347700,4
+1183,4640,02:11.7,3,183,131700,22:32.9,27.66,1352900,4
+1184,4660,02:15.2,3,183,135200,22:38.4,27.98285714,1358400,4
+1185,4680,02:10.9,3,183,130900,22:43.6,27.84,1363600,4
+1186,4700,02:12.8,3,182.9142857,132800,22:48.9,27.81714286,1368900,4
+1187,4720,02:13.6,3,183.2571429,133600,22:54.2,27.81428571,1374200,4
+1188,4740,02:13.6,3,183.7428571,133600,22:59.6,27.78571429,1379600,4
+1189,4760,02:18.7,3,184.0857143,138700,23:05.1,27.76,1385100,4
+1190,4780,02:18.3,3,184,138300,23:10.7,27.95142857,1390700,4
+1191,4800,02:07.7,3,184,127700,23:15.8,28.25714286,1395800,4
+1192,4820,02:11.3,3,184,131300,23:21.0,28.85142857,1401000,4
+1193,4840,02:09.3,3,183.9142857,129300,23:26.2,29.72285714,1406200,4
+1194,4860,02:09.3,3,184.2571429,129300,23:31.4,30.53142857,1411400,4
+1195,4880,02:03.1,3,184.8285714,123100,23:36.3,31.17142857,1416300,4
+1196,4900,02:12.8,3,185.1714286,132800,23:41.6,28.64857143,1421600,4
+1197,4920,03:32.5,3,183.5714286,212500,23:50.1,23.55428571,1430100,4
+1198,4940,04:06.5,3,181.4571429,246500,24:00.0,17.26571429,1440000,4
+1199,4960,04:53.0,3,172.3142857,293000,24:11.7,14.90285714,1451700,4
+1201,5000,03:50.9,3,152.7714286,230900,24:33.6,18.27714286,1473600,4
+1202,5020,03:38.8,3,150.2857143,218800,24:42.3,20.19142857,1482300,4
+1203,5040,02:58.5,3,146.8,178500,24:49.5,18.47142857,1489500,4
+1204,5060,03:29.0,3,146.4571429,209000,24:57.8,18.4,1497800,4
+1205,5080,02:51.1,3,145.5428571,171100,25:04.7,17.55714286,1504700,4
+1206,5100,03:15.7,3,144.6,195700,25:12.5,19.71714286,1512500,4
+1207,5120,02:49.2,3,143.3428571,169200,25:19.3,20.26571429,1519300,4
+1208,5140,02:45.2,3,143.4857143,165200,25:25.9,21.81714286,1525900,4
+1209,5160,03:00.5,3,143.1714286,180500,25:33.1,21.63714286,1533100,4
+1210,5180,02:47.2,3,141.9142857,167200,25:39.8,21.34,1539800,4
+1211,5200,02:57.7,3,141.1714286,177700,25:46.9,21.07714286,1546900,4
+1212,5220,02:53.5,3,141.3428571,173500,25:53.8,21.40285714,1553800,4
+1213,5240,03:00.9,3,139.5428571,180900,26:01.1,20.84571429,1561100,4
+1215,5280,04:33.1,3,136.4571429,273100,26:25.6,21.45714286,1585600,4
+1216,5300,03:21.6,3,135.3428571,201600,26:33.7,20.42857143,1593700,4
+1217,5320,03:02.0,3,133.3428571,182000,26:41.0,18.96857143,1601000,4
+1218,5340,02:43.7,3,134.0857143,163700,26:47.5,20.21428571,1607500,4
+1219,5360,02:39.0,3,135.5714286,159000,26:53.9,20.88857143,1613900,4
+1220,5380,02:36.3,3,136.0857143,156300,27:00.1,20.68285714,1620100,4
+1221,5400,02:37.8,3,136.2571429,157800,27:06.4,20.77142857,1626400,4
+1222,5420,02:33.1,3,136.6571429,153100,27:12.6,20.93714286,1639.9999,4
+1223,5440,02:36.7,3,137.2571429,156700,27:18.8,20.66,1638800,4
+1224,5460,02:44.9,3,138,164900,27:25.4,20.41714286,1645400,4
+1225,5480,02:42.1,3,138.7428571,162100,27:31.9,20.78,1651900,4
+1226,5500,02:43.7,3,139.1714286,163700,27:38.5,21.37714286,1658500,4
+1227,5520,02:36.7,3,140.1714286,156700,27:44.7,20.03142857,1664700,4
+1228,5540,02:49.5,3,141.8285714,169500,27:51.5,19.53142857,1671500,4
+1229,5560,02:52.7,3,142.9142857,172700,27:58.4,19.91142857,1678400,4
+1230,5580,02:44.1,3,143.0857143,164100,28:05.0,21.20571429,1685000,4
+1231,5600,02:44.5,3,143,164500,28:11.5,20.60857143,1691500,4
+1232,5620,02:53.1,3,143.0857143,173100,28:18.5,20.82,1698500,4
+1233,5640,02:40.6,3,142.8285714,160600,28:24.9,20.61714286,1704900,4
+1234,5660,03:00.1,3,142.0857143,180100,28:32.1,19.02285714,1712100,4
+1235,5680,03:15.3,3,141,195300,28:39.9,17.61714286,1719900,4
+1236,5700,03:25.5,3,140.0857143,205500,28:48.1,18.15714286,1728100,4
+1237,5720,03:13.0,3,138.7428571,193000,28:55.8,19.87142857,1735800,4
+1238,5740,03:05.2,3,137.2571429,185200,29:03.2,19.95142857,1743200,4
+1239,5760,02:55.0,3,135.8285714,175000,29:10.2,19.34,1750200,4
+1240,5780,03:13.8,3,135.1714286,193800,29:18.0,19.10857143,1758000,4
+1241,5800,03:05.2,3,135,185200,29:25.4,19.75428571,1765400,4
+1242,5820,02:47.6,3,134.7428571,167600,29:32.1,19.80857143,1772100,4
+1243,5840,02:57.7,3,134.1714286,177700,29:39.2,19.02285714,1779200,4
+1244,5860,03:04.8,3,134.2571429,184800,29:46.6,17.70571429,1786600,4
+1245,5880,03:01.7,3,134.4857143,181700,29:53.9,16.57714286,1793900,4
+1246,5900,03:25.5,3,134.1714286,205500,30:02.1,17.24857143,1802100,4
+1247,5920,02:58.9,3,134.4285714,178900,30:09.2,17.98857143,1809200,4
+1248,5940,02:35.1,3,135.4857143,155100,30:15.5,19.07714286,1815500,4
+1249,5960,02:29.6,3,136.0857143,149600,30:21.4,17.96285714,1821400,4
+1250,5980,02:36.7,3,136.2571429,156700,30:27.7,18.49714286,1827700,4
+1251,6000,03:03.6,3,136.7428571,183600,30:35.0,15.02857143,1835000,4
+1252,6020,03:22.7,3,137.1714286,202700,30:43.2,13.74285714,1843200,4
+1253,6040,03:20.4,3,136.7428571,200400,30:51.2,15.00571429,1851200,4
+1254,6060,02:53.8,3,136.1714286,173800,30:58.1,19.22285714,1858100,4
+1255,6080,02:38.2,3,136,158200,31:04.5,20.82,1864500,4
+1256,6100,02:30.0,3,137.1714286,150000,31:10.5,20.95428571,1870500,4
+1257,6120,02:29.6,3,138.6571429,149600,31:16.4,21.24857143,1876400,4
+1258,6140,02:28.5,3,140.3428571,148500,31:22.4,21.18857143,1882400,4
+1259,6160,02:27.3,3,141.9142857,147300,31:28.3,21.90857143,1888300,4
+1260,6180,02:41.3,3,142.5714286,161300,31:34.7,17.56571429,1894700,4
+1261,6200,03:59.9,3,142.6,239900,31:44.3,15.94,1904300,4
+1262,6220,03:55.2,3,142.7428571,235200,31:53.7,17.42285714,1913700,4
+1263,6240,02:41.7,3,142.8285714,161700,32:00.2,22.17142857,1920200,4
+1264,6260,02:26.9,3,143.6285714,146900,32:06.1,22.28571429,1926100,4
+1265,6280,03:09.1,3,138.0571429,189100,32:13.6,19.39714286,1933600,4
+1267,6320,04:54.2,3,122.2285714,294200,32:51.5,14.22,1971500,4
+1268,6340,04:40.1,3,123.2571429,280100,33:02.7,16.01428571,1982700,4
+1269,6360,03:45.4,3,124.2285714,225400,33:11.7,16.48,1991700,4
+1270,6380,03:25.9,3,125.8571429,205900,33:19.9,16.66571429,1999900,4
+1271,6400,03:41.5,3,127.6571429,221500,33:28.8,16.66285714,2008800,4
+1272,6420,03:34.5,3,128.4,214500,33:37.3,17.29142857,2017300,4
+1273,6440,03:30.2,3,127.6857143,210200,33:45.8,16.38285714,2025800,4
+1274,6460,03:04.8,3,128,184800,33:53.1,16.24,2033100,4
+1275,6480,02:45.2,3,130,165200,33:59.8,17.13142857,2039800,4
+1276,6500,04:58.8,3,130.7428571,298800,34:11.7,17.76857143,2051700,4
+1277,6520,04:37.0,3,128.6571429,277000,34:22.8,17.44857143,2062800,4
+1278,6540,04:17.0,3,125.6,257000,34:33.1,15.90571429,2073100,4
+1279,6560,03:42.3,3,123.6571429,222300,34:42.0,17.48,2082000,4
+1280,6580,03:22.4,3,124.4285714,202400,34:50.0,19.24285714,2090000,4
+1281,6600,02:48.4,3,126.8285714,168400,34:56.8,20.73428571,2096800,4
+1282,6620,02:51.5,3,129.7428571,171500,35:03.6,21.06,2103600,4
+1283,6640,02:35.9,3,132.6857143,155900,35:09.9,24.12,2109900,4
+1284,6660,02:42.5,3,133.7142857,162500,35:16.4,15.77428571,2116400,4
+1286,6700,04:07.3,3,134.2285714,247300,35:34.6,11.19142857,2134600,4
+1287,6720,03:03.6,3,134.0857143,183600,35:42.0,20.16,2142000,4
+1288,6740,03:04.8,3,131.8285714,184800,35:49.4,19.37714286,2149400,4
+1289,6760,03:04.8,3,130.7714286,184800,35:56.8,18.00571429,2156800,4
+1290,6780,03:08.7,3,130.0571429,188700,36:04.3,17.85428571,2164300,4
+1291,6800,03:06.0,3,129.5142857,186000,36:11.7,18.40571429,2171700,4
+1292,6820,03:01.7,3,129.0857143,181700,36:19.0,19.38285714,2179000,4
+1293,6840,02:51.5,3,129.7428571,171500,36:25.9,18.68571429,2185900,4
+1294,6860,02:54.2,3,130.1714286,174200,36:32.8,18.47142857,2192800,4
+1295,6880,02:55.0,3,129.7428571,175000,36:39.8,18.82285714,2199800,4
+1296,6900,03:43.8,3,129.1714286,223800,36:48.8,17.32285714,2208800,4
+1297,6920,03:35.6,3,129.3428571,215600,36:57.4,16.45428571,2217400,4
+1298,6940,03:09.9,3,129.3142857,189900,37:05.0,16.78571429,2225000,4
+1299,6960,03:14.2,3,128.2571429,194200,37:12.8,18.57428571,2232800,4
+1300,6980,03:18.8,3,127.3428571,198800,37:20.7,18.82,2240700,4
+1301,7000,03:27.4,3,127.7428571,207400,37:29.0,18.33428571,2249000,4
+1302,7020,03:06.0,3,127.9142857,186000,37:36.5,16.97142857,2256500,4
+1303,7040,03:07.5,3,127,187500,37:44.0,17.31428571,2264000,4
+1304,7060,03:05.2,3,126.0857143,185200,37:51.4,15.52857143,2271400,4
+1305,7080,03:42.7,3,126.1714286,222700,38:00.3,15.28285714,2280300,4
+1306,7100,03:29.4,3,126.8285714,209400,38:08.6,16.79714286,2288600,4
+1307,7120,03:10.2,3,126.5714286,190200,38:16.3,18.70571429,2296300,4
+1308,7140,03:19.2,3,126.9428571,199200,38:24.2,17.78285714,2304200,4
+1309,7160,02:56.2,3,128.4857143,176200,38:31.3,18.33142857,2311300,4
+1310,7180,02:53.8,3,129.7428571,173800,38:38.2,20.31714286,2318200,4
+1311,7200,02:55.8,3,129.1714286,175800,38:45.3,20.25714286,2325300,4
+1312,7220,02:43.7,3,129.3428571,163700,38:51.8,20.09714286,2331800,4
+1313,7240,02:42.9,3,130.6571429,162900,38:58.3,20.16571429,2338300,4
+1314,7260,02:39.4,3,132.1714286,159400,39:04.7,20.67142857,2344700,4
+1315,7280,02:35.9,3,132.5714286,155900,39:10.9,21.14857143,2350900,4
+1316,7300,02:41.3,3,133.6857143,161300,39:17.4,20.89142857,2357400,4
+1317,7320,02:35.9,3,135.6571429,155900,39:23.6,20.22285714,2363600,4
+1318,7340,02:37.8,3,137.9142857,157800,39:29.9,20.23428571,2369900,4
+1319,7360,02:37.0,3,139.0857143,157000,39:36.2,20.97142857,2376200,4
+1320,7380,02:36.7,3,140,156700,39:42.5,20.93714286,2382500,4
+1321,7400,02:35.1,3,141.1714286,155100,39:48.7,20.72571429,2388700,4
+1322,7420,02:43.3,3,141.5714286,163300,39:55.2,19.34571429,2395200,4
+1323,7440,02:59.3,3,141.3428571,179300,40:02.4,19.09714286,2402400,4
+1324,7460,03:03.6,3,140.9142857,183600,40:09.7,19.59142857,2409700,4
+1325,7480,02:40.6,3,140.9142857,160600,40:16.1,21.23142857,2416100,4
+1326,7500,02:48.8,3,141.2571429,168800,40:22.9,21.16571429,2422900,4
+1327,7520,02:39.0,3,141.8285714,159000,40:29.3,21.35428571,2429300,4
+1328,7540,02:33.9,3,141.9142857,153900,40:35.4,21.19142857,2435400,4
+1329,7560,02:47.6,3,141.0857143,167600,40:42.1,20.27428571,2442100,4
+1330,7580,03:02.0,3,140.1714286,182000,40:49.4,19.01714286,2449400,4
+1331,7600,03:09.5,3,138.4857143,189500,40:57.0,16.88,2457000,4
+1332,7620,03:34.9,3,136.6,214900,41:05.6,14.68,2465600,4
+1333,7640,03:27.4,3,134.5714286,207400,41:13.9,15.78285714,2473900,4
+1334,7660,03:04.8,3,133.3428571,184800,41:21.3,18.14857143,2481300,4
+1335,7680,03:11.8,3,131.8285714,191800,41:28.9,18.93428571,2488900,4
+1336,7700,03:24.3,3,129.8285714,204300,41:37.1,20.09714286,2497100,4
+1337,7720,03:25.9,3,127.2571429,205900,41:45.3,22.05428571,2505300,4
+1338,7740,03:39.2,3,124.7428571,219200,41:54.1,20.40571429,2514100,4
+1339,7760,04:09.6,3,123.3428571,249600,42:04.1,17.76,2524100,4
+1340,7780,03:13.8,3,122.8285714,193800,42:11.8,17.50857143,2531800,4
+1341,7800,03:03.2,3,122.7428571,183200,42:19.2,18.88571429,2539200,4
+1342,7820,02:44.5,3,123.6857143,164500,42:25.7,19.37142857,2545700,4
+1343,7840,02:35.5,3,125.5714286,155500,42:32.0,19.36,2552000,4
+1344,7860,02:46.4,3,126.6571429,166400,42:38.6,18.94571429,2558600,4
+1345,7880,02:53.1,3,126.5142857,173100,42:45.5,18.05714286,2565500,4
+1346,7900,02:58.5,3,127,178500,42:52.7,18.42571429,2572700,4
+1347,7920,02:50.7,3,127.5714286,170700,42:59.5,19.13428571,2579500,4
+1348,7940,03:16.1,3,127.4285714,196100,43:07.3,18.88857143,2587300,4
+1349,7960,03:12.6,3,126.6571429,192600,43:15.0,17.72285714,2595000,4
+1350,7980,03:09.9,3,127.4571429,189900,43:22.6,17.56571429,2602600,4
+1351,8000,03:21.2,3,120.9428571,201200,43:30.7,17.82571429,2610700,4
+1352,8020,03:07.1,3,119.8,187100,43:38.2,17.67142857,2618200,4
+1353,8040,02:55.0,3,122.6,175000,43:45.2,17.52571429,2625200,4
+1354,8060,03:00.5,3,128.0285714,180500,43:52.4,19.36571429,2632400,4
+1356,8100,03:02.8,3,125.4,182800,44:11.9,19.29714286,2651900,4
+1357,8120,02:57.0,3,125,177000,44:19.0,18.31428571,2659000,4
+1358,8140,03:05.6,3,124.5142857,185600,44:26.4,18.44285714,2666400,4
+1359,8160,03:12.6,3,124.5714286,192600,44:34.1,18.39142857,2674100,4
+1360,8180,03:02.0,3,123.8285714,182000,44:41.4,15.79714286,2681400,4
+1361,8200,03:57.5,3,122.3428571,237500,44:50.9,15.76,2690900,4
+1362,8220,03:24.3,3,122.0857143,204300,44:59.1,17.60571429,2699100,4
+1363,8240,03:09.9,3,122.5714286,189900,45:06.7,19.90857143,2706700,4
+1364,8260,02:55.4,3,123.3428571,175400,45:13.7,19.60857143,2713700,4
+1365,8280,02:48.8,3,125.1714286,168800,45:20.5,20.53428571,2720500,4
+1366,8300,02:45.6,3,127.5714286,165600,45:27.1,21.03714286,2727100,4
+1367,8320,02:48.8,3,129.0857143,168800,45:33.8,20.94,2733800,4
+1368,8340,02:45.2,3,130.3428571,165200,45:40.4,20.74285714,2740400,4
+1369,8360,02:44.5,3,131.4857143,164500,45:47.0,21.22285714,2747000,4
+1370,8380,02:44.1,3,132.4285714,164100,45:53.6,20.41428571,2753600,4
+1371,8400,02:46.8,3,132.5714286,166800,46:00.3,20.10857143,2760300,4
+1372,8420,02:39.4,3,133.6857143,159400,46:06.6,20.84,2766600,4
+1373,8440,02:49.9,3,134.2285714,169900,46:13.4,19.14857143,2773400,4
+1374,8460,03:00.9,3,134.4285714,180900,46:20.7,18.04285714,2780700,4
+1375,8480,02:56.6,3,134.0857143,176600,46:27.7,17.96285714,2787700,4
+1376,8500,02:55.0,3,133.4857143,175000,46:34.7,19.39428571,2794700,4
+1377,8520,02:56.2,3,132.5142857,176200,46:41.8,19.5,2801800,4
+1378,8540,02:53.8,3,131.7428571,173800,46:48.7,19.76285714,2808700,4
+1379,8560,02:46.4,3,132.4285714,166400,46:55.4,19.37714286,2815400,4
+1380,8580,02:42.5,3,132.3142857,162500,47:01.9,19.22571429,2821900,4
+1381,8600,02:57.0,3,131.3428571,177000,47:09.0,19.37428571,2829000,4
+1382,8620,03:09.9,3,130,189900,47:16.5,19.66571429,2836500,4
+1383,8640,02:49.9,3,130.3428571,169900,47:23.3,18.85714286,2843300,4
+1384,8660,02:46.4,3,130.4,166400,47:30.0,19.05714286,2850000,4
+1385,8680,02:50.3,3,129.0857143,170300,47:36.8,17.12285714,2856800,4
+1386,8700,02:58.1,3,127.4285714,178100,47:43.9,17.06571429,2863900,4
+1387,8720,03:07.9,3,126.4857143,187900,47:51.5,17.68,2871500,4
+1388,8740,02:58.1,3,126.4285714,178100,47:58.6,20.31428571,2878600,4
+1389,8760,02:55.4,3,127,175400,48:05.6,18.96857143,2885600,4
+1390,8780,03:12.6,3,127.4857143,192600,48:13.3,18.59714286,2893300,4
+1391,8800,03:05.2,3,127.2571429,185200,48:20.7,19.44,2900700,4
+1392,8820,02:58.9,3,128.8571429,178900,48:27.9,21.48857143,2907900,4
+1393,8840,02:45.6,3,130.6285714,165600,48:34.5,18.81714286,2914500,4
+1394,8860,03:02.4,3,130.7714286,182400,48:41.8,16.06,2921800,4
+1395,8880,03:28.6,3,128.5714286,208600,48:50.1,15.00857143,2930100,4
+1396,8900,03:20.8,3,127.4285714,200800,48:58.2,17.34571429,2938200,4
+1397,8920,02:52.7,3,126.8285714,172700,49:05.1,18.52571429,2945100,4
+1398,8940,02:50.3,3,127,170300,49:11.9,19.74857143,2951900,4
+1399,8960,02:54.6,3,127,174600,49:18.9,20.26571429,2958900,4
+1400,8980,02:47.6,3,126.8285714,167600,49:25.6,20.20571429,2965600,4
+1401,9000,02:43.7,3,127.2571429,163700,49:32.1,19.37142857,2972100,4
+1402,9020,02:46.0,3,129.0857143,166000,49:38.8,19.47142857,2978800,4
+1403,9040,02:57.0,3,131.8285714,177000,49:45.8,20.43714286,2985800,4
+1404,9060,02:35.5,3,133.8285714,155500,49:52.1,20.92857143,2992100,4
+1405,9080,02:28.8,3,135.3428571,148800,49:58.0,20.89714286,2998000,4
+1406,9100,02:30.4,3,136.7428571,150400,50:04.0,21.40285714,3004000,4
+1407,9120,02:26.5,3,138.0857143,146500,50:09.9,22.31142857,3009900,4
+1408,9140,02:26.9,3,138.9142857,146900,50:15.8,22.7,3015800,4
+1409,9160,02:36.7,3,140.2571429,156700,50:22.0,22.59428571,3022000,4
+1410,9180,02:30.0,3,141.7428571,150000,50:28.0,22.43142857,3028000,4
+1411,9200,02:29.2,3,143.0857143,149200,50:34.0,22.20857143,3034000,4
+1412,9220,02:27.3,3,144.2571429,147300,50:39.9,21.71142857,3039900,4
+1413,9240,02:35.5,3,146.0285714,155500,50:46.1,23.12857143,3046100,4
+1414,9260,03:08.3,3,138.9714286,188300,50:53.6,22.98857143,3053600,4
+1415,9280,04:01.4,3,126.3428571,241400,51:03.3,13.11142857,3063300,4
+1417,9320,03:36.4,3,117.5714286,216400,51:25.0,11.70571429,3085000,4
+1418,9340,03:51.3,3,119.9142857,231300,51:34.3,19.73714286,3094300,4
+1419,9360,03:22.0,3,122.0857143,202000,51:42.3,18.46857143,3102300,4
+1420,9380,03:16.1,3,125.7142857,196100,51:50.2,15.80285714,3110200,4
+1421,9400,03:25.9,3,118.5714286,205900,51:58.4,16.25428571,3118400,4
+1423,9440,03:14.2,3,110.0285714,194200,52:23.5,20.32285714,3143500,4
+1424,9460,02:58.9,3,118.1428571,178900,52:30.7,19.28285714,3150700,4
+1425,9480,02:50.3,3,122.3142857,170300,52:37.5,17.68,3157500,4
+1426,9500,04:10.0,3,127.4571429,250000,52:47.5,17.38,3167500,4
+1427,9520,03:45.0,3,126.8857143,225000,52:56.5,16.28,3176500,4
diff --git a/rowers/tests/testdata/fake_strokedata.csv b/rowers/tests/testdata/fake_strokedata.csv
new file mode 100644
index 00000000..558cb86c
--- /dev/null
+++ b/rowers/tests/testdata/fake_strokedata.csv
@@ -0,0 +1,192 @@
+,id,time,hr,pace,spm,cumdist,ftime,fpace,driveenergy,power,averageforce,drivelength,peakforce,forceratio,distance,drivespeed,workoutid,equivergpower,ergpace,fergpace,fnowindpace,hr_an,hr_at,hr_bottom,hr_max,hr_tr,hr_ut1,hr_ut2,nowindpace,x_right,workoutstate,catch,finish,peakforceangle,wash,slip,rhythm,effectiveangle,totalangle,efficiency,distanceperstroke,velo
+0,39799136,0.0,126.976190476,267517.544209,1.33333333333,5.4,05:50.0,04:27.5,88.1806760867,19.35721935,102.30906,0.826870748299,209.06634,0.499922562048,5.4,0.85119047619,3252,50.0,191293.118277,03:11.2,04:27.5,0,0,0,0,0,127,0,267517.544209,3.5326e+11,4,0.0,0.0,0.0,0.0,0.0,37.7952755906,0.0,0.0,94.4426720529,84.1066333294,1.86903629621
+1,39799137,3240.00000954,127.095238095,230263.518558,15.5714285714,13.1,00:03.2,03:50.2,220.103927167,25.6355755264,188.604528,1.21267573696,299.810028,0.600977358387,13.1,0.8736913205,3252,50.0,191293.118277,03:11.2,03:50.2,0,0,0,0,0,127,0,230263.518558,6500000000.0,4,0.0,0.0,0.0,0.0,0.0,44.6202531646,0.0,0.0,111.827743719,8.36695937183,2.17142517031
+2,39799138,6150.00009537,127.880952381,201258.643579,21.4285714286,21.0,00:06.1,03:21.2,273.846587402,44.6485827564,195.276858,1.36636621315,310.485756,0.641492073477,21.0,1.29492362983,3252,50.0,191293.118277,03:11.2,03:21.2,0,0,0,0,0,128,0,201258.643579,9020000000.0,4,0.0,0.0,0.0,0.0,0.0,37.7224199288,0.0,0.0,96.1605065241,6.95622297311,2.48436534754
+3,39799139,9269.99998093,129.0,180582.4977,21.9047619048,30.3,00:09.2,03:00.5,278.525981193,64.2054260988,201.059544,1.37036281179,322.49595,0.643049698939,30.3,1.38929798724,3252,50.0,191293.118277,03:11.2,03:00.5,0,0,0,0,0,129,0,180582.4977,12420000000.0,4,0.0,0.0,0.0,0.0,0.0,34.1549295775,0.0,0.0,92.5698041753,7.58415258861,2.76881761171
+4,39799140,12150.0000954,129.952380952,168216.324384,20.380952381,39.0,00:12.1,02:48.2,271.853383897,73.72570625,206.84223,1.32583900227,323.830416,0.627589324063,39.0,1.40372670807,3252,50.0,191293.118277,03:11.2,02:48.2,0,0,0,0,0,130,0,168216.324384,15020000000.0,4,0.0,0.0,0.0,0.0,0.0,33.9483394834,0.0,0.0,99.7343324777,8.75041481387,2.97236312725
+5,39799141,15150.0000954,130.761904762,163348.980307,20.2380952381,48.2,00:15.1,02:43.3,271.598579567,80.0701191136,201.949188,1.29342403628,323.385594,0.628837587302,48.2,1.40838509317,3252,50.0,191293.118277,03:11.2,02:43.3,0,0,0,0,0,131,0,163348.980307,18130000000.0,4,0.0,0.0,0.0,0.0,0.0,32.7402135231,0.0,0.0,100.287842053,9.07476090999,3.06093125932
+6,39799142,18150.0000954,131.380952381,161595.916202,20.4285714286,57.6,00:18.1,02:41.5,272.398664053,82.9313928352,221.521356,1.28757369615,354.967956,0.633692860915,57.6,1.4380952381,3252,50.0,191293.118277,03:11.2,02:41.5,0,0,0,0,0,131,0,161595.916202,21140000000.0,4,0.0,0.0,0.0,0.0,0.0,32.1428571429,0.0,0.0,100.013342349,9.08767686119,3.09413759798
+7,39799143,20910.0000858,131.761904762,160946.930227,20.3333333333,66.4,00:20.9,02:40.9,269.06750204,86.6028089332,214.404204,1.29693877551,334.950966,0.632028077529,66.4,1.50830564784,3252,50.0,191293.118277,03:11.2,02:40.9,0,0,0,0,0,132,0,160946.930227,23710000000.0,4,0.0,0.0,0.0,0.0,0.0,31.1594202899,0.0,0.0,96.9366423557,9.16705794878,3.10661408264
+8,39799144,23819.9999332,131.857142857,160556.046845,20.1904761905,75.5,00:23.8,02:40.5,301.07501704,85.9423518548,215.293848,1.31319727891,337.619898,0.630773850875,75.5,1.48376623377,3252,50.0,191293.118277,03:11.2,02:40.5,0,0,0,0,0,132,0,160556.046845,26730000000.0,4,0.0,0.0,0.0,0.0,0.0,32.1167883212,0.0,0.0,98.396762766,9.25439487206,3.11417732203
+9,39799145,26940.0000572,132.047619048,156621.552107,20.7619047619,85.1,00:26.9,02:36.6,346.52959188,87.8502695392,234.866016,1.34163265306,381.657276,0.623563414808,85.1,1.50240770465,3252,50.0,191293.118277,03:11.2,02:36.6,0,0,0,0,0,132,0,156621.552107,29930000000.0,4,0.0,0.0,0.0,0.0,0.0,32.962962963,0.0,0.0,103.69799887,9.22576815896,3.19240866453
+10,39799146,29640.0001049,132.285714286,150480.356059,21.0952380952,95.0,00:29.6,02:30.4,395.87381738,99.6207143932,324.72006,1.37176870748,532.007112,0.612977608416,95.0,1.60465116279,3252,50.0,191293.118277,03:11.2,02:30.4,0,0,0,0,0,132,0,150480.356059,32470000000.0,4,0.0,0.0,0.0,0.0,0.0,32.5757575758,0.0,0.0,103.104818509,9.45054845301,3.32269282911
+11,39799147,32369.9998856,132.952380952,143847.653479,21.1904761905,105.0,00:32.3,02:23.8,441.03471892,126.436932947,314.044332,1.39544217687,521.331384,0.594869267431,105.0,1.70731707317,3252,50.0,191293.118277,03:11.2,02:23.8,0,0,0,0,0,133,0,143847.653479,35110000000.0,4,0.0,0.0,0.0,0.0,0.0,31.5384615385,0.0,0.0,93.0005991502,9.84187300133,3.47589959174
+12,39799148,35190.0000572,133.904761905,138421.986347,21.2857142857,115.3,00:35.1,02:18.4,462.78370054,134.706308388,312.709866,1.40442176871,529.783002,0.585113064034,115.3,1.773960217,3252,50.0,191293.118277,03:11.2,02:18.4,0,0,0,0,0,134,0,138421.986347,38010000000.0,4,0.0,0.0,0.0,0.0,0.0,30.0380228137,0.0,0.0,97.9636321096,10.1818794134,3.61214293477
+13,39799149,38009.9999905,134.904761905,135418.044204,21.1904761905,125.8,00:38.0,02:15.4,462.60068806,138.97288125,338.06472,1.40095238095,608.961318,0.572328332569,125.8,1.7967032967,3252,50.0,191293.118277,03:11.2,02:15.4,0,0,0,0,0,135,0,135418.044204,40820000000.0,4,0.0,0.0,0.0,0.0,0.0,30.0,0.0,0.0,101.416442286,10.4545176782,3.69227013238
+14,39799150,40890.0001049,136.047619048,134197.799472,21.3333333333,136.6,00:40.8,02:14.1,467.18302038,146.360682773,335.395788,1.39530612245,576.04449,0.573372604334,136.6,1.8107606679,3252,50.0,191293.118277,03:11.2,02:14.1,0,0,0,0,0,136,0,134197.799472,43770000000.0,4,0.0,0.0,0.0,0.0,0.0,29.8449612403,0.0,0.0,98.9480942562,10.4789348673,3.72584350838
+15,39799151,43680.0000668,137.428571429,133465.452616,21.5238095238,147.2,00:43.6,02:13.4,462.1348051,149.79272233,342.068118,1.38816326531,601.844166,0.577043192957,147.2,1.77838827839,3252,50.0,191293.118277,03:11.2,02:13.4,0,0,0,0,0,137,0,133465.452616,46480000000.0,4,0.0,0.0,0.0,0.0,0.0,29.8850574713,0.0,0.0,98.2812654729,10.4431917205,3.74628782355
+16,39799152,46470.0000286,138.619047619,133276.640695,21.7619047619,157.6,00:46.4,02:13.2,463.22873436,152.311202593,319.382196,1.37918367347,535.120866,0.577917524111,157.6,1.84380952381,3252,50.0,191293.118277,03:11.2,02:13.2,0,0,0,0,0,139,0,133276.640695,49260000000.0,4,0.0,0.0,0.0,0.0,0.0,28.8461538462,0.0,0.0,97.0675536464,10.3435665207,3.75159515871
+17,39799153,49200.0000477,139.714285714,133039.90291,21.7142857143,167.8,00:49.2,02:13.0,461.2763289,145.54018967,332.726856,1.37448979592,587.609862,0.573139687516,167.8,1.82857142857,3252,50.0,191293.118277,03:11.2,02:13.0,0,0,0,0,0,140,0,133039.90291,51900000000.0,4,0.0,0.0,0.0,0.0,0.0,29.8804780876,0.0,0.0,102.126712018,10.3846959983,3.75827093273
+18,39799154,51960.0000381,140.380952381,133170.997419,21.2857142857,178.5,00:51.9,02:13.1,461.2964518,149.554325469,360.30582,1.37319727891,644.102256,0.573214309195,178.5,1.8007518797,3252,50.0,191293.118277,03:11.2,02:13.1,0,0,0,0,0,140,0,133170.997419,54760000000.0,4,0.0,0.0,0.0,0.0,0.0,29.0076335878,0.0,0.0,99.0923455439,10.5833552385,3.75457126319
+19,39799155,54660.0000858,140.80952381,133152.931686,21.2380952381,188.5,00:54.6,02:13.1,467.16277644,154.735851561,320.716662,1.37183673469,551.134458,0.566265126248,188.5,1.83619047619,3252,50.0,191293.118277,03:11.2,02:13.1,0,0,0,0,0,141,0,133152.931686,57340000000.0,4,0.0,0.0,0.0,0.0,0.0,28.7356321839,0.0,0.0,95.8131009692,10.6085238675,3.75508067055
+20,39799156,57539.9999619,141.19047619,132699.130953,21.4761904762,199.3,00:57.5,02:12.6,460.85166006,147.538156497,338.06472,1.37285714286,587.16504,0.580181755545,199.3,1.78478664193,3252,50.0,191293.118277,03:11.2,02:12.6,0,0,0,0,0,141,0,132699.130953,60400000000.0,4,0.0,0.0,0.0,0.0,0.0,29.8449612403,0.0,0.0,101.521834232,10.5267892646,3.76792218917
+21,39799157,60269.9999809,141.714285714,132964.959531,21.5714285714,209.4,01:00.2,02:12.9,451.775748,150.748843213,337.619898,1.37,588.054684,0.586801841858,209.4,1.84555984556,3252,50.0,191293.118277,03:11.2,02:12.9,0,0,0,0,0,142,0,132964.959531,62950000000.0,4,0.0,0.0,0.0,0.0,0.0,29.718875502,0.0,0.0,98.7648569306,10.4593607348,3.76038921655
+22,39799158,62849.9999046,142.238095238,133493.269817,21.8571428571,219.4,01:02.8,02:13.4,456.8960426,150.868643612,327.833814,1.36394557823,537.344976,0.590718880399,219.4,1.82285714286,3252,50.0,191293.118277,03:11.2,02:13.4,0,0,0,0,0,142,0,133493.269817,65500000000.0,4,0.0,0.0,0.0,0.0,0.0,30.0,0.0,0.0,97.5193832126,10.2817844037,3.74550717565
+23,39799159,65730.0000191,143.142857143,133423.241182,22.1428571429,230.2,01:05.7,02:13.4,450.13396144,148.010908576,332.726856,1.3562585034,574.265202,0.587126683943,230.2,1.80761904762,3252,50.0,191293.118277,03:11.2,02:13.4,0,0,0,0,0,143,0,133423.241182,68620000000.0,4,0.0,0.0,0.0,0.0,0.0,28.9575289575,0.0,0.0,99.5588474118,10.1544430916,3.7474730457
+24,39799160,68400.0000954,143.952380952,133559.338288,22.3333333333,240.2,01:08.4,02:13.5,451.23542544,147.06641215,336.730254,1.34823129252,572.485914,0.581344675244,240.2,1.8,3252,50.0,191293.118277,03:11.2,02:13.5,0,0,0,0,0,144,0,133559.338288,71060000000.0,4,0.0,0.0,0.0,0.0,0.0,30.487804878,0.0,0.0,99.8922443414,10.0575788957,3.74365436675
+25,39799161,71039.9999619,144.714285714,133228.128188,22.7619047619,250.1,01:11.0,02:13.2,448.59990048,150.0313724,332.726856,1.34,596.951124,0.572068554427,250.1,1.83170254403,3252,50.0,191293.118277,03:11.2,02:13.2,0,0,0,0,0,145,0,133228.128188,73670000000.0,4,0.0,0.0,0.0,0.0,0.0,29.9180327869,0.0,0.0,98.650248521,9.89274299446,3.75296123123
+26,39799162,73500.0,145.142857143,132852.649371,22.9047619048,259.6,01:13.5,02:12.8,447.82781658,151.46859775,340.733652,1.33578231293,588.054684,0.573409353633,259.6,1.85515873016,3252,50.0,191293.118277,03:11.2,02:12.8,0,0,0,0,0,145,0,132852.649371,75990000000.0,4,0.0,0.0,0.0,0.0,0.0,29.6296296296,0.0,0.0,98.5450423905,9.85882717413,3.76356815139
+27,39799163,76349.9999046,144.952380952,132705.854989,22.6666666667,270.3,01:16.3,02:12.7,445.93296564,152.311202593,325.609704,1.33557823129,566.258406,0.568538870911,270.3,1.82974559687,3252,50.0,191293.118277,03:11.2,02:12.7,0,0,0,0,0,145,0,132705.854989,79190000000.0,4,0.0,0.0,0.0,0.0,0.0,28.8537549407,0.0,0.0,98.3254503049,9.97340631186,3.76773127337
+28,39799164,79079.9999237,144.714285714,133013.725151,22.4761904762,280.6,01:19.0,02:13.0,446.46711516,149.43522195,341.623296,1.33843537415,600.954522,0.574029662749,280.6,1.80694980695,3252,50.0,191293.118277,03:11.2,02:13.0,0,0,0,0,0,145,0,133013.725151,81820000000.0,4,0.0,0.0,0.0,0.0,0.0,29.0196078431,0.0,0.0,99.5235141066,10.0346468847,3.75901057903
+29,39799165,81750.0,144.666666667,133278.99447,22.3333333333,290.7,01:21.7,02:13.2,453.9702032,149.79272233,332.282034,1.33891156463,593.392548,0.562905554475,290.7,1.83953033268,3252,50.0,191293.118277,03:11.2,02:13.2,0,0,0,0,0,144,0,133278.99447,84420000000.0,4,0.0,0.0,0.0,0.0,0.0,29.5546558704,0.0,0.0,98.6943311289,10.0787343679,3.75152890362
+30,39799166,84450.0000477,144.714285714,132845.542123,22.3333333333,300.8,01:24.4,02:12.8,461.67512544,149.316181683,341.623296,1.34027210884,594.727014,0.561184618018,300.8,1.83561643836,3252,50.0,191293.118277,03:11.2,02:12.8,0,0,0,0,0,145,0,132845.542123,87140000000.0,4,0.0,0.0,0.0,0.0,0.0,29.0836653386,0.0,0.0,99.9816299192,10.1116195592,3.76376950261
+31,39799167,87180.0000668,144.761904762,132433.757101,22.1428571429,311.1,01:27.1,02:12.4,462.93860148,152.070140328,357.636888,1.34319727891,661.450314,0.558028598825,311.1,1.80888030888,3252,50.0,191293.118277,03:11.2,02:12.4,0,0,0,0,0,145,0,132433.757101,89860000000.0,4,0.0,0.0,0.0,0.0,0.0,29.6,0.0,0.0,99.0895822785,10.2303124168,3.77547243954
+32,39799168,89789.9999619,145.142857143,132296.93032,21.8571428571,321.2,01:29.7,02:12.2,463.39797854,156.571128627,336.730254,1.34659863946,588.499506,0.560523315593,321.2,1.87301587302,3252,50.0,191293.118277,03:11.2,02:12.2,0,0,0,0,0,145,0,132296.93032,92460000000.0,4,0.0,0.0,0.0,0.0,0.0,29.0322580645,0.0,0.0,96.5399478842,10.374760898,3.77937718428
+33,39799169,92670.0000763,145.333333333,132417.814657,21.5714285714,331.9,01:32.6,02:12.4,459.09860748,150.150792431,340.28883,1.35204081633,612.075072,0.565722937216,331.9,1.83011583012,3252,50.0,191293.118277,03:11.2,02:12.4,0,0,0,0,0,145,0,132417.814657,95510000000.0,4,0.0,0.0,0.0,0.0,0.0,29.1338582677,0.0,0.0,100.39247635,10.502578376,3.77592698757
+34,39799170,95339.9999142,145.571428571,132644.156173,21.7142857143,342.0,01:35.3,02:12.6,457.32419134,150.988507466,334.950966,1.35741496599,579.158244,0.570439059313,342.0,1.83204633205,3252,50.0,191293.118277,03:11.2,02:12.6,0,0,0,0,0,146,0,132644.156173,98030000000.0,4,0.0,0.0,0.0,0.0,0.0,29.718875502,0.0,0.0,99.3252778037,10.4156789656,3.76948381613
+35,39799171,98069.9999332,146.0,132824.170064,21.8571428571,352.4,01:38.0,02:12.8,465.83169956,150.868643612,341.178474,1.35972789116,592.058082,0.573613897901,352.4,1.83783783784,3252,50.0,191293.118277,03:11.2,02:12.8,0,0,0,0,0,146,0,132824.170064,1.008e+11,4,0.0,0.0,0.0,0.0,0.0,29.1338582677,0.0,0.0,99.0005769733,10.3335787375,3.76437511153
+36,39799172,100859.999895,146.428571429,132399.04606,22.0952380952,363.0,01:40.8,02:12.3,469.36640042,153.399135658,346.96116,1.36340136054,621.416334,0.570446901224,363.0,1.84362934363,3252,50.0,191293.118277,03:11.2,02:12.3,0,0,0,0,0,146,0,132399.04606,1.0364e+11,4,0.0,0.0,0.0,0.0,0.0,28.5714285714,0.0,0.0,98.3083854908,10.255048364,3.77646225467
+37,39799173,103619.999886,146.666666667,132245.976211,22.0952380952,373.4,01:43.6,02:12.2,468.9419434,152.4318292,347.405982,1.36897959184,592.502904,0.567916935654,373.4,1.84555984556,3252,50.0,191293.118277,03:11.2,02:12.2,0,147,0,0,0,0,0,132245.976211,1.0637e+11,4,0.0,0.0,0.0,0.0,0.0,28.90625,0.0,0.0,99.2761628163,10.266918205,3.78083337072
+38,39799174,106380.000114,146.857142857,132500.471593,21.8571428571,383.9,01:46.3,02:12.5,470.1816956,152.914972515,337.619898,1.37258503401,619.192224,0.565878523172,383.9,1.80827067669,3252,50.0,191293.118277,03:11.2,02:12.5,0,147,0,0,0,0,0,132500.471593,1.0915e+11,4,0.0,0.0,0.0,0.0,0.0,29.4573643411,0.0,0.0,98.3933531887,10.3588236563,3.7735714748
+39,39799175,109230.000019,147.142857143,132775.418655,21.7142857143,394.6,01:49.2,02:12.7,466.5370299,151.46859775,334.061322,1.37394557823,574.265202,0.565880568251,394.6,1.83619047619,3252,50.0,191293.118277,03:11.2,02:12.7,0,147,0,0,0,0,0,132775.418655,1.121e+11,4,0.0,0.0,0.0,0.0,0.0,28.1954887218,0.0,0.0,98.7171028208,10.4053819703,3.76575728448
+40,39799176,111960.000038,147.333333333,132878.01379,21.7619047619,405.0,01:51.9,02:12.8,468.16105384,148.603267434,350.519736,1.37340136054,627.643842,0.56601972006,405.0,1.8045112782,3252,50.0,191293.118277,03:11.2,02:12.8,0,147,0,0,0,0,0,132878.01379,1.1469e+11,4,0.0,0.0,0.0,0.0,0.0,29.6875,0.0,0.0,100.38765333,10.3745966648,3.7628497427
+41,39799177,114690.000057,147.666666667,133014.526935,21.5714285714,415.3,01:54.6,02:13.0,461.97357982,151.82933255,334.061322,1.37108843537,586.275396,0.572604512571,415.3,1.85135135135,3252,50.0,191293.118277,03:11.2,02:13.0,0,148,0,0,0,0,0,133014.526935,1.1741e+11,4,0.0,0.0,0.0,0.0,0.0,29.2490118577,0.0,0.0,97.9524129494,10.4554630901,3.7589879205
+42,39799178,117630.000114,147.857142857,133297.852527,21.5714285714,426.0,01:57.6,02:13.2,467.13796324,150.509432707,343.402584,1.36891156463,590.723616,0.576219283059,426.0,1.85135135135,3252,50.0,191293.118277,03:11.2,02:13.2,0,148,0,0,0,0,0,133297.852527,1.2046e+11,4,0.0,0.0,0.0,0.0,0.0,28.0303030303,0.0,0.0,98.182676506,10.4332399244,3.75099816329
+43,39799179,120329.999924,148.142857143,133012.600446,21.7619047619,436.5,02:00.3,02:13.0,468.43324254,149.316181683,326.054526,1.37163265306,572.485914,0.574708892977,436.5,1.78107606679,3252,50.0,191293.118277,03:11.2,02:13.0,0,148,0,0,0,0,0,133012.600446,1.2316e+11,4,0.0,0.0,0.0,0.0,0.0,29.5019157088,0.0,0.0,99.605384492,10.3640992963,3.75904236383
+44,39799180,123150.000095,148.238095238,132741.318404,21.7142857143,446.9,02:03.1,02:12.7,473.53595608,148.603267434,365.643684,1.37421768707,627.19902,0.56297996655,446.9,1.85328185328,3252,50.0,191293.118277,03:11.2,02:12.7,0,148,0,0,0,0,0,132741.318404,1.2586e+11,4,0.0,0.0,0.0,0.0,0.0,29.1338582677,0.0,0.0,100.698106743,10.408055035,3.76672467933
+45,39799181,125670.000076,148.714285714,132116.286996,21.9523809524,456.9,02:05.6,02:12.1,480.02140032,156.448327748,339.399186,1.37891156463,636.985104,0.552002776041,456.9,1.84380952381,3252,50.0,191293.118277,03:11.2,02:12.1,0,149,0,0,0,0,0,132116.286996,1.2827e+11,4,0.0,0.0,0.0,0.0,0.0,29.4117647059,0.0,0.0,97.0125766755,10.3438750147,3.78454474744
+46,39799182,128490.00001,149.285714286,131446.06373,22.0476190476,467.6,02:08.4,02:11.4,480.97186692,155.223848632,342.068118,1.38394557823,624.97491,0.553015355989,467.6,1.86486486486,3252,50.0,191293.118277,03:11.2,02:11.4,0,149,0,0,0,0,0,131446.06373,1.3133e+11,4,0.0,0.0,0.0,0.0,0.0,29.2490118577,0.0,0.0,99.2811596511,10.3517070508,3.80384155913
+47,39799183,131369.999886,149.761904762,131579.319767,21.5714285714,478.5,02:11.3,02:11.5,468.43309124,155.590518989,351.854202,1.38789115646,628.978308,0.551216571488,478.5,1.80333951763,3252,50.0,191293.118277,03:11.2,02:11.5,0,150,0,0,0,0,0,131579.319767,1.3423e+11,4,0.0,0.0,0.0,0.0,0.0,28.624535316,0.0,0.0,98.7465666185,10.5695065097,3.79998924517
+48,39799184,134190.000057,150.047619048,132379.219894,21.380952381,489.0,02:14.1,02:12.3,470.22868938,154.370525725,329.16828,1.38278911565,575.599668,0.565640526729,489.0,1.84761904762,3252,50.0,191293.118277,03:11.2,02:12.3,0,150,0,0,0,0,0,132379.219894,1.3698e+11,4,0.0,0.0,0.0,0.0,0.0,28.9575289575,0.0,0.0,97.7336703229,10.5992318221,3.77702784771
+49,39799185,136799.999952,150.047619048,132686.986271,21.380952381,499.1,02:16.8,02:12.6,472.07330872,148.366134605,337.619898,1.37421768707,615.633648,0.55548126898,499.1,1.78849721707,3252,50.0,191293.118277,03:11.2,02:12.6,0,150,0,0,0,0,0,132686.986271,1.3944e+11,4,0.0,0.0,0.0,0.0,0.0,29.5019157088,0.0,0.0,100.983000825,10.5746469908,3.7682670626
+50,39799186,139710.000038,149.666666667,132806.105783,21.5714285714,510.0,02:19.7,02:12.8,463.49638406,150.748843213,351.854202,1.35707482993,620.971512,0.552332697655,510.0,1.82818532819,3252,50.0,191293.118277,03:11.2,02:12.8,0,150,0,0,0,0,0,132806.105783,1.4262e+11,4,0.0,0.0,0.0,0.0,0.0,28.6821705426,0.0,0.0,99.1196886936,10.47187152,3.7648871417
+51,39799187,142319.999933,149.428571429,132924.920461,21.9523809524,519.9,02:22.3,02:12.9,467.38403756,152.79409112,351.40938,1.34034013605,670.791576,0.553274143388,519.9,1.86706349206,3252,50.0,191293.118277,03:11.2,02:12.9,0,149,0,0,0,0,0,132924.920461,1.4491e+11,4,0.0,0.0,0.0,0.0,0.0,28.125,0.0,0.0,97.5309057756,10.2809492407,3.76152190474
+52,39799188,145200.000048,149.0,132760.275263,22.0952380952,530.6,02:25.2,02:12.7,452.0791045,151.2284256,329.16828,1.33054421769,567.592872,0.55928136473,530.6,1.81604696673,3252,50.0,191293.118277,03:11.2,02:12.7,0,149,0,0,0,0,0,132760.275263,1.4807e+11,4,0.0,0.0,0.0,0.0,0.0,28.6274509804,0.0,0.0,98.9077177669,10.2271452662,3.76618682818
+53,39799189,147869.999886,148.666666667,133445.996984,22.0,540.8,02:27.8,02:13.4,441.90542016,147.774406503,347.405982,1.33142857143,610.740606,0.57052466683,540.8,1.81996086106,3252,50.0,191293.118277,03:11.2,02:13.4,0,149,0,0,0,0,0,133445.996984,1.5058e+11,4,0.0,0.0,0.0,0.0,0.0,28.9682539683,0.0,0.0,99.6671795686,10.2186382092,3.74683401003
+54,39799190,150569.999933,148.285714286,133974.160675,22.0,550.8,02:30.5,02:13.9,439.90544598,148.8406528,310.930578,1.33653061224,547.575882,0.579100196408,550.8,1.81081081081,3252,50.0,191293.118277,03:11.2,02:13.9,0,148,0,0,0,0,0,133974.160675,1.5324e+11,4,0.0,0.0,0.0,0.0,0.0,29.8387096774,0.0,0.0,97.7875000321,10.1783534733,3.73206294022
+55,39799191,153210.000038,147.714285714,133996.497711,22.0,560.8,02:33.2,02:13.9,447.03488354,144.373384534,338.06472,1.34952380952,574.265202,0.563329080487,560.8,1.8,3252,50.0,191293.118277,03:11.2,02:13.9,0,148,0,0,0,0,0,133996.497711,1.5589e+11,4,0.0,0.0,0.0,0.0,0.0,30.1204819277,0.0,0.0,100.762878325,10.1766567555,3.73144081033
+56,39799192,155910.000086,147.238095238,133634.43276,22.0,571.0,02:35.9,02:13.6,445.222945,149.078290838,333.171678,1.35891156463,610.295784,0.562404477497,571.0,1.80761904762,3252,50.0,191293.118277,03:11.2,02:13.6,0,147,0,0,0,0,0,133634.43276,1.586e+11,4,0.0,0.0,0.0,0.0,0.0,30.0,0.0,0.0,98.3781192719,10.2042290708,3.74155065931
+57,39799193,158460.000038,147.047619048,133400.917518,21.9047619048,580.7,02:38.4,02:13.4,456.42734546,150.270275814,330.502746,1.36496598639,607.18203,0.554919999296,580.7,1.82666666667,3252,50.0,191293.118277,03:11.2,02:13.4,0,147,0,0,0,0,0,133400.917518,1.6102e+11,4,0.0,0.0,0.0,0.0,0.0,30.0,0.0,0.0,98.1111826798,10.2665352149,3.74810015781
+58,39799194,161250.0,146.904761905,132778.406555,22.0476190476,591.2,02:41.2,02:12.7,447.8955082,150.748843213,325.164882,1.36598639456,564.034296,0.554629386616,591.2,1.81904761905,3252,50.0,191293.118277,03:11.2,02:12.7,0,147,0,0,0,0,0,132778.406555,1.6404e+11,4,0.0,0.0,0.0,0.0,0.0,30.2419354839,0.0,0.0,99.1817344353,10.247834569,3.76567254399
+59,39799195,163950.000048,147.0,132807.06861,22.4285714286,601.4,02:43.9,02:12.8,451.54855592,150.270275814,338.954364,1.36346938776,613.85436,0.570959970779,601.4,1.79511278195,3252,50.0,191293.118277,03:11.2,02:12.8,0,147,0,0,0,0,0,132807.06861,1.6664e+11,4,0.0,0.0,0.0,0.0,0.0,30.4,0.0,0.0,99.4331936049,10.0715995905,3.76485984694
+60,39799196,166619.999886,147.0,132572.347555,22.619047619,611.4,02:46.6,02:12.5,457.20073054,153.277999204,324.72006,1.35414965986,551.134458,0.586617053679,611.4,1.85518590998,3252,50.0,191293.118277,03:11.2,02:12.5,0,147,0,0,0,0,0,132572.347555,1.6927e+11,4,0.0,0.0,0.0,0.0,0.0,29.5546558704,0.0,0.0,98.0007459534,10.0044678542,3.77152557995
+61,39799197,169380.000114,146.904761905,132377.004331,22.5238095238,621.8,02:49.3,02:12.3,462.75156442,151.108434789,352.743846,1.34925170068,590.278794,0.589285589269,621.8,1.82432432432,3252,50.0,191293.118277,03:11.2,02:12.3,0,147,0,0,0,0,0,132377.004331,1.7212e+11,4,0.0,0.0,0.0,0.0,0.0,29.0196078431,0.0,0.0,99.8485335066,10.0615956434,3.77709106295
+62,39799198,172049.999952,147.047619048,132122.128079,22.4761904762,632.1,02:52.0,02:12.1,470.00379706,154.8577548,350.519736,1.34394557823,582.71682,0.595205660521,632.1,1.85912698413,3252,50.0,191293.118277,03:11.2,02:12.1,0,147,0,0,0,0,0,132122.128079,1.7475e+11,4,0.0,0.0,0.0,0.0,0.0,28.6852589641,0.0,0.0,97.9960127045,10.1023634884,3.78437743374
+63,39799199,174720.000029,147.333333333,131614.148435,22.380952381,642.3,02:54.7,02:11.6,480.06373406,154.127294899,349.18527,1.34401360544,607.626852,0.589862706687,642.3,1.82239382239,3252,50.0,191293.118277,03:11.2,02:11.6,0,147,0,0,0,0,0,131614.148435,1.7739e+11,4,0.0,0.0,0.0,0.0,0.0,29.718875502,0.0,0.0,99.6049114541,10.1845094001,3.79898366511
+64,39799200,177299.999952,147.571428571,130772.700382,22.6666666667,652.0,02:57.3,02:10.7,480.81046008,157.3092836,366.088506,1.34333333333,620.52669,0.586295170744,652.0,1.8893360161,3252,50.0,191293.118277,03:11.2,02:10.7,0,148,0,0,0,0,0,130772.700382,1.798e+11,4,0.0,0.0,0.0,0.0,0.0,28.8617886179,0.0,0.0,99.486102197,10.120838737,3.82342796731
+65,39799201,180180.000067,148.0,130148.629,22.9047619048,662.7,03:00.1,02:10.1,485.54760256,162.163914945,357.636888,1.34693877551,607.18203,0.583353561525,662.7,1.87301587302,3252,50.0,191293.118277,03:11.2,02:10.1,0,148,0,0,0,0,0,130148.629,1.8297e+11,4,0.0,0.0,0.0,0.0,0.0,29.0322580645,0.0,0.0,97.9027816141,10.063658141,3.84176156016
+66,39799202,182670.000076,148.428571429,129649.404112,22.7619047619,673.1,03:02.6,02:09.6,489.00093428,162.541430374,362.52993,1.34544217687,621.861156,0.587668878441,673.1,1.8893360161,3252,50.0,191293.118277,03:11.2,02:09.6,0,148,0,0,0,0,0,129649.404112,1.8535e+11,4,0.0,0.0,0.0,0.0,0.0,28.5140562249,0.0,0.0,98.8080644551,10.1658132625,3.85655455513
+67,39799203,185430.000067,148.571428571,129434.345963,22.2380952381,683.6,03:05.4,02:09.4,483.88687324,162.793432547,360.30582,1.34448979592,622.305978,0.579260719162,683.6,1.87698412698,3252,50.0,191293.118277,03:11.2,02:09.4,0,149,0,0,0,0,0,129434.345963,1.8813e+11,4,0.0,0.0,0.0,0.0,0.0,28.8,0.0,0.0,99.1476815574,10.4225535544,3.86296230944
+68,39799204,188039.999962,149.0,129521.611571,22.1904761905,693.8,03:08.0,02:09.5,488.07812532,162.163914945,366.088506,1.33972789116,626.754198,0.574143842725,693.8,1.88329979879,3252,50.0,191293.118277,03:11.2,02:09.5,0,149,0,0,0,0,0,129521.611571,1.9069e+11,4,0.0,0.0,0.0,0.0,0.0,28.6290322581,0.0,0.0,99.3315255298,10.4378822505,3.86035962599
+69,39799205,190589.999914,149.333333333,129450.495129,22.0952380952,703.8,03:10.5,02:09.4,485.5135298,163.930665884,355.412778,1.33823129252,634.316172,0.577472776375,703.8,1.85714285714,3252,50.0,191293.118277,03:11.2,02:09.4,0,149,0,0,0,0,0,129450.495129,1.9313e+11,4,0.0,0.0,0.0,0.0,0.0,28.9156626506,0.0,0.0,98.4230215789,10.4886321163,3.8624803984
+70,39799206,193410.000086,149.714285714,129612.827283,22.4761904762,714.7,03:13.4,02:09.6,476.80902898,162.163914945,371.42637,1.33734693878,640.988502,0.575938050313,714.7,1.93581780538,3252,50.0,191293.118277,03:11.2,02:09.6,0,150,0,0,0,0,0,129612.827283,1.9624e+11,4,0.0,0.0,0.0,0.0,0.0,27.380952381,0.0,0.0,99.1219578243,10.2979449696,3.85764287749
+71,39799207,196079.999924,150.285714286,130078.623324,22.4761904762,724.9,03:16.0,02:10.0,475.99809124,162.415526871,346.516338,1.34476190476,588.944328,0.570178181642,724.9,1.84344422701,3252,50.0,191293.118277,03:11.2,02:10.0,0,150,0,0,0,0,0,130078.623324,1.9874e+11,4,0.0,0.0,0.0,0.0,0.0,29.5546558704,0.0,0.0,97.9090199034,10.2610692564,3.84382911828
+72,39799208,198779.999971,150.857142857,130276.140264,22.619047619,735.2,03:18.7,02:10.2,482.79696856,158.792546326,344.73705,1.35265306122,619.637046,0.57022048833,735.2,1.85127201566,3252,50.0,191293.118277,03:11.2,02:10.2,0,151,0,0,0,0,0,130276.140264,2.0146e+11,4,0.0,0.0,0.0,0.0,0.0,29.3172690763,0.0,0.0,99.6880916192,10.1808035361,3.83800133306
+73,39799209,201450.000048,150.904761905,130062.562971,22.4761904762,745.4,03:21.4,02:10.0,482.64500284,158.420860413,367.422972,1.35972789116,657.891738,0.565853991617,745.4,1.86692759295,3252,50.0,191293.118277,03:11.2,02:10.0,0,151,0,0,0,0,0,130062.562971,2.041e+11,4,0.0,0.0,0.0,0.0,0.0,29.5546558704,0.0,0.0,100.41503713,10.2623363112,3.84430376103
+74,39799210,204150.000095,150.761904762,129931.8979,22.380952381,756.0,03:24.1,02:09.9,486.11307118,164.310917277,362.52993,1.36333333333,631.64724,0.564496229892,756.0,1.89484126984,3252,50.0,191293.118277,03:11.2,02:09.9,0,151,0,0,0,0,0,129931.8979,2.0687e+11,4,0.0,0.0,0.0,0.0,0.0,28.4584980237,0.0,0.0,97.1078363282,10.3163699875,3.84816975723
+75,39799211,206789.999962,150.333333333,129650.504848,22.3333333333,766.3,03:26.7,02:09.6,488.3475301,163.171923972,346.516338,1.36959183673,607.626852,0.568695078615,766.3,1.87084148728,3252,50.0,191293.118277,03:11.2,02:09.6,0,150,0,0,0,0,0,129650.504848,2.0946e+11,4,0.0,0.0,0.0,0.0,0.0,29.435483871,0.0,0.0,98.4237648367,10.3608048705,3.8565218129
+76,39799212,209430.000067,150.047619048,129513.21174,22.3333333333,776.5,03:29.4,02:09.5,483.68482722,160.909752581,349.630092,1.37387755102,621.416334,0.56235824624,776.5,1.85328185328,3252,50.0,191293.118277,03:11.2,02:09.5,0,150,0,0,0,0,0,129513.21174,2.1206e+11,4,0.0,0.0,0.0,0.0,0.0,30.2040816327,0.0,0.0,100.125213958,10.3717880519,3.86060999709
+77,39799213,212069.999933,149.904761905,129546.612475,22.2857142857,786.9,03:32.0,02:09.5,484.31314586,162.91953125,361.640286,1.3762585034,648.105654,0.558736076474,786.9,1.92261904762,3252,50.0,191293.118277,03:11.2,02:09.5,0,150,0,0,0,0,0,129546.612475,2.1474e+11,4,0.0,0.0,0.0,0.0,0.0,29.1497975709,0.0,0.0,98.813597128,10.3912701416,3.85961462402
+78,39799214,214740.00001,150.0,129255.687853,22.7142857143,797.2,03:34.7,02:09.2,495.94269932,164.564744602,354.078312,1.37952380952,640.54368,0.564905581725,797.2,1.85907335907,3252,50.0,191293.118277,03:11.2,02:09.2,0,150,0,0,0,0,0,129255.687853,2.174e+11,4,0.0,0.0,0.0,0.0,0.0,29.95951417,0.0,0.0,98.4877588075,10.2181554941,3.86830172276
+79,39799215,217440.000057,150.0,128834.383844,22.6666666667,807.8,03:37.4,02:08.8,505.17584234,165.582667981,359.416176,1.3762585034,618.747402,0.573836119165,807.8,1.85328185328,3252,50.0,191293.118277,03:11.2,02:08.8,0,150,0,0,0,0,0,128834.383844,2.2014e+11,4,0.0,0.0,0.0,0.0,0.0,29.4820717131,0.0,0.0,98.8457074571,10.2731070098,3.88095153703
+80,39799216,220140.000105,149.904761905,128443.049826,22.5714285714,818.2,03:40.1,02:08.4,498.49600786,166.0932,378.543522,1.3662585034,646.771188,0.575927300163,818.2,1.96734693878,3252,50.0,191293.118277,03:11.2,02:08.4,0,150,0,0,0,0,0,128443.049826,2.2282e+11,4,0.0,0.0,0.0,0.0,0.0,27.7777777778,0.0,0.0,99.4453234055,10.3478851199,3.89277583084
+81,39799217,222690.000057,150.047619048,128455.953168,22.8571428571,828.4,03:42.6,02:08.4,505.13326652,167.888324643,373.65048,1.35843537415,653.88834,0.573408655065,828.4,1.85518590998,3252,50.0,191293.118277,03:11.2,02:08.4,0,150,0,0,0,0,0,128455.953168,2.2526e+11,4,0.0,0.0,0.0,0.0,0.0,28.6274509804,0.0,0.0,98.3523725736,10.2175101086,3.89238480327
+82,39799218,225480.000019,150.238095238,128266.252205,22.6666666667,839.2,03:45.4,02:08.2,509.2093793,169.049136108,354.523134,1.34931972789,640.54368,0.559644362835,839.2,1.86706349206,3252,50.0,191293.118277,03:11.2,02:08.2,0,150,0,0,0,0,0,128266.252205,2.2827e+11,4,0.0,0.0,0.0,0.0,0.0,28.9156626506,0.0,0.0,98.111038479,10.318609837,3.89814149399
+83,39799219,228119.999886,150.714285714,127899.526566,22.5238095238,849.6,03:48.1,02:07.8,505.09202214,165.582667981,395.001936,1.34285714286,705.932514,0.556293456915,849.6,1.98109243697,3252,50.0,191293.118277,03:11.2,02:07.8,0,151,0,0,0,0,0,127899.526566,2.3077e+11,4,0.0,0.0,0.0,0.0,0.0,27.6422764228,0.0,0.0,101.029070581,10.4138297132,3.90931861457
+84,39799220,230789.999962,151.285714286,127694.761218,22.3333333333,860.1,03:50.7,02:07.6,507.87618422,171.778477875,380.767632,1.34761904762,688.139634,0.559973575253,860.1,1.89134808853,3252,50.0,191293.118277,03:11.2,02:07.6,0,151,0,0,0,0,0,127694.761218,2.3344e+11,4,0.0,0.0,0.0,0.0,0.0,28.5140562249,0.0,0.0,97.8543312318,10.5194885779,3.91558741512
+85,39799221,233369.999886,151.761904762,127607.773874,22.1904761905,870.3,03:53.3,02:07.6,504.33697462,171.778477875,364.309218,1.34979591837,627.19902,0.577271613127,870.3,1.875,3252,50.0,191293.118277,03:11.2,02:07.6,0,152,0,0,0,0,0,127607.773874,2.3595e+11,4,0.0,0.0,0.0,0.0,0.0,28.8,0.0,0.0,98.0545829537,10.5944276703,3.91825658281
+86,39799222,236160.000086,151.952380952,127739.601229,22.1904761905,881.1,03:56.1,02:07.7,493.34893316,168.6616064,367.422972,1.34544217687,632.536884,0.586842804464,881.1,1.88293650794,3252,50.0,191293.118277,03:11.2,02:07.7,0,152,0,0,0,0,0,127739.601229,2.3894e+11,4,0.0,0.0,0.0,0.0,0.0,28.8,0.0,0.0,99.5577662158,10.5834942138,3.91421293937
+87,39799223,238890.000105,152.0,128505.455385,22.3333333333,891.7,03:58.8,02:08.5,490.76887478,166.860963965,362.52993,1.34027210884,596.06148,0.587689763157,891.7,1.91020408163,3252,50.0,191293.118277,03:11.2,02:08.5,0,152,0,0,0,0,0,128505.455385,2.4163e+11,4,0.0,0.0,0.0,0.0,0.0,27.4509803922,0.0,0.0,98.8436106307,10.4531249515,3.89088539861
+88,39799224,241559.999943,151.952380952,129358.03767,22.380952381,902.1,04:01.5,02:09.3,494.78014038,163.677491155,378.0987,1.3374829932,660.56067,0.58515412607,902.1,1.9,3252,50.0,191293.118277,03:11.2,02:09.3,0,152,0,0,0,0,0,129358.03767,2.4423e+11,4,0.0,0.0,0.0,0.0,0.0,27.4509803922,0.0,0.0,98.786779712,10.3621356358,3.86524107049
+89,39799225,244470.000029,152.380952381,129936.460364,22.0952380952,913.1,04:04.4,02:09.9,486.94870108,161.160065867,359.416176,1.34183673469,633.426528,0.575341883987,913.1,1.8893360161,3252,50.0,191293.118277,03:11.2,02:09.9,0,152,0,0,0,0,0,129936.460364,2.4735e+11,4,0.0,0.0,0.0,0.0,0.0,27.519379845,0.0,0.0,98.9959693609,10.4494044003,3.8480346363
+90,39799226,247259.99999,152.904761905,130664.59819,21.5714285714,923.9,04:07.2,02:10.6,487.4082597,157.802673571,365.198862,1.35659863946,622.305978,0.567196893235,923.9,1.86105675147,3252,50.0,191293.118277,03:11.2,02:10.6,0,153,0,0,0,0,0,130664.59819,2.5006e+11,4,0.0,0.0,0.0,0.0,0.0,27.969348659,0.0,0.0,99.4214002682,10.6434986683,3.82659118788
+91,39799227,250079.999924,153.666666667,131151.327866,21.3333333333,934.6,04:10.0,02:11.1,485.51861348,158.297094122,339.844008,1.36782312925,610.295784,0.576619566674,934.6,1.82476190476,3252,50.0,191293.118277,03:11.2,02:11.1,0,154,0,0,0,0,0,131151.327866,2.5291e+11,4,0.0,0.0,0.0,0.0,0.0,28.4090909091,0.0,0.0,98.0114977086,10.7223466425,3.81238991732
+92,39799228,252900.000095,154.285714286,131618.222937,21.0476190476,945.4,04:12.9,02:11.6,475.58301482,153.884319702,362.52993,1.3680952381,615.188826,0.592352808406,945.4,1.88258317025,3252,50.0,191293.118277,03:11.2,02:11.6,0,154,0,0,0,0,0,131618.222937,2.5572e+11,4,0.0,0.0,0.0,0.0,0.0,27.7566539924,0.0,0.0,99.752917618,10.829346687,3.79886606006
+93,39799229,255690.000057,154.80952381,132270.744011,20.9047619048,956.0,04:15.6,02:12.2,476.33364438,154.49223704,350.964558,1.36156462585,579.603066,0.5943440039,956.0,1.83783783784,3252,50.0,191293.118277,03:11.2,02:12.2,0,155,0,0,0,0,0,132270.744011,2.5849e+11,4,0.0,0.0,0.0,0.0,0.0,28.3524904215,0.0,0.0,97.8971375061,10.8495626707,3.78012540669
+94,39799230,258569.999933,155.285714286,132463.992308,21.0,966.7,04:18.5,02:12.4,483.659197,151.709024051,333.171678,1.35401360544,546.241416,0.595762918594,966.7,1.7980952381,3252,50.0,191293.118277,03:11.2,02:12.4,0,155,0,0,0,0,0,132463.992308,2.614e+11,4,0.0,0.0,0.0,0.0,0.0,28.4090909091,0.0,0.0,99.2574491048,10.7846019411,3.77461067939
+95,39799231,261329.999924,155.761904762,132090.300118,21.0,977.4,04:21.3,02:12.0,481.98781616,150.389822568,380.32281,1.34789115646,681.912126,0.571103232794,977.4,1.875,3252,50.0,191293.118277,03:11.2,02:12.0,0,156,0,0,0,0,0,132090.300118,2.6413e+11,4,0.0,0.0,0.0,0.0,0.0,27.5862068966,0.0,0.0,100.980337209,10.8151122928,3.78528930249
+96,39799232,264150.000095,155.952380952,131898.866612,21.0,988.1,04:24.1,02:11.8,482.59095848,157.062974746,357.636888,1.35081632653,636.985104,0.558185758971,988.1,1.85127201566,3252,50.0,191293.118277,03:11.2,02:11.8,0,156,0,0,0,0,0,131898.866612,2.6697e+11,4,0.0,0.0,0.0,0.0,0.0,27.7566539924,0.0,0.0,97.1115832126,10.8308089771,3.79078314198
+97,39799233,266970.000029,156.095238095,131929.48876,21.0952380952,998.8,04:26.9,02:11.9,482.413998,155.223848632,350.074914,1.35741496599,650.329764,0.562355052214,998.8,1.82818532819,3252,50.0,191293.118277,03:11.2,02:11.9,0,156,0,0,0,0,0,131929.48876,2.6979e+11,4,0.0,0.0,0.0,0.0,0.0,28.1368821293,0.0,0.0,98.1937754828,10.7794088307,3.78990326349
+98,39799234,269880.000114,156.0,132543.540936,20.8571428571,1009.6,04:29.8,02:12.5,465.7281801,151.2284256,338.06472,1.36204081633,567.14805,0.580949267827,1009.6,1.82285714286,3252,50.0,191293.118277,03:11.2,02:12.5,0,156,0,0,0,0,0,132543.540936,2.7276e+11,4,0.0,0.0,0.0,0.0,0.0,27.9850746269,0.0,0.0,99.3937113439,10.8519521526,3.77234527211
+99,39799235,272789.999962,156.095238095,133744.221874,20.8095238095,1020.6,04:32.7,02:13.7,466.41831992,147.420125978,347.405982,1.36789115646,583.161642,0.57806732818,1020.6,1.82476190476,3252,50.0,191293.118277,03:11.2,02:13.7,0,156,0,0,0,0,0,133744.221874,2.7573e+11,4,0.0,0.0,0.0,0.0,0.0,27.2727272727,0.0,0.0,99.2398687646,10.7791392933,3.73847926283
+100,39799236,275730.000019,155.952380952,134547.664928,20.5238095238,1031.5,04:35.7,02:14.5,473.61435974,145.189490569,338.509542,1.37292517007,591.61326,0.57139299945,1031.5,1.77551020408,3252,50.0,191293.118277,03:11.2,02:14.5,0,156,0,0,0,0,0,134547.664928,2.7864e+11,4,0.0,0.0,0.0,0.0,0.0,28.3088235294,0.0,0.0,98.9701817819,10.8639338939,3.7161551653
+101,39799237,278670.000076,155.666666667,134591.850827,20.5238095238,1042.5,04:38.6,02:14.5,480.52150734,144.489783388,349.18527,1.37204081633,657.446916,0.553762484655,1042.5,1.83428571429,3252,50.0,191293.118277,03:11.2,02:14.5,0,156,0,0,0,0,0,134591.850827,2.8163e+11,4,0.0,0.0,0.0,0.0,0.0,27.2727272727,0.0,0.0,99.3515411645,10.8603673133,3.71493516828
+102,39799238,281549.999952,155.333333333,134423.247406,20.4761904762,1053.3,04:41.5,02:14.4,472.94803454,144.606244787,356.747244,1.36782312925,633.87135,0.563911081988,1053.3,1.82857142857,3252,50.0,191293.118277,03:11.2,02:14.4,0,155,0,0,0,0,0,134423.247406,2.8444e+11,4,0.0,0.0,0.0,0.0,0.0,27.7777777778,0.0,0.0,99.6455359429,10.8992775233,3.71959471034
+103,39799239,284460.000038,155.047619048,134984.759451,20.380952381,1064.1,04:44.4,02:14.9,468.36794146,147.302158424,344.73705,1.35897959184,590.723616,0.58176866823,1064.1,1.76252319109,3252,50.0,191293.118277,03:11.2,02:14.9,0,155,0,0,0,0,0,134984.759451,2.8736e+11,4,0.0,0.0,0.0,0.0,0.0,28.3088235294,0.0,0.0,96.6061384746,10.9046578503,3.70412187296
+104,39799240,287490.00001,154.904761905,135735.508722,20.3333333333,1075.3,04:47.4,02:15.7,468.37251072,142.288881459,330.502746,1.34503401361,531.117468,0.602317043727,1075.3,1.79428571429,3252,50.0,191293.118277,03:11.2,02:15.7,0,155,0,0,0,0,0,135735.508722,2.9054e+11,4,0.0,0.0,0.0,0.0,0.0,26.6903914591,0.0,0.0,98.3595773926,10.8697410866,3.68363447936
+105,39799241,290430.000067,155.0,135982.562299,20.4285714286,1086.1,04:50.4,02:15.9,469.90348516,135.932254618,356.747244,1.33870748299,605.847564,0.602943727733,1086.1,1.78285714286,3252,50.0,191293.118277,03:11.2,02:15.9,0,155,0,0,0,0,0,135982.562299,2.9336e+11,4,0.0,0.0,0.0,0.0,0.0,26.4084507042,0.0,0.0,102.399034847,10.7994101869,3.67694203982
+106,39799242,293519.999981,155.0,136032.213736,20.2380952381,1097.5,04:53.5,02:16.0,476.17202572,140.910419686,370.981548,1.34136054422,621.416334,0.591585810569,1097.5,1.80308880309,3252,50.0,191293.118277,03:11.2,02:16.0,0,155,0,0,0,0,0,136032.213736,2.9661e+11,4,0.0,0.0,0.0,0.0,0.0,26.4285714286,0.0,0.0,98.673296846,10.8970728364,3.67559996467
+107,39799243,296460.000038,155.0,135481.330839,20.2857142857,1108.5,04:56.4,02:15.4,482.15046366,145.657214744,346.96116,1.34870748299,598.730412,0.581032083517,1108.5,1.80380952381,3252,50.0,191293.118277,03:11.2,02:15.4,0,155,0,0,0,0,0,135481.330839,2.9942e+11,4,0.0,0.0,0.0,0.0,0.0,27.1739130435,0.0,0.0,96.6268186374,10.9156976115,3.69054538292
+108,39799244,299339.999914,155.0,134935.69799,20.0476190476,1119.2,04:59.3,02:14.9,476.637364,142.63489588,347.405982,1.35278911565,609.850962,0.577901402085,1119.2,1.80952380952,3252,50.0,191293.118277,03:11.2,02:14.9,0,155,0,0,0,0,0,134935.69799,3.022e+11,4,0.0,0.0,0.0,0.0,0.0,27.1739130435,0.0,0.0,99.8761229337,11.0900012149,3.70546865988
+109,39799245,302460.000038,155.0,135043.604152,20.0476190476,1130.6,05:02.4,02:15.0,468.32061482,142.63489588,353.63349,1.34972789116,602.288988,0.576596521567,1130.6,1.78007518797,3252,50.0,191293.118277,03:11.2,02:15.0,0,155,0,0,0,0,0,135043.604152,3.0557e+11,4,0.0,0.0,0.0,0.0,0.0,27.0462633452,0.0,0.0,99.636897092,11.0811397846,3.70250781692
+110,39799246,305400.000095,155.095238095,135598.957647,20.2857142857,1141.3,05:05.4,02:15.5,466.61609928,142.63489588,350.074914,1.34136054422,615.188826,0.57950500723,1141.3,1.80694980695,3252,50.0,191293.118277,03:11.2,02:15.5,0,155,0,0,0,0,0,135598.957647,3.0828e+11,4,0.0,0.0,0.0,0.0,0.0,27.4074074074,0.0,0.0,98.4176977661,10.9062286695,3.68734397873
+111,39799247,308339.999914,154.952380952,135967.371232,20.2380952381,1152.4,05:08.3,02:15.9,467.18544118,142.288881459,342.51294,1.3368707483,584.496108,0.574952299315,1152.4,1.80115830116,3252,50.0,191293.118277,03:11.2,02:15.9,0,155,0,0,0,0,0,135967.371232,3.1135e+11,4,0.0,0.0,0.0,0.0,0.0,26.334519573,0.0,0.0,97.8572429727,10.9022696236,3.67735284921
+112,39799248,311309.999943,154.761904762,135961.143967,20.3333333333,1163.3,05:11.3,02:15.9,472.28473534,138.4064164,350.519736,1.33816326531,616.968114,0.565898195666,1163.3,1.81081081081,3252,50.0,191293.118277,03:11.2,02:15.9,0,155,0,0,0,0,0,135961.143967,3.1427e+11,4,0.0,0.0,0.0,0.0,0.0,26.714801444,0.0,0.0,100.616079279,10.8517021335,3.67752127858
+113,39799249,314099.999905,154.380952381,135472.697606,20.4761904762,1173.8,05:14.1,02:15.4,476.19886634,140.6815452,361.195464,1.34476190476,652.553874,0.567410171149,1173.8,1.79428571429,3252,50.0,191293.118277,03:11.2,02:15.4,0,154,0,0,0,0,0,135472.697606,3.169e+11,4,0.0,0.0,0.0,0.0,0.0,26.9784172662,0.0,0.0,100.063474348,10.8148453892,3.69078056934
+114,39799250,317039.999962,153.571428571,135069.827373,20.5714285714,1184.8,05:17.0,02:15.0,476.06675118,146.125942348,356.302422,1.34918367347,628.533486,0.568519165753,1184.8,1.8,3252,50.0,191293.118277,03:11.2,02:15.0,0,154,0,0,0,0,0,135069.827373,3.1997e+11,4,0.0,0.0,0.0,0.0,0.0,27.6752767528,0.0,0.0,97.199870211,10.7968845574,3.7017889911
+115,39799251,320039.999962,153.047619048,134758.406653,20.9523809524,1195.8,05:20.0,02:14.7,466.5308266,146.008666317,338.509542,1.35210884354,581.827176,0.566821772936,1195.8,1.82818532819,3252,50.0,191293.118277,03:11.2,02:14.7,0,153,0,0,0,0,0,134758.406653,3.2304e+11,4,0.0,0.0,0.0,0.0,0.0,27.4074074074,0.0,0.0,97.9539172087,10.6250750315,3.7103436618
+116,39799252,322980.000019,152.666666667,135247.376024,21.0952380952,1206.6,05:22.9,02:15.2,450.82037928,141.368913101,338.06472,1.35523809524,596.06148,0.563176694837,1206.6,1.77819548872,3252,50.0,191293.118277,03:11.2,02:15.2,0,152,0,0,0,0,0,135247.376024,3.2589e+11,4,0.0,0.0,0.0,0.0,0.0,27.9411764706,0.0,0.0,100.075456865,10.514968482,3.69692939485
+117,39799253,325950.000048,152.380952381,136052.446984,21.0,1217.3,05:25.9,02:16.0,459.2995944,141.02494996,331.39239,1.35605442177,616.523292,0.556395600922,1217.3,1.78759398496,3252,50.0,191293.118277,03:11.2,02:16.0,0,153,0,0,0,0,0,136052.446984,3.2886e+11,4,0.0,0.0,0.0,0.0,0.0,28.0442804428,0.0,0.0,98.549180766,10.5001524062,3.67505334217
+118,39799254,328710.000038,152.142857143,135654.45421,21.0952380952,1227.8,05:28.7,02:15.6,465.51163954,139.654676675,333.171678,1.35632653061,600.064878,0.553329814852,1227.8,1.78759398496,3252,50.0,191293.118277,03:11.2,02:15.6,0,152,0,0,0,0,0,135654.45421,3.3157e+11,4,0.0,0.0,0.0,0.0,0.0,28.4644194757,0.0,0.0,100.394607355,10.4834146762,3.68583547744
+119,39799255,331589.999914,151.80952381,135173.649715,20.8571428571,1238.7,05:31.5,02:15.1,464.95415956,142.519495485,373.205658,1.35496598639,667.233,0.543275865074,1238.7,1.82625482625,3252,50.0,191293.118277,03:11.2,02:15.1,0,152,0,0,0,0,0,135173.649715,3.3447e+11,4,0.0,0.0,0.0,0.0,0.0,27.6119402985,0.0,0.0,99.4300477765,10.6408029036,3.69894577127
+120,39799256,334500.0,151.333333333,135112.064898,20.7142857143,1249.5,05:34.5,02:15.1,466.40188874,148.721928541,328.278636,1.34945578231,595.616658,0.54902713476,1249.5,1.82818532819,3252,50.0,191293.118277,03:11.2,02:15.1,0,151,0,0,0,0,0,135112.064898,3.3743e+11,4,0.0,0.0,0.0,0.0,0.0,27.2058823529,0.0,0.0,95.4136790238,10.7190713365,3.70063177094
+121,39799257,337410.000086,150.904761905,134933.599238,20.7619047619,1260.1,05:37.4,02:14.9,464.5347257,140.795951439,336.730254,1.34741496599,648.105654,0.556663049463,1260.1,1.77255639098,3252,50.0,191293.118277,03:11.2,02:14.9,0,151,0,0,0,0,0,134933.599238,3.4029e+11,4,0.0,0.0,0.0,0.0,0.0,28.0442804428,0.0,0.0,101.185332369,10.7086310348,3.70552629458
+122,39799258,340319.999933,150.619047619,135170.211574,20.6666666667,1270.9,05:40.3,02:15.1,459.90080008,141.25419665,351.40938,1.35034013605,594.727014,0.561725982989,1270.9,1.79238095238,3252,50.0,191293.118277,03:11.2,02:15.1,0,151,0,0,0,0,0,135170.211574,3.4322e+11,4,0.0,0.0,0.0,0.0,0.0,27.7777777778,0.0,0.0,100.328357903,10.73914797,3.69903985633
+123,39799259,343230.000019,150.666666667,135602.343052,20.4285714286,1281.8,05:43.2,02:15.6,464.98638646,144.72276875,345.181872,1.35442176871,592.502904,0.569723096921,1281.8,1.85909980431,3252,50.0,191293.118277,03:11.2,02:15.6,0,150,0,0,0,0,0,135602.343052,3.4615e+11,4,0.0,0.0,0.0,0.0,0.0,26.7399267399,0.0,0.0,96.99058988,10.8296909587,3.68725192165
+124,39799260,346200.000048,150.714285714,135536.874693,20.4761904762,1292.7,05:46.2,02:15.5,467.51112956,142.173667796,342.068118,1.35965986395,613.85436,0.585593542607,1292.7,1.79323308271,3252,50.0,191293.118277,03:11.2,02:15.5,0,151,0,0,0,0,0,135536.874693,3.4917e+11,4,0.0,0.0,0.0,0.0,0.0,27.5362318841,0.0,0.0,98.8727185455,10.8097245298,3.68903297447
+125,39799261,349079.999924,150.761904762,135425.973283,20.4761904762,1303.4,05:49.0,02:15.4,466.74228348,140.910419686,331.837212,1.36217687075,572.485914,0.575030221445,1303.4,1.74542124542,3252,50.0,191293.118277,03:11.2,02:15.4,0,151,0,0,0,0,0,135425.973283,3.5198e+11,4,0.0,0.0,0.0,0.0,0.0,28.5714285714,0.0,0.0,100.004384112,10.8185766995,3.69205395302
+126,39799262,351990.00001,151.142857143,135481.539224,20.4285714286,1314.3,05:51.9,02:15.4,471.5936272,141.25419665,358.08171,1.36081632653,597.840768,0.576985128294,1314.3,1.78947368421,3252,50.0,191293.118277,03:11.2,02:15.4,0,151,0,0,0,0,0,135481.539224,3.5489e+11,4,0.0,0.0,0.0,0.0,0.0,27.9411764706,0.0,0.0,99.6383021711,10.8393473897,3.69053970648
+127,39799263,354960.000038,151.333333333,135051.927441,20.7619047619,1325.2,05:54.9,02:15.0,474.18336878,146.008666317,345.181872,1.35802721088,623.640444,0.572062929127,1325.2,1.83590733591,3252,50.0,191293.118277,03:11.2,02:15.0,0,151,0,0,0,0,0,135051.927441,3.5792e+11,4,0.0,0.0,0.0,0.0,0.0,26.714801444,0.0,0.0,97.3166274991,10.699248473,3.70227963033
+128,39799264,357869.999886,151.666666667,134819.049813,20.619047619,1336.1,05:57.8,02:14.8,467.4154777,142.865883521,348.295626,1.36115646259,608.071674,0.564547005389,1336.1,1.81333333333,3252,50.0,191293.118277,03:11.2,02:14.8,0,152,0,0,0,0,0,134819.049813,3.6078e+11,4,0.0,0.0,0.0,0.0,0.0,27.7777777778,0.0,0.0,99.9736911607,10.7919864439,3.70867470652
+129,39799265,360779.999971,151.952380952,135272.90821,20.5238095238,1346.9,06:00.7,02:15.2,455.47560794,144.373384534,335.84061,1.36503401361,610.740606,0.563426030056,1346.9,1.76437847866,3252,50.0,191293.118277,03:11.2,02:15.2,0,152,0,0,0,0,0,135272.90821,3.637e+11,4,0.0,0.0,0.0,0.0,0.0,28.0,0.0,0.0,97.937367391,10.8056887126,3.69623161517
+130,39799266,363690.000057,152.0,135946.220926,20.380952381,1357.4,06:03.6,02:15.9,458.91508058,141.25419665,320.716662,1.36170068027,550.244814,0.574332484059,1357.4,1.80639097744,3252,50.0,191293.118277,03:11.2,02:15.9,0,152,0,0,0,0,0,135946.220926,3.6655e+11,4,0.0,0.0,0.0,0.0,0.0,28.5714285714,0.0,0.0,98.6200609246,10.8275361154,3.67792496617
+131,39799267,366539.999962,152.142857143,135707.336479,20.5238095238,1368.1,06:06.5,02:15.7,453.16259406,138.18026217,342.51294,1.35258503401,590.278794,0.573720093413,1368.1,1.80952380952,3252,50.0,191293.118277,03:11.2,02:15.7,0,152,0,0,0,0,0,135707.336479,3.6945e+11,4,0.0,0.0,0.0,0.0,0.0,27.6752767528,0.0,0.0,101.34726938,10.7710973871,3.68439918557
+132,39799268,369450.000048,152.285714286,135871.183186,20.619047619,1379.0,06:09.4,02:15.8,455.26642056,141.943427083,352.299024,1.34517006803,610.295784,0.584665452957,1379.0,1.73283858998,3252,50.0,191293.118277,03:11.2,02:15.8,0,152,0,0,0,0,0,135871.183186,3.7236e+11,4,0.0,0.0,0.0,0.0,0.0,28.5185185185,0.0,0.0,98.3038859372,10.7084175161,3.67995617816
+133,39799269,372329.999924,152.333333333,135911.92446,20.7619047619,1389.5,06:12.3,02:15.9,454.40304224,144.72276875,323.385594,1.33952380952,565.813584,0.57809127753,1389.5,1.85714285714,3252,50.0,191293.118277,03:11.2,02:15.9,0,153,0,0,0,0,0,135911.92446,3.7519e+11,4,0.0,0.0,0.0,0.0,0.0,26.8656716418,0.0,0.0,96.3293202928,10.6315478511,3.67885306595
+134,39799270,375150.000095,152.380952381,136089.743077,20.5238095238,1399.9,06:15.1,02:16.0,446.34779998,137.615954692,339.399186,1.34727891156,568.927338,0.575237962562,1399.9,1.80380952381,3252,50.0,191293.118277,03:11.2,02:16.0,0,152,0,0,0,0,0,136089.743077,3.7798e+11,4,0.0,0.0,0.0,0.0,0.0,27.6752767528,0.0,0.0,100.907413543,10.7408310451,3.67404617493
+135,39799271,378089.999914,152.095238095,136630.270895,20.3333333333,1410.7,06:18.0,02:16.6,457.51715936,138.4064164,330.947568,1.36482993197,595.171836,0.572597794735,1410.7,1.74175824176,3252,50.0,191293.118277,03:11.2,02:16.6,0,152,0,0,0,0,0,136630.270895,3.8102e+11,4,0.0,0.0,0.0,0.0,0.0,28.1588447653,0.0,0.0,99.1450490667,10.7985574969,3.65951115171
+136,39799272,381150.000095,151.476190476,136418.047659,20.1904761905,1422.0,06:21.1,02:16.4,470.8275953,139.199899252,334.950966,1.37551020408,584.051286,0.576811197542,1422.0,1.76556776557,3252,50.0,191293.118277,03:11.2,02:16.4,0,152,0,0,0,0,0,136418.047659,3.8423e+11,4,0.0,0.0,0.0,0.0,0.0,28.1588447653,0.0,0.0,99.0406846396,10.8918803787,3.66520419093
+137,39799273,384029.999971,151.476190476,135619.718841,20.0952380952,1432.8,06:24.0,02:15.6,468.96106772,141.02494996,359.860998,1.37557823129,624.085266,0.570099974688,1432.8,1.84761904762,3252,50.0,191293.118277,03:11.2,02:15.6,0,151,0,0,0,0,0,135619.718841,3.8691e+11,4,0.0,0.0,0.0,0.0,0.0,27.8810408922,0.0,0.0,99.495530275,11.0079198513,3.68677950576
+138,39799274,387000.0,151.238095238,135248.659164,20.380952381,1443.6,06:27.0,02:15.2,471.66113726,145.657214744,335.395788,1.36843537415,569.37216,0.579103403429,1443.6,1.81904761905,3252,50.0,191293.118277,03:11.2,02:15.2,0,151,0,0,0,0,0,135248.659164,3.8992e+11,4,0.0,0.0,0.0,0.0,0.0,27.5735294118,0.0,0.0,97.1263656849,10.883380478,3.69689432109
+139,39799275,389880.000114,151.285714286,135020.184383,20.619047619,1454.4,06:29.8,02:15.0,474.42741568,142.750358554,339.844008,1.35217687075,611.63025,0.576122113145,1454.4,1.75139146568,3252,50.0,191293.118277,03:11.2,02:15.0,0,152,0,0,0,0,0,135020.184383,3.928e+11,4,0.0,0.0,0.0,0.0,0.0,28.3088235294,0.0,0.0,99.6081207115,10.7759100213,3.70315003112
+140,39799276,392789.999962,151.523809524,134604.605094,20.8095238095,1465.1,06:32.7,02:14.6,468.0654625,143.328606672,358.971354,1.33258503401,607.626852,0.574599185498,1465.1,1.85912698413,3252,50.0,191293.118277,03:11.2,02:14.6,0,151,0,0,0,0,0,134604.605094,3.9566e+11,4,0.0,0.0,0.0,0.0,0.0,26.8656716418,0.0,0.0,100.127969837,10.7102397889,3.71458316489
+141,39799277,395640.000105,151.857142857,134531.510854,20.9523809524,1475.9,06:35.6,02:14.5,467.13629894,145.3063276,364.75404,1.3274829932,641.878146,0.575502759115,1475.9,1.81409001957,3252,50.0,191293.118277,03:11.2,02:14.5,0,152,0,0,0,0,0,134531.510854,3.9851e+11,4,0.0,0.0,0.0,0.0,0.0,27.4436090226,0.0,0.0,98.9262300291,10.6429948844,3.71660138822
+142,39799278,398490.00001,152.095238095,134717.801846,21.0476190476,1486.6,06:38.4,02:14.7,465.17181974,148.129254179,339.844008,1.32952380952,587.16504,0.580404599147,1486.6,1.80626223092,3252,50.0,191293.118277,03:11.2,02:14.7,0,152,0,0,0,0,0,134717.801846,4.0137e+11,4,0.0,0.0,0.0,0.0,0.0,27.037037037,0.0,0.0,96.6389592792,10.5801857438,3.71146198313
+143,39799279,401430.000067,152.80952381,135058.857384,20.5714285714,1497.4,06:41.4,02:15.0,459.83634628,142.519495485,334.061322,1.33897959184,574.710024,0.572980352813,1497.4,1.82432432432,3252,50.0,191293.118277,03:11.2,02:15.0,0,153,0,0,0,0,0,135058.857384,4.0436e+11,4,0.0,0.0,0.0,0.0,0.0,27.1062271062,0.0,0.0,99.6837929441,10.797761521,3.70208966435
+144,39799280,404369.999886,153.380952381,135382.877147,20.4761904762,1508.2,06:44.3,02:15.3,462.27917556,139.427164349,353.63349,1.35387755102,619.192224,0.57310518315,1508.2,1.77819548872,3252,50.0,191293.118277,03:11.2,02:15.3,0,153,0,0,0,0,0,135382.877147,4.0729e+11,4,0.0,0.0,0.0,0.0,0.0,27.8388278388,0.0,0.0,101.164800904,10.8220205535,3.69322923651
+145,39799281,407309.999943,153.714285714,135730.342589,20.2380952381,1519.2,06:47.3,02:15.7,467.68470092,143.676303949,341.178474,1.36503401361,601.399344,0.577255450082,1519.2,1.77179962894,3252,50.0,191293.118277,03:11.2,02:15.7,0,154,0,0,0,0,0,135730.342589,4.1027e+11,4,0.0,0.0,0.0,0.0,0.0,27.8985507246,0.0,0.0,97.4208829178,10.9213084776,3.68377468489
+146,39799282,410279.999971,153.619047619,135519.060217,20.2857142857,1530.0,06:50.2,02:15.5,473.7156097,143.328606672,343.402584,1.36544217687,591.61326,0.578325132737,1530.0,1.85135135135,3252,50.0,191293.118277,03:11.2,02:15.5,0,154,0,0,0,0,0,135519.060217,4.1321e+11,4,0.0,0.0,0.0,0.0,0.0,27.0072992701,0.0,0.0,98.1146867082,10.9126586111,3.68951791136
+147,39799283,413160.000086,153.428571429,135030.376252,20.7142857143,1540.9,06:53.1,02:15.0,470.76256656,141.25419665,338.954364,1.36789115646,567.14805,0.582445358297,1540.9,1.77365491651,3252,50.0,191293.118277,03:11.2,02:15.0,0,153,0,0,0,0,0,135030.376252,4.1609e+11,4,0.0,0.0,0.0,0.0,0.0,28.2051282051,0.0,0.0,100.640376183,10.7255559991,3.7028705235
+148,39799284,415950.000048,153.142857143,135084.603998,20.7619047619,1551.3,06:55.9,02:15.0,463.76388246,143.328606672,357.192066,1.36448979592,628.088664,0.583689111117,1551.3,1.81523809524,3252,50.0,191293.118277,03:11.2,02:15.0,0,153,0,0,0,0,0,135084.603998,4.1871e+11,4,0.0,0.0,0.0,0.0,0.0,27.6752767528,0.0,0.0,99.0643976896,10.6966603571,3.70138406006
+149,39799285,419039.999962,152.857142857,135426.313714,20.4285714286,1562.6,06:59.0,02:15.4,464.7047869,145.89145305,331.39239,1.36265306122,568.927338,0.579244873232,1562.6,1.79887218045,3252,50.0,191293.118277,03:11.2,02:15.4,0,153,0,0,0,0,0,135426.313714,4.221e+11,4,0.0,0.0,0.0,0.0,0.0,27.5362318841,0.0,0.0,96.58930096,10.8437675682,3.69204467202
+150,39799286,421950.000048,152.666666667,135393.051047,20.4761904762,1573.3,07:01.9,02:15.3,469.49915104,140.910419686,329.613102,1.36176870748,571.151448,0.571828605124,1573.3,1.78571428571,3252,50.0,191293.118277,03:11.2,02:15.3,0,153,0,0,0,0,0,135393.051047,4.2488e+11,4,0.0,0.0,0.0,0.0,0.0,27.7372262774,0.0,0.0,100.077353187,10.8212073496,3.69295171453
+151,39799287,424890.000105,152.333333333,135335.644206,20.4761904762,1584.2,07:04.8,02:15.3,463.31385574,139.199899252,360.750642,1.35925170068,631.64724,0.574232861636,1584.2,1.79323308271,3252,50.0,191293.118277,03:11.2,02:15.3,0,152,0,0,0,0,0,135335.644206,4.2782e+11,4,0.0,0.0,0.0,0.0,0.0,27.7372262774,0.0,0.0,101.4360992,10.8257975027,3.69451819536
+152,39799288,427650.000095,152.047619048,135640.381081,20.4285714286,1594.6,07:07.6,02:15.6,462.32556414,145.3063276,345.626694,1.35578231293,609.850962,0.574948423137,1594.6,1.80761904762,3252,50.0,191293.118277,03:11.2,02:15.6,0,152,0,0,0,0,0,135640.381081,4.3043e+11,4,0.0,0.0,0.0,0.0,0.0,27.4725274725,0.0,0.0,96.5198223331,10.8266539568,3.68621789483
+153,39799289,430769.999981,151.904761905,135755.601608,20.6666666667,1606.0,07:10.7,02:15.7,463.34272378,143.328606672,325.164882,1.35476190476,558.696432,0.57418260892,1606.0,1.77819548872,3252,50.0,191293.118277,03:11.2,02:15.7,0,152,0,0,0,0,0,135755.601608,4.3388e+11,4,0.0,0.0,0.0,0.0,0.0,27.4368231047,0.0,0.0,97.6027129202,10.6928398242,3.68308927277
+154,39799290,433500.0,152.095238095,135778.261376,20.8571428571,1616.2,07:13.5,02:15.7,455.75194226,137.728693043,337.175076,1.35047619048,582.271998,0.570176939833,1616.2,1.80380952381,3252,50.0,191293.118277,03:11.2,02:15.7,0,152,0,0,0,0,0,135778.261376,4.3627e+11,4,0.0,0.0,0.0,0.0,0.0,27.1739130435,0.0,0.0,101.520298996,10.5934201087,3.68247460922
+155,39799291,436559.999943,151.857142857,136008.019233,20.6666666667,1627.4,07:16.5,02:16.0,462.31796888,139.882436364,356.302422,1.34870748299,638.764392,0.569221632348,1627.4,1.8,3252,50.0,191293.118277,03:11.2,02:16.0,0,152,0,0,0,0,0,136008.019233,4.3958e+11,4,0.0,0.0,0.0,0.0,0.0,27.5735294118,0.0,0.0,99.4514934249,10.6729949558,3.67625381812
+156,39799292,439440.000057,151.80952381,135665.72469,20.5238095238,1638.0,07:19.4,02:15.6,473.08898562,144.024563085,341.623296,1.34448979592,608.071674,0.567993168719,1638.0,1.76691729323,3252,50.0,191293.118277,03:11.2,02:15.6,0,152,0,0,0,0,0,135665.72469,4.4228e+11,4,0.0,0.0,0.0,0.0,0.0,27.8388278388,0.0,0.0,97.3242489105,10.7744011297,3.68552927531
+157,39799293,442440.000057,151.619047619,135182.475263,20.3333333333,1649.2,07:22.4,02:15.1,469.43076344,142.750358554,350.964558,1.34108843537,604.068276,0.56991134906,1649.2,1.8166023166,3252,50.0,191293.118277,03:11.2,02:15.1,0,151,0,0,0,0,0,135182.475263,4.4549e+11,4,0.0,0.0,0.0,0.0,0.0,26.8115942029,0.0,0.0,99.2498030347,10.9142093544,3.69870428121
+158,39799294,445380.000114,151.380952381,135350.796391,20.0952380952,1660.2,07:25.3,02:15.3,461.95330562,142.519495485,352.743846,1.34394557823,612.519894,0.577038136948,1660.2,1.80888030888,3252,50.0,191293.118277,03:11.2,02:15.3,0,152,0,0,0,0,0,135350.796391,4.4833e+11,4,0.0,0.0,0.0,0.0,0.0,26.8115942029,0.0,0.0,99.0401573532,11.0297909954,3.69410460323
+159,39799295,448259.99999,151.285714286,135812.873651,20.2380952381,1670.8,07:28.2,02:15.8,459.0357272,141.483691644,332.726856,1.35428571429,584.496108,0.573893979377,1670.8,1.77819548872,3252,50.0,191293.118277,03:11.2,02:15.8,0,151,0,0,0,0,0,135812.873651,4.5114e+11,4,0.0,0.0,0.0,0.0,0.0,28.4644194757,0.0,0.0,98.750395978,10.9146717931,3.68153612069
+160,39799296,451140.000105,151.095238095,136053.741379,20.6666666667,1681.4,07:31.1,02:16.0,454.00415492,140.224539997,332.726856,1.36387755102,579.603066,0.565565878403,1681.4,1.79887218045,3252,50.0,191293.118277,03:11.2,02:16.0,0,151,0,0,0,0,0,136053.741379,4.5402e+11,4,0.0,0.0,0.0,0.0,0.0,28.0442804428,0.0,0.0,99.1088765411,10.669408195,3.67501837828
+161,39799297,454049.999952,150.571428571,136050.158308,20.9523809524,1692.1,07:34.0,02:16.0,460.1101085,140.224539997,331.39239,1.36965986395,598.730412,0.557429377781,1692.1,1.76373626374,3252,50.0,191293.118277,03:11.2,02:16.0,0,151,0,0,0,0,0,136050.158308,4.5695e+11,4,0.0,0.0,0.0,0.0,0.0,28.7822878229,0.0,0.0,99.1167072582,10.5241934271,3.67511516501
+162,39799298,456839.999914,150.333333333,135508.685793,21.1904761905,1702.5,07:36.8,02:15.5,467.22011914,141.25419665,342.957762,1.36659863946,616.523292,0.560940991906,1702.5,1.79511278195,3252,50.0,191293.118277,03:11.2,02:15.5,0,150,0,0,0,0,0,135508.685793,4.5964e+11,4,0.0,0.0,0.0,0.0,0.0,28.2527881041,0.0,0.0,99.5784322917,10.4475246645,3.68980037756
+163,39799299,459839.999914,150.047619048,135121.507637,20.8571428571,1713.7,07:39.8,02:15.1,468.19403724,143.90841425,354.078312,1.35707482993,636.540282,0.562610728352,1713.7,1.80761904762,3252,50.0,191293.118277,03:11.2,02:15.1,0,150,0,0,0,0,0,135121.507637,4.6283e+11,4,0.0,0.0,0.0,0.0,0.0,27.8810408922,0.0,0.0,98.5844481751,10.6449090862,3.70037315852
+164,39799300,462750.0,149.904761905,135122.935,20.7142857143,1724.4,07:42.7,02:15.1,460.93820366,145.657214744,337.175076,1.34870748299,573.82038,0.566754084449,1724.4,1.82432432432,3252,50.0,191293.118277,03:11.2,02:15.1,0,150,0,0,0,0,0,135122.935,4.6566e+11,4,0.0,0.0,0.0,0.0,0.0,27.2058823529,0.0,0.0,97.397729605,10.7182090299,3.70033406986
+165,39799301,465690.000057,149.904761905,135409.984588,20.7619047619,1735.1,07:45.6,02:15.4,460.1344678,141.02494996,338.509542,1.34823129252,604.95792,0.574200782538,1735.1,1.76879699248,3252,50.0,191293.118277,03:11.2,02:15.4,0,150,0,0,0,0,0,135409.984588,4.6859e+11,4,0.0,0.0,0.0,0.0,0.0,28.0442804428,0.0,0.0,99.958567598,10.6709570408,3.69248989667
+166,39799302,468539.999962,150.142857143,135705.405237,20.4761904762,1745.6,07:48.5,02:15.7,451.04914488,140.338698368,329.16828,1.35238095238,580.937532,0.569293296429,1745.6,1.77819548872,3252,50.0,191293.118277,03:11.2,02:15.7,0,150,0,0,0,0,0,135705.405237,4.7139e+11,4,0.0,0.0,0.0,0.0,0.0,28.679245283,0.0,0.0,99.7927892396,10.7963000922,3.68445161877
+167,39799303,471390.000105,150.285714286,136086.491159,20.7142857143,1756.3,07:51.3,02:16.0,446.03839148,141.02494996,346.516338,1.35891156463,593.392548,0.56601285805,1756.3,1.83976833977,3252,50.0,191293.118277,03:11.2,02:16.0,0,150,0,0,0,0,0,136086.491159,4.7428e+11,4,0.0,0.0,0.0,0.0,0.0,27.4074074074,0.0,0.0,98.4752383869,10.642319085,3.67413396981
+168,39799304,474059.999943,150.333333333,136277.633993,20.9523809524,1766.2,07:54.0,02:16.2,440.85237216,141.483691644,308.706468,1.36414965986,565.368762,0.5702633677,1766.2,1.74908424908,3252,50.0,191293.118277,03:11.2,02:16.2,0,151,0,0,0,0,0,136277.633993,4.7673e+11,4,0.0,0.0,0.0,0.0,0.0,28.4671532847,0.0,0.0,97.7435046018,10.5066263617,3.66898063425
+169,39799305,477059.999943,150.285714286,136497.120011,21.1904761905,1777.1,07:57.0,02:16.4,442.06706908,137.728693043,319.827018,1.36027210884,551.134458,0.560617166152,1777.1,1.79323308271,3252,50.0,191293.118277,03:11.2,02:16.4,0,150,0,0,0,0,0,136497.120011,4.8006e+11,4,0.0,0.0,0.0,0.0,0.0,28.5714285714,0.0,0.0,99.9247691213,10.3718696553,3.66308094969
+170,39799306,479880.000114,150.238095238,136580.031401,21.4285714286,1787.5,07:59.8,02:16.5,432.87365744,137.728693043,330.057924,1.35183673469,588.499506,0.562084297404,1787.5,1.78195488722,3252,50.0,191293.118277,03:11.2,02:16.5,0,150,0,0,0,0,0,136580.031401,4.8271e+11,4,0.0,0.0,0.0,0.0,0.0,29.1187739464,0.0,0.0,99.7429005188,10.2504003377,3.66085726348
+171,39799307,482609.999895,149.857142857,136811.69351,21.4761904762,1797.7,08:02.6,02:16.8,449.45807408,139.76852559,336.730254,1.34448979592,614.744004,0.574192025951,1797.7,1.80888030888,3252,50.0,191293.118277,03:11.2,02:16.8,0,150,0,0,0,0,0,136811.69351,4.8534e+11,4,0.0,0.0,0.0,0.0,0.0,28.5714285714,0.0,0.0,97.7887746272,10.2103537446,3.65465836415
+172,39799308,485579.999924,149.666666667,136176.08526,21.3333333333,1808.4,08:05.5,02:16.1,450.0774055,140.224539997,318.492552,1.34136054422,534.231222,0.567041996588,1808.4,1.78857142857,3252,50.0,191293.118277,03:11.2,02:16.1,0,150,0,0,0,0,0,136176.08526,4.8854e+11,4,0.0,0.0,0.0,0.0,0.0,28.1954887218,0.0,0.0,98.841991041,10.3267030868,3.67171665307
+173,39799309,488279.999971,149.428571429,135744.803044,21.4285714286,1818.4,08:08.2,02:15.7,446.29018494,138.4064164,356.302422,1.34741496599,620.081868,0.570033589223,1818.4,1.79619047619,3252,50.0,191293.118277,03:11.2,02:15.7,0,149,0,0,0,0,0,135744.803044,4.9094e+11,4,0.0,0.0,0.0,0.0,0.0,28.1954887218,0.0,0.0,101.097911766,10.31347034,3.68338226429
+174,39799310,491069.999933,149.0,135655.993062,21.2380952381,1828.9,08:11.0,02:15.6,452.80389202,145.657214744,319.827018,1.35897959184,586.275396,0.57254419599,1828.9,1.78383458647,3252,50.0,191293.118277,03:11.2,02:15.6,0,149,0,0,0,0,0,135655.993062,4.9388e+11,4,0.0,0.0,0.0,0.0,0.0,29.2307692308,0.0,0.0,96.2540669287,10.4127803124,3.68579366613
+175,39799311,494039.999962,148.666666667,135300.864262,21.2857142857,1839.9,08:14.0,02:15.3,457.61477812,141.713435077,326.054526,1.36326530612,563.144652,0.568145934555,1839.9,1.80263157895,3252,50.0,191293.118277,03:11.2,02:15.3,0,149,0,0,0,0,0,135300.864262,4.9705e+11,4,0.0,0.0,0.0,0.0,0.0,28.2527881041,0.0,0.0,99.7138091099,10.4167551393,3.69546789466
+176,39799312,496890.000105,148.285714286,134976.811268,21.2380952381,1850.5,08:16.8,02:14.9,450.62353798,141.483691644,347.850804,1.36238095238,599.620056,0.571160947145,1850.5,1.82285714286,3252,50.0,191293.118277,03:11.2,02:14.9,0,148,0,0,0,0,0,134976.811268,4.9972e+11,4,0.0,0.0,0.0,0.0,0.0,28.4090909091,0.0,0.0,100.596800752,10.4651757627,3.7043399922
+177,39799313,499769.999981,147.619047619,135463.633431,20.8571428571,1861.2,08:19.7,02:15.4,456.67402498,144.839355293,330.502746,1.3587755102,574.710024,0.579918778356,1861.2,1.75510204082,3252,50.0,191293.118277,03:11.2,02:15.4,0,148,0,0,0,0,0,135463.633431,5.0265e+11,4,0.0,0.0,0.0,0.0,0.0,28.7313432836,0.0,0.0,97.2105277427,10.6180243948,3.69102752773
+178,39799314,502710.000038,147.19047619,135766.017193,20.5714285714,1871.9,08:22.7,02:15.7,451.3696588,142.519495485,330.947568,1.3568707483,584.496108,0.576471579536,1871.9,1.83204633205,3252,50.0,191293.118277,03:11.2,02:15.7,0,147,0,0,0,0,0,135766.017193,5.0564e+11,4,0.0,0.0,0.0,0.0,0.0,27.1062271062,0.0,0.0,98.1342334945,10.74151959,3.68280671656
+179,39799315,505680.000067,147.428571429,136042.640233,20.4761904762,1882.6,08:25.6,02:16.0,459.4732868,138.519585991,334.506144,1.36469387755,568.482516,0.575279416416,1882.6,1.81904761905,3252,50.0,191293.118277,03:11.2,02:16.0,0,147,0,0,0,0,0,136042.640233,5.0859e+11,4,0.0,0.0,0.0,0.0,0.0,27.6752767528,0.0,0.0,100.353310532,10.7695372316,3.67531826158
+180,39799316,508500.0,147.80952381,135635.192846,20.3333333333,1893.3,08:28.5,02:15.6,468.43714608,139.5408896,335.395788,1.37870748299,590.278794,0.567668322861,1893.3,1.74321880651,3252,50.0,191293.118277,03:11.2,02:15.6,0,148,0,0,0,0,0,135635.192846,5.1138e+11,4,0.0,0.0,0.0,0.0,0.0,29.3680297398,0.0,0.0,100.519284677,10.8777803541,3.68635889778
+181,39799317,511410.000086,148.571428571,135228.054118,20.2380952381,1904.3,08:31.4,02:15.2,469.18608108,144.373384534,358.971354,1.38632653061,637.874748,0.568806989976,1904.3,1.80705009276,3252,50.0,191293.118277,03:11.2,02:15.2,0,149,0,0,0,0,0,135228.054118,5.1434e+11,4,0.0,0.0,0.0,0.0,0.0,28.0,0.0,0.0,98.0348549052,10.9618743747,3.6974576264
+182,39799318,514440.000057,149.333333333,135091.590969,20.2857142857,1915.4,08:34.4,02:15.0,472.29378308,148.129254179,322.051128,1.38857142857,586.720218,0.558225432086,1915.4,1.80705009276,3252,50.0,191293.118277,03:11.2,02:15.0,0,149,0,0,0,0,0,135091.590969,5.1746e+11,4,0.0,0.0,0.0,0.0,0.0,27.4021352313,0.0,0.0,95.8389967843,10.9471894499,3.70119262355
+183,39799319,517410.000086,150.142857143,135165.185389,20.1428571429,1926.2,08:37.4,02:15.1,470.79285682,139.313500906,336.285432,1.38523809524,580.49271,0.552451093149,1926.2,1.81578947368,3252,50.0,191293.118277,03:11.2,02:15.1,0,150,0,0,0,0,0,135165.185389,5.2034e+11,4,0.0,0.0,0.0,0.0,0.0,27.8388278388,0.0,0.0,101.737322801,11.0188263186,3.69917740697
+184,39799320,520380.000114,150.857142857,135528.874331,19.9047619048,1937.3,08:40.3,02:15.5,462.43652756,140.338698368,350.519736,1.38006802721,656.557272,0.549901547877,1937.3,1.79220779221,3252,50.0,191293.118277,03:11.2,02:15.5,0,151,0,0,0,0,0,135528.874331,5.2335e+11,4,0.0,0.0,0.0,0.0,0.0,28.0,0.0,0.0,100.183247751,11.1207079741,3.68925074061
+185,39799321,523170.000076,151.761904762,135908.232418,19.9047619048,1947.8,08:43.1,02:15.9,469.9886368,144.1407744,335.84061,1.37489795918,609.850962,0.56103077658,1947.8,1.7866419295,3252,50.0,191293.118277,03:11.2,02:15.9,0,152,0,0,0,0,0,135908.232418,5.26e+11,4,0.0,0.0,0.0,0.0,0.0,28.0,0.0,0.0,96.726149754,11.0896669516,3.67895300457
+186,39799322,526230.000019,152.380952381,135536.044927,20.0476190476,1959.1,08:46.2,02:15.5,464.41203653,141.943427083,332.726856,1.37003401361,576.489312,0.578327192904,1959.1,1.80639097744,3252,50.0,191293.118277,03:11.2,02:15.5,0,152,0,0,0,0,0,135536.044927,5.293e+11,4,0.0,0.0,0.0,0.0,0.0,27.6363636364,0.0,0.0,99.0349148838,11.0408788706,3.68905555914
+187,39799323,529140.000105,152.666666667,135676.953847,20.3333333333,1969.8,08:49.1,02:15.6,463.23852347,140.11044355,347.850804,1.36343537415,569.37216,0.593066463629,1969.8,1.79135338346,3252,50.0,191293.118277,03:11.2,02:15.6,0,153,0,0,0,0,0,135676.953847,5.3203e+11,4,0.0,0.0,0.0,0.0,0.0,28.0442804428,0.0,0.0,100.018257266,10.8744322026,3.68522424644
+188,39799324,532049.999952,152.904761905,135784.677306,20.7380952381,1980.6,08:52.0,02:15.7,471.712087535,142.63489588,340.28883,1.35807823129,561.365364,0.594141310259,1980.6,1.78665413534,3252,50.0,191293.118277,03:11.2,02:15.7,0,153,0,0,0,0,0,135784.677306,5.3497e+11,4,0.0,0.0,0.0,0.0,0.0,27.8388278388,0.0,0.0,98.0144170752,10.6537285142,3.68230060946
+189,39799325,534960.000038,153.261904762,135356.212775,21.0238095238,1991.4,08:54.9,02:15.3,480.500726285,142.63489588,356.302422,1.35675170068,632.536884,0.591064693856,1991.4,1.81047619048,3252,50.0,191293.118277,03:11.2,02:15.3,0,153,0,0,0,0,0,135356.212775,5.3786e+11,4,0.0,0.0,0.0,0.0,0.0,27.7777777778,0.0,0.0,98.9481483694,10.5422096122,3.69395678078
+190,39799326,537240.00001,153.904761905,134031.309351,21.0238095238,2000.0,08:57.2,02:14.0,485.32090977,146.713264566,356.302422,1.36183673469,595.616658,0.587622263206,2000.0,1.81523809524,3252,50.0,191293.118277,03:11.2,02:14.0,0,154,0,0,0,0,0,134031.309351,5.3946e+11,4,0.0,0.0,0.0,0.0,0.0,27.7777777778,0.0,0.0,99.0786049127,10.6464196634,3.7304716519
diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz
index 039dc318..3838db52 100644
Binary files a/rowers/tests/testdata/testdata.csv.gz and b/rowers/tests/testdata/testdata.csv.gz differ
diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz
new file mode 100644
index 00000000..2d9b5194
Binary files /dev/null and b/rowers/tests/testdata/testdata.tcx.gz differ
diff --git a/rowers/tests/tests.py b/rowers/tests/tests.py
index 43ba5ceb..b83d27fa 100644
--- a/rowers/tests/tests.py
+++ b/rowers/tests/tests.py
@@ -1,4 +1,8 @@
#from __future__ import print_function
+import pytest
+
+pytestmark = pytest.mark.django_db
+
from bs4 import BeautifulSoup
import re
from nose_parameterized import parameterized
@@ -40,906 +44,9 @@ from rowers.dataprep import delete_strokedata
from redis import StrictRedis
redis_connection = StrictRedis()
-
-class DjangoTestCase(TestCase, MockTestCase):
- def _pre_setup(self):
- MockTestCase.setUp(self)
- TestCase._pre_setup(self)
- self.client = Client()
-
- def _post_teardown(self):
- TestCase._post_teardown(self)
- MockTestCase.tearDown(self)
- delete_strokedata(1)
-
-# to be done add polar mocks (for email processing)
-def mocked_requests(*args, **kwargs):
- with open('rowers/tests/testdata/c2jsonworkoutdata.txt','r') as infile:
- c2workoutdata = json.load(infile)
-
- with open('rowers/tests/testdata/c2jsonstrokedata.txt','r') as infile:
- c2strokedata = json.load(infile)
-
- polar_json = {
- 'available-user-data': []
- }
-
- c2workoutlist = json.load(open('rowers/tests/testdata/c2workoutlist.txt'))
-
- c2uploadjson = {
- "data": {
- "id": 339,
- "user_id": 1,
- "date": "2015-08-05 13:15:41",
- "timezone": "Europe/London",
- "date_utc": "2015-08-05 12:15:41",
- "distance": 5649,
- "type": "rower",
- "time": 8649,
- "time_formatted": "14:24.9",
- "workout_type": "JustRow",
- "source": "ErgData",
- "weight_class": "H",
- "verified": True,
- "ranked": False
- }
- }
-
- stravaworkoutlist = json.load(open('rowers/tests/testdata/stravaworkoutlist.txt'))
- sporttracksworkoutlist = json.load(open('rowers/tests/testdata/sporttracksworkouts.txt'))
-
- rkworkoutlistjson = json.load(open('rowers/tests/testdata/rkworkoutslist.txt','r'))
- uaworkoutlistjson = json.load(open('rowers/tests/testdata/uaworkoutlist.txt','r'))
-
- stravasummaryjson = json.load(open('rowers/tests/testdata/stravaworkoutsummary.txt','r'))
-
- stravatimejson = json.load(open('rowers/tests/testdata/stravatimetestdata.txt','r'))
- stravavelojson = json.load(open('rowers/tests/testdata/stravavelotestdata.txt','r'))
-
- stravapowerjson = json.load(open('rowers/tests/testdata/stravapowertestdata.txt','r'))
-
- stravadistancejson = json.load(open('rowers/tests/testdata/stravadistancetestdata.txt','r'))
- stravalatlongjson = json.load(open('rowers/tests/testdata/stravalatlongtestdata.txt','r'))
- stravahrjson = json.load(open('rowers/tests/testdata/stravahrtestdata.txt','r'))
- stravaspmjson = json.load(open('rowers/tests/testdata/stravaspmtestdata.txt','r'))
-
- uapostworkoutjson = json.load(open('rowers/tests/testdata/uapostworkoutresponse.txt','r'))
-
- tpuploadresponse = json.load(open('rowers/tests/testdata/tpuploadresponse.txt','r'))
-
- stravastreamjson = {
- 'time':stravatimejson,
- 'velocity_smooth':stravavelojson,
- 'distance':stravadistancejson,
- 'latlng':stravalatlongjson,
- 'heartrate':stravahrjson,
- 'cadence':stravaspmjson,
- 'power':stravapowerjson,
- }
-
- ststrokesjson = json.load(open('rowers/tests/testdata/sporttracksstrokedata.txt','r'))
-
- rkstrokesjson = json.load(open('rowers/tests/testdata/rkstrokes.txt','r'))
-
- uastrokesjson = json.load(open('rowers/tests/testdata/uastrokes.txt','r'))
- uauserjson = json.load(open('rowers/tests/testdata/uauser.txt','r'))
-
- class MockResponse:
- def __init__(self, json_data, status_code):
- self.json_data = json_data
- self.status_code = status_code
-
- def json(self):
- return self.json_data
-
-
- class MockHeaderResponse:
- def __init__(self, header_data, status_code):
- self.headers = header_data
- self.status_code = status_code
-
- class MockSession:
- def send(self,prepped):
- # prepped.url
- # prepped.body (post data)
- # prepped.headers
- # prepped.method
-
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
-
- return MockResponse(json_data,200)
-
- if not args:
- return MockSession()
-
- polartester = re.compile('.*?polaraccesslink\.com')
- c2tester = re.compile('.*?log\.concept2\.com')
- stravatester = re.compile('.*?strava\.com')
- sttester = re.compile('.*?sporttracks\.mobi')
- rktester = re.compile('.*?runkeeper\.com')
- uatester = re.compile('.*?mapmyfitness\.com')
- tptester = re.compile('.*?trainingpeaks\.com')
-
- c2importregex = '.*?concept2.com\/api\/users\/me\/results\/\d+'
- c2importtester = re.compile(c2importregex)
-
- c2uploadregex = '.*?concept2.com\/api\/users\/\d+\/results$'
- c2uploadtester = re.compile(c2uploadregex)
-
- c2strokesregex = '.*?concept2.com\/api\/users\/me\/results\/\d+\/strokes'
- c2strokestester = re.compile(c2strokesregex)
-
- c2workoutlistregex = '.*?concept2\.com\/api\/users\/me\/results\?page=\d'
- c2workoutlisttester = re.compile(c2workoutlistregex)
-
- stravaworkoutlistregex = '.*?strava\.com\/api\/v3\/athlete\/activities'
- stravaworkoutlisttester = re.compile(stravaworkoutlistregex)
-
- stravastreamregex = '.*?strava\.com\/api\/v3\/activities\/\d+\/streams\/(\w.*?)\?'
- stravastreamtester = re.compile(stravastreamregex)
-
- stravasummaryregex = '.*?strava\.com\/api\/v3\/activities\/\d+$'
- stravasummarytester = re.compile(stravasummaryregex)
-
- stuploadregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities.json$'
- stuploadtester = re.compile(stuploadregex)
-
- stworkoutlistregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities$'
- stworkoutlisttester = re.compile(stworkoutlistregex)
-
- ststrokesregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities/\d+$'
- ststrokestester = re.compile(ststrokesregex)
-
- rkuploadregex = '.*?api\.runkeeper\.com\/fitnessActivities$'
- rkuploadtester = re.compile(rkuploadregex)
- rkuserregex = '.*?api\.runkeeper\.com\/user$'
- rkusertester = re.compile(rkuserregex)
- rkstrokesregex = '.*?api\.runkeeper\.com\/fitnessActivities/\d+$'
- rkstrokestester = re.compile(rkstrokesregex)
-
- uaapiregex = '.*?api\.ua\.com'
- uaapitester = re.compile(uaapiregex)
-
- uauploadregex = '.*?api\.ua\.com\/v7.1\/workout\/$'
- uauploadtester = re.compile(uauploadregex)
-
- uastrokesregex = '.*?api\.ua\.com\/v7.1\/workout\/\d+'
- uastrokestester = re.compile(uastrokesregex)
-
- ualistregex = '.*?api\.ua\.com\/v7.1\/workout\/\?user'
- ualisttester = re.compile(ualistregex)
-
- uauserregex = '.*?api\.ua\.com\/v7.1\/user\/self\/'
- uausertester = re.compile(uauserregex)
-
- tpuploadregex = '.*?trainingpeaks\.com\/v1\/file'
- tpuploadtester = re.compile(tpuploadregex)
-
- if polartester.match(args[0]):
- json_data = polar_json
- return MockResponse(json_data,200)
-
- if tptester.match(args[0]):
- if 'token' in args[0]:
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
- return MockResponse(json_data,200)
- elif tpuploadtester.match(args[0]):
- return MockResponse(tpuploadresponse,200)
-
- if uaapitester.match(args[0]):
- if 'access_token' in args[0]:
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
- return MockResponse(json_data,200)
- elif uauploadtester.match(args[0]):
- if 'data' in kwargs:
- return MockResponse(uapostworkoutjson,200)
- elif uastrokestester.match(args[0]):
- return MockResponse(uastrokesjson,200)
- elif ualisttester.match(args[0]):
- return MockResponse(uaworkoutlistjson,200)
- elif uausertester.match(args[0]):
- return MockResponse(uauserjson,200)
-
-
- if uatester.match(args[0]):
- if 'access_token' in args[0]:
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
- return MockResponse(json_data,200)
-
-
- if rktester.match(args[0]):
- if 'token' in args[0]:
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
- return MockResponse(json_data,200)
- elif rkuploadtester.match(args[0]):
- if 'data' in kwargs:
- # post
- header_data = {
- 'Location': '/fitnessActivities/12'
- }
- return MockHeaderResponse(header_data,200)
- else:
- json_data = rkworkoutlistjson
- return MockResponse(json_data,200)
- elif rkusertester.match(args[0]):
- json_data = {
- "userID": 1234567890,
- "profile": "/profile",
- "settings": "/settings",
- "fitness_activities": "/fitnessActivities",
- "strength_training_activities": "/strengthTrainingActivities",
- "background_activities": "/backgroundActivities",
- "sleep": "/sleep",
- "nutrition": "/nutrition",
- "weight": "/weight",
- "general_measurements": "/generalMeasurements",
- "diabetes": "/diabetes",
- "records": "/records",
- "team": "/team"
- }
- return MockResponse(json_data, 200)
- elif rkstrokestester.match(args[0]):
- return MockResponse(rkstrokesjson,200)
-
- if sttester.match(args[0]):
- if 'oauth2/token' in args[0]:
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
- return MockResponse(json_data,200)
- if ststrokestester.match(args[0]):
- return MockResponse(ststrokesjson,200)
- if stuploadtester.match(args[0]):
- json_data = {
- "uris": [
- "https://api.sporttracks.mobi/api/v2/fitnessActivities/123456.json"
- ]
- }
- return MockResponse(json_data, 200)
- if stworkoutlisttester.match(args[0]):
- return MockResponse(sporttracksworkoutlist,200)
-
-
- if stravatester.match(args[0]):
- if stravaworkoutlisttester.match(args[0]):
- return MockResponse(stravaworkoutlist,200)
- if stravastreamtester.match(args[0]):
- metric = stravastreamtester.match(args[0]).group(1)
- json_data = stravastreamjson[metric]
- return MockResponse(json_data,200)
- elif stravasummarytester.match(args[0]):
- return MockResponse(stravasummaryjson,200)
- elif 'token' in args[0]:
- json_data = {
- "token_type": "Bearer",
- "access_token": "987654321234567898765432123456789",
- "refresh_token": "1234567898765432112345678987654321",
- "expires_at": 1531385304
- }
- return MockResponse(json_data,200)
-
-
- if c2tester.match(args[0]):
- if c2uploadtester.match(args[0]):
- return MockResponse(c2uploadjson,201)
- if c2strokestester.match(args[0]):
- return MockResponse(c2strokedata,200)
- elif c2importtester.match(args[0]):
- return MockResponse(c2workoutdata,200)
- elif c2workoutlisttester.match(args[0]):
- return MockResponse(c2workoutlist,200)
- elif 'access_token' in args[0]:
- json_data = {
- 'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
- 'expires_in': 604800,
- 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
- }
- return MockResponse(json_data,200)
- elif 'users/me' in args[0]:
- json_data = {
- 'data': {
- 'username': 'john',
- 'id': 1234,
- }
- }
- return MockResponse(json_data,200)
- elif 'results' in args[0]:
- json_data = {
- 'data': {
- 'id': 1223,
- }
- }
- else:
- return MockResponse(c2workoutdata,200)
-
- return MockResponse(None,404)
-
-
-class C2Objects(DjangoTestCase):
- def setUp(self):
- self.c = Client()
- self.u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
-
- self.u.first_name = 'John'
- self.u.last_name = 'Sander'
- self.u.save()
- self.r = Rower.objects.create(user=self.u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
- self.r.c2token = '12'
- self.r.c2refreshtoken = 'ab'
- self.r.tokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
- self.r.save()
- self.c.login(username='john',password='koeinsloot')
-
- self.nu = datetime.datetime.now()
-
- filename = 'rowers/tests/testdata/testdata.csv'
-
- rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
- hrut1=self.r.ut1,hrat=self.r.at,
- hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
- row = rdata(filename,rower=rr)
- totaldist = row.df['cum_dist'].max()
- totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
- totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
-
-
- hours = int(totaltime/3600.)
- minutes = int((totaltime - 3600.*hours)/60.)
- seconds = int(totaltime - 3600.*hours - 60.*minutes)
- tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
-
- duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
-
-
- workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
- workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
-
- self.w = Workout.objects.create(
- name='testworkout',workouttype='water',
- user=self.r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=workoutstarttime,
- startdatetime=row.rowdatetime,
- duration=duration,distance=totaldist,
- csvfilename=filename
- )
-
-
- @patch('rowers.c2stuff.requests.Session', side_effect=mocked_requests)
- def test_c2_callback(self, mock_Session):
- response = self.c.get('/call_back?code=dsdoij232s',follow=True)
-
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.c2stuff.Session', side_effect=mocked_requests)
- def test_c2_token_refresh(self, mock_post):
- response = self.c.get('/rowers/me/c2refresh/',follow=True)
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
- def test_c2_upload(self, mock_get, mock_post):
- response = self.c.get('/rowers/workout/1/c2uploadw/')
-
- self.assertRedirects(response,
- expected_url = '/rowers/workout/1/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.url, '/rowers/workout/1/edit')
- self.assertEqual(response.status_code, 302)
-
- @patch('rowers.c2stuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
- def test_c2_list(self, mock_get, mock_post):
- response = self.c.get('/rowers/workout/c2list',follow=True)
-
- self.assertEqual(response.status_code,200)
-
- @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests)
- def test_c2_import(self, mock_get):
-
- response = self.c.get('/rowers/workout/c2import/12/',follow=True)
-
- self.assertRedirects(response,
- expected_url='/rowers/workout/2/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.status_code, 200)
-
-
- def test_strokedata(self):
- with open('rowers/tests/testdata/c2stroketestdata.txt','r') as infile:
- res = json.load(infile)
-
- strokedata = pd.DataFrame.from_dict(res['data'])
-
- with open('rowers/tests/testdata/c2testdata.txt','r') as infile:
- res = json.load(infile)
-
- data = res['data']
-
- from rowers.views import add_workout_from_strokedata
-
- res = add_workout_from_strokedata(self.u,1,data,strokedata,source='c2')
-
- def test_strokedatanohr(self):
- with open('rowers/tests/testdata/c2strokedatanohr.txt','r') as infile:
- res = json.load(infile)
-
- strokedata = pd.DataFrame.from_dict(res['data'])
-
- with open('rowers/tests/testdata/c2testdata.txt','r') as infile:
- res = json.load(infile)
-
- data = res['data']
-
- from rowers.views import add_workout_from_strokedata
-
-
- res = add_workout_from_strokedata(self.u,1,data,strokedata,source='c2')
-
-
-class StravaObjects(DjangoTestCase):
- def setUp(self):
- self.c = Client()
- self.u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
-
- self.u.first_name = 'John'
- self.u.last_name = 'Sander'
- self.u.save()
- self.r = Rower.objects.create(user=self.u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
- self.r.stravatoken = '12'
-
- self.r.save()
- self.c.login(username='john',password='koeinsloot')
-
- @patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
- def test_strava_list(self, mock_get):
- response = self.c.get('/rowers/workout/stravaimport/',follow=True)
-
- self.assertEqual(response.status_code,200)
-
- @patch('rowers.utils.requests.get', side_effect=mocked_requests)
- def test_strava_import(self, mock_get):
-
- response = self.c.get('/rowers/workout/stravaimport/12',follow=True)
-
- self.assertRedirects(response,
- expected_url='/rowers/workout/1/edit',
- status_code=301,target_status_code=200)
-
- self.assertEqual(response.status_code, 200)
-
-
-
-class STObjects(DjangoTestCase):
- def setUp(self):
- self.c = Client()
- self.u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
-
- self.u.first_name = 'John'
- self.u.last_name = 'Sander'
- self.u.save()
- self.r = Rower.objects.create(user=self.u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
-
- self.r.sporttrackstoken = '12'
- self.r.sporttracksrefreshtoken = '12'
- self.r.sporttrackstokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
- self.r.save()
-
- self.c.login(username='john',password='koeinsloot')
-
- self.nu = datetime.datetime.now()
-
- filename = 'rowers/tests/testdata/testdata.csv'
-
- rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
- hrut1=self.r.ut1,hrat=self.r.at,
- hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
- row = rdata(filename,rower=rr)
- totaldist = row.df['cum_dist'].max()
- totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
- totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
-
-
- hours = int(totaltime/3600.)
- minutes = int((totaltime - 3600.*hours)/60.)
- seconds = int(totaltime - 3600.*hours - 60.*minutes)
- tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
-
- duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
-
-
- workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
- workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
-
- self.w = Workout.objects.create(
- name='testworkout',workouttype='water',
- user=self.r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=workoutstarttime,
- startdatetime=row.rowdatetime,
- duration=duration,distance=totaldist,
- csvfilename=filename
- )
-
- @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests)
- def test_sporttracks_callback(self, mock_post):
- response = self.c.get('/sporttracks_callback?code=dsdoij232s',follow=True)
-
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests)
- def test_sporttracks_token_refresh(self, mock_post):
- response = self.c.get('/rowers/me/sporttracksrefresh/',follow=True)
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.sporttracksstuff.requests.get', side_effect=mocked_requests)
- def test_sporttracks_upload(self, mock_get, mock_post):
- response = self.c.get('/rowers/workout/1/sporttracksuploadw/')
-
- self.assertRedirects(response,
- expected_url = '/rowers/workout/1/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.url, '/rowers/workout/1/edit')
- self.assertEqual(response.status_code, 302)
-
- @patch('rowers.sporttracksstuff.requests.get', side_effect=mocked_requests)
- def test_sporttracks_list(self, mock_get):
- response = self.c.get('/rowers/workout/sporttracksimport',follow=True)
-
- self.assertEqual(response.status_code,200)
-
- @patch('rowers.imports.requests.get', side_effect=mocked_requests)
- def test_sporttracks_import(self, mock_get):
-
- response = self.c.get('/rowers/workout/sporttracksimport/12/',follow=True)
-
- self.assertRedirects(response,
- expected_url='/rowers/workout/2/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.status_code, 200)
-
- def test_strokedata(self):
- with open('rowers/tests/testdata/sporttrackstestdata.txt','r') as infile:
- data = json.load(infile)
-
- from rowers.sporttracksstuff import add_workout_from_data
-
- res = add_workout_from_data(self.u,1,data,data)
-
- def test_strokedatanohr(self):
- with open('rowers/tests/testdata/sporttrackstestnohr.txt','r') as infile:
- data = json.load(infile)
-
- from rowers.sporttracksstuff import add_workout_from_data
-
-
-
- res = add_workout_from_data(self.u,1,data,data)
-
-class RunKeeperObjects(DjangoTestCase):
- def setUp(self):
- self.c = Client()
- self.u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
-
- self.u.first_name = 'John'
- self.u.last_name = 'Sander'
- self.u.save()
- self.r = Rower.objects.create(user=self.u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
-
- self.r.runkeepertoken = '12'
-
- self.r.save()
-
- self.c.login(username='john',password='koeinsloot')
-
- self.nu = datetime.datetime.now()
-
- filename = 'rowers/tests/testdata/testdata.csv'
-
- rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
- hrut1=self.r.ut1,hrat=self.r.at,
- hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
- row = rdata(filename,rower=rr)
- totaldist = row.df['cum_dist'].max()
- totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
- totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
-
-
- hours = int(totaltime/3600.)
- minutes = int((totaltime - 3600.*hours)/60.)
- seconds = int(totaltime - 3600.*hours - 60.*minutes)
- tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
-
- duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
-
-
- workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
- workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
-
- self.w = Workout.objects.create(
- name='testworkout',workouttype='water',
- user=self.r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=workoutstarttime,
- startdatetime=row.rowdatetime,
- duration=duration,distance=totaldist,
- csvfilename=filename
- )
-
- @patch('rowers.runkeeperstuff.requests.post', side_effect=mocked_requests)
- def test_runkeeper_callback(self, mock_post):
- response = self.c.get('/runkeeper_callback?code=dsdoij232s',follow=True)
-
- self.assertEqual(response.status_code, 200)
-
- @patch('rowers.runkeeperstuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.runkeeperstuff.requests.get', side_effect=mocked_requests)
- def test_runkeeper_upload(self, mock_get, mock_post):
- response = self.c.get('/rowers/workout/1/runkeeperuploadw/')
-
- self.assertRedirects(response,
- expected_url = '/rowers/workout/1/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.url, '/rowers/workout/1/edit')
- self.assertEqual(response.status_code, 302)
-
- @patch('rowers.runkeeperstuff.requests.get', side_effect=mocked_requests)
- def test_runkeeper_list(self, mock_get):
- response = self.c.get('/rowers/workout/runkeeperimport',follow=True)
-
- self.assertEqual(response.status_code,200)
-
- @patch('rowers.imports.requests.get', side_effect=mocked_requests)
- def test_runkeeper_import(self, mock_get):
-
- response = self.c.get('/rowers/workout/runkeeperimport/12/',follow=True)
-
- self.assertRedirects(response,
- expected_url='/rowers/workout/2/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.status_code, 200)
-
-
-
-class UAObjects(DjangoTestCase):
- def setUp(self):
- self.c = Client()
- self.u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
-
- self.u.first_name = 'John'
- self.u.last_name = 'Sander'
- self.u.save()
- self.r = Rower.objects.create(user=self.u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
-
- self.r.underarmourtoken = '12'
- self.r.underarmourrefreshtoken = '12'
- self.r.underarmourtokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
- self.r.save()
-
- self.c.login(username='john',password='koeinsloot')
-
- self.nu = datetime.datetime.now()
-
- filename = 'rowers/tests/testdata/testdata.csv'
-
- rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
- hrut1=self.r.ut1,hrat=self.r.at,
- hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
- row = rdata(filename,rower=rr)
- totaldist = row.df['cum_dist'].max()
- totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
- totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
-
-
- hours = int(totaltime/3600.)
- minutes = int((totaltime - 3600.*hours)/60.)
- seconds = int(totaltime - 3600.*hours - 60.*minutes)
- tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
-
- duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
-
-
- workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
- workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
-
- self.w = Workout.objects.create(
- name='testworkout',workouttype='water',
- user=self.r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=workoutstarttime,
- startdatetime=row.rowdatetime,
- duration=duration,distance=totaldist,
- csvfilename=filename
- )
-
- @patch('rowers.imports.requests.post', side_effect=mocked_requests)
- def test_underarmour_callback(self, mock_post):
- response = self.c.get('/underarmour_callback?code=dsdoij232s',follow=True)
-
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.underarmourstuff.requests.post', side_effect=mocked_requests)
- def test_underarmour_token_refresh(self, mock_post):
- response = self.c.get('/rowers/me/underarmourrefresh/',follow=True)
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.underarmourstuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.underarmourstuff.requests.get', side_effect=mocked_requests)
- def test_underarmour_upload(self, mock_get, mock_post):
- response = self.c.get('/rowers/workout/1/underarmouruploadw/')
-
- self.assertRedirects(response,
- expected_url = '/rowers/workout/1/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.url, '/rowers/workout/1/edit')
- self.assertEqual(response.status_code, 302)
-
- @patch('rowers.underarmourstuff.requests.get', side_effect=mocked_requests)
- def test_underarmour_list(self, mock_get):
- response = self.c.get('/rowers/workout/underarmourimport',follow=True)
-
- self.assertEqual(response.status_code,200)
-
- @patch('rowers.imports.requests.get', side_effect=mocked_requests)
- def test_underarmour_import(self, mock_get):
-
- response = self.c.get('/rowers/workout/underarmourimport/12/',follow=True)
-
- self.assertRedirects(response,
- expected_url='/rowers/workout/2/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.status_code, 200)
-
-
-class TPObjects(DjangoTestCase):
- def setUp(self):
- self.c = Client()
- self.u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
-
- self.u.first_name = 'John'
- self.u.last_name = 'Sander'
- self.u.save()
- self.r = Rower.objects.create(user=self.u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
-
- self.r.tptoken = '12'
- self.r.tprefreshtoken = '12'
- self.r.tptokenexpirydate = datetime.datetime.now()+datetime.timedelta(days=1)
- self.r.save()
-
- self.c.login(username='john',password='koeinsloot')
-
- self.nu = datetime.datetime.now()
-
- filename = 'rowers/tests/testdata/testdata.csv'
-
- rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
- hrut1=self.r.ut1,hrat=self.r.at,
- hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
- row = rdata(filename,rower=rr)
- totaldist = row.df['cum_dist'].max()
- totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
- totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
-
-
- hours = int(totaltime/3600.)
- minutes = int((totaltime - 3600.*hours)/60.)
- seconds = int(totaltime - 3600.*hours - 60.*minutes)
- tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
-
- duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
-
-
- workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
- workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
-
- self.w = Workout.objects.create(
- name='testworkout',workouttype='water',
- user=self.r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=workoutstarttime,
- startdatetime=row.rowdatetime,
- duration=duration,distance=totaldist,
- csvfilename=filename
- )
-
- @patch('rowers.imports.requests.post', side_effect=mocked_requests)
- def test_tp_callback(self, mock_post):
- response = self.c.get('/tp_callback?code=dsdoij232s',follow=True)
-
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests)
- def test_tp_token_refresh(self, mock_post):
- response = self.c.get('/rowers/me/tprefresh/',follow=True)
-
- self.assertEqual(response.status_code, 200)
-
-
- @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.tpstuff.requests.get', side_effect=mocked_requests)
- def test_tp_upload(self, mock_get, mock_post):
- response = self.c.get('/rowers/workout/1/tpuploadw/')
-
- self.assertRedirects(response,
- expected_url = '/rowers/workout/1/edit',
- status_code=302,target_status_code=200)
-
- self.assertEqual(response.url, '/rowers/workout/1/edit')
- self.assertEqual(response.status_code, 302)
-
-
+#@pytest.mark.django_db
class TestErrorPages(TestCase):
def test_error_handlers(self):
@@ -954,6 +61,7 @@ class TestErrorPages(TestCase):
self.assertEqual(response.status_code, 500)
self.assertIn('500 Internal Server Error', unicode(response))
+#@pytest.mark.django_db
class NewUserRegistrationTest(TestCase):
def setUp(self):
self.c = Client()
@@ -978,171 +86,14 @@ class NewUserRegistrationTest(TestCase):
form = RegistrationFormUniqueEmail(form_data)
self.assertTrue(form.is_valid())
- response = self.c.post('/rowers/register', form_data, follow=True)
+ response = self.c.post('/rowers/register/', form_data, follow=True)
self.assertRedirects(response,
expected_url='/rowers/me/gdpr-optin/?next=/rowers/list-workouts/',
status_code=302,target_status_code=200)
-from django_mailbox.models import Mailbox,MessageAttachment,Message
-
-class AutoExportTests(TestCase):
- def setUp(self):
- redis_connection.publish('tasks','KILL')
- u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
- r = Rower.objects.create(user=u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
- r.c2_auto_export = True
- r.sporttracks_auto_export = True
- r.mapmyfitness_auto_export = True
- r.trainingpeaks_auto_export = True
-
- r.save()
-
- nu = datetime.datetime.now()
- workoutsbox = Mailbox.objects.create(name='workouts')
- workoutsbox.save()
- failbox = Mailbox.objects.create(name='Failed')
- failbox.save()
-
- filename = 'testdata.csv'
-
- m = Message(mailbox=workoutsbox,
- from_header = u.email,
- subject = filename,
- body="""
----
-workouttype: water
-boattype: 2x
-...
- """)
- m.save()
- a2 = 'media/mailbox_attachments/'+filename
- copyfile('rowers/tests/testdata/'+filename,a2)
- a = MessageAttachment(message=m,document=a2[6:])
- a.save()
-
- def tearDown(self):
- for filename in os.listdir('media/mailbox_attachments'):
- path = os.path.join('media/mailbox_attachments/',filename)
- if not os.path.isdir(path):
- os.remove(path)
-
- @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.tpstuff.requests.get', side_effect=mocked_requests)
- def test_emailprocessing(self, mock_post, mock_get):
- out = StringIO()
- call_command('processemail', stdout=out, testing=True)
- self.assertIn('Successfully processed email attachments',out.getvalue())
-
-class UploadTests(TestCase):
- def setUp(self):
- redis_connection.publish('tasks','KILL')
- u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
- r = Rower.objects.create(user=u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
- nu = datetime.datetime.now()
- workoutsbox = Mailbox.objects.create(name='workouts')
- workoutsbox.save()
- failbox = Mailbox.objects.create(name='Failed')
- failbox.save()
- m = Message(mailbox=workoutsbox,
- from_header = u.email,
- subject = "3x(5min/2min)/r2 \r2",
- body = """
-workout run
- """)
- m.save()
- a2 = 'media/mailbox_attachments/colin2.csv'
- copyfile('rowers/tests/testdata/emails/colin.csv',a2)
- a = MessageAttachment(message=m,document=a2[6:])
- a.save()
-
- def tearDown(self):
- for filename in os.listdir('media/mailbox_attachments'):
- path = os.path.join('media/mailbox_attachments/',filename)
- if not os.path.isdir(path):
- try:
- os.remove(path)
- except IOError:
- pass
-
- @patch('requests.get', side_effect=mocked_requests)
- def test_email_workouttype(self, mock_get):
- out = StringIO()
- call_command('processemail', stdout=out, testing=True)
- w = Workout.objects.get(id=1)
- self.assertEqual(w.workouttype,'Run')
-
-class EmailTests(TestCase):
- def setUp(self):
- redis_connection.publish('tasks','KILL')
- u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot')
- r = Rower.objects.create(user=u,gdproptin=True,
- gdproptindate=timezone.now()
- )
-
- nu = datetime.datetime.now()
- workoutsbox = Mailbox.objects.create(name='workouts')
- workoutsbox.save()
- failbox = Mailbox.objects.create(name='Failed')
- failbox.save()
-
- for filename in os.listdir(u'rowers/tests/testdata/emails'):
- m = Message(mailbox=workoutsbox,
- from_header = u.email,
- subject = filename,
- body="""
----
-workouttype: water
-boattype: 4x
-...
- """)
- m.save()
- a2 = 'media/mailbox_attachments/'+filename
- copyfile(u'rowers/tests/testdata/emails/'+filename,a2)
- a = MessageAttachment(message=m,document=a2[6:])
- a.save()
-
- m = Message(mailbox=workoutsbox,
- from_header = u.email,
- subject = "3x(5min/2min)/r2 \r2",
- body = """
-workout water
- """)
- m.save()
- a2 = 'media/mailbox_attachments/colin2.csv'
- copyfile('rowers/tests/testdata/emails/colin.csv',a2)
- a = MessageAttachment(message=m,document=a2[6:])
- a.save()
-
-
- def tearDown(self):
- for filename in os.listdir('media/mailbox_attachments'):
- path = os.path.join('media/mailbox_attachments/',filename)
- if not os.path.isdir(path):
- try:
- os.remove(path)
- except IOError:
- pass
-
- @patch('requests.get', side_effect=mocked_requests)
- def test_emailprocessing(self, mock_get):
- out = StringIO()
- call_command('processemail', stdout=out,testing=True)
- self.assertIn('Successfully processed email attachments',out.getvalue())
-
+#@pytest.mark.django_db
class WorkoutTests(TestCase):
def setUp(self):
redis_connection.publish('tasks','KILL')
@@ -1162,6 +113,7 @@ class WorkoutTests(TestCase):
def test_checkworkoutuser(self):
self.assertEqual(checkworkoutuser(self.u,self.w),True)
+#@pytest.mark.django_db
class C2Tests(TestCase):
def setUp(self):
redis_connection.publish('tasks','KILL')
@@ -1182,6 +134,7 @@ class C2Tests(TestCase):
# should raise NoTokenError
self.assertRaises(NoTokenError)
+#@pytest.mark.django_db
class DataTest(TestCase):
def setUp(self):
redis_connection.publish('tasks','KILL')
@@ -1297,7 +250,7 @@ class DataTest(TestCase):
form = RowerForm(data=form_data)
self.assertFalse(form.is_valid())
- def test_painsled(self):
+ def test_painsled_form(self):
filename = 'rowers/tests/testdata/testdata.csv'
f = open(filename,'rb')
file_data = {'file': SimpleUploadedFile(f.name, f.read())}
@@ -1310,65 +263,127 @@ class DataTest(TestCase):
form = DocumentsForm(form_data,file_data)
self.assertTrue(form.is_valid())
-
+
f.close()
+class InteractiveChartTest(TestCase):
+ def setUp(self):
+ redis_connection.publish('tasks','KILL')
+ u = User.objects.create_user('john',
+ 'sander@ds.ds',
+ 'koeinsloot')
+ r = Rower.objects.create(user=u,gdproptin=True,
+ gdproptindate=timezone.now()
+ )
+ self.nu = datetime.datetime.now()
+
+ self.filename = 'rowers/tests/testdata/testdata.csv'
+ self.wotw = Workout.objects.create(name='testworkout',
+ workouttype='water',
+ user=r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=self.nu.strftime('%H:%M:%S'),
+ duration="0:55:00",distance=8000,
+ csvfilename=self.filename)
+
+ self.wote = Workout.objects.create(name='testworkout',
+ workouttype='Indoor Rower',
+ user=r,date=self.nu.strftime('%Y-%m-%d'),
+ starttime=self.nu.strftime('%H:%M:%S'),
+ duration="0:55:00",distance=8000,
+ csvfilename=self.filename)
+
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_painsled(self, mocked_sqlalchemy, mocked_read_df_sql):
u = User.objects.get(username='john')
r = Rower.objects.get(user=u)
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an,ftp=r.ftp)
- row = rdata(filename,rower=rr)
- totaldist = row.df['cum_dist'].max()
- totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
- totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
-
-
- hours = int(totaltime/3600.)
- minutes = int((totaltime - 3600.*hours)/60.)
- seconds = int(totaltime - 3600.*hours - 60.*minutes)
- tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
-
- duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
-
-
- workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
- workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
-
- w = Workout.objects.create(name='testworkout',workouttype='water',
- user=r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=workoutstarttime,
- duration=duration,distance=totaldist,
- csvfilename=filename)
-
+ row = rdata(self.filename,rower=rr)
fig1 = plots.mkplot(row,'test')
- res = iplots.interactive_chart(w.id)
- res = iplots.interactive_chart(w.id,promember=1)
- res = iplots.interactive_bar_chart(w.id)
- res = iplots.interactive_bar_chart(w.id,promember=1)
- res = iplots.interactive_flex_chart2(w.id,promember=0,xparam='time',
- yparam1='pace',yparam2='hr')
- res = iplots.interactive_flex_chart2(w.id,promember=0,xparam='distance',
- yparam1='pace',yparam2='hr')
- res = iplots.interactive_flex_chart2(w.id,promember=0,xparam='time',
- yparam1='pace',yparam2='spm')
- res = iplots.interactive_flex_chart2(w.id,promember=0,xparam='distance',
- yparam1='pace',yparam2='spm')
- res = iplots.interactive_flex_chart2(w.id,promember=1,xparam='time',
- yparam1='pace',yparam2='hr')
- res = iplots.interactive_flex_chart2(w.id,promember=1,xparam='distance',
- yparam1='pace',yparam2='hr')
- res = iplots.interactive_flex_chart2(w.id,promember=1,xparam='time',
- yparam1='pace',yparam2='spm')
- res = iplots.interactive_flex_chart2(w.id,promember=1,xparam='distance',
- yparam1='pace',yparam2='spm')
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart1(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_chart(self.wote.id)
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart2(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_chart(self.wote.id,promember=1)
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart3(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_bar_chart(self.wote.id)
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart4(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_bar_chart(self.wote.id,promember=1)
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart5(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,promember=0,
+ xparam='time',
+ yparam1='pace',yparam2='hr')
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart6(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,
+ promember=0,xparam='distance',
+ yparam1='pace',yparam2='hr')
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart7(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,promember=0,
+ xparam='time',
+ yparam1='pace',yparam2='spm')
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart8(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,
+ promember=0,xparam='distance',
+ yparam1='pace',yparam2='spm')
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart9(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,
+ promember=1,xparam='time',
+ yparam1='pace',yparam2='hr')
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart10(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,
+ promember=1,xparam='distance',
+ yparam1='pace',yparam2='hr')
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart11(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,
+ promember=1,xparam='time',
+ yparam1='pace',yparam2='spm')
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.read_df_sql')
+ def test_interactive_chart12(self, mocked_sqlalchemy,mocked_read_df_sql):
+ res = iplots.interactive_flex_chart2(self.wote.id,promember=1,
+ xparam='distance',
+ yparam1='pace',yparam2='spm')
+#@pytest.mark.django_db
class ViewTest(TestCase):
def setUp(self):
redis_connection.publish('tasks','KILL')
@@ -1391,8 +406,10 @@ class ViewTest(TestCase):
self.assertEqual(response.status_code, 200)
- def test_upload_view_sled(self):
- self.c.login(username='john',password='koeinsloot')
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled(self, mocked_sqlalchemy):
+ login = self.c.login(username='john',password='koeinsloot')
+ self.assertTrue(login)
filename = 'rowers/tests/testdata/testdata.csv'
f = open(filename,'rb')
@@ -1413,7 +430,7 @@ class ViewTest(TestCase):
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
@@ -1421,11 +438,16 @@ class ViewTest(TestCase):
response = self.c.get('/rowers/workout/1/', form_data, follow=True)
self.assertEqual(response.status_code, 200)
- response = self.c.get('/rowers/workout/1/edit', form_data, follow=True)
+ response = self.c.get('/rowers/workout/1/edit/', form_data, follow=True)
self.assertEqual(response.status_code, 200)
- response = self.c.get('/rowers/workout/1/histo', form_data, follow=True)
+ response = self.c.get('/rowers/workout/1/histo/', form_data, follow=True)
+ self.assertEqual(response.status_code, 200)
+
+ response = self.c.get('/rowers/workout/1/workflow/',
+ follow=True)
+
self.assertEqual(response.status_code, 200)
form_data = {
@@ -1444,13 +466,16 @@ class ViewTest(TestCase):
}
form = WorkoutForm(data=form_data)
self.assertTrue(form.is_valid())
- response = self.c.post('/rowers/workout/1/edit', form_data, follow=True)
+ response = self.c.post('/rowers/workout/1/edit/', form_data, follow=True)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
@@ -1464,7 +489,8 @@ class ViewTest(TestCase):
self.assertEqual(response.status_code, 200)
- def test_upload_view_sled_negativetime(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled_negativetime(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/tim.csv'
@@ -1493,7 +519,7 @@ class ViewTest(TestCase):
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
@@ -1504,12 +530,15 @@ class ViewTest(TestCase):
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
-
- def test_upload_view_sled_noname(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled_noname(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/testdata.csv'
@@ -1532,16 +561,20 @@ class ViewTest(TestCase):
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_logcard(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_logcard(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/logcard.csv'
@@ -1573,7 +606,9 @@ class ViewTest(TestCase):
- def test_upload_view_TCX_CN(self):
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.TCXParser')
+ def test_upload_view_TCX_CN(self, mocked_sqlalchemy, mocked_tcx_parser):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/crewnerddata.tcx'
@@ -1595,7 +630,7 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
@@ -1615,9 +650,15 @@ class ViewTest(TestCase):
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_TCX_SpeedCoach2a(self):
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.TCXParser')
+ def test_upload_view_TCX_SpeedCoach2a(self, mocked_sqlalchemy,
+ mocked_tcx_parser):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/Speedcoach2example.csv'
@@ -1639,16 +680,22 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_TCX_SpeedCoach2b(self):
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.TCXParser')
+ def test_upload_view_TCX_SpeedCoach2b(self, mocked_sqlalchemy,
+ mocked_tcx_parser):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/Speedcoach2example.csv'
@@ -1670,18 +717,24 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_TCX_SpeedCoach2c(self):
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.TCXParser')
+ def test_upload_view_TCX_SpeedCoach2c(self, mocked_sqlalchemy,
+ mocked_tcx_parser):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/speedcoach3test3.csv'
@@ -1703,16 +756,21 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_SpeedCoach2v127(self):
+
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_SpeedCoach2v127(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/SpeedCoach2Linkv1.27.csv'
@@ -1734,17 +792,22 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_SpeedCoach2v127intervals(self):
+
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_SpeedCoach2v127intervals(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/SpeedCoach2Link_interval.csv'
@@ -1766,17 +829,24 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_TCX_NoHR(self):
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.TCXParser')
+ def test_upload_view_TCX_NoHR(self, mocked_sqlalchemy,
+ mocked_tcx_parser):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/NoHR.tcx'
@@ -1798,16 +868,23 @@ class ViewTest(TestCase):
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
f.close()
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_TCX_CN(self):
+
+ @patch('rowers.dataprep.create_engine')
+ @patch('rowers.dataprep.TCXParser')
+ def test_upload_view_TCX_CN(self, mocked_sqlalchemy,
+ mocked_tcx_parser):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/rowinginmotionexample.tcx'
@@ -1827,15 +904,20 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_RP(self):
+
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_RP(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/RP_testdata.csv'
@@ -1855,15 +937,20 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_Mystery(self):
+
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_Mystery(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/mystery.csv'
@@ -1883,15 +970,20 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_RP_interval(self):
+
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_RP_interval(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/RP_interval.csv'
@@ -1911,16 +1003,21 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
+
- def test_upload_view_sled_desktop(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled_desktop(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/painsled_desktop_example.csv'
@@ -1940,15 +1037,19 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_sled_ergdata(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled_ergdata(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/ergdata_example.csv'
@@ -1968,15 +1069,19 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_sled_boatcoach(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled_boatcoach(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/boatcoach.csv'
@@ -1996,15 +1101,19 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
- def test_upload_view_sled_ergstick(self):
+ @patch('rowers.dataprep.create_engine')
+ def test_upload_view_sled_ergstick(self, mocked_sqlalchemy):
self.c.login(username='john',password='koeinsloot')
filename = 'rowers/tests/testdata/ergstick.csv'
@@ -2024,13 +1133,16 @@ class ViewTest(TestCase):
form = DocumentsForm(form_data,file_data)
response = self.c.post('/rowers/workout/upload/', form_data, follow=True)
- self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+ self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
w = Workout.objects.get(id=1)
f_to_be_deleted = w.csvfilename
- os.remove(f_to_be_deleted+'.gz')
+ try:
+ os.remove(f_to_be_deleted+'.gz')
+ except WindowsError:
+ pass
# def test_upload_view_FIT_SpeedCoach2a(self):
@@ -2058,7 +1170,7 @@ class ViewTest(TestCase):
# form_data, follow=True,
# format='multipart')
# f.close()
-# self.assertRedirects(response, expected_url='/rowers/workout/1/edit',
+# self.assertRedirects(response, expected_url='/rowers/workout/1/edit/',
# status_code=302,target_status_code=200)
# self.assertEqual(response.status_code, 200)
@@ -2067,252 +1179,8 @@ class ViewTest(TestCase):
# f_to_be_deleted = w.csvfilename
# os.remove(f_to_be_deleted+'.gz')
-class URLTests(TestCase):
- def setUp(self):
- redis_connection.publish('tasks','KILL')
- u = User.objects.create_user('john',
- 'sander@ds.ds',
- 'koeinsloot',
- )
- r = Rower.objects.create(user=u,rowerplan='coach')
- self.c = Client()
- self.c.login(username='john',password='koeinsloot')
-
- self.nu = datetime.datetime.now()
- filename = 'rowers/tests/testdata/testdata.csv'
- self.wotw = Workout.objects.create(name='testworkout',
- workouttype='water',
- user=r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=self.nu.strftime('%H:%M:%S'),
- duration="0:55:00",distance=8000,
- csvfilename=filename)
-
- self.wote = Workout.objects.create(name='testworkout',
- workouttype='Indoor Rower',
- user=r,date=self.nu.strftime('%Y-%m-%d'),
- starttime=self.nu.strftime('%H:%M:%S'),
- duration="0:55:00",distance=8000,
- csvfilename=filename)
-
- powerperc = 100*np.array([r.pw_ut2,
- r.pw_ut1,
- r.pw_at,
- r.pw_tr,r.pw_an])/r.ftp
-
-
- self.hrdata = {
- 'hrmax':r.max,
- 'hrut2':r.ut2,
- 'hrut1':r.ut1,
- 'hrat':r.at,
- 'hrtr':r.tr,
- 'hran':r.an,
- 'ftp':r.ftp,
- 'powerperc':serialize_list(powerperc),
- 'powerzones':serialize_list(r.powerzones),
- }
-
- urlstotest = [
- '/rowers/400/',
- '/rowers/403/',
- '/rowers/404/',
- '/rowers/500/',
- '/rowers/502/',
- '/rowers/1/list-workouts/',
- '/rowers/1/list-workouts/2016-01-01/2016-12-31',
- '/rowers/1/ote-bests/',
- '/rowers/1/ote-bests2/2016-01-01/2016-12-31',
- '/rowers/about',
- '/rowers/addmanual/',
- '/rowers/agegroupcp/30',
- '/rowers/agegroupcp/30/1',
- '/rowers/agegrouprecords/male/hwt',
- '/rowers/agegrouprecords/male/hwt/2000m',
- '/rowers/agegrouprecords/male/hwt/2000min',
- '/rowers/ajax_agegroup/45/hwt/male/1',
- '/rowers/analysis/',
- '/rowers/analysis/user/1',
- '/rowers/brochure',
- '/rowers/courses/upload',
- '/rowers/createplan/',
- '/rowers/createplan/user/1/',
- '/rowers/cumstats/',
- '/rowers/cumstats/2016-01-01/2016-12-31',
- '/rowers/cumstats/user/1',
- '/rowers/cumstats/user/1/2016-01-01/2016-12-31',
- '/rowers/developers',
- '/rowers/email/',
- '/rowers/email/thankyou/',
- '/rowers/fitness-progress/',
- '/rowers/fitness-progress/user/1',
- '/rowers/fitness-progress/user/1/rower',
- '/rowers/flexall/',
- '/rowers/flexall/spm/hr/None/',
- '/rowers/flexall/spm/hr/None/2016-01-01/2016-12-31/',
- '/rowers/flexall/spm/hr/None/2016-01-01/2016-12-31/user/1',
- '/rowers/flexall/user/1/',
- '/rowers/flexalldata/',
- '/rowers/help',
- '/rowers/histo/',
- '/rowers/histo/user/1',
- '/rowers/histo/user/1/2016-01-01/2016-12-31',
- '/rowers/histodata',
- '/rowers/job-kill/1',
- '/rowers/jobs-status/',
- '/rowers/laboratory/',
- '/rowers/laboratory/user/1',
- '/rowers/legal',
- '/rowers/list-courses/',
- '/rowers/list-graphs/',
- '/rowers/list-jobs/',
- '/rowers/list-workouts/',
- '/rowers/list-workouts/2016-01-01/2016-12-31',
- '/rowers/list-workouts/2016-01-01/2016-12-31/user/1/',
- '/rowers/list-workouts/ranking',
- '/rowers/list-workouts/user/1/',
- '/rowers/me/calcdps/',
- '/rowers/me/edit/',
- '/rowers/me/edit/user/1',
- '/rowers/me/exportsettings/',
- '/rowers/me/exportsettings/user/1',
- '/rowers/me/favoritecharts/',
- '/rowers/me/favoritecharts/user/1',
- '/rowers/me/invitation/',
- '/rowers/me/preferences/',
- '/rowers/me/preferences/user/1',
- '/rowers/me/request/',
- '/rowers/me/teams/',
- '/rowers/me/workflowconfig2/',
- '/rowers/me/workflowconfig2/user/1',
- '/rowers/me/workflowdefault',
- '/rowers/multi-compare',
- '/rowers/ote-bests/',
- '/rowers/ote-bests/2016-01-01/2016-12-31',
- '/rowers/ote-bests/user/1',
- '/rowers/ote-bests/user/1/2016-01-01/2016-12-31',
- '/rowers/ote-bests2/',
- '/rowers/ote-bests2/2016-01-01/2016-12-31',
- '/rowers/ote-bests2/user/1',
- '/rowers/ote-ranking/',
- '/rowers/ote-ranking/2016-01-01/2016-12-31',
- '/rowers/ote-ranking/user/1/',
- '/rowers/ote-ranking/user/1/2016-01-01/2016-12-31',
- '/rowers/otw-bests/',
- '/rowers/otw-bests/2016-01-01/2016-12-31',
- '/rowers/otw-bests/user/1/2016-01-01/2016-12-31',
- '/rowers/partners',
- '/rowers/physics',
- '/rowers/planrequired',
- '/rowers/promembership',
- '/rowers/register',
- '/rowers/register/thankyou/',
- '/rowers/sessions/',
- '/rowers/sessions/2016-01-01/2016-12-31',
- '/rowers/sessions/2016-01-01/2016-12-31/user/1',
- '/rowers/sessions/coach/',
- '/rowers/sessions/coach/user/1/',
- '/rowers/sessions/create/',
- '/rowers/sessions/create/user/1',
- '/rowers/sessions/manage/',
- '/rowers/sessions/manage/user/1/',
- '/rowers/sessions/multiclone/',
- '/rowers/sessions/multiclone/user/1/',
- '/rowers/sessions/multicreate/',
- '/rowers/sessions/multicreate/user/1/',
- '/rowers/sessions/print/',
- '/rowers/sessions/print/user/1',
- '/rowers/sessions/teamcreate/',
- '/rowers/sessions/user/1',
- '/rowers/team-compare-select/',
- '/rowers/team-compare-select/workout/1',
- '/rowers/team-compare-select/2016-01-01/2016-12-31',
- '/rowers/test-job/2',
- '/rowers/test-job2/2',
- '/rowers/test_callback',
- '/rowers/updatefitness',
- '/rowers/updatefitness/rower',
- '/rowers/updatefitness/rower/50',
- '/rowers/user-boxplot',
- '/rowers/user-boxplot-data',
- '/rowers/user-boxplot-select/',
- '/rowers/user-boxplot-select/user/1/',
- '/rowers/user-boxplot/user/1',
- '/rowers/user-multiflex-data',
- '/rowers/user-multiflex-select/',
- '/rowers/user-multiflex-select/2016-01-01/2016-12-31',
- '/rowers/user-multiflex-select/user/1/',
- '/rowers/user-multiflex-select/user/1/2016-01-01/2016-12-31',
- '/rowers/user-multiflex/',
- '/rowers/user-multiflex/user/1',
- '/rowers/workout/1/',
- '/rowers/workout/1/adddistanceplot',
- '/rowers/workout/1/adddistanceplot2',
- '/rowers/workout/1/addotwpowerplot',
- '/rowers/workout/1/addpiechart',
- '/rowers/workout/1/addpowerpiechart',
- '/rowers/workout/1/addstatic',
- '/rowers/workout/1/addstatic/3',
- '/rowers/workout/1/addtimeplot',
- '/rowers/workout/1/addtimeplot2',
- '/rowers/workout/1/comment',
- '/rowers/workout/1/darkskywind',
- '/rowers/workout/1/data',
- '/rowers/workout/1/edit',
- '/rowers/workout/1/editintervals',
- '/rowers/workout/1/flexchart',
- '/rowers/workout/1/flexchart/spm/hr/None',
- '/rowers/workout/1/flexchart/spm/hr/None/scatter',
- '/rowers/workout/1/flexchart/spm/hr/None/scatter/',
- '/rowers/workout/1/forcecurve',
- '/rowers/workout/1/get-testscript',
- '/rowers/workout/1/get-thumbnails',
- '/rowers/workout/1/histo',
- '/rowers/workout/1/image',
- '/rowers/workout/1/instroke',
- '/rowers/workout/1/interactiveotwplot',
- '/rowers/workout/1/map',
- '/rowers/workout/1/otwsetpower',
- '/rowers/workout/1/recalcsummary/',
- '/rowers/workout/1/restore',
- '/rowers/workout/1/smoothenpace',
- '/rowers/workout/1/split',
- '/rowers/workout/1/stats',
- '/rowers/workout/1/stream',
- '/rowers/workout/1/task',
- '/rowers/workout/1/test_strokedata',
- '/rowers/workout/1/toggle-ranking',
- '/rowers/workout/1/undosmoothenpace',
- '/rowers/workout/1/unsubscribe',
- '/rowers/workout/1/updatecp',
- '/rowers/workout/1/view',
- '/rowers/workout/1/wind',
- '/rowers/workout/1/workflow',
- '/rowers/workout/compare/1/2016-01-01/2016-12-31',
- '/rowers/workout/fusion/1/',
- '/rowers/workout/fusion/1/2016-01-01/2016-12-31',
- '/rowers/workout/upload/',
- '/rowers/workout/upload/team/',
- '/rowers/workouts-join',
- '/rowers/workouts-join-select/',
- '/rowers/workouts-join-select/2016-01-01/2016-12-31',
- ]
-
- lijst = []
- for url in urlstotest:
- lijst.append(
- (url,200)
- )
-
- @parameterized.expand(lijst)
- def test_url_generator(self,url,expected):
- response = self.c.get(url,follow=True)
- if response.status_code != expected:
- print response.status_code
- self.assertEqual(response.status_code,
- expected,
- msg=url+' response status code not 200')
-
+#@pytest.mark.django_db
class subroutinetests(TestCase):
def setUp(self):
redis_connection.publish('tasks','KILL')
@@ -2338,6 +1206,7 @@ class subroutinetests(TestCase):
+#@pytest.mark.django_db
class PlotTests(TestCase):
def setUp(self):
redis_connection.publish('tasks','KILL')
@@ -2382,8 +1251,9 @@ class PlotTests(TestCase):
'powerzones':serialize_list(r.powerzones),
}
-
- def test_ote_plots(self):
+ @patch('rowers.tasks.rdata')
+ @patch('rowers.tasks.FigureCanvas')
+ def test_ote_plots(self, mocked_rowingdata, mocked_canvas):
w = self.wote
f1 = 'testdata.csv'[:-4]
timestr = strftime("%Y%m%d-%H%M%S")
@@ -2398,7 +1268,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 1
if (w.workouttype=='water'):
@@ -2408,7 +1281,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 2
if (w.workouttype=='water'):
@@ -2418,7 +1294,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 3
if (w.workouttype=='water'):
@@ -2428,7 +1307,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 4
if (w.workouttype=='water'):
@@ -2438,7 +1320,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 5
if (w.workouttype=='water'):
@@ -2448,7 +1333,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 6
if (w.workouttype=='water'):
@@ -2458,7 +1346,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 7
if (w.workouttype=='water'):
@@ -2468,7 +1359,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 8
if (w.workouttype=='water'):
@@ -2478,7 +1372,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 13
if (w.workouttype=='water'):
@@ -2488,9 +1385,14 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
- def test_otw_plots(self):
+ @patch('rowers.tasks.rdata')
+ @patch('rowers.tasks.FigureCanvas')
+ def test_otw_plots(self, mocked_rowingdata, mocked_canvas):
w = self.wotw
f1 = 'testdata.csv'[:-4]
timestr = strftime("%Y%m%d-%H%M%S")
@@ -2505,7 +1407,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 1
if (w.workouttype=='water'):
@@ -2515,7 +1420,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 2
if (w.workouttype=='water'):
@@ -2525,7 +1433,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 3
if (w.workouttype=='water'):
@@ -2535,7 +1446,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 4
if (w.workouttype=='water'):
@@ -2545,7 +1459,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 5
if (w.workouttype=='water'):
@@ -2555,7 +1472,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 6
if (w.workouttype=='water'):
@@ -2565,7 +1485,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 7
if (w.workouttype=='water'):
@@ -2575,7 +1498,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 8
if (w.workouttype=='water'):
@@ -2585,7 +1511,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 9
if (w.workouttype=='water'):
@@ -2595,7 +1524,10 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
plotnr = 13
if (w.workouttype=='water'):
@@ -2605,4 +1537,7 @@ class PlotTests(TestCase):
w.name,self.hrdata,plotnr,imagename)
i = GraphImage(workout=w,creationdatetime=self.nu,
filename=fullpathimagename)
- os.remove(fullpathimagename)
+ try:
+ os.remove(fullpathimagename)
+ except WindowsError:
+ pass
diff --git a/rowers/urls.py b/rowers/urls.py
index f37951da..f4d2aa88 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -108,9 +108,9 @@ 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),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
- url(r'^api/workouts/(?P\d+)/strokedata$',views.strokedatajson),
+ url(r'^api/workouts/(?P\d+)/strokedata/$',views.strokedatajson),
url(r'^500v/$',views.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'),
@@ -118,244 +118,244 @@ urlpatterns = [
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'^ajax_agegroup/(?P\d+)/(?P\w+.*)/(?P\w+.*)/(?P\d+)$',
+ 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'^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),
- url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)m$',
+ 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),
+ url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)m/$',
views.agegrouprecordview),
- url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)min$',
+ url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)/(?P\d+)min/$',
views.agegrouprecordview),
- url(r'^agegrouprecords/(?P\w+.*)/(?P\w+.*)$',
+ 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/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'^(?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),
+ 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),
url(r'^raceregistration/togglenotification/(?P\d+)/$',
views.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+)/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),
- url(r'^virtualevent/(?P\d+)/submit$',
+ url(r'^virtualevent/(?P\d+)/$',views.virtualevent_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),
+ url(r'^virtualevent/(?P\d+)/submit/$',
views.virtualevent_submit_result_view),
- url(r'^virtualevent/(?P\d+)/submit/(?P\d+)$',
+ url(r'^virtualevent/(?P\d+)/submit/(?P\d+)/$',
views.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'^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/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+)/$',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+)/$',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/(?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+)/(?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/(?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+)/(?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/(?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),
- 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.*)$',views.post_progress),
- url(r'^record-progress$',views.post_progress),
+ 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.*)/$',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'^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'^(?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+)/(?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/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