526 lines
16 KiB
Python
526 lines
16 KiB
Python
from celery import Celery,app
|
|
import os
|
|
import time
|
|
import gc
|
|
import gzip
|
|
import shutil
|
|
import numpy as np
|
|
|
|
import rowingdata
|
|
from rowingdata import main as rmain
|
|
from rowingdata import rowingdata as rdata
|
|
import rowingdata
|
|
from async_messages import message_user,messages
|
|
|
|
from matplotlib.backends.backend_agg import FigureCanvas
|
|
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib import figure
|
|
|
|
import stravalib
|
|
|
|
from django_rq import job
|
|
|
|
from utils import serialize_list,deserialize_list
|
|
|
|
from rowers.dataprepnodjango import update_strokedata
|
|
from rowers.dataprepnodjango import new_workout_from_file
|
|
|
|
from django.core.mail import send_mail, BadHeaderError,EmailMessage
|
|
|
|
|
|
|
|
|
|
|
|
# testing task
|
|
@app.task
|
|
def add(x, y):
|
|
return x + y
|
|
|
|
# create workout
|
|
@app.task
|
|
def handle_new_workout_from_file(r,f2,
|
|
workouttype='rower',
|
|
title='Workout',
|
|
makeprivate=False,
|
|
notes=''):
|
|
return new_workout_from_file(r,f2,workouttype,
|
|
title,makeprivate,notes)
|
|
|
|
# send email to me when an unrecognized file is uploaded
|
|
@app.task
|
|
def handle_sendemail_unrecognized(unrecognizedfile,useremail):
|
|
|
|
# send email with attachment
|
|
fullemail = 'roosendaalsander@gmail.com'
|
|
subject = "Unrecognized file from Rowsandall.com"
|
|
message = "Dear Sander,\n\n"
|
|
message += "Please find attached a file that someone tried to upload to rowsandall.com. The file was not recognized as a valid file type.\n\n"
|
|
message += "User Email "+useremail+"\n\n"
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
email.attach_file(unrecognizedfile)
|
|
|
|
res = email.send()
|
|
|
|
# remove tcx file
|
|
os.remove(unrecognizedfile)
|
|
return 1
|
|
|
|
|
|
# Send email with TCX attachment
|
|
@app.task
|
|
def handle_sendemailtcx(first_name,last_name,email,tcxfile):
|
|
|
|
# send email with attachment
|
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
|
subject = "File from Rowsandall.com"
|
|
message = "Dear "+first_name+",\n\n"
|
|
message += "Please find attached the requested file for your workout.\n\n"
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
email.attach_file(tcxfile)
|
|
|
|
res = email.send()
|
|
|
|
# remove tcx file
|
|
os.remove(tcxfile)
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_zip_file(emailfrom,subject,file):
|
|
message = "... zip processing ... "
|
|
email = EmailMessage(subject,message,
|
|
emailfrom,
|
|
['workouts@rowsandall.com'])
|
|
email.attach_file(file)
|
|
res = email.send()
|
|
time.sleep(60)
|
|
return 1
|
|
|
|
# Send email with CSV attachment
|
|
@app.task
|
|
def handle_sendemailcsv(first_name,last_name,email,csvfile):
|
|
|
|
# send email with attachment
|
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
|
subject = "File from Rowsandall.com"
|
|
message = "Dear "+first_name+",\n\n"
|
|
message += "Please find attached the requested file for your workout.\n\n"
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
if os.path.isfile(csvfile):
|
|
email.attach_file(csvfile)
|
|
else:
|
|
csvfile2 = csvfile
|
|
with gzip.open(csvfile+'.gz','rb') as f_in, open(csvfile2,'wb') as f_out:
|
|
shutil.copyfileobj(f_in, f_out)
|
|
|
|
email.attach_file(csvfile2)
|
|
os.remove(csvfile2)
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
# Calculate wind and stream corrections for OTW rowing
|
|
@app.task
|
|
def handle_otwsetpower(f1,boattype,weightvalue,
|
|
first_name,last_name,email,workoutid,
|
|
debug=False):
|
|
try:
|
|
rowdata = rdata(f1)
|
|
except IOError:
|
|
try:
|
|
rowdata = rdata(f1+'.csv')
|
|
except IOError:
|
|
rowdata = rdata(f1+'.gz')
|
|
|
|
weightvalue = float(weightvalue)
|
|
|
|
# do something with boat type
|
|
boatfile = {
|
|
'1x':'static/rigging/1x.txt',
|
|
'2x':'static/rigging/2x.txt',
|
|
'2-':'static/rigging/2-.txt',
|
|
'4x':'static/rigging/4x.txt',
|
|
'4-':'static/rigging/4-.txt',
|
|
'8+':'static/rigging/8+.txt',
|
|
}
|
|
try:
|
|
rg = rowingdata.getrigging(boatfile[boattype])
|
|
except KeyError:
|
|
rg = rowingdata.getrigging('static/rigging/1x.txt')
|
|
|
|
# do calculation, but do not overwrite NK Empower Power data
|
|
powermeasured = False
|
|
try:
|
|
w = rowdata.df['wash']
|
|
if w.mean() != 0:
|
|
powermeasured = True
|
|
except KeyError:
|
|
pass
|
|
|
|
rowdata.otw_setpower_silent(skiprows=5,mc=weightvalue,rg=rg,
|
|
powermeasured=powermeasured)
|
|
|
|
# save data
|
|
rowdata.write_csv(f1,gzip=True)
|
|
update_strokedata(workoutid,rowdata.df,debug=debug)
|
|
|
|
# send email
|
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
|
subject = "Your Rowsandall OTW calculations are ready"
|
|
message = "Dear "+first_name+",\n\n"
|
|
message += "Your Rowsandall OTW calculations are ready.\n"
|
|
message += "Thank you for using rowsandall.com.\n\n"
|
|
message += "Rowsandall OTW calculations have not been fully implemented yet.\n"
|
|
message += "We are now running an experimental version for debugging purposes. \n"
|
|
message += "Your wind/stream corrected plot is available here: http://rowsandall.com/rowers/workout/"
|
|
message += str(workoutid)
|
|
message +="/interactiveotwplot\n\n"
|
|
message += "Please report any bugs/inconsistencies/unexpected results at rowsandall.slack.com or by reply to this email.\n\n"
|
|
message += "Best Regards, The Rowsandall Physics Department."
|
|
|
|
send_mail(subject, message,
|
|
'Rowsandall Physics Department <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
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']
|
|
hrut2 = hrdata['hrut2']
|
|
hrut1 = hrdata['hrut1']
|
|
hrat = hrdata['hrat']
|
|
hrtr = hrdata['hrtr']
|
|
hran = hrdata['hran']
|
|
ftp = hrdata['ftp']
|
|
powerzones = deserialize_list(hrdata['powerzones'])
|
|
powerperc = np.array(deserialize_list(hrdata['powerperc'])).astype(int)
|
|
|
|
rr = rowingdata.rower(hrmax=hrmax,hrut2=hrut2,
|
|
hrut1=hrut1,hrat=hrat,
|
|
hrtr=hrtr,hran=hran,
|
|
ftp=ftp,powerperc=powerperc,
|
|
powerzones=powerzones)
|
|
try:
|
|
row = rdata(f2,rower=rr)
|
|
except IOError:
|
|
row = rdata(f2+'.gz',rower=rr)
|
|
|
|
|
|
haspower = row.df[' Power (watts)'].mean() > 50
|
|
|
|
nr_rows = len(row.df)
|
|
if (plotnr in [1,2,4,5,8,11,9,12]) and (nr_rows > 1200):
|
|
bin = int(nr_rows/1200.)
|
|
df = row.df.groupby(lambda x:x/bin).mean()
|
|
row.df = df
|
|
nr_rows = len(row.df)
|
|
if (plotnr==1):
|
|
fig1 = row.get_timeplot_erg(t)
|
|
elif (plotnr==2):
|
|
fig1 = row.get_metersplot_erg(t)
|
|
elif (plotnr==3):
|
|
fig1 = row.get_piechart(t)
|
|
elif (plotnr==4):
|
|
if haspower:
|
|
fig1 = row.get_timeplot_otwempower(t)
|
|
else:
|
|
fig1 = row.get_timeplot_otw(t)
|
|
elif (plotnr==5):
|
|
if haspower:
|
|
fig1 = row.get_metersplot_otwempower(t)
|
|
else:
|
|
fig1 = row.get_metersplot_otw(t)
|
|
elif (plotnr==6):
|
|
fig1 = row.get_piechart(t)
|
|
elif (plotnr==7) or (plotnr==10):
|
|
fig1 = row.get_metersplot_erg2(t)
|
|
elif (plotnr==8) or (plotnr==11):
|
|
fig1 = row.get_timeplot_erg2(t)
|
|
elif (plotnr==9) or (plotnr==12):
|
|
fig1 = row.get_time_otwpower(t)
|
|
elif (plotnr==13) or (plotnr==16):
|
|
fig1 = row.get_power_piechart(t)
|
|
|
|
canvas = FigureCanvas(fig1)
|
|
|
|
# plt.savefig('static/plots/'+imagename,format='png')
|
|
canvas.print_figure('static/plots/'+imagename)
|
|
# plt.imsave(fname='static/plots/'+imagename)
|
|
plt.close(fig1)
|
|
fig1.clf()
|
|
gc.collect()
|
|
|
|
return imagename
|
|
|
|
# Team related remote tasks
|
|
|
|
@app.task
|
|
def handle_sendemail_invite(email,name,code,teamname,manager):
|
|
fullemail = name+' <'+email+'>'
|
|
subject = 'Invitation to join team '+teamname
|
|
message = 'Dear '+name+',\n\n'
|
|
message += manager+' is inviting you to join his team '+teamname
|
|
message += ' on rowsandall.com\n\n'
|
|
message += 'By accepting the invite, you will have access to your'
|
|
message += " team's workouts on rowsandall.com and your workouts will "
|
|
message += " be visible to "
|
|
message += "the members of the team.\n\n"
|
|
message += 'If you already have an account on rowsandall.com, you can login to the site and you will find the invitation here on the Teams page:\n'
|
|
message += ' https://rowsandall.com/rowers/me/teams \n\n'
|
|
message += 'You can also click the direct link: \n'
|
|
message += 'https://rowsandall.com/rowers/me/invitation/'+code+' \n\n'
|
|
message += 'If you are not yet registered to rowsandall.com, '
|
|
message += 'you can register for free at https://rowsandall.com/rowers/register\n'
|
|
message += 'After you set up your account, you can use the direct link: '
|
|
message += 'https://rowsandall.com/rowers/me/invitation/'+code+' \n\n'
|
|
|
|
message += 'You can also manually accept your team membership with the code.\n'
|
|
message += 'You will need to do this if you registered under a different email address than this one.\n'
|
|
message += 'Code: '+code+'\n'
|
|
message += 'Link to manually accept your team membership: '
|
|
message += 'https://rowsandall.com/rowers/me/invitation\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemailnewresponse(first_name,last_name,
|
|
email,
|
|
commenter_first_name,
|
|
commenter_last_name,
|
|
comment,
|
|
workoutname,workoutid,commentid):
|
|
fullemail = first_name+' '+last_name+' <'+email+'>'
|
|
subject = 'New comment on workout '+workoutname
|
|
message = 'Dear '+first_name+',\n\n'
|
|
message += commenter_first_name+' '+commenter_last_name
|
|
message += ' has written a new comment on the workout '
|
|
message += workoutname+'\n\n'
|
|
message += comment
|
|
message += '\n\n'
|
|
message += 'You can read the comment here:\n'
|
|
message += 'https://rowsandall.com/rowers/workout/'+str(workoutid)+'/comment'
|
|
message += '\n\n'
|
|
message += 'You are receiving this email because you are subscribed '
|
|
message += 'to comments on this workout. To unsubscribe, follow this link:\n'
|
|
message += 'https://rowsandall.com/rowers/workout/'+str(workoutid)+'/unsubscribe'
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemailnewcomment(first_name,
|
|
last_name,
|
|
email,
|
|
commenter_first_name,
|
|
commenter_last_name,
|
|
comment,workoutname,
|
|
workoutid):
|
|
fullemail = first_name+' '+last_name+' <'+email+'>'
|
|
subject = 'New comment on workout '+workoutname
|
|
message = 'Dear '+first_name+',\n\n'
|
|
message += commenter_first_name+' '+commenter_last_name
|
|
message += ' has written a new comment on your workout '
|
|
message += workoutname+'\n\n'
|
|
message += comment
|
|
message += '\n\n'
|
|
message += 'You can read the comment here:\n'
|
|
message += 'https://rowsandall.com/rowers/workout/'+str(workoutid)+'/comment'
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
|
|
@app.task
|
|
def handle_sendemail_request(email,name,code,teamname,requestor,id):
|
|
fullemail = name+' <'+email+'>'
|
|
subject = 'Request to join team '+teamname
|
|
message = 'Dear '+name+',\n\n'
|
|
message += requestor+' is requesting admission to your team '+teamname
|
|
message += ' on rowsandall.com\n\n'
|
|
message += 'Click the direct link to accept: \n'
|
|
message += 'https://rowsandall.com/rowers/me/request/'+code+' \n\n'
|
|
message += 'Click the following link to reject the request: \n'
|
|
message += 'https://rowsandall.com/rowers/me/request/'+str(id)+' \n\n'
|
|
message += 'You can find all pending requests on your team management page:\n'
|
|
message += 'https://rowsandall.com/rowers/me/teams\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemail_request_accept(email,name,teamname,managername):
|
|
fullemail = name+' <'+email+'>'
|
|
subject = 'Welcome to '+teamname
|
|
message = 'Dear '+name+',\n\n'
|
|
message += managername
|
|
message += ' has accepted your request to be part of the team '
|
|
message += teamname
|
|
message += '\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemail_request_reject(email,name,teamname,managername):
|
|
fullemail = name+' <'+email+'>'
|
|
subject = 'Your application to '+teamname+' was rejected'
|
|
message = 'Dear '+name+',\n\n'
|
|
message += 'Unfortunately, '
|
|
message += managername
|
|
message += ' has rejected your request to be part of the team '
|
|
message += teamname
|
|
message += '\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemail_member_dropped(email,name,teamname,managername):
|
|
fullemail = name+' <'+email+'>'
|
|
subject = 'You were removed from '+teamname
|
|
message = 'Dear '+name+',\n\n'
|
|
message += 'Unfortunately, '
|
|
message += managername
|
|
message += ' has removed you from the team '
|
|
message += teamname
|
|
message += '\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemail_team_removed(email,name,teamname,managername):
|
|
fullemail = name+' <'+email+'>'
|
|
subject = 'Team '+teamname+' was deleted'
|
|
message = 'Dear '+name+',\n\n'
|
|
message += managername
|
|
message += ' has decided to delete the team '
|
|
message += teamname
|
|
message += '\n\n'
|
|
message += 'The '+teamname+' tag has been removed from all your '
|
|
message += 'workouts on rowsandall.com.\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemail_invite_reject(email,name,teamname,managername):
|
|
fullemail = managername+' <'+email+'>'
|
|
subject = 'Your invitation to '+name+' was rejected'
|
|
message = 'Dear '+managername+',\n\n'
|
|
message += 'Unfortunately, '
|
|
message += name
|
|
message += ' has rejected your invitation to be part of the team '
|
|
message += teamname
|
|
message += '\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
@app.task
|
|
def handle_sendemail_invite_accept(email,name,teamname,managername):
|
|
fullemail = managername+' <'+email+'>'
|
|
subject = 'Your invitation to '+name+' was accepted'
|
|
message = 'Dear '+managername+',\n\n'
|
|
message += name+' has accepted your invitation to be part of the team '+teamname+'\n\n'
|
|
message += "Best Regards, the Rowsandall Team"
|
|
|
|
email = EmailMessage(subject, message,
|
|
'Rowsandall <info@rowsandall.com>',
|
|
[fullemail])
|
|
|
|
|
|
res = email.send()
|
|
|
|
return 1
|
|
|
|
|
|
|
|
# Another simple task for debugging purposes
|
|
def add2(x,y):
|
|
return x+y
|