Skip to content

Commit 4651b3b

Browse files
authored
Merge pull request #933 from p2pu/2021-website-refresh
2021 website refresh
2 parents 86e3123 + e410bdc commit 4651b3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2543
-1497
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v2
14+
with:
15+
submodules: true
1416
- name: Build docker image
1517
run: docker build -t p2pu/learning-circles .
1618
- name: start postgres container

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "p2pu-theme"]
2+
path = p2pu-theme
3+
url = https://github.com/p2pu/p2pu-theme.git

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
FROM node:lts-slim AS frontend
22
WORKDIR /opt/app/
33
COPY package.json /opt/app/
4+
COPY p2pu-theme/ /opt/app/p2pu-theme/
45
RUN npm install --quiet --production
56
COPY . /opt/app/
67
RUN npm run build

contact/__init__.py

Whitespace-only changes.

contact/tasks.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from django.conf import settings
2+
from django.core.mail import EmailMultiAlternatives
3+
4+
from celery import shared_task
5+
6+
from studygroups.email_helper import render_html_with_css
7+
from studygroups.utils import html_body_to_text
8+
from studygroups.utils import render_to_string_ctx
9+
10+
11+
@shared_task
12+
def send_contact_form_inquiry(email, name, content, source, organization=None):
13+
context = {
14+
"email": email,
15+
"name": name,
16+
"content": content,
17+
"source": source,
18+
"organization": organization,
19+
}
20+
21+
subject_template = 'contact/contact_email-subject.txt'
22+
html_email_template = 'contact/contact_email.html'
23+
subject = render_to_string_ctx(subject_template, context).strip(' \n')
24+
html_body = render_html_with_css(html_email_template, context)
25+
text_body = html_body_to_text(html_body)
26+
27+
to = [ settings.TEAM_EMAIL ]
28+
email = EmailMultiAlternatives(
29+
subject,
30+
text_body,
31+
settings.DEFAULT_FROM_EMAIL,
32+
to,
33+
)
34+
email.attach_alternative(html_body, 'text/html')
35+
email.send()

contact/urls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.conf.urls import url
2+
3+
from contact import views
4+
5+
urlpatterns = [
6+
url(r'^contact/$', views.ContactAPIView.as_view(), name='api_contact_form')
7+
]

contact/views.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from rest_framework import serializers
2+
from rest_framework.views import APIView
3+
from rest_framework.response import Response
4+
from django import http
5+
6+
from .tasks import send_contact_form_inquiry
7+
8+
9+
# Serializers define the API representation.
10+
class ContactSerializer(serializers.Serializer):
11+
email = serializers.EmailField()
12+
name = serializers.CharField(max_length=255)
13+
content = serializers.CharField()
14+
source = serializers.CharField(max_length=255)
15+
organization = serializers.CharField(max_length=255, required=False)
16+
17+
def create(self, validated_data):
18+
return validated_data
19+
20+
21+
class ContactAPIView(APIView):
22+
authentication_classes = []
23+
permission_classes = []
24+
25+
def post(self, request, *args, **kwargs):
26+
serializer = ContactSerializer(data=request.data, context={'request': request})
27+
serializer.is_valid(raise_exception=True)
28+
# call async task to send email
29+
send_contact_form_inquiry.delay(**serializer.data)
30+
31+
if request.GET.get('next') and not request.is_ajax():
32+
# TODO should this be validated?
33+
return http.HttpResponseRedirect(request.GET.get('next'))
34+
35+
data = {"status": "sent"}
36+
return Response(data)

custom_registration/forms.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
from django.forms import ValidationError
77
from django.contrib.auth import password_validation
88
from django.contrib.auth.forms import UserCreationForm
9+
from django.utils.safestring import mark_safe
10+
911
from studygroups.models import Profile
1012

1113

1214
class SignupForm(UserCreationForm):
13-
communication_opt_in = forms.BooleanField(required=False, initial=False, label=_('P2PU can contact me.'), help_text=_('Joining the community comes with an expectation that you would like to learn about upcoming events, new features, and updates from around the world. If you do not want to receive any of these messages, uncheck this box.'))
14-
interested_in_learning = forms.CharField(required=False, label=_('What are you interested in learning?'))
15+
communication_opt_in = forms.BooleanField(required=False, initial=False, label=_('P2PU can contact me'), help_text=_('Join our mailing list to learn about upcoming events, new courses, and news from the community. (Approximately six emails/year)'))
16+
17+
consent_opt_in = forms.BooleanField(required=True, initial=False, label=mark_safe(_('I consent to P2PU storing my data and accept the <a href="https://www.p2pu.org/en/terms/">terms of service</a>')), help_text=_('P2PU values your privacy and will never sell your data.'))
1518

1619
def __init__(self, *args, **kwargs):
1720
super(SignupForm, self).__init__(*args, **kwargs)
@@ -28,7 +31,7 @@ def clean(self):
2831

2932
class Meta:
3033
model = User
31-
fields = ['email', 'first_name', 'last_name', 'password1', 'password2', 'interested_in_learning', 'communication_opt_in']
34+
fields = ['first_name', 'last_name', 'email', 'password1', 'password2', 'communication_opt_in', 'consent_opt_in']
3235

3336

3437
class CustomPasswordResetForm(PasswordResetForm):

custom_registration/models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
from django.contrib.auth.models import User
22
from django.contrib.auth.tokens import PasswordResetTokenGenerator
3-
from django.utils import six
43
from django.utils import timezone
54
from django.utils.http import urlsafe_base64_encode
65
from django.utils.encoding import force_bytes
76
from django.conf import settings
7+
from django.core.mail import EmailMultiAlternatives
8+
9+
from studygroups.models import Profile
10+
from studygroups.utils import html_body_to_text
811
from studygroups.utils import render_to_string_ctx
912
from studygroups.email_helper import render_html_with_css
10-
from django.core.mail import EmailMultiAlternatives
1113

1214
import random
1315
import string
1416

15-
from studygroups.models import Profile
16-
from studygroups.utils import html_body_to_text
1717

1818
def create_user(email, first_name, last_name, password, communication_opt_in=False, interested_in_learning=''):
1919
""" Create a new user using the email as the username """

custom_registration/tests.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def test_account_create(self):
4040
"first_name": "firstname",
4141
"last_name": "lastname",
4242
"communication_opt_in": "on",
43-
"interested_in_learning": "python",
43+
"consent_opt_in": "on",
4444
"password1": "password",
4545
"password2": "password",
4646
}
@@ -49,7 +49,6 @@ def test_account_create(self):
4949
users = User.objects.filter(email__iexact=data['email'])
5050
self.assertEqual(users.count(), 1)
5151
profile = Profile.objects.get(user=users.first())
52-
self.assertEqual(profile.interested_in_learning, "python")
5352
self.assertEqual(profile.communication_opt_in, True)
5453
self.assertEqual(len(mail.outbox), 1) ##
5554
self.assertIn('Please confirm your email address', mail.outbox[0].subject)
@@ -64,6 +63,7 @@ def test_facilitator_signup_with_mixed_case(self):
6463
"password1": "password",
6564
"password2": "password",
6665
"communication_opt_in": "on",
66+
"consent_opt_in": "on",
6767
}
6868
resp = c.post('/en/accounts/register/', data)
6969
self.assertRedirects(resp, '/en/')
@@ -140,6 +140,7 @@ def test_api_account_create(self):
140140
"last_name": "Test",
141141
"password": "12345",
142142
"communication_opt_in": False,
143+
"consent_opt_in": True,
143144
"g-recaptcha-response": "blah",
144145
}
145146
resp = c.post(url, data=json.dumps(data), content_type='application/json')
@@ -197,7 +198,8 @@ def test_email_address_confirm(self):
197198
"last_name": "Test",
198199
"password": "12345",
199200
"g-recaptcha-response": "blah",
200-
"communication_opt_in": False
201+
"communication_opt_in": False,
202+
"consent_opt_in": True,
201203
}
202204
resp = c.post(url, data=json.dumps(data), content_type='application/json')
203205
self.assertEqual(resp.status_code, 200)
@@ -225,6 +227,7 @@ def test_send_new_user_email(self):
225227
"first_name": "firstname",
226228
"last_name": "lastname",
227229
"communication_opt_in": "on",
230+
"consent_opt_in": "on",
228231
"password1": "password",
229232
"password2": "password",
230233
}

0 commit comments

Comments
 (0)