Private
Public Access
1
0

another batch of files with a light sprinkle of comments

This commit is contained in:
Sander Roosendaal
2017-01-15 16:06:14 +01:00
parent 737ac5fd3f
commit e5810dbf62
11 changed files with 64 additions and 11 deletions

View File

@@ -4,8 +4,9 @@ from django.contrib.auth.models import User
from .models import Rower, Workout,GraphImage,FavoriteChart,SiteAnnouncement
# Register your models here.
# Register your models here so you can use them in the Admin module
# Rower details directly under the User
class RowerInline(admin.StackedInline):
model = Rower
can_delete = False

View File

@@ -2,6 +2,6 @@ from __future__ import unicode_literals
from django.apps import AppConfig
# Store metadata for the app
class RowersConfig(AppConfig):
name = 'rowers'

View File

@@ -4,6 +4,9 @@ import os
from celery import Celery
# Only used for testing with Celery on localhost. RQ is not available
# on Windows, so I use Celery on my notebook.
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rowsandall_app.settings')

View File

@@ -1,3 +1,5 @@
# This is Data prep used for testing purposes (no Django environment)
# Uses the debug SQLite database for stroke data
from rowingdata import rowingdata as rrdata
from rowingdata import rower as rrower

View File

@@ -1,3 +1,4 @@
# Processes emails sent to workouts@rowsandall.com
import time
from django.conf import settings
from rowers.tasks import handle_sendemail_unrecognized
@@ -21,7 +22,9 @@ from scipy.signal import savgol_filter
import zipfile
import os
import rowers.dataprep as dataprep
# Sends a confirmation with a link to the workout
def send_confirm(u,name,link):
fullemail = u.email
subject = 'Workout added: '+name
@@ -38,6 +41,7 @@ def send_confirm(u,name,link):
return 1
# Reads a "rowingdata" object, plus some error protections
def rdata(file,rower=rrower()):
try:
res = rrdata(file,rower=rower)
@@ -49,13 +53,18 @@ def rdata(file,rower=rrower()):
return res
# Some error protection around process attachments
def safeprocessattachments():
try:
return processattachments()
except:
return [0]
# This is duplicated in management/commands/processemail
# Need to double check the code there, update here, and only
# use the code here.
def processattachments():
# in res, we store the ids of the new workouts
res = []
attachments = MessageAttachment.objects.all()
for a in attachments:
@@ -73,7 +82,6 @@ def processattachments():
try:
wid = [make_new_workout_from_email(rr,a.document,name)]
res += wid
print wid
link = 'https://rowsandall.com/rowers/workout/'+str(wid[0])+'/edit'
dd = send_confirm(u,name,link)
except:
@@ -92,6 +100,7 @@ def processattachments():
# no attachments, so can be deleted
m.delete()
# Delete remaining messages (which should not have attachments)
mm = Message.objects.all()
for m in mm:
if m.attachments.exists()==False:
@@ -99,6 +108,7 @@ def processattachments():
return res
# As above, but with some print commands for debugging purposes
def processattachments_debug():
res = []
attachments = MessageAttachment.objects.all()
@@ -144,7 +154,9 @@ def processattachments_debug():
return res
# Process the attachment file, create new workout
# The code here is duplication of the code in views.py (workout_upload_view)
# Need to move the code to a subroutine used both in views.py and here
def make_new_workout_from_email(rr,f2,name,cntr=0):
workouttype = 'rower'
f2 = f2.name
@@ -305,6 +317,16 @@ def make_new_workout_from_email(rr,f2,name,cntr=0):
startdatetime=row.rowdatetime)
w.save()
print w.id
print row.df.info()
# put stroke data in database
res = dataprep.dataprep(row.df,id=w.id,
bands=True,barchart=True,
otwpower=True,empower=True)
return w.id

View File

@@ -1,3 +1,5 @@
# Interactions with Rowsandall.com API. Not fully complete.
# Python
import oauth2 as oauth
import cgi

View File

@@ -1,3 +1,5 @@
# Defines permissions for objects (API related)
from rest_framework import permissions
from rowers.models import Rower

View File

@@ -3,6 +3,7 @@ import matplotlib.pyplot as plt
import numpy as np
# Make pace ticks for pace axis '2:00', '1:50', etc
def format_pace_tick(x,pos=None):
min=int(x/60)
sec=int(x-min*60.)
@@ -10,6 +11,7 @@ def format_pace_tick(x,pos=None):
template='%d:%s'
return template % (min,sec_str)
# Returns a pace string from a pace in seconds/500m, '1:45.4'
def format_pace(x,pos=None):
if isinf(x) or isnan(x):
x=0
@@ -24,6 +26,7 @@ def format_pace(x,pos=None):
return str1
# Returns a time string from a time in seconds
def format_time(x,pos=None):
@@ -37,11 +40,13 @@ def format_time(x,pos=None):
return str1
# Formatting the distance tick marks
def format_dist_tick(x,pos=None):
km = x/1000.
template='%6.3f'
return template % (km)
# Formatting the time tick marks (h:mm)
def format_time_tick(x,pos=None):
hour=int(x/3600)
min=int((x-hour*3600.)/60)
@@ -49,6 +54,11 @@ def format_time_tick(x,pos=None):
template='%d:%s'
return template % (hour,min_str)
# Utility to select reasonable y axis range
# Basically the data range plus some padding, but with ultimate
# you can set the slowest paces to fall off the axis.
# Useful for OTW rowing where you sometimes stops and pace runs out of
# the boundaries
def y_axis_range(ydata,miny=0,padding=.1,ultimate=[-1e9,1e9]):
# ydata must by a numpy array
@@ -86,6 +96,7 @@ def y_axis_range(ydata,miny=0,padding=.1,ultimate=[-1e9,1e9]):
return [yrangemin,yrangemax]
# Make a plot (this one is only used for testing)
def mkplot(row,title):
df = row.df

View File

@@ -1,3 +1,6 @@
# Serializers. Defines which fields from an object get to the JSON object
# Also optionally define POST, PATCH methods (create, update)
from rest_framework import serializers
from rowers.models import Workout,Rower,StrokeData,FavoriteChart
@@ -104,6 +107,7 @@ class WorkoutSerializer(serializers.ModelSerializer):
instance.save()
return instance
# This is just a fake one for URL registration purposes
class StrokeDataSerializer(serializers.Serializer):
workoutid = serializers.IntegerField
strokedata = serializers.JSONField

View File

@@ -21,12 +21,12 @@ from rowers.dataprepnodjango import update_strokedata
from django.core.mail import send_mail, BadHeaderError,EmailMessage
# testing task
@app.task
def add(x, y):
return x + y
# send email to me when an unrecognized file is uploaded
@app.task
def handle_sendemail_unrecognized(unrecognizedfile,useremail):
@@ -51,7 +51,7 @@ def handle_sendemail_unrecognized(unrecognizedfile,useremail):
os.remove(unrecognizedfile)
return 1
# Send email with TCX attachment
@app.task
def handle_sendemailtcx(first_name,last_name,email,tcxfile):
@@ -75,6 +75,7 @@ def handle_sendemailtcx(first_name,last_name,email,tcxfile):
os.remove(tcxfile)
return 1
# Send email with CSV attachment
@app.task
def handle_sendemailcsv(first_name,last_name,email,csvfile):
@@ -104,6 +105,7 @@ def handle_sendemailcsv(first_name,last_name,email,csvfile):
return 1
# Calculate wind and stream corrections for OTW rowing
@app.task
def handle_otwsetpower(f1,boattype,weightvalue,
first_name,last_name,email,workoutid,
@@ -129,7 +131,7 @@ def handle_otwsetpower(f1,boattype,weightvalue,
except KeyError:
rg = rowingdata.getrigging('static/rigging/1x.txt')
# do calculation
# do calculation, but do not overwrite NK Empower Power data
powermeasured = False
try:
w = rowdata.df['wash']
@@ -166,6 +168,7 @@ def handle_otwsetpower(f1,boattype,weightvalue,
return 1
# This function generates all the static (PNG image) plots
@app.task
def handle_makeplot(f1,f2,t,hrdata,plotnr,imagename):
hrmax = hrdata['hrmax']
@@ -222,5 +225,6 @@ def handle_makeplot(f1,f2,t,hrdata,plotnr,imagename):
return imagename
# Another simple task for debugging purposes
def add2(x,y):
return x+y

View File

@@ -8,9 +8,8 @@ from rowers.models import Rower, Workout
from rowsandall_app.settings import FORECAST_IO_KEY
# Get weather data from the DarkSky API
def get_weather_data(long,lat,unixtime):
# url = "https://api.forecast.io/forecast/"+FORECAST_IO_KEY+"/"
url = "https://api.darksky.net/forecast/"+FORECAST_IO_KEY+"/"
url += str(long)+","+str(lat)+","+str(unixtime)
@@ -21,6 +20,7 @@ def get_weather_data(long,lat,unixtime):
else:
return 0
# Get wind data (and translate from knots to m/s)
def get_wind_data(lat,long,unixtime):
data = get_weather_data(lat,long,unixtime)
if data:
@@ -39,6 +39,7 @@ def get_wind_data(lat,long,unixtime):
try:
temperature = data['currently']['temperature']
# Temp is given in Fahrenheit, so convert to Celsius for Europeans
temperaturec = (temperature-32.)*(5./9.)
temperaturec = int(10*temperaturec)/10.
except KeyError:
@@ -54,7 +55,8 @@ def get_wind_data(lat,long,unixtime):
windbearing = 0
message = 'Not able to get weather data'
# apply Hellman's coefficient for neutral air above human inhabitated areas
# apply Hellman's coefficient for neutral air above human
# inhabitated areas
windspeed = windspeed*(0.1)**0.34
windspeed = 0.01*int(100*windspeed)