Skip to content

Commit

Permalink
Adds the unsubscribe feature
Browse files Browse the repository at this point in the history
  • Loading branch information
DerGut committed Apr 30, 2018
1 parent 0a78a0e commit a0a1623
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 9 deletions.
22 changes: 18 additions & 4 deletions creator/management/commands/send_mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.core import mail
from django.core.management.base import BaseCommand
from django.core.signing import Signer
from django.template.loader import render_to_string
from easy_pdf.rendering import render_to_pdf

Expand All @@ -15,6 +16,11 @@
class Command(BaseCommand):
help = 'Looks up all mail subscriptions in the DB, generates the corresponding PDF and sends off an email'

def __init__(self):
super().__init__()

self.signer = Signer()

def handle(self, *args, **options):
logger.info("Starting to send todays email subscriptions")

Expand Down Expand Up @@ -45,20 +51,28 @@ def handle(self, *args, **options):
else:
logger.info('No subscriptions found')

@classmethod
def new_email(cls, subscription, pdf):
def new_email(self, subscription, pdf):
"""Send email with pdf as attachment"""

subject = "StundenzettelCreator - Your monthly timesheet"

unsubscribe_hash = self.signer.sign(subscription.pk)

text_content = """
Hey {first_name},
here is your monthly timesheet from StundenzettelCreator.
You can always unsubscribe with this link: http://stundenzettel-creator/unsubscribe/{hash}
Bye
""".format(first_name=subscription.first_name)
html_content = render_to_string('creator/subscription_email.html', {'context': subscription})
""".format(first_name=subscription.first_name, hash=unsubscribe_hash)
html_content = render_to_string(
'creator/subscription_email.html',
context={
'subscription': subscription,
'hash': unsubscribe_hash
})

from_email = "subscription@stundenzettel-creator.xyz"
recipient_list = [subscription.email]
Expand Down
3 changes: 2 additions & 1 deletion creator/templates/creator/subscription_email.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
<body>
Hey {{ first_name }},

<p>here is your monthly timesheet from <a href="http://www.stundenzettel-creator.xyz">StundenzettelCreator</a>.</p>
<p>here is your monthly timesheet from <a href="http://www.stundenzettel-creator.xyz">StundenzettelCreator</a>.
You can always unsubscribe by visiting <a href="{% url 'unsubscribe' hash %}">unsubscribe</a></p>

<p>Bye</p>
</body>
Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions creator/templates/creator/subscription_unsubscribe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% extends "creator/base.html" %}

{% block container %}
{% if status == 'success' %}
<h3>Success</h3>
<p>You successfully unsubscribed.</p>
{% else %}
<h3>We are sorry, something went wrong.</h3>
<p>Please try visiting {% url 'unsubscribe' %}</p>
{% endif %}
{% endblock %}
5 changes: 3 additions & 2 deletions creator/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from django.conf.urls import url

from creator.views import DetailsFormView, ResultPdfView, SubscriptionFormView, SuccessView
from creator.views import DetailsFormView, ResultPdfView, SubscriptionFormView, SuccessView, UnsubscribeView

urlpatterns = [
url(r'^$', DetailsFormView.as_view(), name='index'),
url(r'^result/', ResultPdfView.as_view(), name='result'),
url(r'^subscribe/', SubscriptionFormView.as_view(), name='subscribe'),
url(r'^success/', SuccessView.as_view(), name='success')
url(r'^success/', SuccessView.as_view(), name='success'),
url(r'^unsubscribe/(?P<hash>[*]{32})/', UnsubscribeView.as_view(), name='unsubscribe')
]
32 changes: 30 additions & 2 deletions creator/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import calendar
import datetime
import logging
import random

import numpy as np
from django.shortcuts import get_object_or_404
from django.core import signing
from django.shortcuts import get_object_or_404, render
from django.views.generic import DetailView
from django.views.generic.edit import FormView
from easy_pdf.views import PDFTemplateView
Expand All @@ -12,6 +14,8 @@
from creator.forms import DetailsForm, SubscriptionForm
from creator.models import Subscription

logger = logging.getLogger(__name__)


def format_timedelta(td):
"""Format datetime.timedelta as "hh:mm"."""
Expand Down Expand Up @@ -145,7 +149,7 @@ def form_valid(self, form):


class SubscriptionFormView(FormView):
template_name = 'creator/subscribe.html'
template_name = 'creator/subscription_subscribe.html'
form_class = SubscriptionForm
success_url = '/success/'

Expand Down Expand Up @@ -174,6 +178,30 @@ def get_object(self, queryset=None):
)


def unsubscribe(request, hash):
signer = signing.Signer()
try:
id = signer.unsign(hash)
Subscription.objects.get(pk=id).delete()
context = {
'status': 'success',
}
except signing.BadSignature:
context = {
'status': 'failed',
'reason': 'This link is not working properly.'
}
logger.error('Tampering with unsubscribe link detected')
except:
context = {
'status': 'failed',
'reason': 'unknown'
}


return render(request, 'creator/subscription_unsubscribe.html', context=context)


class ResultPdfView(PDFTemplateView):
template_name = 'creator/timesheet.html'

Expand Down

0 comments on commit a0a1623

Please sign in to comment.