verbeteringen
This commit is contained in:
@@ -477,12 +477,11 @@ def interactive_forcecurve(theworkouts):
|
|||||||
rowdata = dataprep.getsmallrowdata_pl(columns, ids=ids,
|
rowdata = dataprep.getsmallrowdata_pl(columns, ids=ids,
|
||||||
workstrokesonly=False)
|
workstrokesonly=False)
|
||||||
|
|
||||||
rowdata = rowdata.fill_nan(None).drop_nulls()
|
|
||||||
|
|
||||||
|
|
||||||
if rowdata.is_empty():
|
if rowdata.is_empty():
|
||||||
return "", "No Valid Data Available"
|
return "", "No Valid Data Available"
|
||||||
|
|
||||||
|
rowdata = rowdata.fill_nan(None).drop_nulls()
|
||||||
|
|
||||||
data_dict = rowdata.to_dicts()
|
data_dict = rowdata.to_dicts()
|
||||||
|
|
||||||
thresholdforce = 100. if 'x' in boattype else 200.
|
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]
|
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',
|
def get_zones_report(rower, startdate, enddate, trainingzones='hr', date_agg='week',
|
||||||
yaxis='time'):
|
yaxis='time'):
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ class URLTests(TestCase):
|
|||||||
'/rowers/workout/'+encoded1+'/addtimeplot/',
|
'/rowers/workout/'+encoded1+'/addtimeplot/',
|
||||||
'/rowers/workout/'+encoded1+'/addtimeplot2/',
|
'/rowers/workout/'+encoded1+'/addtimeplot2/',
|
||||||
'/rowers/workout/'+encoded1+'/comment/',
|
'/rowers/workout/'+encoded1+'/comment/',
|
||||||
'/rowers/workout/'+encoded1+'/darkskywind/',
|
|
||||||
'/rowers/workout/'+encoded1+'/data/',
|
'/rowers/workout/'+encoded1+'/data/',
|
||||||
'/rowers/workout/'+encoded1+'/edit/',
|
'/rowers/workout/'+encoded1+'/edit/',
|
||||||
'/rowers/workout/'+encoded1+'/editintervals/',
|
'/rowers/workout/'+encoded1+'/editintervals/',
|
||||||
|
|||||||
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
Binary file not shown.
@@ -510,14 +510,6 @@ urlpatterns = [
|
|||||||
name='workout_erase_column_view'),
|
name='workout_erase_column_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/zeropower-confirm/$', views.remove_power_confirm_view,
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/zeropower-confirm/$', views.remove_power_confirm_view,
|
||||||
name='remove_power_confirm_view'),
|
name='remove_power_confirm_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/zeropower/$', views.remove_power_view,
|
|
||||||
name='remove_power_view'),
|
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/otwsetpower/$',
|
|
||||||
views.workout_otwsetpower_view, name='workout_otwsetpower_view'),
|
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/interactiveotwplot/$',
|
|
||||||
views.workout_otwpowerplot_view, name='workout_otwpowerplot_view'),
|
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/wind/$',
|
|
||||||
views.workout_wind_view, name='workout_wind_view'),
|
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/image/$',
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/image/$',
|
||||||
views.workout_uploadimage_view, name='workout_uploadimage_view'),
|
views.workout_uploadimage_view, name='workout_uploadimage_view'),
|
||||||
re_path(r'^virtualevent/(?P<id>\d+)/compare/$',
|
re_path(r'^virtualevent/(?P<id>\d+)/compare/$',
|
||||||
@@ -540,8 +532,6 @@ urlpatterns = [
|
|||||||
views.workout_downloadwind_view, name='workout_downloadwind_view'),
|
views.workout_downloadwind_view, name='workout_downloadwind_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/metar/(?P<airportcode>\w+)/$',
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/metar/(?P<airportcode>\w+)/$',
|
||||||
views.workout_downloadmetar_view, name='workout_downloadmetar_view'),
|
views.workout_downloadmetar_view, name='workout_downloadmetar_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/stream/$',
|
|
||||||
views.workout_stream_view, name='workout_stream_view'),
|
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/editintervals/$', views.workout_summary_edit_view,
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/editintervals/$', views.workout_summary_edit_view,
|
||||||
name='workout_summary_edit_view'),
|
name='workout_summary_edit_view'),
|
||||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/restore/$',
|
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/restore/$',
|
||||||
|
|||||||
@@ -2763,348 +2763,6 @@ def workout_downloadmetar_view(request, id=0,
|
|||||||
return response
|
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" \
|
|
||||||
" <a href="/rowers/jobs-status/" target="_blank">here</a>'
|
|
||||||
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)
|
@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
|
# 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})
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user