Private
Public Access
1
0

Merge branch 'release/v22.1.3'

This commit is contained in:
2024-06-13 08:47:02 +02:00
11 changed files with 94 additions and 23 deletions
+7 -4
View File
@@ -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
+8 -6
View File
@@ -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(
+3
View File
@@ -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
View File
@@ -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()
+2 -2
View File
@@ -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
+14
View File
@@ -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]
+1 -1
View File
@@ -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()
+39 -1
View File
@@ -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):
Binary file not shown.
+5 -3
View File
@@ -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']
+6 -4
View File
@@ -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