Merge branch 'release/v6.27'
This commit is contained in:
@@ -677,14 +677,11 @@ def getsmallrowdata_db(columns,ids=[],debug=False):
|
|||||||
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False,
|
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False,
|
||||||
doclean=False):
|
doclean=False):
|
||||||
# test if nan among values
|
# test if nan among values
|
||||||
if np.nan in m.values() or np.inf in m.values():
|
for key in m.keys():
|
||||||
for key in m.keys():
|
if str(m[key]) == 'nan':
|
||||||
if np.isnan([m[key]]):
|
m[key] = -1
|
||||||
m[key] = -1
|
if 'inf' in str(m[key]):
|
||||||
if m[key] == np.inf:
|
m[key] = -1
|
||||||
m[key] = -1
|
|
||||||
if -m[key] == np.inf:
|
|
||||||
m[key] = -1
|
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
engine = create_engine(database_url_debug, echo=False)
|
engine = create_engine(database_url_debug, echo=False)
|
||||||
@@ -702,9 +699,10 @@ def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False,
|
|||||||
|
|
||||||
values = tuple(m[key] for key in m.keys())
|
values = tuple(m[key] for key in m.keys())
|
||||||
with engine.connect() as conn, conn.begin():
|
with engine.connect() as conn, conn.begin():
|
||||||
result = conn.execute(query,values)
|
|
||||||
if doclean:
|
if doclean:
|
||||||
result2 = conn.execute(query2)
|
result2 = conn.execute(query2)
|
||||||
|
result = conn.execute(query,values)
|
||||||
|
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
|
|||||||
+283
-385
@@ -5,6 +5,7 @@ import gc
|
|||||||
import gzip
|
import gzip
|
||||||
import shutil
|
import shutil
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import re
|
||||||
|
|
||||||
from scipy import optimize
|
from scipy import optimize
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ import pandas as pd
|
|||||||
|
|
||||||
from django_rq import job
|
from django_rq import job
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.html import strip_tags
|
||||||
|
|
||||||
from utils import deserialize_list
|
from utils import deserialize_list
|
||||||
|
|
||||||
@@ -40,7 +42,13 @@ from rowers.dataprepnodjango import (
|
|||||||
create_c2_stroke_data_db
|
create_c2_stroke_data_db
|
||||||
)
|
)
|
||||||
|
|
||||||
from django.core.mail import send_mail, EmailMessage
|
|
||||||
|
from django.core.mail import (
|
||||||
|
send_mail,
|
||||||
|
EmailMessage,EmailMultiAlternatives,
|
||||||
|
)
|
||||||
|
from django.template.loader import get_template
|
||||||
|
from django.template import Context
|
||||||
from django.db.utils import OperationalError
|
from django.db.utils import OperationalError
|
||||||
|
|
||||||
import datautils
|
import datautils
|
||||||
@@ -51,6 +59,51 @@ import arrow
|
|||||||
|
|
||||||
# testing task
|
# testing task
|
||||||
|
|
||||||
|
from django.contrib.staticfiles import finders
|
||||||
|
|
||||||
|
def textify(html):
|
||||||
|
# Remove html tags and continuous whitespaces
|
||||||
|
text_only = re.sub('[ \t]+', ' ', strip_tags(html))
|
||||||
|
# Strip single spaces in the beginning of each line
|
||||||
|
return text_only.replace('\n ', '\n').strip()
|
||||||
|
|
||||||
|
def send_template_email(from_email,to_email,subject,
|
||||||
|
template,context,
|
||||||
|
*args,**kwargs):
|
||||||
|
|
||||||
|
htmly = get_template(template)
|
||||||
|
|
||||||
|
html_content = htmly.render(context)
|
||||||
|
text_content = textify(html_content)
|
||||||
|
|
||||||
|
msg = EmailMultiAlternatives(subject, text_content, from_email, to_email)
|
||||||
|
msg.attach_alternative(html_content, "text/html")
|
||||||
|
|
||||||
|
if 'attach_file' in kwargs:
|
||||||
|
fileobj = kwargs['attach_file']
|
||||||
|
if os.path.isfile(fileobj):
|
||||||
|
msg.attach_file(fileobj)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
fileobj2 = fileobj
|
||||||
|
with gzip.open(fileobj+'.gz','rb') as f_in, open(fileobj2,'wb') as f_out:
|
||||||
|
shutil.copyfileobj(f_in,f_out)
|
||||||
|
msg.attach_file(fileobj2)
|
||||||
|
os.remove(fileobj2)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if 'emailbounced' in kwargs:
|
||||||
|
emailbounced = kwargs['emailbounced']
|
||||||
|
else:
|
||||||
|
emailbounced = False
|
||||||
|
|
||||||
|
if not emailbounced:
|
||||||
|
res = msg.send()
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
@@ -297,67 +350,43 @@ def handle_sendemail_breakthrough(workoutid, useremail,
|
|||||||
btvalues=pd.DataFrame().to_json(),
|
btvalues=pd.DataFrame().to_json(),
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
|
||||||
|
if 'debug' in kwargs:
|
||||||
|
debug = kwargs['debug']
|
||||||
|
else:
|
||||||
|
debug = False
|
||||||
|
|
||||||
siteurl = SITE_URL
|
siteurl = SITE_URL
|
||||||
if debug:
|
if debug:
|
||||||
siteurl = SITE_URL_DEV
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
# send email with attachment
|
|
||||||
subject = "A breakthrough workout on rowsandall.com"
|
|
||||||
message = "Dear " + userfirstname + ",\n"
|
|
||||||
message += "Congratulations! Your recent workout has been analyzed"
|
|
||||||
message += " by Rowsandall.com and it appears your fitness,"
|
|
||||||
message += " as measured by Critical Power, has improved!"
|
|
||||||
message += " Critical Power (CP) is the power that you can "
|
|
||||||
message += "sustain for a given duration. For more, see this "
|
|
||||||
message += " article in the analytics blog:\n\n"
|
|
||||||
message += " http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/ \n\n"
|
|
||||||
message += "Link to the workout "+siteurl+"/rowers/workout/"
|
|
||||||
message += str(workoutid)
|
|
||||||
message += "/edit\n\n"
|
|
||||||
message += "To add the workout to your Ranking workouts and see the updated CP plot, click the following link:\n"
|
|
||||||
message += siteurl+"/rowers/workout/"
|
|
||||||
message += str(workoutid)
|
|
||||||
message += "/updatecp\n\n"
|
|
||||||
|
|
||||||
btvalues = pd.read_json(btvalues)
|
btvalues = pd.read_json(btvalues)
|
||||||
btvalues.sort_values('delta', axis=0, inplace=True)
|
btvalues.sort_values('delta', axis=0, inplace=True)
|
||||||
|
|
||||||
if not btvalues.empty:
|
tablevalues = [
|
||||||
message += "These were the breakthrough values:\n"
|
{'delta': t.delta,
|
||||||
for t in btvalues.itertuples():
|
'cpvalue': t.cpvalues,
|
||||||
delta = t.delta
|
'pwr': t.pwr
|
||||||
cpvalue = t.cpvalues
|
} for t in btvalues.itertuples()
|
||||||
pwr = t.pwr
|
]
|
||||||
|
|
||||||
message += "Time: {delta} seconds\n".format(
|
# send email with attachment
|
||||||
delta=delta
|
subject = "A breakthrough workout on rowsandall.com"
|
||||||
)
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
message += "New: {cpvalue:.0f} Watt\n".format(
|
|
||||||
cpvalue=cpvalue
|
|
||||||
)
|
|
||||||
message += "Old: {pwr:.0f} Watt\n\n".format(
|
|
||||||
pwr=pwr
|
|
||||||
)
|
|
||||||
|
|
||||||
message += "To opt out of these email notifications, deselect the checkbox on your Profile page under Account Information.\n\n"
|
d = {
|
||||||
|
'first_name':userfirstname,
|
||||||
|
'siteurl':siteurl,
|
||||||
|
'workoutid':workoutid,
|
||||||
|
'btvalues':tablevalues,
|
||||||
|
}
|
||||||
|
|
||||||
message += "Best Regards, the Rowsandall Team"
|
|
||||||
|
|
||||||
email = EmailMessage(subject, message,
|
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[useremail])
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
res = send_template_email(from_email,[useremail],
|
||||||
emailbounced = kwargs['emailbounced']
|
subject,'breakthroughemail.html',
|
||||||
else:
|
d,**kwargs)
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# remove tcx file
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# send email when a breakthrough workout is uploaded
|
# send email when a breakthrough workout is uploaded
|
||||||
@@ -369,43 +398,40 @@ def handle_sendemail_hard(workoutid, useremail,
|
|||||||
btvalues=pd.DataFrame().to_json(),
|
btvalues=pd.DataFrame().to_json(),
|
||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
|
|
||||||
|
if 'debug' in kwargs:
|
||||||
|
debug = kwargs['debug']
|
||||||
|
else:
|
||||||
|
debug = False
|
||||||
|
|
||||||
siteurl = SITE_URL
|
siteurl = SITE_URL
|
||||||
if debug:
|
if debug:
|
||||||
siteurl = SITE_URL_DEV
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
|
btvalues = pd.read_json(btvalues)
|
||||||
|
btvalues.sort_values('delta', axis=0, inplace=True)
|
||||||
|
|
||||||
|
tablevalues = [
|
||||||
|
{'delta': t.delta,
|
||||||
|
'cpvalue': t.cpvalues,
|
||||||
|
'pwr': t.pwr
|
||||||
|
} for t in btvalues.itertuples()
|
||||||
|
]
|
||||||
|
|
||||||
# send email with attachment
|
# send email with attachment
|
||||||
subject = "That was a pretty hard workout on rowsandall.com"
|
subject = "That was a pretty hard workout on rowsandall.com"
|
||||||
message = "Dear " + userfirstname + ",\n"
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
message += "Congratulations! Your recent workout has been analyzed"
|
|
||||||
message += " by Rowsandall.com and it appears that it was pretty hard work."
|
|
||||||
message += " You were working pretty close to your Critical Power\n\n"
|
|
||||||
message += " Critical Power (CP) is the power that you can "
|
|
||||||
message += "sustain for a given duration. For more, see this "
|
|
||||||
message += " article in the analytics blog:\n\n"
|
|
||||||
message += " http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/ \n\n"
|
|
||||||
message += "Link to the workout: "+siteurl+"/rowers/workout/"
|
|
||||||
message += str(workoutid)
|
|
||||||
message += "/edit\n\n"
|
|
||||||
|
|
||||||
message += "To opt out of these email notifications, deselect the checkbox on your Profile page under Account Information.\n\n"
|
d = {
|
||||||
|
'first_name':userfirstname,
|
||||||
|
'siteurl':siteurl,
|
||||||
|
'workoutid':workoutid,
|
||||||
|
'btvalues':tablevalues,
|
||||||
|
}
|
||||||
|
|
||||||
message += "Best Regards, the Rowsandall Team"
|
res = send_template_email(from_email,[useremail],
|
||||||
|
subject,'hardemail.html',d,**kwargs)
|
||||||
|
|
||||||
email = EmailMessage(subject, message,
|
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[useremail])
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
|
||||||
else:
|
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# remove tcx file
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@@ -482,33 +508,16 @@ def handle_sendemail_unrecognizedowner(useremail, userfirstname,
|
|||||||
# send email with attachment
|
# send email with attachment
|
||||||
fullemail = useremail
|
fullemail = useremail
|
||||||
subject = "Unrecognized file from Rowsandall.com"
|
subject = "Unrecognized file from Rowsandall.com"
|
||||||
message = "Dear " + userfirstname + ",\n\n"
|
|
||||||
message += """
|
|
||||||
The file you tried to send to rowsandall.com was not recognized by
|
|
||||||
our email processing system. You may have sent a file in a format
|
|
||||||
that is not supported. Sometimes, rowing apps make file format changes.
|
|
||||||
When that happens, it takes some time for rowsandall.comm to make
|
|
||||||
the necessary changes on our side and support the app again.
|
|
||||||
|
|
||||||
The file has been sent to the developer at rowsandall.com for evaluation.
|
htmly = get_template('unrecognizedemail.html')
|
||||||
|
|
||||||
|
d = {'first_name':userfirstname}
|
||||||
|
|
||||||
"""
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
|
|
||||||
message += "Best Regards, the Rowsandall Team"
|
res = send_template_email(from_email,[fullemail],
|
||||||
|
subject,'csvemail.html',d,
|
||||||
email = EmailMessage(subject, message,
|
**kwargs)
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[fullemail])
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
|
||||||
else:
|
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -520,26 +529,18 @@ def handle_sendemailtcx(first_name, last_name, email, tcxfile,**kwargs):
|
|||||||
# send email with attachment
|
# send email with attachment
|
||||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||||
subject = "File from Rowsandall.com"
|
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,
|
htmly = get_template('tcxemail.html')
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[fullemail])
|
|
||||||
|
|
||||||
email.attach_file(tcxfile)
|
d = {'first_name':first_name}
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
emailbounced = kwargs['emailbounced']
|
|
||||||
else:
|
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
# remove tcx file
|
res = send_template_email(from_email,[fullemail],
|
||||||
|
subject,'tcxemail.html',d,
|
||||||
|
attach_file=tcxfile,**kwargs)
|
||||||
|
|
||||||
os.remove(tcxfile)
|
os.remove(tcxfile)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -562,13 +563,8 @@ def handle_zip_file(emailfrom, subject, file,**kwargs):
|
|||||||
if debug:
|
if debug:
|
||||||
print "attaching"
|
print "attaching"
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
|
||||||
else:
|
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
res = email.send()
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
@@ -580,35 +576,20 @@ def handle_zip_file(emailfrom, subject, file,**kwargs):
|
|||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_sendemailsummary(first_name, last_name, email, csvfile, **kwargs):
|
def handle_sendemailsummary(first_name, last_name, email, csvfile, **kwargs):
|
||||||
# send email with attachment
|
|
||||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||||
subject = "File from Rowsandall.com"
|
subject = "File from Rowsandall.com"
|
||||||
message = "Dear " + first_name + ",\n\n"
|
|
||||||
message += "Please find attached the requested summary file.\n\n"
|
|
||||||
message += "Best Regards, the Rowsandall Team"
|
|
||||||
|
|
||||||
email = EmailMessage(subject, message,
|
htmly = get_template('summarymail.html')
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[fullemail])
|
|
||||||
|
|
||||||
if os.path.isfile(csvfile):
|
d = {'first_name':first_name}
|
||||||
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)
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
os.remove(csvfile2)
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
res = send_template_email(from_email,[fullemail],
|
||||||
emailbounced = kwargs['emailbounced']
|
subject,'summarymail.html',d,
|
||||||
else:
|
attach_file=csvfile,
|
||||||
emailbounced = False
|
**kwargs)
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.remove(csvfile)
|
os.remove(csvfile)
|
||||||
except:
|
except:
|
||||||
@@ -625,35 +606,16 @@ def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
|||||||
# send email with attachment
|
# send email with attachment
|
||||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||||
subject = "File from Rowsandall.com"
|
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"
|
|
||||||
|
|
||||||
|
d = {'first_name':first_name}
|
||||||
|
|
||||||
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
|
|
||||||
|
|
||||||
|
res = send_template_email(from_email,[fullemail],
|
||||||
|
subject,'csvemail.html',d,
|
||||||
|
attach_file=csvfile,**kwargs)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
|
||||||
else:
|
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -775,24 +737,22 @@ def handle_otwsetpower(self,f1, boattype, weightvalue,
|
|||||||
first_name,
|
first_name,
|
||||||
last_name, btvalues=btvalues.to_json())
|
last_name, btvalues=btvalues.to_json())
|
||||||
|
|
||||||
# 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: "
|
|
||||||
message += siteurl+"/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,
|
subject = "Your OTW Physics Calculations are ready"
|
||||||
'Rowsandall Physics Department <info@rowsandall.com>',
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
[fullemail])
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||||
|
|
||||||
|
htmly = get_template('otwpoweremail.html')
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'first_name':first_name,
|
||||||
|
'siteurl':siteurl,
|
||||||
|
'workoutid':workoutid,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = handle_template_email(from_email,[fullemail],
|
||||||
|
subject,'otwpoweremail.html',d,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1015,44 +975,25 @@ def handle_sendemail_invite(email, name, code, teamname, manager,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = name + ' <' + email + '>'
|
fullemail = name + ' <' + email + '>'
|
||||||
subject = 'Invitation to join team ' + teamname
|
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 += "By accepting the invite, you are agreeing with the sharing "
|
|
||||||
message += "of personal data according to our privacy policy.\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'
|
siteurl = SITE_URL
|
||||||
message += 'You will need to do this if you registered under a different email address than this one.\n'
|
if debug:
|
||||||
message += 'Code: ' + code + '\n'
|
siteurl = SITE_URL_DEV
|
||||||
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])
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
|
||||||
else:
|
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'name':name,
|
||||||
|
'manager':manager,
|
||||||
|
'code':code,
|
||||||
|
'teamname':teamname,
|
||||||
|
'siteurl':siteurl
|
||||||
|
}
|
||||||
|
|
||||||
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
|
|
||||||
|
res = send_template_email(from_email,[fullemail],
|
||||||
|
subject,'teaminviteemail.html',d,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@@ -1065,34 +1006,26 @@ def handle_sendemailnewresponse(first_name, last_name,
|
|||||||
workoutname, workoutid, commentid,
|
workoutname, workoutid, commentid,
|
||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = first_name + ' ' + last_name + ' <' + email + '>'
|
fullemail = first_name + ' ' + last_name + ' <' + email + '>'
|
||||||
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
subject = 'New comment on workout ' + workoutname
|
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
d = {
|
||||||
else:
|
'first_name':first_name,
|
||||||
emailbounced = False
|
'commenter_first_name':commenter_first_name,
|
||||||
|
'commenter_last_name':commenter_last_name,
|
||||||
|
'comment':comment,
|
||||||
|
'workoutname':workoutname,
|
||||||
|
'siteurl':siteurl,
|
||||||
|
'workoutid':workoutid,
|
||||||
|
'commentid':commentid
|
||||||
|
}
|
||||||
|
|
||||||
if not emailbounced:
|
res = send_template_email(from_email,[fullemail],subject,'teamresponseemail.html',d,**kwargs)
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1106,30 +1039,32 @@ def handle_sendemailnewcomment(first_name,
|
|||||||
comment, workoutname,
|
comment, workoutname,
|
||||||
workoutid,
|
workoutid,
|
||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fullemail = first_name + ' ' + last_name + ' <' + email + '>'
|
fullemail = first_name + ' ' + last_name + ' <' + email + '>'
|
||||||
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
subject = 'New comment on workout ' + workoutname
|
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
|
||||||
emailbounced = kwargs['emailbounced']
|
d = {
|
||||||
else:
|
'first_name':first_name,
|
||||||
emailbounced = False
|
'commenter_first_name':commenter_first_name,
|
||||||
|
'commenter_last_name':commenter_last_name,
|
||||||
|
'comment':comment,
|
||||||
|
'workoutname':workoutname,
|
||||||
|
'siteurl':siteurl,
|
||||||
|
'workoutid':workoutid,
|
||||||
|
'commentid':commentid
|
||||||
|
}
|
||||||
|
|
||||||
if not emailbounced:
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
res = email.send()
|
'teamresponseemail.html',d,**kwargs)
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1139,29 +1074,23 @@ def handle_sendemail_request(email, name, code, teamname, requestor, id,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = name + ' <' + email + '>'
|
fullemail = name + ' <' + email + '>'
|
||||||
subject = 'Request to join team ' + teamname
|
subject = 'Request to join team ' + teamname
|
||||||
message = 'Dear ' + name + ',\n\n'
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
d = {
|
||||||
emailbounced = kwargs['emailbounced']
|
'requestor':requestor,
|
||||||
else:
|
'teamname':teamname,
|
||||||
emailbounced = False
|
'siteurl':siteurl,
|
||||||
|
'id':id,
|
||||||
|
'first_name':name,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
|
'teamrequestemail.html',d,**kwargs)
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1171,25 +1100,20 @@ def handle_sendemail_request_accept(email, name, teamname, managername,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = name + ' <' + email + '>'
|
fullemail = name + ' <' + email + '>'
|
||||||
subject = 'Welcome to ' + teamname
|
subject = 'Welcome to ' + teamname
|
||||||
message = 'Dear ' + name + ',\n\n'
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
d = {
|
||||||
emailbounced = kwargs['emailbounced']
|
'first_name':name,
|
||||||
else:
|
'managername':managername,
|
||||||
emailbounced = False
|
'teamname':teamname,
|
||||||
|
}
|
||||||
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
|
'teamwelcomeemail.html',d,**kwargs)
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1199,26 +1123,19 @@ def handle_sendemail_request_reject(email, name, teamname, managername,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = name + ' <' + email + '>'
|
fullemail = name + ' <' + email + '>'
|
||||||
subject = 'Your application to ' + teamname + ' was rejected'
|
subject = 'Your application to ' + teamname + ' was rejected'
|
||||||
message = 'Dear ' + name + ',\n\n'
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
d = {
|
||||||
emailbounced = kwargs['emailbounced']
|
'first_name':name,
|
||||||
else:
|
'managername':managername,
|
||||||
emailbounced = False
|
'teamname':teamname,
|
||||||
|
}
|
||||||
if not emailbounced:
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
res = email.send()
|
'teamrejectemail.html',d,**kwargs)
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1228,26 +1145,20 @@ def handle_sendemail_member_dropped(email, name, teamname, managername,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = name + ' <' + email + '>'
|
fullemail = name + ' <' + email + '>'
|
||||||
subject = 'You were removed from ' + teamname
|
subject = 'You were removed from ' + teamname
|
||||||
message = 'Dear ' + name + ',\n\n'
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
d = {
|
||||||
emailbounced = kwargs['emailbounced']
|
'first_name':name,
|
||||||
else:
|
'managername':managername,
|
||||||
emailbounced = False
|
'teamname':teamname,
|
||||||
|
}
|
||||||
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
|
'teamdropemail.html',d,**kwargs)
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1255,29 +1166,23 @@ def handle_sendemail_member_dropped(email, name, teamname, managername,
|
|||||||
@app.task
|
@app.task
|
||||||
def handle_sendemail_team_removed(email, name, teamname, managername,
|
def handle_sendemail_team_removed(email, name, teamname, managername,
|
||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
|
|
||||||
fullemail = name + ' <' + email + '>'
|
fullemail = name + ' <' + email + '>'
|
||||||
subject = 'Team ' + teamname + ' was deleted'
|
subject = 'You were removed from ' + teamname
|
||||||
message = 'Dear ' + name + ',\n\n'
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
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,
|
siteurl = SITE_URL
|
||||||
'Rowsandall <info@rowsandall.com>',
|
if debug:
|
||||||
[fullemail])
|
siteurl = SITE_URL_DEV
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
d = {
|
||||||
emailbounced = kwargs['emailbounced']
|
'first_name':name,
|
||||||
else:
|
'managername':managername,
|
||||||
emailbounced = False
|
'teamname':teamname,
|
||||||
|
}
|
||||||
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
|
'teamremoveemail.html',d,**kwargs)
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1287,26 +1192,20 @@ def handle_sendemail_invite_reject(email, name, teamname, managername,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = managername + ' <' + email + '>'
|
fullemail = managername + ' <' + email + '>'
|
||||||
subject = 'Your invitation to ' + name + ' was rejected'
|
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,
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[fullemail])
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
siteurl = SITE_URL
|
||||||
emailbounced = kwargs['emailbounced']
|
if debug:
|
||||||
else:
|
siteurl = SITE_URL_DEV
|
||||||
emailbounced = False
|
|
||||||
|
|
||||||
if not emailbounced:
|
d = {
|
||||||
res = email.send()
|
'first_name':name,
|
||||||
|
'managername':managername,
|
||||||
|
'teamname':teamname,
|
||||||
|
}
|
||||||
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
|
'teaminviterejectemail.html',d,**kwargs)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -1316,22 +1215,21 @@ def handle_sendemail_invite_accept(email, name, teamname, managername,
|
|||||||
debug=False,**kwargs):
|
debug=False,**kwargs):
|
||||||
fullemail = managername + ' <' + email + '>'
|
fullemail = managername + ' <' + email + '>'
|
||||||
subject = 'Your invitation to ' + name + ' was accepted'
|
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,
|
from_email = 'Rowsandall <info@rowsandall.com>'
|
||||||
'Rowsandall <info@rowsandall.com>',
|
|
||||||
[fullemail])
|
|
||||||
|
|
||||||
if 'emailbounced' in kwargs:
|
siteurl = SITE_URL
|
||||||
emailbounced = kwargs['emailbounced']
|
if debug:
|
||||||
else:
|
siteurl = SITE_URL_DEV
|
||||||
emailbounced = False
|
|
||||||
|
d = {
|
||||||
|
'first_name':name,
|
||||||
|
'managername':managername,
|
||||||
|
'teamname':teamname,
|
||||||
|
}
|
||||||
|
res = send_template_email(from_email,[fullemail],subject,
|
||||||
|
'teaminviteacceptemail.html',d,**kwargs)
|
||||||
|
|
||||||
if not emailbounced:
|
|
||||||
res = email.send()
|
|
||||||
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|||||||
@@ -393,6 +393,7 @@ def send_request_email(rekwest):
|
|||||||
code = rekwest.code
|
code = rekwest.code
|
||||||
teamname = rekwest.team.name
|
teamname = rekwest.team.name
|
||||||
requestor = rekwest.user.first_name+' '+rekwest.user.last_name
|
requestor = rekwest.user.first_name+' '+rekwest.user.last_name
|
||||||
|
print requestor,'aap'
|
||||||
|
|
||||||
res = myqueue(queuehigh,
|
res = myqueue(queuehigh,
|
||||||
handle_sendemail_request,
|
handle_sendemail_request,
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Congratulations! Your recent workout has been analyzed
|
||||||
|
by Rowsandall.com and it appears your fitness,
|
||||||
|
as measured by Critical Power, has improved!
|
||||||
|
Critical Power (CP) is the power that you can
|
||||||
|
sustain for a given duration. For more, see this
|
||||||
|
article in the analytics blog:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/">
|
||||||
|
http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Link to the workout: <a href="{{ siteurl }}/rowers/workout/{{ workoutid }}">
|
||||||
|
{{ siteurl }}/rowers/workout/{{ workoutid }}</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To add the workout to your Ranking workouts and see the updated CP plot,
|
||||||
|
click the following link:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="{{ siteurl }}/rowers/workout/{{ workoutid }}/updatecp">
|
||||||
|
{{ siteurl }}/rowers/workout/{{ workoutid }}/updatecp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% if btvalues %}
|
||||||
|
<p>
|
||||||
|
These were the breakthrough values:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Time (sec)</th><th>New Power (W)</th><th>Old Power </th>
|
||||||
|
</tr>
|
||||||
|
{% for set in btvalues %}
|
||||||
|
<tr>
|
||||||
|
<th>{{ set|lookup:"delta" }}</th>
|
||||||
|
<th>{{ set|lookup:"cpvalue" }}</th>
|
||||||
|
<th>{{ set|lookup:"pwr" }}</th>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To opt out of these email notifications, deselect the checkbox on your Profile
|
||||||
|
page under Account Information.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please find attached the requested file for your workout.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<font face="verdana, sans-serif">
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
|
||||||
|
<img src="https://rowsandall.com/static/img/logoemail.png" height="50">
|
||||||
|
<font face="verdana, sans-serif">
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please find attached the requested file for your workout.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Congratulations! Your recent workout has been analyzed
|
||||||
|
by Rowsandall.com and it appears it was pretty hard work.
|
||||||
|
You were working pretty close to your Critical Power.
|
||||||
|
Critical Power (CP) is the power that you can
|
||||||
|
sustain for a given duration. For more, see this
|
||||||
|
article in the analytics blog:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/">
|
||||||
|
http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Link to the workout: <a href="{{ siteurl }}/rowers/workout/{{ workoutid }}">
|
||||||
|
{{ siteurl }}/rowers/workout/{{ workoutid }}</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To opt out of these email notifications, deselect the checkbox on your Profile
|
||||||
|
page under Account Information.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Your Rowsandall OTW calculations are ready.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Thank you for using rowsandall.com.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Rowsandall OTW calculations have not been fully implemented yet.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We are now running an experimental version for debugging purposes.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Your wind/stream corrected plot is available here:
|
||||||
|
<a href="{{ siteurl }}/rowers/workout/{{ workoutid }}/interactiveotwplot">
|
||||||
|
{{ siteurl }}/rowers/workout/{{ workoutid }}/interactiveotwplot</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Please report any bugs/inconsistencies/unexpected results
|
||||||
|
by reply to this email.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Physics Department
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please find attached the requested summary file.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please find attached the requested file for your workout.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unfortunately,
|
||||||
|
{{ managername }} has removed you from
|
||||||
|
the team {{ teamname }}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ managername }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ first_name }} has accepted your invitation to be
|
||||||
|
part of the team {{ teamname }}.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ manager }} is inviting you to join his team {{ teamname }}
|
||||||
|
on rowsandall.com
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
By accepting the invite, you will have access to your
|
||||||
|
team's workouts on rowsandall.com and your workouts will
|
||||||
|
be visible to
|
||||||
|
the members of the team.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
By accepting the invite, you are agreeing with the sharing
|
||||||
|
of personal data according to our privacy policy.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
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:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/teams">{{ siteurl }}/rowers/me/teams</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can also click the direct link:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/invitation/{{ code }}">
|
||||||
|
{{ siteurl }}/rowers/me/invitation/{{ code }}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you are not yet registered to rowsandall.com,
|
||||||
|
you can register for free at
|
||||||
|
<a href="{{ siteurl }}/rowers/register">{{ siteurl }}/rowers/register</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
After you set up your account, you can use the direct link:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/invitation/{{ code }}">
|
||||||
|
{{ siteurl }}/rowers/me/invitation/{{ code }}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can also manually accept your team membership with the code.
|
||||||
|
You will need to do this if you registered under a different email address than this one.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Code: {{ code }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Link to manually accept your team membership:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/invitation">
|
||||||
|
{{ siteurl }}/rowers/me/invitation</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ managername }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unfortunately,
|
||||||
|
{{ first_name }} has rejected your invitation to be
|
||||||
|
part of the team {{ teamname }}.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unfortunately,
|
||||||
|
{{ managername }} has rejected your request to be part
|
||||||
|
of the team {{ teamname }}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ managername }} has decided to delete the team {{ teamname }}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The {{ teamname }} tag has been removed from all your
|
||||||
|
workouts on rowsandall.com
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ requestor }} is requesting access to your team {{ teamname }}
|
||||||
|
on rowsandall.com
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Click the direct link to accept:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/request/{{ code }}">
|
||||||
|
{{ siteurl }}/rowers/me/request/{{ code }}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Click the following link to reject the request:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/request/{{ id }}">
|
||||||
|
{{ siteurl }}/rowers/me/request/{{ id }}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can find all pending requests on your team management page:
|
||||||
|
<a href="{{ siteurl }}/rowers/me/teams">{{ siteurl }}/rowers/me/teams</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ commenter_first_name }} {{ commenter_last_name }} has written
|
||||||
|
a new comment on workout {{ workoutname }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ comment }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can read the comment here:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="{{ siteurl }}/rowers/workout/{{ workoutid }}/comment">
|
||||||
|
{{ siteurl }}/rowers/workout/{{ workoutid }}/comment</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ managername }} has accepted your request to be part
|
||||||
|
of the team {{ teamname }}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ first_name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The file you tried to send to rowsandall.com was not recognized by
|
||||||
|
our email processing system. You may have sent a file in a format
|
||||||
|
that is not supported. Sometimes, rowing apps make file format changes.
|
||||||
|
When that happens, it takes some time for rowsandall.comm to make
|
||||||
|
the necessary changes on our side and support the app again.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The file has been sent to the developer at rowsandall.com for evaluation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -7,6 +7,7 @@ from django.conf import settings
|
|||||||
import uuid
|
import uuid
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
lbstoN = 4.44822
|
lbstoN = 4.44822
|
||||||
|
|
||||||
landingpages = (
|
landingpages = (
|
||||||
|
|||||||
+2
-1
@@ -13031,7 +13031,8 @@ def plannedsession_view(request,id=0,rowerid=0,
|
|||||||
{
|
{
|
||||||
'psdict': psdict,
|
'psdict': psdict,
|
||||||
'attrs':[
|
'attrs':[
|
||||||
'name','startdate','enddate','sessiontype',
|
'name','startdate','enddate','preferreddate',
|
||||||
|
'sessiontype',
|
||||||
'sessionmode','criterium',
|
'sessionmode','criterium',
|
||||||
'sessionvalue','sessionunit','comment',
|
'sessionvalue','sessionunit','comment',
|
||||||
],
|
],
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
Reference in New Issue
Block a user