From 2b90c9bfea5267704348bc0610904641684e2cf3 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 13 Apr 2024 10:41:22 +0200 Subject: [PATCH] verbeteringen --- rowers/interactiveplots.py | 104 +------ rowers/tests/test_urls.py | 1 - rowers/tests/testdata/testdata.tcx.gz | Bin 4001 -> 4000 bytes rowers/urls.py | 10 - rowers/views/workoutviews.py | 393 -------------------------- 5 files changed, 2 insertions(+), 506 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 856154b3..8777367b 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -477,12 +477,11 @@ def interactive_forcecurve(theworkouts): rowdata = dataprep.getsmallrowdata_pl(columns, ids=ids, workstrokesonly=False) - rowdata = rowdata.fill_nan(None).drop_nulls() - - if rowdata.is_empty(): return "", "No Valid Data Available" + rowdata = rowdata.fill_nan(None).drop_nulls() + data_dict = rowdata.to_dicts() thresholdforce = 100. if 'x' in boattype else 200. @@ -3131,105 +3130,6 @@ def interactive_multiple_compare_chart(ids, xparam, yparam, plottype='line', return [script, div, message, errormessage] -def interactive_otw_advanced_pace_chart(id=0, promember=0): - # check if valid ID exists (workout exists) - rowdata, row = dataprep.getrowdata_db(id=id) - rowdata.dropna(axis=1, how='all', inplace=True) - rowdata.dropna(axis=0, how='any', inplace=True) - - if rowdata.empty: - return "", "No Valid Data Available" - - # Add hover to this comma-separated string and see what changes - if (promember == 1): - TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' - else: # pragma: no cover - TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' - - source = ColumnDataSource( - rowdata - ) - - plot = figure(x_axis_type="datetime", y_axis_type="datetime", - tools=TOOLS, - width=920, - toolbar_sticky=False) - - # add watermark - watermarkurl = "/static/img/logo7.png" - watermarkrange = Range1d(start=0, end=1) - watermarkalpha = 0.6 - watermarkx = 0.99 - watermarky = 0.01 - watermarkw = 184 - watermarkh = 35 - watermarkanchor = 'bottom_right' - plot.extra_y_ranges = {"watermark": watermarkrange} - plot.extra_x_ranges = {"watermark": watermarkrange} - #plot.sizing_mode = 'scale_both' - - plot.image_url([watermarkurl], watermarkx, watermarky, - watermarkw, watermarkh, - global_alpha=watermarkalpha, - w_units='screen', - h_units='screen', - anchor=watermarkanchor, - dilate=True, - x_range_name="watermark", - y_range_name="watermark", - ) - - try: - plot.title.text = row.name - except ValueError: # pragma: no cover - plot.title.text = "" - #plot.title.text_font_size = value("1.2em") - plot.xaxis.axis_label = "Time" - plot.yaxis.axis_label = "Pace (/500m)" - plot.xaxis[0].formatter = DatetimeTickFormatter( - hours=["%H"], - minutes=["%M"], - seconds=["%S"], - days=["0"], - months=[""], - years=[""] - ) - plot.yaxis[0].formatter = DatetimeTickFormatter( - seconds=["%S"], - minutes=["%M"] - ) - - ymax = 1.0e3*90 - ymin = 1.0e3*210 - - plot.y_range = Range1d(ymin, ymax) - - hover = plot.select(dict(type=HoverTool)) - - plot.line('time', 'pace', source=source, - legend_label="Pace", color="black") - plot.line('time', 'nowindpace', source=source, - legend_label="Corrected Pace", color="red") - - hover.tooltips = OrderedDict([ - ('Time', '@ftime'), - ('Pace', '@fpace'), - ('Corrected Pace', '@fnowindpace'), - ('HR', '@hr{int}'), - ('SPM', '@spm{1.1}'), - ]) - - hover.mode = 'mouse' - - try: - script, div = components(plot) - except: # pragma: no cover - script = '' - div = '' - - return [script, div] - - def get_zones_report(rower, startdate, enddate, trainingzones='hr', date_agg='week', yaxis='time'): diff --git a/rowers/tests/test_urls.py b/rowers/tests/test_urls.py index af6e07e1..4e1f0f4f 100644 --- a/rowers/tests/test_urls.py +++ b/rowers/tests/test_urls.py @@ -146,7 +146,6 @@ class URLTests(TestCase): '/rowers/workout/'+encoded1+'/addtimeplot/', '/rowers/workout/'+encoded1+'/addtimeplot2/', '/rowers/workout/'+encoded1+'/comment/', - '/rowers/workout/'+encoded1+'/darkskywind/', '/rowers/workout/'+encoded1+'/data/', '/rowers/workout/'+encoded1+'/edit/', '/rowers/workout/'+encoded1+'/editintervals/', diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 2f3d726fb35072c64ab94b513e74853cf9d6ccfb..e3b8adc00f8289642ff85c1a3d6305d33a81fa55 100644 GIT binary patch delta 3773 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 delta 3733 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 diff --git a/rowers/urls.py b/rowers/urls.py index ca762683..0135688a 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -510,14 +510,6 @@ urlpatterns = [ name='workout_erase_column_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/zeropower-confirm/$', views.remove_power_confirm_view, name='remove_power_confirm_view'), - re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/zeropower/$', views.remove_power_view, - name='remove_power_view'), - re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/otwsetpower/$', - views.workout_otwsetpower_view, name='workout_otwsetpower_view'), - re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/interactiveotwplot/$', - views.workout_otwpowerplot_view, name='workout_otwpowerplot_view'), - re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/wind/$', - views.workout_wind_view, name='workout_wind_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/image/$', views.workout_uploadimage_view, name='workout_uploadimage_view'), re_path(r'^virtualevent/(?P\d+)/compare/$', @@ -540,8 +532,6 @@ urlpatterns = [ views.workout_downloadwind_view, name='workout_downloadwind_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/metar/(?P\w+)/$', views.workout_downloadmetar_view, name='workout_downloadmetar_view'), - re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/stream/$', - views.workout_stream_view, name='workout_stream_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/editintervals/$', views.workout_summary_edit_view, name='workout_summary_edit_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/restore/$', diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index e7a951ee..987c9bdb 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -2763,348 +2763,6 @@ def workout_downloadmetar_view(request, id=0, return response -# Show form to update wind data -@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True) -@user_passes_test(ispromember, - login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher." - " If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -def workout_wind_view(request, id=0, message="", successmessage=""): - row = get_workoutuser(id, request) - r = getrower(request.user) - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': get_workout_default_page(request, id), - 'name': row.name - }, - { - 'url': reverse('workout_wind_view', kwargs={'id': id}), - 'name': 'Wind' - } - - ] - - # get data - f1 = row.csvfilename - u = row.user.user - r = getrower(u) - - # create bearing - rowdata = rdata(csvfile=f1) - if row == 0: # pragma: no cover - return HttpResponse("Error: CSV Data File Not Found") - - hascoordinates = 1 - try: - latitude = rowdata.df.loc[:, ' latitude'] - except KeyError: - hascoordinates = 0 - - if hascoordinates and not latitude.std(): # pragma: no cover - hascoordinates = 0 - - try: - _ = rowdata.df.loc[:, 'bearing'].values - except KeyError: - rowdata.add_bearing() - rowdata.write_csv(f1, gzip=True) - - if hascoordinates: - avglat = rowdata.df[' latitude'].mean() - avglon = rowdata.df[' longitude'].mean() - airportcode, newlat, newlon, airportdistance = get_airport_code( - avglat, avglon) - airportcode = airportcode.upper() - airportdistance = airportdistance[0] - else: - airportcode = 'UNKNOWN' - airportdistance = 0 - - if request.method == 'POST': - # process form - form = UpdateWindForm(request.POST) - - if form.is_valid(): - - vwind1 = form.cleaned_data['vwind1'] - vwind2 = form.cleaned_data['vwind2'] - dist1 = form.cleaned_data['dist1'] - dist2 = form.cleaned_data['dist2'] - winddirection1 = form.cleaned_data['winddirection1'] - winddirection2 = form.cleaned_data['winddirection2'] - windunit = form.cleaned_data['windunit'] - - rowdata.update_wind(vwind1, vwind2, - winddirection1, - winddirection2, - dist1, dist2, - units=windunit) - - rowdata.write_csv(f1, gzip=True) - - else: # pragma: no cover - message = "Invalid Form" - messages.error(request, message) - kwargs = { - 'id': id - } - url = reverse('workout_wind_view', kwargs=kwargs) - _ = HttpResponseRedirect(url) - - else: - form = UpdateWindForm() - - # create interactive plot - res = interactive_windchart(encoder.decode_hex(id), promember=1) - script = res[0] - div = res[1] - - if hascoordinates: - gmscript, gmdiv = leaflet_chart( - rowdata.df[' latitude'], - rowdata.df[' longitude'], - row.name) - else: - gmscript = "" - gmdiv = "No GPS data available" - - messages.info(request, successmessage) - messages.error(request, message) - - return render(request, - 'windedit.html', - {'workout': row, - 'rower': r, - 'breadcrumbs': breadcrumbs, - 'active': 'nav-workouts', - 'teams': get_my_teams(request.user), - 'interactiveplot': script, - 'form': form, - 'airport': airportcode, - 'airportdistance': airportdistance, - 'the_div': div, - 'gmap': gmscript, - 'gmapdiv': gmdiv}) - - -# Show form to update River stream data (for river dwellers) -@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True) -@user_passes_test(ispromember, - login_url="/rowers/paidplans", - message="This functionality requires a Pro plan or higher." - " If you are already a Pro user, please log in to access this functionality", - redirect_field_name=None) -def workout_stream_view(request, id=0, message="", successmessage=""): - row = get_workoutuser(id, request) - r = getrower(request.user) - - # create interactive plot - f1 = row.csvfilename - u = row.user.user - r = getrower(u) - - rowdata = rdata(csvfile=f1) - if rowdata == 0: # pragma: no cover - messages.info(request, "Error: CSV data file not found") - url = reverse('workout_edit_view', kwargs={ - 'id': encoder.encode_hex(row.id)}) - return HttpResponseRedirect(url) - - if request.method == 'POST': - # process form - form = UpdateStreamForm(request.POST) - - if form.is_valid(): - - dist1 = form.cleaned_data['dist1'] - dist2 = form.cleaned_data['dist2'] - stream1 = form.cleaned_data['stream1'] - stream2 = form.cleaned_data['stream2'] - streamunit = form.cleaned_data['streamunit'] - - rowdata.update_stream(stream1, stream2, dist1, dist2, - units=streamunit) - - rowdata.write_csv(f1, gzip=True) - - else: # pragma: no cover - message = "Invalid Form" - messages.error(request, message) - kwargs = { - 'id': id} - url = reverse('workout_wind_view', kwargs=kwargs) - _ = HttpResponseRedirect(url) - - else: - form = UpdateStreamForm() - - # create interactive plot - res = interactive_streamchart(encoder.decode_hex(id), promember=1) - script = res[0] - div = res[1] - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': get_workout_default_page(request, id), - 'name': row.name - }, - { - 'url': reverse('workout_stream_view', kwargs={'id': id}), - 'name': 'Stream' - } - - ] - - messages.info(request, successmessage) - messages.error(request, message) - return render(request, - 'streamedit.html', - {'workout': row, - 'rower': r, - 'breadcrumbs': breadcrumbs, - 'active': 'nav-workouts', - 'teams': get_my_teams(request.user), - 'interactiveplot': script, - 'form': form, - 'the_div': div}) - -# Form to set average crew weight and boat type, then run power calcs - - -@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True) -@user_passes_test(ispromember, login_url="/rowers/paidplans", redirect_field_name=None) -def workout_otwsetpower_view(request, id=0, message="", successmessage=""): - w = get_workoutuser(id, request) - r = getrower(request.user) - - mayedit = 1 - - if request.method == 'POST': - # process form - form = AdvancedWorkoutForm(request.POST) - - if form.is_valid(): - boattype = form.cleaned_data['boattype'] - weightvalue = form.cleaned_data['weightvalue'] - coastalbrand = form.cleaned_data['boatbrand'] - boatclass = w.workouttype - w.boattype = boattype - w.weightvalue = weightvalue - w.boatbrand = coastalbrand - w.save() - - # load row data & create power/wind/bearing columns if not set - f1 = w.csvfilename - rowdata = rdata(csvfile=f1) - if rowdata == 0: # pragma: no cover - return HttpResponse("Error: CSV Data File Not Found") - try: - _ = rowdata.df['vstream'] - except KeyError: - rowdata.add_stream(0) - rowdata.write_csv(f1, gzip=True) - - try: - _ = rowdata.df['bearing'] - except KeyError: - rowdata.add_bearing() - rowdata.write_csv(f1, gzip=True) - - try: - _ = rowdata.df['vwind'] - except KeyError: - rowdata.add_wind(0, 0) - rowdata.write_csv(f1, gzip=True) - - # do power calculation (asynchronous) - r = w.user - u = r.user - - first_name = u.first_name - last_name = u.last_name - emailaddress = u.email - - job = myqueue(queue, - handle_otwsetpower, f1, boattype, boatclass, coastalbrand, - weightvalue, - first_name, last_name, emailaddress, encoder.decode_hex( - id), - ps=[r.p0, r.p1, r.p2, r.p3], - ratio=r.cpratio, - # quick_calc = quick_calc, - # go_service=go_service, - emailbounced=r.emailbounced - ) - - try: - request.session['async_tasks'] += [(job.id, 'otwsetpower')] - except KeyError: - request.session['async_tasks'] = [(job.id, 'otwsetpower')] - - successmessage = 'Your calculations have been submitted." \ - " You will receive an email when they are done." \ - " You can check the status of your calculations" \ - " here' - messages.info(request, successmessage) - kwargs = { - 'id': id} - - try: - url = request.session['referer'] - except KeyError: - url = reverse('workout_edit_view', kwargs=kwargs) - - response = HttpResponseRedirect(url) - return response - - else: # pragma: no cover - message = "Invalid Form" - messages.error(request, message) - kwargs = { - 'id': id} - url = reverse('workout_otwsetpower_view', kwargs=kwargs) - response = HttpResponseRedirect(url) - - else: - form = AdvancedWorkoutForm(instance=w) - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': get_workout_default_page(request, id), - 'name': w.name - }, - { - 'url': reverse('workout_otwsetpower_view', kwargs={'id': id}), - 'name': 'OTW Power' - } - - ] - - messages.error(request, message) - messages.info(request, successmessage) - return render(request, - 'otwsetpower.html', - {'workout': w, - 'rower': w, - 'mayedit': mayedit, - 'active': 'nav-workouts', - 'breadcrumbs': breadcrumbs, - 'teams': get_my_teams(request.user), - 'form': form, - }) @permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True) @@ -4501,57 +4159,6 @@ def workout_flexchart_stacked_view(request, *args, **kwargs): # The interactive plot with wind corrected pace for OTW outings -def workout_otwpowerplot_view(request, id=0, message="", successmessage=""): - w = get_workout(id) - r = getrower(request.user) - - breadcrumbs = [ - { - 'url': '/rowers/list-workouts/', - 'name': 'Workouts' - }, - { - 'url': get_workout_default_page(request, id), - 'name': w.name - }, - { - 'url': reverse('workout_otwpowerplot_view', kwargs={'id': id}), - 'name': 'Interactive OTW Power Plot' - } - - ] - - # check if user is owner of this workout - - # create interactive plot - - promember = 0 - mayedit = 0 - result = request.user.is_authenticated and ispromember(request.user) - if result: - promember = 1 - if request.user == w.user.user: - mayedit = 1 - - # create interactive plot - res = interactive_otw_advanced_pace_chart( - encoder.decode_hex(id), promember=promember) - script = res[0] - div = res[1] - - messages.error(request, message) - messages.info(request, successmessage) - - return render(request, - 'otwinteractive.html', - {'workout': w, - 'rower': r, - 'active': 'nav-workouts', - 'breadcrumbs': breadcrumbs, - 'teams': get_my_teams(request.user), - 'interactiveplot': script, - 'the_div': div, - 'mayedit': mayedit}) #