Add EmailRecord to accounts to track what emails are being sent out. Only visible to site sysadmins

This commit is contained in:
Michael Hall 2018-05-13 21:30:43 -04:00
parent dde2b2160f
commit dbbe5ec9e1
11 changed files with 204 additions and 24 deletions

View file

@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from .models import Account, Badge, BadgeGrant, EmailConfirmation from .models import Account, Badge, BadgeGrant, EmailConfirmation, EmailRecord
# Register your models here. # Register your models here.
class AccountAdmin(admin.ModelAdmin): class AccountAdmin(admin.ModelAdmin):
@ -27,3 +27,32 @@ class ConfirmationAdmin(admin.ModelAdmin):
list_display = ('email', 'user', 'key', 'expires') list_display = ('email', 'user', 'key', 'expires')
admin.site.register(EmailConfirmation, ConfirmationAdmin) admin.site.register(EmailConfirmation, ConfirmationAdmin)
class EmailAdmin(admin.ModelAdmin):
list_display = ['when', 'recipient_display', 'subject', 'sender_display', 'ok',]
list_filter = ['ok', 'when', 'sender']
readonly_fields = ['when', 'email', 'subject', 'body', 'ok']
search_fields = ['subject', 'body', 'to']
def sender_display(self, record):
if record.sender is not None:
return record.sender
else:
return 'System'
sender_display.short_description = 'From'
def recipient_display(self, record):
if record.recipient is not None:
return '%s <%s>' % (record.recipient, record.email)
else:
return record.email
recipient_display.short_description = 'To'
def has_delete_permission(self, request, obj=None):
return False
def has_add_permission(self, request):
return False
admin.site.register(EmailRecord, EmailAdmin)

View file

@ -0,0 +1,29 @@
# Generated by Django 2.0 on 2018-05-13 23:43
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('accounts', '0003_auto_20180304_1649'),
]
operations = [
migrations.CreateModel(
name='EmailRecord',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('when', models.DateTimeField(auto_now_add=True)),
('email', models.EmailField(max_length=254)),
('subject', models.CharField(max_length=128)),
('body', models.TextField(max_length=1024)),
('ok', models.BooleanField(default=True)),
('recipient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='recv_messages', to=settings.AUTH_USER_MODEL)),
('sender', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sent_messages', to=settings.AUTH_USER_MODEL)),
],
),
]

View file

@ -107,3 +107,24 @@ class BadgeGrant(models.Model):
return '%s for %s' % (self.badge.name, self.account.acctname) return '%s for %s' % (self.badge.name, self.account.acctname)
class EmailRecord(models.Model):
"""
Model to store all the outgoing emails.
"""
when = models.DateTimeField(
null=False, auto_now_add=True
)
sender = models.ForeignKey(User, related_name='sent_messages', null=True, blank=True, on_delete=models.SET_NULL)
recipient = models.ForeignKey(User, related_name='recv_messages', null=True, blank=True, on_delete=models.SET_NULL)
email = models.EmailField(
null=False, blank=False,
)
subject = models.CharField(
null=False, max_length=128,
)
body = models.TextField(
null=False, max_length=1024,
)
ok = models.BooleanField(
null=False, default=True,
)

View file

@ -6,6 +6,7 @@ from django.core.mail import send_mail
from django.template.loader import get_template, render_to_string from django.template.loader import get_template, render_to_string
from events.models import Event, EventSeries, Attendee from events.models import Event, EventSeries, Attendee
from accounts.models import EmailRecord
import time import time
import datetime import datetime
@ -34,11 +35,19 @@ def email_host_new_event(event):
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
for attendee in Attendee.objects.filter(event=event, role=Attendee.HOST, user__user__account__is_email_confirmed=True): for attendee in Attendee.objects.filter(event=event, role=Attendee.HOST, user__user__account__is_email_confirmed=True):
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
recipient_list=[attendee.user.user.email], recipient_list=[attendee.user.user.email],
subject=email_subject, subject=email_subject,
fail_silently=True, fail_silently=True,
)
EmailRecord.objects.create(
sender=None,
recipient=attendee.user.user,
email=attendee.user.user.email,
subject=email_subject,
body=email_body_text,
ok=success
) )

View file

@ -7,6 +7,7 @@ from django.contrib.sites.models import Site
from django.utils import timezone from django.utils import timezone
from events.models import Event, Attendee from events.models import Event, Attendee
from accounts.models import EmailRecord
import datetime import datetime
@ -35,8 +36,8 @@ class Command(BaseCommand):
def send_new_attendees(event, new_attendees): def send_new_attendees(event, new_attendees):
if len(new_attendees) < 1: if len(new_attendees) < 1:
return return
host_emails = [attendee.user.user.email for attendee in Attendee.objects.filter(event=event, role=Attendee.HOST) if attendee.user.user.account.is_email_confirmed] hosts = [attendee.user.user for attendee in Attendee.objects.filter(event=event, role=Attendee.HOST) if attendee.user.user.account.is_email_confirmed]
if len(host_emails) < 1: if len(hosts) < 1:
return return
context = { context = {
'event': event, 'event': event,
@ -47,13 +48,23 @@ def send_new_attendees(event, new_attendees):
email_subject = '[GetTogether] New event attendees' email_subject = '[GetTogether] New event attendees'
email_body_text = render_to_string('get_together/emails/new_event_attendees.txt', context) email_body_text = render_to_string('get_together/emails/new_event_attendees.txt', context)
email_body_html = render_to_string('get_together/emails/new_event_attendees.html', context) email_body_html = render_to_string('get_together/emails/new_event_attendees.html', context)
email_recipients = host_emails email_recipients = [host.email for host in hosts]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
recipient_list=email_recipients, recipient_list=email_recipients,
subject=email_subject, subject=email_subject,
) )
for host in hosts:
EmailRecord.objects.create(
sender=None,
recipient=host,
email=host.email,
subject=email_subject,
body=email_body_text,
ok=success
)

View file

@ -7,6 +7,7 @@ from django.contrib.sites.models import Site
from django.utils import timezone from django.utils import timezone
from events.models import Event, Member from events.models import Event, Member
from accounts.models import EmailRecord
import datetime import datetime
@ -35,8 +36,8 @@ class Command(BaseCommand):
def send_new_members(team, new_members): def send_new_members(team, new_members):
if len(new_members) < 1: if len(new_members) < 1:
return return
admin_emails = [member.user.user.email for member in Member.objects.filter(team=team, role=Member.ADMIN) if member.user.user.account.is_email_confirmed] admins = [member.user.user for member in Member.objects.filter(team=team, role=Member.ADMIN) if member.user.user.account.is_email_confirmed]
if len(admin_emails) < 1: if len(admins) < 1:
return return
context = { context = {
'team': team, 'team': team,
@ -47,13 +48,23 @@ def send_new_members(team, new_members):
email_subject = '[GetTogether] New team members' email_subject = '[GetTogether] New team members'
email_body_text = render_to_string('get_together/emails/new_team_members.txt', context) email_body_text = render_to_string('get_together/emails/new_team_members.txt', context)
email_body_html = render_to_string('get_together/emails/new_team_members.html', context) email_body_html = render_to_string('get_together/emails/new_team_members.html', context)
email_recipients = admin_emails email_recipients = [admin.email for admin in admins]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
recipient_list=email_recipients, recipient_list=email_recipients,
subject=email_subject, subject=email_subject,
) )
for admin in admins:
EmailRecord.objects.create(
sender=None,
recipient=admin,
email=admin.email,
subject=email_subject,
body=email_body_text,
ok=success
)

View file

@ -5,7 +5,7 @@ from django.template.loader import get_template, render_to_string
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from accounts.models import Account, EmailConfirmation from accounts.models import Account, EmailConfirmation, EmailRecord
import time import time
import urllib import urllib
@ -47,13 +47,23 @@ class Command(BaseCommand):
email_body_html = render_to_string('get_together/emails/confirm_email.html', context) email_body_html = render_to_string('get_together/emails/confirm_email.html', context)
email_recipients = [account.user.email] email_recipients = [account.user.email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
subject=email_subject, subject=email_subject,
message=email_body_text, message=email_body_text,
from_email=email_from, from_email=email_from,
recipient_list=email_recipients, recipient_list=email_recipients,
html_message=email_body_html html_message=email_body_html
) )
EmailRecord.objects.create(
sender=None,
recipient=account.user,
email=account.user.email,
subject=email_subject,
body=email_body_text,
ok=success
)
time.sleep(0.1) time.sleep(0.1)

View file

@ -7,7 +7,7 @@ from django.contrib.sites.models import Site
from django.utils import timezone from django.utils import timezone
from django.db.models import Q from django.db.models import Q
from accounts.models import Account, EmailConfirmation from accounts.models import EmailRecord
from events.models import Event, Attendee from events.models import Event, Attendee
import time import time
@ -47,7 +47,7 @@ class Command(BaseCommand):
email_recipients = [attendee.user.user.email] email_recipients = [attendee.user.user.email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
@ -58,4 +58,12 @@ class Command(BaseCommand):
attendee.last_reminded = timezone.now() attendee.last_reminded = timezone.now()
attendee.save() attendee.save()
EmailRecord.objects.create(
sender=None,
recipient=attendee.user.user,
email=attendee.user.user.email,
subject=email_subject,
body=email_body_text,
ok=success
)
time.sleep(0.1) time.sleep(0.1)

View file

@ -1,7 +1,7 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import logout as logout_user from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, reverse, get_object_or_404 from django.shortcuts import render, redirect, reverse, get_object_or_404
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
@ -38,6 +38,8 @@ from events.forms import (
) )
from events import location from events import location
from accounts.models import EmailRecord
import datetime import datetime
import simplejson import simplejson
@ -159,7 +161,7 @@ def invite_attendees(request, event_id):
if email_form.is_valid(): if email_form.is_valid():
to = email_form.cleaned_data['emails'] to = email_form.cleaned_data['emails']
for email in to: for email in to:
invite_attendee(email, event, request.user.profile) invite_attendee(email, event, request.user)
messages.add_message(request, messages.SUCCESS, message=_('Sent %s invites' % len(to))) messages.add_message(request, messages.SUCCESS, message=_('Sent %s invites' % len(to)))
return redirect(event.get_absolute_url()) return redirect(event.get_absolute_url())
team_form = EventInviteMemberForm() team_form = EventInviteMemberForm()
@ -175,7 +177,7 @@ def invite_attendees(request, event_id):
attendee = Attendee.objects.get(event=event, user=user) attendee = Attendee.objects.get(event=event, user=user)
except: except:
# No attendee record found, so send the invite # No attendee record found, so send the invite
invite_attendee(user.user.email, event, request.user.profile) invite_attendee(user.user, event, request.user)
messages.add_message(request, messages.SUCCESS, message=_('Sent %s invites' % len(member_choices))) messages.add_message(request, messages.SUCCESS, message=_('Sent %s invites' % len(member_choices)))
return redirect(event.get_absolute_url()) return redirect(event.get_absolute_url())
else: else:
@ -184,7 +186,7 @@ def invite_attendees(request, event_id):
attendee = Attendee.objects.get(event=event, user=member.user) attendee = Attendee.objects.get(event=event, user=member.user)
except: except:
# No attendee record found, so send the invite # No attendee record found, so send the invite
invite_attendee(member.user.user.email, event, request.user.profile) invite_attendee(member.user.user, event, request.user)
messages.add_message(request, messages.SUCCESS, message=_('Invited %s' % member.user)) messages.add_message(request, messages.SUCCESS, message=_('Invited %s' % member.user))
return redirect(event.get_absolute_url()) return redirect(event.get_absolute_url())
email_form = EventInviteEmailForm() email_form = EventInviteEmailForm()
@ -206,18 +208,23 @@ def invite_attendees(request, event_id):
def invite_attendee(email, event, sender): def invite_attendee(email, event, sender):
context = { context = {
'sender': sender, 'sender': sender.profile,
'team': event.team, 'team': event.team,
'event': event, 'event': event,
'site': Site.objects.get(id=1), 'site': Site.objects.get(id=1),
} }
recipient = None
if type(email) == User:
recipient = email
email = recipient.email
email_subject = '[GetTogether] Invite to attend %s' % event.name email_subject = '[GetTogether] Invite to attend %s' % event.name
email_body_text = render_to_string('get_together/emails/attendee_invite.txt', context) email_body_text = render_to_string('get_together/emails/attendee_invite.txt', context)
email_body_html = render_to_string('get_together/emails/attendee_invite.html', context) email_body_html = render_to_string('get_together/emails/attendee_invite.html', context)
email_recipients = [email] email_recipients = [email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
@ -225,6 +232,14 @@ def invite_attendee(email, event, sender):
subject=email_subject, subject=email_subject,
fail_silently=True, fail_silently=True,
) )
EmailRecord.objects.create(
sender=sender,
recipient=recipient,
email=email,
subject=email_subject,
body=email_body_text,
ok=success
)
def attend_event(request, event_id): def attend_event(request, event_id):
@ -278,7 +293,7 @@ def send_comment_emails(comment):
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
for attendee in comment.event.attendees.filter(user__account__is_email_confirmed=True): for attendee in comment.event.attendees.filter(user__account__is_email_confirmed=True):
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
@ -286,6 +301,14 @@ def send_comment_emails(comment):
subject=email_subject, subject=email_subject,
fail_silently=True, fail_silently=True,
) )
EmailRecord.objects.create(
sender=comment.author.user,
recipient=attendee.user.user,
email=attendee.user.user.email,
subject=email_subject,
body=email_body_text,
ok=success
)
@login_required @login_required
def add_event_photo(request, event_id): def add_event_photo(request, event_id):

View file

@ -13,6 +13,8 @@ from events.models.profiles import Team, UserProfile, Member, Category
from events.models.events import Event, Place, Attendee from events.models.events import Event, Place, Attendee
from events.forms import SendNotificationsForm, UserForm, ConfirmProfileForm from events.forms import SendNotificationsForm, UserForm, ConfirmProfileForm
from accounts.models import EmailRecord
from .utils import get_nearby_teams from .utils import get_nearby_teams
import datetime import datetime
@ -146,13 +148,21 @@ def user_send_confirmation_email(request):
email_body_html = render_to_string('get_together/emails/confirm_email.html', context, request) email_body_html = render_to_string('get_together/emails/confirm_email.html', context, request)
email_recipients = [request.user.email] email_recipients = [request.user.email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
subject=email_subject, subject=email_subject,
message=email_body_text, message=email_body_text,
from_email=email_from, from_email=email_from,
recipient_list=email_recipients, recipient_list=email_recipients,
html_message=email_body_html html_message=email_body_html
) )
EmailRecord.objects.create(
sender=request.user,
recipient=request.user,
email=request.user.email,
subject=email_subject,
body=email_body_text,
ok=success
)
return render(request, 'get_together/new_user/sent_email_confirmation.html', context) return render(request, 'get_together/new_user/sent_email_confirmation.html', context)
@login_required @login_required

View file

@ -16,6 +16,8 @@ from events.models.events import Event, CommonEvent, Place, Attendee
from events.forms import TeamForm, NewTeamForm, DeleteTeamForm, TeamContactForm, TeamInviteForm from events.forms import TeamForm, NewTeamForm, DeleteTeamForm, TeamContactForm, TeamInviteForm
from events import location from events import location
from accounts.models import EmailRecord
import datetime import datetime
import simplejson import simplejson
@ -242,7 +244,7 @@ def invite_member(email, team, sender):
email_recipients = [email] email_recipients = [email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
@ -251,6 +253,15 @@ def invite_member(email, team, sender):
fail_silently=True, fail_silently=True,
) )
EmailRecord.objects.create(
sender=sender.user,
recipient=None,
email=email,
subject=email_subject,
body=email_body_text,
ok=success
)
def contact_member(member, body, sender): def contact_member(member, body, sender):
context = { context = {
@ -265,7 +276,7 @@ def contact_member(member, body, sender):
email_recipients = [member.user.user.email] email_recipients = [member.user.user.email]
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community') email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
send_mail( success = send_mail(
from_email=email_from, from_email=email_from,
html_message=email_body_html, html_message=email_body_html,
message=email_body_text, message=email_body_text,
@ -273,6 +284,14 @@ def contact_member(member, body, sender):
subject=email_subject, subject=email_subject,
fail_silently=True, fail_silently=True,
) )
EmailRecord.objects.create(
sender=sender.user,
recipient=member.user.user,
email=member.user.user.email,
subject=email_subject,
body=email_body_text,
ok=success
)
def show_org(request, org_slug): def show_org(request, org_slug):
org = get_object_or_404(Organization, slug=org_slug) org = get_object_or_404(Organization, slug=org_slug)