adding functionality to make it easier to do timed courses
This commit is contained in:
@@ -111,6 +111,15 @@
|
||||
</table>
|
||||
</p>
|
||||
</li>
|
||||
{% if workoutid %}
|
||||
<li>
|
||||
<p>
|
||||
Suggested Workout: {{ workoutid|getworkoutname }}
|
||||
<br /><a href="/rowers/workout/{{ workoutid }}/submit/{{ course.id }}/" target="__">Measure time on course</a>
|
||||
|
||||
</p>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if form %}
|
||||
<li class="grid_4">
|
||||
|
||||
@@ -136,6 +145,16 @@
|
||||
</p>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if workoutid %}
|
||||
<li>
|
||||
<p>
|
||||
Suggested Workout: {{ workoutid|getworkoutname }}
|
||||
<br /><a href="/rowers/workout/{{ workoutid }}/submit/{{ course.id }}/" target="__">Measure time on course</a>
|
||||
|
||||
</p>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if ownrecords %}
|
||||
<li class="grid_4">
|
||||
|
||||
@@ -212,6 +212,18 @@
|
||||
{{ mapscript|safe }}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if suggested_courses %}
|
||||
<li>
|
||||
<h2>Suggested Measured Courses</h2>
|
||||
{% for course in suggested_courses %}
|
||||
<p>
|
||||
{{ course }}
|
||||
<br /><a href="/rowers/courses/{{ course.id }}/workout/{{ workout.id|encode }}/" target="_">See course</a>
|
||||
<br /><a href="/rowers/workout/{{ workout.id|encode }}/submit/{{ course.id }}/">Measure time on course</a>
|
||||
</p>
|
||||
{% endfor %}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% for graph in graphs %}
|
||||
<li>
|
||||
|
||||
@@ -48,6 +48,16 @@ from six import string_types
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter
|
||||
def getworkoutname(id):
|
||||
try:
|
||||
w = Workout.objects.get(id=encoder.decode_hex(id))
|
||||
return w
|
||||
except Workout.DoesNotExist:
|
||||
return ''
|
||||
|
||||
return ''
|
||||
|
||||
@register.filter
|
||||
def workoutdate(id): # pragma: no cover
|
||||
try:
|
||||
@@ -56,6 +66,8 @@ def workoutdate(id): # pragma: no cover
|
||||
except Workout.DoesNotExist:
|
||||
return 'unknown'
|
||||
|
||||
return 'unknown'
|
||||
|
||||
@register.filter
|
||||
def usermessages(rower):
|
||||
try:
|
||||
|
||||
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
Binary file not shown.
@@ -366,6 +366,8 @@ urlpatterns = [
|
||||
views.course_follow_view, name='course_follow_view'),
|
||||
re_path(r'^courses/(?P<id>\d+)/unfollow/',
|
||||
views.course_unfollow_view, name='course_unfollow_view'),
|
||||
re_path(r'^courses/(?P<id>\d+)/workout/(?P<workoutid>\b[0-9A-Fa-f]+\b)',
|
||||
views.course_view, name='course_view'),
|
||||
re_path(r'^standards/upload/$', views.standards_upload_view,
|
||||
name='standards_upload_view'),
|
||||
re_path(r'^standards/upload/(?P<id>\d+)/$',
|
||||
@@ -385,6 +387,8 @@ urlpatterns = [
|
||||
re_path(
|
||||
r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(r'workout/(?P<id>\b[0-9A-Fa-f]+\b)/submit/(?P<courseid>\d+)/$',
|
||||
views.workout_submit_course_view, name='workout_submit_course_view'),
|
||||
re_path(r'^workouts-dupes-select/user/(?P<userid>\d+)/$',
|
||||
views.workouts_duplicates_select_view, name='workouts_duplicates_select_view'),
|
||||
re_path(r'^workouts-dupes-select/$',
|
||||
|
||||
@@ -356,7 +356,7 @@ def course_unfollow_view(request, id=0):
|
||||
url = reverse("courses_view")
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
def course_view(request, id=0):
|
||||
def course_view(request, id=0, workoutid=0):
|
||||
try:
|
||||
course = GeoCourse.objects.get(id=id)
|
||||
except GeoCourse.DoesNotExist: # pragma: no cover
|
||||
@@ -477,6 +477,7 @@ def course_view(request, id=0):
|
||||
'rower': r,
|
||||
'form': form,
|
||||
'onlyme': onlyme,
|
||||
'workoutid': workoutid,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -4540,24 +4540,13 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
|
||||
|
||||
hascoordinates = 1
|
||||
courses = []
|
||||
if rowdata != 0:
|
||||
try:
|
||||
latitude = rowdata.df[' latitude']
|
||||
longitude = rowdata.df[' longitude']
|
||||
if not latitude.std(): # pragma: no cover
|
||||
hascoordinates = 0
|
||||
if not longitude.std():
|
||||
hascoordinates = 0
|
||||
except (KeyError, AttributeError):
|
||||
hascoordinates = 0
|
||||
|
||||
else: # pragma: no cover
|
||||
hascoordinates = 0
|
||||
suggested_courses = []
|
||||
has_latlon, lat_mean, lon_mean = dataprep.workout_has_latlon(row.id)
|
||||
|
||||
mapscript = ""
|
||||
mapdiv = ""
|
||||
|
||||
if hascoordinates:
|
||||
if has_latlon:
|
||||
try:
|
||||
mapscript, mapdiv = leaflet_chart(
|
||||
rowdata.df[' latitude'],
|
||||
@@ -4570,6 +4559,12 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
|
||||
workoutid=row.id, userid=row.user.user.id, coursecompleted=True)
|
||||
if records.count() > 0: # pragma: no cover
|
||||
courses = list(set([record.course for record in records]))
|
||||
suggested_courses = getnearestcourses([lat_mean, lon_mean], GeoCourse.objects.all(), whatisnear=25,
|
||||
strict=True)
|
||||
|
||||
suggested_courses = list(set(courses) ^ set(suggested_courses))
|
||||
|
||||
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
@@ -4608,6 +4603,7 @@ def workout_edit_view(request, id=0, message="", successmessage=""):
|
||||
'mapdiv': mapdiv,
|
||||
'rower': r,
|
||||
'courses': courses,
|
||||
'suggested_courses': suggested_courses,
|
||||
})
|
||||
|
||||
|
||||
@@ -6102,7 +6098,70 @@ def workout_fusion_view(request, id1=0, id2=1):
|
||||
'workout2': w2,
|
||||
})
|
||||
|
||||
# See attached courses
|
||||
# See attached courses / attaching courses
|
||||
|
||||
@login_required()
|
||||
@permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True)
|
||||
def workout_submit_course_view(request, id, courseid):
|
||||
row = get_workout_by_opaqueid(request, id)
|
||||
r = getrower(request.user)
|
||||
try:
|
||||
course = GeoCourse.objects.get(id=courseid)
|
||||
except GeoCourse.DoesNotExist:
|
||||
url = reverse('workout_edit_view', kwargs={'id': encoder.encode_hex(row.id)})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# got a course
|
||||
records = VirtualRaceResult.objects.filter(
|
||||
userid = r.id,
|
||||
course=course,
|
||||
workoutid=row.id
|
||||
)
|
||||
if records:
|
||||
record = records[0]
|
||||
else:
|
||||
# create record
|
||||
record = VirtualRaceResult(
|
||||
userid=r.id,
|
||||
username=r.user.first_name+' '+r.user.last_name,
|
||||
workoutid=row.id,
|
||||
weightcategory=r.weightcategory,
|
||||
adaptiveclass=r.adaptiveclass,
|
||||
course=course,
|
||||
distance=course.distance,
|
||||
boatclass=row.workouttype,
|
||||
boattype=row.boattype,
|
||||
sex=r.sex,
|
||||
age=calculate_age(r.birthdate),
|
||||
)
|
||||
record.save()
|
||||
|
||||
job = myqueue(
|
||||
queuehigh,
|
||||
handle_check_race_course,
|
||||
row.csvfilename,
|
||||
row.id,
|
||||
course.id,
|
||||
record.id,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
summary=True,
|
||||
successemail=True,
|
||||
)
|
||||
|
||||
try:
|
||||
request.session['async_tasks'] += [
|
||||
(job.id, 'check_race_course')]
|
||||
except KeyError: # pragma: no cover
|
||||
request.session['async_tasks'] = [
|
||||
(job.id, 'check_race_course')]
|
||||
|
||||
messages.info(request, 'We are checking your time on the course in the background." \
|
||||
" You will receive an email when the check is complete." \
|
||||
" You can check the status <a href="/rowers/jobs-status/" target="_blank">here</a>')
|
||||
|
||||
url = reverse('workout_edit_view', kwargs={'id': encoder.encode_hex(row.id)})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
@login_required()
|
||||
|
||||
Reference in New Issue
Block a user