diff --git a/008fc633-d9d4-4abc-9812-e22014e19498.tcx b/008fc633-d9d4-4abc-9812-e22014e19498.tcx
deleted file mode 100644
index 31d671d7..00000000
--- a/008fc633-d9d4-4abc-9812-e22014e19498.tcx
+++ /dev/null
@@ -1,2523 +0,0 @@
-
-
-
-
- 2016-05-20T13:41:26.962390+00:00
-
- 537
- 2000
- 1
-
- 148
-
-
- 156
-
- Active
- 21
- Manual
-
-
- <Element 'Notes' at 0x7f5eb3c3ef98>
-
-
-
- rowsandall.com/rowingdata
-
-
- rowingdata
-
-
- 0
- 75
-
- Release
-
- EN
- 000-00000-00
-
-
diff --git a/03f8abfb-ccec-45bf-ac29-b193477d2045.tcx b/03f8abfb-ccec-45bf-ac29-b193477d2045.tcx
deleted file mode 100644
index eb0a1c3e..00000000
--- a/03f8abfb-ccec-45bf-ac29-b193477d2045.tcx
+++ /dev/null
@@ -1,2523 +0,0 @@
-
-
-
-
- 2016-05-20T13:41:26.962390+00:00
-
- 537
- 2000
- 1
-
- 148
-
-
- 156
-
- Active
- 21
- Manual
-
-
- <Element 'Notes' at 0x13b50a20>
-
-
-
- rowsandall.com/rowingdata
-
-
- rowingdata
-
-
- 0
- 75
-
- Release
-
- EN
- 000-00000-00
-
-
diff --git a/23099b58-7632-4d34-97e2-2f4890cf5773.tcx b/23099b58-7632-4d34-97e2-2f4890cf5773.tcx
deleted file mode 100644
index e7df305a..00000000
--- a/23099b58-7632-4d34-97e2-2f4890cf5773.tcx
+++ /dev/null
@@ -1,2523 +0,0 @@
-
-
-
-
- 2016-05-20T13:41:26.962390+00:00
-
- 537
- 2000
- 118
-
- 148
-
-
- 156
-
- Active
- 21
- Manual
-
-
- <Element 'Notes' at 0x7f433c451b38>
-
-
-
- rowsandall.com/rowingdata
-
-
- rowingdata
-
-
- 0
- 75
-
- Release
-
- EN
- 000-00000-00
-
-
diff --git a/b90680ee-35d5-4633-9974-fdc4bba4c68f.tcx b/b90680ee-35d5-4633-9974-fdc4bba4c68f.tcx
deleted file mode 100644
index 97ac8d4f..00000000
--- a/b90680ee-35d5-4633-9974-fdc4bba4c68f.tcx
+++ /dev/null
@@ -1,2523 +0,0 @@
-
-
-
-
- 2016-05-20T13:41:26.962390+00:00
-
- 537
- 2000
- 1
-
- 148
-
-
- 156
-
- Active
- 21
- Manual
-
-
- <Element 'Notes' at 0x000002C71C48FE58>
-
-
-
- rowsandall.com/rowingdata
-
-
- rowingdata
-
-
- 0
- 75
-
- Release
-
- EN
- 000-00000-00
-
-
diff --git a/c6c032ca-da24-42cf-b61f-02816b7e2ccd.tcx b/c6c032ca-da24-42cf-b61f-02816b7e2ccd.tcx
deleted file mode 100644
index 98408a5a..00000000
--- a/c6c032ca-da24-42cf-b61f-02816b7e2ccd.tcx
+++ /dev/null
@@ -1,2523 +0,0 @@
-
-
-
-
- 2016-05-20T13:41:26.962390+00:00
-
- 537
- 2000
- 1
-
- 148
-
-
- 156
-
- Active
- 21
- Manual
-
-
- <Element 'Notes' at 0x15038e80>
-
-
-
- rowsandall.com/rowingdata
-
-
- rowingdata
-
-
- 0
- 75
-
- Release
-
- EN
- 000-00000-00
-
-
diff --git a/requirements.txt b/requirements.txt
index 00ed095f..8ebc3c9b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,138 +1,217 @@
-amqp==2.5.2
-anytree==2.8.0
-apparmor==2.13.3
+amqp==2.4.2
+apipkg==1.5
appdirs==1.4.3
-asn1crypto==1.3.0
-attrs==19.3.0
+arcgis==1.6.0
+arrow==0.13.1
+asn1crypto==0.24.0
+atomicwrites==1.3.0
+attrs==19.1.0
backcall==0.1.0
-beautifulsoup4==4.8.2
-billiard==3.6.1.0
+beautifulsoup4==4.7.1
+billiard==3.6.0.0
bleach==3.1.0
+bokeh==1.0.4
boto==2.49.0
-btrfsutil==1.1.1
-CacheControl==0.12.6
-case==1.5.3
-catfish==1.4.13
+braintree==3.55.0
+cairocffi==1.0.2
celery==4.3.0
-ceph-volume==1.0.0
-cephfs==2.0.0
-cephfs-shell==0.0.1
-certifi==2019.11.28
-cffi==1.13.2
+certifi==2019.3.9
+cffi==1.12.2
chardet==3.0.4
-colorama==0.4.3
-contextlib2==0.6.0
-cryptography==2.8
+Click==7.0
+cloudpickle==1.2.2
+colorama==0.4.1
+colorclass==2.2.0
+cookies==2.2.1
+coreapi==2.3.3
+coreschema==0.0.4
+coverage==4.5.3
+cryptography==2.6.1
cycler==0.10.0
-decorator==4.4.1
-defusedxml==0.6.0
-distlib==0.3.0
-distro==1.4.0
+dask==2.6.0
+decorator==4.4.0
+defusedxml==0.5.0
+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.5.2
+django-countries==5.3.3
+django-datetime-widget==0.9.3
+django-debug-toolbar==2.0
+django-extensions==2.1.6
+django-htmlmin==0.11.0
+django-leaflet==0.24.0
+django-mailbox==4.8.0
+django-oauth-toolkit==1.2.0
+django-oauth2-provider==0.2.6.1
+django-redis==4.10.0
+django-rest-framework==0.1.0
+django-rest-swagger==2.2.0
+django-rq==1.3.1
+django-rq-dashboard==0.3.3
+django-ses==0.8.10
+django-shell-plus==1.1.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.9.2
docopt==0.6.2
+docutils==0.14
entrypoints==0.3
-gufw==19.10.0
+execnet==1.5.0
+factory-boy==2.11.1
+Faker==1.0.4
+fastparquet==0.3.2
+fitparse==1.1.0
+Flask==1.0.2
+fsspec==0.5.2
+future==0.17.1
+geocoder==1.38.1
+geos==0.2.1
+grpcio==1.26.0
+grpcio-tools==1.26.0
+holoviews==1.11.3
html5lib==1.0.1
htmlmin==0.1.12
-httplib2==0.14.0
+HTMLParser==0.0.2
+httplib2==0.12.1
+hvplot==0.4.0
+icalendar==4.0.3
idna==2.8
-importlib-metadata==1.4.0
-ipykernel==5.1.3
-ipython==7.11.1
-ipython-genutils==0.1.0
-ipywidgets==7.5.1
-Jade-Application-Kit==2.1.3
-jedi==0.15.1
-Jinja2==2.10.3
-jsonschema==3.2.0
-jupyter-client==5.3.4
+image==1.5.27
+importlib-resources==1.0.2
+ipykernel==5.1.0
+ipython==7.4.0
+ipython-genutils==0.2.0
+ipywidgets==7.4.2
+iso8601==0.1.12
+isodate==0.6.0
+itsdangerous==1.1.0
+itypes==1.1.0
+jedi==0.13.3
+jeepney==0.4
+Jinja2==2.10
+json5==0.8.5
+jsonschema==3.0.1
+jupyter==1.0.0
+jupyter-client==5.2.4
jupyter-console==6.0.0
-jupyter-core==4.6.1
-keyutils==0.6
-kiwisolver==1.1.0
-kombu==4.6.7
-lensfun==0.3.2
-LibAppArmor==2.13.3
-lightdm-gtk-greeter-settings==1.2.2
-lockfile==0.12.2
-louis==3.12.0
-lxml==4.4.2
+jupyter-core==4.4.0
+jupyterlab==0.35.4
+jupyterlab-server==0.3.0
+keyring==18.0.0
+kiwisolver==1.0.1
+kombu==4.5.0
+llvmlite==0.30.0
+lxml==4.3.2
+Markdown==3.0.1
MarkupSafe==1.1.1
-matplotlib==3.1.2
-menulibre==2.2.1
+matplotlib==3.0.3
+minify==0.1.4
+MiniMockTest==0.5
mistune==0.8.4
-more-itertools==8.1.0
-msgpack==0.6.2
-mugshot==0.4.2
-nbconvert==5.6.1
+mock==2.0.0
+more-itertools==6.0.0
+mpld3==0.3
+mysqlclient==1.4.2.post1
+nbconvert==5.4.1
nbformat==4.4.0
+newrelic==5.2.1.129
nose==1.3.7
-notebook==6.0.2
-npyscreen==4.10.5
-numpy==1.18.1
-openshot-qt==2.4.4
-ordered-set==3.1.1
-packaging==20.0
-pacman-mirrors==4.16.2
+nose-parameterized==0.6.0
+notebook==5.7.6
+numba==0.46.0
+numpy==1.16.2
+oauth2==1.9.0.post1
+oauthlib==3.0.1
+openapi-codec==1.3.2
+packaging==19.0
+pandas==0.24.2
pandocfilters==1.4.2
-parso==0.5.2
-pep517==0.6.0
-pexpect==4.7.0
+param==1.8.2
+parso==0.3.4
+pathspec==0.5.9
+pbr==5.1.3
+pexpect==4.6.0
pickleshare==0.7.5
-Pillow==6.2.1
-pkgconfig==1.5.1
-pkginfo==1.5.0.1
-ply==3.11
-progress==1.5
-prometheus-client==0.7.1
-prompt-toolkit==3.0.2
-psutil==5.6.7
+Pillow==5.4.1
+pip-upgrader==1.4.6
+pluggy==0.9.0
+prometheus-client==0.6.0
+prompt-toolkit==2.0.9
+protobuf==3.11.1
+psycopg2==2.8.1
ptyprocess==0.6.0
-pycairo==1.18.2
+py==1.8.0
+pyarrow==0.15.0
+pycairo==1.19.0
pycparser==2.19
-pycups==1.9.74
-pycurl==7.43.0.3
-Pygments==2.5.2
-PyGObject==3.34.0
-pymongo==3.10.1
-pyOpenSSL==19.1.0
-pyparsing==2.4.6
-PyQt5==5.14.1
-PyQt5-sip==12.7.0
-PyQtWebEngine==5.14.0
-Pyro4==4.77
-pyrsistent==0.15.7
-python-dateutil==2.8.1
-python-distutils-extra==2.39
-pytoml==0.1.21
-pytz==2019.3
-pyxdg==0.26
-PyYAML==5.3
-pyzmq==18.1.1
-rados==2.0.0
-rbd==2.0.0
-redis==3.3.11
-requests==2.22.0
-retrying==1.3.3
-rgw==2.0.0
-scipy==1.4.1
+Pygments==2.3.1
+pyparsing==2.3.1
+pyrsistent==0.14.11
+pyshp==2.1.0
+pytest==4.3.1
+pytest-django==3.4.8
+pytest-forked==1.0.2
+pytest-runner==4.4
+pytest-sugar==0.9.2
+pytest-xdist==1.27.0
+python-dateutil==2.8.0
+python-memcached==1.59
+python-twitter==3.5
+pytz==2018.9
+pyviz-comms==0.7.1
+pywin32-ctypes==0.2.0
+pywinpty==0.5.5
+PyYAML==5.1
+pyzmq==18.0.1
+qtconsole==4.4.3
+ratelim==0.1.6
+redis==3.2.1
+requests==2.21.0
+requests-oauthlib==1.2.0
+rowingdata==2.6.6
+rowingphysics==0.5.0
+rq==0.13.0
+rules==2.1
+scipy==1.2.1
+SecretStorage==3.1.1
Send2Trash==1.5.0
-serpent==1.27
-six==1.13.0
-soupsieve==1.9.5
-SQLAlchemy==1.3.12
-team==1.0
-terminado==0.8.3
-testpath==0.4.4
-tornado==6.0.3
-traitlets==4.3.3
-udiskie==2.0.2
-ufw==0.36
-urllib3==1.25.7
+shell==1.0.1
+shortuuid==0.5.0
+simplejson==3.16.0
+six==1.12.0
+soupsieve==1.8
+SQLAlchemy==1.3.1
+sqlparse==0.3.0
+stravalib==0.10.2
+termcolor==1.1.0
+terminado==0.8.1
+terminaltables==3.1.0
+testpath==0.4.2
+text-unidecode==1.2
+thrift==0.11.0
+timezonefinder==4.0.1
+tk==0.1.0
+toolz==0.10.0
+tornado==6.0.1
+tqdm==4.31.1
+traitlets==4.3.2
+units==0.7
+uritemplate==3.0.0
+urllib3==1.24.1
+VerbalExpressions==0.0.2
vine==1.3.0
-virtualenv==16.1.0
-wcwidth==0.1.8
+wcwidth==0.1.7
webencodings==0.5.1
-widgetsnbextension==3.5.1
-wrapt==1.11.2
+Werkzeug==0.15.1
+widgetsnbextension==3.4.2
xlrd==1.2.0
-zipp==0.6.0
+xmltodict==0.12.0
+yamjam==0.1.7
+yamllint==1.15.0
+yuicompressor==2.4.8
diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py
index d725b8b5..30e0d69b 100644
--- a/rowers/tests/mocks.py
+++ b/rowers/tests/mocks.py
@@ -610,6 +610,7 @@ def mocked_requests(*args, **kwargs):
def __init__(self, json_data, status_code):
self.json_data = json_data
self.status_code = status_code
+ self.ok = True
def json(self):
return self.json_data
diff --git a/rowers/tests/test_aworkouts.py b/rowers/tests/test_aworkouts.py
index d82bc9ac..55d48c5d 100644
--- a/rowers/tests/test_aworkouts.py
+++ b/rowers/tests/test_aworkouts.py
@@ -242,9 +242,9 @@ class WorkoutViewTest(TestCase):
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db')
- # @patch('rowers.weather.requests.get', side_effect=mocked_requests)
+ @patch('rowers.weather.requests.get', side_effect=mocked_requests)
def test_waterworkout_view(self,
- mocked_sqlalchemy, mocked_getsmallrowdata_db):
+ mocked_sqlalchemy, mocked_getsmallrowdata_db, mocked_requests):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
diff --git a/rowers/tests/test_permissions.py b/rowers/tests/test_permissions.py
index ffaf1658..543170d5 100644
--- a/rowers/tests/test_permissions.py
+++ b/rowers/tests/test_permissions.py
@@ -777,7 +777,7 @@ class PermissionsViewTests(TestCase):
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
- url = reverse('rower_favoritecharts_view',kwargs={'id':self.ubasic.id})
+ url = reverse('rower_favoritecharts_view',kwargs={'userid':self.ubasic.id})
response = self.c.get(url)
self.assertEqual(response.status_code,200)
@@ -788,7 +788,7 @@ class PermissionsViewTests(TestCase):
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
- url = reverse('rower_favoritecharts_view',kwargs={'id':self.ubasic.id})
+ url = reverse('rower_favoritecharts_view',kwargs={'userid':self.ubasic.id})
response = self.c.get(url)
self.assertEqual(response.status_code,403)
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index ab64ca8b..783648c6 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -2214,8 +2214,21 @@ def workout_smoothenpace_view(request,id=0,message="",successmessage=""):
if row == 0:
return HttpResponse("Error: CSV Data File Not Found")
- pace = row.df[' Stroke500mPace (sec/500m)'].values
- velo = 500./pace
+ try:
+ pace = row.df[' Stroke500mPace (sec/500m)'].values
+ velo = 500./pace
+ except KeyError:
+ messages.error(request,'Unable to find the data')
+ if previousurl:
+ url = previousurl
+ else:
+ url = reverse(r.defaultlandingpage,
+ kwargs = {
+ 'id':id,
+ }
+ )
+
+ return HttpResponseRedirect(url)
if not 'originalvelo' in row.df:
row.df['originalvelo'] = velo
diff --git a/rowers/weather.py b/rowers/weather.py
index 2af994f3..cb31817a 100644
--- a/rowers/weather.py
+++ b/rowers/weather.py
@@ -4,6 +4,7 @@ from __future__ import print_function
from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import
import requests
+from requests.exceptions import ConnectionError
import json
from lxml import objectify,etree
import xml.etree.ElementTree as ET
@@ -26,13 +27,16 @@ def get_airport_code(lat,lon):
newlon = a.iloc[0]['lon']
distance = geo_distance(lat,lon,newlat,newlon)
return airport_code,newlat,newlon,distance
-
+
# Get weather data from the DarkSky API
def get_weather_data(long,lat,unixtime):
url = "https://api.darksky.net/forecast/"+FORECAST_IO_KEY+"/"
url += str(long)+","+str(lat)+","+str(unixtime)
- s = requests.get(url)
+ try:
+ s = requests.get(url)
+ except ConnectionError:
+ return 0
if s.ok:
return s.json()
@@ -55,10 +59,14 @@ def get_metar_data(airportcode,unixtime):
except:
message = 'Failed to download METAR data'
return [0,0,message,'','']
-
+
if s.ok:
- doc = etree.fromstring(s.content)
+ try:
+ doc = etree.fromstring(s.content)
+ except AttributeError:
+ message = 'METAR data content error'
+ return [0,0,message,'',0]
lengte = len(doc.xpath('data/METAR/station_id'))
idnr = int(lengte/2)
try:
@@ -77,7 +85,7 @@ def get_metar_data(airportcode,unixtime):
wind_knots = float(wind_speed)
wind_ms = 0.514444*wind_knots
wind_ms = int(10*wind_ms)/10.
-
+
temperaturec = float(temp_c)
temp_f = 32.+(9./5.)*temperaturec
temp_f = str(int(10*temp_f)/10.)
@@ -87,17 +95,19 @@ def get_metar_data(airportcode,unixtime):
message += '. Wind: '+str(wind_ms)+' m/s ('+str(wind_knots)+' kt)'
message +='. Wind Bearing: '+str(windbearing)+' degrees'
# message +='\n'+rawtext
-
+
return [wind_ms,windbearing,message,rawtext,timestamp]
message = 'Failed to download METAR data'
return [0,0,message,'',timestamp]
-
+
# Get wind data (and translate from knots to m/s)
def get_wind_data(lat,long,unixtime):
data = get_weather_data(lat,long,unixtime)
+ summary = ''
+ temperature = 20
if data:
try:
# we are getting wind in mph
@@ -107,11 +117,13 @@ def get_wind_data(lat,long,unixtime):
windspeed = 0
windbearing = 0
+
try:
airports = data['flags']['madis-stations']
except KeyError:
airports = ['unknown']
+
try:
temperature = data['currently']['temperature']
# Temp is given in Fahrenheit, so convert to Celsius for Europeans
@@ -121,6 +133,7 @@ def get_wind_data(lat,long,unixtime):
temperature = 'unknown'
temperaturec = 'unknown'
+
try:
summary = data['currently']['summary']
except KeyError:
@@ -128,15 +141,19 @@ def get_wind_data(lat,long,unixtime):
else:
windspeed = 0
windbearing = 0
+ summary = 'unknown'
+ airports = ['unknown']
+ temparature = 'unknown'
+ temperaturec = 'unknown'
message = 'Not able to get weather data'
# apply Hellman's coefficient for neutral air above human
# inhabitated areas
windspeed = windspeed*(0.1)**0.34
windspeed = 0.01*int(100*windspeed)
-
+
timestamp = arrow.get(unixtime).isoformat()
-
+
message = 'Summary for your location at '+timestamp+': '+summary
message += '. Temperature '+str(temperature)+'F/'+str(temperaturec)+'C'