Private
Public Access
1
0

initial version of form working

This commit is contained in:
Sander Roosendaal
2019-11-05 18:14:43 +01:00
parent ee69d6b537
commit 4904db724f
4 changed files with 209 additions and 155 deletions

View File

@@ -51,6 +51,11 @@ class FlexibleDecimalField(forms.DecimalField):
value = value.replace('.', '').replace(',', '.') value = value.replace('.', '').replace(',', '.')
return super(FlexibleDecimalField, self).to_python(value) return super(FlexibleDecimalField, self).to_python(value)
# Video Analysis creation form
class VideoAnalysisCreateForm(forms.Form):
url = forms.CharField(max_length=255,required=True,label='YouTube Video URL')
delay = forms.IntegerField(initial=0,label='Delay (seconds)')
# BillingForm form # BillingForm form
class BillingForm(forms.Form): class BillingForm(forms.Form):
amount = FlexibleDecimalField(required=True,decimal_places=2, amount = FlexibleDecimalField(required=True,decimal_places=2,
@@ -59,7 +64,7 @@ class BillingForm(forms.Form):
payment_method_nonce = forms.CharField(max_length=255,required=True) payment_method_nonce = forms.CharField(max_length=255,required=True)
paymenttype = forms.CharField(max_length=255,required=True) paymenttype = forms.CharField(max_length=255,required=True)
tac= forms.BooleanField(required=True,initial=False) tac= forms.BooleanField(required=True,initial=False)
# login form # login form
class LoginForm(forms.Form): class LoginForm(forms.Form):
@@ -73,8 +78,8 @@ class SearchForm(forms.Form):
attrs={'placeholder': 'keyword or leave empty'}), attrs={'placeholder': 'keyword or leave empty'}),
label='Filter by Keyword') label='Filter by Keyword')
# simple form for Contact page. Sends email to info@rowsandall.com # simple form for Contact page. Sends email to info@rowsandall.com
class EmailForm(forms.Form): class EmailForm(forms.Form):
firstname = forms.CharField(max_length=255) firstname = forms.CharField(max_length=255)
@@ -107,7 +112,7 @@ class MetricsForm(forms.Form):
avghr = forms.IntegerField(required=False,label='Average Heart Rate') avghr = forms.IntegerField(required=False,label='Average Heart Rate')
avgpwr = forms.IntegerField(required=False,label='Average Power') avgpwr = forms.IntegerField(required=False,label='Average Power')
avgspm = forms.FloatField(required=False,label='Average SPM') avgspm = forms.FloatField(required=False,label='Average SPM')
# Upload the CrewNerd Summary CSV # Upload the CrewNerd Summary CSV
class CNsummaryForm(forms.Form): class CNsummaryForm(forms.Form):
file = forms.FileField(required=True,validators=[must_be_csv]) file = forms.FileField(required=True,validators=[must_be_csv])
@@ -120,7 +125,7 @@ class SummaryStringForm(forms.Form):
class TeamInviteCodeForm(forms.Form): class TeamInviteCodeForm(forms.Form):
code = forms.CharField(max_length=10,label='Team Code', code = forms.CharField(max_length=10,label='Team Code',
) )
# Used for testing the POST API for StrokeData # Used for testing the POST API for StrokeData
class StrokeDataForm(forms.Form): class StrokeDataForm(forms.Form):
strokedata = forms.CharField(label='payload',widget=forms.Textarea) strokedata = forms.CharField(label='payload',widget=forms.Textarea)
@@ -133,7 +138,7 @@ class ImageForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
from django.forms.widgets import HiddenInput from django.forms.widgets import HiddenInput
super(ImageForm, self).__init__(*args, **kwargs) super(ImageForm, self).__init__(*args, **kwargs)
# The form used for uploading images # The form used for uploading images
class CourseForm(forms.Form): class CourseForm(forms.Form):
@@ -147,9 +152,9 @@ class CourseForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
from django.forms.widgets import HiddenInput from django.forms.widgets import HiddenInput
super(CourseForm, self).__init__(*args, **kwargs) super(CourseForm, self).__init__(*args, **kwargs)
# The form used for uploading files # The form used for uploading files
class DocumentsForm(forms.Form): class DocumentsForm(forms.Form):
title = forms.CharField(required=False) title = forms.CharField(required=False)
file = forms.FileField(required=False, file = forms.FileField(required=False,
@@ -157,7 +162,7 @@ class DocumentsForm(forms.Form):
workouttype = forms.ChoiceField(required=True, workouttype = forms.ChoiceField(required=True,
choices=Workout.workouttypes) choices=Workout.workouttypes)
boattype = forms.ChoiceField(required=True, boattype = forms.ChoiceField(required=True,
choices=mytypes.boattypes, choices=mytypes.boattypes,
label = "Boat Type") label = "Boat Type")
@@ -181,7 +186,7 @@ from rowers.utils import (
defaultleft,defaultmiddle defaultleft,defaultmiddle
) )
# Form to change Workflow page layout # Form to change Workflow page layout
class WorkFlowLeftPanelForm(forms.Form): class WorkFlowLeftPanelForm(forms.Form):
@@ -212,14 +217,14 @@ class WorkFlowLeftPanelForm(forms.Form):
self.base_fields['leftpanel'].initial=panels self.base_fields['leftpanel'].initial=panels
else: else:
panels = defaultleft panels = defaultleft
super(WorkFlowLeftPanelForm,self).__init__(*args, **kwargs) super(WorkFlowLeftPanelForm,self).__init__(*args, **kwargs)
class WorkFlowMiddlePanelForm(forms.Form): class WorkFlowMiddlePanelForm(forms.Form):
panels = defaultmiddle panels = defaultmiddle
middlepanel = forms.MultipleChoiceField( middlepanel = forms.MultipleChoiceField(
label='', label='',
@@ -237,7 +242,7 @@ class WorkFlowMiddlePanelForm(forms.Form):
# 'css/uid-manage-form.css'], # 'css/uid-manage-form.css'],
} }
js = ['/admin/jsi18n/'] js = ['/admin/jsi18n/']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
if 'instance' in kwargs: if 'instance' in kwargs:
r = kwargs.pop('instance') r = kwargs.pop('instance')
@@ -245,7 +250,7 @@ class WorkFlowMiddlePanelForm(forms.Form):
self.base_fields['middlepanel'].initial=panels self.base_fields['middlepanel'].initial=panels
else: else:
panels = defaultmiddle panels = defaultmiddle
super(WorkFlowMiddlePanelForm,self).__init__(*args, **kwargs) super(WorkFlowMiddlePanelForm,self).__init__(*args, **kwargs)
class WorkFlowLeftPanelElement(forms.Form): class WorkFlowLeftPanelElement(forms.Form):
@@ -265,8 +270,8 @@ class WorkFlowMiddlePanelElement(forms.Form):
choices=panelchoices, choices=panelchoices,
initial='None', initial='None',
) )
# The form to indicate additional actions to be performed immediately # The form to indicate additional actions to be performed immediately
# after a successful upload # after a successful upload
@@ -359,7 +364,7 @@ class TeamUploadOptionsForm(forms.Form):
class Meta: class Meta:
fields = ['make_plot','plottype'] fields = ['make_plot','plottype']
# This form is used on the Workout Split page # This form is used on the Workout Split page
class WorkoutSplitForm(forms.Form): class WorkoutSplitForm(forms.Form):
splitchoices = ( splitchoices = (
@@ -386,7 +391,7 @@ class WorkoutSplitForm(forms.Form):
label='Split Mode', label='Split Mode',
choices=splitchoices, choices=splitchoices,
widget = forms.CheckboxSelectMultiple()) widget = forms.CheckboxSelectMultiple())
# This form is used on the Analysis page to add a custom distance/time # This form is used on the Analysis page to add a custom distance/time
# trial and predict the pace # trial and predict the pace
from rowers.utils import rankingdistances,rankingdurations from rowers.utils import rankingdistances,rankingdurations
@@ -427,14 +432,14 @@ class PredictedPieceForm(forms.Form):
choices=rankingdistancechoices,initial=rankingdistances, choices=rankingdistancechoices,initial=rankingdistances,
label='Ranking Distances' label='Ranking Distances'
) )
trankingdurations = forms.MultipleChoiceField( trankingdurations = forms.MultipleChoiceField(
required=True, required=True,
choices=rankingdurationchoices, choices=rankingdurationchoices,
initial=[a for a,b in rankingdurationchoices], initial=[a for a,b in rankingdurationchoices],
label='Ranking Durations' label='Ranking Durations'
) )
value = forms.FloatField(initial=10,label='Free ranking piece (minutes)') value = forms.FloatField(initial=10,label='Free ranking piece (minutes)')
pieceunit = forms.ChoiceField(required=True,choices=unitchoices, pieceunit = forms.ChoiceField(required=True,choices=unitchoices,
initial='t',label='Unit') initial='t',label='Unit')
@@ -451,17 +456,17 @@ class PredictedPieceFormNoDistance(forms.Form):
thetuple = (timestr,timestr) thetuple = (timestr,timestr)
rankingdurationchoices.append(thetuple) rankingdurationchoices.append(thetuple)
trankingdurations = forms.MultipleChoiceField( trankingdurations = forms.MultipleChoiceField(
required=True, required=True,
choices=rankingdurationchoices, choices=rankingdurationchoices,
initial=[a for a,b in rankingdurationchoices], initial=[a for a,b in rankingdurationchoices],
label='Ranking Durations' label='Ranking Durations'
) )
value = forms.FloatField(initial=10,label='Free ranking piece') value = forms.FloatField(initial=10,label='Free ranking piece')
# On the Geeky side, to update stream information for river dwellers # On the Geeky side, to update stream information for river dwellers
class UpdateStreamForm(forms.Form): class UpdateStreamForm(forms.Form):
unitchoices = ( unitchoices = (
@@ -545,16 +550,16 @@ class FitnessMetricForm(forms.Form):
('rower','indoor rower'), ('rower','indoor rower'),
('water','on the water') ('water','on the water')
) )
mode = forms.ChoiceField(required=True, mode = forms.ChoiceField(required=True,
choices=modechoices, choices=modechoices,
initial='rower', initial='rower',
label='Workout Mode' label='Workout Mode'
) )
class Meta: class Meta:
fields = ['startdate','enddate','mode'] fields = ['startdate','enddate','mode']
class SessionDateShiftForm(forms.Form): class SessionDateShiftForm(forms.Form):
shiftstartdate = forms.DateField( shiftstartdate = forms.DateField(
initial=timezone.now(), initial=timezone.now(),
@@ -563,7 +568,7 @@ class SessionDateShiftForm(forms.Form):
class Meta: class Meta:
fields = ['shiftstartdate'] fields = ['shiftstartdate']
# Form used to select workouts for the past N days # Form used to select workouts for the past N days
class DeltaDaysForm(forms.Form): class DeltaDaysForm(forms.Form):
deltadays = forms.IntegerField(initial=7,required=False,label='') deltadays = forms.IntegerField(initial=7,required=False,label='')
@@ -599,7 +604,7 @@ class RegistrationFormTermsOfService(RegistrationForm):
tos = forms.BooleanField(widget=forms.CheckboxInput, tos = forms.BooleanField(widget=forms.CheckboxInput,
label='I have read and agree to the Terms of Service', label='I have read and agree to the Terms of Service',
error_messages={'required': "You must agree to the terms to register"}) error_messages={'required': "You must agree to the terms to register"})
class RegistrationFormUniqueEmail(RegistrationFormTermsOfService): class RegistrationFormUniqueEmail(RegistrationFormTermsOfService):
@@ -631,20 +636,20 @@ class RegistrationFormSex(RegistrationFormUniqueEmail):
adaptivecategories = mytypes.adaptivetypes adaptivecategories = mytypes.adaptivetypes
thisyear = timezone.now().year thisyear = timezone.now().year
birthdate = forms.DateTimeField( birthdate = forms.DateTimeField(
widget=SelectDateWidget(years=range(1900,thisyear)), widget=SelectDateWidget(years=range(1900,thisyear)),
initial = datetime.date(year=1970, initial = datetime.date(year=1970,
month=4, month=4,
day=15)) day=15))
def clean_birthdate(self): def clean_birthdate(self):
dob = self.cleaned_data['birthdate'] dob = self.cleaned_data['birthdate']
age = (timezone.now() - dob).days/365 age = (timezone.now() - dob).days/365
if age < 16: if age < 16:
raise forms.ValidationError('Must be at least 16 years old to register') raise forms.ValidationError('Must be at least 16 years old to register')
return self.cleaned_data['birthdate'] return self.cleaned_data['birthdate']
sex = forms.ChoiceField(required=False, sex = forms.ChoiceField(required=False,
choices=sexcategories, choices=sexcategories,
initial='not specified', initial='not specified',
@@ -655,10 +660,10 @@ class RegistrationFormSex(RegistrationFormUniqueEmail):
adaptiveclass = forms.ChoiceField(label='Adaptive Classification', adaptiveclass = forms.ChoiceField(label='Adaptive Classification',
choices=adaptivecategories,initial='None',required=False) choices=adaptivecategories,initial='None',required=False)
# def __init__(self, *args, **kwargs): # def __init__(self, *args, **kwargs):
# self.fields['sex'].initial = 'not specified' # self.fields['sex'].initial = 'not specified'
# Time field supporting microseconds. Not used, I believe. # Time field supporting microseconds. Not used, I believe.
class MyTimeField(forms.TimeField): class MyTimeField(forms.TimeField):
@@ -673,7 +678,7 @@ class PowerIntervalUpdateForm(forms.Form):
('pace','Pace'), ('pace','Pace'),
('work','Work per Stroke'), ('work','Work per Stroke'),
) )
pace = forms.DurationField(required=False,label='Pace (/500m)') pace = forms.DurationField(required=False,label='Pace (/500m)')
power = forms.IntegerField(required=False,label='Power (W)') power = forms.IntegerField(required=False,label='Power (W)')
work = forms.IntegerField(required=False,label='Work per Stroke (J)') work = forms.IntegerField(required=False,label='Work per Stroke (J)')
@@ -681,10 +686,10 @@ class PowerIntervalUpdateForm(forms.Form):
required=True, required=True,
initial='power', initial='power',
label='Use') label='Use')
# Form used to update interval stats # Form used to update interval stats
class IntervalUpdateForm(forms.Form): class IntervalUpdateForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
typechoices = ( typechoices = (
(1,'single time'), (1,'single time'),
@@ -733,7 +738,7 @@ class HistoForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False) includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False)
histoparam = forms.ChoiceField(choices=parchoices,initial='power', histoparam = forms.ChoiceField(choices=parchoices,initial='power',
label='Metric') label='Metric')
class AnalysisOptionsForm(forms.Form): class AnalysisOptionsForm(forms.Form):
modality = forms.ChoiceField(choices=workouttypes, modality = forms.ChoiceField(choices=workouttypes,
label='Workout Type', label='Workout Type',
@@ -744,8 +749,8 @@ class AnalysisOptionsForm(forms.Form):
rankingonly = forms.BooleanField(initial=False, rankingonly = forms.BooleanField(initial=False,
label='Only Ranking Pieces', label='Only Ranking Pieces',
required=False) required=False)
# form to select modality and boat type for trend flex # form to select modality and boat type for trend flex
class TrendFlexModalForm(forms.Form): class TrendFlexModalForm(forms.Form):
modality = forms.ChoiceField(choices=workouttypes, modality = forms.ChoiceField(choices=workouttypes,
@@ -759,7 +764,7 @@ class TrendFlexModalForm(forms.Form):
required=False) required=False)
# This form sets options for the summary stats page # This form sets options for the summary stats page
class StatsOptionsForm(forms.Form): class StatsOptionsForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False) includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False)
@@ -772,13 +777,13 @@ class StatsOptionsForm(forms.Form):
initial = mytypes.waterboattype) initial = mytypes.waterboattype)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(StatsOptionsForm, self).__init__(*args,**kwargs) super(StatsOptionsForm, self).__init__(*args,**kwargs)
for type in mytypes.checktypes: for type in mytypes.checktypes:
self.fields[type] = forms.BooleanField(initial=True,required=False) self.fields[type] = forms.BooleanField(initial=True,required=False)
class PlanSelectForm(forms.Form): class PlanSelectForm(forms.Form):
plan = forms.ModelChoiceField(queryset=PaidPlan.objects.all(), plan = forms.ModelChoiceField(queryset=PaidPlan.objects.all(),
widget=forms.RadioSelect,required=True) widget=forms.RadioSelect,required=True)
@@ -812,10 +817,10 @@ class PlanSelectForm(forms.Form):
"price","shortname" "price","shortname"
) )
class CourseSelectForm(forms.Form): class CourseSelectForm(forms.Form):
course = forms.ModelChoiceField(queryset=GeoCourse.objects.all()) course = forms.ModelChoiceField(queryset=GeoCourse.objects.all())
class WorkoutMultipleCompareForm(forms.Form): class WorkoutMultipleCompareForm(forms.Form):
workouts = forms.ModelMultipleChoiceField( workouts = forms.ModelMultipleChoiceField(
queryset=Workout.objects.filter(), queryset=Workout.objects.filter(),
@@ -824,8 +829,8 @@ class WorkoutMultipleCompareForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(WorkoutMultipleCompareForm,self).__init__(*args,**kwargs) super(WorkoutMultipleCompareForm,self).__init__(*args,**kwargs)
self.fields['workouts'].queryset = Workout.objects.filter() self.fields['workouts'].queryset = Workout.objects.filter()
class PlannedSessionMultipleCloneForm(forms.Form): class PlannedSessionMultipleCloneForm(forms.Form):
plannedsessions = forms.ModelMultipleChoiceField( plannedsessions = forms.ModelMultipleChoiceField(
queryset=PlannedSession.objects.all(), queryset=PlannedSession.objects.all(),
@@ -867,7 +872,7 @@ class AnalysisChoiceForm(forms.Form):
) )
axchoices = dict((x,y) for x,y in axchoices) axchoices = dict((x,y) for x,y in axchoices)
axchoices = list(sorted(axchoices.items(), key = lambda x:x[1])) axchoices = list(sorted(axchoices.items(), key = lambda x:x[1]))
yaxchoices = list((ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']) yaxchoices = list((ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time'])
yaxchoices = dict((x,y) for x,y in yaxchoices) yaxchoices = dict((x,y) for x,y in yaxchoices)
@@ -877,7 +882,7 @@ class AnalysisChoiceForm(forms.Form):
('line','Line Plot'), ('line','Line Plot'),
('scatter','Scatter Plot'), ('scatter','Scatter Plot'),
) )
yaxchoices2 = list( yaxchoices2 = list(
(ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time'] (ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']
) )
@@ -914,7 +919,7 @@ class AnalysisChoiceForm(forms.Form):
palette = forms.ChoiceField(choices=palettechoices, palette = forms.ChoiceField(choices=palettechoices,
label = 'Color Scheme', label = 'Color Scheme',
initial='monochrome_blue') initial='monochrome_blue')
spmmin = forms.FloatField(initial=15, spmmin = forms.FloatField(initial=15,
required=False,label = 'Min SPM') required=False,label = 'Min SPM')
spmmax = forms.FloatField(initial=55, spmmax = forms.FloatField(initial=55,
@@ -927,7 +932,7 @@ class AnalysisChoiceForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False, includereststrokes = forms.BooleanField(initial=False,
required=False, required=False,
label='Include Rest Strokes') label='Include Rest Strokes')
class BoxPlotChoiceForm(forms.Form): class BoxPlotChoiceForm(forms.Form):
yparam = forms.ChoiceField(choices=parchoices,initial='spm', yparam = forms.ChoiceField(choices=parchoices,initial='spm',
label='Metric') label='Metric')
@@ -971,7 +976,7 @@ class MultiFlexChoiceForm(forms.Form):
palette = forms.ChoiceField(choices=palettechoices, palette = forms.ChoiceField(choices=palettechoices,
label = 'Color Scheme', label = 'Color Scheme',
initial='monochrome_blue') initial='monochrome_blue')
class ChartParamChoiceForm(forms.Form): class ChartParamChoiceForm(forms.Form):
plotchoices = ( plotchoices = (
('line','Line Plot'), ('line','Line Plot'),
@@ -993,7 +998,7 @@ class FusionMetricChoiceForm(ModelForm):
class Meta: class Meta:
model = Workout model = Workout
fields = [] fields = []
posneg = ( posneg = (
('pos','Workout 2 starts after Workout 1'), ('pos','Workout 2 starts after Workout 1'),
('neg','Workout 2 starts before Workout 1'), ('neg','Workout 2 starts before Workout 1'),
@@ -1021,14 +1026,14 @@ class FusionMetricChoiceForm(ModelForm):
formaxlabels2.pop(label) formaxlabels2.pop(label)
except KeyError: except KeyError:
pass pass
metricchoices = list(sorted(formaxlabels2.items(), key = lambda x:x[1])) metricchoices = list(sorted(formaxlabels2.items(), key = lambda x:x[1]))
self.fields['columns'].choices = metricchoices self.fields['columns'].choices = metricchoices
class PlannedSessionSelectForm(forms.Form): class PlannedSessionSelectForm(forms.Form):
def __init__(self, sessionchoices, *args, **kwargs): def __init__(self, sessionchoices, *args, **kwargs):
initialsession = kwargs.pop('initialsession',None) initialsession = kwargs.pop('initialsession',None)
super(PlannedSessionSelectForm, self).__init__(*args,**kwargs) super(PlannedSessionSelectForm, self).__init__(*args,**kwargs)
self.fields['plannedsession'] = forms.ChoiceField( self.fields['plannedsession'] = forms.ChoiceField(
@@ -1040,7 +1045,7 @@ class PlannedSessionSelectForm(forms.Form):
class WorkoutSessionSelectForm(forms.Form): class WorkoutSessionSelectForm(forms.Form):
def __init__(self, workoutdata, *args, **kwargs): def __init__(self, workoutdata, *args, **kwargs):
super(WorkoutSessionSelectForm, self).__init__(*args, **kwargs) super(WorkoutSessionSelectForm, self).__init__(*args, **kwargs)
@@ -1053,7 +1058,7 @@ class WorkoutSessionSelectForm(forms.Form):
) )
class RaceResultFilterForm(forms.Form): class RaceResultFilterForm(forms.Form):
boatclasses = (type for type in mytypes.workouttypes if type[0] in mytypes.rowtypes) boatclasses = (type for type in mytypes.workouttypes if type[0] in mytypes.rowtypes)
boatclassinitial = [t for t in mytypes.rowtypes] boatclassinitial = [t for t in mytypes.rowtypes]
@@ -1069,7 +1074,7 @@ class RaceResultFilterForm(forms.Form):
) )
adaptivecategories = mytypes.adaptivetypes adaptivecategories = mytypes.adaptivetypes
sex = forms.MultipleChoiceField( sex = forms.MultipleChoiceField(
choices=sexchoices, choices=sexchoices,
initial=['male','female','mixed'], initial=['male','female','mixed'],
@@ -1081,7 +1086,7 @@ class RaceResultFilterForm(forms.Form):
initial=boatclassinitial, initial=boatclassinitial,
label='Boat/Erg Class', label='Boat/Erg Class',
widget=forms.CheckboxSelectMultiple()) widget=forms.CheckboxSelectMultiple())
boattype = forms.MultipleChoiceField( boattype = forms.MultipleChoiceField(
choices=boattypes, choices=boattypes,
label='Boat Type', label='Boat Type',
@@ -1106,7 +1111,7 @@ class RaceResultFilterForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
if 'records' in kwargs: if 'records' in kwargs:
records = kwargs.pop('records',None) records = kwargs.pop('records',None)
super(RaceResultFilterForm,self).__init__(*args,**kwargs) super(RaceResultFilterForm,self).__init__(*args,**kwargs)
if records: if records:
@@ -1135,7 +1140,7 @@ class RaceResultFilterForm(forms.Form):
if choice[0] in theboatclasses: if choice[0] in theboatclasses:
boatclasschoices.append(choice) boatclasschoices.append(choice)
self.fields['boatclass'].choices = boatclasschoices self.fields['boatclass'].choices = boatclasschoices
# boattype # boattype
try: try:
theboattypees = [record.boattype for record in records] theboattypees = [record.boattype for record in records]
@@ -1151,7 +1156,7 @@ class RaceResultFilterForm(forms.Form):
if choice[0] in theboattypees: if choice[0] in theboattypees:
boattypechoices.append(choice) boattypechoices.append(choice)
self.fields['boattype'].choices = boattypechoices self.fields['boattype'].choices = boattypechoices
# weightcategory # weightcategory
theweightcategoryes = [record.weightcategory for record in records] theweightcategoryes = [record.weightcategory for record in records]
theweightcategoryes = list(set(theweightcategoryes)) theweightcategoryes = list(set(theweightcategoryes))
@@ -1177,7 +1182,7 @@ class RaceResultFilterForm(forms.Form):
if choice[0] in theadaptivecategoryes: if choice[0] in theadaptivecategoryes:
adaptivecategorychoices.append(choice) adaptivecategorychoices.append(choice)
self.fields['adaptivecategory'].choices = adaptivecategorychoices self.fields['adaptivecategory'].choices = adaptivecategorychoices
class WorkoutRaceSelectForm(forms.Form): class WorkoutRaceSelectForm(forms.Form):
# evaluate_after = forms.TimeField( # evaluate_after = forms.TimeField(
# input_formats=['%H:%M:%S.%f', # input_formats=['%H:%M:%S.%f',
@@ -1188,7 +1193,7 @@ class WorkoutRaceSelectForm(forms.Form):
# '%M'], # '%M'],
# label = 'Only Evaluate After:', # label = 'Only Evaluate After:',
# required=False) # required=False)
def __init__(self, workoutdata,entries, *args, **kwargs): def __init__(self, workoutdata,entries, *args, **kwargs):
super(WorkoutRaceSelectForm, self).__init__(*args, **kwargs) super(WorkoutRaceSelectForm, self).__init__(*args, **kwargs)
@@ -1206,7 +1211,7 @@ class WorkoutRaceSelectForm(forms.Form):
initial = entries['initial'], initial = entries['initial'],
) )
# self.fields['evaluate_after'] = # self.fields['evaluate_after'] =
# form to send messages to team members # form to send messages to team members
class TeamMessageForm(forms.Form): class TeamMessageForm(forms.Form):
@@ -1256,7 +1261,7 @@ class PlannedSessionTeamMemberForm(forms.Form):
members = forms.ModelMultipleChoiceField( members = forms.ModelMultipleChoiceField(
queryset=Rower.objects.all(), queryset=Rower.objects.all(),
widget=forms.CheckboxSelectMultiple()) widget=forms.CheckboxSelectMultiple())
def __init__(self, thesession, *args, **kwargs): def __init__(self, thesession, *args, **kwargs):
super(PlannedSessionTeamMemberForm,self).__init__(*args,**kwargs) super(PlannedSessionTeamMemberForm,self).__init__(*args,**kwargs)
@@ -1283,13 +1288,13 @@ class VirtualRaceSelectForm(forms.Form):
('my','My Races'), ('my','My Races'),
('all','All Races'), ('all','All Races'),
) )
regattatype = forms.ChoiceField( regattatype = forms.ChoiceField(
label='Type', label='Type',
choices = regattatypechoices, choices = regattatypechoices,
initial = 'upcoming', initial = 'upcoming',
) )
country = forms.ChoiceField( country = forms.ChoiceField(
label='Country', label='Country',
choices = get_countries() choices = get_countries()
@@ -1311,7 +1316,7 @@ class FlexOptionsForm(forms.Form):
) )
plottype = forms.ChoiceField(choices=plotchoices,initial='line', plottype = forms.ChoiceField(choices=plotchoices,initial='line',
label='Chart Type') label='Chart Type')
class ForceCurveOptionsForm(forms.Form): class ForceCurveOptionsForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False, required = False, includereststrokes = forms.BooleanField(initial=False, required = False,
label='Include Rest Strokes') label='Include Rest Strokes')
@@ -1322,15 +1327,15 @@ class ForceCurveOptionsForm(forms.Form):
) )
plottype = forms.ChoiceField(choices=plotchoices,initial='line', plottype = forms.ChoiceField(choices=plotchoices,initial='line',
label='Individual Stroke Chart Type') label='Individual Stroke Chart Type')
class FlexAxesForm(forms.Form): class FlexAxesForm(forms.Form):
axchoices = list( axchoices = list(
(ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','None'] (ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','None']
) )
axchoices = dict((x,y) for x,y in axchoices) axchoices = dict((x,y) for x,y in axchoices)
axchoices = list(sorted(axchoices.items(), key = lambda x:x[1])) axchoices = list(sorted(axchoices.items(), key = lambda x:x[1]))
yaxchoices = list((ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']) yaxchoices = list((ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time'])
yaxchoices = dict((x,y) for x,y in yaxchoices) yaxchoices = dict((x,y) for x,y in yaxchoices)
@@ -1355,9 +1360,9 @@ class FlexAxesForm(forms.Form):
super(FlexAxesForm, self).__init__(*args, **kwargs) super(FlexAxesForm, self).__init__(*args, **kwargs)
rower = Rower.objects.get(user=request.user) rower = Rower.objects.get(user=request.user)
axchoicespro = ( axchoicespro = (
('',ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0],ax[1]) for ax in axes ('',ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0],ax[1]) for ax in axes
) )
axchoicesbasicx = [] axchoicesbasicx = []
@@ -1375,12 +1380,8 @@ class FlexAxesForm(forms.Form):
if ax[0] not in ['cumdist','distance','time']: if ax[0] not in ['cumdist','distance','time']:
axchoicesbasicy.insert(0,('None',ax[1]+' (PRO)')) axchoicesbasicy.insert(0,('None',ax[1]+' (PRO)'))
if rower.rowerplan == 'basic': if rower.rowerplan == 'basic':
self.fields['xaxis'].choices = axchoicesbasicx self.fields['xaxis'].choices = axchoicesbasicx
self.fields['yaxis1'].choices = axchoicesbasicy self.fields['yaxis1'].choices = axchoicesbasicy
self.fields['yaxis2'].choices = axchoicesbasicy self.fields['yaxis2'].choices = axchoicesbasicy

View File

@@ -45,6 +45,11 @@
<span id="time"> <span id="time">
</span> seconds </span> seconds
</li> </li>
<li>
SPM
<span id="spm">
</span>
</li>
<li> <li>
Boat Speed Boat Speed
<span id="speed"> <span id="speed">
@@ -70,12 +75,13 @@
var boatspeed = data["boatspeed"]; var boatspeed = data["boatspeed"];
var latitude = data["latitude"]; var latitude = data["latitude"];
var longitude = data["longitude"]; var longitude = data["longitude"];
var spm = data["spm"]
function onYouTubeIframeAPIReady() { function onYouTubeIframeAPIReady() {
player = new YT.Player('player', { player = new YT.Player('player', {
height: '390', height: '390',
width: '640', width: '640',
videoId: '9dLFC2q9RWc', videoId: '{{ video_id }}',
events: { events: {
'onReady': onPlayerReady 'onReady': onPlayerReady
} }
@@ -92,8 +98,10 @@
velo = boatspeed[Math.round(videotime)]; velo = boatspeed[Math.round(videotime)];
lat = latitude[Math.round(videotime)]; lat = latitude[Math.round(videotime)];
lon = longitude[Math.round(videotime)]; lon = longitude[Math.round(videotime)];
strokerate = spm[Math.round(videotime)];
document.getElementById("time").innerHTML = Math.round(videotime); document.getElementById("time").innerHTML = Math.round(videotime);
document.getElementById("speed").innerHTML = velo; document.getElementById("speed").innerHTML = velo;
document.getElementById("spm").innerHTML = strokerate;
var newLatLng = new L.LatLng(lat, lon); var newLatLng = new L.LatLng(lat, lon);
marker.setLatLng(newLatLng); marker.setLatLng(newLatLng);
} }
@@ -117,6 +125,23 @@
</script> </script>
</li> </li>
<li class="grid_4">
{% if not video_id %}
<p>
To load your video, paste the URL of your YouTube video in the form below,
and submit the form.
</p>
{% endif %}
<p>
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<input type="submit" value="submit">
</form>
</p>
</li>
</ul> </ul>
{% endlanguage %} {% endlanguage %}

View File

@@ -58,7 +58,8 @@ from rowers.forms import (
RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm, RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm,
FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm, FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm,
MetricsForm,DisqualificationForm,disqualificationreasons, MetricsForm,DisqualificationForm,disqualificationreasons,
disqualifiers,SearchForm,BillingForm,PlanSelectForm disqualifiers,SearchForm,BillingForm,PlanSelectForm,
VideoAnalysisCreateForm
) )
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
@@ -80,7 +81,7 @@ from rowers.forms import (
UpdateStreamForm,WorkoutMultipleCompareForm,ChartParamChoiceForm, UpdateStreamForm,WorkoutMultipleCompareForm,ChartParamChoiceForm,
FusionMetricChoiceForm,BoxPlotChoiceForm,MultiFlexChoiceForm, FusionMetricChoiceForm,BoxPlotChoiceForm,MultiFlexChoiceForm,
TrendFlexModalForm,WorkoutSplitForm,WorkoutJoinParamForm, TrendFlexModalForm,WorkoutSplitForm,WorkoutJoinParamForm,
AnalysisOptionsForm, AnalysisChoiceForm, AnalysisOptionsForm, AnalysisChoiceForm,
PlannedSessionMultipleCloneForm,SessionDateShiftForm,RowerTeamForm, PlannedSessionMultipleCloneForm,SessionDateShiftForm,RowerTeamForm,
) )
from rowers.models import ( from rowers.models import (
@@ -255,7 +256,7 @@ def getfavorites(r,row):
workoutsource = row.workoutsource workoutsource = row.workoutsource
if 'speedcoach2' in row.workoutsource: if 'speedcoach2' in row.workoutsource:
workoutsource = 'speedcoach2' workoutsource = 'speedcoach2'
favorites = FavoriteChart.objects.filter(user=r, favorites = FavoriteChart.objects.filter(user=r,
workouttype__in=matchworkouttypes).order_by("id") workouttype__in=matchworkouttypes).order_by("id")
favorites2 = FavoriteChart.objects.filter(user=r, favorites2 = FavoriteChart.objects.filter(user=r,
@@ -264,12 +265,12 @@ def getfavorites(r,row):
favorites = favorites | favorites2 favorites = favorites | favorites2
maxfav = len(favorites)-1 maxfav = len(favorites)-1
return favorites,maxfav return favorites,maxfav
def get_workout_default_page(request,id): def get_workout_default_page(request,id):
if request.user.is_anonymous: if request.user.is_anonymous:
return reverse('workout_view',kwargs={'id':id}) return reverse('workout_view',kwargs={'id':id})
@@ -279,7 +280,7 @@ def get_workout_default_page(request,id):
return reverse('workout_edit_view',kwargs={'id':id}) return reverse('workout_edit_view',kwargs={'id':id})
else: else:
return reverse('workout_workflow_view',kwargs={'id':id}) return reverse('workout_workflow_view',kwargs={'id':id})
def getrequestrower(request,rowerid=0,userid=0,notpermanent=False): def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
userid = int(userid) userid = int(userid)
@@ -288,12 +289,12 @@ def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
if notpermanent == False: if notpermanent == False:
if rowerid == 0 and 'rowerid' in request.session: if rowerid == 0 and 'rowerid' in request.session:
rowerid = request.session['rowerid'] rowerid = request.session['rowerid']
if userid != 0: if userid != 0:
rowerid = 0 rowerid = 0
try: try:
if rowerid != 0: if rowerid != 0:
r = Rower.objects.get(id=rowerid) r = Rower.objects.get(id=rowerid)
elif userid != 0: elif userid != 0:
@@ -301,7 +302,7 @@ def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
r = getrower(u) r = getrower(u)
else: else:
r = getrower(request.user) r = getrower(request.user)
except Rower.DoesNotExist: except Rower.DoesNotExist:
raise Http404("Rower doesn't exist") raise Http404("Rower doesn't exist")
@@ -321,12 +322,12 @@ def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False):
if notpermanent == False: if notpermanent == False:
if rowerid == 0 and 'rowerid' in request.session: if rowerid == 0 and 'rowerid' in request.session:
rowerid = request.session['rowerid'] rowerid = request.session['rowerid']
if userid != 0: if userid != 0:
rowerid = 0 rowerid = 0
try: try:
if rowerid != 0: if rowerid != 0:
r = Rower.objects.get(id=rowerid) r = Rower.objects.get(id=rowerid)
elif userid != 0: elif userid != 0:
@@ -334,7 +335,7 @@ def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False):
r = getrower(u) r = getrower(u)
else: else:
r = getrower(request.user) r = getrower(request.user)
except Rower.DoesNotExist: except Rower.DoesNotExist:
raise Http404("Rower doesn't exist") raise Http404("Rower doesn't exist")
@@ -374,20 +375,20 @@ def get_workout(id):
def get_workout_permitted(user,id): def get_workout_permitted(user,id):
w = get_workout(id) w = get_workout(id)
if (checkworkoutuser(user,w)==False): if (checkworkoutuser(user,w)==False):
raise PermissionDenied("Access denied") raise PermissionDenied("Access denied")
return w return w
def get_workout_permittedview(user,id): def get_workout_permittedview(user,id):
w = get_workout(id) w = get_workout(id)
if (checkworkoutuserview(user,w)==False): if (checkworkoutuserview(user,w)==False):
raise PermissionDenied("Access denied") raise PermissionDenied("Access denied")
return w return w
def getvalue(data): def getvalue(data):
perc = 0 perc = 0
total = 1 total = 1
@@ -412,7 +413,7 @@ class SessionTaskListener(threading.Thread):
self.redis = r self.redis = r
self.pubsub = self.redis.pubsub() self.pubsub = self.redis.pubsub()
self.pubsub.subscribe(channels) self.pubsub.subscribe(channels)
def work(self, item): def work(self, item):
try: try:
@@ -420,10 +421,10 @@ class SessionTaskListener(threading.Thread):
total,done,id,session_key = getvalue(data) total,done,id,session_key = getvalue(data)
perc = int(100.*done/total) perc = int(100.*done/total)
cache.set(id,perc,3600) cache.set(id,perc,3600)
except TypeError: except TypeError:
pass pass
def run(self): def run(self):
for item in self.pubsub.listen(): for item in self.pubsub.listen():
if item['data'] == "KILL": if item['data'] == "KILL":
@@ -497,14 +498,14 @@ def remove_asynctask(request,id):
oldtasks = request.session['async_tasks'] oldtasks = request.session['async_tasks']
except KeyError: except KeyError:
oldtasks = [] oldtasks = []
newtasks = [] newtasks = []
for task in oldtasks: for task in oldtasks:
if id not in task[0]: if id not in task[0]:
newtasks += [(task[0],task[1])] newtasks += [(task[0],task[1])]
request.session['async_tasks'] = newtasks request.session['async_tasks'] = newtasks
def get_job_result(jobid): def get_job_result(jobid):
if settings.TESTING: if settings.TESTING:
return None return None
@@ -522,7 +523,7 @@ def get_job_result(jobid):
result = job.result result = job.result
except NoSuchJobError: except NoSuchJobError:
return None return None
return result return result
verbose_job_status = { verbose_job_status = {
@@ -551,7 +552,7 @@ def get_job_status(jobid):
job = celery_result.AsyncResult(jobid) job = celery_result.AsyncResult(jobid)
jobresult = job.result jobresult = job.result
if 'fail' in job.status.lower(): if 'fail' in job.status.lower():
jobresult = '0' jobresult = '0'
summary = { summary = {
@@ -566,7 +567,7 @@ def get_job_status(jobid):
status = job.status status = job.status
except AttributeError: except AttributeError:
status = job.get_status() status = job.get_status()
summary = { summary = {
'status':status, 'status':status,
'result':job.result, 'result':job.result,
@@ -611,7 +612,7 @@ def kill_async_job(request,id='aap'):
cancel_job(id,connection=redis_connection) cancel_job(id,connection=redis_connection)
except NoSuchJobError: except NoSuchJobError:
pass pass
remove_asynctask(request,id) remove_asynctask(request,id)
cache.delete(id) cache.delete(id)
url = reverse(session_jobs_status) url = reverse(session_jobs_status)
@@ -637,7 +638,7 @@ def raise_500(request):
# try: # try:
# request.session['async_tasks'] += [(job.id,'long_test_task')] # request.session['async_tasks'] += [(job.id,'long_test_task')]
# except KeyError: # except KeyError:
# request.session['async_tasks'] = [(job.id,'long_test_task')] # request.session['async_tasks'] = [(job.id,'long_test_task')]
# #
# url = reverse(session_jobs_status) # url = reverse(session_jobs_status)
# #
@@ -654,7 +655,7 @@ def raise_500(request):
# try: # try:
# request.session['async_tasks'] += [(job.id,'long_test_task2')] # request.session['async_tasks'] += [(job.id,'long_test_task2')]
# except KeyError: # except KeyError:
# request.session['async_tasks'] = [(job.id,'long_test_task2')] # request.session['async_tasks'] = [(job.id,'long_test_task2')]
# #
# url = reverse(session_jobs_status) # url = reverse(session_jobs_status)
# #
@@ -689,7 +690,7 @@ def post_progress(request,id=None,value=0):
else: # request method is not POST else: # request method is not POST
return HttpResponse('GET method not allowed',status=405) return HttpResponse('GET method not allowed',status=405)
def get_all_queued_jobs(userid=0): def get_all_queued_jobs(userid=0):
r = StrictRedis() r = StrictRedis()
@@ -709,13 +710,13 @@ def get_all_queued_jobs(userid=0):
'function':'', 'function':'',
'meta':job.info, 'meta':job.info,
})) }))
ids = [j.id for j in queue.jobs] ids = [j.id for j in queue.jobs]
ids += [j.id for j in queuehigh.jobs] ids += [j.id for j in queuehigh.jobs]
ids += [j.id for j in queuelow.jobs] ids += [j.id for j in queuelow.jobs]
ids += [j.id for j in queuefailed.jobs] ids += [j.id for j in queuefailed.jobs]
for id in ids: for id in ids:
job = Job.fetch(id,connection=redis_connection) job = Job.fetch(id,connection=redis_connection)
jobs.append( jobs.append(
@@ -766,14 +767,14 @@ def get_stored_tasks_status(request):
taskstatus.append(this_task_status) taskstatus.append(this_task_status)
return taskstatus return taskstatus
@login_required() @login_required()
def get_thumbnails(request,id): def get_thumbnails(request,id):
row = get_workout_permitted(request.user,id) row = get_workout_permitted(request.user,id)
r = getrower(request.user) r = getrower(request.user)
result = request.user.is_authenticated and ispromember(request.user) result = request.user.is_authenticated and ispromember(request.user)
if result: if result:
@@ -788,15 +789,15 @@ def get_thumbnails(request,id):
favorites,maxfav = getfavorites(r,row) favorites,maxfav = getfavorites(r,row)
charts = [] charts = []
charts = thumbnails_set(r,encoder.decode_hex(id),favorites) charts = thumbnails_set(r,encoder.decode_hex(id),favorites)
try: try:
if charts[0]['script'] == '': if charts[0]['script'] == '':
charts = [] charts = []
except IndexError: except IndexError:
charts = [] charts = []
return JSONResponse(charts) return JSONResponse(charts)
def get_blog_posts(request): def get_blog_posts(request):
@@ -810,7 +811,7 @@ def get_blog_posts(request):
'title':blogpost.title, 'title':blogpost.title,
'link':blogpost.link, 'link':blogpost.link,
} }
jsondata.append(thedict) jsondata.append(thedict)
return JSONResponse(jsondata) return JSONResponse(jsondata)
@@ -827,12 +828,12 @@ def get_blog_posts_old(request):
blogs_json = [] blogs_json = []
except ConnectionError: except ConnectionError:
pass pass
blogposts = [] blogposts = []
for postdata in blogs_json[0:3]: for postdata in blogs_json[0:3]:
try: try:
title = postdata['title']['rendered'].encode( title = postdata['title']['rendered'].encode(
'ascii','xmlcharrefreplace') 'ascii','xmlcharrefreplace')
@@ -841,7 +842,7 @@ def get_blog_posts_old(request):
title = postdata['title']['rendered'].encode( title = postdata['title']['rendered'].encode(
'ascii','xmlcharrefreplace').decode('utf-8') 'ascii','xmlcharrefreplace').decode('utf-8')
thedict = { thedict = {
'title': title, 'title': title,
# 'author': '', # 'author': '',
@@ -874,7 +875,7 @@ Hoi
""" """
} }
return JSONResponse([object,object]) return JSONResponse([object,object])
@login_required() @login_required()
@@ -935,7 +936,7 @@ def get_my_teams(user):
teams1 = therower.team.all() teams1 = therower.team.all()
except AttributeError: except AttributeError:
teams1 = [] teams1 = []
teams2 = Team.objects.filter(manager=user) teams2 = Team.objects.filter(manager=user)
teams = list(set(teams1).union(set(teams2))) teams = list(set(teams1).union(set(teams2)))
except TypeError: except TypeError:
@@ -960,10 +961,10 @@ def get_time(second):
hours = int((second-24.*3600.*days)/3600.) % 24 hours = int((second-24.*3600.*days)/3600.) % 24
minutes = int((second-3600.*(hours+24.*days))/60.) % 60 minutes = int((second-3600.*(hours+24.*days))/60.) % 60
sec = int(second-3600.*(hours+24.*days)-60.*minutes) % 60 sec = int(second-3600.*(hours+24.*days)-60.*minutes) % 60
microsecond = int(1.0e6*(second-3600.*(hours+24.*days)-60.*minutes-sec)) microsecond = int(1.0e6*(second-3600.*(hours+24.*days)-60.*minutes-sec))
return datetime.time(hours,minutes,sec,microsecond) return datetime.time(hours,minutes,sec,microsecond)
# get the workout ID from the SportTracks URI # get the workout ID from the SportTracks URI
def getidfromsturi(uri,length=8): def getidfromsturi(uri,length=8):
return uri[len(uri)-length:] return uri[len(uri)-length:]
@@ -975,7 +976,7 @@ def getidfromuri(uri):
return m.group(2) return m.group(2)
from rowers.utils import ( from rowers.utils import (
geo_distance,serialize_list,deserialize_list,uniqify, geo_distance,serialize_list,deserialize_list,uniqify,
str2bool,range_to_color_hex,absolute,myqueue,get_call, str2bool,range_to_color_hex,absolute,myqueue,get_call,
@@ -997,11 +998,11 @@ def iscoachmember(user):
except Rower.DoesNotExist: except Rower.DoesNotExist:
r = Rower(user=user) r = Rower(user=user)
r.save() r.save()
result = user.is_authenticated and ('coach' in r.rowerplan) result = user.is_authenticated and ('coach' in r.rowerplan)
else: else:
result = False result = False
return result return result
def cancreateteam(user): def cancreateteam(user):
@@ -1092,7 +1093,7 @@ def sendmail(request):
messages.error(request,'You have to answer YES to the question') messages.error(request,'You have to answer YES to the question')
return HttpResponseRedirect('/rowers/email/') return HttpResponseRedirect('/rowers/email/')
else: else:
return HttpResponseRedirect('/rowers/email/') return HttpResponseRedirect('/rowers/email/')
else: else:
return HttpResponseRedirect('/rowers/email/') return HttpResponseRedirect('/rowers/email/')
@@ -1106,7 +1107,7 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
workouttype = data['type'] workouttype = data['type']
except KeyError: except KeyError:
workouttype = 'rower' workouttype = 'rower'
if workouttype not in [x[0] for x in Workout.workouttypes]: if workouttype not in [x[0] for x in Workout.workouttypes]:
workouttype = 'other' workouttype = 'other'
try: try:
@@ -1128,14 +1129,14 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
rowdatetime = iso8601.parse_date(data['start_date']) rowdatetime = iso8601.parse_date(data['start_date'])
except ParseError: except ParseError:
rowdatetime = iso8601.parse_date(data['date']) rowdatetime = iso8601.parse_date(data['date'])
try: try:
c2intervaltype = data['workout_type'] c2intervaltype = data['workout_type']
except KeyError: except KeyError:
c2intervaltype = '' c2intervaltype = ''
try: try:
title = data['name'] title = data['name']
except KeyError: except KeyError:
@@ -1177,7 +1178,7 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
spm = strokedata.loc[:,'spm'] spm = strokedata.loc[:,'spm']
except KeyError: except KeyError:
spm = 0*dist2 spm = 0*dist2
try: try:
hr = strokedata.loc[:,'hr'] hr = strokedata.loc[:,'hr']
except KeyError: except KeyError:
@@ -1189,7 +1190,7 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
velo = 500./pace velo = 500./pace
power = 2.8*velo**3 power = 2.8*velo**3
# save csv # save csv
# Create data frame with all necessary data to write to csv # Create data frame with all necessary data to write to csv
df = pd.DataFrame({'TimeStamp (sec)':unixtime, df = pd.DataFrame({'TimeStamp (sec)':unixtime,
@@ -1211,9 +1212,9 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
' ElapsedTime (sec)':seconds ' ElapsedTime (sec)':seconds
}) })
df.sort_values(by='TimeStamp (sec)',ascending=True) df.sort_values(by='TimeStamp (sec)',ascending=True)
timestr = strftime("%Y%m%d-%H%M%S") timestr = strftime("%Y%m%d-%H%M%S")
@@ -1249,11 +1250,11 @@ def add_workout_from_strokedata(user,importid,data,strokedata,
dosummary=True dosummary=True
) )
return id,message return id,message
def keyvalue_get_default(key,options,def_options): def keyvalue_get_default(key,options,def_options):
@@ -1288,5 +1289,3 @@ def trydf(df,aantal,column):
import rowers.teams as teams import rowers.teams as teams
from rowers.models import C2WorldClassAgePerformance from rowers.models import C2WorldClassAgePerformance

View File

@@ -12,6 +12,7 @@ from urllib.parse import urlparse, parse_qs
def default(o): def default(o):
if isinstance(o, numpy.int64): return int(o) if isinstance(o, numpy.int64): return int(o)
if isinstance(o, numpy.int32): return int(o)
raise TypeError raise TypeError
def get_video_id(url): def get_video_id(url):
@@ -53,32 +54,59 @@ def workout_video_view(request,id=0):
# get workout # get workout
w = get_workout_permitted(request.user,id) w = get_workout_permitted(request.user,id)
# get video ID and offset
if request.method == 'POST':
form = VideoAnalysisCreateForm(request.POST)
if form.is_valid():
url = form.cleaned_data['url']
delay = form.cleaned_data['delay']
video_id = get_video_id(url)
else:
video_id = None
delay = 0
else:
form = VideoAnalysisCreateForm()
video_id = None
delay = 0
# get data # get data
df = getsmallrowdata_db(['time','velo'],ids=[w.id]) df = getsmallrowdata_db(['time','velo','spm'],ids=[w.id],
workstrokesonly=False,doclean=False,compute=False)
df['time'] = (df['time']-df['time'].min())/1000. df['time'] = (df['time']-df['time'].min())/1000.
df.sort_values(by='time',inplace=True) df.sort_values(by='time',inplace=True)
df.set_index(pd.to_timedelta(df['time'],unit='s'),inplace=True) df.set_index(pd.to_timedelta(df['time'],unit='s'),inplace=True)
df2 = df.resample('1s').mean().interpolate() df2 = df.resample('1s').mean().interpolate()
mask = df2['time'] < delay
df2 = df2.mask(mask).dropna()
df2['time'] = (df2['time']-df2['time'].min())
boatspeed = (100*df2['velo']).astype(int)/100. boatspeed = (100*df2['velo']).astype(int)/100.
spm = (10*df2['spm']).astype(int)/10.
coordinates = dataprep.get_latlon_time(w.id) coordinates = dataprep.get_latlon_time(w.id)
mask = coordinates['time'] < delay
coordinates = coordinates.mask(mask).dropna()
coordinates['time'] = coordinates['time']-coordinates['time'].min()
coordinates.set_index(pd.to_timedelta(coordinates['time'],unit='s'),inplace=True) coordinates.set_index(pd.to_timedelta(coordinates['time'],unit='s'),inplace=True)
coordinates = coordinates.resample('1s').mean().interpolate() coordinates = coordinates.resample('1s').mean().interpolate()
latitude = coordinates['latitude'] latitude = coordinates['latitude']
longitude = coordinates['longitude'] longitude = coordinates['longitude']
# get video
url = "https://www.youtube.com/watch?time_continue=496&v=9dLFC2q9RWc"
video_id = get_video_id(url)
# create map # create map
mapscript, mapdiv = leaflet_chart_video(latitude,longitude, mapscript, mapdiv = leaflet_chart_video(latitude,longitude,
w.name) w.name)
# bundle data # bundle data
data = {'boatspeed':[ v for v in boatspeed.values], data = {
'latitude':[ l for l in latitude.values], 'boatspeed':[ v for v in boatspeed.values],
'longitude':[ l for l in longitude.values]} 'latitude':[ l for l in latitude.values],
'longitude':[ l for l in longitude.values],
'spm':[ s for s in spm.values ]
}
return render(request, return render(request,
'embedded_video.html', 'embedded_video.html',
@@ -89,6 +117,7 @@ def workout_video_view(request,id=0):
'mapscript': mapscript, 'mapscript': mapscript,
'mapdiv': mapdiv, 'mapdiv': mapdiv,
'video_id': video_id, 'video_id': video_id,
'form':form,
}) })
# Show the EMpower Oarlock generated Stroke Profile # Show the EMpower Oarlock generated Stroke Profile