Private
Public Access
1
0
Files
rowsandall/rowers/models.py
Sander Roosendaal da7f679c30 boatcoach
2016-11-28 17:58:32 +01:00

378 lines
11 KiB
Python

from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django import forms
from django.forms import ModelForm
from django.dispatch import receiver
from django.forms.widgets import SplitDateTimeWidget
from datetimewidget.widgets import DateTimeWidget
import os
from django.conf import settings
from sqlalchemy import create_engine
import sqlalchemy as sa
from sqlite3 import OperationalError
user = settings.DATABASES['default']['USER']
password = settings.DATABASES['default']['PASSWORD']
database_name = settings.DATABASES['default']['NAME']
host = settings.DATABASES['default']['HOST']
port = settings.DATABASES['default']['PORT']
database_url = 'mysql://{user}:{password}@{host}:{port}/{database_name}'.format(
user=user,
password=password,
database_name=database_name,
host=host,
port=port,
)
if settings.DEBUG or user=='':
database_url = 'sqlite:///db.sqlite3'
# Create your models here.
class Team(models.Model):
name = models.CharField(max_length=150)
notes = models.CharField(blank=True,max_length=200)
class Rower(models.Model):
weightcategories = (
('hwt','heavy-weight'),
('lwt','light-weight'),
)
user = models.OneToOneField(User)
max = models.IntegerField(default=192,verbose_name="Max Heart Rate")
rest = models.IntegerField(default=48,verbose_name="Resting Heart Rate")
ut2 = models.IntegerField(default=105,verbose_name="UT2 band lower HR")
ut1 = models.IntegerField(default=146,verbose_name="UT1 band lower HR")
at = models.IntegerField(default=160,verbose_name="AT band lower HR")
tr = models.IntegerField(default=167,verbose_name="TR band lower HR")
an = models.IntegerField(default=180,verbose_name="AN band lower HR")
weightcategory = models.CharField(default="hwt",
max_length=30,
choices=weightcategories)
ftp = models.IntegerField(default=226,verbose_name="Functional Threshold Power")
c2token = models.CharField(default='',max_length=200,blank=True,null=True)
tokenexpirydate = models.DateTimeField(blank=True,null=True)
c2refreshtoken = models.CharField(default='',max_length=200,blank=True,null=True)
sporttrackstoken = models.CharField(default='',max_length=200,blank=True,null=True)
sporttrackstokenexpirydate = models.DateTimeField(blank=True,null=True)
sporttracksrefreshtoken = models.CharField(default='',max_length=200,
blank=True,null=True)
stravatoken = models.CharField(default='',max_length=200,blank=True,null=True)
plans = (
('basic','basic'),
('pro','pro'),
('coach','coach')
)
rowerplan = models.CharField(default='basic',max_length=30,
choices=plans)
friends = models.ManyToManyField("self",blank=True)
team = models.ForeignKey(Team,blank=True,null=True)
def __str__(self):
return self.user.username
class Workout(models.Model):
workouttypes = (
('water','On-water'),
('rower','Indoor Rower'),
('skierg','Ski Erg'),
('dynamic','Dynamic Indoor Rower'),
('slides','Indoor Rower on Slides'),
('paddle','Paddle Adapter'),
('snow','On-snow'),
)
boattypes = (
('1x', '1x (single)'),
('2x', '2x (double)'),
('2-', '2- (pair)'),
('4x', '4x (quad)'),
('4-', '4- (four)'),
('8+', '8+ (eight)'),
)
user = models.ForeignKey(Rower)
team = models.ForeignKey(Team,blank=True,null=True)
name = models.CharField(max_length=150)
date = models.DateField()
workouttype = models.CharField(choices=workouttypes,max_length=50)
boattype = models.CharField(choices=boattypes,max_length=50,
default='1x (single)',
verbose_name = 'Boat Type')
starttime = models.TimeField(blank=True,null=True)
startdatetime = models.DateTimeField(blank=True,null=True)
distance = models.IntegerField(default=0,blank=True)
duration = models.TimeField(default=1,blank=True)
weightcategory = models.CharField(default="hwt",max_length=10)
weightvalue = models.FloatField(default=80.0,blank=True,verbose_name = 'Average Crew Weight (kg)')
csvfilename = models.CharField(blank=True,max_length=150)
uploadedtoc2 = models.IntegerField(default=0)
averagehr = models.IntegerField(blank=True,null=True)
maxhr = models.IntegerField(blank=True,null=True)
uploadedtostrava = models.IntegerField(default=0)
uploadedtosporttracks = models.IntegerField(default=0)
notes = models.CharField(blank=True,null=True,max_length=200)
summary = models.TextField(blank=True)
def __str__(self):
date = self.date
name = self.name
str = date.strftime('%Y-%m-%d')+'_'+name
return str
# delete files belonging to workout instance
# related GraphImage objects should be deleted automatically
@receiver(models.signals.post_delete,sender=Workout)
def auto_delete_file_on_delete(sender, instance, **kwargs):
# delete CSV file
if instance.csvfilename:
if os.path.isfile(instance.csvfilename):
os.remove(instance.csvfilename)
@receiver(models.signals.post_delete,sender=Workout)
def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
if instance.id:
query = sa.text('DELETE FROM strokedata WHERE workoutid={id};'.format(
id=instance.id,
))
engine = create_engine(database_url, echo=False)
with engine.connect() as conn, conn.begin():
try:
result = conn.execute(query)
except:
print "Database Locked"
conn.close()
engine.dispose()
class StrokeData(models.Model):
class Meta:
db_table = 'strokedata'
index_together = ['workoutid']
workoutid = models.IntegerField(null=True)
time = models.FloatField(null=True)
hr = models.IntegerField(null=True)
pace = models.FloatField(null=True)
workoutstate = models.IntegerField(null=True,default=1)
spm = models.FloatField(null=True)
cumdist = models.FloatField(null=True)
ftime = models.CharField(max_length=30)
fpace = models.CharField(max_length=30)
driveenergy = models.FloatField(null=True)
power = models.FloatField(null=True)
averageforce = models.FloatField(null=True)
drivelength = models.FloatField(null=True)
peakforce = models.FloatField(null=True)
forceratio = models.FloatField(null=True)
distance = models.FloatField(null=True)
drivespeed = models.FloatField(null=True)
hr_ut2 = models.IntegerField(null=True)
hr_ut1 = models.IntegerField(null=True)
hr_at = models.IntegerField(null=True)
hr_tr = models.IntegerField(null=True)
hr_an = models.IntegerField(null=True)
hr_max = models.IntegerField(null=True)
hr_bottom = models.IntegerField(null=True)
x_right = models.FloatField(null=True)
ergpace = models.FloatField(null=True)
nowindpace = models.FloatField(null=True)
equivergpower = models.FloatField(null=True)
fergpace = models.CharField(max_length=30)
fnowindpace = models.CharField(max_length=30)
class GraphImage(models.Model):
filename = models.CharField(default='',max_length=150,blank=True,null=True)
creationdatetime = models.DateTimeField()
workout = models.ForeignKey(Workout)
def __str__(self):
return self.filename
# delete related file object
@receiver(models.signals.post_delete,sender=GraphImage)
def auto_delete_image_on_delete(sender,instance, **kwargs):
if instance.filename:
if os.path.isfile(instance.filename):
os.remove(instance.filename)
else:
print "couldn't find the file "+instance.filename
class DateInput(forms.DateInput):
input_type = 'date'
class WorkoutForm(ModelForm):
duration = forms.TimeInput(format='%H:%M:%S.%f')
class Meta:
model = Workout
fields = ['name','date','starttime','duration','distance','workouttype','notes']
widgets = {
'date': DateInput(),
'notes': forms.Textarea,
'duration': forms.TimeInput(format='%H:%M:%S.%f'),
}
class AdvancedWorkoutForm(ModelForm):
class Meta:
model = Workout
fields = ['boattype','weightvalue']
class RowerPowerForm(ModelForm):
class Meta:
model = Rower
fields = ['ftp']
class RowerForm(ModelForm):
class Meta:
model = Rower
fields = ['rest','ut2','ut1','at','tr','an','max','weightcategory']
def clean_rest(self):
rest = self.cleaned_data['rest']
if rest<10:
self.data['rest']=10
raise forms.ValidationError("Resting heart rate should be higher than 10 bpm")
if rest>250:
self.data['rest'] = 250
raise forms.ValidationError("Resting heart rate should be lower than 250 bpm")
return rest
def clean_ut2(self):
ut2 = self.cleaned_data['ut2']
if ut2<10:
raise forms.ValidationError("UT2 heart rate should be higher than 10 bpm")
if ut2>250:
raise forms.ValidationError("UT2 heart rate should be lower than 250 bpm")
return ut2
def clean_ut1(self):
ut1 = self.cleaned_data['ut1']
if ut1<10:
raise forms.ValidationError("UT1 heart rate should be higher than 10 bpm")
if ut1>250:
raise forms.ValidationError("Resting heart rate should be lower than 250 bpm")
return ut1
def clean_at(self):
at = self.cleaned_data['at']
if at<10:
raise forms.ValidationError("AT heart rate should be higher than 10 bpm")
if at>250:
raise forms.ValidationError("AT heart rate should be lower than 250 bpm")
return at
def clean_tr(self):
tr = self.cleaned_data['tr']
if tr<10:
raise forms.ValidationError("TR heart rate should be higher than 10 bpm")
if tr>250:
raise forms.ValidationError("TR heart rate should be lower than 250 bpm")
return tr
def clean_an(self):
an = self.cleaned_data['an']
if an<10:
raise forms.ValidationError("AN heart rate should be higher than 10 bpm")
if an>250:
raise forms.ValidationError("AN heart rate should be lower than 250 bpm")
return an
def clean_max(self):
max = self.cleaned_data['max']
if max<10:
raise forms.ValidationError("Max heart rate should be higher than 10 bpm")
if max>250:
raise forms.ValidationError("Max heart rate should be lower than 250 bpm")
return max
def clean(self):
try:
rest = self.cleaned_data['rest']
except:
rest = int(self.data['rest'])
try:
ut2 = self.cleaned_data['ut2']
except:
ut2 = self.data['ut2']
try:
ut1 = self.cleaned_data['ut1']
except:
ut1 = self.data['ut1']
try:
at = self.cleaned_data['at']
except:
at = self.data['at']
try:
an = self.cleaned_data['an']
except:
an = self.data['an']
try:
tr = self.cleaned_data['tr']
except:
tr = self.data['tr']
try:
max = self.cleaned_data['max']
except:
max = self.data['max']
if rest>=ut2:
raise forms.ValidationError("Resting heart rate should be lower than UT2")
if ut2>=ut1:
raise forms.ValidationError("UT2 should be lower than UT1")
if ut2>=ut1:
raise forms.ValidationError("UT2 should be lower than UT1")
if ut1>=at:
raise forms.ValidationError("UT1 should be lower than AT")
if at>=tr:
raise forms.ValidationError("AT should be lower than TR")
if tr>=an:
raise forms.ValidationError("TR should be lower than AN")
if an>=max:
raise forms.ValidationError("AN should be lower than Max")