register and withdraw done
This commit is contained in:
@@ -422,6 +422,12 @@ def course_length(course):
|
|||||||
|
|
||||||
return int(totaldist)
|
return int(totaldist)
|
||||||
|
|
||||||
|
sexcategories = (
|
||||||
|
('male','male'),
|
||||||
|
('female','female'),
|
||||||
|
('not specified','not specified'),
|
||||||
|
)
|
||||||
|
|
||||||
# Extension of User with rowing specific data
|
# Extension of User with rowing specific data
|
||||||
class Rower(models.Model):
|
class Rower(models.Model):
|
||||||
weightcategories = (
|
weightcategories = (
|
||||||
@@ -429,11 +435,6 @@ class Rower(models.Model):
|
|||||||
('lwt','light-weight'),
|
('lwt','light-weight'),
|
||||||
)
|
)
|
||||||
|
|
||||||
sexcategories = (
|
|
||||||
('male','male'),
|
|
||||||
('female','female'),
|
|
||||||
('not specified','not specified'),
|
|
||||||
)
|
|
||||||
|
|
||||||
stravatypes = (
|
stravatypes = (
|
||||||
('Ride','Ride'),
|
('Ride','Ride'),
|
||||||
@@ -1066,6 +1067,10 @@ class VirtualRace(PlannedSession):
|
|||||||
end_time = models.TimeField(blank=True,null=True)
|
end_time = models.TimeField(blank=True,null=True)
|
||||||
country = models.CharField(max_length=100,blank=True)
|
country = models.CharField(max_length=100,blank=True)
|
||||||
|
|
||||||
|
timezone = models.CharField(default='UTC',
|
||||||
|
choices=timezones,
|
||||||
|
max_length=100)
|
||||||
|
|
||||||
phone_regex = RegexValidator(
|
phone_regex = RegexValidator(
|
||||||
regex=r'^\+?1?\d{9,15}$',
|
regex=r'^\+?1?\d{9,15}$',
|
||||||
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
|
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
|
||||||
@@ -1088,6 +1093,8 @@ class VirtualRace(PlannedSession):
|
|||||||
|
|
||||||
return stri
|
return stri
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Date input utility
|
# Date input utility
|
||||||
class DateInput(forms.DateInput):
|
class DateInput(forms.DateInput):
|
||||||
input_type = 'date'
|
input_type = 'date'
|
||||||
@@ -1199,12 +1206,12 @@ class PlannedSessionFormSmall(ModelForm):
|
|||||||
'manager': forms.HiddenInput(),
|
'manager': forms.HiddenInput(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boattypes = types.boattypes
|
||||||
|
|
||||||
# Workout
|
# Workout
|
||||||
class Workout(models.Model):
|
class Workout(models.Model):
|
||||||
workouttypes = types.workouttypes
|
workouttypes = types.workouttypes
|
||||||
workoutsources = types.workoutsources
|
workoutsources = types.workoutsources
|
||||||
boattypes = types.boattypes
|
|
||||||
privacychoices = types.privacychoices
|
privacychoices = types.privacychoices
|
||||||
|
|
||||||
user = models.ForeignKey(Rower)
|
user = models.ForeignKey(Rower)
|
||||||
@@ -1317,6 +1324,24 @@ def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
|
|||||||
conn.close()
|
conn.close()
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
|
|
||||||
|
# Virtual Race results (for keeping results when workouts are deleted)
|
||||||
|
class VirtualRaceResult(models.Model):
|
||||||
|
user = models.ForeignKey(Rower)
|
||||||
|
username = models.CharField(max_length=150)
|
||||||
|
workout = models.ForeignKey(Workout)
|
||||||
|
race = models.ForeignKey(VirtualRace)
|
||||||
|
duration = models.TimeField(default=3600)
|
||||||
|
boattype = models.CharField(choices=boattypes,max_length=40,
|
||||||
|
default='1x',
|
||||||
|
verbose_name = 'Boat Type'
|
||||||
|
)
|
||||||
|
|
||||||
|
sex = models.CharField(default="not specified",
|
||||||
|
max_length=30,
|
||||||
|
choices=sexcategories,
|
||||||
|
verbose_name='Gender')
|
||||||
|
|
||||||
|
|
||||||
from rowers.metrics import rowingmetrics
|
from rowers.metrics import rowingmetrics
|
||||||
|
|
||||||
strokedatafields = {
|
strokedatafields = {
|
||||||
|
|||||||
@@ -477,6 +477,7 @@ def update_virtualrace(ps,cd):
|
|||||||
ps.registration_closure.replace(tzinfo=None)
|
ps.registration_closure.replace(tzinfo=None)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ps.timezone = timezone_str
|
||||||
|
|
||||||
ps.save()
|
ps.save()
|
||||||
|
|
||||||
@@ -488,6 +489,110 @@ def race_rower_status(r,race):
|
|||||||
|
|
||||||
is_complete = is_session_complete_ws(ws,race)[1]
|
is_complete = is_session_complete_ws(ws,race)[1]
|
||||||
|
|
||||||
has_registered = r in race.rower
|
has_registered = r in race.rower.all()
|
||||||
|
|
||||||
return is_complete,has_registered
|
return is_complete,has_registered
|
||||||
|
|
||||||
|
|
||||||
|
def race_can_submit(r,race):
|
||||||
|
if r not in race.rower.all():
|
||||||
|
return False
|
||||||
|
|
||||||
|
start_time = race.start_time
|
||||||
|
start_date = race.startdate
|
||||||
|
startdatetime = datetime.combine(start_date,start_time)
|
||||||
|
startdatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
startdatetime
|
||||||
|
)
|
||||||
|
evaluation_closure = race.evaluation_closure
|
||||||
|
|
||||||
|
|
||||||
|
if timezone.now() > startdatetime and timezone.now() < evaluation_closure:
|
||||||
|
is_complete,has_registered = race_rower_status(r,race)
|
||||||
|
if is_complete == 'not done':
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def race_can_resubmit(r,race):
|
||||||
|
if r not in race.rower.all():
|
||||||
|
return False
|
||||||
|
|
||||||
|
start_time = race.start_time
|
||||||
|
start_date = race.startdate
|
||||||
|
startdatetime = datetime.combine(start_date,start_time)
|
||||||
|
startdatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
startdatetime
|
||||||
|
)
|
||||||
|
evaluation_closure = race.evaluation_closure
|
||||||
|
|
||||||
|
|
||||||
|
if timezone.now() > startdatetime and timezone.now() < evaluation_closure:
|
||||||
|
is_complete,has_registered = race_rower_status(r,race)
|
||||||
|
if is_complete in ['partial','completed']:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def race_can_withdraw(r,race):
|
||||||
|
if r not in race.rower.all():
|
||||||
|
return False
|
||||||
|
|
||||||
|
start_time = race.start_time
|
||||||
|
start_date = race.startdate
|
||||||
|
startdatetime = datetime.combine(start_date,start_time)
|
||||||
|
startdatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
startdatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
registration_closure = race.registration_closure
|
||||||
|
if registration_closure is not None and registration_closure != '':
|
||||||
|
if timezone.now() > registration_closure:
|
||||||
|
return False
|
||||||
|
elif timezone.now() > startdatetime:
|
||||||
|
return False
|
||||||
|
elif timezone.now() > startdatetime:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def race_can_register(r,race):
|
||||||
|
if r in race.rower.all():
|
||||||
|
return False
|
||||||
|
|
||||||
|
start_time = race.start_time
|
||||||
|
start_date = race.startdate
|
||||||
|
startdatetime = datetime.combine(start_date,start_time)
|
||||||
|
startdatetime = pytz.timezone(race.timezone).localize(
|
||||||
|
startdatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
registration_closure = race.registration_closure
|
||||||
|
if registration_closure is not None and registration_closure != '':
|
||||||
|
if timezone.now() > registration_closure:
|
||||||
|
return False
|
||||||
|
elif timezone.now() > startdatetime:
|
||||||
|
return False
|
||||||
|
elif timezone.now() > startdatetime:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def add_rower_race(r,race):
|
||||||
|
race.rower.add(r)
|
||||||
|
race.save()
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def remove_rower_race(r,race):
|
||||||
|
race.rower.remove(r)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|||||||
@@ -29,6 +29,12 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Course</th><td>{{ race.course }}</td>
|
<th>Course</th><td>{{ race.course }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% if race.has_registration %}
|
||||||
|
<tr>
|
||||||
|
<th>Registration closure</th>
|
||||||
|
<td>{{ race.registration_closure }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Date</th><td>{{ race.startdate }}</td>
|
<th>Date</th><td>{{ race.startdate }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -55,9 +61,31 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="registerbuttons">
|
<div id="registerbuttons">
|
||||||
|
{% if request.user.is_anonymous %}
|
||||||
<p>
|
<p>
|
||||||
hier komen de registratieknoppen en zo
|
Registered users of rowsandall.com can participate in this event.
|
||||||
</p>
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
See race rules below.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{% for button in buttons %}
|
||||||
|
{% if button == 'registerbutton' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/register" class="button gray small grid_2">Register</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'submitbutton' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/submit" class="button gray small grid_2">Submit Result</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'resubmitbutton' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/resubmit" class="button gray small grid_2">Submit New Result</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if button == 'withdrawbutton' %}
|
||||||
|
<a href="/rowers/virtualevent/{{ race.id }}/withdraw" class="button gray small grid_2">Withdraw</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div id="results">
|
<div id="results">
|
||||||
<h2>Results</h2>
|
<h2>Results</h2>
|
||||||
@@ -65,6 +93,42 @@
|
|||||||
No results yet
|
No results yet
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="rules">
|
||||||
|
<h2>Rules</h2>
|
||||||
|
<p>
|
||||||
|
As a rowsandall.com user, you can
|
||||||
|
register to take part in this event.
|
||||||
|
If the race organizer has set a registration deadline, you must
|
||||||
|
register before the deadline. Otherwise, it is sufficient to
|
||||||
|
register before the start of the race window.
|
||||||
|
You can always withdraw from participating before the registration
|
||||||
|
deadline or the start of the race window, if no registration
|
||||||
|
deadline was set.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
After the start of the race window and before the submission deadline,
|
||||||
|
you can submit results by linking the race to one of your uploaded
|
||||||
|
workouts. The workout start time must be within the race window
|
||||||
|
and your trajectory must pass through the blue polygons on the course
|
||||||
|
map (in the right order), for your result to be valid.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The results table has a link to a page where details of your workout
|
||||||
|
are shown.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Race results are stored permanently and are not deleted when
|
||||||
|
you delete the respective workout or remove your account.
|
||||||
|
By registering, you agree with this and the race rules.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Virtual Racing on rowsandall.com is honors based. Please be a good
|
||||||
|
sport, submit real results rowed by you, and make sure you set the
|
||||||
|
boat type correctly. For (future functionality) age and gender
|
||||||
|
corrected times, please be sure your gender and birth date are set
|
||||||
|
correctly in your user settings.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_4 omega">
|
<div class="grid_4 omega">
|
||||||
<h2>Course</h2>
|
<h2>Course</h2>
|
||||||
|
|||||||
@@ -147,6 +147,8 @@ urlpatterns = [
|
|||||||
url(r'^virtualevent/create$',views.virtualevent_create_view),
|
url(r'^virtualevent/create$',views.virtualevent_create_view),
|
||||||
url(r'^virtualevent/(?P<id>\d+)$',views.virtualevent_view),
|
url(r'^virtualevent/(?P<id>\d+)$',views.virtualevent_view),
|
||||||
url(r'^virtualevent/(?P<id>\d+)/edit$',views.virtualevent_edit_view),
|
url(r'^virtualevent/(?P<id>\d+)/edit$',views.virtualevent_edit_view),
|
||||||
|
url(r'^virtualevent/(?P<id>\d+)/register$',views.virtualevent_register_view),
|
||||||
|
url(r'^virtualevent/(?P<id>\d+)/withdraw$',views.virtualevent_withdraw_view),
|
||||||
url(r'^list-workouts/$',views.workouts_view),
|
url(r'^list-workouts/$',views.workouts_view),
|
||||||
url(r'^list-courses/$',views.courses_view),
|
url(r'^list-courses/$',views.courses_view),
|
||||||
url(r'^courses/upload$',views.course_upload_view),
|
url(r'^courses/upload$',views.course_upload_view),
|
||||||
|
|||||||
@@ -13376,7 +13376,10 @@ def virtualevents_view(request):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def virtualevent_view(request,id=0):
|
def virtualevent_view(request,id=0):
|
||||||
r = getrower(request.user)
|
if not request.user.is_anonymous():
|
||||||
|
r = getrower(request.user)
|
||||||
|
else:
|
||||||
|
r = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
race = VirtualRace.objects.get(id=id)
|
race = VirtualRace.objects.get(id=id)
|
||||||
@@ -13384,7 +13387,21 @@ def virtualevent_view(request,id=0):
|
|||||||
raise Http404("Virtual Race does not exist")
|
raise Http404("Virtual Race does not exist")
|
||||||
|
|
||||||
script,div = course_map(race.course)
|
script,div = course_map(race.course)
|
||||||
is_complete,has_registered = race_rower_status(r,race)
|
|
||||||
|
buttons = []
|
||||||
|
|
||||||
|
if not request.user.is_anonymous():
|
||||||
|
if race_can_register(r,race):
|
||||||
|
buttons += ['registerbutton']
|
||||||
|
|
||||||
|
if race_can_submit(r,race):
|
||||||
|
buttons += ['submitbutton']
|
||||||
|
|
||||||
|
if race_can_resubmit(r,race):
|
||||||
|
buttons += ['resubmitbutton']
|
||||||
|
|
||||||
|
if race_can_withdraw(r,race):
|
||||||
|
buttons += ['withdrawbutton']
|
||||||
|
|
||||||
|
|
||||||
return render(request,'virtualevent.html',
|
return render(request,'virtualevent.html',
|
||||||
@@ -13392,11 +13409,54 @@ def virtualevent_view(request,id=0):
|
|||||||
'coursescript':script,
|
'coursescript':script,
|
||||||
'coursediv':div,
|
'coursediv':div,
|
||||||
'race':race,
|
'race':race,
|
||||||
'rower':r
|
'rower':r,
|
||||||
'has_registered':has_registered,
|
'buttons':buttons,
|
||||||
'has_rowed':is_complete,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def virtualevent_withdraw_view(request,id=0):
|
||||||
|
r = getrower(request.user)
|
||||||
|
try:
|
||||||
|
race = VirtualRace.objects.get(id=id)
|
||||||
|
except VirtualRace.DoesNotExist:
|
||||||
|
raise Http404("Virtual Race does not exist")
|
||||||
|
|
||||||
|
if race_can_withdraw(r,race):
|
||||||
|
remove_rower_race(r,race)
|
||||||
|
messages.info(request,
|
||||||
|
"You have successfully withdrawn from this race.")
|
||||||
|
else:
|
||||||
|
messages.error(request,"You cannot withdraw from this race")
|
||||||
|
|
||||||
|
url = reverse(virtualevent_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':race.id
|
||||||
|
})
|
||||||
|
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def virtualevent_register_view(request,id=0):
|
||||||
|
r = getrower(request.user)
|
||||||
|
try:
|
||||||
|
race = VirtualRace.objects.get(id=id)
|
||||||
|
except VirtualRace.DoesNotExist:
|
||||||
|
raise Http404("Virtual Race does not exist")
|
||||||
|
|
||||||
|
if race_can_register(r,race):
|
||||||
|
add_rower_race(r,race)
|
||||||
|
messages.info(request,
|
||||||
|
"You have successfully registered for this race. Good luck!")
|
||||||
|
else:
|
||||||
|
messages.error(request,"You cannot register for this race")
|
||||||
|
|
||||||
|
url = reverse(virtualevent_view,
|
||||||
|
kwargs = {
|
||||||
|
'id':race.id
|
||||||
|
})
|
||||||
|
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def virtualevent_create_view(request):
|
def virtualevent_create_view(request):
|
||||||
r = getrower(request.user)
|
r = getrower(request.user)
|
||||||
@@ -13451,6 +13511,7 @@ def virtualevent_create_view(request):
|
|||||||
course=geocourse,
|
course=geocourse,
|
||||||
comment=comment,
|
comment=comment,
|
||||||
sessiontype = 'coursetest',
|
sessiontype = 'coursetest',
|
||||||
|
timezone=timezone_str,
|
||||||
has_registration=has_registration,
|
has_registration=has_registration,
|
||||||
evaluation_closure=evaluation_closure,
|
evaluation_closure=evaluation_closure,
|
||||||
registration_closure=registration_closure,
|
registration_closure=registration_closure,
|
||||||
|
|||||||
Reference in New Issue
Block a user