Skip to content

Commit

Permalink
in progress mailing list signup
Browse files Browse the repository at this point in the history
  • Loading branch information
struan committed Feb 1, 2024
1 parent 4e569a9 commit 6f4ff99
Show file tree
Hide file tree
Showing 12 changed files with 969 additions and 618 deletions.
6 changes: 6 additions & 0 deletions .env-example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@ MAPIT_URL="https://mapit.mysociety.org/"
MAPIT_API_KEY=""
GOOGLE_ANALYTICS=""
GOOGLE_SITE_VERIFICATION=""
MAILCHIMP_MYSOC_KEY=""
MAILCHIMP_MYSOC_SERVER_PREFIX=""
MAILCHIMP_MYSOC_LIST_ID=""
MAILCHIMP_TCC_KEY=""
MAILCHIMP_TCC_SERVER_PREFIX=""
MAILCHIMP_TCC_LIST_ID=""
6 changes: 6 additions & 0 deletions conf/env-example
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
SECRET_KEY="secr3t-k3y"
GOOGLE_ANALYTICS=""
GOOGLE_SITE_VERIFICATION=""
MAILCHIMP_MYSOC_KEY=""
MAILCHIMP_MYSOC_SERVER_PREFIX=""
MAILCHIMP_MYSOC_LIST_ID=""
MAILCHIMP_TCC_KEY=""
MAILCHIMP_TCC_SERVER_PREFIX=""
MAILCHIMP_TCC_LIST_ID=""
18 changes: 18 additions & 0 deletions hub/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
BooleanField,
CharField,
EmailField,
Form,
ModelForm,
modelformset_factory,
)
Expand Down Expand Up @@ -158,3 +159,20 @@ def confirm_login_allowed(self, user):
self.error_messages["inactive"],
code="inactive",
)


class MailingListSignupForm(Form):
email = EmailField(label="Email")
full_name = CharField()
mysoc_signup = BooleanField(
required=False,
label=mark_safe(
'mySociety <a href="https://www.mysociety.org/privacy/">(privacy policy)</a>'
),
)
tcc_signup = BooleanField(
required=False,
label=mark_safe(
'The Climate Coalition <a href="https://www.theclimatecoalition.org/privacy-policy">(privacy policy)</a>'
),
)
21 changes: 21 additions & 0 deletions hub/management/commands/mailchimp_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.conf import settings
from django.core.management.base import BaseCommand

import mailchimp_marketing as MailchimpMarketing
from mailchimp_marketing.api_client import ApiClientError


class Command(BaseCommand):
def handle(self, *args, **kwargs):
try:
client = MailchimpMarketing.Client()
client.set_config(
{
"api_key": settings.MAILCHIMP_MYSOC_KEY,
"server": settings.MAILCHIMP_MYSOC_SERVER_PREFIX,
}
)
response = client.ping.get()
print(response)
except ApiClientError as error:
print(error)
33 changes: 33 additions & 0 deletions hub/static/js/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ exploreApp.mount('#exploreApp')

import setUpAreaPage from './area.esm.js'

async function mailingListSignup($form) {
const response = await fetch($form.attr('action'), {
method: $form.attr('method') || 'GET',
mode: 'cors',
credentials: 'same-origin',
body: $form.serialize(),
headers: {
"Content-Type": 'application/x-www-form-urlencoded',
"Accept": 'application/json; charset=utf-8',
},
})
return response.json()
}

$(function(){
if( 'geolocation' in navigator ) {
$('.js-geolocate').removeClass('d-none');
Expand Down Expand Up @@ -95,6 +109,25 @@ $(function(){
});
}
})

$('#mailing_list_signup').on('submit', function(e){
e.preventDefault();
var $form = $(this);
mailingListSignup($form).then(function(response){
if (response['response'] == 'ok') {
$form.parent().hide()
} else {
console.log(response)
for (var k in response["errors"]) {
var id = '#' + k
console.log(id)
var el = $(id)
console.log(k, el)
el.addClass('is-invalid')
}
}
});
})
})

var makeChart = function() {
Expand Down
36 changes: 36 additions & 0 deletions hub/templates/hub/contact.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,42 @@ <h1 class="mb-4">Contact us</h1>
<p>Whether you’ve spotted an error on the site, or you have new data to contribute, or you need help managing your account, or anything else – send an email to <a href="mailto:[email protected]">[email protected]</a>, and we’ll direct your message to the right place.</p>

</div>

<div class="readable">
<form id="mailing_list_signup" method="POST" action="{% url 'mailing_list_signup' %}">
{% csrf_token %}
<h2 class="h4">Want notifications when we add new data?</h2>
<fieldset>
<legend>Let us know your email address and we’ll notify you about new data:</legend>
<div class="mb-3">
<label class="form-label" for="full_name">Name</label>
<input type="text" name="full_name" id="full_name" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="email">Email address</label>
<input type="email" name="email" id="email" class="form-control">
</div>
</fieldset>
<fieldset>
<legend>You can also, optionally, join our newsletters for more inspiration on data, democracy, and climate action:</legend>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="yes" name="mysoc_signup" id="mysoc_signup">
<label class="form-check-label" for="mysoc_signup">
mySociety
<a href="https://www.mysociety.org/privacy/">(privacy policy)</a>
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="yes" name="tcc_signup" id="tcc_signup">
<label class="form-check-label" for="tcc_signup">
The Climate Coalition
<a href="https://www.theclimatecoalition.org/privacy-policy">(privacy policy)</a>
</label>
</div>
</fieldset>
<button type="submit" class="btn btn-primary mt-4">Subscribe</button>
</form>
</div>
</div>
</div>

Expand Down
53 changes: 53 additions & 0 deletions hub/templates/hub/signed_up.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{% extends "hub/base.html" %}

{% block content %}

<div class="py-4 py-lg-5">
<div class="container">
<div class="readable">
<h1 class="mb-4">Signed up</h1>

<p>Thanks for signing up!</p>

</div>

<!--
<div class="readable">
<form method="POST" action="{% url 'mailing_list_signup' %}">
<h2 class="h4">Want notifications when we add new data?</h2>
<fieldset>
<legend>Let us know your email address and we’ll notify you about new data:</legend>
<div class="mb-3">
<label class="form-label" for="name">Name</label>
<input type="text" id="name" class="form-control">
</div>
<div class="mb-3">
<label class="form-label" for="email">Email address</label>
<input type="email" id="email" class="form-control">
</div>
</fieldset>
<fieldset>
<legend>You can also, optionally, join our newsletters for more inspiration on data, democracy, and climate action:</legend>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="check1">
<label class="form-check-label" for="check1">
mySociety
<a href="https://www.mysociety.org/privacy/">(privacy policy)</a>
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="check2">
<label class="form-check-label" for="check2">
The Climate Coalition
<a href="https://www.theclimatecoalition.org/privacy-policy">(privacy policy)</a>
</label>
</div>
</fieldset>
<button type="submit" class="btn btn-primary mt-4">Subscribe</button>
</form>
</div>
-->
</div>
</div>

{% endblock %}
79 changes: 78 additions & 1 deletion hub/views/core.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from django.conf import settings
from django.db import connection
from django.db.utils import OperationalError
from django.http import JsonResponse
from django.views.generic import TemplateView
from django.views.generic import FormView, TemplateView

import mailchimp_marketing as MailChimp
from mailchimp_marketing.api_client import ApiClientError

from hub.forms import MailingListSignupForm
from hub.mixins import TitleMixin
from hub.models import Area, DataSet

Expand Down Expand Up @@ -98,6 +103,78 @@ class ContactView(TitleMixin, TemplateView):
template_name = "hub/contact.html"


class MailChimpSignupView(TitleMixin, FormView):
form_class = MailingListSignupForm
page_title = "Signup!!!"
template_name = "hub/signed_up.html"
success_url = "/mailing-list/"

def form_invalid(self, form):
response = super().form_invalid(form)

Check warning on line 113 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L113

Added line #L113 was not covered by tests
if self.request.accepts("application/json"):
return JsonResponse({"errors": form.errors}, status=400)

Check warning on line 115 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L115

Added line #L115 was not covered by tests
else:
return response

Check warning on line 117 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L117

Added line #L117 was not covered by tests

def form_valid(self, form):
mysoc_client = MailChimp.Client()

Check warning on line 120 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L120

Added line #L120 was not covered by tests

mysoc_climate_signup = form.cleaned_data.get("mysoc_signup", False)
tcc_signup = form.cleaned_data.get("tcc_signup", False)

Check warning on line 123 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L122-L123

Added lines #L122 - L123 were not covered by tests

mysoc_client.set_config(

Check warning on line 125 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L125

Added line #L125 was not covered by tests
{
"api_key": settings.MAILCHIMP_MYSOC_KEY,
"server": settings.MAILCHIMP_MYSOC_SERVER_PREFIX,
}
)

content = {

Check warning on line 132 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L132

Added line #L132 was not covered by tests
"email_address": form.cleaned_data.get("email"),
"status": "subscribed",
}

mysoc_content = {

Check warning on line 137 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L137

Added line #L137 was not covered by tests
**content,
"interests": {settings.MAILCHIMP_MYSOC_DATA_UPDATES_INTEREST: True},
}
if mysoc_climate_signup:
mysoc_content["interests"][settings.MAILCHIMP_MYSOC_CLIMATE_INTEREST] = True
print("signed up for mysoc mailing list")

Check warning on line 143 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L142-L143

Added lines #L142 - L143 were not covered by tests

if tcc_signup:
tcc_content = content
print("signed up for TCC mailing list")

Check warning on line 147 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L146-L147

Added lines #L146 - L147 were not covered by tests

http_status = 200
response_data = {"data": content}

Check warning on line 150 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L149-L150

Added lines #L149 - L150 were not covered by tests

try:
print("posting to mysoc API", mysoc_content)

Check warning on line 153 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L152-L153

Added lines #L152 - L153 were not covered by tests
# mysoc_client.lists.batch_list_members(settings.MAILCHIMP_MYSOC_LIST_ID, {"members": mysoc_content, "update_existing": True)

if tcc_signup:
print("posting to TCC API", tcc_content)

Check warning on line 157 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L157

Added line #L157 was not covered by tests

except ApiClientError as error:
http_status = 500
response_data = {

Check warning on line 161 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L159-L161

Added lines #L159 - L161 were not covered by tests
"errors": [
{
"status": 500,
"title": "mailchimp_marketing ApiClientError",
"detail": error.text,
}
]
}

response = super().form_valid(form)

Check warning on line 171 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L171

Added line #L171 was not covered by tests
if self.request.accepts("application/json"):
return JsonResponse(response_data, status=http_status)

Check warning on line 173 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L173

Added line #L173 was not covered by tests
else:
return response

Check warning on line 175 in hub/views/core.py

View check run for this annotation

Codecov / codecov/patch

hub/views/core.py#L175

Added line #L175 was not covered by tests


class StyleView(TitleMixin, TemplateView):
page_title = "Style preview"
template_name = "hub/style.html"
Expand Down
14 changes: 14 additions & 0 deletions local_intelligence_hub/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
HIDE_DEBUG_TOOLBAR=(bool, False),
GOOGLE_ANALYTICS=(str, ""),
GOOGLE_SITE_VERIFICATION=(str, ""),
MAILCHIMP_MYSOC_KEY=(str, ""),
MAILCHIMP_MYSOC_SERVER_PREFIX=(str, ""),
MAILCHIMP_MYSOC_LIST_ID=(str, ""),
MAILCHIMP_TCC_KEY=(str, ""),
MAILCHIMP_TCC_SERVER_PREFIX=(str, ""),
MAILCHIMP_TCC_LIST_ID=(str, ""),
)
environ.Env.read_env(BASE_DIR / ".env")

Expand All @@ -40,6 +46,14 @@
GOOGLE_ANALYTICS = env("GOOGLE_ANALYTICS")
GOOGLE_SITE_VERIFICATION = env("GOOGLE_SITE_VERIFICATION")

# mailing list signup config
MAILCHIMP_MYSOC_KEY = env("MAILCHIMP_MYSOC_KEY")
MAILCHIMP_MYSOC_SERVER_PREFIX = env("MAILCHIMP_MYSOC_SERVER_PREFIX")
MAILCHIMP_MYSOC_LIST_ID = env("MAILCHIMP_MYSOC_LIST_ID")
MAILCHIMP_TCC_KEY = env("MAILCHIMP_TCC_KEY")
MAILCHIMP_TCC_SERVER_PREFIX = env("MAILCHIMP_TCC_SERVER_PREFIX")
MAILCHIMP_TCC_LIST_ID = env("MAILCHIMP_TCC_LIST_ID")

# make sure CSRF checking still works behind load balancers
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

Expand Down
3 changes: 3 additions & 0 deletions local_intelligence_hub/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
path("contact/", core.ContactView.as_view(), name="contact"),
path("location/", area.AreaSearchView.as_view(), name="area_search"),
path("style/", core.StyleView.as_view(), name="style"),
path(
"mailing-list/", core.MailChimpSignupView.as_view(), name="mailing_list_signup"
),
path("status/", core.StatusView.as_view(), name="status"),
path("me/", accounts.MyAccountView.as_view(), name="my_account"),
path("signup/", accounts.SignupView.as_view(), name="signup"),
Expand Down
Loading

0 comments on commit 6f4ff99

Please sign in to comment.