Merge branch 'release/v10.19'
This commit is contained in:
@@ -108,6 +108,7 @@ def alert_get_stats(alert,nperiod=0):
|
|||||||
'nr_strokes':0,
|
'nr_strokes':0,
|
||||||
'nr_strokes_qualifying':0,
|
'nr_strokes_qualifying':0,
|
||||||
'percentage':0,
|
'percentage':0,
|
||||||
|
'nperiod':nperiod,
|
||||||
}
|
}
|
||||||
|
|
||||||
# check if filters are in columns list
|
# check if filters are in columns list
|
||||||
@@ -139,6 +140,7 @@ def alert_get_stats(alert,nperiod=0):
|
|||||||
'nr_strokes':0,
|
'nr_strokes':0,
|
||||||
'nr_strokes_qualifying':0,
|
'nr_strokes_qualifying':0,
|
||||||
'percentage':0,
|
'percentage':0,
|
||||||
|
'nperiod':nperiod,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -168,6 +170,10 @@ def alert_get_stats(alert,nperiod=0):
|
|||||||
else:
|
else:
|
||||||
percentage = 0
|
percentage = 0
|
||||||
|
|
||||||
|
median_q = df2[alert.measured.metric].median()
|
||||||
|
median = df[alert.measured.metric].median()
|
||||||
|
std = df[alert.measured.metric].std()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'workouts':len(workouts),
|
'workouts':len(workouts),
|
||||||
'startdate':startdate,
|
'startdate':startdate,
|
||||||
@@ -175,6 +181,10 @@ def alert_get_stats(alert,nperiod=0):
|
|||||||
'nr_strokes':nr_strokes,
|
'nr_strokes':nr_strokes,
|
||||||
'nr_strokes_qualifying':nr_strokes_qualifying,
|
'nr_strokes_qualifying':nr_strokes_qualifying,
|
||||||
'percentage': percentage,
|
'percentage': percentage,
|
||||||
|
'nperiod':nperiod,
|
||||||
|
'median':median,
|
||||||
|
'median_q':median_q,
|
||||||
|
'standard_dev':std,
|
||||||
}
|
}
|
||||||
|
|
||||||
# run alert report
|
# run alert report
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ class RowerPlanMiddleWare(object):
|
|||||||
paymentprocessor='braintree')
|
paymentprocessor='braintree')
|
||||||
r.paidplan = basicplans[0]
|
r.paidplan = basicplans[0]
|
||||||
r.save()
|
r.save()
|
||||||
|
# remove from Free Coach groups
|
||||||
|
|
||||||
# send email
|
# send email
|
||||||
job = myqueue(queue,
|
job = myqueue(queue,
|
||||||
handle_sendemail_expired,
|
handle_sendemail_expired,
|
||||||
|
|||||||
@@ -878,6 +878,19 @@ class Rower(models.Model):
|
|||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
return self.user.email.lower()
|
return self.user.email.lower()
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
for group in self.coachinggroups.all():
|
||||||
|
try:
|
||||||
|
coach = Rower.objects.get(mycoachgroup=group)
|
||||||
|
if coach.rowerplan == 'freecoach':
|
||||||
|
self.coachinggroups.remove(group)
|
||||||
|
except Rower.DoesNotExist:
|
||||||
|
pass
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
super(Rower, self).save(*args, **kwargs)
|
||||||
|
|
||||||
class DeactivateUserForm(forms.ModelForm):
|
class DeactivateUserForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -1083,6 +1096,11 @@ class Alert(models.Model):
|
|||||||
|
|
||||||
return stri
|
return stri
|
||||||
|
|
||||||
|
def metricname(self):
|
||||||
|
metricdict = {key:value for (key,value) in parchoicesy1}
|
||||||
|
|
||||||
|
return metricdict[self.measured.metric]
|
||||||
|
|
||||||
def description(self):
|
def description(self):
|
||||||
metricdict = {key:value for (key,value) in parchoicesy1}
|
metricdict = {key:value for (key,value) in parchoicesy1}
|
||||||
|
|
||||||
@@ -1105,6 +1123,24 @@ class Alert(models.Model):
|
|||||||
|
|
||||||
return description
|
return description
|
||||||
|
|
||||||
|
def shortdescription(self):
|
||||||
|
metricdict = {key:value for (key,value) in parchoicesy1}
|
||||||
|
|
||||||
|
if self.measured.condition == 'between':
|
||||||
|
description = '{value1} < {metric} < {value2}'.format(
|
||||||
|
metric = self.measured.metric,
|
||||||
|
value1 = self.measured.value1,
|
||||||
|
value2 = self.measured.value2,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
description = '{metric} {condition} {value1}'.format(
|
||||||
|
metric = self.measured.metric,
|
||||||
|
value1 = self.measured.value1,
|
||||||
|
condition = self.measured.condition
|
||||||
|
)
|
||||||
|
|
||||||
|
return description
|
||||||
|
|
||||||
|
|
||||||
class AlertEditForm(ModelForm):
|
class AlertEditForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
+33
-2
@@ -756,6 +756,26 @@ def handle_updatedps(useremail, workoutids, debug=False,**kwargs):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
import math
|
||||||
|
def sigdig(value, digits = 3):
|
||||||
|
try:
|
||||||
|
order = int(math.floor(math.log10(math.fabs(value))))
|
||||||
|
except (ValueError,TypeError):
|
||||||
|
return value
|
||||||
|
|
||||||
|
# return integers as is
|
||||||
|
if value % 1 == 0:
|
||||||
|
return value
|
||||||
|
|
||||||
|
places = digits - order - 1
|
||||||
|
if places > 0:
|
||||||
|
fmtstr = "%%.%df" % (places)
|
||||||
|
else:
|
||||||
|
fmtstr = "%.0f"
|
||||||
|
return fmtstr % (round(value, places))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_send_email_alert(
|
def handle_send_email_alert(
|
||||||
useremail, userfirstname, userlastname, rowerfirstname, alertname, stats, **kwargs):
|
useremail, userfirstname, userlastname, rowerfirstname, alertname, stats, **kwargs):
|
||||||
@@ -770,15 +790,26 @@ def handle_send_email_alert(
|
|||||||
else:
|
else:
|
||||||
othertexts = None
|
othertexts = None
|
||||||
|
|
||||||
subject = "Your rowing performance on rowsandall.com ({startdate} to {enddate})".format(
|
report = {}
|
||||||
|
report['Percentage'] = int(stats['percentage'])
|
||||||
|
report['Number of workouts'] = int(stats['workouts'])
|
||||||
|
report['Data set'] = "{a} strokes out of {b}".format(
|
||||||
|
a = stats['nr_strokes_qualifying'],
|
||||||
|
b = stats['nr_strokes']
|
||||||
|
)
|
||||||
|
report['Median'] = sigdig(stats['median'])
|
||||||
|
report['Median of qualifying strokes'] = sigdig(stats['median_q'])
|
||||||
|
|
||||||
|
subject = "Rowsandall.com: {alertname} ({startdate} to {enddate})".format(
|
||||||
startdate = stats['startdate'],
|
startdate = stats['startdate'],
|
||||||
enddate = stats['enddate'],
|
enddate = stats['enddate'],
|
||||||
|
alertname=alertname,
|
||||||
)
|
)
|
||||||
|
|
||||||
from_email = 'Rowsandall <info@rowsandall.com>'
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
|
|
||||||
d = {
|
d = {
|
||||||
'report':stats,
|
'report':report,
|
||||||
'first_name':userfirstname,
|
'first_name':userfirstname,
|
||||||
'last_name':userlastname,
|
'last_name':userlastname,
|
||||||
'siteurl':siteurl,
|
'siteurl':siteurl,
|
||||||
|
|||||||
+2
-2
@@ -135,8 +135,8 @@ def add_member(id,rower):
|
|||||||
t= Team.objects.get(id=id)
|
t= Team.objects.get(id=id)
|
||||||
try:
|
try:
|
||||||
rower.team.add(t)
|
rower.team.add(t)
|
||||||
except ValidationError:
|
except ValidationError as e:
|
||||||
return(0,"Couldn't add member")
|
return(0,"Couldn't add member: "+str(e.message))
|
||||||
|
|
||||||
# code to add all workouts
|
# code to add all workouts
|
||||||
ws = Workout.objects.filter(user=rower)
|
ws = Workout.objects.filter(user=rower)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{% extends "newbase.html" %}
|
{% extends "newbase.html" %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
{% block title %}Metric Alert{% endblock %}
|
{% block title %}Metric Alert{% endblock %}
|
||||||
|
|
||||||
@@ -13,19 +14,33 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul class="main-content">
|
<ul class="main-content">
|
||||||
|
<li>
|
||||||
|
{{ stats|lookuplong:'startdate' }} - {{ stats|lookuplong:'enddate' }}
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<h2>Alert</h2>
|
<h2>{{ alert.name }}</h2>
|
||||||
<p>{{ alert }}</p>
|
<p>{{ alert }}</p>
|
||||||
<p>{{ alert.description }}</p>
|
<p>{{ alert.description }}</p>
|
||||||
<p>This is a page under construction. Currently with minimal information</p>
|
<p>This is a page under construction. Currently with minimal information</p>
|
||||||
</li>
|
</li>
|
||||||
{% for key, value in stats.items %}
|
<li class="rounder">
|
||||||
<li>
|
<h2>Score</h2>
|
||||||
<h2>{{ key }}</h2>
|
<hr>
|
||||||
<p>{{ value }}</p>
|
<h2>{{ stats|lookup:'percentage' }}%</h2>
|
||||||
|
</li>
|
||||||
|
<li class="rounder">
|
||||||
|
<h2>Data set</h2>
|
||||||
|
<hr>
|
||||||
|
<p>{{ stats|lookup:'workouts' }} workouts</p>
|
||||||
|
<p>{{ stats|lookup:'nr_strokes_qualifying' }} strokes out of {{ stats|lookup:'nr_strokes' }}</p>
|
||||||
|
</li>
|
||||||
|
<li class="rounder">
|
||||||
|
<h2>Statistics</h2>
|
||||||
|
<hr>
|
||||||
|
<p>Median {{ alert.metricname }}: {{ stats|lookup:'median'|sigdig }}</p>
|
||||||
|
<p>Median {{ alert.metricname }}: {{ stats|lookup:'median_q'|sigdig }} ({{ alert.shortdescription }})</p>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<ul class="main-content">
|
<ul class="main-content">
|
||||||
{% if alerts %}
|
{% if alerts %}
|
||||||
{% for alert in alerts %}
|
{% for alert in alerts %}
|
||||||
<li class="rounder">
|
<li class="rounder" id="alert_{{ alert.id }}">
|
||||||
<h2>{{ alert.name }}</h2>
|
<h2>{{ alert.name }}</h2>
|
||||||
<a class="small" href="/rowers/alerts/{{ alert.id }}/edit/" title="Edit">
|
<a class="small" href="/rowers/alerts/{{ alert.id }}/edit/" title="Edit">
|
||||||
<i class="fas fa-pencil-alt fa-fw"></i>
|
<i class="fas fa-pencil-alt fa-fw"></i>
|
||||||
@@ -22,10 +22,24 @@
|
|||||||
title="Delete">
|
title="Delete">
|
||||||
<i class="fas fa-trash-alt fa-fw"></i>
|
<i class="fas fa-trash-alt fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a class="small iteratorleft"
|
||||||
|
data-nperiod="{{ stats|alertnperiod:forloop.counter }}"
|
||||||
|
data-user="{{ rower.user.id }}"
|
||||||
|
data-alertid="{{ alert.id }}"
|
||||||
|
href="/rowers/alerts/{{ alert.id }}/report/">
|
||||||
|
<i class="fas fa-arrow-alt-left fa-fw"></i>
|
||||||
|
</a>
|
||||||
|
<a class="small iteratorright"
|
||||||
|
data-nperiod="{{ stats|alertnperiod:forloop.counter }}"
|
||||||
|
data-user="{{ rower.user.id }}"
|
||||||
|
data-alertid="{{ alert.id }}"
|
||||||
|
href="/rowers/alerts/{{ alert.id }}/report/">
|
||||||
|
<i class="fas fa-arrow-alt-right fa-fw"></i>
|
||||||
|
</a>
|
||||||
<hr>
|
<hr>
|
||||||
<a href="/rowers/alerts/{{ alert.id }}/report/">
|
<a id="percentages" href="/rowers/alerts/{{ alert.id }}/report/">
|
||||||
<div id="id_alert_{{ forloop.counter }}">
|
<div>
|
||||||
<h1>{{ stats|alertstatspercentage:forloop.counter }}%</h1>
|
<h1><span id="percentage">{{ stats|alertstatspercentage:forloop.counter }}</span>%</h1>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
@@ -34,51 +48,16 @@
|
|||||||
<p>
|
<p>
|
||||||
Workout type: {{ alert.workouttype }}
|
Workout type: {{ alert.workouttype }}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p id="dates">
|
||||||
Next Run: {{ alert.next_run }}
|
<span id="startdate">
|
||||||
|
{{ stats|alertstartdate:forloop.counter }}
|
||||||
|
</span> -
|
||||||
|
<span id="enddate">
|
||||||
|
{{ stats|alertenddate:forloop.counter }}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li class="grid_4">
|
|
||||||
<table width="100%" class="listtable shortpadded">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>metric</th>
|
|
||||||
<th>Workout type</th>
|
|
||||||
<th>Next Run</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for alert in alerts %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ alert.name }}</td>
|
|
||||||
<td>{{ alert.measured.metric }}</td>
|
|
||||||
<td>{{ alert.workouttype }}</td>
|
|
||||||
<td>{{ alert.next_run }}</td>
|
|
||||||
<td>
|
|
||||||
<a class="small" href="/rowers/alerts/{{ alert.id }}/edit/" title="Edit">
|
|
||||||
<i class="fas fa-pencil-alt fa-fw"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a class="small"
|
|
||||||
href="/rowers/alerts/{{ alert.id }}/report/"
|
|
||||||
title="Report">
|
|
||||||
<i class="fal fa-table fa-fw"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a class="small" href="/rowers/alerts/{{ alert.id }}/delete/"
|
|
||||||
title="Delete">
|
|
||||||
<i class="fas fa-trash-alt fa-fw"></i>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<p>You have not set any alerts for {{ rower.user.first_name }}</p>
|
<p>You have not set any alerts for {{ rower.user.first_name }}</p>
|
||||||
@@ -95,6 +74,61 @@
|
|||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script type='text/javascript'
|
||||||
|
src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$(".iteratorleft").click(function( event ){
|
||||||
|
event.preventDefault();
|
||||||
|
var nperiod=$(this).data().nperiod+1;
|
||||||
|
var user = $(this).data().user;
|
||||||
|
var alertid = $(this).data().alertid;
|
||||||
|
var thediv = $(this);
|
||||||
|
url = "/rowers/alerts/"+alertid+"/report/"+nperiod+"/user/"+user+"/";
|
||||||
|
$.getJSON(window.location.protocol + '//' + window.location.host + url,
|
||||||
|
function(json) {
|
||||||
|
var percentage = json['stats']['percentage'];
|
||||||
|
var startdate = json['stats']['startdate'];
|
||||||
|
var enddate = json['stats']['enddate'];
|
||||||
|
thediv.siblings("#percentages").find("#percentage").text(percentage);
|
||||||
|
thediv.siblings("#dates").find("#startdate").text(startdate);
|
||||||
|
thediv.siblings("#dates").find("#enddate").text(enddate);
|
||||||
|
thediv.data().nperiod=nperiod;
|
||||||
|
if (nextperiod<0) {nextperiod=0};
|
||||||
|
var nextperiod = nperiod
|
||||||
|
thediv.siblings(".iteratorright").data().nperiod=nextperiod;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$(".iteratorright").click(function( event ){
|
||||||
|
event.preventDefault();
|
||||||
|
var nperiod=$(this).data().nperiod-1;
|
||||||
|
if ( nperiod<0 ) {
|
||||||
|
nperiod=0
|
||||||
|
};
|
||||||
|
|
||||||
|
var user = $(this).data().user;
|
||||||
|
var alertid = $(this).data().alertid;
|
||||||
|
var thediv = $(this)
|
||||||
|
url = "/rowers/alerts/"+alertid+"/report/"+nperiod+"/user/"+user+"/";
|
||||||
|
$.getJSON(window.location.protocol + '//' + window.location.host + url,
|
||||||
|
function(json) {
|
||||||
|
var percentage = json['stats']['percentage'];
|
||||||
|
var startdate = json['stats']['startdate'];
|
||||||
|
var enddate = json['stats']['enddate'];
|
||||||
|
thediv.siblings("#percentages").find("#percentage").text(percentage);
|
||||||
|
thediv.siblings("#dates").find("#startdate").text(startdate);
|
||||||
|
thediv.siblings("#dates").find("#enddate").text(enddate);
|
||||||
|
thediv.data().nperiod=nperiod;
|
||||||
|
var nextperiod = nperiod;
|
||||||
|
thediv.siblings(".iteratorleft").data().nperiod=nextperiod;
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% include 'menu_analytics.html' %}
|
{% include 'menu_analytics.html' %}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li class="rounder">
|
<li class="rounder">
|
||||||
<h1>Power Progress</h1>
|
<h2>Power Progress</h2>
|
||||||
<a href="/rowers/fitness-progress/">
|
<a href="/rowers/fitness-progress/">
|
||||||
<div class="vignet">
|
<div class="vignet">
|
||||||
<img src="/static/img/powerprogress.png" alt="Power Progress">
|
<img src="/static/img/powerprogress.png" alt="Power Progress">
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>Rowsandall</title>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<font face="verdana, sans-serif">
|
<font face="verdana, sans-serif">
|
||||||
|
|
||||||
|
|
||||||
<img src="https://rowsandall.com/static/img/logoemail.png" height="50">
|
<img src="https://rowsandall.com/static/img/logoemail.png" height="50">
|
||||||
<font face="verdana, sans-serif">
|
<font face="verdana, sans-serif">
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
</font>
|
</font>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -54,6 +54,14 @@
|
|||||||
|
|
||||||
{% if team.manager == user %}
|
{% if team.manager == user %}
|
||||||
<p>Use the form to add a new user. You can either select a user from the list of your existing club members who are not on this team yet, or you can type the user's email address, which also works for users who have not registered to the site yet.</p>
|
<p>Use the form to add a new user. You can either select a user from the list of your existing club members who are not on this team yet, or you can type the user's email address, which also works for users who have not registered to the site yet.</p>
|
||||||
|
{% if team.manager.rower.rowerplan == 'freecoach' %}
|
||||||
|
<p>
|
||||||
|
As a Free Coach user, your team members can only be users on a paid
|
||||||
|
plan. You can also upgrade to a
|
||||||
|
<a href="/rowers/paidplans/">Paid Coach Plan</a>
|
||||||
|
which allows you to coach users on a free Rower Plan.
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
{% if inviteform.errors %}
|
{% if inviteform.errors %}
|
||||||
<p style="color: red;">
|
<p style="color: red;">
|
||||||
Please correct the error{{ inviteform.errors|pluralize }} below.
|
Please correct the error{{ inviteform.errors|pluralize }} below.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from time import strftime
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
@@ -37,6 +38,25 @@ from django.template.defaultfilters import stringfilter
|
|||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def sigdig(value, digits = 3):
|
||||||
|
try:
|
||||||
|
order = int(math.floor(math.log10(math.fabs(value))))
|
||||||
|
except (ValueError,TypeError):
|
||||||
|
return value
|
||||||
|
|
||||||
|
# return integers as is
|
||||||
|
if value % 1 == 0:
|
||||||
|
return value
|
||||||
|
|
||||||
|
places = digits - order - 1
|
||||||
|
if places > 0:
|
||||||
|
fmtstr = "%%.%df" % (places)
|
||||||
|
else:
|
||||||
|
fmtstr = "%.0f"
|
||||||
|
return fmtstr % (round(value, places))
|
||||||
|
|
||||||
|
|
||||||
@register.filter(is_safe=True, needs_autoescape=True)
|
@register.filter(is_safe=True, needs_autoescape=True)
|
||||||
@stringfilter
|
@stringfilter
|
||||||
def urlshorten(value, limit,autoescape=None):
|
def urlshorten(value, limit,autoescape=None):
|
||||||
@@ -71,10 +91,27 @@ from rowers.teams import rower_get_managers
|
|||||||
@register.filter
|
@register.filter
|
||||||
def alertstatspercentage(list,i):
|
def alertstatspercentage(list,i):
|
||||||
alertstats = list[i-1]
|
alertstats = list[i-1]
|
||||||
print(alertstats)
|
|
||||||
|
|
||||||
return alertstats["percentage"]
|
return alertstats["percentage"]
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def alertstartdate(list,i):
|
||||||
|
alertstats = list[i-1]
|
||||||
|
|
||||||
|
return alertstats["startdate"]
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def alertnperiod(list,i):
|
||||||
|
alertstats = list[i-1]
|
||||||
|
|
||||||
|
return alertstats["nperiod"]
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def alertenddate(list,i):
|
||||||
|
alertstats = list[i-1]
|
||||||
|
|
||||||
|
return alertstats["enddate"]
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def is_coach(rower,rowers):
|
def is_coach(rower,rowers):
|
||||||
for r in rowers:
|
for r in rowers:
|
||||||
@@ -261,9 +298,14 @@ def jsdict(dict,key):
|
|||||||
s = dict.get(key)
|
s = dict.get(key)
|
||||||
return mark_safe(json.dumps(s))
|
return mark_safe(json.dumps(s))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def lookup(dict, key):
|
def lookup(dict, key):
|
||||||
s = dict.get(key)
|
try:
|
||||||
|
s = dict.get(key)
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
if isinstance(s,string_types) and len(s) > 22:
|
if isinstance(s,string_types) and len(s) > 22:
|
||||||
s = s[:22]
|
s = s[:22]
|
||||||
@@ -271,7 +313,10 @@ def lookup(dict, key):
|
|||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def lookuplong(dict, key):
|
def lookuplong(dict, key):
|
||||||
s = dict.get(key)
|
try:
|
||||||
|
s = dict.get(key)
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -4329,6 +4329,7 @@ def alerts_view(request,userid=0):
|
|||||||
for alert in alerts:
|
for alert in alerts:
|
||||||
stats.append(alert_get_stats(alert))
|
stats.append(alert_get_stats(alert))
|
||||||
|
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
'url':'/rowers/analysis',
|
'url':'/rowers/analysis',
|
||||||
|
|||||||
+14
-12
@@ -16,11 +16,16 @@ def team_view(request,id=0,userid=0):
|
|||||||
teams.remove_expired_invites()
|
teams.remove_expired_invites()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
t = Team.objects.get(id=id)
|
t = Team.objects.get(id=id)
|
||||||
except Team.DoesNotExist:
|
except Team.DoesNotExist:
|
||||||
raise Http404("Team doesn't exist")
|
raise Http404("Team doesn't exist")
|
||||||
|
|
||||||
|
if r.rowerplan == 'basic' and t.manager.rower.rowerplan != 'coach':
|
||||||
|
raise PermissionDenied("You need to be on a Paid Plan to see or join this team")
|
||||||
|
|
||||||
|
|
||||||
q = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
|
q = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
|
||||||
mygroups = [request.user.rower.mycoachgroup]
|
mygroups = [request.user.rower.mycoachgroup]
|
||||||
q2 = User.objects.filter(rower__isnull=False,rower__coachinggroups__in=mygroups).distinct().exclude(rower__team__name=t.name)
|
q2 = User.objects.filter(rower__isnull=False,rower__coachinggroups__in=mygroups).distinct().exclude(rower__team__name=t.name)
|
||||||
@@ -168,19 +173,22 @@ def get_teams(request):
|
|||||||
private='open').exclude(
|
private='open').exclude(
|
||||||
rower=r).exclude(manager=request.user).order_by('name')
|
rower=r).exclude(manager=request.user).order_by('name')
|
||||||
|
|
||||||
|
if r.rowerplan == 'basic':
|
||||||
|
otherteams = otherteams.filter(manager__rower__rowerplan='coach')
|
||||||
|
|
||||||
return myteams, memberteams, otherteams
|
return myteams, memberteams, otherteams
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def rower_teams_view(request,message='',successmessage=''):
|
def rower_teams_view(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = TeamInviteCodeForm(request.POST)
|
form = TeamInviteCodeForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
code = form.cleaned_data['code']
|
code = form.cleaned_data['code']
|
||||||
res,text = teams.process_invite_code(request.user,code)
|
res,text = teams.process_invite_code(request.user,code)
|
||||||
if res:
|
if res:
|
||||||
successmessage = text
|
messages.info(request,text)
|
||||||
else:
|
else:
|
||||||
message = text
|
messages.error(request,text)
|
||||||
else:
|
else:
|
||||||
form = TeamInviteCodeForm()
|
form = TeamInviteCodeForm()
|
||||||
|
|
||||||
@@ -249,8 +257,6 @@ def rower_teams_view(request,message='',successmessage=''):
|
|||||||
# clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
|
# clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
|
||||||
# max_clubsize = r.clubsize
|
# max_clubsize = r.clubsize
|
||||||
|
|
||||||
messages.info(request,successmessage)
|
|
||||||
messages.error(request,message)
|
|
||||||
|
|
||||||
breadcrumbs = [
|
breadcrumbs = [
|
||||||
{
|
{
|
||||||
@@ -312,18 +318,14 @@ def manager_member_drop_view(request,teamid,userid,
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def manager_requests_view(request,code=None,message='',successmessage=''):
|
def manager_requests_view(request,code=None):
|
||||||
if code:
|
if code:
|
||||||
res,text = teams.process_request_code(request.user,code)
|
res,text = teams.process_request_code(request.user,code)
|
||||||
if res:
|
if res:
|
||||||
successmessage = text
|
messages.info(request,text)
|
||||||
message = ''
|
|
||||||
else:
|
else:
|
||||||
message = text
|
messages.error(request,text)
|
||||||
successmessage = ''
|
|
||||||
|
|
||||||
messages.info(request,successmessage)
|
|
||||||
messages.error(request,message)
|
|
||||||
url = reverse(rower_teams_view,kwargs={
|
url = reverse(rower_teams_view,kwargs={
|
||||||
})
|
})
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|||||||
Reference in New Issue
Block a user