diff --git a/rowers/dataprepnodjango.py b/rowers/dataprepnodjango.py
index e9e3cd10..49a3e6dc 100644
--- a/rowers/dataprepnodjango.py
+++ b/rowers/dataprepnodjango.py
@@ -677,14 +677,11 @@ def getsmallrowdata_db(columns,ids=[],debug=False):
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False,
doclean=False):
# test if nan among values
- if np.nan in m.values() or np.inf in m.values():
- for key in m.keys():
- if np.isnan([m[key]]):
- m[key] = -1
- if m[key] == np.inf:
- m[key] = -1
- if -m[key] == np.inf:
- m[key] = -1
+ for key in m.keys():
+ if str(m[key]) == 'nan':
+ m[key] = -1
+ if 'inf' in str(m[key]):
+ m[key] = -1
if debug:
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())
with engine.connect() as conn, conn.begin():
- result = conn.execute(query,values)
if doclean:
result2 = conn.execute(query2)
+ result = conn.execute(query,values)
+
conn.close()
engine.dispose()
diff --git a/rowers/tasks.py b/rowers/tasks.py
index 42568a6e..d802a565 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -5,6 +5,7 @@ import gc
import gzip
import shutil
import numpy as np
+import re
from scipy import optimize
@@ -29,6 +30,7 @@ import pandas as pd
from django_rq import job
from django.utils import timezone
+from django.utils.html import strip_tags
from utils import deserialize_list
@@ -40,7 +42,13 @@ from rowers.dataprepnodjango import (
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
import datautils
@@ -51,6 +59,51 @@ import arrow
# 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
@@ -297,67 +350,43 @@ def handle_sendemail_breakthrough(workoutid, useremail,
btvalues=pd.DataFrame().to_json(),
**kwargs):
+ if 'debug' in kwargs:
+ debug = kwargs['debug']
+ else:
+ debug = False
+
siteurl = SITE_URL
if debug:
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.sort_values('delta', axis=0, inplace=True)
- if not btvalues.empty:
- message += "These were the breakthrough values:\n"
- for t in btvalues.itertuples():
- delta = t.delta
- cpvalue = t.cpvalues
- pwr = t.pwr
+ tablevalues = [
+ {'delta': t.delta,
+ 'cpvalue': t.cpvalues,
+ 'pwr': t.pwr
+ } for t in btvalues.itertuples()
+ ]
- message += "Time: {delta} seconds\n".format(
- delta=delta
- )
- message += "New: {cpvalue:.0f} Watt\n".format(
- cpvalue=cpvalue
- )
- message += "Old: {pwr:.0f} Watt\n\n".format(
- pwr=pwr
- )
+ # send email with attachment
+ subject = "A breakthrough workout on rowsandall.com"
+ from_email = 'Rowsandall '
- 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 ',
- [useremail])
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ res = send_template_email(from_email,[useremail],
+ subject,'breakthroughemail.html',
+ d,**kwargs)
- if not emailbounced:
- res = email.send()
-
-
- # remove tcx file
return 1
# send email when a breakthrough workout is uploaded
@@ -369,43 +398,40 @@ def handle_sendemail_hard(workoutid, useremail,
btvalues=pd.DataFrame().to_json(),
debug=False,**kwargs):
+ if 'debug' in kwargs:
+ debug = kwargs['debug']
+ else:
+ debug = False
+
siteurl = SITE_URL
if debug:
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
subject = "That was a pretty hard workout on rowsandall.com"
- message = "Dear " + userfirstname + ",\n"
- 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"
+ from_email = 'Rowsandall '
- 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 ',
- [useremail])
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
-
- if not emailbounced:
- res = email.send()
-
-
-
- # remove tcx file
return 1
@@ -482,33 +508,16 @@ def handle_sendemail_unrecognizedowner(useremail, userfirstname,
# send email with attachment
fullemail = useremail
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 '
- message += "Best Regards, the Rowsandall Team"
-
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
-
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
-
- if not emailbounced:
- res = email.send()
-
+ res = send_template_email(from_email,[fullemail],
+ subject,'csvemail.html',d,
+ **kwargs)
return 1
@@ -520,26 +529,18 @@ def handle_sendemailtcx(first_name, last_name, email, tcxfile,**kwargs):
# 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 ',
- [fullemail])
+ htmly = get_template('tcxemail.html')
- email.attach_file(tcxfile)
+ d = {'first_name':first_name}
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ from_email = 'Rowsandall '
- 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)
return 1
@@ -562,13 +563,8 @@ def handle_zip_file(emailfrom, subject, file,**kwargs):
if debug:
print "attaching"
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
- if not emailbounced:
- res = email.send()
+ res = email.send()
if debug:
@@ -580,35 +576,20 @@ def handle_zip_file(emailfrom, subject, file,**kwargs):
@app.task
def handle_sendemailsummary(first_name, last_name, email, csvfile, **kwargs):
- # 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 summary file.\n\n"
- message += "Best Regards, the Rowsandall Team"
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
+ htmly = get_template('summarymail.html')
- 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)
+ d = {'first_name':first_name}
- email.attach_file(csvfile2)
- os.remove(csvfile2)
+ from_email = 'Rowsandall '
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
-
- if not emailbounced:
- res = email.send()
-
+ res = send_template_email(from_email,[fullemail],
+ subject,'summarymail.html',d,
+ attach_file=csvfile,
+ **kwargs)
+
try:
os.remove(csvfile)
except:
@@ -625,35 +606,16 @@ def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
# 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"
-
+ d = {'first_name':first_name}
+
+ from_email = 'Rowsandall '
+
+
+ res = send_template_email(from_email,[fullemail],
+ subject,'csvemail.html',d,
+ attach_file=csvfile,**kwargs)
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [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
@@ -775,24 +737,22 @@ def handle_otwsetpower(self,f1, boattype, weightvalue,
first_name,
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,
- 'Rowsandall Physics Department ',
- [fullemail])
+ subject = "Your OTW Physics Calculations are ready"
+ from_email = 'Rowsandall '
+ 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
@@ -1015,44 +975,25 @@ def handle_sendemail_invite(email, name, code, teamname, manager,
debug=False,**kwargs):
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 += "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'
- 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 ',
- [fullemail])
-
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
-
- if not emailbounced:
- res = email.send()
-
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
+ d = {
+ 'name':name,
+ 'manager':manager,
+ 'code':code,
+ 'teamname':teamname,
+ 'siteurl':siteurl
+ }
+
+ from_email = 'Rowsandall '
+
+ res = send_template_email(from_email,[fullemail],
+ subject,'teaminviteemail.html',d,
+ **kwargs)
+
return 1
@@ -1065,34 +1006,26 @@ def handle_sendemailnewresponse(first_name, last_name,
workoutname, workoutid, commentid,
debug=False,**kwargs):
fullemail = first_name + ' ' + last_name + ' <' + email + '>'
+ from_email = 'Rowsandall '
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 ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+
+ d = {
+ 'first_name':first_name,
+ '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 = email.send()
-
+ res = send_template_email(from_email,[fullemail],subject,'teamresponseemail.html',d,**kwargs)
return 1
@@ -1106,30 +1039,32 @@ def handle_sendemailnewcomment(first_name,
comment, workoutname,
workoutid,
debug=False,**kwargs):
+
+
+
fullemail = first_name + ' ' + last_name + ' <' + email + '>'
+ from_email = 'Rowsandall '
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 ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+
+ d = {
+ 'first_name':first_name,
+ '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 = email.send()
-
+ res = send_template_email(from_email,[fullemail],subject,
+ 'teamresponseemail.html',d,**kwargs)
+
return 1
@@ -1139,29 +1074,23 @@ def handle_sendemail_request(email, name, code, teamname, requestor, id,
debug=False,**kwargs):
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"
+ from_email = 'Rowsandall '
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ d = {
+ 'requestor':requestor,
+ 'teamname':teamname,
+ '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
@@ -1171,25 +1100,20 @@ def handle_sendemail_request_accept(email, name, teamname, managername,
debug=False,**kwargs):
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"
+ from_email = 'Rowsandall '
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ d = {
+ 'first_name':name,
+ 'managername':managername,
+ 'teamname':teamname,
+ }
+ res = send_template_email(from_email,[fullemail],subject,
+ 'teamwelcomeemail.html',d,**kwargs)
- if not emailbounced:
- res = email.send()
-
return 1
@@ -1199,26 +1123,19 @@ def handle_sendemail_request_reject(email, name, teamname, managername,
debug=False,**kwargs):
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"
+ from_email = 'Rowsandall '
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
-
- if not emailbounced:
- res = email.send()
-
+ d = {
+ 'first_name':name,
+ 'managername':managername,
+ 'teamname':teamname,
+ }
+ res = send_template_email(from_email,[fullemail],subject,
+ 'teamrejectemail.html',d,**kwargs)
return 1
@@ -1228,26 +1145,20 @@ def handle_sendemail_member_dropped(email, name, teamname, managername,
debug=False,**kwargs):
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"
+ from_email = 'Rowsandall '
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ d = {
+ 'first_name':name,
+ 'managername':managername,
+ 'teamname':teamname,
+ }
+ res = send_template_email(from_email,[fullemail],subject,
+ 'teamdropemail.html',d,**kwargs)
- if not emailbounced:
- res = email.send()
-
return 1
@@ -1255,29 +1166,23 @@ def handle_sendemail_member_dropped(email, name, teamname, managername,
@app.task
def handle_sendemail_team_removed(email, name, teamname, managername,
debug=False,**kwargs):
+
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"
+ subject = 'You were removed from ' + teamname
+ from_email = 'Rowsandall '
- email = EmailMessage(subject, message,
- 'Rowsandall ',
- [fullemail])
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ d = {
+ 'first_name':name,
+ 'managername':managername,
+ 'teamname':teamname,
+ }
+ res = send_template_email(from_email,[fullemail],subject,
+ 'teamremoveemail.html',d,**kwargs)
- if not emailbounced:
- res = email.send()
-
return 1
@@ -1287,26 +1192,20 @@ def handle_sendemail_invite_reject(email, name, teamname, managername,
debug=False,**kwargs):
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 ',
- [fullemail])
+ from_email = 'Rowsandall '
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
- if not emailbounced:
- res = email.send()
-
+ d = {
+ 'first_name':name,
+ 'managername':managername,
+ 'teamname':teamname,
+ }
+ res = send_template_email(from_email,[fullemail],subject,
+ 'teaminviterejectemail.html',d,**kwargs)
return 1
@@ -1316,22 +1215,21 @@ def handle_sendemail_invite_accept(email, name, teamname, managername,
debug=False,**kwargs):
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 ',
- [fullemail])
+ from_email = 'Rowsandall '
- if 'emailbounced' in kwargs:
- emailbounced = kwargs['emailbounced']
- else:
- emailbounced = False
+ siteurl = SITE_URL
+ if debug:
+ siteurl = SITE_URL_DEV
+
+ 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
diff --git a/rowers/teams.py b/rowers/teams.py
index ba802fd2..7ddbfcad 100644
--- a/rowers/teams.py
+++ b/rowers/teams.py
@@ -393,6 +393,7 @@ def send_request_email(rekwest):
code = rekwest.code
teamname = rekwest.team.name
requestor = rekwest.user.first_name+' '+rekwest.user.last_name
+ print requestor,'aap'
res = myqueue(queuehigh,
handle_sendemail_request,
diff --git a/rowers/templates/breakthroughemail.html b/rowers/templates/breakthroughemail.html
new file mode 100644
index 00000000..bd1107ab
--- /dev/null
+++ b/rowers/templates/breakthroughemail.html
@@ -0,0 +1,68 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ 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:
+
+
+
+
+ http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/
+
+
+
+ Link to the workout:
+ {{ siteurl }}/rowers/workout/{{ workoutid }}
+
+
+
+ To add the workout to your Ranking workouts and see the updated CP plot,
+ click the following link:
+
+
+
+
+ {{ siteurl }}/rowers/workout/{{ workoutid }}/updatecp
+
+
+{% if btvalues %}
+
+ These were the breakthrough values:
+
+
+
+
+
+ | Time (sec) | New Power (W) | Old Power |
+
+ {% for set in btvalues %}
+
+ | {{ set|lookup:"delta" }} |
+ {{ set|lookup:"cpvalue" }} |
+ {{ set|lookup:"pwr" }} |
+
+ {% endfor %}
+
+
+{% endif %}
+
+
+
+ To opt out of these email notifications, deselect the checkbox on your Profile
+ page under Account Information.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
+
diff --git a/rowers/templates/csvemail.html b/rowers/templates/csvemail.html
new file mode 100644
index 00000000..edb5ec7e
--- /dev/null
+++ b/rowers/templates/csvemail.html
@@ -0,0 +1,15 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+ Dear {{ first_name }},
+
+
+ Please find attached the requested file for your workout.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/emailbase.html b/rowers/templates/emailbase.html
new file mode 100644
index 00000000..4f457f2b
--- /dev/null
+++ b/rowers/templates/emailbase.html
@@ -0,0 +1,16 @@
+
+
+
+{% load staticfiles %}
+{% load rowerfilters %}
+
+
+
+
+ {% block body %}
+
+ {% endblock %}
+
+
+
+
diff --git a/rowers/templates/gpxemail.html b/rowers/templates/gpxemail.html
new file mode 100644
index 00000000..edb5ec7e
--- /dev/null
+++ b/rowers/templates/gpxemail.html
@@ -0,0 +1,15 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+ Dear {{ first_name }},
+
+
+ Please find attached the requested file for your workout.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/hardemail.html b/rowers/templates/hardemail.html
new file mode 100644
index 00000000..0ca5cf10
--- /dev/null
+++ b/rowers/templates/hardemail.html
@@ -0,0 +1,36 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+ Dear {{ first_name }},
+
+
+ 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:
+
+
+
+
+ http://analytics.rowsandall.com/2017/06/17/how-do-we-calculate-critical-power/
+
+
+
+ Link to the workout:
+ {{ siteurl }}/rowers/workout/{{ workoutid }}
+
+
+
+
+ To opt out of these email notifications, deselect the checkbox on your Profile
+ page under Account Information.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/otwpoweremail.html b/rowers/templates/otwpoweremail.html
new file mode 100644
index 00000000..8b90a830
--- /dev/null
+++ b/rowers/templates/otwpoweremail.html
@@ -0,0 +1,35 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ Your Rowsandall OTW calculations are ready.
+
+
+ Thank you for using rowsandall.com.
+
+
+ Rowsandall OTW calculations have not been fully implemented yet.
+
+
+ We are now running an experimental version for debugging purposes.
+
+
+ Your wind/stream corrected plot is available here:
+
+ {{ siteurl }}/rowers/workout/{{ workoutid }}/interactiveotwplot
+
+
+ Please report any bugs/inconsistencies/unexpected results
+ by reply to this email.
+
+
+
+
+
+ Best Regards, the Rowsandall Physics Department
+
+{% endblock %}
diff --git a/rowers/templates/summarymail.html b/rowers/templates/summarymail.html
new file mode 100644
index 00000000..918f8443
--- /dev/null
+++ b/rowers/templates/summarymail.html
@@ -0,0 +1,15 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+ Dear {{ first_name }},
+
+
+ Please find attached the requested summary file.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/tcxemail.html b/rowers/templates/tcxemail.html
new file mode 100644
index 00000000..edb5ec7e
--- /dev/null
+++ b/rowers/templates/tcxemail.html
@@ -0,0 +1,15 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+ Dear {{ first_name }},
+
+
+ Please find attached the requested file for your workout.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teamdropemail.html b/rowers/templates/teamdropemail.html
new file mode 100644
index 00000000..d8255b15
--- /dev/null
+++ b/rowers/templates/teamdropemail.html
@@ -0,0 +1,16 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ Unfortunately,
+ {{ managername }} has removed you from
+ the team {{ teamname }}.
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teaminviteacceptemail.html b/rowers/templates/teaminviteacceptemail.html
new file mode 100644
index 00000000..86754ee1
--- /dev/null
+++ b/rowers/templates/teaminviteacceptemail.html
@@ -0,0 +1,16 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ managername }},
+
+
+ {{ first_name }} has accepted your invitation to be
+ part of the team {{ teamname }}.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teaminviteemail.html b/rowers/templates/teaminviteemail.html
new file mode 100644
index 00000000..f0895252
--- /dev/null
+++ b/rowers/templates/teaminviteemail.html
@@ -0,0 +1,58 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ name }},
+
+
+ {{ manager }} is inviting you to join his team {{ teamname }}
+ on rowsandall.com
+
+
+ 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.
+
+
+ By accepting the invite, you are agreeing with the sharing
+ of personal data according to our privacy policy.
+
+
+ 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:
+ {{ siteurl }}/rowers/me/teams
+
+
+ You can also click the direct link:
+
+ {{ siteurl }}/rowers/me/invitation/{{ code }}
+
+
+ If you are not yet registered to rowsandall.com,
+ you can register for free at
+ {{ siteurl }}/rowers/register
+
+
+ After you set up your account, you can use the direct link:
+
+ {{ siteurl }}/rowers/me/invitation/{{ code }}
+
+
+ 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.
+
+
+ Code: {{ code }}
+
+
+ Link to manually accept your team membership:
+
+ {{ siteurl }}/rowers/me/invitation
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teaminviterejectemail.html b/rowers/templates/teaminviterejectemail.html
new file mode 100644
index 00000000..30ab689a
--- /dev/null
+++ b/rowers/templates/teaminviterejectemail.html
@@ -0,0 +1,17 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ managername }},
+
+
+ Unfortunately,
+ {{ first_name }} has rejected your invitation to be
+ part of the team {{ teamname }}.
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teamrejectemail.html b/rowers/templates/teamrejectemail.html
new file mode 100644
index 00000000..34422898
--- /dev/null
+++ b/rowers/templates/teamrejectemail.html
@@ -0,0 +1,16 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ Unfortunately,
+ {{ managername }} has rejected your request to be part
+ of the team {{ teamname }}.
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teamremoveemail.html b/rowers/templates/teamremoveemail.html
new file mode 100644
index 00000000..64c92d62
--- /dev/null
+++ b/rowers/templates/teamremoveemail.html
@@ -0,0 +1,19 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ {{ managername }} has decided to delete the team {{ teamname }}.
+
+
+ The {{ teamname }} tag has been removed from all your
+ workouts on rowsandall.com
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teamrequestemail.html b/rowers/templates/teamrequestemail.html
new file mode 100644
index 00000000..dd436837
--- /dev/null
+++ b/rowers/templates/teamrequestemail.html
@@ -0,0 +1,29 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ {{ requestor }} is requesting access to your team {{ teamname }}
+ on rowsandall.com
+
+
+ Click the direct link to accept:
+
+ {{ siteurl }}/rowers/me/request/{{ code }}
+
+
+ Click the following link to reject the request:
+
+ {{ siteurl }}/rowers/me/request/{{ id }}
+
+
+ You can find all pending requests on your team management page:
+ {{ siteurl }}/rowers/me/teams
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teamresponseemail.html b/rowers/templates/teamresponseemail.html
new file mode 100644
index 00000000..d0def71a
--- /dev/null
+++ b/rowers/templates/teamresponseemail.html
@@ -0,0 +1,26 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ name }},
+
+
+ {{ commenter_first_name }} {{ commenter_last_name }} has written
+ a new comment on workout {{ workoutname }}
+
+
+ {{ comment }}
+
+
+ You can read the comment here:
+
+
+
+ {{ siteurl }}/rowers/workout/{{ workoutid }}/comment
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/teamwelcomeemail.html b/rowers/templates/teamwelcomeemail.html
new file mode 100644
index 00000000..d255002c
--- /dev/null
+++ b/rowers/templates/teamwelcomeemail.html
@@ -0,0 +1,15 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+Dear {{ first_name }},
+
+
+ {{ managername }} has accepted your request to be part
+ of the team {{ teamname }}.
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/templates/unrecognizedemail.html b/rowers/templates/unrecognizedemail.html
new file mode 100644
index 00000000..bc6706ab
--- /dev/null
+++ b/rowers/templates/unrecognizedemail.html
@@ -0,0 +1,26 @@
+{% extends "emailbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block body %}
+ Dear {{ first_name }},
+
+
+ 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.
+
+
+
+
+
+
+ Best Regards, the Rowsandall Team
+
+{% endblock %}
diff --git a/rowers/utils.py b/rowers/utils.py
index e1588ffe..fa159aba 100644
--- a/rowers/utils.py
+++ b/rowers/utils.py
@@ -7,6 +7,7 @@ from django.conf import settings
import uuid
import datetime
+
lbstoN = 4.44822
landingpages = (
diff --git a/rowers/views.py b/rowers/views.py
index fb69cd79..9a5588a5 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -13031,7 +13031,8 @@ def plannedsession_view(request,id=0,rowerid=0,
{
'psdict': psdict,
'attrs':[
- 'name','startdate','enddate','sessiontype',
+ 'name','startdate','enddate','preferreddate',
+ 'sessiontype',
'sessionmode','criterium',
'sessionvalue','sessionunit','comment',
],
diff --git a/static/img/logoemail.png b/static/img/logoemail.png
new file mode 100644
index 00000000..aacc2e3f
Binary files /dev/null and b/static/img/logoemail.png differ
diff --git a/temp.txt b/temp.txt
deleted file mode 100644
index 5fdc2a13..00000000
--- a/temp.txt
+++ /dev/null
@@ -1,5 +0,0 @@
----
-aap: noot
-mies: jet
-jet
-...
\ No newline at end of file