Private
Public Access
1
0

Merge branch 'release/v6.52'

This commit is contained in:
Sander Roosendaal
2018-04-25 15:22:24 +02:00
12 changed files with 170 additions and 30 deletions

View File

@@ -28,7 +28,7 @@ from rowers.models import (
Rower, Workout, Rower, Workout,
GeoPoint,GeoPolygon, GeoCourse, GeoPoint,GeoPolygon, GeoCourse,
course_length,course_coord_center,course_coord_maxmin, course_length,course_coord_center,course_coord_maxmin,
polygon_coord_center polygon_coord_center,PlannedSession
) )
# low level methods # low level methods
@@ -307,3 +307,13 @@ def get_time_course(ws,course):
coursemeters = coursemeters-coursemetersfirst coursemeters = coursemeters-coursemetersfirst
return coursetimeseconds,coursemeters,coursecompleted return coursetimeseconds,coursemeters,coursecompleted
def replacecourse(course1,course2):
ps = PlannedSession.objects.filter(course=course1)
for p in ps:
p.course = course2
p.save()
course1.delete()
return 1

View File

@@ -1,6 +1,6 @@
from django import forms from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple from django.contrib.admin.widgets import FilteredSelectMultiple
from rowers.models import Workout,Rower,Team,PlannedSession from rowers.models import Workout,Rower,Team,PlannedSession,GeoCourse
from rowers.rows import validate_file_extension,must_be_csv,validate_image_extension,validate_kml from rowers.rows import validate_file_extension,must_be_csv,validate_image_extension,validate_kml
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
@@ -536,6 +536,9 @@ class StatsOptionsForm(forms.Form):
coastal = forms.BooleanField(initial=False,required=False) coastal = forms.BooleanField(initial=False,required=False)
other = forms.BooleanField(initial=False,required=False) other = forms.BooleanField(initial=False,required=False)
class CourseSelectForm(forms.Form):
course = forms.ModelChoiceField(queryset=GeoCourse.objects.all())
class WorkoutMultipleCompareForm(forms.Form): class WorkoutMultipleCompareForm(forms.Form):
workouts = forms.ModelMultipleChoiceField(queryset=Workout.objects.all(), workouts = forms.ModelMultipleChoiceField(queryset=Workout.objects.all(),
widget=forms.CheckboxSelectMultiple()) widget=forms.CheckboxSelectMultiple())

View File

@@ -15,8 +15,7 @@
<h1>{{ workout.name }} - Advanced</h1> <h1>{{ workout.name }} - Advanced</h1>
{% if user.rower.rowerplan == 'basic' %} {% if user.rower.rowerplan == 'basic' %}
<p>This is a preview of the page with advanced functionality for Pro users. <p>Functionality marked with an asterisk (*) is limited to the paid plans. See
See
<a href="/rowers/promembership">the page about Pro membership</a> <a href="/rowers/promembership">the page about Pro membership</a>
for more information and to sign up for Pro Membership</a></p> for more information and to sign up for Pro Membership</a></p>
{% endif %} {% endif %}
@@ -63,7 +62,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ workout.id }}">Compare Workouts</a> <a class="button blue small" href="/rowers/workout/compare/{{ workout.id }}">Compare Workouts</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership/">Compare Workouts</a> <a class="button blue small" href="/rowers/promembership/">Compare Workouts*</a>
{% endif %} {% endif %}
<p> <p>
Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts. Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts.
@@ -83,7 +82,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/editintervals">Edit Intervals</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/editintervals">Edit Intervals</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Edit Intervals</a> <a class="button blue small" href="/rowers/promembership">Edit Intervals*</a>
{% endif %} {% endif %}
</p> </p>
<span class="tooltiptext">Enter or change the interval and summary data for your workout</span> <span class="tooltiptext">Enter or change the interval and summary data for your workout</span>
@@ -94,13 +93,12 @@
</div> </div>
</div> </div>
<div class="grid_6 alpha"> <div class="grid_6 alpha">
<div class="grid_2 alpha"> <div class="grid_2 alpha">
<p> <p>
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/adddistanceplot2">Dist Metrics Plot</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/adddistanceplot2">Dist Metrics Plot</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Dist Metrics Plot</a> <a class="button blue small" href="/rowers/promembership">Dist Metrics Plot*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -112,7 +110,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addtimeplot2">Time Metrics Plot</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/addtimeplot2">Time Metrics Plot</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Time Metrics Plot</a> <a class="button blue small" href="/rowers/promembership">Time Metrics Plot*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -124,7 +122,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/histo">Power Histogram</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/histo">Power Histogram</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Power Histogram</a> <a class="button blue small" href="/rowers/promembership">Power Histogram*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -138,7 +136,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workouts-join-select">Glue</a> <a class="button blue small" href="/rowers/workouts-join-select">Glue</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Glue</a> <a class="button blue small" href="/rowers/promembership">Glue*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -151,7 +149,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/fusion/{{ workout.id }}/">Sensor Fusion</a> <a class="button blue small" href="/rowers/workout/fusion/{{ workout.id }}/">Sensor Fusion</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Sensor Fusion</a> <a class="button blue small" href="/rowers/promembership">Sensor Fusion*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -163,7 +161,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/split">Split Workout</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/split">Split Workout</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Split Workout</a> <a class="button blue small" href="/rowers/promembership">Split Workout*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>

View File

@@ -15,8 +15,9 @@
<h1>{{ workout.name }} - Advanced OTW</h1> <h1>{{ workout.name }} - Advanced OTW</h1>
{% if user.rower.rowerplan == 'basic' %} {% if user.rower.rowerplan == 'basic' %}
<p>This is a preview of the page with advanced functionality for Pro users. <p>Functionality marked with an asterisk (*) is limited to the paid plans. See
See <a href="/rowers/promembership">the page about Pro membership</a> for more information and to sign up for Pro Membership</a> <a href="/rowers/promembership">the page about Pro membership</a>
for more information and to sign up for Pro Membership</a></p>
{% endif %} {% endif %}
<div class="grid_2 alpha"> <div class="grid_2 alpha">
<p> <p>
@@ -59,7 +60,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ workout.id }}">Compare Workouts</a> <a class="button blue small" href="/rowers/workout/compare/{{ workout.id }}">Compare Workouts</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Compare Workouts</a> <a class="button blue small" href="/rowers/promembership">Compare Workouts*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -81,7 +82,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/editintervals">Edit Intervals</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/editintervals">Edit Intervals</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Edit Intervals</a> <a class="button blue small" href="/rowers/promembership">Edit Intervals*</a>
{% endif %} {% endif %}
</p> </p>
<span class="tooltiptext">Enter or change the interval and summary data for your workout</span> <span class="tooltiptext">Enter or change the interval and summary data for your workout</span>
@@ -98,7 +99,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id }}/crewnerdsummary">CrewNerd Summary</a> <a class="button blue small"href="/rowers/workout/{{ workout.id }}/crewnerdsummary">CrewNerd Summary</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">CrewNerd Summary</a> <a class="button blue small" href="/rowers/promembership">CrewNerd Summary*</a>
{% endif %} {% endif %}
</p> </p>
@@ -112,7 +113,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/forcecurve">Stroke Profile (Empower)</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/forcecurve">Stroke Profile (Empower)</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Stroke Profile (Empower)</a> <a class="button blue small" href="/rowers/promembership">Stroke Profile (Empower)*</a>
{% endif %} {% endif %}
</p> </p>
<span class="tooltiptext">Analyze your stroke force profile (need Empower Oarlock data)</span> <p> <span class="tooltiptext">Analyze your stroke force profile (need Empower Oarlock data)</span> <p>
@@ -125,7 +126,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addotwpowerplot">OTW Power Plot</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/addotwpowerplot">OTW Power Plot</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">OTW Power Plot</a> <a class="button blue small" href="/rowers/promembership">OTW Power Plot*</a>
{% endif %} {% endif %}
</p> </p>
<span class="tooltiptext">Note: You must run the OTW calculations under Geeky Stuff first. Otherwise the plot will be empty</span> <span class="tooltiptext">Note: You must run the OTW calculations under Geeky Stuff first. Otherwise the plot will be empty</span>
@@ -145,7 +146,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/geeky">Geeky Stuff</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/geeky">Geeky Stuff</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Geeky Stuff</a> <a class="button blue small" href="/rowers/promembership">Geeky Stuff*</a>
{% endif %} {% endif %}
</p> </p>
@@ -160,7 +161,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id }}/smoothenpace">Smooth out Pace Data</a> <a class="button blue small"href="/rowers/workout/{{ workout.id }}/smoothenpace">Smooth out Pace Data</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Smooth out Pace Data</a> <a class="button blue small" href="/rowers/promembership">Smooth out Pace Data*</a>
{% endif %} {% endif %}
</p> </p>
@@ -177,7 +178,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id }}/undosmoothenpace">Raw Data</a> <a class="button blue small"href="/rowers/workout/{{ workout.id }}/undosmoothenpace">Raw Data</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Reset Smoothing</a> <a class="button blue small" href="/rowers/promembership">Reset Smoothing*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -192,7 +193,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workouts-join-select">Glue</a> <a class="button blue small" href="/rowers/workouts-join-select">Glue</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Glue</a> <a class="button blue small" href="/rowers/promembership">Glue*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -204,7 +205,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/fusion/{{ workout.id }}/">Sensor Fusion</a> <a class="button blue small" href="/rowers/workout/fusion/{{ workout.id }}/">Sensor Fusion</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Sensor Fusion</a> <a class="button blue small" href="/rowers/promembership">Sensor Fusion*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>
@@ -216,7 +217,7 @@
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/split">Split Workout</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/split">Split Workout</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Split Workout</a> <a class="button blue small" href="/rowers/promembership">Split Workout*</a>
{% endif %} {% endif %}
</p> </p>
<p> <p>

View File

@@ -39,7 +39,10 @@
<li> Concept2 Logbook: Exports stroke by stroke data for erg and OTW rowing</li> <li> Concept2 Logbook: Exports stroke by stroke data for erg and OTW rowing</li>
<li> Strava </li> <li> Strava </li>
<li> SportTracks</li> <li> SportTracks</li>
<li> email (TCX or CSV format)</li></ul></p> <li> Runkeeper</li>
<li> MapMyFitness</li>
<li> TrainingPeaks</li>
<li> email (TCX, GPX or CSV format)</li></ul></p>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@@ -13,7 +13,8 @@
{% if nosessions %} {% if nosessions %}
<a class="button small red" href="/rowers/courses/{{ course.id }}/delete">Delete</a> <a class="button small red" href="/rowers/courses/{{ course.id }}/delete">Delete</a>
{% else %} {% else %}
&nbsp; <a class="button small red" href="/rowers/courses/{{ course.id }}/replace">
Update</a>
{% endif %} {% endif %}
</div> </div>
<div class="grid_2"> <div class="grid_2">

View File

@@ -0,0 +1,51 @@
{% extends "base.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block scripts %}
{% include "monitorjobs.html" %}
{% endblock %}
{% block title %}{{ course.name }} {% endblock %}
{% block og_title %}{{ course.name }} {% endblock %}
{% block content %}
<div class="grid_12 alpha">
<div class="grid_2 prefix_2 alpha">
{% if course.manager == rower %}
<a class="button small gray" href="/rowers/courses/{{ course.id }}">View Course</a>
{% else %}
&nbsp;
{% endif %}
</div>
<div class="grid_2">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
</div>
<div class="grid_12 alpha">
<h1>Replace {{ course.name }}</h1>
<div class="grid_8 alpha">
<p>
This replaces the course {{ course.name }} with the course you select below for all
planned sessions and virtual races, and then deletes this course.
</p>
<form id="course_form" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1 alpha">
<input class="button green" type="submit" value="Submit">
</div>
</form>
</div>
<div class="grid_4 omega">
{{ mapdiv|safe }}
{{ mapscript|safe }}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,7 @@
<div>
{{ mapscript|safe }}
{{ mapdiv|safe }}
</div>

View File

@@ -141,7 +141,7 @@
var istcx = false; var istcx = false;
var isgzip = false; var isgzip = false;
var size1 = 10485760; var size1 = 10485760;
var size2 = 1048576; var size2 = 2097152;
if ((/\.(tcx|TCX)/i).test(f.name)) { if ((/\.(tcx|TCX)/i).test(f.name)) {
istcx = true; istcx = true;
console.log('tcx'); console.log('tcx');

View File

@@ -275,7 +275,11 @@
</div> </div>
{% endif %} {% endif %}
<div class="grid_2 suffix_1 omega"> <div class="grid_2 suffix_1 omega">
{% if user|is_promember %}
<a class="button small gray" href="/rowers/workouts-join-select">Glue Workouts</a> <a class="button small gray" href="/rowers/workouts-join-select">Glue Workouts</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Glue</a>
{% endif %}
</div> </div>
<p>&nbsp;</p> <p>&nbsp;</p>
{% if team %} {% if team %}

View File

@@ -513,7 +513,9 @@ urlpatterns = [
url(r'^courses/(?P<id>\d+)/edit$',views.course_edit_view, url(r'^courses/(?P<id>\d+)/edit$',views.course_edit_view,
name='course_edit_view'), name='course_edit_view'),
url(r'^courses/(?P<id>\d+)/delete$',views.course_delete_view), url(r'^courses/(?P<id>\d+)/delete$',views.course_delete_view),
url(r'^courses/(?P<id>\d+)/replace$',views.course_replace_view),
url(r'^courses/(?P<id>\d+)$',views.course_view), url(r'^courses/(?P<id>\d+)$',views.course_view),
url(r'^courses/(?P<id>\d+)/map$',views.course_map_view),
] ]
if settings.DEBUG: if settings.DEBUG:

View File

@@ -34,7 +34,7 @@ from rowers.forms import (
WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement, WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement,
LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm, LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm,
PlannedSessionTeamForm,PlannedSessionTeamMemberForm, PlannedSessionTeamForm,PlannedSessionTeamMemberForm,
VirtualRaceSelectForm,WorkoutRaceSelectForm, VirtualRaceSelectForm,WorkoutRaceSelectForm,CourseSelectForm,
) )
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
@@ -8841,6 +8841,66 @@ def workout_comment_view(request,id=0):
'form':form, 'form':form,
}) })
# for ajax calls
def course_map_view(request,id=0):
if id != 0:
try:
course = GeoCourse.objects.get(id=id)
except GeoCourse.DoesNotExist:
return Http404("Course doesn't exist")
script,div = course_map(course)
return render(request,
'coursemap.html',
{
'mapdiv':div,
'mapscript':script
})
else:
return ""
@login_required()
def course_replace_view(request,id=0):
try:
course = GeoCourse.objects.get(id=id)
except GeoCourse.DoesNotExist:
return Http404("Course doesn't exist")
r = getrower(request.user)
if course.manager != r:
raise PermissionDenied("Access denied")
thecourses = GeoCourse.objects.filter(manager=r).exclude(id=id)
if request.method == 'POST':
form = CourseSelectForm(request.POST)
if form.is_valid():
course2 = form.cleaned_data['course']
res = courses.replacecourse(course,course2)
url = reverse(course_view,
kwargs = {
'id':course2.id
})
return HttpResponseRedirect(url)
else:
form = CourseSelectForm()
form.fields["course"].queryset = thecourses
script,div = course_map(course)
return render(request,
'course_replace.html',
{'course':course,
'mapdiv':div,
'mapscript':script,
'form':form})
@login_required() @login_required()
def course_delete_view(request,id=0): def course_delete_view(request,id=0):
try: try: