diff --git a/rowers/templates/course_view.html b/rowers/templates/course_view.html index decc0089..4a610e83 100644 --- a/rowers/templates/course_view.html +++ b/rowers/templates/course_view.html @@ -111,6 +111,15 @@

+ {% if workoutid %} +
  • +

    + Suggested Workout: {{ workoutid|getworkoutname }} +
    Measure time on course + +

    +
  • + {% endif %} {% if form %}
  • @@ -136,6 +145,16 @@

  • {% endif %} + {% else %} + {% if workoutid %} +
  • +

    + Suggested Workout: {{ workoutid|getworkoutname }} +
    Measure time on course + +

    +
  • + {% endif %} {% endif %} {% if ownrecords %}
  • diff --git a/rowers/templates/workout_form.html b/rowers/templates/workout_form.html index ac019062..98034e21 100644 --- a/rowers/templates/workout_form.html +++ b/rowers/templates/workout_form.html @@ -213,6 +213,18 @@
  • {% endif %} + {% if suggested_courses %} +
  • +

    Suggested Measured Courses

    + {% for course in suggested_courses %} +

    + {{ course }} +
    See course +
    Measure time on course +

    + {% endfor %} +
  • +{% endif %} {% for graph in graphs %}
  • diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index 2d4af95e..60a97c29 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -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: diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 96de0892..5cf8d9a4 100644 Binary files a/rowers/tests/testdata/testdata.tcx.gz and b/rowers/tests/testdata/testdata.tcx.gz differ diff --git a/rowers/urls.py b/rowers/urls.py index afe89f63..18b28d66 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -366,6 +366,8 @@ urlpatterns = [ views.course_follow_view, name='course_follow_view'), re_path(r'^courses/(?P\d+)/unfollow/', views.course_unfollow_view, name='course_unfollow_view'), + re_path(r'^courses/(?P\d+)/workout/(?P\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\d+)/$', @@ -385,6 +387,8 @@ urlpatterns = [ re_path( r'^user-analysis-select/(?P\w.*)/team/(?P\d+)/workout/(?P\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'), + re_path(r'workout/(?P\b[0-9A-Fa-f]+\b)/submit/(?P\d+)/$', + views.workout_submit_course_view, name='workout_submit_course_view'), re_path(r'^workouts-dupes-select/user/(?P\d+)/$', views.workouts_duplicates_select_view, name='workouts_duplicates_select_view'), re_path(r'^workouts-dupes-select/$', diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index 006de323..c233a985 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -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, } ) diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 73719594..fe0724b3 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -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,8 +6098,71 @@ 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 here') + + url = reverse('workout_edit_view', kwargs={'id': encoder.encode_hex(row.id)}) + return HttpResponseRedirect(url) + @login_required() @permission_required('workout.change_workout', fn=get_workout_by_opaqueid, raise_exception=True)