Merge branch 'bheesham-feature/35-email-reminders'

This commit is contained in:
Michael Hall 2018-04-05 22:50:50 -04:00
commit a5822d4088
12 changed files with 208 additions and 12 deletions

View file

@ -0,0 +1,24 @@
# Generated by Django 2.0 on 2018-04-04 05:04
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('events', '0023_add_searchable_timezone'),
]
operations = [
migrations.AddField(
model_name='attendee',
name='last_reminded',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='team',
name='created_date',
field=models.DateField(blank=True, default=django.utils.timezone.now, null=True, verbose_name='Date Created'),
),
]

View file

@ -208,6 +208,7 @@ class Attendee(models.Model):
role = models.SmallIntegerField(_("Role"), choices=ROLES, default=NORMAL, db_index=True)
status = models.SmallIntegerField(_("Attending?"), choices=STATUSES, default=YES, db_index=True)
joined_date = models.DateTimeField(default=timezone.now)
last_reminded = models.DateTimeField(null=True, blank=True)
@property
def role_name(self):

View file

@ -13,4 +13,3 @@ class BaseTest(TestCase):
def test_harness(self):
return

View file

@ -0,0 +1,61 @@
from django.core.management.base import BaseCommand, CommandError
from django.urls import reverse
from django.core.mail import send_mail
from django.template.loader import get_template, render_to_string
from django.conf import settings
from django.contrib.sites.models import Site
from django.utils import timezone
from django.db.models import Q
from accounts.models import Account, EmailConfirmation
from events.models import Event, Attendee
import time
import urllib
import datetime
class Command(BaseCommand):
help = "Sends upcomming event notifications to attendees."
def handle(self, *args, **options):
site = Site.objects.get(id=1)
# Events that start within a day.
query = Q(status=Attendee.YES,
event__start_time__gt=timezone.now(),
event__start_time__lt=timezone.now()+datetime.timedelta(days=1))
attendees = Attendee.objects.filter(query)
for attendee in attendees:
# Skip people who don't want notificiations or have no email address.
if not attendee.user.send_notifications or not attendee.user.user.email:
continue
# Skip people who have been reminded in the last day.
if attendee.last_reminded and timezone.now() - datetime.timedelta(days=1) < attendee.last_reminded:
continue
context = {
'event': attendee.event,
}
email_subject = '[GetTogether] Upcoming event reminder'
email_body_text = render_to_string('get_together/emails/reminder.txt', context)
email_body_html = render_to_string('get_together/emails/reminder.html', context)
email_recipients = [attendee.user.user.email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail(
from_email=email_from,
html_message=email_body_html,
message=email_body_text,
recipient_list=email_recipients,
subject=email_subject,
)
attendee.last_reminded = timezone.now()
attendee.save()
time.sleep(0.1)

View file

@ -35,7 +35,10 @@ form {
<main role="main" class="container">
{% block content %}{% endblock %}
<hr>
<p>This is an automated email sent by <a href="https://gettogether.community">https://gettogether.community</a></p>
<p>
Learn more at <a href="https://github.com/GetTogetherComm/GetTogether/">https://github.com/GetTogetherComm/GetTogether/</a></p>
</main>
</html>

View file

@ -0,0 +1,3 @@
--
This is an automated email sent by https://gettogether.community
Learn more at https://github.com/GetTogetherComm/GetTogether/

View file

@ -6,8 +6,4 @@
<p>Please confirm this email address with GetTogether.Community by clicking on the link below:</p>
<p><a href="{{confirmation_url}}" class="btn btn-success">Confirm email</a></p>
<hr/>
<p>This is an automated email sent by <a href="https://gettogether.community">https://gettogether.community</a></p>
<p>Learn more at <a href="https://github.com/GetTogetherComm/GetTogether/">https://github.com/GetTogetherComm/GetTogether/</a></p>
{% endblock %}

View file

@ -1,9 +1,8 @@
{% extends 'get_together/emails/base.txt' %}
{% block content %}
== Request Email Confirmation ==
Please confirm this email address with GetTogether.Community by clicking on the link below:
Confirm email: {{confirmation_url}}
--
This is an automated email sent by https://gettogether.community
Learn more at https://github.com/GetTogetherComm/GetTogether/
{% endblock %}

View file

@ -0,0 +1,15 @@
{% extends "get_together/emails/base.html" %}
{% block content %}
<h3>Event Reminder Notification</h3>
<p>You have an event coming up!</p>
<p>
<strong>Name</strong>: {{ event.name|striptags }}<br>
<strong>Time</strong>: {{event.local_start_time}}<br>
<strong>Location</strong>: {{ event.location|striptags }}<br>
<br>
<a href="{{event.get_full_url}}" title="{{ event.name|striptags }} page.">Go to the event page.</a>
</p>
{% endblock %}

View file

@ -0,0 +1,11 @@
{% block content %}
== Event Reminder Notification ==
You have an event coming up!
Name: {{ event.name|striptags }}
Time: {{event.local_start_time}}
Location: {{ event.location|striptags }}
Event page: {{event.get_full_url}}
{% endblock %}

View file

@ -1,4 +1,4 @@
from django.test import TestCase
from .events import *
from .event_reminder import *

View file

@ -0,0 +1,84 @@
from django.test import TestCase
from django.core.management import call_command
from django.core import mail
from django.utils import timezone
from model_mommy import mommy
from model_mommy.recipe import Recipe
import datetime
from django.contrib.auth.models import User
from events.models.events import Event, Attendee
from events.models.profiles import UserProfile
class UpcommingEventReminderTest(TestCase):
def setUp(self):
super().setUp()
user = mommy.make(User, email='test@gettogether.community')
self.userProfile = mommy.make(UserProfile, user=user, send_notifications=True)
self.event = mommy.make(Event, start_time=timezone.now() + datetime.timedelta(hours=1))
def tearDown(self):
super().tearDown()
def test_reminder(self):
attendee = mommy.make(Attendee, event=self.event, user=self.userProfile, status=Attendee.YES)
call_command('send_event_reminder')
self.assertEquals(len(mail.outbox), 1)
def test_reminder_updated_last_reminded(self):
attendee = mommy.make(Attendee, event=self.event, user=self.userProfile, status=Attendee.YES)
last_reminded = attendee.last_reminded
call_command('send_event_reminder')
attendee.refresh_from_db()
self.assertNotEqual(attendee.last_reminded, last_reminded)
def test_quick_successive_reminders(self):
attendee = mommy.make(Attendee, event=self.event, user=self.userProfile, status=Attendee.YES)
call_command('send_event_reminder')
call_command('send_event_reminder')
self.assertEquals(len(mail.outbox), 1)
def test_successive_reminders_after_a_day(self):
attendee = mommy.make(Attendee, event=self.event, user=self.userProfile, status=Attendee.YES)
attendee_id = attendee.id
call_command('send_event_reminder')
self.assertEquals(len(mail.outbox), 1)
attendee.last_reminded = timezone.now() - datetime.timedelta(days=2)
attendee.save()
# This should send another email, because the last one was more than a day ago
call_command('send_event_reminder')
self.assertEquals(len(mail.outbox), 2)
def test_reminders_only_for_the_upcoming_day(self):
attendee = mommy.make(Attendee, event=self.event, user=self.userProfile, status=Attendee.YES)
self.event.start_time = timezone.now() + datetime.timedelta(days=2)
self.event.save()
call_command('send_event_reminder')
self.assertEquals(len(mail.outbox), 0)
self.event.start_time = timezone.now() + datetime.timedelta(hours=23)
self.event.save()
call_command('send_event_reminder')
self.assertEquals(len(mail.outbox), 1)