diff --git a/008fc633-d9d4-4abc-9812-e22014e19498.tcx b/008fc633-d9d4-4abc-9812-e22014e19498.tcx
new file mode 100644
index 00000000..31d671d7
--- /dev/null
+++ b/008fc633-d9d4-4abc-9812-e22014e19498.tcx
@@ -0,0 +1,2523 @@
+
+
+
+
+ 2016-05-20T13:41:26.962390+00:00
+
+ 537
+ 2000
+ 1
+
+ 148
+
+
+ 156
+
+ Active
+ 21
+ Manual
+
+
+ <Element 'Notes' at 0x7f5eb3c3ef98>
+
+
+
+ rowsandall.com/rowingdata
+
+
+ rowingdata
+
+
+ 0
+ 75
+
+ Release
+
+ EN
+ 000-00000-00
+
+
diff --git a/requirements.txt b/requirements.txt
index f7fe3525..5dfec22a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,7 @@ apipkg==1.5
appdirs==1.4.3
arcgis==1.6.0
arrow==0.13.1
+asn1crypto==0.24.0
atomicwrites==1.3.0
attrs==19.1.0
backcall==0.1.0
@@ -24,29 +25,30 @@ cookies==2.2.1
coreapi==2.3.3
coreschema==0.0.4
coverage==4.5.3
+cryptography==2.6.1
cycler==0.10.0
dask==1.1.4
decorator==4.4.0
defusedxml==0.5.0
-Django==1.9.5
+Django==2.1.7
django-analytical==2.5.0
django-async-messages==0.3.1
django-braces==1.13.0
django-classy-tags==0.8.0
django-cookie-law==2.0.1
-django-cors-headers==2.4.0
+django-cors-headers==2.5.2
django-countries==5.3.3
django-datetime-widget==0.9.3
-django-debug-toolbar==1.4
+django-debug-toolbar==1.11
django-extensions==2.1.6
-django-htmlmin==0.10.0
+django-htmlmin==0.11.0
django-leaflet==0.24.0
django-mailbox==4.7.1
-django-oauth-toolkit==0.10.0
+django-oauth-toolkit==1.2.0
django-oauth2-provider==0.2.6.1
django-rest-framework==0.1.0
django-rest-swagger==2.2.0
-django-rq==1.3.0
+django-rq==1.3.1
django-rq-dashboard==0.3.3
django-ses==0.8.10
django-shell-plus==1.1.7
@@ -54,7 +56,7 @@ django-social-share==1.3.2
django-suit==0.2.26
django-suit-rq==1.0.1
django-tz-detect==0.2.9
-djangorestframework==3.5.4
+djangorestframework==3.9.2
docopt==0.6.2
docutils==0.14
entrypoints==0.3
@@ -63,7 +65,6 @@ factory-boy==2.11.1
Faker==1.0.4
fitparse==1.1.0
future==0.17.1
-GDAL==2.3.3
geocoder==1.38.1
holoviews==1.11.3
html5lib==1.0.1
@@ -75,13 +76,14 @@ idna==2.8
image==1.5.27
importlib-resources==1.0.2
ipykernel==5.1.0
-ipython==7.3.0
+ipython==7.4.0
ipython-genutils==0.2.0
ipywidgets==7.4.2
iso8601==0.1.12
isodate==0.6.0
itypes==1.1.0
jedi==0.13.3
+jeepney==0.4
Jinja2==2.10
jsonschema==3.0.1
jupyter==1.0.0
@@ -89,7 +91,7 @@ jupyter-client==5.2.4
jupyter-console==6.0.0
jupyter-core==4.4.0
jupyterlab==0.35.4
-jupyterlab-server==0.2.0
+jupyterlab-server==0.3.0
keyring==18.0.0
kiwisolver==1.0.1
kombu==4.3.0
@@ -109,7 +111,7 @@ nose-parameterized==0.6.0
notebook==5.7.6
numpy==1.16.2
oauth2==1.9.0.post1
-oauthlib==1.0.3
+oauthlib==3.0.1
openapi-codec==1.3.2
packaging==19.0
pandas==0.24.2
@@ -152,10 +154,11 @@ ratelim==0.1.6
redis==3.2.1
requests==2.21.0
requests-oauthlib==1.2.0
-rowingdata==2.2.3
+rowingdata==2.2.5
rowingphysics==0.5.0
rq==0.13.0
scipy==1.2.1
+SecretStorage==3.1.1
Send2Trash==1.5.0
shell==1.0.1
shortuuid==0.5.0
@@ -182,7 +185,6 @@ vine==1.3.0
wcwidth==0.1.7
webencodings==0.5.1
widgetsnbextension==3.4.2
-winkerberos==0.7.0
xmltodict==0.12.0
yamjam==0.1.7
yamllint==1.15.0
diff --git a/rowers/dataprep.py b/rowers/dataprep.py
index 757254f5..871087d9 100644
--- a/rowers/dataprep.py
+++ b/rowers/dataprep.py
@@ -54,7 +54,7 @@ from rowers.models import strokedatafields
#allowedcolumns = [item[0] for item in rowingmetrics]
allowedcolumns = [key for key,value in strokedatafields.items()]
-from async_messages import messages as a_messages
+#from async_messages import messages as a_messages
import os
import zipfile
import pandas as pd
@@ -920,12 +920,6 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
for key, value in checks.items():
if not value:
allchecks = 0
- if consistencychecks:
- a_messages.error(
- r.user, 'Failed consistency check: ' + key + ', autocorrected')
- else:
- pass
- # a_messages.error(r.user,'Failed consistency check: '+key+', not corrected')
except ZeroDivisionError:
pass
@@ -1148,9 +1142,6 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
# submit email task to send email about breakthrough workout
if isbreakthrough:
- a_messages.info(
- r.user, 'It looks like you have a new breakthrough workout'
- )
if r.getemailnotifications and not r.emailbounced:
job = myqueue(queuehigh,handle_sendemail_breakthrough,
w.id,
@@ -1161,7 +1152,6 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
# submit email task to send email about breakthrough workout
if ishard:
- a_messages.info(r.user, 'That was a pretty hard workout')
if r.getemailnotifications and not r.emailbounced:
job = myqueue(queuehigh,handle_sendemail_hard,
w.id,
@@ -1733,7 +1723,7 @@ def getsmallrowdata_db(columns, ids=[], doclean=True, workstrokesonly=True):
row = rdata(w.csvfilename)
try:
row.set_instroke_metrics()
- except AttributeError:
+ except (AttributeError,TypeError):
pass
try:
diff --git a/rowers/decorators.py b/rowers/decorators.py
index 36a4a3b5..f9d03ed7 100644
--- a/rowers/decorators.py
+++ b/rowers/decorators.py
@@ -42,7 +42,7 @@ def login_required_message(function=None, message=default_message):
to the log-in page if necessary.
"""
actual_decorator = user_passes_test(
- lambda u: u.is_authenticated(),
+ lambda u: u.is_authenticated,
message=message,
)
if function:
diff --git a/rowers/mailprocessing.py b/rowers/mailprocessing.py
index a7cc453a..9d3d824d 100644
--- a/rowers/mailprocessing.py
+++ b/rowers/mailprocessing.py
@@ -90,6 +90,7 @@ def make_new_workout_from_email(rower, datafile, name, cntr=0,testing=False):
try:
datafilename = datafile.name
fileformat = get_file_type('media/' + datafilename)
+ raise ValueError
except IOError:
datafilename = datafile.name + '.gz'
fileformat = get_file_type('media/' + datafilename)
@@ -108,11 +109,8 @@ def make_new_workout_from_email(rower, datafile, name, cntr=0,testing=False):
print('Fileformat = ',fileformat)
- if fileformat == 'unknown':
-# extension = datafilename[-4:].lower()
-# fcopy = "media/"+datafilename[:-4]+"_copy"+extension
-# with open('media/'+datafilename, 'r') as f_in, open(fcopy, 'w') as f_out:
-# shutil.copyfileobj(f_in,f_out)
+ f,e = os.path.splitext(datafilename)
+ if fileformat == 'unknown' and 'txt' not in e:
fcopy = "media/"+datafilename
if not testing:
if settings.CELERY:
diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py
index 25382b96..ceed4054 100644
--- a/rowers/management/commands/processemail.py
+++ b/rowers/management/commands/processemail.py
@@ -14,7 +14,7 @@ import io
from django.core.management.base import BaseCommand
from django_mailbox.models import Message, MessageAttachment,Mailbox
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.conf import settings
from django.utils import timezone
@@ -213,7 +213,9 @@ class Command(BaseCommand):
testing = False
cntr = 0
for attachment in attachments:
- extension = attachment.document.name[-3:].lower()
+ filename, extension = os.path.splitext(attachment.document.name)
+ extension = extension.lower()
+# extension = attachment.document.name[-3:].lower()
try:
message = Message.objects.get(id=attachment.message_id)
if message.encoded:
diff --git a/rowers/middleware.py b/rowers/middleware.py
index a4e9249a..9b49e13a 100644
--- a/rowers/middleware.py
+++ b/rowers/middleware.py
@@ -9,6 +9,7 @@ queuelow = django_rq.get_queue('low')
from rowers.tasks import handle_updatefitnessmetric,handle_sendemail_expired
from rowers.mytypes import otwtypes
from django.contrib import messages
+from django.http import HttpResponse
def getrower(user):
try:
@@ -70,11 +71,18 @@ def do_update(user,mode='rower',days=42):
class PowerTimeFitnessMetricMiddleWare(object):
- def process_request(self, request):
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
# Code to be executed before the view is called
- if request.user.is_authenticated():
+ if request.user.is_authenticated:
result = do_update(request.user,mode='rower')
result = do_update(request.user,mode='water')
+
+ response = self.get_response(request)
+
+ return response
from django.shortcuts import redirect
@@ -93,8 +101,11 @@ allowed_paths = [
]
class GDPRMiddleWare(object):
- def process_request(self, request):
- if request.user.is_authenticated() and request.path not in allowed_paths:
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
+ if request.user.is_authenticated and request.path not in allowed_paths:
r = getrower(request.user)
nexturl = request.path
if 'optin' in nexturl:
@@ -104,9 +115,16 @@ class GDPRMiddleWare(object):
'/rowers/me/gdpr-optin/?next=%s' % nexturl
)
+ response = self.get_response(request)
+
+ return response
+
class RowerPlanMiddleWare(object):
- def process_request(self, request):
- if request.user.is_authenticated() and request.user.rower.rowerplan != 'basic':
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
+ if request.user.is_authenticated and request.user.rower.rowerplan != 'basic':
if request.user.rower.paymenttype == 'single':
if request.user.rower.planexpires < timezone.now().date():
messg = 'Your paid plan has expired. We have reset you to a free basic plan.'
@@ -122,3 +140,6 @@ class RowerPlanMiddleWare(object):
r.user.last_name,
str(r.planexpires))
+ response = self.get_response(request)
+
+ return response
diff --git a/rowers/models.py b/rowers/models.py
index f3f1eed9..f124ac36 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -1014,7 +1014,7 @@ class BasePlannedSessionFormSet(BaseFormSet):
# Check if workout is owned by this user
def checkworkoutuser(user,workout):
- if user.is_anonymous():
+ if user.is_anonymous:
return False
try:
r = Rower.objects.get(user=user)
@@ -1034,7 +1034,7 @@ def checkworkoutuser(user,workout):
# Check if workout may be viewed by this user
def checkworkoutuserview(user,workout):
- if user.is_anonymous():
+ if user.is_anonymous:
return False
try:
r = Rower.objects.get(user=user)
diff --git a/rowers/tasks.py b/rowers/tasks.py
index 04c65fec..5e8059f9 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -298,7 +298,7 @@ def handle_check_race_course(self,
rowdata = rowdata[rowdata['time']>splitsecond]
# we may want to expand the time (interpolate)
rowdata['dt'] = rowdata['time'].apply(
- lambda x: safetimedelta(seconds=x)
+ lambda x: safetimedelta(x)
)
rowdata = rowdata.resample('100ms',on='dt').mean()
rowdata = rowdata.interpolate()
@@ -624,7 +624,7 @@ def handle_calctrimp(id,
df2['time'] = df2[' ElapsedTime (sec)']
df2['time'] = df2['time'].apply(
- lambda x:safetimedelta(seconds=x)
+ lambda x:safetimedelta(x)
)
duration = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min()
diff --git a/rowers/tasks_standalone.py b/rowers/tasks_standalone.py
index f20586c3..d2b2375c 100644
--- a/rowers/tasks_standalone.py
+++ b/rowers/tasks_standalone.py
@@ -14,7 +14,6 @@ django.setup()
import time
from celery import app
from django_rq import job
-from async_messages import message_user,messages
from rowers.models import Workout
from django.contrib.auth.models import User
diff --git a/rowers/templates/registration/login.html b/rowers/templates/registration/login.html
index aa650e83..21089cb6 100644
--- a/rowers/templates/registration/login.html
+++ b/rowers/templates/registration/login.html
@@ -8,7 +8,7 @@