Private
Public Access
1
0

Merge branch 'feature/newdataflow' into develop

This commit is contained in:
2025-11-16 13:11:52 +01:00
32 changed files with 3738 additions and 2402 deletions

View File

@@ -15,6 +15,7 @@ from rest_framework.decorators import parser_classes
from rest_framework.parsers import BaseParser
from rowers.utils import geo_distance
from rowers.dataflow import upload_handler
from datetime import datetime as dt
@@ -467,7 +468,6 @@ def strokedata_rowingdata(request):
filename, completefilename = handle_uploaded_file(f)
uploadoptions = {
'secret': settings.UPLOAD_SERVICE_SECRET,
'user': r.user.id,
'file': completefilename,
'workouttype': form.cleaned_data['workouttype'],
@@ -477,17 +477,21 @@ def strokedata_rowingdata(request):
'notes': form.cleaned_data['notes']
}
url = settings.UPLOAD_SERVICE_URL
result = upload_handler(uploadoptions, completefilename, createworkout=True)
if result['status'] != 'processing':
dologging('apilog.log','Error in strokedata_rowingdata:')
dologging('apilog.log',result)
return JsonResponse(
result,
status=500
)
_ = myqueue(queuehigh,
handle_request_post,
url,
uploadoptions)
workoutid = result.get('job_id',0)
response = JsonResponse(
{
"status": "success",
}
)
{"workout public id": workoutid,
"status": "success",
}
)
response.status_code = 201
return response
@@ -518,7 +522,6 @@ def strokedata_rowingdata_apikey(request):
filename, completefilename = handle_uploaded_file(f)
uploadoptions = {
'secret': settings.UPLOAD_SERVICE_SECRET,
'user': r.user.id,
'file': completefilename,
'workouttype': form.cleaned_data['workouttype'],
@@ -528,17 +531,22 @@ def strokedata_rowingdata_apikey(request):
'notes': form.cleaned_data['notes']
}
url = settings.UPLOAD_SERVICE_URL
_ = myqueue(queuehigh,
handle_request_post,
url,
uploadoptions)
result = upload_handler(uploadoptions, completefilename, createworkout=True)
if result['status'] != 'processing':
dologging('apilog.log','Error in strokedata_rowingdata_apikey:')
dologging('apilog.log',result)
return JsonResponse(
result,
status=500
)
workoutid = result.get('job_id',0)
response = JsonResponse(
{
"status": "success",
}
)
{"workout public id": workoutid,
"status": "success",
}
)
response.status_code = 201
return response
@@ -614,7 +622,6 @@ def strokedata_fit(request):
)
uploadoptions = {
'secret': UPLOAD_SERVICE_SECRET,
'user': request.user.id,
'file': fit_filename,
'boattype': '1x',
@@ -626,20 +633,18 @@ def strokedata_fit(request):
'offline': False,
}
url = UPLOAD_SERVICE_URL
_ = myqueue(queuehigh,
handle_request_post,
url,
uploadoptions)
result = upload_handler(uploadoptions, fit_filename)
dologging('apilog.log','FIT file uploaded, returning response')
returndict = {
"status": "success",
"workout public id": encoder.encode_hex(w.id),
"workout id": w.id,
}
return JsonResponse(returndict, status=201)
if result.get('status','') != 'processing':
return JsonResponse(result, status=500)
workoutid = result.get('job_id',0)
return JsonResponse(
{"workout public id": workoutid,
"status": "success",
})
except Exception as e:
dologging('apilog.log','FIT API endpoint')
dologging('apilog.log',e)
@@ -736,7 +741,6 @@ def strokedata_tcx(request):
# need workouttype, duration
uploadoptions = {
'secret': UPLOAD_SERVICE_SECRET,
'user': request.user.id,
'file': tcxfilename,
'id': w.id,
@@ -747,17 +751,15 @@ def strokedata_tcx(request):
'notes': '',
'offline': False,
}
_ = myqueue(queuehigh,
handle_post_workout_api,
uploadoptions)
workoutid = w.id
result = upload_handler(uploadoptions, tcxfilename)
if result.get('status','') != 'processing':
return JsonResponse(result, status=500)
workoutid = result.get('job_id',0)
return JsonResponse(
{"workout public id": encoder.encode_hex(workoutid),
"workout id": workoutid,
{"workout public id": workoutid,
"status": "success",
})
except Exception as e: # pragma: no cover
@@ -777,7 +779,7 @@ def strokedatajson_v3(request):
"""
POST: Add Stroke data to workout
GET: Get stroke data of workout
This v2 API works on stroke based data dict:
This v3 API works on stroke based data dict:
{
"distance": 2100,
"elapsedTime": 592,
@@ -884,7 +886,6 @@ def strokedatajson_v3(request):
w.save()
uploadoptions = {
'secret': UPLOAD_SERVICE_SECRET,
'user': request.user.id,
'file': csvfilename,
'title': title,
@@ -898,10 +899,9 @@ def strokedatajson_v3(request):
'id': w.id,
}
_ = myqueue(queuehigh,
handle_post_workout_api,
uploadoptions)
result = upload_handler(uploadoptions, csvfilename)
if result.get('status','') != 'processing':
return JsonResponse(result, status=500)
workoutid = w.id

View File

@@ -5,7 +5,7 @@ from rowsandall_app.settings import (
from rowers.views.statements import *
from rowers.plannedsessions import get_dates_timeperiod
from rowers.tasks import fetch_strava_workout
from rowers.utils import NoTokenError
from rowers.models import PlannedSession

View File

@@ -255,14 +255,12 @@ from rowers.plannedsessions import *
from rowers.tasks import handle_makeplot, handle_otwsetpower, handle_sendemailtcx, handle_sendemailcsv
from rowers.tasks import (
handle_intervals_updateworkout,
handle_post_workout_api,
handle_sendemail_newftp,
instroke_static,
fetch_rojabo_session,
handle_sendemail_unrecognized, handle_sendemailnewcomment,
handle_request_post,
handle_sendemailsummary,
handle_rp3_async_workout,
handle_send_template_email,
handle_send_disqualification_email,
handle_send_withdraw_email,
@@ -278,11 +276,17 @@ from rowers.tasks import (
handle_sendemail_racesubmission,
handle_sendemail_optout,
handle_sendemail_ical,
handle_c2_async_workout,
handle_send_email_instantplan_notification,
handle_nk_async_workout,
check_tp_workout_id,
)
from rowers.upload_tasks import (
handle_assignworkouts,
handle_post_workout_api,
handle_c2_async_workout,
handle_rp3_async_workout,
handle_sporttracks_workout_from_data,
handle_split_workout_by_intervals,
)

View File

@@ -23,6 +23,7 @@ def default(o): # pragma: no cover
return int(o)
raise TypeError
from rowers.dataflow import upload_handler
def get_video_id(url):
"""Returns Video_ID extracting from the given url of Youtube
@@ -5263,16 +5264,10 @@ def workout_upload_view(request,
'upload_to_C2': False,
'plottype': 'timeplot',
'landingpage': 'workout_edit_view',
},
docformoptions={
'workouttype': 'rower',
},
raceid=0):
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
if settings.TESTING:
is_ajax = False
r = getrower(request.user)
if r.imports_are_private:
uploadoptions['makeprivate'] = True
@@ -5290,418 +5285,53 @@ def workout_upload_view(request,
if 'uploadoptions' in request.session:
uploadoptions = request.session['uploadoptions']
try:
_ = uploadoptions['landingpage']
except KeyError: # pragma: no cover
uploadoptions['landingpage'] = r.defaultlandingpage
else:
request.session['uploadoptions'] = uploadoptions
if 'docformoptions' in request.session:
docformoptions = request.session['docformoptions']
else:
request.session['docformoptions'] = docformoptions
form = DocumentsForm(initial=uploadoptions)
optionsform = UploadOptionsForm(initial=uploadoptions,
request=request, raceid=raceid)
makeprivate = uploadoptions.get('makeprivate', False)
make_plot = uploadoptions.get('make_plot', False)
workouttype = uploadoptions.get('WorkoutType', 'rower')
boattype = docformoptions.get('boattype', '1x')
try:
rpe = docformoptions['rpe']
try: # pragma: no cover
rpe = int(rpe)
except ValueError: # pragma: no cover
rpe = 0
if not rpe: # pragma: no cover
rpe = -1
except KeyError:
rpe = -1
notes = docformoptions.get('notes', '')
workoutsource = uploadoptions.get('workoutsource', None)
plottype = uploadoptions.get('plottype', 'timeplot')
landingpage = uploadoptions.get('landingpage', r.defaultlandingpage)
upload_to_c2 = uploadoptions.get('upload_to_C2', False)
upload_to_strava = uploadoptions.get('upload_to_Strava', False)
upload_to_st = uploadoptions.get('upload_to_SportTracks', False)
upload_to_tp = uploadoptions.get('upload_to_TrainingPeaks', False)
upload_to_intervals = uploadoptions.get('upload_to_Intervals', False)
response = {}
if request.method == 'POST':
form = DocumentsForm(request.POST, request.FILES)
optionsform = UploadOptionsForm(request.POST, request=request)
if form.is_valid():
# f = request.FILES['file']
f = form.cleaned_data['file']
if f is not None:
res = handle_uploaded_file(f)
else: # pragma: no cover
messages.error(request,
"Something went wrong - no file attached")
url = reverse('workout_upload_view')
if is_ajax:
return JSONResponse({'result': 0, 'url': 0})
else:
return HttpResponseRedirect(url)
t = form.cleaned_data['title']
workouttype = form.cleaned_data['workouttype']
boattype = form.cleaned_data['boattype']
try:
rpe = form.cleaned_data['rpe']
try:
rpe = int(rpe)
except ValueError:
rpe = 0
except KeyError: # pragma: no cover
rpe = -1
request.session['docformoptions'] = {
'workouttype': workouttype,
'boattype': boattype,
}
notes = form.cleaned_data['notes']
offline = form.cleaned_data['offline']
registrationid = 0
if optionsform.is_valid():
make_plot = optionsform.cleaned_data['make_plot']
plottype = optionsform.cleaned_data['plottype']
upload_to_c2 = optionsform.cleaned_data['upload_to_C2']
upload_to_strava = optionsform.cleaned_data['upload_to_Strava']
upload_to_st = optionsform.cleaned_data['upload_to_SportTracks']
upload_to_tp = optionsform.cleaned_data['upload_to_TrainingPeaks']
upload_to_intervals = optionsform.cleaned_data['upload_to_Intervals']
makeprivate = optionsform.cleaned_data['makeprivate']
landingpage = optionsform.cleaned_data['landingpage']
raceid = optionsform.cleaned_data['raceid']
try:
registrationid = optionsform.cleaned_data['submitrace']
except KeyError:
registrationid = 0
uploadoptions = {
'makeprivate': makeprivate,
'make_plot': make_plot,
'plottype': plottype,
'upload_to_C2': upload_to_c2,
'upload_to_Strava': upload_to_strava,
'upload_to_SportTracks': upload_to_st,
'upload_to_TrainingPeaks': upload_to_tp,
'upload_to_Intervals': upload_to_intervals,
'landingpage': landingpage,
'boattype': boattype,
'rpe': rpe,
'workouttype': workouttype,
}
if form.is_valid() and optionsform.is_valid():
uploadoptions = form.cleaned_data.copy()
uploadoptions.update(optionsform.cleaned_data)
request.session['uploadoptions'] = uploadoptions
f1 = res[0] # file name
f2 = res[1] # file name incl media directory
if not offline:
id, message, f2 = dataprep.new_workout_from_file(
r, f2,
workouttype=workouttype,
workoutsource=workoutsource,
boattype=boattype,
rpe=rpe,
makeprivate=makeprivate,
title=t,
notes=notes,
)
uploadoptions['user'] = r.user.id
if 'file' in request.FILES and request.FILES['file'] is not None:
filename, file_path = handle_uploaded_file(request.FILES['file'])
else:
uploadoptions['secret'] = settings.UPLOAD_SERVICE_SECRET
uploadoptions['user'] = r.user.id
uploadoptions['title'] = t
uploadoptions['file'] = f2
messages.error(request,"No file attached")
return HttpResponseRedirect(reverse("workout_upload_view"))
url = settings.UPLOAD_SERVICE_URL
uploadoptions['file'] = file_path
_ = myqueue(queuehigh,
handle_request_post,
url,
uploadoptions
)
messages.info(
request,
"The file was too large to process in real time."
" It will be processed in a background process."
" You will receive an email when it is ready")
response = upload_handler(uploadoptions, file_path)
if response["status"] not in ["processing"]:
messages.error(request, response["message"])
url = reverse('workout_upload_view')
if is_ajax: # pragma: no cover
return JSONResponse({'result': 1, 'url': url})
else:
response = HttpResponseRedirect(url)
return response
if not id: # pragma: no cover
messages.error(request, message)
url = reverse('workout_upload_view')
if is_ajax: # pragma: no cover
return JSONResponse({'result': 0, 'url': url})
else:
response = HttpResponseRedirect(url)
return response
elif id == -1: # pragma: no cover
message = 'The zip archive will be processed in the background." \
" The files in the archive will only be uploaded without the extra actions." \
" You will receive email when the workouts are ready.'
messages.info(request, message)
url = reverse('workout_upload_view')
if is_ajax:
return JSONResponse({'result': 1, 'url': url})
else:
response = HttpResponseRedirect(url)
return response
return HttpResponseRedirect(url)
else:
if message: # pragma: no cover
messages.error(request, message)
messages.info(request, response["message"])
w = Workout.objects.get(id=id)
url = reverse('workout_edit_view',
kwargs={
'id': encoder.encode_hex(w.id),
})
if is_ajax: # pragma: no cover
response = {'result': 1, 'url': url}
else:
response = HttpResponseRedirect(url)
r = getrower(request.user)
if (make_plot): # pragma: no cover
res, jobid = uploads.make_plot(r, w, f1, f2, plottype, t)
if res == 0:
messages.error(request, jobid)
else:
try:
request.session['async_tasks'] += [
(jobid, 'make_plot')]
except KeyError:
request.session['async_tasks'] = [(jobid, 'make_plot')]
elif r.staticchartonupload is not None:
plottype = r.staticchartonupload
res, jobid = uploads.make_plot(r, w, f1, f2, plottype, t)
# upload to C2
if (upload_to_c2): # pragma: no cover
try:
c2integration = C2Integration(request.user)
id = c2integration.workout_export(w)
except NoTokenError:
id = 0
message = "Something went wrong with the Concept2 sync"
messages.error(request, message)
if (upload_to_strava): # pragma: no cover
strava_integration = StravaIntegration(request.user)
try:
id = strava_integration.workout_export(w)
except NoTokenError:
id = 0
message = "Please connect to Strava first"
messages.error(request, message)
if (upload_to_st): # pragma: no cover
st_integration = SportTracksIntegration(request.user)
try:
id = st_integration.workout_export(w)
except NoTokenError:
message = "Please connect to SportTracks first"
id = 0
messages.error(request, message)
if (upload_to_tp): # pragma: no cover
tp_integration = TPIntegration(request.user)
try:
id = tp_integration.workout_export(w)
except NoTokenError:
message = "Please connect to TrainingPeaks first"
messages.error(request, message)
if (upload_to_intervals):
intervals_integration = IntervalsIntegration(request.user)
try:
id = intervals_integration.workout_export(w)
except NoTokenError:
message = "Please connect to Intervals.icu first"
messages.error(request, message)
if int(registrationid) < 0: # pragma: no cover
race = VirtualRace.objects.get(id=-int(registrationid))
if race.sessiontype == 'race':
result, comments, errors, jobid = add_workout_race(
[w], race, r, doregister=True,
)
if result:
messages.info(
request,
"We have submitted your workout to the race")
for c in comments:
messages.info(request, c)
for er in errors:
messages.error(request, er)
elif race.sessiontype == 'indoorrace':
result, comments, errors, jobid = add_workout_indoorrace(
[w], race, r, doregister=True,
)
if result:
messages.info(
request,
"We have submitted your workout to the race")
for c in comments:
messages.info(request, c)
for er in errors:
messages.error(request, er)
elif race.sessiontype in ['fastest_time', 'fastest_distance']:
result, comments, errors, jobid = add_workout_fastestrace(
[w], race, r, doregister=True,
)
if result:
messages.info(
request, "We have submitted your workout to the race")
for c in comments:
messages.info(request, c)
for er in errors:
messages.error(request, er)
if int(registrationid) > 0: # pragma: no cover
races = VirtualRace.objects.filter(
registration_closure__gt=timezone.now()
)
if raceid != 0:
races = VirtualRace.objects.filter(
registration_closure__gt=timezone.now(),
id=raceid,
)
registrations = IndoorVirtualRaceResult.objects.filter(
race__in=races,
id=registrationid,
userid=r.id,
)
registrations2 = VirtualRaceResult.objects.filter(
race__in=races,
id=registrationid,
userid=r.id,
)
if int(registrationid) in [r.id for r in registrations]: # pragma: no cover
# indoor race
registrations = registrations.filter(id=registrationid)
if registrations:
race = registrations[0].race
if race.sessiontype == 'indoorrace':
result, comments, errors, jobid = add_workout_indoorrace(
[w], race, r, recordid=registrations[0].id
)
elif race.sessiontype in ['fastest_time', 'fastest_distance']:
result, comments, errors, jobid = add_workout_fastestrace(
[w], race, r, recordid=registrations[0].id
)
if result:
messages.info(
request,
"We have submitted your workout to the race")
for c in comments:
messages.info(request, c)
for er in errors:
messages.error(request, er)
if int(registrationid) in [r.id for r in registrations2]: # pragma: no cover
# race
registrations = registrations2.filter(id=registrationid)
if registrations:
race = registrations[0].race
if race.sessiontype == 'race':
result, comments, errors, jobid = add_workout_race(
[w], race, r, recordid=registrations[0].id
)
elif race.sessiontype in ['fastest_time', 'fastest_distance']:
result, comments, errors, jobid = add_workout_fastestrace(
[w], race, r, recordid=registrations[0].id
)
if result:
messages.info(
request,
"We have submitted your workout to the race")
for c in comments:
messages.info(request, c)
for er in errors:
messages.error(request, er)
if registrationid != 0: # pragma: no cover
try:
url = reverse('virtualevent_view',
kwargs={
'id': race.id,
})
except UnboundLocalError:
if landingpage != 'workout_upload_view':
url = reverse(landingpage,
kwargs={
'id': encoder.encode_hex(w.id),
})
else: # pragma: no cover
url = reverse(landingpage)
elif landingpage != 'workout_upload_view': # pragma: no cover
url = reverse(landingpage,
kwargs={
'id': encoder.encode_hex(w.id),
})
else: # pragma: no cover
url = reverse(landingpage)
if is_ajax: # pragma: no cover
response = {'result': 1, 'url': url}
else:
response = HttpResponseRedirect(url)
# redirect to workouts_view
url = reverse('workouts_view')
return HttpResponseRedirect(url)
else:
if not is_ajax: # pragma: no cover
response = render(request,
'document_form.html',
{'form': form,
'teams': get_my_teams(request.user),
'optionsform': optionsform,
})
if is_ajax: # pragma: no cover
return JSONResponse(response)
else:
return response
else:
if not is_ajax:
form = DocumentsForm(initial=docformoptions)
optionsform = UploadOptionsForm(initial=uploadoptions,
request=request, raceid=raceid)
return render(request, 'document_form.html',
{'form': form,
'active': 'nav-workouts',
'breadcrumbs': breadcrumbs,
'teams': get_my_teams(request.user),
'optionsform': optionsform,
})
else: # pragma: no cover
return {'result': 0}
messages.error(request, "error")
return render(request, 'file_upload.html',
{'form': form,
'active': 'nav-workouts',
'breadcrumbs': breadcrumbs,
'teams': get_my_teams(request.user),
'optionsform': optionsform,
})
# This is the main view for processing uploaded files
@user_passes_test(ispromember, login_url="/rowers/paidplans", redirect_field_name=None,
@@ -5713,6 +5343,8 @@ def team_workout_upload_view(request, userid=0, message="",
'plottype': 'timeplot',
}):
r = getrower(request.user)
if 'uploadoptions' in request.session:
uploadoptions = request.session['uploadoptions']
else:
@@ -5732,11 +5364,22 @@ def team_workout_upload_view(request, userid=0, message="",
make_plot = uploadoptions['make_plot']
plottype = uploadoptions['plottype']
form = DocumentsForm(initial=uploadoptions)
optionsform = TeamUploadOptionsForm(initial=uploadoptions)
rowerform = TeamInviteForm(userid=userid)
rowerform.fields.pop('email')
rowers = Rower.objects.filter(
coachinggroups__in=[r.mycoachgroup]
).distinct()
rowerform.fields['user'].queryset = User.objects.filter(
rower__in=rowers).distinct()
r = getrower(request.user)
if request.method == 'POST':
form = DocumentsForm(request.POST, request.FILES)
optionsform = TeamUploadOptionsForm(request.POST)
rowerform = TeamInviteForm(request.POST)
rowerform.fields.pop('email')
rowers = Rower.objects.filter(
@@ -5746,155 +5389,53 @@ def team_workout_upload_view(request, userid=0, message="",
rowerform.fields['user'].queryset = User.objects.filter(
rower__in=rowers).distinct()
rowerform.fields['user'].required = True
if form.is_valid() and rowerform.is_valid():
f = request.FILES.get('file', False)
if f:
res = handle_uploaded_file(f)
else: # pragma: no cover
messages.error(request, 'No file attached')
response = render(request,
'team_document_form.html',
{'form': form,
'teams': get_my_teams(request.user),
'optionsform': optionsform,
'rowerform': rowerform,
})
return response
t = form.cleaned_data['title']
offline = form.cleaned_data['offline']
boattype = form.cleaned_data['boattype']
workouttype = form.cleaned_data['workouttype']
if rowerform.is_valid():
u = rowerform.cleaned_data['user']
r = getrower(u)
if not can_add_workout_member(request.user, r): # pragma: no cover
message = 'Please select a rower'
messages.error(request, message)
messages.info(request, successmessage)
response = render(request,
'team_document_form.html',
{'form': form,
'teams': get_my_teams(request.user),
'optionsform': optionsform,
'rowerform': rowerform,
})
return response
workouttype = form.cleaned_data['workouttype']
if optionsform.is_valid():
make_plot = optionsform.cleaned_data['make_plot']
plottype = optionsform.cleaned_data['plottype']
uploadoptions = {
'makeprivate': False,
'make_plot': make_plot,
'plottype': plottype,
'upload_to_C2': False,
}
if form.is_valid() and rowerform.is_valid() and optionsform.is_valid():
uploadoptions = form.cleaned_data.copy()
uploadoptions.update(optionsform.cleaned_data)
uploadoptions.update(rowerform.cleaned_data)
request.session['uploadoptions'] = uploadoptions
f1 = res[0] # file name
f2 = res[1] # file name incl media directory
if not offline:
id, message, f2 = dataprep.new_workout_from_file(
r, f2,
workouttype=workouttype,
boattype=boattype,
makeprivate=False,
title=t,
notes=''
)
else: # pragma: no cover
_ = myqueue(
queuehigh,
handle_zip_file,
r.user.email,
t,
f2,
emailbounced=r.emailbounced
)
messages.info(
request,
"The file was too large to process in real time."
" It will be processed in a background process."
" The user will receive an email when it is ready"
)
url = reverse('team_workout_upload_view')
response = HttpResponseRedirect(url)
return response
if not id: # pragma: no cover
messages.error(request, message)
url = reverse('team_workout_upload_view')
response = HttpResponseRedirect(url)
return response
elif id == -1: # pragma: no cover
message = 'The zip archive will be processed in the background." \
" The files in the archive will only be uploaded without the extra actions." \
" You will receive email when the workouts are ready.'
messages.info(request, message)
url = reverse('team_workout_upload_view')
response = HttpResponseRedirect(url)
return response
if 'file' in request.FILES and request.FILES['file'] is not None:
filename, file_path = handle_uploaded_file(request.FILES['file'])
else:
successmessage = "The workout was added to the user's account"
messages.info(request, successmessage)
messages.error(request,"No file attached")
return HttpResponseRedirect(reverse("team_workout_upload_view"))
uploadoptions['file'] = file_path
u = rowerform.cleaned_data['user']
r = getrower(u)
if not can_add_workout_member(request.user, r): # pragma: no cover
message = 'Please select a rower'
messages.error(request, message)
uploadoptions['user'] = u.id
response = upload_handler(uploadoptions, file_path)
if response["status"] not in ["processing"]:
messages.error(request, response["message"])
url = reverse('team_workout_upload_view')
return HttpResponseRedirect(url)
else:
messages.info(request, response["message"])
response = HttpResponseRedirect(url)
w = Workout.objects.get(id=id)
r = getrower(request.user)
if (make_plot): # pragma: no cover
id, jobid = uploads.make_plot(r, w, f1, f2, plottype, t)
elif r.staticchartonupload:
plottype = r.staticchartonupload
id, jobid = uploads.make_plot(r, w, f1, f2, plottype, t)
# redirect to workouts_view
url = reverse('team_workout_upload_view')
return HttpResponseRedirect(url)
else:
response = render(request,
'team_document_form.html',
{'form': form,
'teams': get_my_teams(request.user),
'active': 'nav-workouts',
'breadcrumbs': breadcrumbs,
'optionsform': optionsform,
'rowerform': rowerform,
})
messages.error(request, "error")
return response
else:
form = DocumentsForm()
optionsform = TeamUploadOptionsForm(initial=uploadoptions)
rowerform = TeamInviteForm(userid=userid)
rowerform.fields.pop('email')
rowers = Rower.objects.filter(
coachinggroups__in=[r.mycoachgroup]
).distinct()
rowerform.fields['user'].queryset = User.objects.filter(
rower__in=rowers).distinct()
return render(request, 'team_document_form.html',
response = render(request,
'team_document_form.html',
{'form': form,
# 'teams':get_my_teams(request.user),
'optionsform': optionsform,
'teams': get_my_teams(request.user),
'active': 'nav-workouts',
'breadcrumbs': breadcrumbs,
# 'rower':r,
'optionsform': optionsform,
'rowerform': rowerform,
})
return response
# A page with all the recent graphs (searchable on workout name)
@login_required()