From 59e53d8bf2e2cac6affc2ea67331ca068b05b870 Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Thu, 23 Jun 2016 18:20:15 +0200 Subject: [PATCH] unsubscribe link (#10795) --- corbo/models.py | 16 +++++++++++--- corbo/static/css/corbo.css | 17 +++++++++++++++ corbo/templates/corbo/announce.html | 9 ++++++++ .../corbo/subscription_confirm_delete.html | 18 ++++++++++++++++ corbo/templates/corbo/unsubscription.html | 13 +++++++++++ corbo/templates/corbo/unsubscription_done.html | 10 +++++++++ corbo/urls.py | 8 +++++-- corbo/views.py | 25 ++++++++++++++++++++++ 8 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 corbo/templates/corbo/announce.html create mode 100644 corbo/templates/corbo/subscription_confirm_delete.html create mode 100644 corbo/templates/corbo/unsubscription.html create mode 100644 corbo/templates/corbo/unsubscription_done.html diff --git a/corbo/models.py b/corbo/models.py index 7edee72..4e2cbca 100644 --- a/corbo/models.py +++ b/corbo/models.py @@ -9,6 +9,9 @@ from django.conf import settings from django.db import models from django.core.files.storage import DefaultStorage from django.utils.translation import ugettext_lazy as _ +from django.core import signing +from django.template import loader, Context +from django.core.urlresolvers import reverse from ckeditor.fields import RichTextField @@ -75,9 +78,8 @@ class Broadcast(models.Model): subscriptions = self.announce.category.subscription_set.all() total_sent = 0 handler = HTML2Text() - m = Message(html=self.announce.text, subject=self.announce.title, - text=handler.handle(self.announce.text), - mail_from=settings.DEFAULT_FROM_EMAIL) + template = loader.get_template('corbo/announce.html') + m = Message(subject=self.announce.title, mail_from=settings.DEFAULT_FROM_EMAIL) html_tree = HTMLTree(self.announce.text) storage = DefaultStorage() for img in html_tree.xpath('//img/@src'): @@ -89,6 +91,14 @@ class Broadcast(models.Model): for s in subscriptions: if not s.identifier: continue + unsubscribe_token = signing.dumps({'category': self.announce.category.pk, + 'identifier': s.identifier}) + unsubscribe_link = reverse('unsubscribe', kwargs={'unsubscription_token': unsubscribe_token}) + message = template.render(Context({'unsubscribe_link': unsubscribe_link, + 'content': self.announce.text})) + m.html = message + m.text=handler.handle(message) + result = m.send(to=s.identifier) if result.status_code == 250: total_sent += 1 diff --git a/corbo/static/css/corbo.css b/corbo/static/css/corbo.css index 1dad7dd..d3406f5 100644 --- a/corbo/static/css/corbo.css +++ b/corbo/static/css/corbo.css @@ -280,4 +280,21 @@ form ul li label { #id_transport_channel li, #id_transport_channel label { display: inline; +} + +.content { + width: 50%; + margin: auto; +} + +.unsubscription { + background: #e6db74; + border: 1px solid #aaa; + padding: 5px; +} + +.info { + background: #a6e22e; + border: 1px solid #aaa; + padding: 5px; } \ No newline at end of file diff --git a/corbo/templates/corbo/announce.html b/corbo/templates/corbo/announce.html new file mode 100644 index 0000000..39592e4 --- /dev/null +++ b/corbo/templates/corbo/announce.html @@ -0,0 +1,9 @@ +{% load i18n %} +
+ {{ content|safe }} +
+ diff --git a/corbo/templates/corbo/subscription_confirm_delete.html b/corbo/templates/corbo/subscription_confirm_delete.html new file mode 100644 index 0000000..3daab21 --- /dev/null +++ b/corbo/templates/corbo/subscription_confirm_delete.html @@ -0,0 +1,18 @@ +{% extends 'corbo/unsubscription.html' %} +{% load i18n %} + +{% block title %}{% blocktrans with object.category as category %} +Unsubscription from {{ category }} +{% endblocktrans %}{% endblock %} + +{% block content %} +
+{% blocktrans with object.category as category %} +Are you sure you want to unsubscribe from "{{ category }}"? +{% endblocktrans %} +
+ {% csrf_token %} + +
+
+{% endblock %} diff --git a/corbo/templates/corbo/unsubscription.html b/corbo/templates/corbo/unsubscription.html new file mode 100644 index 0000000..d3c8971 --- /dev/null +++ b/corbo/templates/corbo/unsubscription.html @@ -0,0 +1,13 @@ +{% load static %} + + + {% block title %}{% endblock %} + + + +
+ {% block content %} + {% endblock %} +
+ + diff --git a/corbo/templates/corbo/unsubscription_done.html b/corbo/templates/corbo/unsubscription_done.html new file mode 100644 index 0000000..7450dea --- /dev/null +++ b/corbo/templates/corbo/unsubscription_done.html @@ -0,0 +1,10 @@ +{% extends 'corbo/unsubscription.html' %} +{% load i18n %} + +{% block title %} +{% trans 'Successfully unsubscription' %} +{% endblock %} + +{% block content %} +
{% trans 'You were sucessfully unsubcribed.' %}
+{% endblock %} diff --git a/corbo/urls.py b/corbo/urls.py index f8b074d..c52dfd4 100644 --- a/corbo/urls.py +++ b/corbo/urls.py @@ -5,7 +5,7 @@ from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib import admin from .urls_utils import decorated_includes, manager_required -from .views import homepage, atom +from .views import homepage, atom, unsubscribe, unsubscription_done from manage_urls import urlpatterns as manage_urls from api_urls import urlpatterns as api_urls @@ -17,7 +17,11 @@ urlpatterns = patterns('', include(manage_urls))), url(r'^ckeditor/', include('ckeditor.urls')), url(r'^admin/', include(admin.site.urls)), - url(r'^api/', include(api_urls)) + url(r'^api/', include(api_urls)), + url(r'^unsubscribe/done/$', unsubscription_done, + name='unsubscription_done'), + url(r'^unsubscribe/(?P[\w:-]+)$', unsubscribe, + name='unsubscribe'), ) if 'mellon' in settings.INSTALLED_APPS: diff --git a/corbo/views.py b/corbo/views.py index 272e0ee..27335bf 100644 --- a/corbo/views.py +++ b/corbo/views.py @@ -1,12 +1,14 @@ from datetime import datetime from django.conf import settings +from django.core import signing from django.core.urlresolvers import reverse from django.views.generic import CreateView, UpdateView, DeleteView, \ ListView, TemplateView from django.contrib.syndication.views import Feed from django.utils.feedgenerator import Atom1Feed from django.utils.http import urlencode +from django.http import Http404 import models from .forms import AnnounceForm, CategoryForm @@ -79,6 +81,29 @@ class CategoryDeleteView(DeleteView): delete_category = CategoryDeleteView.as_view() +class UnsubscribeView(DeleteView): + model = models.Subscription + + def get_object(self, queryset=None): + data = signing.loads(self.kwargs['unsubscription_token']) + try: + return models.Subscription.objects.get(category__pk=data['category'], + identifier=data['identifier']) + except models.Subscription.DoesNotExist: + raise Http404 + + def get_success_url(self): + return reverse('unsubscription_done') + +unsubscribe = UnsubscribeView.as_view() + + +class UnsubscriptionDoneView(TemplateView): + template_name='corbo/unsubscription_done.html' + +unsubscription_done = UnsubscriptionDoneView.as_view() + + class ManageView(ListView): paginate_by = settings.ANNOUNCES_PER_PAGE template_name = 'corbo/manage.html' -- 2.8.1