codeforlife-portal 7.3.8__py2.py3-none-any.whl → 7.4.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codeforlife-portal might be problematic. Click here for more details.
- cfl_common/common/app_settings.py +0 -1
- cfl_common/common/helpers/emails.py +153 -36
- cfl_common/common/mail.py +5 -0
- {codeforlife_portal-7.3.8.dist-info → codeforlife_portal-7.4.1.dist-info}/METADATA +2 -2
- {codeforlife_portal-7.3.8.dist-info → codeforlife_portal-7.4.1.dist-info}/RECORD +31 -31
- example_project/portal_test_settings.py +1 -0
- example_project/settings.py +1 -0
- portal/__init__.py +1 -1
- portal/context_processors.py +5 -1
- portal/forms/dotmailer.py +39 -4
- portal/static/portal/js/common.js +35 -5
- portal/static/portal/sass/colorbox.scss +0 -1
- portal/static/portal/sass/modules/_colours.scss +3 -0
- portal/static/portal/sass/modules/_levels.scss +1 -1
- portal/static/portal/sass/modules/_mixins.scss +5 -0
- portal/static/portal/sass/partials/_buttons.scss +31 -3
- portal/static/portal/sass/partials/_header.scss +7 -6
- portal/static/portal/sass/partials/_popup.scss +7 -2
- portal/templates/portal/base.html +12 -3
- portal/templates/portal/partials/donate_popup.html +46 -0
- portal/templates/portal/partials/header.html +34 -30
- portal/templates/portal/teach.html +1 -1
- portal/templates/portal/terms.html +11 -9
- portal/tests/test_emails.py +17 -22
- portal/tests/{test_newsletter_footer.py → test_global_forms.py} +17 -1
- portal/urls.py +2 -0
- portal/views/dotmailer.py +30 -2
- portal/views/teacher/dashboard.py +174 -57
- portal/static/portal/img/x_close_video.png +0 -0
- {codeforlife_portal-7.3.8.dist-info → codeforlife_portal-7.4.1.dist-info}/LICENSE.md +0 -0
- {codeforlife_portal-7.3.8.dist-info → codeforlife_portal-7.4.1.dist-info}/WHEEL +0 -0
- {codeforlife_portal-7.3.8.dist-info → codeforlife_portal-7.4.1.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,6 @@ DOTDIGITAL_AUTH = getattr(settings, "DOTDIGITAL_AUTH", "")
|
|
|
8
8
|
|
|
9
9
|
# Dotmailer URLs for adding users to the newsletter address book
|
|
10
10
|
DOTMAILER_CREATE_CONTACT_URL = getattr(settings, "DOTMAILER_CREATE_CONTACT_URL", "")
|
|
11
|
-
DOTMAILER_MAIN_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_MAIN_ADDRESS_BOOK_URL", "")
|
|
12
11
|
DOTMAILER_TEACHER_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_TEACHER_ADDRESS_BOOK_URL", "")
|
|
13
12
|
DOTMAILER_STUDENT_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_STUDENT_ADDRESS_BOOK_URL", "")
|
|
14
13
|
DOTMAILER_NO_ACCOUNT_ADDRESS_BOOK_URL = getattr(settings, "DOTMAILER_NO_ACCOUNT_ADDRESS_BOOK_URL", "")
|
|
@@ -5,7 +5,12 @@ from uuid import uuid4
|
|
|
5
5
|
|
|
6
6
|
import jwt
|
|
7
7
|
from common import app_settings
|
|
8
|
-
from common.mail import
|
|
8
|
+
from common.mail import (
|
|
9
|
+
address_book_ids,
|
|
10
|
+
campaign_ids,
|
|
11
|
+
django_send_email,
|
|
12
|
+
send_dotdigital_email,
|
|
13
|
+
)
|
|
9
14
|
from common.models import Student, Teacher
|
|
10
15
|
from django.conf import settings
|
|
11
16
|
from django.contrib.auth.models import User
|
|
@@ -15,9 +20,15 @@ from django.utils import timezone
|
|
|
15
20
|
from requests import delete, get, post, put
|
|
16
21
|
from requests.exceptions import RequestException
|
|
17
22
|
|
|
18
|
-
NOTIFICATION_EMAIL =
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
NOTIFICATION_EMAIL = (
|
|
24
|
+
"Code For Life Notification <" + app_settings.EMAIL_ADDRESS + ">"
|
|
25
|
+
)
|
|
26
|
+
VERIFICATION_EMAIL = (
|
|
27
|
+
"Code For Life Verification <" + app_settings.EMAIL_ADDRESS + ">"
|
|
28
|
+
)
|
|
29
|
+
PASSWORD_RESET_EMAIL = (
|
|
30
|
+
"Code For Life Password Reset <" + app_settings.EMAIL_ADDRESS + ">"
|
|
31
|
+
)
|
|
21
32
|
INVITE_FROM = "Code For Life Invitation <" + app_settings.EMAIL_ADDRESS + ">"
|
|
22
33
|
|
|
23
34
|
|
|
@@ -41,7 +52,9 @@ def generate_token_for_email(email: str, new_email: str = ""):
|
|
|
41
52
|
"email": email,
|
|
42
53
|
"new_email": new_email,
|
|
43
54
|
"email_verification_token": uuid4().hex[:30],
|
|
44
|
-
"expires": (
|
|
55
|
+
"expires": (
|
|
56
|
+
timezone.now() + datetime.timedelta(hours=1)
|
|
57
|
+
).timestamp(),
|
|
45
58
|
},
|
|
46
59
|
settings.SECRET_KEY,
|
|
47
60
|
algorithm="HS256",
|
|
@@ -62,10 +75,21 @@ def send_email(
|
|
|
62
75
|
plaintext_template="email.txt",
|
|
63
76
|
html_template="email.html",
|
|
64
77
|
):
|
|
65
|
-
django_send_email(
|
|
78
|
+
django_send_email(
|
|
79
|
+
sender,
|
|
80
|
+
recipients,
|
|
81
|
+
subject,
|
|
82
|
+
text_content,
|
|
83
|
+
title,
|
|
84
|
+
replace_url,
|
|
85
|
+
plaintext_template,
|
|
86
|
+
html_template,
|
|
87
|
+
)
|
|
66
88
|
|
|
67
89
|
|
|
68
|
-
def send_verification_email(
|
|
90
|
+
def send_verification_email(
|
|
91
|
+
request, user, data, new_email=None, age=None, school=None
|
|
92
|
+
):
|
|
69
93
|
"""
|
|
70
94
|
Sends emails relating to email address verification.
|
|
71
95
|
|
|
@@ -98,18 +122,30 @@ def send_verification_email(request, user, data, new_email=None, age=None, schoo
|
|
|
98
122
|
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"
|
|
99
123
|
|
|
100
124
|
send_dotdigital_email(
|
|
101
|
-
campaign_ids["verify_released_student"],
|
|
102
|
-
|
|
125
|
+
campaign_ids["verify_released_student"],
|
|
126
|
+
[user.email],
|
|
127
|
+
personalization_values={
|
|
128
|
+
"VERIFICATION_LINK": url,
|
|
129
|
+
"SCHOOL_NAME": school.name,
|
|
130
|
+
},
|
|
103
131
|
)
|
|
104
132
|
else:
|
|
105
133
|
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"
|
|
106
134
|
|
|
107
135
|
send_dotdigital_email(
|
|
108
|
-
campaign_ids["verify_new_user"],
|
|
136
|
+
campaign_ids["verify_new_user"],
|
|
137
|
+
[user.email],
|
|
138
|
+
personalization_values={"VERIFICATION_LINK": url},
|
|
109
139
|
)
|
|
110
140
|
|
|
111
141
|
if _newsletter_ticked(data):
|
|
112
|
-
add_to_dotmailer(
|
|
142
|
+
add_to_dotmailer(
|
|
143
|
+
user.first_name,
|
|
144
|
+
user.last_name,
|
|
145
|
+
user.email,
|
|
146
|
+
address_book_ids["newsletter"],
|
|
147
|
+
DotmailerUserType.TEACHER,
|
|
148
|
+
)
|
|
113
149
|
# if the user is an independent student
|
|
114
150
|
else:
|
|
115
151
|
if age < 13:
|
|
@@ -117,29 +153,50 @@ def send_verification_email(request, user, data, new_email=None, age=None, schoo
|
|
|
117
153
|
send_dotdigital_email(
|
|
118
154
|
campaign_ids["verify_new_user_via_parent"],
|
|
119
155
|
[user.email],
|
|
120
|
-
personalization_values={
|
|
156
|
+
personalization_values={
|
|
157
|
+
"FIRST_NAME": user.first_name,
|
|
158
|
+
"ACTIVATION_LINK": url,
|
|
159
|
+
},
|
|
121
160
|
)
|
|
122
161
|
else:
|
|
123
162
|
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"
|
|
124
163
|
send_dotdigital_email(
|
|
125
|
-
campaign_ids["verify_new_user"],
|
|
164
|
+
campaign_ids["verify_new_user"],
|
|
165
|
+
[user.email],
|
|
166
|
+
personalization_values={"VERIFICATION_LINK": url},
|
|
126
167
|
)
|
|
127
168
|
|
|
128
169
|
if _newsletter_ticked(data):
|
|
129
|
-
add_to_dotmailer(
|
|
170
|
+
add_to_dotmailer(
|
|
171
|
+
user.first_name,
|
|
172
|
+
user.last_name,
|
|
173
|
+
user.email,
|
|
174
|
+
address_book_ids["newsletter"],
|
|
175
|
+
DotmailerUserType.STUDENT,
|
|
176
|
+
)
|
|
130
177
|
# verifying change of email address.
|
|
131
178
|
else:
|
|
132
179
|
verification = generate_token(user, new_email)
|
|
133
180
|
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"
|
|
134
181
|
send_dotdigital_email(
|
|
135
|
-
campaign_ids["email_change_verification"],
|
|
182
|
+
campaign_ids["email_change_verification"],
|
|
183
|
+
[new_email],
|
|
184
|
+
personalization_values={"VERIFICATION_LINK": url},
|
|
136
185
|
)
|
|
137
186
|
|
|
138
187
|
|
|
139
|
-
def add_to_dotmailer(
|
|
188
|
+
def add_to_dotmailer(
|
|
189
|
+
first_name: str,
|
|
190
|
+
last_name: str,
|
|
191
|
+
email: str,
|
|
192
|
+
address_book_id: int,
|
|
193
|
+
user_type: DotmailerUserType = None,
|
|
194
|
+
):
|
|
140
195
|
try:
|
|
141
196
|
create_contact(first_name, last_name, email)
|
|
142
|
-
add_contact_to_address_book(
|
|
197
|
+
add_contact_to_address_book(
|
|
198
|
+
first_name, last_name, email, address_book_id, user_type
|
|
199
|
+
)
|
|
143
200
|
except RequestException:
|
|
144
201
|
return HttpResponse(status=404)
|
|
145
202
|
|
|
@@ -157,15 +214,34 @@ def create_contact(first_name, last_name, email):
|
|
|
157
214
|
{"key": "FULLNAME", "value": f"{first_name} {last_name}"},
|
|
158
215
|
],
|
|
159
216
|
},
|
|
160
|
-
"consentFields": [
|
|
217
|
+
"consentFields": [
|
|
218
|
+
{
|
|
219
|
+
"fields": [
|
|
220
|
+
{
|
|
221
|
+
"key": "DATETIMECONSENTED",
|
|
222
|
+
"value": datetime.datetime.now().__str__(),
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
],
|
|
161
227
|
"preferences": app_settings.DOTMAILER_DEFAULT_PREFERENCES,
|
|
162
228
|
}
|
|
163
229
|
|
|
164
|
-
post(
|
|
230
|
+
post(
|
|
231
|
+
url,
|
|
232
|
+
json=body,
|
|
233
|
+
auth=(app_settings.DOTMAILER_USER, app_settings.DOTMAILER_PASSWORD),
|
|
234
|
+
)
|
|
165
235
|
|
|
166
236
|
|
|
167
|
-
def add_contact_to_address_book(
|
|
168
|
-
|
|
237
|
+
def add_contact_to_address_book(
|
|
238
|
+
first_name: str,
|
|
239
|
+
last_name: str,
|
|
240
|
+
email: str,
|
|
241
|
+
address_book_id: int,
|
|
242
|
+
user_type: DotmailerUserType = None,
|
|
243
|
+
):
|
|
244
|
+
main_address_book_url = f"https://r1-api.dotmailer.com/v2/address-books/{address_book_id}/contacts"
|
|
169
245
|
|
|
170
246
|
body = {
|
|
171
247
|
"email": email,
|
|
@@ -178,16 +254,31 @@ def add_contact_to_address_book(first_name: str, last_name: str, email: str, use
|
|
|
178
254
|
],
|
|
179
255
|
}
|
|
180
256
|
|
|
181
|
-
post(
|
|
182
|
-
|
|
183
|
-
|
|
257
|
+
post(
|
|
258
|
+
main_address_book_url,
|
|
259
|
+
json=body,
|
|
260
|
+
auth=(app_settings.DOTMAILER_USER, app_settings.DOTMAILER_PASSWORD),
|
|
261
|
+
)
|
|
184
262
|
|
|
185
|
-
if user_type
|
|
186
|
-
specific_address_book_url =
|
|
187
|
-
|
|
188
|
-
|
|
263
|
+
if user_type is not None:
|
|
264
|
+
specific_address_book_url = (
|
|
265
|
+
app_settings.DOTMAILER_NO_ACCOUNT_ADDRESS_BOOK_URL
|
|
266
|
+
)
|
|
189
267
|
|
|
190
|
-
|
|
268
|
+
if user_type == DotmailerUserType.TEACHER:
|
|
269
|
+
specific_address_book_url = (
|
|
270
|
+
app_settings.DOTMAILER_TEACHER_ADDRESS_BOOK_URL
|
|
271
|
+
)
|
|
272
|
+
elif user_type == DotmailerUserType.STUDENT:
|
|
273
|
+
specific_address_book_url = (
|
|
274
|
+
app_settings.DOTMAILER_STUDENT_ADDRESS_BOOK_URL
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
post(
|
|
278
|
+
specific_address_book_url,
|
|
279
|
+
json=body,
|
|
280
|
+
auth=(app_settings.DOTMAILER_USER, app_settings.DOTMAILER_PASSWORD),
|
|
281
|
+
)
|
|
191
282
|
|
|
192
283
|
|
|
193
284
|
def delete_contact(email: str):
|
|
@@ -195,8 +286,16 @@ def delete_contact(email: str):
|
|
|
195
286
|
user = get_dotmailer_user_by_email(email)
|
|
196
287
|
user_id = user.get("id")
|
|
197
288
|
if user_id:
|
|
198
|
-
url = app_settings.DOTMAILER_DELETE_USER_BY_ID_URL.replace(
|
|
199
|
-
|
|
289
|
+
url = app_settings.DOTMAILER_DELETE_USER_BY_ID_URL.replace(
|
|
290
|
+
"ID", str(user_id)
|
|
291
|
+
)
|
|
292
|
+
delete(
|
|
293
|
+
url,
|
|
294
|
+
auth=(
|
|
295
|
+
app_settings.DOTMAILER_USER,
|
|
296
|
+
app_settings.DOTMAILER_PASSWORD,
|
|
297
|
+
),
|
|
298
|
+
)
|
|
200
299
|
except RequestException:
|
|
201
300
|
return HttpResponse(status=404)
|
|
202
301
|
|
|
@@ -204,7 +303,9 @@ def delete_contact(email: str):
|
|
|
204
303
|
def get_dotmailer_user_by_email(email):
|
|
205
304
|
url = app_settings.DOTMAILER_GET_USER_BY_EMAIL_URL.replace("EMAIL", email)
|
|
206
305
|
|
|
207
|
-
response = get(
|
|
306
|
+
response = get(
|
|
307
|
+
url, auth=(app_settings.DOTMAILER_USER, app_settings.DOTMAILER_PASSWORD)
|
|
308
|
+
)
|
|
208
309
|
|
|
209
310
|
return json.loads(response.content)
|
|
210
311
|
|
|
@@ -212,7 +313,9 @@ def get_dotmailer_user_by_email(email):
|
|
|
212
313
|
def add_consent_record_to_dotmailer_user(user):
|
|
213
314
|
consent_date_time = datetime.datetime.now().__str__()
|
|
214
315
|
|
|
215
|
-
url = app_settings.DOTMAILER_PUT_CONSENT_DATA_URL.replace(
|
|
316
|
+
url = app_settings.DOTMAILER_PUT_CONSENT_DATA_URL.replace(
|
|
317
|
+
"USER_ID", str(user["id"])
|
|
318
|
+
)
|
|
216
319
|
body = {
|
|
217
320
|
"contact": {
|
|
218
321
|
"email": user["email"],
|
|
@@ -220,10 +323,20 @@ def add_consent_record_to_dotmailer_user(user):
|
|
|
220
323
|
"emailType": user["emailType"],
|
|
221
324
|
"dataFields": user["dataFields"],
|
|
222
325
|
},
|
|
223
|
-
"consentFields": [
|
|
326
|
+
"consentFields": [
|
|
327
|
+
{
|
|
328
|
+
"fields": [
|
|
329
|
+
{"key": "DATETIMECONSENTED", "value": consent_date_time}
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
],
|
|
224
333
|
}
|
|
225
334
|
|
|
226
|
-
put(
|
|
335
|
+
put(
|
|
336
|
+
url,
|
|
337
|
+
json=body,
|
|
338
|
+
auth=(app_settings.DOTMAILER_USER, app_settings.DOTMAILER_PASSWORD),
|
|
339
|
+
)
|
|
227
340
|
|
|
228
341
|
|
|
229
342
|
def send_dotmailer_consent_confirmation_email_to_user(user):
|
|
@@ -231,7 +344,11 @@ def send_dotmailer_consent_confirmation_email_to_user(user):
|
|
|
231
344
|
campaign_id = app_settings.DOTMAILER_THANKS_FOR_STAYING_CAMPAIGN_ID
|
|
232
345
|
body = {"campaignID": campaign_id, "contactIds": [str(user["id"])]}
|
|
233
346
|
|
|
234
|
-
post(
|
|
347
|
+
post(
|
|
348
|
+
url,
|
|
349
|
+
json=body,
|
|
350
|
+
auth=(app_settings.DOTMAILER_USER, app_settings.DOTMAILER_PASSWORD),
|
|
351
|
+
)
|
|
235
352
|
|
|
236
353
|
|
|
237
354
|
def update_indy_email(user, request, data):
|
cfl_common/common/mail.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codeforlife-portal
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.4.1
|
|
4
4
|
Classifier: Programming Language :: Python
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Framework :: Django
|
|
@@ -21,7 +21,7 @@ Requires-Dist: django-classy-tags==2.0.0
|
|
|
21
21
|
Requires-Dist: libsass==0.23.0
|
|
22
22
|
Requires-Dist: phonenumbers==8.12.12
|
|
23
23
|
Requires-Dist: more-itertools==8.7.0
|
|
24
|
-
Requires-Dist: cfl-common==7.
|
|
24
|
+
Requires-Dist: cfl-common==7.4.1
|
|
25
25
|
Requires-Dist: django-ratelimit==3.0.1
|
|
26
26
|
Requires-Dist: django-preventconcurrentlogins==0.8.2
|
|
27
27
|
Requires-Dist: django-csp==3.7
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
cfl_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
cfl_common/setup.py,sha256=5Rk-FXyWToTujXqGRYqeA0A5nJ4NC5woXxyb6NLLbpo,818
|
|
3
3
|
cfl_common/common/__init__.py,sha256=XlncBOpKp_gekbKH7Y_i6yu1qy5tJc3Y8sn8cDy-Vgk,48
|
|
4
|
-
cfl_common/common/app_settings.py,sha256=
|
|
4
|
+
cfl_common/common/app_settings.py,sha256=Bw1DXkZpNIdwUJ-cIOjZnngH5_NbMXC0koW7NgQ0pKY,2495
|
|
5
5
|
cfl_common/common/apps.py,sha256=49UXZ3bSkFKvIEOL4zM7y1sAhccQJyRtsoOg5XVd_8Y,129
|
|
6
6
|
cfl_common/common/context_processors.py,sha256=X0iuX5qu9kMWa7q8osE9CJ2LgM7pPOYQFGdjm8X3rk0,236
|
|
7
7
|
cfl_common/common/csp_config.py,sha256=9ECOLnp60ENRFAYEEIoYOMhqQzLgfKA-wkWxeUBwDrQ,2824
|
|
8
|
-
cfl_common/common/mail.py,sha256=
|
|
8
|
+
cfl_common/common/mail.py,sha256=pIRfUMVoJWxdv74UqToj_0_pTVTC51z6QlFVLI3QBOw,6874
|
|
9
9
|
cfl_common/common/models.py,sha256=yAULJtzuF4loEt6mPrgZjwHGiQH6Hqm82etE7Sofvys,15989
|
|
10
10
|
cfl_common/common/permissions.py,sha256=gC6RQGZI2QDBbglx-xr_V4Hl2C2nf1V2_uPmEuoEcJo,2416
|
|
11
11
|
cfl_common/common/utils.py,sha256=Nn2Npao9Uqad5Js_IdHwF-ow6wrPNpBLW4AO1LxoEBc,1727
|
|
12
12
|
cfl_common/common/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
cfl_common/common/helpers/data_migration_loader.py,sha256=_BhS5lPmhcuVUbryBmJytlWdHyT02KYyxPkHar32mOE,1748
|
|
14
|
-
cfl_common/common/helpers/emails.py,sha256=
|
|
14
|
+
cfl_common/common/helpers/emails.py,sha256=KyXIudPRgetggOnlNUohArF7cPBuazQI2V6dtMfKnrM,12368
|
|
15
15
|
cfl_common/common/helpers/generators.py,sha256=kTL5e91I8wgmjJ-mu4jr9vIacjccUZ5pZSAz5cUNhdM,1505
|
|
16
16
|
cfl_common/common/helpers/organisation.py,sha256=e-JKumKoXrkMTzZPv0H4ViWL8vtCt7oXJjn_zZ1ec00,427
|
|
17
17
|
cfl_common/common/migrations/0001_initial.py,sha256=Y2kt2xmdCbrmDXCgqmhXeacicNg26Zj7L7SANSsgAAI,9664
|
|
@@ -104,23 +104,23 @@ deploy/static/robots.txt,sha256=5cS4RITuQhbpNzvpk4AyDCXdlIBfmfCoBYRvCHY2VT8,24
|
|
|
104
104
|
deploy/templates/deploy/csrf_failure.html,sha256=-pBRPn4Y7nUdYHGpTHCokT9Boi-isuwuivF8V2K1SgM,412
|
|
105
105
|
example_project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
106
106
|
example_project/manage.py,sha256=EUgybZlZ7xk2Zf2KCwBbK_z7gf7Ifqs0_bl4Kijhdgo,242
|
|
107
|
-
example_project/portal_test_settings.py,sha256=
|
|
108
|
-
example_project/settings.py,sha256=
|
|
107
|
+
example_project/portal_test_settings.py,sha256=_gI7-HMoPJ-cDGO6n5UlEIHKHuTR5SC_Xt-l5Vdbx-0,7312
|
|
108
|
+
example_project/settings.py,sha256=HgGSG0n6Xggd0NieFVoJgn8vKGqyRbCddoB3CRuoT-Y,5640
|
|
109
109
|
example_project/urls.py,sha256=3SsP5jvPAXV5xmduka4zbSZB5PbXggjsalu1ojY5KIo,434
|
|
110
110
|
example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
|
|
111
|
-
portal/__init__.py,sha256=
|
|
111
|
+
portal/__init__.py,sha256=p8eq7jnQadKhC-wWoeEv-nRdPB1JN2Jan_o-R14Xz9w,22
|
|
112
112
|
portal/admin.py,sha256=on1-zNRnZvf2cwBN6GVRVYRhkaksrCgfzX8XPWtkvz8,6062
|
|
113
113
|
portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
|
|
114
114
|
portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
|
|
115
115
|
portal/beta.py,sha256=0TCC-9_KZoM1nuzJ9FiuKR5n9JITdMYenHGQtRvn9UU,255
|
|
116
|
-
portal/context_processors.py,sha256=
|
|
116
|
+
portal/context_processors.py,sha256=Q68UhmArLPRchS2KmfVR4hKrijllXal3sO5cHYWC2Fc,222
|
|
117
117
|
portal/handlers.py,sha256=gF99OfQrGcIGDnUyONhvylZNU8sl6XHYEurwu0fuiss,422
|
|
118
118
|
portal/models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
|
-
portal/urls.py,sha256=
|
|
119
|
+
portal/urls.py,sha256=4bGQQWiQI9zSG1oceVjQctUnDKggzzZsbYAxuBvijpY,18002
|
|
120
120
|
portal/wsgi.py,sha256=3yRcNxBQG30NhzrVi93bX-DrbXtsIQBc70HiW5wbOyE,401
|
|
121
121
|
portal/forms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
122
122
|
portal/forms/admin.py,sha256=Cdl8-wvasAzvMfgUlFYzQjYeuyC7gIsSiy8V_-jMp7w,2080
|
|
123
|
-
portal/forms/dotmailer.py,sha256=
|
|
123
|
+
portal/forms/dotmailer.py,sha256=j-o9qthQc7xmOsHSQGEEoHvaEyOpzlWrj6bOnV0PpsI,1567
|
|
124
124
|
portal/forms/error_messages.py,sha256=8d3z_3e2L-5zwj5hFhnUByC5k2CEpIVVuJg2nYkCUQ8,148
|
|
125
125
|
portal/forms/invite_teacher.py,sha256=jkDNcCfkts4_lXRzhcI3xBam21Zn2yX9wMpMVhDtW1w,880
|
|
126
126
|
portal/forms/organisation.py,sha256=QcQyd7AiqBmvt4y8uQSQylguUbKOKqo2pjqWIkpWjDg,7433
|
|
@@ -259,7 +259,6 @@ portal/static/portal/img/thumbnail_python_den.png,sha256=0if8hLRK9tR-oII6IEuRRq2
|
|
|
259
259
|
portal/static/portal/img/twitter.png,sha256=QD2ckrIWgV6WpuV0R7p717_T9a-DibzIxXsqHbvDR48,15969
|
|
260
260
|
portal/static/portal/img/universities.png,sha256=y015DeiJzJyIAEC-qIGY5HgsXJDr_DhUXOx8_2xbxf0,145961
|
|
261
261
|
portal/static/portal/img/wes.png,sha256=z2Z-vqqzIPkHY0PN7pgb7Im8CU0w9p2bc9VNRXGxtd0,54619
|
|
262
|
-
portal/static/portal/img/x_close_video.png,sha256=R6YR7j0axvkIdfB2u17hvbgTWA1sCk_0GREBRfFu3aY,1051
|
|
263
262
|
portal/static/portal/img/colorboxImages/border.png,sha256=Eb2D9kRqG0Gw2I3bLicfzJkSshDXf0DjTl4x4amvF0o,112
|
|
264
263
|
portal/static/portal/img/colorboxImages/controls.png,sha256=zQowXWoW0otiA3-wj5sGLdGgpqO5cNj5Xs69VvdAZ-k,2893
|
|
265
264
|
portal/static/portal/img/colorboxImages/loading.gif,sha256=NO9VJC_CTJTweQkCwJYB0ijpB0v3ofiMTeajm0DOOPo,9427
|
|
@@ -267,7 +266,7 @@ portal/static/portal/img/colorboxImages/loading_background.png,sha256=lZ7Mxrcb7-
|
|
|
267
266
|
portal/static/portal/img/colorboxImages/overlay.png,sha256=qy73bf_q55z4kktuaTaMhVrxDzVRCIjgmBQ5cbOmLtE,182
|
|
268
267
|
portal/static/portal/js/bootstrap.min.js,sha256=nuL8_2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL-1ev4,39680
|
|
269
268
|
portal/static/portal/js/carouselCards.js,sha256=IByMjKk37E-TCc3vx9nfF-IJWl9BOFPNVqf4WuD75GI,778
|
|
270
|
-
portal/static/portal/js/common.js,sha256=
|
|
269
|
+
portal/static/portal/js/common.js,sha256=kVUdm0luaqMLElbDq3Mht1k5DfkYHXAmJtce1Rekogg,7554
|
|
271
270
|
portal/static/portal/js/independentLogin.js,sha256=wjjJBAF5arJ2iwW30lHTraG_f2FJ9UMGnXGpUSXwXIs,538
|
|
272
271
|
portal/static/portal/js/independentRegistration.js,sha256=YWhIzwJcl0acU9weAKB7pWK76J1dpAuAQkI7DrUm3uA,2622
|
|
273
272
|
portal/static/portal/js/join_create_game_toggle.js,sha256=eWxhMfzVKu1oft9iUFV4w8CgqMRv9-unb5P5cGi1h_4,393
|
|
@@ -293,7 +292,7 @@ portal/static/portal/js/lib/jquery.min.js,sha256=2Pmvv0kuTBOenSvLm6bvfBSSHrUJ-3A
|
|
|
293
292
|
portal/static/portal/js/lib/modernizr-build.js,sha256=pGqgo-dxjy43hd1yL75ivaH9xWF9qfVKLlD4EYlTzJ4,36698
|
|
294
293
|
portal/static/portal/js/lib/papaparse.min.js,sha256=tDf9H6Pr0oXtuyG0hGdMQ5OU5EuM5IK8WMK2iTbdvd0,18829
|
|
295
294
|
portal/static/portal/sass/bootstrap.scss,sha256=q_gMkiqFVJBrMKNr0kXaP7y4caychGNGkyEyEUUFN3k,2144
|
|
296
|
-
portal/static/portal/sass/colorbox.scss,sha256=
|
|
295
|
+
portal/static/portal/sass/colorbox.scss,sha256=DqEMSAPBfBwNGY1acoh9fCW9PPY-SchjKW7sNMxd9UM,3637
|
|
297
296
|
portal/static/portal/sass/styles.scss,sha256=gTv8yjfzrN1acywPBkS9b49648LUGN4xvkwqAK-gAvc,780
|
|
298
297
|
portal/static/portal/sass/bootstrap/_alerts.scss,sha256=C5kv4Wt7RFE3ESibknOeFzbE79it0qfwV59y_yaeImE,1546
|
|
299
298
|
portal/static/portal/sass/bootstrap/_badges.scss,sha256=lHaAb3wWe4sh5kwNTsni1f0PCkNXBTfcVbakJTzoAYY,1228
|
|
@@ -394,21 +393,21 @@ portal/static/portal/sass/modules/_all.scss,sha256=k1U_FAKajqT8B3U53UT9B1Hc4jn5P
|
|
|
394
393
|
portal/static/portal/sass/modules/_animation.scss,sha256=s75-4xRmPSmqwHUuyVy0OcnbS5jreRnotMXm-CuTLkE,39
|
|
395
394
|
portal/static/portal/sass/modules/_breakpoints.scss,sha256=Nc7nrvjzQ0eK844ITuqwYcybIJxpYVFU5s30mz3BGOg,498
|
|
396
395
|
portal/static/portal/sass/modules/_card_constants.scss,sha256=FUojcT5Fs-IYErt-frahD3HnVb06A515k4SQJrqVUfQ,107
|
|
397
|
-
portal/static/portal/sass/modules/_colours.scss,sha256=
|
|
396
|
+
portal/static/portal/sass/modules/_colours.scss,sha256=Wen7UlF98ijyDjIEsLeIzLx0fcgXOLjavAVIh8PfqX0,4350
|
|
398
397
|
portal/static/portal/sass/modules/_homepage_constants.scss,sha256=GfSppJtWNxufu4hKO6vHX7YBQgmU1oB0KBonh-ltgv0,44
|
|
399
|
-
portal/static/portal/sass/modules/_levels.scss,sha256
|
|
400
|
-
portal/static/portal/sass/modules/_mixins.scss,sha256=
|
|
398
|
+
portal/static/portal/sass/modules/_levels.scss,sha256=-PrZ21k_-sQAxYZB0uJd7macz46-VVwsQdmtxYyZYnA,106
|
|
399
|
+
portal/static/portal/sass/modules/_mixins.scss,sha256=8xDWuApUG6B3pjadB4iHpJ87ehXCg0qqpabnVd2cgxU,1987
|
|
401
400
|
portal/static/portal/sass/modules/_spacing.scss,sha256=WHBcd8ZSl4UHqPAOmW_JLt_MOfww44Hj8W42dWOpTO8,31
|
|
402
401
|
portal/static/portal/sass/partials/_banners.scss,sha256=Q13Mybarzkq0GWvhStiqIuK_bgKku8wkqC6qCFIruEg,5658
|
|
403
402
|
portal/static/portal/sass/partials/_base.scss,sha256=cUvskrzNXLA-Xg1EgpL-S0wTWDnRn86AcdMbE2_aLMM,26
|
|
404
|
-
portal/static/portal/sass/partials/_buttons.scss,sha256=
|
|
403
|
+
portal/static/portal/sass/partials/_buttons.scss,sha256=UR0a6ne8nZQyyWlWzVDD5RG2vfVe8w9rM5yWLBav3qM,9572
|
|
405
404
|
portal/static/portal/sass/partials/_carousel.scss,sha256=m8N6jSuHBzeKyMUNGGc48NlNYTmotKlaiy10hwFnyWY,3500
|
|
406
405
|
portal/static/portal/sass/partials/_footer.scss,sha256=oqt-Qvz7vtUFNnpe4FkQkaZk3J3fojCy9cKCxqGTWoM,2493
|
|
407
406
|
portal/static/portal/sass/partials/_forms.scss,sha256=cbonSxhtfaHR-4R6i0u65AaIZRG_25C837CgZlLuwCI,7101
|
|
408
407
|
portal/static/portal/sass/partials/_grids.scss,sha256=pnMQht5lZ65MRB-0_nl8yn655hlKC_oWCwZopillVwc,4968
|
|
409
|
-
portal/static/portal/sass/partials/_header.scss,sha256=
|
|
408
|
+
portal/static/portal/sass/partials/_header.scss,sha256=NNb8hb66LPTeaGdL-vcsNSDJTxPljsOfpkYMI5EmOWc,7421
|
|
410
409
|
portal/static/portal/sass/partials/_images.scss,sha256=Fro4a0VfLo6FyrvGk5yjsjzzGKWVdHeMFJiVC96C7vk,6213
|
|
411
|
-
portal/static/portal/sass/partials/_popup.scss,sha256=
|
|
410
|
+
portal/static/portal/sass/partials/_popup.scss,sha256=GQ6Vtmj3vdOP4Hvsf8ZxKdEtuL8gqoClYpDgQ19kvnQ,2280
|
|
412
411
|
portal/static/portal/sass/partials/_progress-bars.scss,sha256=cTyRa9WLeIE0rETmY58Rcyf-8O6JE3iDTa_jw3mk23g,144
|
|
413
412
|
portal/static/portal/sass/partials/_subnavs.scss,sha256=6FJV1wBmHchnGBL9Yx56Ua4RR1b5P6ABTextZPTqXSs,5052
|
|
414
413
|
portal/static/portal/sass/partials/_tables.scss,sha256=XrO-I41hfyFy1Uh-STokSpoG0qifJVNlpWS4sNxDYdQ,2984
|
|
@@ -434,7 +433,7 @@ portal/templates/email.txt,sha256=z3bkT2WnkCrVa1RLVbGd-pE81cLEHlZ_QowfbSQAOvg,19
|
|
|
434
433
|
portal/templates/captcha/widget_v2_invisible.html,sha256=wPBAvvjm-qhSCrQruwJ2SSBkxFg4oUNFl26Axs1IjZw,306
|
|
435
434
|
portal/templates/captcha/includes/js_v2_invisible.html,sha256=FUyDf1RDyS7whzW2B_TnD1ovS8an9sDavCJFqAsrnmQ,1409
|
|
436
435
|
portal/templates/portal/about.html,sha256=_iD0GCP6q3-XuZ2LC-9O0KYY-mKL6c9qk3O-NRRqsRM,10321
|
|
437
|
-
portal/templates/portal/base.html,sha256=
|
|
436
|
+
portal/templates/portal/base.html,sha256=4xLACNgKmRQTdEsdNNGYhLzMozzYzWIIzk31HrLGBf0,12109
|
|
438
437
|
portal/templates/portal/base_no_userprofile.html,sha256=PlRufyYmUUGWBZ6CvbYhJWOMTqKqdcee4xnO5--AogA,447
|
|
439
438
|
portal/templates/portal/coding_club.html,sha256=aaLx9UQ8p_7Vvy3Vlh1rOufeNN0KhJ6fj4oqI6QqJcM,4518
|
|
440
439
|
portal/templates/portal/contribute.html,sha256=UIC_N3Lun9wB_6jEra0wvlT9fDiiIeMby7_onXYo6k0,4176
|
|
@@ -457,9 +456,9 @@ portal/templates/portal/reset_password.html,sha256=YzsREz5D2OwhicMLahVOVDXiNDxoH
|
|
|
457
456
|
portal/templates/portal/reset_password_confirm.html,sha256=jPHSDatezRXzCG4zH_5BQPWAxLblidqro0hzvsH54ho,3499
|
|
458
457
|
portal/templates/portal/reset_password_done.html,sha256=rpzN3svZne5H2FS3TJaGnHypRj2KX-SRS6DbFQkgLf0,667
|
|
459
458
|
portal/templates/portal/reset_password_email_sent.html,sha256=kwNvoH_M-Qd5s-g0HiULwfQt_SD12WEMgPRSnLmldTQ,914
|
|
460
|
-
portal/templates/portal/teach.html,sha256=
|
|
459
|
+
portal/templates/portal/teach.html,sha256=2qOWzA00evHYlwSvXDOz8VQo1yXB-95Db7KgqpOItm0,9006
|
|
461
460
|
portal/templates/portal/ten_year_map.html,sha256=_NxEXDJMGdtguuZ3vYl00yBgYo12wv1w8QJ-LMhw8fg,8390
|
|
462
|
-
portal/templates/portal/terms.html,sha256=
|
|
461
|
+
portal/templates/portal/terms.html,sha256=ekhBnhJVHcr5BE5W4PZ-YNzGsmhvRTrj1gdpdNdSYRk,29314
|
|
463
462
|
portal/templates/portal/login/independent_student.html,sha256=G4u82m0lko4yQvqRDMger5p63A6KtFI_bsEOsQWlyJw,1777
|
|
464
463
|
portal/templates/portal/login/student.html,sha256=s5rUyT-u7gei2xWQ-Ba35ePC5WbtwReEzUZAKwUoZVY,1261
|
|
465
464
|
portal/templates/portal/login/student_class_code.html,sha256=rJr6NB4Oz7XjZXDOUHpwzT6r6yxh7nZ5joca-z2bK-s,966
|
|
@@ -469,8 +468,9 @@ portal/templates/portal/partials/benefits.html,sha256=TZm4U_XimgivkPMjDXxxkV7PLf
|
|
|
469
468
|
portal/templates/portal/partials/card_list.html,sha256=yHcp4oc0WRG9H6Ek871VCHbwYkDRcwQYbZ320gtsFn8,1550
|
|
470
469
|
portal/templates/portal/partials/character_list.html,sha256=SnNFHzbIkOSaiRPIvSdplEf_B87UYgJ1pOvMltNDxLE,415
|
|
471
470
|
portal/templates/portal/partials/delete_popup.html,sha256=nEhnwgnmKoFzb6LlCwdX973Em9bVOFh6MON36RPteYs,1275
|
|
471
|
+
portal/templates/portal/partials/donate_popup.html,sha256=iPxXqIwZ-9_n4ssdUEiZ_GY3nbpes2AlcEKphL2Plno,2151
|
|
472
472
|
portal/templates/portal/partials/footer.html,sha256=m0mKlUenQN4pVCNi8Dkzer5aQ4uUmvfLjyzTMWoBiQ4,4838
|
|
473
|
-
portal/templates/portal/partials/header.html,sha256=
|
|
473
|
+
portal/templates/portal/partials/header.html,sha256=LCOppTXDr8hEYp2eBJjxw3LvqwnVR-6E9jdYGodlD5U,20373
|
|
474
474
|
portal/templates/portal/partials/headline.html,sha256=xKb-WtkT0FyQqT0smyNSKkXFvU7KQ5Czad8ca6YKQg4,89
|
|
475
475
|
portal/templates/portal/partials/hero_card.html,sha256=UN5hyxrw-McuXFsDzPBIECB9yGrv9VjsFf8SEBowwXc,786
|
|
476
476
|
portal/templates/portal/partials/info_popup.html,sha256=gzffd5MBVb7p2hGQuZMNDudThrRgs847hCu9ziT9uLE,566
|
|
@@ -536,12 +536,12 @@ portal/tests/test_api.py,sha256=Yo5s_nEGOoG35jA39yZ6nuDOUZvuCZ8o8o8XhZos61w,1381
|
|
|
536
536
|
portal/tests/test_captcha_forms.py,sha256=lirhIli-sHovun8VdrF0he7KRFTAd8DMCpkJ8cQNotg,1015
|
|
537
537
|
portal/tests/test_class.py,sha256=43g2HslNosbSuSnnMBzM6VWk4LaV0HXkWS3f8VKVRmw,15930
|
|
538
538
|
portal/tests/test_daily_activities.py,sha256=-siDCMGBD1ijjccHVk7eEmrk4bgTsvbh0B6hDoj2fo0,1803
|
|
539
|
-
portal/tests/test_emails.py,sha256=
|
|
539
|
+
portal/tests/test_emails.py,sha256=pLr06j3uMBxP1raoZQWzUTBVFvsEDFtUh85J8OnqCwE,9238
|
|
540
|
+
portal/tests/test_global_forms.py,sha256=A5JpAe4AYK-wpu0o1qU4THmeNv_wr7lhzaMbjz5czpY,1543
|
|
540
541
|
portal/tests/test_helper_methods.py,sha256=-SQCDZm2XUtyXGEp0CHIb_SSC9CPD-XOSnpnY8QclHk,890
|
|
541
542
|
portal/tests/test_independent_student.py,sha256=NrRjTEr6V4WXpCE74N8LYNVocvLSvddkjuo3dYpfAZc,27245
|
|
542
543
|
portal/tests/test_invite_teacher.py,sha256=oeOaoJV1IqJSYPlaPFjnhVXdB2mq8otCTLp_lfjuCfk,12224
|
|
543
544
|
portal/tests/test_middleware.py,sha256=b6jfNmiRZ2snqLKsyJUG-RivoX5fmrqLlQkG9MeVnqM,8034
|
|
544
|
-
portal/tests/test_newsletter_footer.py,sha256=MdVUX53mEoDTa4Krq-jg9LFNo-QyghqvTvhHeNXBGnE,838
|
|
545
545
|
portal/tests/test_organisation.py,sha256=kCMUNzLN6EzaMUBcFkqXwnqLGgOuQxQWIHHt63nhqBs,7574
|
|
546
546
|
portal/tests/test_partials.py,sha256=cSLNLjdsriROjPxkZlM3HKD3CSKDuKgpaDIdL3fPyBs,1794
|
|
547
547
|
portal/tests/test_ratelimit.py,sha256=XWq1A9XgRrlcMHibGoJ0kc4gLc5U_u5UhKHjthxCfYA,19376
|
|
@@ -608,7 +608,7 @@ portal/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
608
608
|
portal/views/about.py,sha256=-muXy17UhxCSKkjnMAkSLXiCvT_pBPlf2ykTYr794dI,443
|
|
609
609
|
portal/views/admin.py,sha256=4Xt3zEyQH7sUwQSrwuRtoCodWidjOzd7gJUwWU96pXY,957
|
|
610
610
|
portal/views/api.py,sha256=lCwiclR98G-yTgK55u8IjkueIH8iremeiZSa3jAvO-M,6990
|
|
611
|
-
portal/views/dotmailer.py,sha256=
|
|
611
|
+
portal/views/dotmailer.py,sha256=x49p89TtwA1MLysRLtq5yRRzVtIpzGoU__Xb5hPuHak,3208
|
|
612
612
|
portal/views/email.py,sha256=V3wXRxIjeZ4OJBVqGCQrPn-GQWKZK1PCXbR1f2Zpa_4,2174
|
|
613
613
|
portal/views/home.py,sha256=GlNTJqSST_jQi0REuaV2aI2zram-KAhedmATdC6yU58,10247
|
|
614
614
|
portal/views/legal.py,sha256=nUunsTHnhMcXBcDlg1GmUal86k9Vhinne4A2FWfq78M,342
|
|
@@ -626,14 +626,14 @@ portal/views/student/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
|
626
626
|
portal/views/student/edit_account_details.py,sha256=Ba-3D_zzKbX5N01NG5qqBS0ud10B8D5SN8hOpLiGa9U,8468
|
|
627
627
|
portal/views/student/play.py,sha256=GMxk65bxWOe1Ds2kb6rvuOd1GoAtt5v_9AihLNXoUL0,8768
|
|
628
628
|
portal/views/teacher/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
629
|
-
portal/views/teacher/dashboard.py,sha256=
|
|
629
|
+
portal/views/teacher/dashboard.py,sha256=pjzOOCz29d4VHukaCI5QhkDsu-RPvy7SXC9dDcPo50k,27422
|
|
630
630
|
portal/views/teacher/teach.py,sha256=MxheM_kxt_K1J7jEWlim8yZonnp63iYUTw5dCaLscLI,37056
|
|
631
631
|
portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
632
632
|
portal/views/two_factor/core.py,sha256=O_wcBeFqdPYSGNGv-pT_vbs5-Dj1Z-Jfkd6f9-E5yZI,760
|
|
633
633
|
portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
|
|
634
634
|
portal/views/two_factor/profile.py,sha256=tkl_ludo8arMtd5LKNmohM66vpC_YQiP-0nspTSJiJ4,383
|
|
635
|
-
codeforlife_portal-7.
|
|
636
|
-
codeforlife_portal-7.
|
|
637
|
-
codeforlife_portal-7.
|
|
638
|
-
codeforlife_portal-7.
|
|
639
|
-
codeforlife_portal-7.
|
|
635
|
+
codeforlife_portal-7.4.1.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
|
|
636
|
+
codeforlife_portal-7.4.1.dist-info/METADATA,sha256=6kN9QQduDOTlZTEwl5YTS2LiqxZijcWzKsBWa0qUYFQ,3317
|
|
637
|
+
codeforlife_portal-7.4.1.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
|
|
638
|
+
codeforlife_portal-7.4.1.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
|
|
639
|
+
codeforlife_portal-7.4.1.dist-info/RECORD,,
|
example_project/settings.py
CHANGED
portal/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "7.
|
|
1
|
+
__version__ = "7.4.1"
|
portal/context_processors.py
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
from portal.forms.dotmailer import NewsletterForm
|
|
1
|
+
from portal.forms.dotmailer import DonateForm, NewsletterForm
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def process_newsletter_form(request):
|
|
5
5
|
return {"news_form": NewsletterForm()}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def process_donate_form(request):
|
|
9
|
+
return {"donate_form": DonateForm()}
|
portal/forms/dotmailer.py
CHANGED
|
@@ -5,16 +5,51 @@ class NewsletterForm(forms.Form):
|
|
|
5
5
|
email = forms.EmailField(
|
|
6
6
|
label="Sign up to receive updates about Code for Life games and teaching resources.",
|
|
7
7
|
label_suffix="",
|
|
8
|
-
widget=forms.EmailInput(
|
|
8
|
+
widget=forms.EmailInput(
|
|
9
|
+
attrs={
|
|
10
|
+
"placeholder": "Your email address",
|
|
11
|
+
"id": "newsletter_email_field",
|
|
12
|
+
}
|
|
13
|
+
),
|
|
9
14
|
help_text="Enter email address above",
|
|
10
15
|
)
|
|
11
16
|
|
|
12
|
-
age_verification = forms.BooleanField(
|
|
17
|
+
age_verification = forms.BooleanField(
|
|
18
|
+
widget=forms.CheckboxInput(), initial=False, required=True
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DonateForm(forms.Form):
|
|
23
|
+
email = forms.EmailField(
|
|
24
|
+
label="This data will only be used for this purpose and you will be "
|
|
25
|
+
"able to opt out anytime. Please read our privacy notice for "
|
|
26
|
+
"further details.",
|
|
27
|
+
label_suffix="",
|
|
28
|
+
widget=forms.EmailInput(
|
|
29
|
+
attrs={
|
|
30
|
+
"placeholder": "Enter your email address",
|
|
31
|
+
"id": "donate_email_field",
|
|
32
|
+
}
|
|
33
|
+
),
|
|
34
|
+
help_text="Enter your email address",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
age_verification = forms.BooleanField(
|
|
38
|
+
widget=forms.CheckboxInput(attrs={"id": "donate_age_verification"}),
|
|
39
|
+
initial=False,
|
|
40
|
+
required=True,
|
|
41
|
+
)
|
|
13
42
|
|
|
14
43
|
|
|
15
44
|
class ConsentForm(forms.Form):
|
|
16
45
|
email = forms.EmailField(
|
|
17
|
-
label="Email",
|
|
46
|
+
label="Email",
|
|
47
|
+
label_suffix="",
|
|
48
|
+
widget=forms.EmailInput(
|
|
49
|
+
attrs={"placeholder": "your.name@yourdomain.com"}
|
|
50
|
+
),
|
|
18
51
|
)
|
|
19
52
|
|
|
20
|
-
consent_ticked = forms.BooleanField(
|
|
53
|
+
consent_ticked = forms.BooleanField(
|
|
54
|
+
widget=forms.CheckboxInput(), initial=False, required=True
|
|
55
|
+
)
|