Merge branch 'release/v22.1.3'
This commit is contained in:
+7
-4
@@ -80,11 +80,14 @@ def getnearestcourses(lat_lon, courses, whatisnear=150, strict=False):
|
|||||||
newlist = []
|
newlist = []
|
||||||
counter = 0
|
counter = 0
|
||||||
for c in courses:
|
for c in courses:
|
||||||
distance = howfaris(lat_lon, c)
|
try:
|
||||||
|
distance = howfaris(lat_lon, c)
|
||||||
|
|
||||||
if distance < whatisnear:
|
if distance < whatisnear:
|
||||||
newlist.append(c)
|
newlist.append(c)
|
||||||
counter += 1
|
counter += 1
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
if counter > 0:
|
if counter > 0:
|
||||||
courses = newlist
|
courses = newlist
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import rowers.c2stuff as c2stuff
|
|||||||
import rowers.metrics as metrics
|
import rowers.metrics as metrics
|
||||||
import rowers.dataprep as dataprep
|
import rowers.dataprep as dataprep
|
||||||
from rowers.dataprep import rdata
|
from rowers.dataprep import rdata
|
||||||
|
from rowers.dataroutines import remove_nulls_pl
|
||||||
import rowers.utils as utils
|
import rowers.utils as utils
|
||||||
import polars as pl
|
import polars as pl
|
||||||
import pytz
|
import pytz
|
||||||
@@ -1205,6 +1206,7 @@ def forcecurve_multi_interactive_chart(selected): # pragma: no cover
|
|||||||
rowdata = dataprep.read_data(columns, ids=workoutids,
|
rowdata = dataprep.read_data(columns, ids=workoutids,
|
||||||
workstrokesonly=False)
|
workstrokesonly=False)
|
||||||
|
|
||||||
|
rowdata = remove_nulls_pl(rowdata)
|
||||||
rowdata = rowdata.fill_nan(None).drop_nulls()
|
rowdata = rowdata.fill_nan(None).drop_nulls()
|
||||||
|
|
||||||
if rowdata.is_empty():
|
if rowdata.is_empty():
|
||||||
@@ -1225,7 +1227,7 @@ def forcecurve_multi_interactive_chart(selected): # pragma: no cover
|
|||||||
'forcecurve_analyses': selected_dict,
|
'forcecurve_analyses': selected_dict,
|
||||||
}
|
}
|
||||||
|
|
||||||
script, div = get_chart("/forcecurve_compare", chart_data)
|
script, div = get_chart("/forcecurve_compare", chart_data, debug=False)
|
||||||
return script, div
|
return script, div
|
||||||
|
|
||||||
|
|
||||||
@@ -2224,11 +2226,11 @@ def get_zones_report_pl(rower, startdate, enddate, trainingzones='hr', date_agg=
|
|||||||
pw_tr = rower.pw_tr
|
pw_tr = rower.pw_tr
|
||||||
pw_an = rower.pw_an
|
pw_an = rower.pw_an
|
||||||
if iswater:
|
if iswater:
|
||||||
pw_ut2 = pw_ut2*rower.otwslack/100.
|
pw_ut2 = pw_ut2*(100.-rower.otwslack)/100.
|
||||||
pw_ut1 = pw_ut1*rower.otwslack/100.
|
pw_ut1 = pw_ut1*(100.-rower.otwslack)/100.
|
||||||
pw_at = pw_at*rower.otwslack/100.
|
pw_at = pw_at*(100.-rower.otwslack)/100.
|
||||||
pw_tr = pw_tr*rower.otwslack/100.
|
pw_tr = pw_tr*(100.-rower.otwslack)/100.
|
||||||
pw_an = pw_an*rower.otwslack/100.
|
pw_an = pw_an*(100.-rower.otwslack)/100.
|
||||||
|
|
||||||
# 1
|
# 1
|
||||||
time_ut2 = df.filter(
|
time_ut2 = df.filter(
|
||||||
|
|||||||
@@ -175,6 +175,9 @@ def get_nk_intervalstats(workoutdata, strokedata):
|
|||||||
spm = interval['avgStrokeRate']
|
spm = interval['avgStrokeRate']
|
||||||
dps = interval['distStrokeGps']
|
dps = interval['distStrokeGps']
|
||||||
|
|
||||||
|
if pwr is None:
|
||||||
|
pwr = 0
|
||||||
|
|
||||||
stri += "{i:0>2}{sep}{sdist:0>5}{sep}{split}{sep}{space}{sep} {pwr:0>3} {sep}".format(
|
stri += "{i:0>2}{sep}{sdist:0>5}{sep}{split}{sep}{space}{sep} {pwr:0>3} {sep}".format(
|
||||||
i=i + 1,
|
i=i + 1,
|
||||||
sdist=int(float(sdist)),
|
sdist=int(float(sdist)),
|
||||||
|
|||||||
+9
-2
@@ -2163,7 +2163,10 @@ def handle_sendemail_hard(workoutid, useremail,
|
|||||||
debug=False, **kwargs):
|
debug=False, **kwargs):
|
||||||
|
|
||||||
btvalues = pd.read_json(btvalues)
|
btvalues = pd.read_json(btvalues)
|
||||||
btvalues.sort_values('delta', axis=0, inplace=True)
|
try:
|
||||||
|
btvalues.sort_values('delta', axis=0, inplace=True)
|
||||||
|
except KeyError:
|
||||||
|
return 0
|
||||||
|
|
||||||
tablevalues = [
|
tablevalues = [
|
||||||
{'delta': t.delta,
|
{'delta': t.delta,
|
||||||
@@ -3993,7 +3996,11 @@ def fetch_strava_workout(stravatoken, oauth_data, stravaid, csvfilename, userid,
|
|||||||
df.sort('TimeStamp (sec)')
|
df.sort('TimeStamp (sec)')
|
||||||
|
|
||||||
row = rowingdata.rowingdata_pl(df=df)
|
row = rowingdata.rowingdata_pl(df=df)
|
||||||
row.write_csv(csvfilename, compressed=False)
|
try:
|
||||||
|
row.write_csv(csvfilename, compressed=False)
|
||||||
|
except ComputeError:
|
||||||
|
row = rowingdata.rowingdata(df=df)
|
||||||
|
row.write_csv(csvfilename, compressed=False)
|
||||||
|
|
||||||
# summary = row.allstats()
|
# summary = row.allstats()
|
||||||
# maxdist = df['cum_dist'].max()
|
# maxdist = df['cum_dist'].max()
|
||||||
|
|||||||
@@ -389,14 +389,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<div id="id_script">
|
|
||||||
</div>
|
|
||||||
<ul class="main-content">
|
<ul class="main-content">
|
||||||
<canvas hidden id="canvas"></canvas>
|
<canvas hidden id="canvas"></canvas>
|
||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<div id="id_chart">
|
<div id="id_chart">
|
||||||
{{ the_div|safe }}
|
{{ the_div|safe }}
|
||||||
</div>
|
</div>
|
||||||
|
<div id="id_script">
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<p>You can use the date and search forms to search through all
|
<p>You can use the date and search forms to search through all
|
||||||
|
|||||||
@@ -109,6 +109,20 @@ from rowers.opaque import encoder
|
|||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MyTestCase(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.osm_mock = patch('something')
|
||||||
|
self.osm_mock.return_value = ""
|
||||||
|
super(MyTestCase, self).setUp()
|
||||||
|
self.osm_mock.start()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(MyTestCase, self).tearDown()
|
||||||
|
self.osm_mock.stop()
|
||||||
|
|
||||||
|
|
||||||
def get_random_file(filename='rowers/tests/testdata/testdata.csv',name=''):
|
def get_random_file(filename='rowers/tests/testdata/testdata.csv',name=''):
|
||||||
|
|
||||||
frm = inspect.stack()[3]
|
frm = inspect.stack()[3]
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import rowers.courses as courses
|
|||||||
import rowers.plannedsessions as plannedsessions
|
import rowers.plannedsessions as plannedsessions
|
||||||
|
|
||||||
@override_settings(TESTING=True)
|
@override_settings(TESTING=True)
|
||||||
class VirtualEventViewTest(TestCase):
|
class VirtualEventViewTest(MyTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Main User
|
# Main User
|
||||||
self.u = UserFactory()
|
self.u = UserFactory()
|
||||||
|
|||||||
@@ -49,13 +49,31 @@ class RojaboObjects(DjangoTestCase):
|
|||||||
self.r.defaulttimezone = 'Europe/Prague'
|
self.r.defaulttimezone = 'Europe/Prague'
|
||||||
self.r.rowerplan = 'plan'
|
self.r.rowerplan = 'plan'
|
||||||
self.r.save()
|
self.r.save()
|
||||||
self.c.login(username='john',password='koeinsloot')
|
|
||||||
|
self.u2 = User.objects.create_user('john2',
|
||||||
|
'sander@ds2.ds',
|
||||||
|
'stierinsloot')
|
||||||
|
|
||||||
|
self.u2.first_name = 'Sander'
|
||||||
|
self.u2.last_name = 'John'
|
||||||
|
self.u2.save()
|
||||||
|
self.r2 = Rower.objects.create(user=self.u2,gdproptin=True, ftpset=True,surveydone=True,
|
||||||
|
gdproptindate=timezone.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
self.r2.rojabo_token = '12'
|
||||||
|
self.r2.rojabo_refreshtoken = 'ab'
|
||||||
|
self.r2.rojabo_tokenexpirydate = arrow.get(datetime.datetime.now()+datetime.timedelta(days=1)).datetime
|
||||||
|
self.r2.defaulttimezone = 'Europe/Prague'
|
||||||
|
self.r2.rowerplan = 'pro'
|
||||||
|
self.r2.save()
|
||||||
|
|
||||||
self.nu = datetime.datetime.now()
|
self.nu = datetime.datetime.now()
|
||||||
|
|
||||||
@patch('rowers.rojabo_stuff.requests.get', side_effect=mocked_requests)
|
@patch('rowers.rojabo_stuff.requests.get', side_effect=mocked_requests)
|
||||||
@patch('rowers.rojabo_stuff.requests.post', side_effect=mocked_requests)
|
@patch('rowers.rojabo_stuff.requests.post', side_effect=mocked_requests)
|
||||||
def test_rojabo_import(self, mock_get, mock_post):
|
def test_rojabo_import(self, mock_get, mock_post):
|
||||||
|
self.c.login(username='john',password='koeinsloot')
|
||||||
url = '/rowers/session/rojaboimport/'
|
url = '/rowers/session/rojaboimport/'
|
||||||
response = self.c.get(url)
|
response = self.c.get(url)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
@@ -79,6 +97,26 @@ class RojaboObjects(DjangoTestCase):
|
|||||||
self.assertEqual(len(ps.steps['steps']),20)
|
self.assertEqual(len(ps.steps['steps']),20)
|
||||||
|
|
||||||
|
|
||||||
|
@patch('rowers.rojabo_stuff.requests.get', side_effect=mocked_requests)
|
||||||
|
@patch('rowers.rojabo_stuff.requests.post', side_effect=mocked_requests)
|
||||||
|
def test_rojabo_import_denied(self, mock_get, mock_post):
|
||||||
|
self.c.login(username='john2',password='stierinsloot')
|
||||||
|
url = '/rowers/session/rojaboimport/'
|
||||||
|
response = self.c.get(url)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
form_data = {
|
||||||
|
'csrfmiddlewaretoken': ['xalRrf8y7P2Hhobges9QC4aKCWg4l06gexDc8g2DeuVExgadfk4YhV8oSE1Yu43U'],
|
||||||
|
'sessions': ['Import selected sessions'],
|
||||||
|
'sessionid': ['862172']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
response = self.c.post(url,form_data)
|
||||||
|
self.assertEqual(response.status_code,302)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@override_settings(TESTING=True)
|
@override_settings(TESTING=True)
|
||||||
class GarminObjects(DjangoTestCase):
|
class GarminObjects(DjangoTestCase):
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -5,6 +5,7 @@ from jinja2 import Environment, FileSystemLoader
|
|||||||
from rowers.rower_rules import can_view_session
|
from rowers.rower_rules import can_view_session
|
||||||
|
|
||||||
from django.forms.widgets import SelectDateWidget, HiddenInput
|
from django.forms.widgets import SelectDateWidget, HiddenInput
|
||||||
|
from polars.exceptions import ComputeError
|
||||||
|
|
||||||
def floatformat(x, prec=2): # pragma: no cover
|
def floatformat(x, prec=2): # pragma: no cover
|
||||||
return '{x}'.format(x=round(x, prec))
|
return '{x}'.format(x=round(x, prec))
|
||||||
@@ -945,8 +946,10 @@ def boxplotdata(workouts, options):
|
|||||||
except ColumnNotFoundError:
|
except ColumnNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
datadf = datadf.with_columns((pl.col("workoutid").apply(lambda x: datemapping[x])).alias("date"))
|
datadf = datadf.with_columns((pl.col("workoutid").apply(lambda x: datemapping[x])).alias("date"))
|
||||||
|
except ComputeError:
|
||||||
|
return ("","No Valid Data")
|
||||||
|
|
||||||
if userid == 0: # pragma: no cover
|
if userid == 0: # pragma: no cover
|
||||||
extratitle = ''
|
extratitle = ''
|
||||||
@@ -1591,7 +1594,6 @@ class SavedAnalysisView(UserPassesTestMixin, View):
|
|||||||
|
|
||||||
def post(self, request, *args, **kwargs): # pragma: no cover
|
def post(self, request, *args, **kwargs): # pragma: no cover
|
||||||
form = self.form_class(request.POST)
|
form = self.form_class(request.POST)
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
cd = form.cleaned_data
|
cd = form.cleaned_data
|
||||||
self.selected = cd['analyses']
|
self.selected = cd['analyses']
|
||||||
|
|||||||
@@ -649,10 +649,10 @@ def rower_process_testcallback(request): # pragma: no cover
|
|||||||
|
|
||||||
# The page where you select which Strava workout to import
|
# The page where you select which Strava workout to import
|
||||||
@login_required()
|
@login_required()
|
||||||
@user_passes_test(ispromember, login_url="/rowers/paidplans/",
|
@user_passes_test(isplanmember, login_url="/rowers/paidplans/",
|
||||||
message="This functionality requires a Pro plan or higher",
|
message="This functionality requires a Self-coach plan or higher",
|
||||||
redirect_field_name=None)
|
redirect_field_name=None)
|
||||||
@permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True)
|
@permission_required('plannedsession.add_session', fn=get_user_by_userid, raise_exception=True)
|
||||||
def workout_rojaboimport_view(request, message="", userid=0): # pragma: no cover
|
def workout_rojaboimport_view(request, message="", userid=0): # pragma: no cover
|
||||||
r = getrequestrower(request, userid=userid)
|
r = getrequestrower(request, userid=userid)
|
||||||
if r.user != request.user:
|
if r.user != request.user:
|
||||||
@@ -753,10 +753,12 @@ def workout_rojaboimport_view(request, message="", userid=0): # pragma: no cover
|
|||||||
'steps': steps,
|
'steps': steps,
|
||||||
}
|
}
|
||||||
ps.save()
|
ps.save()
|
||||||
|
|
||||||
messages.info(request,'Saved planned session {id}'.format(id=ps.id))
|
messages.info(request,'Saved planned session {id}'.format(id=ps.id))
|
||||||
|
|
||||||
except KeyError: # pragma: no cover
|
except KeyError: # pragma: no cover
|
||||||
pass
|
pass
|
||||||
|
except ValidationError:
|
||||||
|
messages.error(request,"You cannot import sessions")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user