From 3cd05e9660ec3b05cd13ffbe8a3878fc42321fc9 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 20 Mar 2018 09:43:26 +0100 Subject: [PATCH 1/7] mail processing confirmation uses template --- rowers/mailprocessing.py | 30 ++++++++++------------ rowers/management/commands/processemail.py | 19 ++++++++------ rowers/templates/confirmemail.html | 18 +++++++++++++ 3 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 rowers/templates/confirmemail.html diff --git a/rowers/mailprocessing.py b/rowers/mailprocessing.py index da8073fc..08c727fc 100644 --- a/rowers/mailprocessing.py +++ b/rowers/mailprocessing.py @@ -33,25 +33,23 @@ queuelow = django_rq.get_queue('low') queuehigh = django_rq.get_queue('default') # Sends a confirmation with a link to the workout - +from rowers.emails import send_template_email def send_confirm(user, name, link, options): - """ Send confirmation email to user when email has been processed """ + d = { + 'first_name':user.first_name, + 'name':name, + 'link':link, + } + fullemail = user.email - subject = 'Workout added: ' + name - message = 'Dear ' + user.first_name + ',\n\n' - message += "Your workout has been added to Rowsandall.com.\n" - message += "Link to workout: " + link + "\n\n" - message += "Best Regards, the Rowsandall Team" - - if options: - message += "\n\n" + str(options) - - email = EmailMessage(subject, message, - 'Rowsandall ', - [fullemail]) - - res = email.send() + subject = 'New Workout Added: '+name + + res = send_template_email('Rowsandall ', + [fullemail], + subject,'confirmemail.html', + d + ) return 1 diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py index 80540061..35b175d2 100644 --- a/rowers/management/commands/processemail.py +++ b/rowers/management/commands/processemail.py @@ -83,8 +83,12 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False): plottype, title, imagename=imagename ) + email_sent = send_confirm( + rower.user, title, link, + uploadoptions + ) try: - if workoutid and not testing: + if workoutid: email_sent = send_confirm( rower.user, title, link, uploadoptions @@ -92,13 +96,12 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False): time.sleep(10) except: try: - if not testing: - time.sleep(10) - if workoutid: - email_sent = send_confirm( - rower.user, title, link, - uploadoptions - ) + time.sleep(10) + if workoutid: + email_sent = send_confirm( + rower.user, title, link, + uploadoptions + ) except: pass diff --git a/rowers/templates/confirmemail.html b/rowers/templates/confirmemail.html new file mode 100644 index 00000000..0fd847e0 --- /dev/null +++ b/rowers/templates/confirmemail.html @@ -0,0 +1,18 @@ +{% extends "emailbase.html" %} + +{% block body %} +

Dear {{ first_name }},

+ +

+ Your workout has been added to Rowsandall.com. +

+ +

+ Link to workout: {{ link }} +

+ + +

+ Best Regards, the Rowsandall Team +

+{% endblock %} From 04aaeea5db0cec6a64a603b847fb7a5cbb4be241 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 20 Mar 2018 10:00:11 +0100 Subject: [PATCH 2/7] changes email processing --- rowers/management/commands/processemail.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py index 35b175d2..9b166bc1 100644 --- a/rowers/management/commands/processemail.py +++ b/rowers/management/commands/processemail.py @@ -83,10 +83,6 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False): plottype, title, imagename=imagename ) - email_sent = send_confirm( - rower.user, title, link, - uploadoptions - ) try: if workoutid: email_sent = send_confirm( From 639473e2f8506419e2640189adeb2c40f2985140 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 20 Mar 2018 18:44:33 +0100 Subject: [PATCH 3/7] registration email from template --- rowers/stravastuff.py | 5 ++- rowers/templates/registeremail.html | 55 +++++++++++++++++++++++++++++ rowers/views.py | 24 +++++-------- 3 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 rowers/templates/registeremail.html diff --git a/rowers/stravastuff.py b/rowers/stravastuff.py index 605f796f..c14e6817 100644 --- a/rowers/stravastuff.py +++ b/rowers/stravastuff.py @@ -303,7 +303,10 @@ def handle_stravaexport(f2,workoutname,stravatoken,description='', # w = Workout.objects.get(id=workoutid) client = stravalib.Client(access_token=stravatoken) - act = client.upload_activity(f2,'tcx.gz',name=workoutname) + try: + act = client.upload_activity(f2,'tcx.gz',name=workoutname) + except: + return {0,'Strava upload failed'} try: res = act.wait(poll_interval=5.0,timeout=30) message = 'Workout successfully synchronized to Strava' diff --git a/rowers/templates/registeremail.html b/rowers/templates/registeremail.html new file mode 100644 index 00000000..b9ac171c --- /dev/null +++ b/rowers/templates/registeremail.html @@ -0,0 +1,55 @@ +{% extends "emailbase.html" %} + +{% block body %} +

Dear {{ first_name }},

+ +

+ Thank you for registering on rowsandall.com. + You can now login using the credentials you provided. + The first thing you should do is go to the + Settings page + and make yourself familiar with the various options + available to personalize your experience on the website. + To get there, use the link in the email or click the button + with your first name on it in the upper right corner of the opening page. +

+ +

+ As a minimum to get you started, enter your data in the + Heart Rate Zones and Power Zones sections and your + Functional Threshold Power. + Then check your Account Information to make sure it is + accurate and reflects your preferences. +

+ +

+ For additional details on these settings and + the buttons at the bottom of the page, read + the settings tutorial at + http://analytics.rowsandall.com/2017/11/02/rowsandall-settings-page-tutorial/. +

+ +

+ Also check out our instructional videos at + http://rowsandall.com/rowers/videos +

+ +

+ This website is a labor of love "by rowers, for rowers". + If you find it to be useful, please help us cover + our hosting costs and gain access to additional functionality + by signing on as a Pro member: + https://rowsandall.com/rowers/promembership +

+ +

+ Oh, one more thing. The site is currently in beta and is + developing fast. Bear with us. Don't hesitate to + contact me at info@rowsandall.com if anything is broken + or doesn't seem to work as advertised. +

+ +

+ Best Regards, the Rowsandall Team +

+{% endblock %} diff --git a/rowers/views.py b/rowers/views.py index 9a5588a5..c75f965f 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -141,6 +141,8 @@ import pandas as pd import numpy as np import matplotlib.pyplot as plt +from rowers.emails import send_template_email + from pytz import timezone as tz,utc import dateutil import mpld3 @@ -954,23 +956,13 @@ def rower_register_view(request): # Create and send email fullemail = first_name + " " + last_name + " " + "<" + email + ">" subject = "Thank you for registering on rowsandall.com" - message = """ -Thank you for registering on rowsandall.com. You can now login using the credentials you provided. The first thing you should do is go to the Settings page and make yourself familiar with the various options available to personalize your experience on the website. To get there, click the button with your first name on it in the upper right corner of the opening page. + from_address = 'Sander Roosendaal ' -As a minimum to get you started, enter your data in the Heart Rate Zones and Power Zones sections and your Functional Threshold Power. Then check your Account Information to make sure it is accurate and reflects your preferences. - -For additional details on these settings and the buttons at the bottom of the page, read the settings tutorial at http://analytics.rowsandall.com/2017/11/02/rowsandall-settings-page-tutorial/. - -Also check out our instructional videos at http://rowsandall.com/rowers/videos. - -This website is a labor of love "by rowers, for rowers". If you find it to be useful, please help us cover our hosting costs and gain access to additional functionality by signing on as a Pro member: https://rowsandall.com/rowers/promembership - -Oh, one more thing. The site is currently in beta and is developing fast. Bear with us. Don't hesitate to contact me at info@rowsandall.com if anything is broken or doesn't seem to work as advertised. -""" - - send_mail(subject, message, - 'Sander Roosendaal ', - [fullemail]) + d = {'first_name':theuser.first_name} + + send_template_email(from_address,[fullemail], + subject,'registeremail.html',d) + subject2 = "New User" message2 = "New user registered.\n" From 5f5e873fbdd968f06b9477efd2ee41e38f50f2e2 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 23 Mar 2018 08:47:05 +0100 Subject: [PATCH 4/7] activate GDPR --- rowsandall_app/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index 05a52223..9bfc9d1e 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -94,7 +94,7 @@ MIDDLEWARE_CLASSES = [ 'async_messages.middleware.AsyncMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'tz_detect.middleware.TimezoneMiddleware', -# 'rowers.middleware.GDPRMiddleWare', + 'rowers.middleware.GDPRMiddleWare', 'rowers.middleware.PowerTimeFitnessMetricMiddleWare', ] From a72863deec0356a558ce2c0c107cf34a4434a78a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 23 Mar 2018 13:36:12 +0100 Subject: [PATCH 5/7] changes in tests to accomodate rower has opted in to gdpr --- rowers/tests.py | 52 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/rowers/tests.py b/rowers/tests.py index ce4ca872..b081e398 100644 --- a/rowers/tests.py +++ b/rowers/tests.py @@ -10,6 +10,7 @@ import rowers.interactiveplots as iplots import datetime from rowingdata import rowingdata as rdata from rowingdata import rower as rrower +from django.utils import timezone from rowers.rows import handle_uploaded_file from django.core.files.uploadedfile import SimpleUploadedFile from time import strftime,strptime,mktime,time,daylight @@ -68,7 +69,9 @@ class C2Objects(DjangoTestCase): u.first_name = 'John' u.last_name = 'Sander' u.save() - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) res = add_workout_from_strokedata(u,1,data,strokedata,source='c2') @@ -91,7 +94,10 @@ class C2Objects(DjangoTestCase): u.first_name = 'John' u.last_name = 'Sander' u.save() - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) + res = add_workout_from_strokedata(u,1,data,strokedata,source='c2') @@ -168,7 +174,10 @@ class StravaObjects(DjangoTestCase): u.first_name = 'John' u.last_name = 'Sander' u.save() - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) + res = add_workout_from_strokedata(u,1,workoutsummary,strokedata, source='strava') @@ -244,7 +253,9 @@ class StravaObjects(DjangoTestCase): u.first_name = 'John' u.last_name = 'Sander' u.save() - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) res = add_workout_from_strokedata(u,1,workoutsummary,strokedata, source='strava') @@ -261,7 +272,10 @@ class STObjects(DjangoTestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) + res = add_workout_from_stdata(u,1,data) @@ -274,7 +288,11 @@ class STObjects(DjangoTestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u) + + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) + res = add_workout_from_stdata(u,1,data) @@ -329,7 +347,10 @@ class EmailTests(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts') workoutsbox.save() @@ -367,7 +388,9 @@ class WorkoutTests(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) nu = datetime.datetime.now() w = Workout.objects.create(name='testworkout',workouttype='On-water', user=r,date=nu.strftime('%Y-%m-%d'), @@ -376,7 +399,10 @@ class WorkoutTests(TestCase): def test_checkworkoutuser(self): u = User.objects.get(username='john') - r = Rower.objects.get(user=u) + + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) w = Workout.objects.get(user=r) self.assertEqual(checkworkoutuser(u,w),True) @@ -387,7 +413,9 @@ class C2Tests(TestCase): self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=u) + self.r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) self.nu = datetime.datetime.now() self.w = Workout.objects.create(name='testworkout',workouttype='On-water', user=r,date=nu.strftime('%Y-%m-%d'), @@ -405,7 +433,9 @@ class DataTest(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u) + r = Rower.objects.create(user=u,gdproptin=True, + gdproptindate=timezone.today() + ) self.nu = datetime.datetime.now() From 965d44cd37ec86ee5040356d3a99afe795c8090b Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 23 Mar 2018 13:45:05 +0100 Subject: [PATCH 6/7] further tests debug --- rowers/tests.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/rowers/tests.py b/rowers/tests.py index b081e398..55112808 100644 --- a/rowers/tests.py +++ b/rowers/tests.py @@ -70,7 +70,7 @@ class C2Objects(DjangoTestCase): u.last_name = 'Sander' u.save() r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) res = add_workout_from_strokedata(u,1,data,strokedata,source='c2') @@ -95,7 +95,7 @@ class C2Objects(DjangoTestCase): u.last_name = 'Sander' u.save() r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) @@ -175,7 +175,7 @@ class StravaObjects(DjangoTestCase): u.last_name = 'Sander' u.save() r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) @@ -254,7 +254,7 @@ class StravaObjects(DjangoTestCase): u.last_name = 'Sander' u.save() r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) res = add_workout_from_strokedata(u,1,workoutsummary,strokedata, @@ -273,7 +273,7 @@ class STObjects(DjangoTestCase): 'sander@ds.ds', 'koeinsloot') r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) @@ -290,7 +290,7 @@ class STObjects(DjangoTestCase): 'koeinsloot') r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) @@ -348,7 +348,7 @@ class EmailTests(TestCase): 'sander@ds.ds', 'koeinsloot') r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) nu = datetime.datetime.now() @@ -389,7 +389,7 @@ class WorkoutTests(TestCase): 'sander@ds.ds', 'koeinsloot') r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) nu = datetime.datetime.now() w = Workout.objects.create(name='testworkout',workouttype='On-water', @@ -401,7 +401,7 @@ class WorkoutTests(TestCase): u = User.objects.get(username='john') r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) w = Workout.objects.get(user=r) @@ -413,8 +413,8 @@ class C2Tests(TestCase): self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + self.r = Rower.objects.create(user=self.u,gdproptin=True, + gdproptindate=timezone.now() ) self.nu = datetime.datetime.now() self.w = Workout.objects.create(name='testworkout',workouttype='On-water', @@ -434,7 +434,7 @@ class DataTest(TestCase): 'sander@ds.ds', 'koeinsloot') r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.today() + gdproptindate=timezone.now() ) self.nu = datetime.datetime.now() @@ -616,7 +616,9 @@ class ViewTest(TestCase): self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=self.u) + self.r = Rower.objects.create(user=self.u,gdproptin=True, + gdproptindate=timezone.now() + ) self.nu = datetime.datetime.now() def test_upload_view_notloggedin(self): From abf413b3062ed103752d8faf817d44f8358e2166 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 23 Mar 2018 14:15:21 +0100 Subject: [PATCH 7/7] further tests.py refinement --- rowers/tests.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/rowers/tests.py b/rowers/tests.py index 55112808..0e6df0f0 100644 --- a/rowers/tests.py +++ b/rowers/tests.py @@ -385,27 +385,21 @@ class EmailTests(TestCase): class WorkoutTests(TestCase): def setUp(self): redis_connection.publish('tasks','KILL') - u = User.objects.create_user('john', + self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True, gdproptindate=timezone.now() ) nu = datetime.datetime.now() - w = Workout.objects.create(name='testworkout',workouttype='On-water', - user=r,date=nu.strftime('%Y-%m-%d'), + self.w = Workout.objects.create(name='testworkout', + workouttype='On-water', + user=self.r,date=nu.strftime('%Y-%m-%d'), starttime=nu.strftime('%H:%M:%S'), duration="0:55:00",distance=8000) def test_checkworkoutuser(self): - u = User.objects.get(username='john') - - r = Rower.objects.create(user=u,gdproptin=True, - gdproptindate=timezone.now() - ) - w = Workout.objects.get(user=r) - - self.assertEqual(checkworkoutuser(u,w),True) + self.assertEqual(checkworkoutuser(self.u,self.w),True) class C2Tests(TestCase): def setUp(self):