Move the newsletter.
authorRadek Czajka <rczajka@rczajka.pl>
Thu, 20 Aug 2020 09:11:33 +0000 (11:11 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Thu, 10 Sep 2020 12:15:11 +0000 (14:15 +0200)
13 files changed:
src/contact/mailing.py [deleted file]
src/newsletter/admin.py
src/newsletter/forms.py
src/newsletter/migrations/0003_newsletter.py [new file with mode: 0644]
src/newsletter/models.py
src/newsletter/subscribe.py [new file with mode: 0644]
src/newsletter/templates/newsletter/subscribe_email.html [deleted file]
src/newsletter/templates/newsletter/unsubscribe.html [deleted file]
src/newsletter/templates/newsletter/unsubscribe_email.html [deleted file]
src/newsletter/templates/newsletter/unsubscribe_form.html [deleted file]
src/newsletter/templates/newsletter/unsubscribed.html [deleted file]
src/newsletter/urls.py
src/newsletter/views.py

diff --git a/src/contact/mailing.py b/src/contact/mailing.py
deleted file mode 100644 (file)
index 4dee9c5..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-from hashlib import md5
-
-from django.conf import settings
-from mailchimp3 import MailChimp
-from mailchimp3.mailchimpclient import MailChimpError
-
-
-def subscriber_hash(email):
-    return md5(email.encode('utf-8')).hexdigest()
-
-
-def remove_from_groups(email, client):
-    group_ids = []
-    categories = client.lists.interest_categories.all(list_id=settings.MAILCHIMP_LIST_ID)['categories']
-    for category in categories:
-        groups = client.lists.interest_categories.interests.all(
-            list_id=settings.MAILCHIMP_LIST_ID, category_id=category['id'])['interests']
-        group_ids += [group['id'] for group in groups]
-    interests = {group_id: False for group_id in group_ids}
-    client.lists.members.update(
-         settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
-         data={'interests': interests})
-
-
-def subscribe(email, mailing_lists=None):
-    client = MailChimp(mc_api=settings.MAILCHIMP_API_KEY, timeout=10.0)
-    try:
-        member = client.lists.members.get(settings.MAILCHIMP_LIST_ID, subscriber_hash(email))
-    except MailChimpError:
-        pass
-    else:
-        if member['status'] != 'subscribed':
-            remove_from_groups(email, client)
-    mailing_lists = mailing_lists or [settings.MAILCHIMP_DEFAULT_GROUP]
-    interests = {
-        settings.MAILCHIMP_GROUP_IDS[mailing_list]: True
-        for mailing_list in mailing_lists
-        if mailing_list in settings.MAILCHIMP_GROUP_IDS
-    }
-    client.lists.members.create_or_update(
-        settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
-        data={
-            'email_address': email,
-            'status_if_new': 'subscribed',
-            'status': 'subscribed',
-            'interests': interests,
-        }
-    )
-
-
-def unsubscribe(email, mailing_lists=None):
-    client = MailChimp(mc_api=settings.MAILCHIMP_API_KEY, timeout=10.0)
-    try:
-        member = client.lists.members.get(settings.MAILCHIMP_LIST_ID, subscriber_hash(email))
-    except MailChimpError:
-        return
-    else:
-        if member['status'] != 'subscribed':
-            return
-    mailing_lists = mailing_lists or settings.MAILCHIMP_GROUP_IDS
-    interests = {
-        settings.MAILCHIMP_GROUP_IDS[mailing_list]: False
-        for mailing_list in mailing_lists
-        if mailing_list in settings.MAILCHIMP_GROUP_IDS
-    }
-    client.lists.members.update(
-        settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
-        data={
-            'interests': interests,
-        }
-    )
index 48134b1..7af7e0d 100644 (file)
@@ -5,8 +5,8 @@ from django.urls import path
 from django.contrib import admin
 from django.http.response import HttpResponse
 from django.views.decorators.cache import never_cache
-
-from newsletter.models import Subscription
+from modeltranslation.admin import TranslationAdmin
+from newsletter.models import Subscription, Newsletter
 
 
 class SubscriptionAdmin(admin.ModelAdmin):
@@ -28,3 +28,6 @@ class SubscriptionAdmin(admin.ModelAdmin):
 
 
 admin.site.register(Subscription, SubscriptionAdmin)
+
+
+admin.site.register(Newsletter, TranslationAdmin)
index b75b7c6..ba086e3 100644 (file)
@@ -3,16 +3,12 @@
 #
 from django.core.exceptions import ValidationError
 from django.core.validators import validate_email
-from django.forms import Form, BooleanField, MultipleChoiceField
+from django.forms import Form, BooleanField
 from django.forms.fields import EmailField
-from django.forms.widgets import CheckboxSelectMultiple
-from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _, ugettext
-
-from contact import mailing
-from newsletter.models import Subscription
-from wolnelektury.utils import send_noreply_mail
+from django.utils.translation import ugettext_lazy as _
+from newsletter.subscribe import subscribe
+from .models import Newsletter
 
 
 class NewsletterForm(Form):
@@ -21,7 +17,7 @@ class NewsletterForm(Form):
         required=False, initial=False, label=_('I want to receive Wolne Lektury\'s newsletter.'))
     mailing = False
     mailing_field = 'agree_newsletter'
-    mailing_list = 'general'
+    newsletter = None
 
     data_processing_part1 = '''\
 Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125, 00-514 Warszawa).
@@ -36,6 +32,10 @@ Więcej informacji w <a href="">polityce prywatności.</a>'''
         return mark_safe('%s %s %s' % (self.data_processing_part1, self.data_processing_part2, self.data_processing_part3))
 
     def save(self, *args, **kwargs):
+        newsletter = self.newsletter or Newsletter.objects.filter(slug='').first()
+        if not newsletter:
+            return
+
         try:
             # multiple inheritance mode
             super(NewsletterForm, self).save(*args, **kwargs)
@@ -49,11 +49,7 @@ Więcej informacji w <a href="">polityce prywatności.</a>'''
         except ValidationError:
             pass
         else:
-            # subscription, created = Subscription.objects.get_or_create(email=email, defaults={'active': False})
-            # send_noreply_mail(
-            #     ugettext('Confirm your subscription to Wolne Lektury newsletter'),
-            #     render_to_string('newsletter/subscribe_email.html', {'subscription': subscription}), [email])
-            mailing.subscribe(email, mailing_lists=[self.mailing_list])
+            subscribe(email, newsletter=newsletter)
 
 
 class SubscribeForm(NewsletterForm):
@@ -62,31 +58,7 @@ class SubscribeForm(NewsletterForm):
 
     email = EmailField(label=_('email address'))
 
-    def __init__(self, mailing_list, *args, **kwargs):
-        self.mailing_list = mailing_list
+    def __init__(self, newsletter, *args, **kwargs):
+        self.newsletter = newsletter
         super(SubscribeForm, self).__init__(*args, **kwargs)
 
-
-class UnsubscribeForm(Form):
-    email = EmailField(label=_('email address'))
-
-    def clean(self):
-        email = self.cleaned_data.get('email')
-        try:
-            subscription = Subscription.objects.get(email=email)
-        except Subscription.DoesNotExist:
-            raise ValidationError(ugettext('Email address not found.'))
-        self.cleaned_data['subscription'] = subscription
-
-    def save(self):
-        subscription = self.cleaned_data['subscription']
-        subscription.active = False
-        subscription.save()
-        mailing.unsubscribe(subscription.email)
-
-        context = {'subscription': subscription}
-        # refactor to send_noreply_mail
-        send_noreply_mail(
-            ugettext('Unsubscribe from Wolne Lektury\'s newsletter.'),
-            render_to_string('newsletter/unsubscribe_email.html', context),
-            [subscription.email], fail_silently=True)
diff --git a/src/newsletter/migrations/0003_newsletter.py b/src/newsletter/migrations/0003_newsletter.py
new file mode 100644 (file)
index 0000000..158d5d2
--- /dev/null
@@ -0,0 +1,31 @@
+# Generated by Django 2.2.10 on 2020-08-20 09:06
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('newsletter', '0002_auto_20160914_1452'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Newsletter',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('slug', models.SlugField(blank=True)),
+                ('page_title', models.CharField(blank=True, max_length=255)),
+                ('page_title_de', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_en', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_es', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_fr', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_it', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_lt', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_pl', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_ru', models.CharField(blank=True, max_length=255, null=True)),
+                ('page_title_uk', models.CharField(blank=True, max_length=255, null=True)),
+                ('phplist_id', models.IntegerField()),
+            ],
+        ),
+    ]
index 38faf34..af57d38 100644 (file)
@@ -3,16 +3,16 @@
 #
 import hashlib
 
-from django.db.models import Model, EmailField, DateTimeField, BooleanField
+from django.db import models
 from django.utils.translation import ugettext_lazy as _
 from django.conf import settings
 
 
-class Subscription(Model):
-    email = EmailField(verbose_name=_('email address'), unique=True)
-    active = BooleanField(default=True, verbose_name=_('active'))
-    created_at = DateTimeField(auto_now_add=True)
-    last_modified = DateTimeField(auto_now=True)
+class Subscription(models.Model):
+    email = models.EmailField(verbose_name=_('email address'), unique=True)
+    active = models.BooleanField(default=True, verbose_name=_('active'))
+    created_at = models.DateTimeField(auto_now_add=True)
+    last_modified = models.DateTimeField(auto_now=True)
 
     class Meta:
         verbose_name = _('subscription')
@@ -23,3 +23,9 @@ class Subscription(Model):
 
     def hashcode(self):
         return hashlib.sha224(self.email + settings.SECRET_KEY).hexdigest()[:30]
+
+
+class Newsletter(models.Model):
+    slug = models.SlugField(blank=True)
+    page_title = models.CharField(max_length=255, blank=True)
+    phplist_id = models.IntegerField()
diff --git a/src/newsletter/subscribe.py b/src/newsletter/subscribe.py
new file mode 100644 (file)
index 0000000..d7a8a27
--- /dev/null
@@ -0,0 +1,21 @@
+# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+import requests
+
+
+def subscribe(email, newsletter):
+    list_id = newsletter.phplist_id
+    data = {
+        "email": email,
+        "emailconfirm": email,
+        f"list[{list_id}]": "signup",
+        "htmlemail": 1,
+        "subscribe": "Subscribe",
+    }
+    response = requests.post(
+        'https://mailing.mdrn.pl/?p=subscribe',
+        data=data,
+    )
+    response.raise_for_status()
+
diff --git a/src/newsletter/templates/newsletter/subscribe_email.html b/src/newsletter/templates/newsletter/subscribe_email.html
deleted file mode 100644 (file)
index 2670a48..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-Dziękujemy za zapisanie się na newsletter Wolnych Lektur!
-
-W celu dokończenia rejestracji kliknij w poniższy link:
-
-https://wolnelektury.pl{% url 'confirm_subscription' subscription_id=subscription.id hashcode=subscription.hashcode %}
-
-lub skopiuj go do swojej przeglądarki.
-
-Dopóki tego nie zrobisz, nie będziesz otrzymywał od nas newsletterów.
-
-Jeżeli jednak otrzymałaś/eś tę wiadomość przez przypadek i nie chcesz otrzymywać newslettera Wolnych Lektur, zignoruj ją.
-
-Pozdrawiamy,
-zespół Wolnych Lektur
\ No newline at end of file
diff --git a/src/newsletter/templates/newsletter/unsubscribe.html b/src/newsletter/templates/newsletter/unsubscribe.html
deleted file mode 100644 (file)
index 0661821..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{% extends "base/base.html" %}
-{% load i18n %}
-
-{% block body %}
-  <h1>{{ page_title }}</h1>
-{% endblock %}
\ No newline at end of file
diff --git a/src/newsletter/templates/newsletter/unsubscribe_email.html b/src/newsletter/templates/newsletter/unsubscribe_email.html
deleted file mode 100644 (file)
index fe26a1a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Dziękujemy za dotychczasowe korzystanie z newslettera Wolnych Lektur.
-Jeśli w przyszłości zdecydujesz ponownie się na niego zapisać, wypełnij formularz
-https://wolnelektury.pl{% url "subscribe" %}, a będziemy Cię na bieżąco informować o naszych działaniach.
-
-Pozdrawiamy,
-zespół Wolnych Lektur
\ No newline at end of file
diff --git a/src/newsletter/templates/newsletter/unsubscribe_form.html b/src/newsletter/templates/newsletter/unsubscribe_form.html
deleted file mode 100644 (file)
index d7a6f70..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "base/base.html" %}
-{% load i18n %}
-{% load honeypot %}
-
-{% block body %}
-  <h1>{{ page_title }}</h1>
-  <form id="unsubscribe-form" action="" method="post" accept-charset="utf-8" class="cuteform">
-    {% csrf_token %}
-    {% render_honeypot_field %}
-    <ol>
-      {{ form.as_ul }}
-      <li><input type="submit" value="{% trans "Unsubscribe" %}"/></li>
-    </ol>
-  </form>
-{% endblock %}
diff --git a/src/newsletter/templates/newsletter/unsubscribed.html b/src/newsletter/templates/newsletter/unsubscribed.html
deleted file mode 100644 (file)
index f96c613..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "base/base.html" %}
-{% load i18n %}
-
-{% block body %}
-  <h1>{{ page_title }}</h1>
-  <p>{% trans "You have unsubscribed from Wolne Lektury newsletter. You'll receive a confirmation by email." %}</p>
-{% endblock %}
\ No newline at end of file
index 290bb87..2b0a6f1 100644 (file)
@@ -2,14 +2,15 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.urls import path
+from django.views.generic import RedirectView
 from . import views
 
 urlpatterns = [
     path('zapisz-sie/', views.subscribe_form, name='subscribe'),
-    path('zapisz-sie/konkurs/', views.subscribe_form, {"title": "Zapisz się na newsletter Konkursu", "mailing_list": "contest"}, name='subscribe-contest'),
+    path('zapisz-sie/<slug:slug>/', views.subscribe_form, name='subscribe'),
     path('zapis/', views.subscribed, name='subscribed'),
-    path('potwierdzenie/<int:subscription_id>/<slug:hashcode>/',
-        views.confirm_subscription, name='confirm_subscription'),
-    path('wypisz-sie/', views.unsubscribe_form, name='unsubscribe'),
-    path('wypisano/', views.unsubscribed, name='unsubscribed'),
+    path('wypisz-sie/', RedirectView.as_view(
+            url='https://mailing.mdrn.pl/?p=unsubscribe',
+            permanent=False,
+        ), name='unsubscribe'),
 ]
index 6c90873..3440a47 100644 (file)
@@ -1,26 +1,25 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.http import Http404
 from django.http.response import HttpResponseRedirect
 from django.shortcuts import render, get_object_or_404
 from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
 
-from newsletter.forms import UnsubscribeForm, SubscribeForm
-from newsletter.models import Subscription
+from newsletter.forms import SubscribeForm, Newsletter
 
 
-def subscribe_form(request, mailing_list='general', title=None):
+def subscribe_form(request, slug=''):
+    newsletter = get_object_or_404(Newsletter, slug=slug)
     if request.POST:
-        form = SubscribeForm(mailing_list, request.POST)
+        form = SubscribeForm(newsletter, request.POST)
         if form.is_valid():
             form.save()
             return HttpResponseRedirect(reverse('subscribed'))
     else:
-        form = SubscribeForm(mailing_list)
+        form = SubscribeForm(newsletter)
     return render(request, 'newsletter/subscribe_form.html', {
-        'page_title': title or _('Subscribe To Newsletter'),
+        'page_title': newsletter.page_title,
         'form': form,
     })
 
@@ -30,37 +29,3 @@ def subscribed(request):
         'page_title': _('Subscribed'),
     })
 
-
-def check_subscription(subscription, hashcode):
-    if hashcode != subscription.hashcode():
-        raise Http404
-
-
-def confirm_subscription(request, subscription_id, hashcode):
-    subscription = get_object_or_404(Subscription, id=subscription_id)
-    check_subscription(subscription, hashcode)
-    subscription.active = True
-    subscription.save()
-    return render(request, 'newsletter/confirm_subscription.html', {
-        'page_title': _('Subscription confirmed')
-    })
-
-
-def unsubscribe_form(request):
-    if request.POST:
-        form = UnsubscribeForm(request.POST)
-        if form.is_valid():
-            form.save()
-            return HttpResponseRedirect(reverse('unsubscribed'))
-    else:
-        form = UnsubscribeForm()
-    return render(request, 'newsletter/unsubscribe_form.html', {
-        'page_title': _('Unsubscribe'),
-        'form': form,
-    })
-
-
-def unsubscribed(request):
-    return render(request, 'newsletter/unsubscribed.html', {
-        'page_title': _('Unsubscribed'),
-    })