Merge branch 'release/v6.64'
This commit is contained in:
@@ -28,9 +28,12 @@ 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,PlannedSession
|
polygon_coord_center,PlannedSession,
|
||||||
|
polygon_to_path,coordinate_in_path
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from utils import geo_distance
|
||||||
|
|
||||||
# low level methods
|
# low level methods
|
||||||
class InvalidTrajectoryError(Exception):
|
class InvalidTrajectoryError(Exception):
|
||||||
def __init__(self,value):
|
def __init__(self,value):
|
||||||
@@ -39,6 +42,7 @@ class InvalidTrajectoryError(Exception):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
|
|
||||||
def get_course_timezone(course):
|
def get_course_timezone(course):
|
||||||
polygons = GeoPolygon.objects.filter(course = course)
|
polygons = GeoPolygon.objects.filter(course = course)
|
||||||
points = GeoPoint.objects.filter(polygon = polygons[0])
|
points = GeoPoint.objects.filter(polygon = polygons[0])
|
||||||
@@ -58,19 +62,6 @@ def get_course_timezone(course):
|
|||||||
|
|
||||||
return timezone_str
|
return timezone_str
|
||||||
|
|
||||||
def polygon_to_path(polygon):
|
|
||||||
points = GeoPoint.objects.filter(polygon=polygon).order_by("order_in_poly")
|
|
||||||
s = []
|
|
||||||
for point in points:
|
|
||||||
s.append([point.latitude,point.longitude])
|
|
||||||
|
|
||||||
p = path.Path(s[:-1])
|
|
||||||
|
|
||||||
return p
|
|
||||||
|
|
||||||
def coordinate_in_path(latitude,longitude, p):
|
|
||||||
|
|
||||||
return p.contains_points([(latitude,longitude)])[0]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -293,7 +284,7 @@ def get_time_course(ws,course):
|
|||||||
rowdata = rowdata.resample('100ms',on='dt').mean()
|
rowdata = rowdata.resample('100ms',on='dt').mean()
|
||||||
rowdata = rowdata.interpolate()
|
rowdata = rowdata.interpolate()
|
||||||
|
|
||||||
polygons = GeoPolygon.objects.filter(course=course)
|
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
|
||||||
paths = []
|
paths = []
|
||||||
for polygon in polygons:
|
for polygon in polygons:
|
||||||
path = polygon_to_path(polygon)
|
path = polygon_to_path(polygon)
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ from courses import (
|
|||||||
polygon_coord_center
|
polygon_coord_center
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from rowers.models import course_spline
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import math
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -853,6 +855,8 @@ def course_map(course):
|
|||||||
latmean,lonmean,coordinates = course_coord_center(course)
|
latmean,lonmean,coordinates = course_coord_center(course)
|
||||||
lat_min, lat_max, long_min, long_max = course_coord_maxmin(course)
|
lat_min, lat_max, long_min, long_max = course_coord_maxmin(course)
|
||||||
|
|
||||||
|
coordinates = course_spline(coordinates)
|
||||||
|
|
||||||
scoordinates = "["
|
scoordinates = "["
|
||||||
|
|
||||||
for index,row in coordinates.iterrows():
|
for index,row in coordinates.iterrows():
|
||||||
@@ -2208,7 +2212,6 @@ def interactive_chart(id=0,promember=0):
|
|||||||
|
|
||||||
script, div = components(plot)
|
script, div = components(plot)
|
||||||
|
|
||||||
|
|
||||||
return [script,div]
|
return [script,div]
|
||||||
|
|
||||||
def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='',
|
def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='',
|
||||||
|
|||||||
221
rowers/models.py
221
rowers/models.py
@@ -18,6 +18,9 @@ import twitter
|
|||||||
import re
|
import re
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
|
from scipy.interpolate import splprep, splev, CubicSpline
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
@@ -29,9 +32,10 @@ import datetime
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from rowers.rows import validate_file_extension
|
from rowers.rows import validate_file_extension
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from timezonefinder import TimezoneFinder
|
||||||
|
|
||||||
import types
|
import types
|
||||||
|
from matplotlib import path
|
||||||
|
|
||||||
from rowsandall_app.settings import (
|
from rowsandall_app.settings import (
|
||||||
TWEET_ACCESS_TOKEN_KEY,
|
TWEET_ACCESS_TOKEN_KEY,
|
||||||
@@ -362,7 +366,46 @@ def polygon_coord_center(polygon):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def polygon_to_path(polygon):
|
||||||
|
points = GeoPoint.objects.filter(polygon=polygon).order_by("order_in_poly")
|
||||||
|
s = []
|
||||||
|
for point in points:
|
||||||
|
s.append([point.latitude,point.longitude])
|
||||||
|
|
||||||
|
p = path.Path(s[:-1])
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
def coordinate_in_path(latitude,longitude, p):
|
||||||
|
|
||||||
|
return p.contains_points([(latitude,longitude)])[0]
|
||||||
|
|
||||||
|
def course_spline(coordinates):
|
||||||
|
latitudes = coordinates['latitude'].values
|
||||||
|
longitudes = coordinates['longitude'].values
|
||||||
|
|
||||||
|
# spline parameters
|
||||||
|
s = 1.0
|
||||||
|
k = min([5,len(latitudes)-1])
|
||||||
|
nest = -1
|
||||||
|
|
||||||
|
t = np.linspace(0,1,len(latitudes))
|
||||||
|
tnew = np.linspace(0,1,100)
|
||||||
|
|
||||||
|
latnew = CubicSpline(t,latitudes,bc_type='clamped')(tnew)
|
||||||
|
lonnew = CubicSpline(t,longitudes,bc_type='clamped')(tnew)
|
||||||
|
# latnew = CubicSpline(t,latitudes,bc_type='natural')(tnew)
|
||||||
|
# lonnew = CubicSpline(t,longitudes,bc_type='natural')(tnew)
|
||||||
|
|
||||||
|
# tckp,u = splprep([t,latitudes,longitudes],s=s,k=k,nest=nest)
|
||||||
|
# tnew,latnew,lonnew = splev(np.linspace(0,1,100),tckp)
|
||||||
|
|
||||||
|
newcoordinates = pd.DataFrame({
|
||||||
|
'latitude':latnew,
|
||||||
|
'longitude':lonnew,
|
||||||
|
})
|
||||||
|
|
||||||
|
return newcoordinates
|
||||||
|
|
||||||
def course_coord_center(course):
|
def course_coord_center(course):
|
||||||
|
|
||||||
@@ -379,11 +422,13 @@ def course_coord_center(course):
|
|||||||
latitude = pd.Series(latitudes).median()
|
latitude = pd.Series(latitudes).median()
|
||||||
longitude = pd.Series(longitudes).median()
|
longitude = pd.Series(longitudes).median()
|
||||||
|
|
||||||
|
|
||||||
coordinates = pd.DataFrame({
|
coordinates = pd.DataFrame({
|
||||||
'latitude':latitudes,
|
'latitude':latitudes,
|
||||||
'longitude':longitudes,
|
'longitude':longitudes,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
return latitude,longitude,coordinates
|
return latitude,longitude,coordinates
|
||||||
|
|
||||||
def course_coord_maxmin(course):
|
def course_coord_maxmin(course):
|
||||||
@@ -406,6 +451,62 @@ def course_coord_maxmin(course):
|
|||||||
|
|
||||||
return lat_min,lat_max,long_min,long_max
|
return lat_min,lat_max,long_min,long_max
|
||||||
|
|
||||||
|
def get_dir_vector(polygon1,polygon2):
|
||||||
|
lat1,lon1 = polygon_coord_center(polygon1)
|
||||||
|
lat2,lon2 = polygon_coord_center(polygon2)
|
||||||
|
|
||||||
|
return [lat2-lat1,lon2-lon1]
|
||||||
|
|
||||||
|
def get_delta(vector,polygon):
|
||||||
|
x = pd.Series(range(10000))/9999.
|
||||||
|
vlat = vector[0]
|
||||||
|
vlon = vector[1]
|
||||||
|
|
||||||
|
lat1,lon1 = polygon_coord_center(polygon)
|
||||||
|
|
||||||
|
lat = x.apply(lambda x:lat1+x*vlat)
|
||||||
|
lon = x.apply(lambda x:lon1+x*vlon)
|
||||||
|
|
||||||
|
totdist,bearing = geo_distance(lat1,lon1,lat1+vlat,lon1+vlon)
|
||||||
|
|
||||||
|
dist = x*totdist
|
||||||
|
|
||||||
|
p = polygon_to_path(polygon)
|
||||||
|
|
||||||
|
f = lambda x: coordinate_in_path(x['lat'],x['lon'],p)
|
||||||
|
|
||||||
|
df = pd.DataFrame({'x':x,
|
||||||
|
'lat':lat,
|
||||||
|
'lon':lon,
|
||||||
|
'dist':dist,
|
||||||
|
})
|
||||||
|
|
||||||
|
df['inpolygon'] = df.apply(f,axis=1)
|
||||||
|
|
||||||
|
|
||||||
|
b = (~df['inpolygon']).shift(-1)+df['inpolygon']
|
||||||
|
|
||||||
|
|
||||||
|
if len(df[b==2]):
|
||||||
|
return 1.0e3*df[b==2]['dist'].min()
|
||||||
|
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_delta_start(course):
|
||||||
|
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
|
||||||
|
vector = get_dir_vector(polygons[0],polygons[1])
|
||||||
|
delta = get_delta(vector,polygons[0])
|
||||||
|
|
||||||
|
return delta
|
||||||
|
|
||||||
|
def get_delta_finish(course):
|
||||||
|
polygons = GeoPolygon.objects.filter(course=course).order_by("-order_in_course")
|
||||||
|
vector = get_dir_vector(polygons[0],polygons[1])
|
||||||
|
delta = get_delta(vector,polygons[0])
|
||||||
|
|
||||||
|
return delta
|
||||||
|
|
||||||
def course_length(course):
|
def course_length(course):
|
||||||
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
|
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
|
||||||
@@ -420,7 +521,14 @@ def course_length(course):
|
|||||||
|
|
||||||
totaldist += 1000.*dist[0]
|
totaldist += 1000.*dist[0]
|
||||||
|
|
||||||
return int(totaldist)
|
vector = get_dir_vector(polygons[0],polygons[1])
|
||||||
|
deltastart = get_delta(vector,polygons[0])
|
||||||
|
|
||||||
|
polygons = polygons.reverse()
|
||||||
|
vector = get_dir_vector(polygons[0],polygons[1])
|
||||||
|
deltafinish = get_delta(vector,polygons[0])
|
||||||
|
|
||||||
|
return int(totaldist-deltastart-deltafinish)
|
||||||
|
|
||||||
sexcategories = (
|
sexcategories = (
|
||||||
('male','male'),
|
('male','male'),
|
||||||
@@ -765,9 +873,10 @@ class GeoCourse(models.Model):
|
|||||||
name = self.name
|
name = self.name
|
||||||
country = self.country
|
country = self.country
|
||||||
|
|
||||||
return u'{country} - {name}'.format(
|
return u'{country} - {name} - {d}m'.format(
|
||||||
name=name,
|
name=name,
|
||||||
country=country
|
country=country,
|
||||||
|
d = course_length(self)
|
||||||
)
|
)
|
||||||
|
|
||||||
class GeoCourseEditForm(ModelForm):
|
class GeoCourseEditForm(ModelForm):
|
||||||
@@ -784,6 +893,16 @@ class GeoPolygon(models.Model):
|
|||||||
course = models.ForeignKey(GeoCourse, blank=True)
|
course = models.ForeignKey(GeoCourse, blank=True)
|
||||||
order_in_course = models.IntegerField(default=0)
|
order_in_course = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
name = self.name
|
||||||
|
coursename = self.course.name
|
||||||
|
|
||||||
|
return u'{coursename} - {name}'.format(
|
||||||
|
name=name,
|
||||||
|
coursename=coursename
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Need error checking to insert new polygons into existing course (all later polygons
|
# Need error checking to insert new polygons into existing course (all later polygons
|
||||||
# increase there order_in_course number
|
# increase there order_in_course number
|
||||||
|
|
||||||
@@ -1069,9 +1188,12 @@ registerchoices = (
|
|||||||
|
|
||||||
class VirtualRace(PlannedSession):
|
class VirtualRace(PlannedSession):
|
||||||
# has_registration = models.BooleanField(default=False)
|
# has_registration = models.BooleanField(default=False)
|
||||||
registration_form = models.CharField(max_length=100,
|
registration_form = models.CharField(
|
||||||
|
max_length=100,
|
||||||
default='windowstart',
|
default='windowstart',
|
||||||
choices=registerchoices)
|
choices=registerchoices,
|
||||||
|
verbose_name='Registration Closure Quick Selector'
|
||||||
|
)
|
||||||
registration_closure = models.DateTimeField(blank=True,null=True)
|
registration_closure = models.DateTimeField(blank=True,null=True)
|
||||||
evaluation_closure = models.DateTimeField(blank=True,null=True)
|
evaluation_closure = models.DateTimeField(blank=True,null=True)
|
||||||
start_time = models.TimeField(blank=True,null=True)
|
start_time = models.TimeField(blank=True,null=True)
|
||||||
@@ -1105,6 +1227,35 @@ class VirtualRace(PlannedSession):
|
|||||||
return stri
|
return stri
|
||||||
|
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
# test race window logic
|
||||||
|
|
||||||
|
start_time = self.start_time
|
||||||
|
start_date = self.startdate
|
||||||
|
startdatetime = datetime.datetime.combine(start_date,start_time)
|
||||||
|
startdatetime = pytz.timezone(self.timezone).localize(
|
||||||
|
startdatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
end_time = self.end_time
|
||||||
|
end_date = self.enddate
|
||||||
|
enddatetime = datetime.datetime.combine(end_date,end_time)
|
||||||
|
enddatetime = pytz.timezone(self.timezone).localize(
|
||||||
|
enddatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
if startdatetime > enddatetime:
|
||||||
|
self.start_time = end_time
|
||||||
|
self.startdate = end_date
|
||||||
|
self.end_time = start_time
|
||||||
|
self.enddate = start_date
|
||||||
|
enddatetime = startdatetime
|
||||||
|
|
||||||
|
if self.evaluation_closure < enddatetime:
|
||||||
|
self.evaluation_closure = enddatetime + timezone.timedelta(days=1)
|
||||||
|
|
||||||
|
super(VirtualRace,self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Date input utility
|
# Date input utility
|
||||||
class DateInput(forms.DateInput):
|
class DateInput(forms.DateInput):
|
||||||
@@ -1143,6 +1294,26 @@ class PlannedSessionForm(ModelForm):
|
|||||||
super(PlannedSessionForm, self).__init__(*args, **kwargs)
|
super(PlannedSessionForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name")
|
self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name")
|
||||||
|
|
||||||
|
def get_course_timezone(course):
|
||||||
|
polygons = GeoPolygon.objects.filter(course = course)
|
||||||
|
points = GeoPoint.objects.filter(polygon = polygons[0])
|
||||||
|
lat = points[0].latitude
|
||||||
|
lon = points[0].longitude
|
||||||
|
|
||||||
|
tf = TimezoneFinder()
|
||||||
|
try:
|
||||||
|
timezone_str = tf.timezone_at(lng=lon,lat=lat)
|
||||||
|
except ValueError:
|
||||||
|
timezone_str = 'UTC'
|
||||||
|
|
||||||
|
if timezone_str is None:
|
||||||
|
timezone_str = tf.closest_timezone_at(lng=lon,lat=lat)
|
||||||
|
if timezone_str is None:
|
||||||
|
timezone_str = 'UTC'
|
||||||
|
|
||||||
|
return timezone_str
|
||||||
|
|
||||||
|
|
||||||
class VirtualRaceForm(ModelForm):
|
class VirtualRaceForm(ModelForm):
|
||||||
course = forms.ModelChoiceField(queryset = GeoCourse.objects, empty_label=None)
|
course = forms.ModelChoiceField(queryset = GeoCourse.objects, empty_label=None)
|
||||||
registration_closure = forms.SplitDateTimeField(widget=AdminSplitDateTime(),required=False)
|
registration_closure = forms.SplitDateTimeField(widget=AdminSplitDateTime(),required=False)
|
||||||
@@ -1187,6 +1358,44 @@ class VirtualRaceForm(ModelForm):
|
|||||||
self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name")
|
self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name")
|
||||||
|
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cd = self.cleaned_data
|
||||||
|
course = cd['course']
|
||||||
|
geocourse = GeoCourse.objects.get(id=course.id)
|
||||||
|
timezone_str = get_course_timezone(geocourse)
|
||||||
|
|
||||||
|
start_time = cd['start_time']
|
||||||
|
start_date = cd['startdate']
|
||||||
|
startdatetime = datetime.datetime.combine(start_date,start_time)
|
||||||
|
startdatetime = pytz.timezone(timezone_str).localize(
|
||||||
|
startdatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
end_time = cd['end_time']
|
||||||
|
end_date = cd['enddate']
|
||||||
|
enddatetime = datetime.datetime.combine(end_date,end_time)
|
||||||
|
enddatetime = pytz.timezone(timezone_str).localize(
|
||||||
|
enddatetime
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if startdatetime > enddatetime:
|
||||||
|
raise forms.ValidationError("The Start of the Race Window should be before the End of the Race Window")
|
||||||
|
|
||||||
|
try:
|
||||||
|
evaluation_closure = cd['evaluation_closure']
|
||||||
|
except KeyError:
|
||||||
|
evaluation_closure = enddatetime+datetime.timedelta(days=1)
|
||||||
|
cd['evaluation_closure'] = evaluation_closure
|
||||||
|
|
||||||
|
if cd['evaluation_closure'] <= enddatetime:
|
||||||
|
raise forms.ValidationError("Evaluation closure deadline should be after the Race Window closes")
|
||||||
|
|
||||||
|
if cd['evaluation_closure'] <= timezone.now():
|
||||||
|
raise forms.ValidationError("Evaluation closure cannot be in the past")
|
||||||
|
|
||||||
|
|
||||||
|
return cd
|
||||||
|
|
||||||
class PlannedSessionFormSmall(ModelForm):
|
class PlannedSessionFormSmall(ModelForm):
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th> Country</th>
|
<th> Country</th>
|
||||||
<th> Name</th>
|
<th> Name</th>
|
||||||
|
<th> Distance</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -41,6 +42,9 @@
|
|||||||
<a href="/rowers/courses/{{ course.id }}">{{ course.name }}</a>
|
<a href="/rowers/courses/{{ course.id }}">{{ course.name }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ course|courselength }} m
|
||||||
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}">Edit</a>
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}">Edit</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/clone/{{ timeperoid }}/rower/{{ rower.id }}">Clone</a>
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/clone/{{ timeperiod }}/rower/{{ rower.id }}">Clone</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -96,7 +96,8 @@
|
|||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}">Edit</a>
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}">Edit</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/clone/{{ timeperiod }}/rower/{{ rower.id }}">Clone</a>
|
<a class="small"
|
||||||
|
href="/rowers/sessions/{{ ps.id }}/clone/{{ timeperiod }}/rower/{{ rower.id }}">Clone</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm">Delete</a>
|
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm">Delete</a>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load rowerfilters %}
|
{% load rowerfilters %}
|
||||||
|
|
||||||
{% block title %}New Virtual Race{% endblock %}
|
{% block title %}Rowsandall Virtual Race{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import json
|
|||||||
import datetime
|
import datetime
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
from rowers.utils import calculate_age
|
from rowers.utils import calculate_age
|
||||||
|
from rowers.models import course_length
|
||||||
from rowers.plannedsessions import (
|
from rowers.plannedsessions import (
|
||||||
race_can_register, race_can_submit,race_rower_status
|
race_can_register, race_can_submit,race_rower_status
|
||||||
)
|
)
|
||||||
@@ -75,6 +76,9 @@ def deltatimeprint(d):
|
|||||||
else:
|
else:
|
||||||
return strfdeltah(d)
|
return strfdeltah(d)
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def courselength(course):
|
||||||
|
return course_length(course)
|
||||||
|
|
||||||
@register.filter(is_safe=True)
|
@register.filter(is_safe=True)
|
||||||
def jsdict(dict,key):
|
def jsdict(dict,key):
|
||||||
|
|||||||
@@ -463,9 +463,9 @@ urlpatterns = [
|
|||||||
url(r'^sessions/multicreate/(?P<timeperiod>[\w\ ]+.*)$',
|
url(r'^sessions/multicreate/(?P<timeperiod>[\w\ ]+.*)$',
|
||||||
views.plannedsession_multicreate_view),
|
views.plannedsession_multicreate_view),
|
||||||
|
|
||||||
url(r'^sessions/(?P<id>\d+)/edit$',views.plannedsession_edit_view),
|
|
||||||
url(r'^sessions/(?P<id>\d+)/edit/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',views.plannedsession_edit_view),
|
url(r'^sessions/(?P<id>\d+)/edit/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',views.plannedsession_edit_view),
|
||||||
url(r'^sessions/(?P<id>\d+)/edit/(?P<timeperiod>[\w\ ]+.*)$',views.plannedsession_edit_view),
|
url(r'^sessions/(?P<id>\d+)/edit/(?P<timeperiod>[\w\ ]+.*)$',views.plannedsession_edit_view),
|
||||||
|
url(r'^sessions/(?P<id>\d+)/edit$',views.plannedsession_edit_view),
|
||||||
|
|
||||||
url(r'^sessions/(?P<id>\d+)/clone$',views.plannedsession_clone_view),
|
url(r'^sessions/(?P<id>\d+)/clone$',views.plannedsession_clone_view),
|
||||||
url(r'^sessions/(?P<id>\d+)/clone/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',views.plannedsession_clone_view),
|
url(r'^sessions/(?P<id>\d+)/clone/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',views.plannedsession_clone_view),
|
||||||
|
|||||||
@@ -253,8 +253,9 @@ def isbreakthrough(delta,cpvalues,p0,p1,p2,p3,ratio):
|
|||||||
pwr *= ratio
|
pwr *= ratio
|
||||||
|
|
||||||
|
|
||||||
delta = delta.values
|
delta = delta.values.astype(int)
|
||||||
cpvalues = cpvalues.values
|
cpvalues = cpvalues.values.astype(int)
|
||||||
|
pwr = pwr.astype(int)
|
||||||
|
|
||||||
res = np.sum(cpvalues>pwr)
|
res = np.sum(cpvalues>pwr)
|
||||||
res2 = np.sum(cpvalues>pwr2)
|
res2 = np.sum(cpvalues>pwr2)
|
||||||
|
|||||||
@@ -10822,7 +10822,13 @@ def workout_split_view(request,id=id):
|
|||||||
splitsecond += splittime.second
|
splitsecond += splittime.second
|
||||||
splitsecond += splittime.microsecond/1.e6
|
splitsecond += splittime.microsecond/1.e6
|
||||||
splitmode = form.cleaned_data['splitmode']
|
splitmode = form.cleaned_data['splitmode']
|
||||||
ids,mesgs = dataprep.split_workout(r,row,splitsecond,splitmode)
|
try:
|
||||||
|
ids,mesgs = dataprep.split_workout(
|
||||||
|
r,row,splitsecond,splitmode
|
||||||
|
)
|
||||||
|
except IndexError:
|
||||||
|
messages.error("Something went wrong in Split")
|
||||||
|
|
||||||
for message in mesgs:
|
for message in mesgs:
|
||||||
messages.info(request,message)
|
messages.info(request,message)
|
||||||
|
|
||||||
@@ -13588,7 +13594,6 @@ def virtualevent_create_view(request):
|
|||||||
startdatetime = datetime.datetime.combine(startdate,start_time)
|
startdatetime = datetime.datetime.combine(startdate,start_time)
|
||||||
enddatetime = datetime.datetime.combine(enddate,end_time)
|
enddatetime = datetime.datetime.combine(enddate,end_time)
|
||||||
|
|
||||||
print enddatetime
|
|
||||||
|
|
||||||
startdatetime = pytz.timezone(timezone_str).localize(
|
startdatetime = pytz.timezone(timezone_str).localize(
|
||||||
startdatetime
|
startdatetime
|
||||||
|
|||||||
Reference in New Issue
Block a user