Skip to content

Commit

Permalink
Added proper ratelimited sending and task support for amazon SES
Browse files Browse the repository at this point in the history
  • Loading branch information
dlareau committed Nov 13, 2020
1 parent f901512 commit 75a62aa
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 10 deletions.
2 changes: 1 addition & 1 deletion huntserver/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def save(self, *args, **kwargs):
self.full_clean()
if self.is_current_hunt:
Hunt.objects.filter(is_current_hunt=True).update(is_current_hunt=False)
if(self.resource_file.name == ""):
if(self.resource_file.name == "" and self.pk):
old_obj = Hunt.objects.get(pk=self.pk)
if(old_obj.resource_file.name != ""):
extension = old_obj.resource_file.name.split('.')[-1]
Expand Down
10 changes: 3 additions & 7 deletions huntserver/staff_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib import admin
from django.core.exceptions import ObjectDoesNotExist
from django.core.mail import EmailMessage
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
from django.shortcuts import render, redirect
Expand All @@ -15,12 +14,12 @@
from django.db.models.functions import Lower
from huey.contrib.djhuey import result
import json
from django.conf import settings
from copy import deepcopy
# from silk.profiling.profiler import silk_profile

from .models import Submission, Hunt, Team, Puzzle, Unlock, Solve, Message, Prepuzzle, Hint, Person
from .forms import SubmissionForm, UnlockForm, EmailForm, HintResponseForm, LookupForm
from .utils import send_mass_email

DT_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'

Expand Down Expand Up @@ -649,11 +648,8 @@ def emails(request):
if email_form.is_valid():
subject = email_form.cleaned_data['subject']
message = email_form.cleaned_data['message']
email_to_chunks = [email_list[x: x + 80] for x in range(0, len(email_list), 80)]
for to_chunk in email_to_chunks:
email = EmailMessage(subject, message, settings.EMAIL_FROM, [], to_chunk)
email.send()
return HttpResponseRedirect('')
task_id = send_mass_email(email_list, subject, message)
return HttpResponse(task_id.id)
else:
email_form = EmailForm()
context = {'email_list': (', ').join(email_list), 'email_form': email_form}
Expand Down
73 changes: 72 additions & 1 deletion huntserver/templates/email.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,83 @@
height: 300px;
}
</style>

<script type="text/javascript">
$(function() {
$('.download-btn').on('click', function(e) {
e.stopPropagation();
})

$(".emailForm").submit(function(e) {
e.preventDefault();

var form = $(this);
var url = form.attr('action');

$.ajax({
type: "POST",
url: url,
data: form.serialize(),
success: function(task_id) {
$('#emailResponse').html("Sending Emails (This can take up to 4 minutes) ");
$('#myModal').modal();
$(".emailForm").find("input[type=text], textarea").val("");
var num_requests = 0;
var checkInterval = setInterval(function(){
$.ajax({
type: "GET",
url: "/staff/control/",
data: {action: "check_task", task_id: task_id},
success: function(result) {
num_requests += 1;
if(num_requests > 200) {
$('#emailResponse').append("<br>Request timed out");
clearInterval(checkInterval);
return;
}
var result = JSON.parse(result);
if(result['have_result']) {
$('#emailResponse').html(result['result_text']);
clearInterval(checkInterval);
} else {
$('#emailResponse').append(".");
}
},
error: function(result) {
$('#emailResponse').append(" 500 Server Error<br>Please report this issue.");
clearInterval(checkInterval);
}
});
}, 500);
}
});
});

});
</script>
{% endblock includes %}

{% block content %}
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Email Status</h4>
</div>
<div class="modal-body">
<div id="emailResponse" style="white-space: pre;"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

<h1>Email</h1>
<h3> Send email to all hunt competitors: </h3>
<form method="POST" action="/staff/emails/">
<form method="POST" class="emailForm" action="/staff/emails/">
{% csrf_token %}
{{ email_form|crispy }}
<div class="submit-row">
Expand Down
18 changes: 17 additions & 1 deletion huntserver/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from django.db.models import F
from django.utils import timezone
from huey import crontab
from huey.contrib.djhuey import db_periodic_task
from huey.contrib.djhuey import db_periodic_task, db_task
from django.core.cache import cache
from django.core.mail import EmailMessage, get_connection
import time

from .models import Hunt, HintUnlockPlan

Expand Down Expand Up @@ -91,3 +93,17 @@ def update_time_items():
playtesters = [t for t in playtesters if t.playtest_happening]
if(len(playtesters) > 0):
check_puzzles(hunt, new_points, playtesters, True)


@db_task()
def send_mass_email(email_list, subject, message):
result = ""
email_to_chunks = [email_list[x: x + 10] for x in range(0, len(email_list), 10)]
with get_connection() as conn:
for to_chunk in email_to_chunks:
email = EmailMessage(subject, message, settings.EMAIL_FROM, [], to_chunk,
connection=conn)
email.send()
result += "Emailed: " + ", ".join(to_chunk) + "\n"
time.sleep(1)
return result

0 comments on commit 75a62aa

Please sign in to comment.