from rowers.views.statements import * from rowers.rower_rules import user_is_not_basic, user_is_coachee from rowers.tokens import create_token from rowers.forms import DeepWaterLoginForm from django.contrib.auth import get_user import jwt def deepwatertoken_login(request): # Check if user is already authenticated if request.user.is_authenticated: user = request.user elif request.method == 'POST': username = request.POST.get('username', '') password = request.POST.get('password', '') user = authenticate(request, username=username, password=password) else: redirect_url = request.GET.get('redirect', settings.DEEP_WATER_URL) return render(request, "deepwaterlogin.html") if user is None: messages.error(request, 'Invalid credentials') return render(request, 'deepwaterlogin.html') # Generate token (same as before) payload = { 'user_id': user.id, 'username': user.username, 'email': user.email, 'exp': timezone.now() + datetime.timedelta(days=1), 'iat': timezone.now(), } token = jwt.encode(payload, settings.DEEP_WATER_SECRET_KEY, algorithm='HS256') # Redirect with token redirect_url = request.GET.get('redirect', settings.DEEP_WATER_URL) return HttpResponseRedirect(f"{redirect_url}?token={token}") @login_required() def get_deepwater_token(request): payload = { 'user_id': request.user.id, 'username': request.user.username, 'email': request.user.email, 'exp': timezone.now() + datetime.timedelta(days=1), # Token valid for 1 day 'iat': timezone.now(), } token = jwt.encode(payload, settings.DEEP_WATER_SECRET_KEY, algorithm='HS256') return JsonResponse({'token': token}) @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': # pragma: no cover 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 = 10 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: # pragma: no cover 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: # pragma: no cover 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': # pragma: no cover 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: pass if cd['delete_user']: # delete workouts Workout.objects.filter(user=user.rower).delete() # delete planned sessions PlannedSession.objects.filter(manager=user).delete() user.delete() _ = 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: # pragma: no cover raise PermissionDenied @login_required() def survey(request): # pragma: no cover r = getrower(request.user) surveyform = SurveyForm() if request.method == 'POST': r.surveydone = True r.surveydonedate = timezone.now() r.save() nexturl = request.GET.get('next') return HttpResponseRedirect(nexturl) context = { 'teams': get_my_teams(request.user), 'rower': r, 'form': surveyform, } return render(request, 'survey.html', context) @login_required() def start_trial_view(request): r = getrower(request.user) if not can_start_trial(request.user): # pragma: no cover messages.error(request, 'You do not qualify for a trial') url = '/rowers/paidplans' return HttpResponseRedirect(url) r.protrialexpires = timezone.now()+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 ', ['roosendaalsander@gmail.com']) send_template_email('Rowsandall ', [r.user.email], 'Welcome to the Rowsandall Pro Trial', 'protrialewelcome.html', {'first_name': r.user.first_name, 'last_name': r.user.last_name}) return HttpResponseRedirect(url) @login_required() def user_messages_delete_all(request, userid=0): r = getrower(request.user) usermessages = UserMessage.objects.filter(receiver=r) for m in usermessages: m.delete() messages.info(request,"Messages Deleted") url = reverse('user_messages') return HttpResponseRedirect(url) @login_required() @permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) def user_messages(request,userid=0): r = getrequestrowercoachee(request, userid=userid, notpermanent=True) usermessages = UserMessage.objects.filter(receiver=r).order_by('-datetime') return render(request,'user_messages.html', {'usermessages':usermessages, 'rower':r}) @login_required() def user_message_delete(request,id=0): # pragma: no cover try: msg = UserMessage.objects.get(id=id) except UserMessage.DoesNotExist: messages.error(request,'Could not find this message') url = reverse('user_messages') return HttpResponseRedirect(url) if msg.receiver == request.user.rower: msg.delete() messages.info(request,'Deleted message {id}'.format(id=id)) else: messages.error(request,'You are not allowed to delete this message') url = reverse('user_messages') return HttpResponseRedirect(url) @login_required() def user_message_markread(request,id=0): # pragma: no cover try: msg = UserMessage.objects.get(id=id) except UserMessage.DoesNotExist: pass if msg.receiver == request.user.rower: msg.isread = True msg.save() messages.info(request,'Marked message {id} read'.format(id=id)) else: messages.error('You are not allowed to change this message') url = reverse('user_messages') return HttpResponseRedirect(url) # Page where user can manage his favorite charts @login_required() @permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) def rower_favoritecharts_view(request, userid=0): message = '' r = getrequestrowercoachee(request, userid=userid, notpermanent=True) staticchartform = StaticChartRowerForm(instance=r) datasettingsform = DataRowerForm(instance=r) xparam = 'time' yparam1 = 'pace' yparam2 = 'power' yparam3 = 'hr' yparam4 = 'spm' xparam = r.chartstacktemplate_x yparam1 = r.chartstacktemplate_y[0] yparam2 = r.chartstacktemplate_y[1] yparam3 = r.chartstacktemplate_y[2] yparam4 = r.chartstacktemplate_y[3] initial = { 'xaxis': xparam, 'yaxis1': yparam1, 'yaxis2': yparam2, 'yaxis3': yparam3, 'yaxis4': yparam4, } stackedchartform = StravaChartForm(request, initial=initial) 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) workoutnametemplate = r.workoutnametemplate WorkoutNameTemplateFormSet = formset_factory(WorkoutNameTemplateElement, extra=1) workoutnametemplate_data = [{'element': element} for element in r.workoutnametemplate] workoutnametemplate_formset = WorkoutNameTemplateFormSet(initial=workoutnametemplate_data, prefix='workoutname') if request.method == 'POST' and 'yaxis4' in request.POST: stackedchartform = StravaChartForm(request, request.POST) if stackedchartform.is_valid(): r.chartstacktemplate_x = stackedchartform.cleaned_data.get('xaxis') r.chartstacktemplate_y = [stackedchartform.cleaned_data.get('yaxis1'), stackedchartform.cleaned_data.get('yaxis2'), stackedchartform.cleaned_data.get('yaxis3'), stackedchartform.cleaned_data.get('yaxis4')] r.save() messages.info(request, "We have updated your stacked chart settings") if request.method == 'POST' and 'workoutname-TOTAL_FORMS' in request.POST: if 'defaults_workoutname' in request.POST: r.workoutnametemplate = ['date','name','distance','ownerfirst','ownerlast','duration','boattype','workouttype'] r.save() else: workoutnametemplate_formset = WorkoutNameTemplateFormSet(request.POST, prefix='workoutname') newworkoutnametemplate = [] if workoutnametemplate_formset.is_valid(): for form in workoutnametemplate_formset: element = form.cleaned_data.get('element') if element != 'None': newworkoutnametemplate.append(element) newworkoutnametemplate = [i for i in newworkoutnametemplate if i is not None] r.workoutnametemplate = newworkoutnametemplate try: r.save() except IntegrityError: messages.error("Something went wrong") workoutnametemplate_data = [{'element': element} for element in r.workoutnametemplate] workoutnametemplate_formset = WorkoutNameTemplateFormSet(initial=workoutnametemplate_data, prefix='workoutname') if request.method == 'POST' and 'staticgrids' in request.POST: # pragma: no cover staticchartform = StaticChartRowerForm(request.POST, instance=r) if staticchartform.is_valid(): r.staticgrids = staticchartform.cleaned_data.get('staticgrids') r.slowpaceerg = staticchartform.cleaned_data.get('slowpaceerg') r.fastpaceerg = staticchartform.cleaned_data.get('fastpaceerg') r.slowpaceotw = staticchartform.cleaned_data.get('slowpaceotw') r.fastpaceotw = staticchartform.cleaned_data.get('fastpaceotw') r.staticchartonupload = staticchartform.cleaned_data.get( 'staticchartonupload') r.fav_analysis = staticchartform.cleaned_data.get('fav_analysis') r.usersmooth = staticchartform.cleaned_data.get('usersmooth') r.save() if request.method == 'POST' and 'save_data' in request.POST: # pragma: no cover datasettingsform = DataRowerForm(request.POST, instance=r) if datasettingsform.is_valid(): cd = datasettingsform.cleaned_data r.autojoin = cd.get('autojoin') r.dosmooth = cd.get('dosmooth') r.erg_recalculatepower = cd.get('erg_recalculatepower') r.save() messages.info(request, "We have updated your data settings") if request.method == 'POST' and 'defaults_data' in request.POST: # pragma: no cover defaultsmooth = Rower._meta.get_field('dosmooth').get_default() defaultautojoin = Rower._meta.get_field('autojoin').get_default() defaultergcalcpower = Rower._meta.get_field( 'erg_recalculatepower').get_default() r.dosmooth = defaultsmooth r.autojoin = defaultautojoin r.erg_recalculatepower = defaultergcalcpower r.save() datasettingsform = DataRowerForm(instance=r) messages.info( request, "We have reset your data settings to the default values") if request.method == 'POST' and 'form-TOTAL_FORMS' in request.POST: # pragma: no cover 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) 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, 'stackedchartform': stackedchartform, 'staticchartform': staticchartform, 'datasettingsform': datasettingsform, 'workoutnametemplate_formset': workoutnametemplate_formset, } return render(request, 'favoritecharts.html', context) # page where user sets his export settings @login_required() def rower_exportsettings_view(request, userid=0): attrtokens = { 'polar_auto_import': 'polartoken', 'c2_auto_export': 'c2token', 'c2_auto_import': 'c2token', 'sporttracks_auto_export': 'sporttrackstoken', 'strava_auto_export': 'stravatoken', 'strava_auto_import': 'stravatoken', 'strava_auto_delete': 'stravatoken', 'trainingpeaks_auto_export': 'tptoken', 'rp3_auto_import': 'rp3token', 'rp3_use_split_power': 'rp3token', 'nk_auto_import': 'nktoken', 'intervals_auto_export': 'intervals_token', 'intervals_resample_to_1s': 'intervals_token', } r = getrequestrowercoachee(request, userid=userid) forms = { 'polar': RowerExportFormPolar(instance=r), 'c2': RowerExportFormConcept2(instance=r), 'sporttracks': RowerExportFormSportTracks(instance=r), 'strava': RowerExportFormStrava(instance=r), 'trainingpeaks': RowerExportFormTrainingPeaks(instance=r), 'rp3': RowerExportFormRP3(instance=r), 'intervals': RowerExportFormIntervals(instance=r), 'nk': RowerExportFormNK(instance=r), 'imports_are_private': RowerPrivateImportForm(instance=r) } if request.method == 'POST': form = RowerExportForm(request.POST) forms = { 'polar': RowerExportFormPolar(request.POST, instance=r), 'c2': RowerExportFormConcept2(request.POST, instance=r), 'sporttracks': RowerExportFormSportTracks(request.POST, instance=r), 'strava': RowerExportFormStrava(request.POST, instance=r), 'trainingpeaks': RowerExportFormTrainingPeaks(request.POST, instance=r), 'rp3': RowerExportFormRP3(request.POST, instance=r), 'intervals': RowerExportFormIntervals(request.POST, instance=r), 'nk': RowerExportFormNK(request.POST, instance=r), 'imports_are_private': RowerPrivateImportForm(request.POST, instance=r), } if form.is_valid(): cd = form.cleaned_data for attr, value in cd.items(): try: tokenname = attrtokens[attr] if (getattr(r, tokenname) == '' or getattr(r, tokenname) is None) and value: messages.error( request, 'Set '+attr+' but it will not be effective until you create a connection.' ) except KeyError: pass 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' } ] grants = AccessToken.objects.filter(user=request.user) try: apikey = APIKey.objects.get(user=request.user) except APIKey.DoesNotExist: apikey = APIKey.objects.create(user=request.user) apps = Application.objects.filter(user=request.user) return render(request, 'rower_exportsettings.html', {'form': form, 'forms': forms, 'rower': r, 'breadcrumbs': breadcrumbs, 'grants': grants, 'apikey': apikey.key, 'apps': apps, }) # Page where user can set his details # Add email address to form so user can change his email address @login_required() @permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) def rower_edit_view(request, rowerid=0, userid=0, message=""): r = getrequestrowercoachee( request, rowerid=rowerid, userid=userid, notpermanent=True) if 'courseshare' in request.GET: # pragma: no cover courseshare = request.GET.get('courseshare', "ok") if courseshare == 'true': r.share_course_results = True r.save() elif courseshare == 'false': r.share_course_results = False r.save() 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, instance=r) userform = UserForm(request.POST, instance=r.user) privateform = RowerPrivateImportForm(request.POST, instance=r) if accountform.is_valid() and userform.is_valid() and privateform.is_valid(): # process cd = accountform.cleaned_data ucd = userform.cleaned_data pcd = privateform.cleaned_data first_name = ucd['first_name'] last_name = ucd['last_name'] email = ucd['email'] sex = cd['sex'] try: offercoaching = cd['offercoaching'] except KeyError: # pragma: no cover offercoaching = False autojoin = cd['autojoin'] adaptiveclass = cd['adaptiveclass'] defaultlandingpage = cd['defaultlandingpage'] weightcategory = cd['weightcategory'] birthdate = cd['birthdate'] showfavoritechartnotes = cd['showfavoritechartnotes'] getemailnotifications = cd['getemailnotifications'] getimportantemails = cd['getimportantemails'] get_rpe_warnings = cd['get_rpe_warnings'] share_course_results = cd['share_course_results'] defaulttimezone = cd['defaulttimezone'] fav_analysis = cd['fav_analysis'] usersmooth = cd['usersmooth'] u = r.user if u.email != email and len(email): # pragma: no cover 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 emailalternatives = cd['emailalternatives'] imports_are_private = pcd['imports_are_private'] u.save() r.defaulttimezone = defaulttimezone r.weightcategory = weightcategory r.adaptiveclass = adaptiveclass r.getemailnotifications = getemailnotifications r.getimportantemails = getimportantemails r.offercoaching = offercoaching r.defaultlandingpage = defaultlandingpage r.showfavoritechartnotes = showfavoritechartnotes r.share_course_results = share_course_results r.imports_are_private = imports_are_private r.sex = sex r.birthdate = birthdate r.autojoin = autojoin r.get_rpe_warnings = cd['get_rpe_warnings'] r.emailalternatives = emailalternatives r.fav_analysis = fav_analysis r.usersmooth = usersmooth if resetbounce and r.emailbounced: # pragma: no cover r.emailbounced = False r.save() accountform = AccountRowerForm(instance=r) userform = UserForm(instance=u) privateform = RowerPrivateImportForm(instance=r) successmessage = 'Account Information changed' messages.info(request, successmessage) else: accountform = AccountRowerForm(instance=r) userform = UserForm(instance=r.user) privateform = RowerPrivateImportForm(instance=r) grants = AccessToken.objects.filter(user=request.user) try: apikey = APIKey.objects.get(user=request.user) except APIKey.DoesNotExist: apikey = APIKey.objects.create(user=request.user) return render(request, 'rower_form.html', { 'teams': get_my_teams(request.user), 'breadcrumbs': breadcrumbs, 'grants': grants, 'userform': userform, 'accountform': accountform, 'privateform': privateform, 'rower': r, 'apikey': apikey.key, }) @login_required() def rower_regenerate_apikey(request): try: referer = request.META['HTTP_REFERER'] except KeyError: referer = '/rowers/me/edit/' try: apikey = APIKey.objects.get(user=request.user) except APIKey.DoesNotExist: apikey = APIKey.objects.create(user=request.user) apikey.regenerate_key() return HttpResponseRedirect(referer) #simple initial settings page @login_required() @permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) def rower_simpleprefs_view(request, userid=0): r = getrequestrowercoachee(request, userid=userid, notpermanent=True) firsttime = False if not r.ftpset: # pragma: no cover r.ftpset = True r.save() firsttime = True breadcrumbs = [ { 'url': '/rowers/me/edit/', 'name': 'Profile' }, { 'url': reverse('rower_simpleprefs_view'), 'name': 'Zones' } ] form = SimpleRowerPowerForm(instance=r) if request.method == 'POST': # pragma: no cover form = SimpleRowerPowerForm(request.POST, instance=r) if form.is_valid(): form.save(commit=True) messages.info(request,'FTP and OTW FTP saved') if firsttime: nexturl = request.GET.get('next', '/rowers/list-workouts/') return HttpResponseRedirect(nexturl) return render(request, 'rower_simplepreferences.html', { 'form': form, 'teams': get_my_teams(request.user), 'breadcrumbs': breadcrumbs, 'rower': r, }) # Page where user can set his details # Add email address to form so user can change his email address @login_required() @permission_required('rower.is_coach', fn=get_user_by_userid, raise_exception=True) def rower_prefs_view(request, userid=0, message=""): r = getrequestrowercoachee(request, userid=userid, notpermanent=True) breadcrumbs = [ { 'url': '/rowers/me/edit/', 'name': 'Profile' }, { 'url': reverse('rower_prefs_view'), 'name': 'Zones' } ] form = RowerHRZonesForm(instance=r) powerform = RowerPowerForm(instance=r) powerzonesform = RowerPowerZonesForm(instance=r) cpform = RowerCPForm(instance=r) if request.method == 'POST' and "ut2" in request.POST: form = RowerHRZonesForm(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'] hrrestname = cd['hrrestname'] hrut2name = cd['hrut2name'] hrut1name = cd['hrut1name'] hratname = cd['hratname'] hrtrname = cd['hrtrname'] hranname = cd['hranname'] hrmaxname = cd['hrmaxname'] hrzones = [hrrestname, hrut2name, hrut1name, hratname, hrtrname, hranname, hrmaxname] 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.hrzones = hrzones 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, instance=r) if powerform.is_valid(): powerform.save(commit=True) cd = powerform.cleaned_data hrftp = cd['hrftp'] if hrftp == 0: # pragma: no cover hrftp = int((r.an+r.tr)/2.) cogganzones = cd['cogganzones'] powerfrac = 100*np.array([r.pw_ut2, r.pw_ut1, r.pw_at, r.pw_tr, r.pw_an])/r.ftp if cogganzones: # pragma: no cover powerfrac = np.array([55.,75.,90.,105.,120.]) powerzones = ['Rest', 'Active Recovery', 'Endurance', 'Tempo', 'Threshold', 'Anaerobic'] r.powerzones = powerzones 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() powerzonesform = RowerPowerZonesForm(instance=r) 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) elif request.method == 'POST' and 'cprange' in request.POST: # pragma: no cover cpform = RowerCPForm(request.POST) if cpform.is_valid(): cd = cpform.cleaned_data cprange = cd['cprange'] kfit = cd['kfit'] kfatigue = cd['kfatigue'] r.cprange = cprange r.kfit = kfit r.kfatigue = kfatigue r.save() messages.info(request, 'Updated CP range and time decay constants') _ = dataprep.update_rolling_cp(r, mytypes.otwtypes, 'water') _ = dataprep.update_rolling_cp(r, mytypes.otetypes, 'erg') return render(request, 'rower_preferences.html', { 'form': form, 'teams': get_my_teams(request.user), 'powerform': powerform, 'powerzonesform': powerzonesform, 'breadcrumbs': breadcrumbs, 'cpform': cpform, '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): # pragma: no cover 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() ): # pragma: no cover 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 here' 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 })