Private
Public Access
1
0

moving to views

This commit is contained in:
Sander Roosendaal
2019-02-07 16:02:04 +01:00
parent ef26871778
commit a3b309fb16
17 changed files with 18568 additions and 8 deletions

View File

@@ -1360,7 +1360,7 @@ class PlannedSessionsView(TestCase):
'criterium': 'none',
'sessionvalue': 13000,
'sessionunit': 'm',
'course': None,
'course': '',
'comment':faker.text(),
'members': [self.r.id,self.r2.id]
}
@@ -1440,7 +1440,7 @@ class PlannedSessionsView(TestCase):
'criterium': 'none',
'sessionvalue': 13000,
'sessionunit': 'm',
'course': None,
'course': '',
'comment':faker.text(),
}

Binary file not shown.

View File

@@ -0,0 +1 @@
E408191@CZ27LT9RCGN72.1380:1549472010

File diff suppressed because it is too large Load Diff

182
rowers/views/apiviews.py Normal file
View File

@@ -0,0 +1,182 @@
from statements import *
# Stroke data form to test API upload
@login_required()
def strokedataform(request,id=0):
try:
id=int(id)
except ValueError:
id = 0
try:
w = Workout.objects.get(id=id)
except Workout.DoesNotExist:
raise Http404("Workout doesn't exist")
if request.method == 'GET':
form = StrokeDataForm()
return render(request, 'strokedata_form.html',
{
'form':form,
'teams':get_my_teams(request.user),
'id':id,
'workout':w,
})
elif request.method == 'POST':
form = StrokeDataForm()
return render(request, 'strokedata_form.html',
{
'form':form,
'teams':get_my_teams(request.user),
'id':id,
'workout':w,
})
# Process the POSTed stroke data according to the API definition
# Return the GET stroke data according to the API definition
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
@csrf_exempt
@login_required()
@api_view(['GET','POST'])
def strokedatajson(request,id):
"""
POST: Add Stroke data to workout
GET: Get stroke data of workout
"""
row = get_workout_permitted(request.user,id)
try:
id = int(id)
except ValueError:
return HttpResponse("Not a valid workout number",status=400)
if request.method == 'GET':
# currently only returns a subset.
columns = ['spm','time','hr','pace','power','distance']
datadf = dataprep.getsmallrowdata_db(columns,ids=[id])
with open('media/apilog.log','a') as logfile:
logfile.write(str(timezone.now())+": ")
logfile.write(request.user.username+"(GET) \n")
return JSONResponse(datadf)
if request.method == 'POST':
checkdata,r = dataprep.getrowdata_db(id=row.id)
if not checkdata.empty:
return HttpResponse("Duplicate Error",409)
# strokedata = request.POST['strokedata']
# checking/validating and cleaning
try:
strokedata = json.loads(request.POST['strokedata'])
except:
return HttpResponse("No JSON object could be decoded",400)
df = pd.DataFrame(strokedata)
df.index = df.index.astype(int)
df.sort_index(inplace=True)
# time, hr, pace, spm, power, drivelength, distance, drivespeed, dragfactor, strokerecoverytime, averagedriveforce, peakdriveforce, lapidx
try:
time = df['time']/1.e3
except KeyError:
return HttpResponse("There must be time values",status=400)
aantal = len(time)
pace = df['pace']/1.e3
if len(pace) != aantal:
return HttpResponse("Pace array has incorrect length",status=400)
distance = df['distance']
if len(distance) != aantal:
return HttpResponse("Distance array has incorrect length",status=400)
spm = df['spm']
if len(spm) != aantal:
return HttpResponse("SPM array has incorrect length",status=400)
res = dataprep.testdata(time,distance,pace,spm)
if not res:
return HttpResponse("Data are not numerical",status=400)
power = trydf(df,aantal,'power')
drivelength = trydf(df,aantal,'drivelength')
drivespeed = trydf(df,aantal,'drivespeed')
dragfactor = trydf(df,aantal,'dragfactor')
drivetime = trydf(df,aantal,'drivetime')
strokerecoverytime = trydf(df,aantal,'strokerecoverytime')
averagedriveforce = trydf(df,aantal,'averagedriveforce')
peakdriveforce = trydf(df,aantal,'peakdriveforce')
wash = trydf(df,aantal,'wash')
catch = trydf(df,aantal,'catch')
finish = trydf(df,aantal,'finish')
peakforceangle = trydf(df,aantal,'peakforceangle')
driveenergy = trydf(df,aantal,'driveenergy')
slip = trydf(df,aantal,'slip')
lapidx = trydf(df,aantal,'lapidx')
hr = trydf(df,aantal,'hr')
starttime = totimestamp(row.startdatetime)+time[0]
unixtime = starttime+time
with open('media/apilog.log','a') as logfile:
logfile.write(str(starttime)+": ")
logfile.write(request.user.username+"(POST) \r\n")
data = pd.DataFrame({'TimeStamp (sec)':unixtime,
' Horizontal (meters)': distance,
' Cadence (stokes/min)':spm,
' HRCur (bpm)':hr,
' DragFactor':dragfactor,
' Stroke500mPace (sec/500m)':pace,
' Power (watts)':power,
' DriveLength (meters)':drivelength,
' DriveTime (ms)':drivetime,
' StrokeRecoveryTime (ms)':strokerecoverytime,
' AverageDriveForce (lbs)':averagedriveforce,
' PeakDriveForce (lbs)':peakdriveforce,
' lapIdx':lapidx,
' ElapsedTime (sec)':time,
'catch':catch,
'slip':slip,
'finish':finish,
'wash':wash,
'driveenergy':driveenergy,
'peakforceangle':peakforceangle,
})
# Following part should be replaced with dataprep.new_workout_from_df
r = getrower(request.user)
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
csvfilename ='media/Import_'+timestr+'.csv'
res = data.to_csv(csvfilename+'.gz',index_label='index',
compression='gzip')
row.csvfilename = csvfilename
row.save()
powerperc = 100*np.array([r.pw_ut2,
r.pw_ut1,
r.pw_at,
r.pw_tr,r.pw_an])/r.ftp
ftp = float(r.ftp)
if row.workouttype in mytypes.otwtypes:
ftp = ftp*(100.-r.otwslack)/100.
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an,ftp=ftp,
powerperc=powerperc,powerzones=r.powerzones)
rowdata = rdata(row.csvfilename,rower=rr).df
datadf = dataprep.dataprep(rowdata,id=row.id,bands=True,barchart=True,otwpower=True,empower=True)
# mangling
#
return HttpResponse(row.id,status=201)
#Method not supported
return HttpResponseNotAllowed("Method not supported")

View File

@@ -0,0 +1,30 @@
from statements import *
# Custom error pages with Rowsandall headers
def error500_view(request):
response = render_to_response('500.html', {},
context_instance = RequestContext(request))
response.status_code = 500
return response
def error404_view(request):
response = render_to_response('404.html', {},
context_instance = RequestContext(request))
response.status_code = 404
return response
def error400_view(request):
response = render_to_response('400.html', {},
context_instance = RequestContext(request))
response.status_code = 400
return response
def error403_view(request):
response = render_to_response('403.html', {},
context_instance = RequestContext(request))
response.status_code = 403
return response

220
rowers/views/exportviews.py Normal file
View File

@@ -0,0 +1,220 @@
from statements import *
# Export workout to TCX and send to user's email address
@login_required()
def workout_tcxemail_view(request,id=0):
r = getrower(request.user)
w = get_workout(id)
if not checkworkoutuser(request.user,w):
raise PermissionDenied("Access denied")
row = rdata(w.csvfilename)
code = str(uuid4())
tcxfilename = code+'.tcx'
row.exporttotcx(tcxfilename)
with open(tcxfilename,'r') as f:
response = HttpResponse(f)
response['Content-Disposition'] = 'attachment; filename="%s"' % tcxfilename
response['Content-Type'] = 'application/octet-stream'
os.remove(tcxfilename)
return response
@login_required()
def plannedsessions_icsemail_view(request,userid=0):
r = getrequestrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request)
sps = get_sessions(r,startdate=startdate,enddate=enddate)
cal = Calendar()
cal.add('prodid','rowsandall')
cal.add('version','1.0')
for ps in sps:
event = Event()
comment = '{d} {u} {c}'.format(
d=ps.sessionvalue,
u = ps.sessionunit,
c = ps.criterium)
event.add('summary',ps.name)
event.add('dtstart',ps.preferreddate)
event.add('dtend',ps.preferreddate)
event['uid'] = 'plannedsession_'+str(ps.id)
event.add('description',ps.comment)
event.add('comment',comment)
cal.add_component(event)
response = HttpResponse(cal.to_ical())
response['Content-Disposition'] = 'attachment; filename="training_plan_{u}_{d1}_{d2}.ics"'.format(
u = request.user.username,
d1 = startdate.strftime("%Y%m%d"),
d2 = enddate.strftime("%Y%m%d"),
)
response['Content-Type'] = 'application/octet-stream'
return response
@login_required()
def course_kmldownload_view(request,id=0):
r = getrower(request.user)
if r.emailbounced:
message = "Please check your email address first. Email to this address bounced."
messages.error(request,message)
return HttpResponseRedirect(
reverse(course_view,
kwargs = {
'id':str(id),
})
)
course = GeoCourse.objects.get(id=id)
kmlstring = courses.coursetokml(course)
kmlfilename = 'course_{id}.kml'.format(id=id)
response = HttpResponse(kmlstring)
response['Content-Disposition'] = 'attachment; filename="{filename}"'.format(filename=kmlfilename)
response['Content-Type'] = 'application/octet-stream'
return response
# Export workout to GPX and send to user's email address
@login_required()
def workout_gpxemail_view(request,id=0):
r = getrower(request.user)
w = get_workout(id)
if not checkworkoutuser(request.user,w):
raise PermissionDenied("Access denied")
row = rdata(w.csvfilename)
code = str(uuid4())
gpxfilename = code+'.gpx'
row.exporttogpx(gpxfilename)
with open(gpxfilename,'r') as f:
response = HttpResponse(f)
response['Content-Disposition'] = 'attachment; filename="%s"' % gpxfilename
response['Content-Type'] = 'application/octet-stream'
os.remove(gpxfilename)
return response
# Get Workout summary CSV file
@login_required()
def workouts_summaries_email_view(request):
r = getrower(request.user)
if r.emailbounced:
message = "Please check your email address first. Email to this address bounced."
messages.error(request, message)
return HttpResponseRedirect(
reverse(r.defaultlandingpage,
kwargs = {
'id':str(w.id),
})
)
if request.method == 'POST':
form = DateRangeForm(request.POST)
if form.is_valid():
startdate = form.cleaned_data['startdate']
enddate = form.cleaned_data['enddate']
filename = 'rowsandall_workouts_{first}_{last}.csv'.format(
first=startdate,
last=enddate
)
df = dataprep.workout_summary_to_df(r,startdate=startdate,enddate=enddate)
df.to_csv(filename,encoding='utf-8')
res = myqueue(queuehigh,handle_sendemailsummary,
r.user.first_name,
r.user.last_name,
r.user.email,
filename,
emailbounced = r.emailbounced
)
messages.info(request,'The summary CSV file was sent to you per email')
else:
form = DateRangeForm()
return render(request,"export_workouts.html",
{
'form':form
})
# Get Workout CSV file and send it to user's email address
@login_required()
def workout_csvemail_view(request,id=0):
r = getrower(request.user)
w = get_workout(id)
if not checkworkoutuser(request.user,w):
raise PermissionDenied("Access denied")
rowdata = rdata(w.csvfilename)
code = str(uuid4())
filename = code+'.csv'
rowdate = rowdata.rowdatetime
starttimeunix = arrow.get(rowdate).timestamp
df = rowdata.df
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
df['TimeStamp (sec)'] = df['TimeStamp (sec)'] + starttimeunix
response = HttpResponse(df.to_csv())
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
response['Content-Type'] = 'application/octet-stream'
return response
# Get Workout CSV file and send it to user's email address
@login_required()
def workout_csvtoadmin_view(request,id=0):
message = ""
r = getrower(request.user)
w = get_workout(id)
csvfile = w.csvfilename
res = myqueue(queuehigh,
handle_sendemailcsv,
'Sander',
'Roosendaal',
'roosendaalsander@gmail.com',
csvfile)
successmessage = "The CSV file was sent to the site admin per email"
messages.info(request,successmessage)
url = reverse(workout_view,
kwargs = {
'id':str(w.id),
})
response = HttpResponseRedirect(url)
return response

1604
rowers/views/importviews.py Normal file

File diff suppressed because it is too large Load Diff

142
rowers/views/otherviews.py Normal file
View File

@@ -0,0 +1,142 @@
from statements import *
@login_required()
def deactivate_user(request):
pk = request.user.id
user = User.objects.get(pk=pk)
user_form = DeactivateUserForm(instance=user)
if request.user.is_authenticated() and request.user.id == user.id:
if request.method == "POST":
user_form = DeactivateUserForm(request.POST, instance=user)
if user_form.is_valid():
if not user_form.cleaned_data['is_active']:
r = Rower.objects.get(user=user)
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
try:
subscriptions = braintreestuff.find_subscriptions(r)
for subscription in subscriptions:
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
for message in themessages:
messages.info(request,message)
except ProcessorCustomerError:
pass
r.paidplan = None
r.teamplanexpires = timezone.now()
r.planexpires = timezone.now()
r.clubsize = 0
r.rowerplan = 'basic'
r.save()
deactivate_user = user_form.save(commit=False)
user.is_active = False
user.save()
deactivate_user.save()
# url = reverse(auth_views.logout_then_login)
url = '/logout/?next=/login'
return HttpResponseRedirect(url)
return render(request, "userprofile_deactivate.html", {
"user_form": user_form,
})
else:
raise PermissionDenied
@login_required()
def user_gdpr_optin(request):
r = getrower(request.user)
r.gdproptin = False
r.gdproptindate = None
r.save()
nexturl = request.GET.get('next','/rowers/list-workouts/')
if r.gdproptin:
return HttpResponseRedirect(nexturl)
return render(request,'gdpr_optin.html',{
"next": nexturl
})
@login_required()
def user_gdpr_confirm(request):
r = getrower(request.user)
r.gdproptin = True
r.gdproptindate = timezone.now()
r.save()
nexturl = request.GET.get('next','/rowers/list-workouts/')
return HttpResponseRedirect(nexturl)
@login_required()
def remove_user(request):
pk = request.user.id
user = User.objects.get(pk=pk)
user_form = DeleteUserForm(instance=user)
if request.user.is_authenticated() and request.user.id == user.id:
if request.method == "POST":
user_form = DeleteUserForm(request.POST,instance=user)
if user_form.is_valid():
cd = user_form.cleaned_data
name = user.first_name+' '+user.last_name
email = user.email
r = Rower.objects.get(user=user)
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
try:
subscriptions = braintreestuff.find_subscriptions(r)
for subscription in subscriptions:
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
for message in themessages:
messages.info(request,message)
except ProcessorCustomerError:
pass
if cd['delete_user']:
user.delete()
res = myqueue(queuehigh,
handle_sendemail_userdeleted,
name, email)
url = '/logout/?next=/login'
# url = reverse(auth_views.logout_then_login)
return HttpResponseRedirect(url)
return render(request, "userprofile_delete.html", {
"user_form": user_form,
})
else:
raise PermissionDenied
# Shows analysis page
@login_required()
def analysis_view(request,userid=0):
r = getrequestrower(request,userid=userid)
return render(request,
"analysis.html",
{
'active':'nav-analysis',
'rower':r,
}
)
# Shows laboratory page
@login_required()
def laboratory_view(request,userid=0):
r = getrequestrower(request,userid=userid)
return render(request,
"laboratory.html",
{
'active':'nav-analysis',
'rower':r,
}
)

View File

@@ -0,0 +1,559 @@
def paidplans_view(request):
if not request.user.is_anonymous():
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
else:
r = None
return render(request,
'paidplans.html',
{'rower':r})
@login_required()
def billing_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
if payments.is_existing_customer(r):
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
if request.method == 'POST':
billingaddressform = RowerBillingAddressForm(request.POST)
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
if billingaddressform.is_valid():
cd = billingaddressform.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
if billingaddressform.is_valid():
if planselectform.is_valid():
plan = planselectform.cleaned_data['plan']
try:
customer_id = braintreestuff.create_customer(r)
except ProcessorCustomerError:
messages.error(request,"Something went wrong registering you as a customer.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
url = reverse(payment_confirm_view,
kwargs={
'planid':plan.id
})
return HttpResponseRedirect(url)
else:
billingaddressform = RowerBillingAddressForm(instance=r)
planselectform = PlanSelectForm(paymentprocessor='braintree')
return render(request,
'billing.html',
{'rower':r,
'billingaddressform':billingaddressform,
'planselectform':planselectform,
})
@login_required()
def upgrade_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
if r.subscription_id is None or r.subscription_id == '':
url = reverse(billing_view)
return HttpResponseRedirect(url)
if request.method == 'POST':
billingaddressform = RowerBillingAddressForm(request.POST)
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
if billingaddressform.is_valid():
cd = billingaddressform.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
if planselectform.is_valid():
plan = planselectform.cleaned_data['plan']
if billingaddressform.is_valid():
url = reverse(upgrade_confirm_view,
kwargs={
'planid':plan.id
})
return HttpResponseRedirect(url)
else:
billingaddressform = RowerBillingAddressForm(instance=r)
planselectform = PlanSelectForm(paymentprocessor='braintree',
rower=r)
return render(request,
'upgrade.html',
{'rower':r,
'billingaddressform':billingaddressform,
'planselectform':planselectform,
})
@login_required()
def downgrade_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
if r.subscription_id is None or r.subscription_id == '':
url = reverse(billing_view)
return HttpResponseRedirect(url)
if request.method == 'POST':
billingaddressform = RowerBillingAddressForm(request.POST)
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
if billingaddressform.is_valid():
cd = billingaddressform.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
if planselectform.is_valid():
plan = planselectform.cleaned_data['plan']
if plan.price > r.paidplan.price:
nextview = upgrade_confirm_view
elif plan.price == r.paidplan.price:
messages.info(request,'You did not select a new plan')
url = reverse(downgrade_view)
return HttpResponseRedirect(url)
else:
nextview = downgrade_confirm_view
if billingaddressform.is_valid():
url = reverse(nextview,
kwargs={
'planid':plan.id
})
return HttpResponseRedirect(url)
else:
billingaddressform = RowerBillingAddressForm(instance=r)
planselectform = PlanSelectForm(paymentprocessor='braintree',
rower=r,includeall=True, initial={'plan':r.paidplan})
return render(request,
'downgrade.html',
{'rower':r,
'billingaddressform':billingaddressform,
'planselectform':planselectform,
})
@login_required()
def plan_stop_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
subscriptions = []
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
try:
subscriptions = braintreestuff.find_subscriptions(r)
except ProcessorCustomerError:
r.paymentprocessor = None
r.save()
return render(request,
'subscriptions_cancel.html',
{'rower':r,
'subscriptions':subscriptions
})
@login_required()
def plan_tobasic_view(request,id=0):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paidplan.paymentprocessor == 'braintree':
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
for message in themessages:
messages.info(request,message)
for message in errormessages:
messages.error(request,message)
url = reverse(plan_stop_view)
return HttpResponseRedirect(url)
@login_required()
def upgrade_confirm_view(request,planid = 0):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
try:
plan = PaidPlan.objects.get(id=planid)
except PaidPlan.DoesNotExist:
messages.error(request,"Something went wrong. Please try again.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
client_token = braintreestuff.get_client_token(r)
return render(request,
"upgradeconfirm.html",
{
'plan':plan,
'client_token':client_token,
'rower':r,
})
@login_required()
def downgrade_confirm_view(request,planid = 0):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
try:
plan = PaidPlan.objects.get(id=planid)
except PaidPlan.DoesNotExist:
messages.error(request,"Something went wrong. Please try again.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
r = getrequestrower(request)
client_token = braintreestuff.get_client_token(r)
return render(request,
"downgradeconfirm.html",
{
'plan':plan,
'client_token':client_token,
'rower':r,
})
@login_required()
def payment_confirm_view(request,planid = 0):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
try:
plan = PaidPlan.objects.get(id=planid)
except PaidPlan.DoesNotExist:
messages.error(request,"Something went wrong. Please try again.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
client_token = braintreestuff.get_client_token(r)
return render(request,
"paymentconfirm.html",
{
'plan':plan,
'client_token':client_token,
'rower':r,
})
@login_required()
def checkouts_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring':
messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed')
if request.method != 'POST':
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
form = BillingForm(request.POST)
if form.is_valid():
data = form.cleaned_data
success,amount = braintreestuff.create_subscription(r,data)
if success:
messages.info(request,"Your payment has succeeded and your plan has been updated")
url = "{baseurl}?amount={amount:.2f}".format(
baseurl = reverse(payment_completed_view),
amount = amount)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was a problem with your payment")
url = reverse(billing_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(billing_view)
return HttpResponseRedirect(url)
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
@login_required()
def upgrade_checkouts_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if request.method != 'POST':
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
form = BillingForm(request.POST)
if form.is_valid():
data = form.cleaned_data
success,amount = braintreestuff.update_subscription(r,data)
if success:
messages.info(request,"Your payment has succeeded and your plan has been updated")
url = "{baseurl}?amount={amount:.2f}".format(
baseurl = reverse(payment_completed_view),
amount = amount)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was a problem with your payment")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
@login_required()
def downgrade_checkouts_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if request.method != 'POST':
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
form = BillingForm(request.POST)
if form.is_valid():
data = form.cleaned_data
success = braintreestuff.update_subscription(r,data,method='down')
if success:
messages.info(request,"Your plan has been updated")
url = reverse(downgrade_completed_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was a problem with your transaction")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
@login_required()
def payment_completed_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
amount = request.GET.get('amount',0)
r = getrequestrower(request)
return render(request,
"payment_completed.html",
{
'rower':r,
'amount':amount,
})
@login_required()
def downgrade_completed_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
return render(request,
"downgrade_completed.html",
{
'rower':r
})
# User registration
def rower_register_view(request):
nextpage = request.GET.get('next','/rowers/list-workouts/')
if nextpage == '':
nextpage = '/rowers/list-workouts/'
if request.method == 'POST':
#form = RegistrationFormUniqueEmail(request.POST)
form = RegistrationFormSex(request.POST)
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
password = form.cleaned_data['password1']
username = form.cleaned_data['username']
sex = form.cleaned_data['sex']
birthdate = form.cleaned_data['birthdate']
weightcategory = form.cleaned_data['weightcategory']
adaptiveclass = form.cleaned_data['adaptiveclass']
nextpage = request.POST['next']
theuser = User.objects.create_user(username,password=password)
theuser.first_name = first_name
theuser.last_name = last_name
theuser.email = email
theuser.save()
birthdate = birthdate.replace(tzinfo=None)
therower = Rower(user=theuser,sex=sex,birthdate=birthdate,
weightcategory=weightcategory,
adaptiveclass=adaptiveclass)
therower.save()
# create default favorite charts
add_defaultfavorites(therower)
# Create Sample workout
f = 'media/testdata.csv.gz'
timestr = strftime("%Y%m%d-%H%M%S")
f2 = f[:-7]+timestr+'.csv.gz'
copyfile(f,f2)
response = dataprep.new_workout_from_file(therower,f2,
title='New User Sample Data',
notes='This is an example workout to get you started')
newworkoutid = response[0]
w = Workout.objects.get(id=newworkoutid)
w.startdatetime = timezone.now()
w.save()
# Create and send email
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
subject = "Thank you for registering on rowsandall.com"
from_address = 'Sander Roosendaal <info@rowsandall.com>'
d = {'first_name':theuser.first_name}
send_template_email(from_address,[fullemail],
subject,'registeremail.html',d)
subject2 = "New User"
message2 = "New user registered.\n"
message2 += fullemail + "\n"
message2 += "User name: "+username
send_mail(subject2, message2,
'Rowsandall Server <info@rowsandall.com>',
['roosendaalsander@gmail.com'])
theuser = authenticate(username=username,password=password)
login(request,theuser)
return HttpResponseRedirect(nextpage)
# '/rowers/register/thankyou/')
else:
return render(request,
"registration_form.html",
{'form':form,
'next':nextpage,})
else:
form = RegistrationFormSex()
return render(request,
"registration_form.html",
{'form':form,
'next':nextpage,})
@login_required()
def transactions_view(request):
if not request.user.is_staff:
raise PermissionDenied("Not Allowed")
if request.method == 'POST':
dateform = DateRangeForm(request.POST)
if dateform.is_valid():
startdate = dateform.cleaned_data['startdate']
enddate = dateform.cleaned_data['enddate']
df = braintreestuff.get_transactions(startdate,enddate)
filename="transactions_{s}_{e}.csv".format(s = startdate, e = enddate)
response = HttpResponse(df.to_csv())
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
response['Content-Type'] = 'application/octet-stream'
return response
else:
dateform = DateRangeForm()
return render(request,
'transactions.html',
{
'dateform':dateform
})

2575
rowers/views/planviews.py Normal file

File diff suppressed because it is too large Load Diff

2305
rowers/views/racesviews.py Normal file

File diff suppressed because it is too large Load Diff

1148
rowers/views/statements.py Normal file

File diff suppressed because it is too large Load Diff

536
rowers/views/teamviews.py Normal file
View File

@@ -0,0 +1,536 @@
from statements import *
@login_required()
def team_view(request,id=0,userid=0):
ismember = 0
hasrequested = 0
r = getrequestrower(request,userid=userid)
myteams, memberteams, otherteams = get_teams(request)
teams.remove_expired_invites()
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("Team doesn't exist")
if request.method == 'POST' and request.user == t.manager:
inviteform = TeamInviteForm(request.POST)
inviteform.fields['user'].queryset = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
if inviteform.is_valid():
cd = inviteform.cleaned_data
newmember = cd['user']
email = cd['email']
inviteid,text = teams.create_invite(t,t.manager,
user=newmember,
email=email)
if inviteid:
teams.send_invite_email(inviteid)
successmessage = text
messages.info(request,successmessage)
else:
message = text
messages.error(request,message)
elif request.user == t.manager:
inviteform = TeamInviteForm()
inviteform.fields['user'].queryset = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
else:
inviteform = ''
members = Rower.objects.filter(team=t).order_by('user__last_name','user__first_name')
thisteammyrequests = TeamRequest.objects.filter(team=t,user=request.user)
if len(thisteammyrequests):
hasrequested = 1
if r in members:
ismember = 1
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
},
{
'url':reverse(team_view,kwargs={'id':id}),
'name': t.name
}
]
return render(request, 'team.html',
{
'team':t,
'teams':get_my_teams(request.user),
'myteams':myteams,
'memberteams':memberteams,
'members':members,
'breadcrumbs':breadcrumbs,
'active':'nav-teams',
'inviteform':inviteform,
'ismember':ismember,
'hasrequested':hasrequested,
})
@login_required()
def team_leaveconfirm_view(request,id=0):
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("Team doesn't exist")
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
},
{
'url':reverse(team_view,kwargs={'id':id}),
'name': t.name
},
{
'url':reverse(team_leaveconfirm_view,kwargs={'id':id}),
'name': 'Leave'
}
]
return render(request,'teamleaveconfirm.html',
{
'team':t,
'teams':get_my_teams(request.user),
'myteams':myteams,
'memberteams':memberteams,
'otherteams':otherteams,
'active':'nav-teams',
'breadcrumbs':breadcrumbs,
})
@login_required()
def rower_calcdps_view(request):
r = getrower(request.user)
ws = [(w.id,w.csvfilename) for w in Workout.objects.filter(user=r)]
res = myqueue(queue,handle_updatedps,r.user.email,ws,debug=False,
emailbounced=r.emailbounced)
messages.info(request,"Your workouts are being updated in the background. You will receive email when this is done.")
url = reverse(workouts_view)
return HttpResponseRedirect(url)
@login_required()
def team_leave_view(request,id=0):
r = getrower(request.user)
teams.remove_member(id,r)
url = reverse(rower_teams_view)
response = HttpResponseRedirect(url)
return response
from rowers.forms import TeamInviteCodeForm
def get_teams(request):
r = Rower.objects.get(user=request.user)
myteams = Team.objects.filter(
manager=request.user).order_by('name')
memberteams = Team.objects.filter(
rower=r).exclude(manager=request.user).order_by('name')
otherteams = Team.objects.filter(
private='open').exclude(
rower=r).exclude(manager=request.user).order_by('name')
return myteams, memberteams, otherteams
@login_required()
def rower_teams_view(request,message='',successmessage=''):
if request.method == 'POST':
form = TeamInviteCodeForm(request.POST)
if form.is_valid():
code = form.cleaned_data['code']
res,text = teams.process_invite_code(request.user,code)
if res:
successmessage = text
else:
message = text
else:
form = TeamInviteCodeForm()
r = getrower(request.user)
ts = Team.objects.filter(rower=r)
myteams, memberteams, otherteams = get_teams(request)
teams.remove_expired_invites()
invites = TeamInvite.objects.filter(user=request.user)
requests = TeamRequest.objects.filter(user=request.user)
myrequests = TeamRequest.objects.filter(team__in=myteams)
myinvites = TeamInvite.objects.filter(team__in=myteams)
clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
max_clubsize = r.clubsize
messages.info(request,successmessage)
messages.error(request,message)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
}
]
return render(request, 'teams.html',
{
'teams':ts,
'active':'nav-teams',
'breadcrumbs':breadcrumbs,
'clubsize':clubsize,
'max_clubsize':max_clubsize,
'myteams':myteams,
'memberteams':memberteams,
'invites':invites,
'otherteams':otherteams,
'requests':requests,
'myrequests':myrequests,
'form':form,
'myinvites':myinvites,
})
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def invitation_revoke_view(request,id):
res,text = teams.revoke_invite(request.user,id)
if res:
messages.info(request,text)
successmessage = text
else:
message = text
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def manager_member_drop_view(request,teamid,userid,
message='',successmessage=''):
rower = Rower.objects.get(user__id=userid)
res, text = teams.mgr_remove_member(teamid,request.user,rower)
if res:
messages.info(request,text)
else:
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def manager_requests_view(request,code=None,message='',successmessage=''):
if code:
res,text = teams.process_request_code(request.user,code)
if res:
successmessage = text
message = ''
else:
message = text
successmessage = ''
messages.info(request,successmessage)
messages.error(request,message)
url = reverse(rower_teams_view,kwargs={
})
return HttpResponseRedirect(url)
@login_required()
def team_requestmembership_view(request,teamid,userid):
try:
t = Team.objects.get(id=teamid)
except Team.DoesNotExist:
raise Http404("Team doesn't exist")
res,text = teams.create_request(t,userid)
if res:
messages.info(request,text)
else:
messages.error(request,text)
url = reverse(team_view,kwargs={
'id':int(teamid),
})
return HttpResponseRedirect(url)
@login_required()
def request_revoke_view(request,id=0):
res,text = teams.revoke_request(request.user,id)
if res:
messages.info(request,text)
else:
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def request_reject_view(request,id=0):
res,text = teams.reject_request(request.user,id)
if res:
messages.info(request,text)
else:
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def invitation_reject_view(request,id=0):
res,text = teams.reject_invitation(request.user,id)
if res:
messages.info(request,text)
else:
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
@login_required()
def rower_invitations_view(request,code=None,message='',successmessage=''):
if code:
teams.remove_expired_invites()
res,text = teams.process_invite_code(request.user,code)
if res:
messages.info(request,text)
teamid=res
url = reverse(team_view,kwargs={
'id':teamid,
})
else:
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
url = reverse(rower_teams_view,kwargs={
})
return HttpResponseRedirect(url)
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def team_edit_view(request,id=0):
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("Team does not exist")
if request.method == 'POST':
teamcreateform = TeamForm(request.POST,instance=t)
if teamcreateform.is_valid():
cd = teamcreateform.cleaned_data
name = cd['name']
notes = cd['notes']
manager = request.user
private = cd['private']
viewing = cd['viewing']
res,message=teams.update_team(t,name,manager,private,notes,
viewing)
if res:
messages.info(request,message)
else:
messages.error(request,message)
url = reverse(team_view,
kwargs={
'id':int(id),
}
)
response = HttpResponseRedirect(url)
return response
else:
teamcreateform = TeamForm(instance=t)
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
},
{
'url':reverse(team_view,kwargs={'id':id}),
'name': t.name
},
{
'url':reverse(team_edit_view,kwargs={'id':id}),
'name': 'Edit'
}
]
return render(request,'teamedit.html',
{
'form':teamcreateform,
'teams':get_my_teams(request.user),
'myteams':myteams,
'memberteams':memberteams,
'otherteams':otherteams,
'active':'nav-teams',
'breadcrumbs':breadcrumbs,
'team':t,
})
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def team_create_view(request):
if request.method == 'POST':
teamcreateform = TeamForm(request.POST)
if teamcreateform.is_valid():
cd = teamcreateform.cleaned_data
name = cd['name']
notes = cd['notes']
manager = request.user
private = cd['private']
viewing = cd['viewing']
res,message=teams.create_team(name,manager,private,notes,
viewing)
url = reverse(rower_teams_view)
response = HttpResponseRedirect(url)
return response
else:
teamcreateform = TeamForm()
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
},
{
'url':reverse(team_create_view),
'name': "New Team"
},
]
return render(request,'teamcreate.html',
{
'teams':get_my_teams(request.user),
'form':teamcreateform,
'myteams':myteams,
'memberteams':memberteams,
'otherteams':otherteams,
'active':'nav-teams',
'breadcrumbs':breadcrumbs,
})
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def team_deleteconfirm_view(request,id):
r = getrower(request.user)
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("This team doesn't exist")
if t.manager != request.user:
raise PermissionDenied("You are not allowed to delete this team")
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
},
{
'url':reverse(team_view,kwargs={'id':id}),
'name': t.name
},
{
'url':reverse(team_deleteconfirm_view,kwargs={'id':id}),
'name': 'Leave'
}
]
return render(request,'teamdeleteconfirm.html',
{
'teams':get_my_teams(request.user),
'team':t,
'myteams':myteams,
'memberteams':memberteams,
'otherteams':otherteams,
'active':'nav-teams',
})
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def team_delete_view(request,id):
r = getrower(request.user)
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("This team doesn't exist")
if t.manager != request.user:
raise PermissionDenied("You are not allowed to delete this team")
teams.remove_team(t.id)
url = reverse(rower_teams_view)
response = HttpResponseRedirect(url)
return response
@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def team_members_stats_view(request,id):
r = getrower(request.user)
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("This team doesn't exist")
if t.manager != request.user:
raise PermissionDenied("You are not allowed to see this page")
members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")
theusers = [member.user for member in members]
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
'name': 'Teams'
},
{
'url':reverse(team_view,kwargs={'id':id}),
'name': t.name
},
{
'url':reverse(team_members_stats_view,kwargs={'id':id}),
'name': 'Members Stats'
}
]
response = render(request,'teamstats.html',
{
'teams':get_my_teams(request.user),
'myteams':myteams,
'memberteams':memberteams,
'otherteams':otherteams,
'active':'nav-teams',
'breadcrumbs':breadcrumbs,
'team':t,
'theusers':theusers,
})
return response

485
rowers/views/userviews.py Normal file
View File

@@ -0,0 +1,485 @@
from statements import *
@login_required()
def start_trial_view(request):
r = getrower(request.user)
if r.protrialexpires is not None:
messages.error(request,'You do not qualify for a trial')
url = '/rowers/paidplans'
return HttpResponseRedirect(url)
r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
r.save()
url = reverse(workouts_view)
messages.info(request,'We have started your 14 day trial period')
subject2 = "User started Pro Trial"
message2 = "User Started Pro Trial.\n"
message2 += request.user.email + "\n"
message2 += "User name: "+request.user.username
send_mail(subject2, message2,
'Rowsandall Server <info@rowsandall.com>',
['roosendaalsander@gmail.com'])
return HttpResponseRedirect(url)
@login_required()
def start_plantrial_view(request):
r = getrower(request.user)
if r.plantrialexpires is not None:
messages.error(request,'You do not qualify for a trial')
url = '/rowers/paidplans'
return HttpResponseRedirect(url)
r.plantrialexpires = datetime.date.today()+datetime.timedelta(13)
r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
r.save()
url = reverse(workouts_view)
messages.info(request,'We have started your 14 day trial period')
subject2 = "User started Plan Trial"
message2 = "User Started Plan Trial.\n"
message2 += request.user.email + "\n"
message2 += "User name: "+request.user.username
send_mail(subject2, message2,
'Rowsandall Server <info@rowsandall.com>',
['roosendaalsander@gmail.com'])
return HttpResponseRedirect(url)
# Page where user can manage his favorite charts
@login_required()
def rower_favoritecharts_view(request,userid=0):
message = ''
successmessage = ''
r = getrequestrower(request,userid=userid,notpermanent=True)
favorites = FavoriteChart.objects.filter(user=r).order_by('id')
aantal = len(favorites)
favorites_data = [{'yparam1':f.yparam1,
'yparam2':f.yparam2,
'xparam':f.xparam,
'plottype':f.plottype,
'workouttype':f.workouttype,
'reststrokes':f.reststrokes,
'notes':f.notes,}
for f in favorites]
FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=0)
if aantal==0:
FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1)
if request.method == 'POST':
favorites_formset = FavoriteChartFormSet(request.POST)
if favorites_formset.is_valid():
new_instances = []
for favorites_form in favorites_formset:
yparam1 = favorites_form.cleaned_data.get('yparam1')
yparam2 = favorites_form.cleaned_data.get('yparam2')
xparam = favorites_form.cleaned_data.get('xparam')
plottype = favorites_form.cleaned_data.get('plottype')
workouttype = favorites_form.cleaned_data.get('workouttype')
reststrokes = favorites_form.cleaned_data.get('reststrokes')
notes = favorites_form.cleaned_data.get('notes')
new_instances.append(FavoriteChart(user=r,
yparam1=yparam1,
yparam2=yparam2,
xparam=xparam,
plottype=plottype,
notes=notes,
workouttype=workouttype,
reststrokes=reststrokes))
try:
with transaction.atomic():
FavoriteChart.objects.filter(user=r).delete()
FavoriteChart.objects.bulk_create(new_instances)
successmessage = "You have updated your favorites"
messages.info(request,message)
if len(new_instances)==0:
FavoriteChartFormSet=formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1)
favorites_formset = FavoriteChartFormSet()
except IntegrityError:
message = "something went wrong"
messages.error(request,message)
else:
favorites_formset = FavoriteChartFormSet(initial=favorites_data)
context = {
'favorites_formset':favorites_formset,
'teams':get_my_teams(request.user),
'rower':r,
}
return render(request,'favoritecharts.html',context)
# page where user sets his export settings
@login_required()
def rower_exportsettings_view(request,userid=0):
r = getrequestrower(request,userid=userid)
if request.method == 'POST':
form = RowerExportForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
messages.info(request,'Settings saved')
else:
form = RowerExportForm(instance=r)
breadcrumbs = [
{
'url':'/rowers/me/edit/',
'name': 'Profile'
},
{
'url': reverse(rower_exportsettings_view),
'name': 'Export Settings'
}
]
return render(request, 'rower_exportsettings.html',
{'form':form,
'rower':r,
'breadcrumbs': breadcrumbs,
})
# Page where user can set his details
# Add email address to form so user can change his email address
@login_required()
def rower_edit_view(request,rowerid=0,userid=0,message=""):
r = getrequestrower(request,rowerid=rowerid,userid=userid,notpermanent=True)
rowerid = r.id
breadcrumbs = [
{
'url':'/rowers/me/edit/',
'name': 'Profile'
},
{
'url': reverse(rower_edit_view),
'name': 'Account Settings'
}
]
if request.method == 'POST':
accountform = AccountRowerForm(request.POST)
userform = UserForm(request.POST,instance=r.user)
if accountform.is_valid() and userform.is_valid():
# process
cd = accountform.cleaned_data
ucd = userform.cleaned_data
first_name = ucd['first_name']
last_name = ucd['last_name']
email = ucd['email']
sex = cd['sex']
adaptiveclass = cd['adaptiveclass']
defaultlandingpage = cd['defaultlandingpage']
weightcategory = cd['weightcategory']
birthdate = cd['birthdate']
showfavoritechartnotes = cd['showfavoritechartnotes']
getemailnotifications = cd['getemailnotifications']
getimportantemails = cd['getimportantemails']
defaulttimezone=cd['defaulttimezone']
u = r.user
if u.email != email and len(email):
resetbounce = True
else:
resetbounce = False
if len(first_name):
u.first_name = first_name
u.last_name = last_name
if len(email): ## and check_email_freeforuse(u,email):
u.email = email
resetbounce = True
u.save()
r.defaulttimezone=defaulttimezone
r.weightcategory = weightcategory
r.adaptiveclass = adaptiveclass
r.getemailnotifications = getemailnotifications
r.getimportantemails = getimportantemails
r.defaultlandingpage = defaultlandingpage
r.showfavoritechartnotes = showfavoritechartnotes
r.sex = sex
r.birthdate = birthdate
if resetbounce and r.emailbounced:
r.emailbounced = False
r.save()
accountform = AccountRowerForm(instance=r)
userform = UserForm(instance=u)
successmessage = 'Account Information changed'
messages.info(request,successmessage)
else:
accountform = AccountRowerForm(instance=r)
userform = UserForm(instance=r.user)
grants = AccessToken.objects.filter(user=request.user)
return render(request, 'rower_form.html',
{
'teams':get_my_teams(request.user),
'breadcrumbs':breadcrumbs,
'grants':grants,
'userform':userform,
'accountform':accountform,
'rower':r,
})
# Page where user can set his details
# Add email address to form so user can change his email address
@login_required()
def rower_prefs_view(request,userid=0,message=""):
r = getrequestrower(request,userid=userid,notpermanent=True)
rowerid = r.id
breadcrumbs = [
{
'url':'/rowers/me/edit/',
'name': 'Profile'
},
{
'url': reverse(rower_prefs_view),
'name': 'Zones'
}
]
form = RowerForm(instance=r)
powerform = RowerPowerForm(instance=r)
powerzonesform = RowerPowerZonesForm(instance=r)
if request.method == 'POST' and "ut2" in request.POST:
form = RowerForm(request.POST)
if form.is_valid():
# something
cd = form.cleaned_data
hrmax = cd['max']
ut2 = cd['ut2']
ut1 = cd['ut1']
at = cd['at']
tr = cd['tr']
an = cd['an']
rest = cd['rest']
r.max = max(min(hrmax,250),10)
r.ut2 = max(min(ut2,250),10)
r.ut1 = max(min(ut1,250),10)
r.at = max(min(at,250),10)
r.tr = max(min(tr,250),10)
r.an = max(min(an,250),10)
r.rest = max(min(rest,250),10)
r.save()
successmessage = "Your Heart Rate data were changed"
messages.info(request,successmessage)
elif request.method == 'POST' and "ftp" in request.POST:
powerform = RowerPowerForm(request.POST)
if powerform.is_valid():
cd = powerform.cleaned_data
hrftp = cd['hrftp']
if hrftp == 0:
hrftp = int((r.an+r.tr)/2.)
ftp = cd['ftp']
otwslack = cd['otwslack']
powerfrac = 100*np.array([r.pw_ut2,
r.pw_ut1,
r.pw_at,
r.pw_tr,r.pw_an])/r.ftp
r.ftp = max(min(ftp,650),50)
r.otwslack = max(min(otwslack,50),0)
ut2,ut1,at,tr,an = (r.ftp*powerfrac/100.).astype(int)
r.pw_ut2 = ut2
r.pw_ut1 = ut1
r.pw_at = at
r.pw_tr = tr
r.pw_an = an
r.hrftp = hrftp
r.save()
message = "FTP and/or OTW slack values changed."
messages.info(request,message)
elif request.method == 'POST' and "ut3name" in request.POST:
powerzonesform = RowerPowerZonesForm(request.POST)
if powerzonesform.is_valid():
cd = powerzonesform.cleaned_data
pw_ut2 = cd['pw_ut2']
pw_ut1 = cd['pw_ut1']
pw_at = cd['pw_at']
pw_tr = cd['pw_tr']
pw_an = cd['pw_an']
ut3name = cd['ut3name']
ut2name = cd['ut2name']
ut1name = cd['ut1name']
atname = cd['atname']
trname = cd['trname']
anname = cd['anname']
powerzones = [ut3name,ut2name,ut1name,atname,trname,anname]
r.pw_ut2 = pw_ut2
r.pw_ut1 = pw_ut1
r.pw_at = pw_at
r.pw_tr = pw_tr
r.pw_an = pw_an
r.powerzones = powerzones
r.save()
successmessage = "Your Power Zone data were changed"
messages.info(request,successmessage)
return render(request, 'rower_preferences.html',
{
'form':form,
'teams':get_my_teams(request.user),
'powerform':powerform,
'powerzonesform':powerzonesform,
'breadcrumbs':breadcrumbs,
'rower':r,
})
# Revoke an app that you granted access through the API.
# this views is called when you press a button on the User edit page
# the button is only there when you have granted access to an app
@login_required()
def rower_revokeapp_view(request,id=0):
try:
tokens = AccessToken.objects.filter(user=request.user,application=id)
refreshtokens = AccessToken.objects.filter(user=request.user,application=id)
for token in tokens:
token.revoke()
for token in refreshtokens:
token.revoke()
r = getrower(request.user)
form = RowerForm(instance=r)
powerform = RowerPowerForm(instance=r)
grants = AccessToken.objects.filter(user=request.user)
url = reverse(rower_edit_view)
return HttpResponseRedirect(url)
except AccessToken.DoesNotExist:
raise Http404("Access token doesn't exist")
@login_required()
def rower_update_empower_view(
request,
startdate=timezone.now()-datetime.timedelta(days=365),
enddate=timezone.now()
):
try:
r = getrower(request.user)
except Rower.DoesNotExist:
raise Http404("Rower doesn't exist")
if request.method == 'POST' and 'daterange' in request.POST:
dateform = DateRangeForm(request.POST)
if dateform.is_valid():
startdate = dateform.cleaned_data['startdate']
enddate = dateform.cleaned_data['enddate']
startdatestring = startdate.strftime('%Y-%m-%d')
enddatestring = enddate.strftime('%Y-%m-%d')
request.session['startdate'] = startdatestring
request.session['enddate'] = enddatestring
else:
dateform = DateRangeForm(initial={
'startdate':startdate,
'enddate':enddate,
})
if request.method == 'POST' and 'workouts' in request.POST:
form = WorkoutMultipleCompareForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
workouts = cd['workouts']
workoutdicts = []
for w in workouts:
if w.user != r:
message = "You can only alter your own workouts"
messages.error(request,message)
if 'x' in w.boattype and w.oarlength is not None and w.oarlength > 3.30:
message = "Oarlength and boat type mismatch for workout "+str(w.id)+". Skipping workout"
messages.error(request,message)
elif 'x' not in w.boattype and w.oarlength is not None and w.oarlength <= 3.30:
message = "Oarlength and boat type mismatch for workout "+str(w.id)+". Skipping workout"
messages.error(request,message)
elif w.oarlength is None:
message = "Incorrect oarlength in workout "+str(w.id)+". Skipping workout"
messages.error(request,message)
else:
workoutdict = {
'id':w.id,
'boattype':w.boattype,
'filename':w.csvfilename,
'inboard':w.inboard,
'oarlength':w.oarlength
}
workoutdicts.append(workoutdict)
w.workoutsource = 'speedcoach2corrected'
w.save()
job = myqueue(queuelow,handle_update_empower,
request.user.email,workoutdicts,
debug=False,
emailbounced=r.emailbounced)
try:
request.session['async_tasks'] += [(job.id,'update_empower')]
except KeyError:
request.session['async_tasks'] = [(job.id,'update_empower')]
successmessage = 'Your workouts are being updated in the background. You will receive email when this is done. You can check the status of your calculations <a href="/rowers/jobs-status" target="_blank">here</a>'
messages.info(request,successmessage)
url = reverse(workouts_view)
return HttpResponseRedirect(url)
else:
workouts = Workout.objects.filter(
startdatetime__gte=startdate,
startdatetime__lte=enddate,
workoutsource='speedcoach2',
user=r,
).order_by("-date","-starttime")
form = WorkoutMultipleCompareForm()
form.fields["workouts"].queryset = workouts
# GET request = prepare form
return render(request, 'empower_fix.html',
{'workouts':workouts,
'active': 'nav-workouts',
'dateform':dateform,
'form':form,
'rower':r
})

5407
rowers/views/workoutviews.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14442,12 +14442,6 @@ def plannedsession_teamcreate_view(request,
request.user,request.POST
)
print sessioncreateform.is_valid(),'sessioncreateform'
print sessioncreateform.errors,'errors'
print sessionteamselectform.is_valid(),'teamselectform'
print sessionteamselectform.errors,'errors'
raise ValueError
if sessioncreateform.is_valid() and sessionteamselectform.is_valid():
cd = sessioncreateform.cleaned_data
startdate = cd['startdate']