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