favorites on ote flex - need to do otw flex
This commit is contained in:
@@ -6,6 +6,7 @@ from django import forms
|
||||
from django.forms import ModelForm
|
||||
from django.dispatch import receiver
|
||||
from django.forms.widgets import SplitDateTimeWidget
|
||||
from django.forms.formsets import BaseFormSet
|
||||
from datetimewidget.widgets import DateTimeWidget
|
||||
import os
|
||||
|
||||
@@ -81,11 +82,95 @@ class Rower(models.Model):
|
||||
return self.user.username
|
||||
|
||||
class FavoriteChart(models.Model):
|
||||
yparam1 = models.CharField(max_length=50)
|
||||
yparam2 = models.CharField(max_length=50)
|
||||
xparam = models.CharField(max_length=50)
|
||||
user = models.ForeignKey(Rower)
|
||||
y1params = (
|
||||
('hr','Heart Rate'),
|
||||
('pace','Pace'),
|
||||
('spm','SPM'),
|
||||
('driveenergy','Work per Stroke'),
|
||||
('power','Power'),
|
||||
('drivelength','Drivelength'),
|
||||
('averageforce','Average Force'),
|
||||
('peakforce','Peak Force'),
|
||||
('forceratio','Average/Peak Force Ratio'),
|
||||
('drivespeed','Drive Speed'),
|
||||
('wash','Wash'),
|
||||
('slip','Slip'),
|
||||
('catch','Catch Angle'),
|
||||
('finish','Finish Angle'),
|
||||
('peakforceangle','Peak Force Angle')
|
||||
)
|
||||
|
||||
y2params = (
|
||||
('hr','Heart Rate'),
|
||||
('spm','SPM'),
|
||||
('driveenergy','Work per Stroke'),
|
||||
('power','Power'),
|
||||
('drivelength','Drivelength'),
|
||||
('averageforce','Average Force'),
|
||||
('peakforce','Peak Force'),
|
||||
('forceratio','Average/Peak Force Ratio'),
|
||||
('drivespeed','Drive Speed'),
|
||||
('wash','Wash'),
|
||||
('slip','Slip'),
|
||||
('catch','Catch Angle'),
|
||||
('finish','Finish Angle'),
|
||||
('peakforceangle','Peak Force Angle'),
|
||||
('None','None')
|
||||
)
|
||||
|
||||
xparams = (
|
||||
('time','Time'),
|
||||
('distance','Distance'),
|
||||
('hr','Heart Rate'),
|
||||
('spm','SPM'),
|
||||
('driveenergy','Work per Stroke'),
|
||||
('power','Power'),
|
||||
('drivelength','Drivelength'),
|
||||
('averageforce','Average Force'),
|
||||
('peakforce','Peak Force'),
|
||||
('forceratio','Average/Peak Force Ratio'),
|
||||
('drivespeed','Drive Speed'),
|
||||
('wash','Wash'),
|
||||
('slip','Slip'),
|
||||
('catch','Catch Angle'),
|
||||
('finish','Finish Angle'),
|
||||
('peakforceangle','Peak Force Angle'),
|
||||
)
|
||||
|
||||
plottypes = (
|
||||
('line','Line Chart'),
|
||||
('scatter','Scatter Chart')
|
||||
)
|
||||
|
||||
yparam1 = models.CharField(max_length=50,choices=y1params,verbose_name='Y1')
|
||||
yparam2 = models.CharField(max_length=50,choices=y2params,verbose_name='Y2')
|
||||
xparam = models.CharField(max_length=50,choices=xparams,verbose_name='X')
|
||||
plottype = models.CharField(max_length=50,choices=plottypes,default='line')
|
||||
user = models.ForeignKey(Rower)
|
||||
|
||||
class FavoriteForm(ModelForm):
|
||||
class Meta:
|
||||
model = FavoriteChart
|
||||
fields = ['xparam','yparam1','yparam2','plottype']
|
||||
|
||||
class BaseFavoriteFormSet(BaseFormSet):
|
||||
def clean(self):
|
||||
if any(self.errors):
|
||||
return
|
||||
|
||||
for form in self.forms:
|
||||
if form.cleaned_data:
|
||||
xparam = form.cleaned_data['xparam']
|
||||
yparam1 = form.cleaned_data['yparam1']
|
||||
yparam2 = form.cleaned_data['yparam2']
|
||||
plottype = form.cleaned_data['plottype']
|
||||
|
||||
if not xparam:
|
||||
raise forms.ValidationError(
|
||||
'Must have x parameter.',
|
||||
code='missing_xparam'
|
||||
)
|
||||
|
||||
class Workout(models.Model):
|
||||
workouttypes = (
|
||||
('water','On-water'),
|
||||
|
||||
35
rowers/templates/favoritecharts.html
Normal file
35
rowers/templates/favoritecharts.html
Normal file
@@ -0,0 +1,35 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Change Favorite Charts{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ favorites_formset.management_form }}
|
||||
|
||||
{% for favorites_form in favorites_formset %}
|
||||
<div class="fav-formset grid_6 alpha">
|
||||
<h2>Chart {{ forloop.counter }}</h2>
|
||||
<table>
|
||||
{{ favorites_form.as_table }}
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="grid_12 alpha">
|
||||
<div class="grid_2">
|
||||
<p><input type="submit" value="Update Favorites" class="button green small"/></p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Include formset plugin - including jQuery dependency -->
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
||||
<script src="/static/js/jquery.formset.js"></script>
|
||||
<script>
|
||||
$('.fav-formset').formset({
|
||||
addText: '<div class="grid_12"> </div><div class="button grid_2 green small">add chart</div>',
|
||||
deleteText: '<div class="grid_12"><p> </p></div><div class="button grid_1 red small">remove</div>'
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
@@ -163,6 +163,37 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id="favorites" class="grid_12 alpha">
|
||||
<div class="grid_2 suffix_4 alpha">
|
||||
{% if maxfav >= 0 %}
|
||||
<a class="button gray small" href="/rowers/me/favoritecharts">Manage Favorites</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid_1">
|
||||
{% if favoritenr > 0 %}
|
||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ favoritenr|add:-1 }}"><</a>
|
||||
{% else %}
|
||||
<p> </p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input class="grid_2 alpha button blue small" type="hidden" name="savefavorite" value="True">
|
||||
<input class="grid_2 alpha button blue small" value="Make Favorite" type="Submit">
|
||||
</form>
|
||||
</div>
|
||||
<div class="grid_1">
|
||||
{% if favoritenr < maxfav %}
|
||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ favoritenr|add:1 }}">></a>
|
||||
{% else %}
|
||||
<p> </p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
{% endlocaltime %}
|
||||
|
||||
@@ -146,6 +146,7 @@ urlpatterns = [
|
||||
url(r'^me/sporttracksauthorize/$',views.rower_sporttracks_authorize),
|
||||
url(r'^me/sporttracksrefresh/$',views.rower_sporttracks_token_refresh),
|
||||
url(r'^me/c2refresh/$',views.rower_c2_token_refresh),
|
||||
url(r'^me/favoritecharts/$',views.rower_favoritecharts_view),
|
||||
url(r'^email/send/$', views.sendmail),
|
||||
url(r'^email/thankyou/$', TemplateView.as_view(template_name='thankyou.html'), name='thankyou'),
|
||||
url(r'^email/$', TemplateView.as_view(template_name='email.html'), name='email'),
|
||||
|
||||
147
rowers/views.py
147
rowers/views.py
@@ -2,6 +2,7 @@ import time
|
||||
import operator
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.db.models import Q
|
||||
from django.db import IntegrityError, transaction
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
@@ -16,8 +17,10 @@ from django.core.mail import send_mail, BadHeaderError
|
||||
from rowers.forms import EmailForm, RegistrationForm, RegistrationFormTermsOfService,RegistrationFormUniqueEmail,CNsummaryForm,UpdateWindForm,UpdateStreamForm
|
||||
from rowers.forms import PredictedPieceForm,DateRangeForm,DeltaDaysForm
|
||||
from rowers.forms import SummaryStringForm,IntervalUpdateForm,StrokeDataForm
|
||||
from rowers.models import Workout, User, Rower, WorkoutForm
|
||||
from rowers.models import Workout, User, Rower, WorkoutForm,FavoriteChart
|
||||
from rowers.models import RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm
|
||||
from rowers.models import FavoriteForm,BaseFavoriteFormSet
|
||||
from django.forms.formsets import formset_factory
|
||||
import StringIO
|
||||
from django.contrib.auth.decorators import login_required,user_passes_test
|
||||
from time import strftime,strptime,mktime,time,daylight
|
||||
@@ -2573,27 +2576,29 @@ def workout_comparison_view2(request,id1=0,id2=0,xparam='distance',
|
||||
|
||||
|
||||
|
||||
def workout_flexchart3_view(request,id=0,#*args,**kwargs):
|
||||
xparam='distance',yparam1='pace',
|
||||
yparam2='hr',plottype='line',
|
||||
promember=0):
|
||||
def workout_flexchart3_view(request,*args,**kwargs):
|
||||
# xparam='distance',yparam1='pace',
|
||||
# yparam2='hr',plottype='line',
|
||||
# promember=0):
|
||||
|
||||
# print args
|
||||
# try:
|
||||
# id = args[0]
|
||||
# except:
|
||||
# pass
|
||||
|
||||
# if 'xparam' in kwargs:
|
||||
# print "found it"
|
||||
if request.method == 'POST':
|
||||
workstrokesonly = request.POST['workstrokesonly']
|
||||
if workstrokesonly == 'True':
|
||||
workstrokesonly = True
|
||||
else:
|
||||
workstrokesonly = False
|
||||
|
||||
try:
|
||||
id = kwargs['id']
|
||||
except KeyError:
|
||||
return HttpResponse("Invalid workout number")
|
||||
|
||||
if 'promember' in kwargs:
|
||||
promember = kwargs['promember']
|
||||
else:
|
||||
workstrokesonly = False
|
||||
promember = 0
|
||||
|
||||
try:
|
||||
favoritenr = int(request.GET['favoritechart'])
|
||||
except:
|
||||
favoritenr = 0
|
||||
|
||||
|
||||
|
||||
row = Workout.objects.get(id=id)
|
||||
promember=0
|
||||
@@ -2606,6 +2611,56 @@ def workout_flexchart3_view(request,id=0,#*args,**kwargs):
|
||||
if request.user == row.user.user:
|
||||
mayedit=1
|
||||
|
||||
|
||||
favorites = FavoriteChart.objects.filter(user=r).order_by("id")
|
||||
maxfav = len(favorites)-1
|
||||
|
||||
if 'xparam' in kwargs:
|
||||
xparam = kwargs['xparam']
|
||||
else:
|
||||
if favorites:
|
||||
xparam = favorites[favoritenr].xparam
|
||||
else:
|
||||
xparam = 'distance'
|
||||
|
||||
if 'yparam1' in kwargs:
|
||||
yparam1 = kwargs['yparam1']
|
||||
else:
|
||||
if favorites:
|
||||
yparam1 = favorites[favoritenr].yparam1
|
||||
else:
|
||||
yparam1 = 'pace'
|
||||
|
||||
if 'yparam2' in kwargs:
|
||||
yparam2 = kwargs['yparam2']
|
||||
else:
|
||||
if favorites:
|
||||
yparam2 = favorites[favoritenr].yparam2
|
||||
else:
|
||||
yparam2 = 'hr'
|
||||
|
||||
if 'plottype' in kwargs:
|
||||
plottype = kwargs['plottype']
|
||||
else:
|
||||
if favorites:
|
||||
plottype = favorites[favoritenr].plottype
|
||||
else:
|
||||
plottype = 'line'
|
||||
|
||||
if request.method == 'POST' and 'savefavorite' in request.POST:
|
||||
f = FavoriteChart(user=r,xparam=xparam,
|
||||
yparam1=yparam1,yparam2=yparam2,
|
||||
plottype=plottype)
|
||||
f.save()
|
||||
if request.method == 'POST' and 'workstrokesonly' in request.POST:
|
||||
workstrokesonly = request.POST['workstrokesonly']
|
||||
if workstrokesonly == 'True':
|
||||
workstrokesonly = True
|
||||
else:
|
||||
workstrokesonly = False
|
||||
else:
|
||||
workstrokesonly = False
|
||||
|
||||
# create interactive plot
|
||||
res = interactive_flex_chart2(id,xparam=xparam,yparam1=yparam1,
|
||||
yparam2=yparam2,
|
||||
@@ -2631,6 +2686,8 @@ def workout_flexchart3_view(request,id=0,#*args,**kwargs):
|
||||
'mayedit':mayedit,
|
||||
'promember':promember,
|
||||
'workstrokesonly': not workstrokesonly,
|
||||
'favoritenr':favoritenr,
|
||||
'maxfav':maxfav,
|
||||
})
|
||||
else:
|
||||
return render(request,
|
||||
@@ -2647,6 +2704,8 @@ def workout_flexchart3_view(request,id=0,#*args,**kwargs):
|
||||
'mayedit':mayedit,
|
||||
'promember':promember,
|
||||
'workstrokesonly': not workstrokesonly,
|
||||
'favoritenr':favoritenr,
|
||||
'maxfav':maxfav,
|
||||
})
|
||||
|
||||
def testbokeh(request):
|
||||
@@ -4433,6 +4492,56 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
|
||||
})
|
||||
|
||||
|
||||
@login_required()
|
||||
def rower_favoritecharts_view(request):
|
||||
message = ''
|
||||
successmessage = ''
|
||||
r = Rower.objects.get(user=request.user)
|
||||
favorites = FavoriteChart.objects.filter(user=r).order_by('id')
|
||||
favorites_data = [{'yparam1':f.yparam1,
|
||||
'yparam2':f.yparam2,
|
||||
'xparam':f.xparam,
|
||||
'plottype':f.plottype}
|
||||
for f in favorites]
|
||||
FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet)
|
||||
|
||||
if request.method == 'POST':
|
||||
favorites_formset = FavoriteChartFormSet(request.POST)
|
||||
|
||||
if favorites_formset.is_valid():
|
||||
new_instances = []
|
||||
for favorites_form in favorites_formset:
|
||||
yparam1 = favorites_form.cleaned_data.get('yparam1')
|
||||
yparam2 = favorites_form.cleaned_data.get('yparam2')
|
||||
xparam = favorites_form.cleaned_data.get('xparam')
|
||||
plottype = favorites_form.cleaned_data.get('plottype')
|
||||
new_instances.append(FavoriteChart(user=r,
|
||||
yparam1=yparam1,
|
||||
yparam2=yparam2,
|
||||
xparam=xparam,
|
||||
plottype=plottype))
|
||||
try:
|
||||
with transaction.atomic():
|
||||
FavoriteChart.objects.filter(user=r).delete()
|
||||
FavoriteChart.objects.bulk_create(new_instances)
|
||||
successmessage = "You have updated your favorites"
|
||||
|
||||
except IntegrityError:
|
||||
message = "something went wrong"
|
||||
|
||||
else:
|
||||
favorites_formset = FavoriteChartFormSet(initial=favorites_data)
|
||||
|
||||
|
||||
context = {
|
||||
'favorites_formset':favorites_formset,
|
||||
'message':message,
|
||||
'successmessage':successmessage,
|
||||
}
|
||||
|
||||
|
||||
|
||||
return render(request,'favoritecharts.html',context)
|
||||
|
||||
@login_required()
|
||||
def rower_edit_view(request,message=""):
|
||||
|
||||
Reference in New Issue
Block a user