codeforlife-portal 5.33.5__py2.py3-none-any.whl → 8.9.9__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.
Files changed (391) hide show
  1. cfl_common/common/__init__.py +1 -0
  2. cfl_common/common/app_settings.py +66 -0
  3. cfl_common/common/apps.py +6 -0
  4. cfl_common/common/context_processors.py +9 -0
  5. cfl_common/common/csp_config.py +85 -0
  6. cfl_common/common/helpers/__init__.py +0 -0
  7. cfl_common/common/helpers/data_migration_loader.py +42 -0
  8. cfl_common/common/helpers/emails.py +393 -0
  9. cfl_common/common/helpers/generators.py +52 -0
  10. cfl_common/common/helpers/organisation.py +10 -0
  11. cfl_common/common/mail.py +201 -0
  12. cfl_common/common/migrations/0001_initial.py +240 -0
  13. cfl_common/common/migrations/0002_emailverification.py +55 -0
  14. cfl_common/common/migrations/0003_aimmocharacter.py +31 -0
  15. cfl_common/common/migrations/0004_add_aimmocharacters.py +17 -0
  16. cfl_common/common/migrations/0005_add_worksheets.py +8 -0
  17. cfl_common/common/migrations/0006_update_aimmo_character_image_path.py +17 -0
  18. cfl_common/common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +8 -0
  19. cfl_common/common/migrations/0008_unlock_worksheet_3.py +11 -0
  20. cfl_common/common/migrations/0009_add_blocked_time_to_teacher_and_student.py +24 -0
  21. cfl_common/common/migrations/0010_remove_teacher_title.py +18 -0
  22. cfl_common/common/migrations/0011_student_login_id.py +18 -0
  23. cfl_common/common/migrations/0012_usersession.py +39 -0
  24. cfl_common/common/migrations/0013_class_school.py +42 -0
  25. cfl_common/common/migrations/0014_login_type.py +29 -0
  26. cfl_common/common/migrations/0015_dailyactivity.py +31 -0
  27. cfl_common/common/migrations/0016_joinreleasestudent.py +42 -0
  28. cfl_common/common/migrations/0017_copy_email_to_username.py +18 -0
  29. cfl_common/common/migrations/0018_update_aimmo_character_image_path.py +15 -0
  30. cfl_common/common/migrations/0019_aimmocharacter_alt.py +16 -0
  31. cfl_common/common/migrations/0020_class_is_active_and_null_access_code.py +23 -0
  32. cfl_common/common/migrations/0021_school_is_active.py +28 -0
  33. cfl_common/common/migrations/0022_school_cleanup.py +29 -0
  34. cfl_common/common/migrations/0023_userprofile_aimmo_badges.py +22 -0
  35. cfl_common/common/migrations/0024_teacher_invited_by.py +25 -0
  36. cfl_common/common/migrations/0025_schoolteacherinvitation.py +47 -0
  37. cfl_common/common/migrations/0026_teacher_remove_join_request.py +22 -0
  38. cfl_common/common/migrations/0027_class_created_by.py +25 -0
  39. cfl_common/common/migrations/0028_coding_club_downloads.py +23 -0
  40. cfl_common/common/migrations/0029_dynamicelement.py +22 -0
  41. cfl_common/common/migrations/0030_add_maintenance_banner.py +25 -0
  42. cfl_common/common/migrations/0031_improve_admin_panel.py +56 -0
  43. cfl_common/common/migrations/0032_dailyactivity_level_control_submits.py +18 -0
  44. cfl_common/common/migrations/0033_password_reset_tracking_fields.py +23 -0
  45. cfl_common/common/migrations/0034_dailyactivity_daily_school_student_lockout_reset.py +18 -0
  46. cfl_common/common/migrations/0035_rename_lockout_fields.py +27 -0
  47. cfl_common/common/migrations/0036_rename_awaiting_email_verification_userprofile_is_verified.py +17 -0
  48. cfl_common/common/migrations/0037_migrate_email_verification.py +21 -0
  49. cfl_common/common/migrations/0038_delete_emailverification.py +16 -0
  50. cfl_common/common/migrations/0039_copy_email_to_username.py +18 -0
  51. cfl_common/common/migrations/0040_school_county.py +18 -0
  52. cfl_common/common/migrations/0041_populate_gb_counties.py +27 -0
  53. cfl_common/common/migrations/0042_totalactivity.py +25 -0
  54. cfl_common/common/migrations/0043_add_total_activity.py +30 -0
  55. cfl_common/common/migrations/0044_update_activity_models.py +33 -0
  56. cfl_common/common/migrations/0045_otp.py +23 -0
  57. cfl_common/common/migrations/0046_alter_school_country.py +19 -0
  58. cfl_common/common/migrations/0047_delete_school_postcode.py +16 -0
  59. cfl_common/common/migrations/0048_unique_school_names.py +42 -0
  60. cfl_common/common/migrations/0049_anonymise_orphan_users.py +29 -0
  61. cfl_common/common/migrations/0050_anonymise_orphan_schools.py +30 -0
  62. cfl_common/common/migrations/0051_verify_returning_users.py +26 -0
  63. cfl_common/common/migrations/0052_add_cse_fields.py +68 -0
  64. cfl_common/common/migrations/0053_clean_class_data.py +24 -0
  65. cfl_common/common/migrations/0054_delete_aimmo_models.py +20 -0
  66. cfl_common/common/migrations/0055_alter_schoolteacherinvitation_token.py +18 -0
  67. cfl_common/common/migrations/0056_set_non_school_teachers_as_non_admins.py +25 -0
  68. cfl_common/common/migrations/0057_teacher_teacher__is_admin.py +19 -0
  69. cfl_common/common/migrations/0058_userprofile_google_refresh_token_and_more.py +24 -0
  70. cfl_common/common/migrations/__init__.py +0 -0
  71. cfl_common/common/models.py +557 -0
  72. cfl_common/common/permissions.py +84 -0
  73. cfl_common/common/tests/__init__.py +0 -0
  74. cfl_common/common/tests/test_migration_anonymise_orphan_schools.py +30 -0
  75. cfl_common/common/tests/test_migration_anonymise_orphan_users.py +30 -0
  76. cfl_common/common/tests/test_migration_blocked_time.py +15 -0
  77. cfl_common/common/tests/test_migration_remove_teacher_title.py +13 -0
  78. cfl_common/common/tests/test_migration_unique_school_names.py +33 -0
  79. cfl_common/common/tests/test_migration_verify_returning_users.py +59 -0
  80. cfl_common/common/tests/test_models.py +87 -0
  81. cfl_common/common/tests/utils/__init__.py +0 -0
  82. cfl_common/common/tests/utils/classes.py +38 -0
  83. cfl_common/common/tests/utils/email.py +67 -0
  84. cfl_common/common/tests/utils/organisation.py +41 -0
  85. cfl_common/common/tests/utils/student.py +123 -0
  86. cfl_common/common/tests/utils/teacher.py +73 -0
  87. cfl_common/common/tests/utils/user.py +27 -0
  88. cfl_common/common/utils.py +56 -0
  89. cfl_common/setup.py +61 -0
  90. codeforlife_portal-8.9.9.dist-info/METADATA +226 -0
  91. {codeforlife_portal-5.33.5.dist-info → codeforlife_portal-8.9.9.dist-info}/RECORD +339 -241
  92. {codeforlife_portal-5.33.5.dist-info → codeforlife_portal-8.9.9.dist-info}/WHEEL +1 -1
  93. codeforlife_portal-8.9.9.dist-info/licenses/LICENSE.md +3 -0
  94. {codeforlife_portal-5.33.5.dist-info → codeforlife_portal-8.9.9.dist-info}/top_level.txt +1 -0
  95. deploy/middleware/maintenance.py +25 -0
  96. deploy/middleware/screentime_warning.py +29 -0
  97. deploy/middleware/security.py +5 -6
  98. deploy/middleware/session_timeout.py +4 -2
  99. deploy/middleware/tmp_basic_auth.py +41 -0
  100. example_project/portal_test_settings.py +239 -0
  101. example_project/settings.py +156 -17
  102. example_project/urls.py +5 -6
  103. portal/__init__.py +1 -1
  104. portal/admin.py +142 -29
  105. portal/app_settings.py +8 -7
  106. portal/forms/dotmailer.py +6 -4
  107. portal/forms/invite_teacher.py +19 -10
  108. portal/forms/organisation.py +137 -68
  109. portal/forms/play.py +53 -98
  110. portal/forms/registration.py +70 -164
  111. portal/forms/teach.py +147 -121
  112. portal/handlers.py +1 -2
  113. portal/helpers/decorators.py +30 -10
  114. portal/helpers/password.py +86 -47
  115. portal/helpers/ratelimit.py +32 -15
  116. portal/helpers/regexes.py +5 -0
  117. portal/helpers/request_handlers.py +10 -0
  118. portal/migrations/0044_auto_20150430_0959.py +6 -2
  119. portal/mixins/__init__.py +1 -0
  120. portal/mixins/cron_mixin.py +12 -0
  121. portal/permissions/__init__.py +1 -0
  122. portal/permissions/is_cron_request_from_google.py +14 -0
  123. portal/static/portal/img/10_years_anniversary.png +0 -0
  124. portal/static/portal/img/RR_logo_grass_background.png +0 -0
  125. portal/static/portal/img/coding_club_hero.jpg +0 -0
  126. portal/static/portal/img/coding_club_python_pack.png +0 -0
  127. portal/static/portal/img/facebook.png +0 -0
  128. portal/static/portal/img/gitbook.png +0 -0
  129. portal/static/portal/img/howe_dell_1.png +0 -0
  130. portal/static/portal/img/howe_dell_2.png +0 -0
  131. portal/static/portal/img/howe_dell_3.png +0 -0
  132. portal/static/portal/img/logo_cfl.png +0 -0
  133. portal/static/portal/img/logo_cfl_powered.svg +35 -0
  134. portal/static/portal/img/logo_cfl_reminder_cards.jpg +0 -0
  135. portal/static/portal/img/logo_ocado_group.png +0 -0
  136. portal/static/portal/img/logo_python_den.svg +21 -0
  137. portal/static/portal/img/long_europe_map.png +0 -0
  138. portal/static/portal/img/python_den.png +0 -0
  139. portal/static/portal/img/python_den_banner.svg +26 -0
  140. portal/static/portal/img/rapid_router_landing_hero.png +0 -0
  141. portal/static/portal/img/rr_advanced.png +0 -0
  142. portal/static/portal/img/ten_year_map_pin.svg +1 -0
  143. portal/static/portal/img/thumbnail_educate_rapid_router.png +0 -0
  144. portal/static/portal/img/thumbnail_educate_resources.png +0 -0
  145. portal/static/portal/img/thumbnail_play_rapid_router.png +0 -0
  146. portal/static/portal/img/thumbnail_python_den.png +0 -0
  147. portal/static/portal/img/twitter.png +0 -0
  148. portal/static/portal/js/carouselCards.js +25 -0
  149. portal/static/portal/js/common.js +96 -1
  150. portal/static/portal/js/independentLogin.js +16 -0
  151. portal/static/portal/js/independentRegistration.js +86 -0
  152. portal/static/portal/js/levelControl.js +77 -0
  153. portal/static/portal/js/lib/jquery.min.js +2 -0
  154. portal/static/portal/js/organisation_manage.js +142 -14
  155. portal/static/portal/js/passwordStrength.js +154 -64
  156. portal/static/portal/js/resetPassword.js +23 -0
  157. portal/static/portal/js/riveted.min.js +238 -239
  158. portal/static/portal/js/school.js +13 -0
  159. portal/static/portal/js/studentLogin.js +16 -0
  160. portal/static/portal/js/teacherEditStudent.js +23 -0
  161. portal/static/portal/js/teacherLogin.js +16 -0
  162. portal/static/portal/js/tenYearMap.js +14 -0
  163. portal/static/portal/sass/colorbox.scss +0 -1
  164. portal/static/portal/sass/modules/_colours.scss +1 -0
  165. portal/static/portal/sass/modules/_levels.scss +1 -1
  166. portal/static/portal/sass/modules/_mixins.scss +21 -0
  167. portal/static/portal/sass/partials/_banners.scss +4 -177
  168. portal/static/portal/sass/partials/_buttons.scss +12 -15
  169. portal/static/portal/sass/partials/_carousel.scss +129 -0
  170. portal/static/portal/sass/partials/_footer.scss +21 -22
  171. portal/static/portal/sass/partials/_forms.scss +60 -5
  172. portal/static/portal/sass/partials/_grids.scss +34 -61
  173. portal/static/portal/sass/partials/_header.scss +28 -20
  174. portal/static/portal/sass/partials/_images.scss +292 -39
  175. portal/static/portal/sass/partials/_popup.scss +18 -15
  176. portal/static/portal/sass/partials/_tables.scss +12 -20
  177. portal/static/portal/sass/partials/_text.scss +6 -10
  178. portal/static/portal/sass/styles.scss +0 -1
  179. portal/static/portal/video/code for life .pdf +0 -0
  180. portal/strings/about.py +5 -0
  181. portal/strings/coding_club.py +9 -0
  182. portal/strings/play.py +6 -5
  183. portal/strings/teach.py +1 -1
  184. portal/strings/teacher_resources.py +2 -8
  185. portal/strings/ten_year_map.py +13 -0
  186. portal/templates/403.html +2 -2
  187. portal/templates/404.html +1 -1
  188. portal/templates/500.html +2 -2
  189. portal/templates/{captcha → django_recaptcha}/includes/js_v2_invisible.html +3 -3
  190. portal/templates/{captcha → django_recaptcha}/widget_v2_invisible.html +2 -2
  191. portal/templates/email.html +4 -2
  192. portal/templates/maintenance.html +34 -0
  193. portal/templates/portal/about.html +94 -62
  194. portal/templates/portal/base.html +176 -152
  195. portal/templates/portal/coding_club.html +100 -0
  196. portal/templates/portal/contribute.html +56 -52
  197. portal/templates/portal/email_invitation_sent.html +1 -1
  198. portal/templates/portal/email_style_template.html +374 -0
  199. portal/templates/portal/email_verification_failed.html +1 -1
  200. portal/templates/portal/email_verification_needed.html +9 -9
  201. portal/templates/portal/form_shapes.html +20 -8
  202. portal/templates/portal/getinvolved.html +6 -6
  203. portal/templates/portal/home.html +35 -10
  204. portal/templates/portal/home_learning.html +19 -19
  205. portal/templates/portal/locked_out.html +0 -1
  206. portal/templates/portal/locked_out_school_student.html +16 -0
  207. portal/templates/portal/login/independent_student.html +31 -15
  208. portal/templates/portal/login/student.html +10 -7
  209. portal/templates/portal/login/student_class_code.html +7 -4
  210. portal/templates/portal/login/teacher.html +34 -17
  211. portal/templates/portal/partials/banner.html +18 -4
  212. portal/templates/portal/partials/benefits.html +1 -1
  213. portal/templates/portal/partials/card_list.html +34 -24
  214. portal/templates/portal/partials/character_list.html +5 -5
  215. portal/templates/portal/partials/cookie_list.html +161 -0
  216. portal/templates/portal/partials/delete_popup.html +18 -0
  217. portal/templates/portal/partials/footer.html +57 -26
  218. portal/templates/portal/partials/header.html +118 -117
  219. portal/templates/portal/partials/hero_card.html +4 -3
  220. portal/templates/portal/partials/info_popup.html +3 -3
  221. portal/templates/portal/partials/invite_admin_teacher.html +23 -0
  222. portal/templates/portal/partials/popup.html +7 -2
  223. portal/templates/portal/partials/register_newsletter_tickbox.html +2 -5
  224. portal/templates/portal/partials/screentime_popup.html +14 -0
  225. portal/templates/portal/partials/service_unavailable_popup.html +17 -0
  226. portal/templates/portal/partials/session_popup.html +19 -0
  227. portal/templates/portal/play/student_dashboard.html +42 -29
  228. portal/templates/portal/play/student_edit_account.html +64 -9
  229. portal/templates/portal/play.html +61 -41
  230. portal/templates/portal/privacy_notice.html +697 -0
  231. portal/templates/portal/register.html +122 -92
  232. portal/templates/portal/reset_password.html +20 -40
  233. portal/templates/portal/reset_password_confirm.html +9 -4
  234. portal/templates/portal/reset_password_email_sent.html +15 -13
  235. portal/templates/portal/teach/base_registering.html +1 -1
  236. portal/templates/portal/teach/class.html +4 -6
  237. portal/templates/portal/teach/dashboard.html +212 -117
  238. portal/templates/portal/teach/invited.html +90 -0
  239. portal/templates/portal/teach/onboarding_classes.html +5 -3
  240. portal/templates/portal/teach/onboarding_print.html +1 -1
  241. portal/templates/portal/teach/onboarding_school.html +26 -139
  242. portal/templates/portal/teach/onboarding_students.html +1 -1
  243. portal/templates/portal/teach/teacher_dismiss_students.html +73 -55
  244. portal/templates/portal/teach/teacher_edit_class.html +168 -11
  245. portal/templates/portal/teach/teacher_edit_student.html +12 -5
  246. portal/templates/portal/teach/teacher_move_all_classes.html +25 -38
  247. portal/templates/portal/teach/teacher_move_students_to_class.html +1 -1
  248. portal/templates/portal/teach.html +61 -42
  249. portal/templates/portal/ten_year_map.html +147 -0
  250. portal/templates/portal/terms.html +191 -42
  251. portal/templates/two_factor/core/login.html +71 -59
  252. portal/templates/two_factor/core/setup.html +58 -49
  253. portal/templates/two_factor/profile/disable.html +1 -1
  254. portal/templates/two_factor/profile/profile.html +35 -17
  255. portal/templatetags/app_tags.py +59 -84
  256. portal/templatetags/card_list_tags.py +0 -4
  257. portal/tests/base_test.py +14 -3
  258. portal/tests/conftest.py +0 -15
  259. portal/tests/migrations/test_migration_make_portaladmin_teacher.py +2 -6
  260. portal/tests/migrations/test_migration_preview_users.py +3 -9
  261. portal/tests/migrations/test_migration_remove_guardian.py +1 -3
  262. portal/tests/migrations/test_migration_use_common_models.py +2 -6
  263. portal/tests/migrations/test_migration_verify_portaladmin.py +1 -3
  264. portal/tests/pageObjects/portal/admin/admin_base_page.py +0 -21
  265. portal/tests/pageObjects/portal/base_page.py +16 -26
  266. portal/tests/pageObjects/portal/email_verification_needed_page.py +3 -2
  267. portal/tests/pageObjects/portal/game_page.py +12 -19
  268. portal/tests/pageObjects/portal/home_page.py +13 -15
  269. portal/tests/pageObjects/portal/independent_login_page.py +13 -17
  270. portal/tests/pageObjects/portal/password_reset_form_page.py +20 -4
  271. portal/tests/pageObjects/portal/password_reset_page.py +25 -0
  272. portal/tests/pageObjects/portal/play/account_page.py +18 -27
  273. portal/tests/pageObjects/portal/play/dashboard_page.py +4 -4
  274. portal/tests/pageObjects/portal/play/join_school_or_club_page.py +8 -10
  275. portal/tests/pageObjects/portal/play/play_base_page.py +5 -3
  276. portal/tests/pageObjects/portal/signup_page.py +28 -59
  277. portal/tests/pageObjects/portal/student_login_class_code.py +6 -9
  278. portal/tests/pageObjects/portal/student_login_page.py +6 -8
  279. portal/tests/pageObjects/portal/teach/add_independent_student_to_class_page.py +3 -3
  280. portal/tests/pageObjects/portal/teach/added_independent_student_to_class_page.py +3 -1
  281. portal/tests/pageObjects/portal/teach/class_page.py +36 -13
  282. portal/tests/pageObjects/portal/teach/dashboard_page.py +43 -84
  283. portal/tests/pageObjects/portal/teach/dismiss_students_page.py +7 -5
  284. portal/tests/pageObjects/portal/teach/edit_student_page.py +10 -8
  285. portal/tests/pageObjects/portal/teach/move_class_page.py +5 -10
  286. portal/tests/pageObjects/portal/teach/move_classes_page.py +4 -2
  287. portal/tests/pageObjects/portal/teach/move_students_disambiguate_page.py +4 -2
  288. portal/tests/pageObjects/portal/teach/move_students_page.py +6 -13
  289. portal/tests/pageObjects/portal/teach/onboarding_classes_page.py +5 -3
  290. portal/tests/pageObjects/portal/teach/onboarding_organisation_page.py +11 -49
  291. portal/tests/pageObjects/portal/teach/onboarding_student_list_page.py +7 -12
  292. portal/tests/pageObjects/portal/teach/onboarding_students_page.py +4 -27
  293. portal/tests/pageObjects/portal/teach/teach_base_page.py +6 -4
  294. portal/tests/pageObjects/portal/teacher_login_page.py +10 -16
  295. portal/tests/selenium_test_case.py +3 -43
  296. portal/tests/snapshots/snap_test_partials.py +11 -165
  297. portal/tests/test_2FA.py +15 -33
  298. portal/tests/test_admin.py +15 -97
  299. portal/tests/test_api.py +212 -91
  300. portal/tests/test_captcha_forms.py +2 -2
  301. portal/tests/test_class.py +374 -24
  302. portal/tests/test_emails.py +83 -20
  303. portal/tests/{test_newsletter_footer.py → test_global_forms.py} +5 -5
  304. portal/tests/test_helper_methods.py +30 -0
  305. portal/tests/test_independent_student.py +255 -144
  306. portal/tests/test_invite_teacher.py +318 -10
  307. portal/tests/test_middleware.py +96 -9
  308. portal/tests/test_organisation.py +78 -262
  309. portal/tests/test_partials.py +0 -88
  310. portal/tests/test_ratelimit.py +218 -36
  311. portal/tests/test_school_student.py +35 -40
  312. portal/tests/test_security.py +12 -31
  313. portal/tests/test_teacher.py +425 -325
  314. portal/tests/test_teacher_student.py +103 -91
  315. portal/tests/test_views.py +900 -76
  316. portal/tests/utils/classes.py +2 -2
  317. portal/tests/utils/messages.py +13 -28
  318. portal/urls.py +235 -166
  319. portal/views/admin.py +0 -332
  320. portal/views/api.py +82 -48
  321. portal/views/cron/__init__.py +1 -0
  322. portal/views/cron/user.py +322 -0
  323. portal/views/dotmailer.py +9 -1
  324. portal/views/email.py +33 -77
  325. portal/views/google_analytics.py +28 -0
  326. portal/views/home.py +126 -97
  327. portal/views/legal.py +13 -0
  328. portal/views/login/independent_student.py +5 -5
  329. portal/views/login/student.py +51 -14
  330. portal/views/login/teacher.py +2 -6
  331. portal/views/organisation.py +20 -189
  332. portal/views/registration.py +97 -17
  333. portal/views/student/edit_account_details.py +99 -72
  334. portal/views/student/play.py +81 -62
  335. portal/views/teacher/dashboard.py +421 -149
  336. portal/views/teacher/teach.py +226 -177
  337. portal/views/two_factor/core.py +22 -19
  338. portal/views/two_factor/profile.py +2 -2
  339. codeforlife_portal-5.33.5.dist-info/LICENSE.md +0 -577
  340. codeforlife_portal-5.33.5.dist-info/METADATA +0 -38
  341. deploy/permissions.py +0 -2
  342. example_project/manage.py +0 -10
  343. portal/autoconfig.py +0 -141
  344. portal/csp_config.py +0 -60
  345. portal/forms/add_game.py +0 -33
  346. portal/helpers/location.py +0 -121
  347. portal/static/portal/img/kurono_hero.jpg +0 -0
  348. portal/static/portal/img/kurono_landing_hero.png +0 -0
  349. portal/static/portal/img/kurono_logo.svg +0 -1
  350. portal/static/portal/img/kurono_logo_grey_background.svg +0 -1
  351. portal/static/portal/img/kurono_logo_mark.svg +0 -1
  352. portal/static/portal/img/kurono_resources_hero.jpg +0 -0
  353. portal/static/portal/img/kurono_story.png +0 -0
  354. portal/static/portal/img/ocado-swirl.svg +0 -22
  355. portal/static/portal/img/thumbnail_educate_kurono.png +0 -0
  356. portal/static/portal/img/thumbnail_educate_resources_and_progress_tracking.png +0 -0
  357. portal/static/portal/img/thumbnail_kurono_resources.png +0 -0
  358. portal/static/portal/img/thumbnail_play_kurono.png +0 -0
  359. portal/static/portal/img/x_close_video.png +0 -0
  360. portal/static/portal/js/aimmoGame.js +0 -106
  361. portal/static/portal/js/deleteWorkspaces.js +0 -14
  362. portal/static/portal/js/fuzzySchoolLookup.js +0 -46
  363. portal/static/portal/js/lib/jquery-3.5.1.min.js +0 -2
  364. portal/static/portal/js/lib/jquery-ui-1.12.1.min.js +0 -13
  365. portal/static/portal/sass/partials/_videos.scss +0 -10
  366. portal/static/portal/video/aimmo_play_now_background_video.mp4 +0 -0
  367. portal/strings/student_aimmo_dashboard.py +0 -6
  368. portal/templates/portal/admin/aggregated_data.html +0 -35
  369. portal/templates/portal/admin/map.html +0 -70
  370. portal/templates/portal/mouseflow.html +0 -9
  371. portal/templates/portal/partials/aimmo_games_table.html +0 -83
  372. portal/templates/portal/partials/register_over_required_age_tickbox.html +0 -9
  373. portal/templates/portal/play/independent_student_dashboard.html +0 -64
  374. portal/templates/portal/play/student_aimmo_dashboard.html +0 -63
  375. portal/templates/portal/privacy_policy.html +0 -483
  376. portal/templates/portal/reset_password_email.html +0 -9
  377. portal/templates/portal/teach/invite.html +0 -25
  378. portal/templates/portal/teach/teacher_aimmo_dashboard.html +0 -95
  379. portal/templates/portal/teach/teacher_resources.html +0 -68
  380. portal/templatetags/character_list_tags.py +0 -16
  381. portal/tests/pageObjects/portal/kurono_teacher_dashboard_page.py +0 -49
  382. portal/tests/pageObjects/portal/student_password_reset_form_page.py +0 -23
  383. portal/tests/pageObjects/portal/teach/onboarding_revoke_request_page.py +0 -20
  384. portal/tests/pageObjects/portal/teacher_password_reset_form_page.py +0 -23
  385. portal/tests/test_aimmo_dashboards.py +0 -172
  386. portal/tests/test_location.py +0 -217
  387. portal/tests/utils/aimmo_games.py +0 -30
  388. portal/views/aimmo/dashboard.py +0 -119
  389. portal/views/privacy_policy.py +0 -9
  390. portal/views/teacher/teacher_resources.py +0 -42
  391. {portal/views/aimmo → cfl_common}/__init__.py +0 -0
portal/urls.py CHANGED
@@ -1,7 +1,6 @@
1
- from aimmo.urls import HOMEPAGE_REGEX
2
1
  from common.permissions import teacher_verified
3
- from django.conf.urls import include, url
4
- from django.urls import reverse_lazy
2
+ from django.http import HttpResponse
3
+ from django.urls import include, path, re_path
5
4
  from django.views.generic import RedirectView
6
5
  from django.views.generic.base import TemplateView
7
6
  from django.views.i18n import JavaScriptCatalog
@@ -15,82 +14,82 @@ from two_factor.views import (
15
14
 
16
15
  from portal.helpers.decorators import ratelimit
17
16
  from portal.helpers.ratelimit import (
18
- RATELIMIT_GROUP,
17
+ RATELIMIT_LOGIN_GROUP,
18
+ RATELIMIT_LOGIN_RATE,
19
+ RATELIMIT_LOGIN_RATE_SCHOOL_STUDENT,
19
20
  RATELIMIT_METHOD,
20
- RATELIMIT_RATE,
21
+ school_student_key,
21
22
  )
22
- from portal.helpers.regexes import ACCESS_CODE_REGEX
23
- from portal.views.about import about, getinvolved, contribute
24
- from portal.views.admin import (
25
- AdminChangePasswordDoneView,
26
- AdminChangePasswordView,
27
- aggregated_data,
28
- schools_map,
29
- )
30
- from portal.views.aimmo.dashboard import StudentAimmoDashboard, TeacherAimmoDashboard
23
+ from portal.helpers.regexes import ACCESS_CODE_REGEX, JWT_REGEX
24
+ from portal.views import cron, google_analytics
25
+ from portal.views.about import about, contribute, getinvolved
26
+ from portal.views.admin import AdminChangePasswordDoneView, AdminChangePasswordView
31
27
  from portal.views.api import (
28
+ AnonymiseOrphanSchoolsView,
32
29
  InactiveUsersView,
33
- DuplicateIndyTeacherView,
30
+ RemoveFakeAccounts,
34
31
  last_connected_since,
35
32
  number_users_per_country,
36
33
  registered_users,
37
34
  )
38
35
  from portal.views.dotmailer import dotmailer_consent_form, process_newsletter_form
39
- from portal.views.email import send_new_users_report, verify_email
36
+ from portal.views.email import verify_email
40
37
  from portal.views.home import (
38
+ coding_club,
41
39
  home,
42
40
  home_learning,
43
41
  logout_view,
44
42
  register_view,
43
+ reset_screentime_warning,
44
+ ten_year_map_page,
45
45
  )
46
+ from portal.views.legal import privacy_notice, terms
46
47
  from portal.views.login import old_login_form_redirect
47
48
  from portal.views.login.independent_student import IndependentStudentLoginView
48
49
  from portal.views.login.student import (
49
- StudentLoginView,
50
50
  StudentClassCodeView,
51
+ StudentLoginView,
51
52
  student_direct_login,
52
53
  )
53
54
  from portal.views.login.teacher import TeacherLoginView
54
- from portal.views.organisation import (
55
- OrganisationFuzzyLookup,
56
- organisation_leave,
57
- organisation_manage,
58
- )
55
+ from portal.views.organisation import organisation_leave, organisation_manage
59
56
  from portal.views.play_landing_page import play_landing_page
60
- from portal.views.privacy_policy import privacy_policy
61
57
  from portal.views.registration import (
58
+ delete_account,
62
59
  password_reset_check_and_confirm,
63
60
  password_reset_done,
64
61
  student_password_reset,
65
62
  teacher_password_reset,
66
63
  )
67
64
  from portal.views.student.edit_account_details import (
68
- IndependentStudentEditAccountView,
69
65
  SchoolStudentEditAccountView,
66
+ independentStudentEditAccountView,
70
67
  student_edit_account,
71
68
  )
72
69
  from portal.views.student.play import (
73
- SchoolStudentDashboard,
74
70
  IndependentStudentDashboard,
71
+ SchoolStudentDashboard,
75
72
  student_join_organisation,
76
73
  )
77
74
  from portal.views.teach import teach
78
75
  from portal.views.teacher.dashboard import (
79
76
  dashboard_manage,
80
- organisation_allow_join,
81
- organisation_deny_join,
77
+ delete_teacher_invite,
78
+ invite_toggle_admin,
79
+ invited_teacher,
82
80
  organisation_kick,
83
81
  organisation_toggle_admin,
82
+ resend_invite_teacher,
84
83
  teacher_accept_student_request,
85
84
  teacher_disable_2FA,
86
85
  teacher_reject_student_request,
87
86
  )
88
87
  from portal.views.teacher.teach import (
89
- invite_teacher,
90
88
  teacher_class_password_reset,
91
89
  teacher_delete_class,
92
90
  teacher_delete_students,
93
91
  teacher_dismiss_students,
92
+ teacher_download_csv,
94
93
  teacher_edit_class,
95
94
  teacher_edit_student,
96
95
  teacher_move_students,
@@ -98,39 +97,32 @@ from portal.views.teacher.teach import (
98
97
  teacher_onboarding_create_class,
99
98
  teacher_onboarding_edit_class,
100
99
  teacher_print_reminder_cards,
101
- teacher_download_csv,
102
100
  teacher_view_class,
103
101
  )
104
- from portal.views.teacher.teacher_resources import (
105
- teacher_kurono_resources,
106
- teacher_rapid_router_resources,
107
- kurono_teaching_packs,
108
- materials,
109
- )
110
102
  from portal.views.two_factor.core import CustomSetupView
111
103
  from portal.views.two_factor.profile import CustomDisableView
112
104
 
113
105
  js_info_dict = {"packages": ("conf.locale",)}
114
106
 
115
107
  two_factor_patterns = [
116
- url(r"^account/two_factor/setup/$", CustomSetupView.as_view(), name="setup"),
117
- url(r"^account/two_factor/qrcode/$", QRGeneratorView.as_view(), name="qr"),
118
- url(
108
+ re_path(r"^account/two_factor/setup/$", CustomSetupView.as_view(), name="setup"),
109
+ re_path(r"^account/two_factor/qrcode/$", QRGeneratorView.as_view(), name="qr"),
110
+ re_path(
119
111
  r"^account/two_factor/setup/complete/$",
120
112
  SetupCompleteView.as_view(),
121
113
  name="setup_complete",
122
114
  ),
123
- url(
115
+ re_path(
124
116
  r"^account/two_factor/backup/tokens/$",
125
117
  teacher_verified(BackupTokensView.as_view()),
126
118
  name="backup_tokens",
127
119
  ),
128
- url(
120
+ re_path(
129
121
  r"^account/two_factor/$",
130
122
  teacher_verified(ProfileView.as_view()),
131
123
  name="profile",
132
124
  ),
133
- url(
125
+ re_path(
134
126
  r"^account/two_factor/disable/$",
135
127
  teacher_verified(CustomDisableView.as_view()),
136
128
  name="disable",
@@ -139,308 +131,373 @@ two_factor_patterns = [
139
131
 
140
132
 
141
133
  urlpatterns = [
142
- url(HOMEPAGE_REGEX, include("aimmo.urls")),
143
- url(
144
- r"^teach/kurono/dashboard/$",
145
- TeacherAimmoDashboard.as_view(),
146
- name="teacher_aimmo_dashboard",
147
- ),
148
- url(
149
- r"^play/kurono/dashboard/$",
150
- StudentAimmoDashboard.as_view(),
151
- name="student_aimmo_dashboard",
152
- ),
153
- url(
134
+ path(
135
+ "google-analytics/collect/",
136
+ google_analytics.collect,
137
+ name="collect-google-analytics",
138
+ ),
139
+ path(
140
+ "cron/",
141
+ include(
142
+ [
143
+ path(
144
+ "user/",
145
+ include(
146
+ [
147
+ path(
148
+ "unverified/send-first-reminder/",
149
+ cron.user.FirstVerifyEmailReminderView.as_view(),
150
+ name="first-verify-email-reminder",
151
+ ),
152
+ path(
153
+ "unverified/send-second-reminder/",
154
+ cron.user.SecondVerifyEmailReminderView.as_view(),
155
+ name="second-verify-email-reminder",
156
+ ),
157
+ path(
158
+ "unverified/delete/",
159
+ cron.user.AnonymiseUnverifiedAccounts.as_view(),
160
+ name="anonymise-unverified-accounts",
161
+ ),
162
+ path(
163
+ "inactive/send-first-reminder/",
164
+ cron.user.FirstInactivityReminderView.as_view(),
165
+ name="first-inactivity-reminder",
166
+ ),
167
+ path(
168
+ "inactive/send-second-reminder/",
169
+ cron.user.SecondInactivityReminderView.as_view(),
170
+ name="second-inactivity-reminder",
171
+ ),
172
+ path(
173
+ "inactive/send-final-reminder/",
174
+ cron.user.FinalInactivityReminderView.as_view(),
175
+ name="final-inactivity-reminder",
176
+ ),
177
+ ]
178
+ ),
179
+ ),
180
+ ]
181
+ ),
182
+ ),
183
+ re_path(
154
184
  r"^favicon\.ico$",
155
185
  RedirectView.as_view(url="/static/portal/img/favicon.ico", permanent=True),
156
186
  ),
157
- url(
187
+ re_path(
158
188
  r"^administration/password_change/$",
159
189
  AdminChangePasswordView.as_view(),
160
190
  name="administration_password_change",
161
191
  ),
162
- url(
192
+ re_path(
163
193
  r"^administration/password_change_done/$",
164
194
  AdminChangePasswordDoneView.as_view(),
165
195
  name="administration_password_change_done",
166
196
  ),
167
- url(
168
- r"^admin/$",
169
- RedirectView.as_view(url=reverse_lazy("aggregated_data"), permanent=True),
170
- ),
171
- url(r"^admin/map/$", schools_map, name="map"),
172
- url(r"^admin/data/$", aggregated_data, name="aggregated_data"),
173
- url(r"^mail/weekly", send_new_users_report, name="send_new_users_report"),
174
- url(r"^users/inactive/", InactiveUsersView.as_view(), name="inactive_users"),
175
- url(
176
- r"^indycleanup/",
177
- DuplicateIndyTeacherView.as_view(),
178
- name="teacher_indy_cleanup",
179
- ),
180
- url(
197
+ re_path(r"^users/inactive/", InactiveUsersView.as_view(), name="inactive_users"),
198
+ re_path(
181
199
  r"^locked_out/$",
182
200
  TemplateView.as_view(template_name="portal/locked_out.html"),
183
201
  name="locked_out",
184
202
  ),
185
- url(r"^", include((two_factor_patterns, "two_factor"), namespace="two_factor")),
186
- url(r"^i18n/", include("django.conf.urls.i18n")),
187
- url(r"^jsi18n/$", JavaScriptCatalog.as_view(), js_info_dict),
188
- url(r"^(?P<levelName>[A-Z0-9]+)/$", play_default_level, name="play_default_level"),
189
- url(r"^$", home, name="home"),
190
- url(r"^home-learning", home_learning, name="home-learning"),
191
- url(r"^register_form", register_view, name="register"),
192
- url(
203
+ re_path(
204
+ r"^",
205
+ include((two_factor_patterns, "two_factor"), namespace="two_factor"),
206
+ ),
207
+ re_path(r"^i18n/", include("django.conf.urls.i18n")),
208
+ re_path(r"^jsi18n/$", JavaScriptCatalog.as_view(), js_info_dict),
209
+ re_path(
210
+ r"^(?P<level_name>[A-Z0-9]+)/$",
211
+ play_default_level,
212
+ name="play_default_level",
213
+ ),
214
+ re_path(r"^$", home, name="home"),
215
+ re_path(r"^home-learning", home_learning, name="home-learning"),
216
+ re_path(r"^register_form", register_view, name="register"),
217
+ re_path(
193
218
  r"^login/teacher/$",
194
219
  # The ratelimit decorator checks how often a POST request is performed on that view.
195
220
  # It checks against the username value specifically. If the number of requests
196
221
  # exceeds the specified rate, then the user will be blocked (if block = True).
197
222
  ratelimit(
198
- group=RATELIMIT_GROUP,
223
+ group=RATELIMIT_LOGIN_GROUP,
199
224
  key="post:auth-username",
200
225
  method=RATELIMIT_METHOD,
201
- rate=RATELIMIT_RATE,
226
+ rate=RATELIMIT_LOGIN_RATE,
202
227
  block=True,
203
228
  )(TeacherLoginView.as_view()),
204
229
  name="teacher_login",
205
230
  ),
206
- url(
231
+ re_path(
207
232
  rf"^login/student/(?P<access_code>{ACCESS_CODE_REGEX})/(?:(?P<login_type>classform)/)?$",
208
- StudentLoginView.as_view(),
233
+ ratelimit(
234
+ group=RATELIMIT_LOGIN_GROUP,
235
+ key=school_student_key,
236
+ method=RATELIMIT_METHOD,
237
+ rate=RATELIMIT_LOGIN_RATE_SCHOOL_STUDENT,
238
+ block=True,
239
+ is_teacher=False,
240
+ )(StudentLoginView.as_view()),
209
241
  name="student_login",
210
242
  ),
211
- url(
243
+ re_path(
212
244
  r"^login/student/$",
213
245
  StudentClassCodeView.as_view(),
214
246
  name="student_login_access_code",
215
247
  ),
216
- url(
248
+ re_path(
217
249
  r"^u/(?P<user_id>[0-9]+)/(?P<login_id>[a-z0-9]+)/$",
218
250
  student_direct_login,
219
251
  name="student_direct_login",
220
252
  ),
221
- url(
253
+ re_path(
222
254
  r"^login/independent/$",
223
255
  ratelimit(
224
- group=RATELIMIT_GROUP,
256
+ group=RATELIMIT_LOGIN_GROUP,
225
257
  key="post:username",
226
258
  method=RATELIMIT_METHOD,
227
- rate=RATELIMIT_RATE,
259
+ rate=RATELIMIT_LOGIN_RATE,
228
260
  block=True,
229
261
  is_teacher=False,
230
262
  )(IndependentStudentLoginView.as_view()),
231
263
  name="independent_student_login",
232
264
  ),
233
- url(r"^login_form", old_login_form_redirect, name="old_login_form"),
234
- url(r"^logout/$", logout_view, name="logout_view"),
235
- url(r"^news_signup/$", process_newsletter_form, name="process_newsletter_form"),
236
- url(r"^consent_form/$", dotmailer_consent_form, name="consent_form"),
237
- url(
265
+ re_path(r"^login_form", old_login_form_redirect, name="old_login_form"),
266
+ re_path(r"^logout/$", logout_view, name="logout_view"),
267
+ re_path(
268
+ r"^news_signup/$",
269
+ process_newsletter_form,
270
+ name="process_newsletter_form",
271
+ ),
272
+ re_path(r"^consent_form/$", dotmailer_consent_form, name="consent_form"),
273
+ re_path(
238
274
  r"^verify_email/$",
239
275
  TemplateView.as_view(template_name="portal/email_verification_needed.html"),
240
276
  name="email_verification",
241
277
  ),
242
- url(r"^verify_email/(?P<token>[0-9a-f]+)/$", verify_email, name="verify_email"),
243
- url(
278
+ re_path(
279
+ rf"^verify_email/(?P<token>{JWT_REGEX})/$",
280
+ verify_email,
281
+ name="verify_email",
282
+ ),
283
+ re_path(
244
284
  r"^user/password/reset/student/$",
245
285
  student_password_reset,
246
286
  name="student_password_reset",
247
287
  ),
248
- url(
288
+ re_path(
249
289
  r"^user/password/reset/teacher/$",
250
290
  teacher_password_reset,
251
291
  name="teacher_password_reset",
252
292
  ),
253
- url(
293
+ re_path(
254
294
  r"^user/password/reset/done/$",
255
295
  password_reset_done,
256
296
  name="reset_password_email_sent",
257
297
  ),
258
- url(
298
+ re_path(
259
299
  r"^user/password/reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$",
260
300
  password_reset_check_and_confirm,
261
301
  name="password_reset_check_and_confirm",
262
302
  ),
263
- url(
303
+ re_path(
304
+ r"^user/reset_screentime_warning/$",
305
+ reset_screentime_warning,
306
+ name="reset_screentime_warning",
307
+ ),
308
+ re_path(
309
+ r"^user/reset_session_time/$",
310
+ lambda _: HttpResponse(status=204),
311
+ name="reset_session_time",
312
+ ),
313
+ re_path(
264
314
  r"^teacher/password/reset/complete/$",
265
315
  TemplateView.as_view(template_name="portal/reset_password_done.html"),
266
316
  name="password_reset_complete",
267
317
  ),
268
- url(r"^teach/$", teach, name="teach"),
269
- url(
270
- r"^teach/fuzzy_lookup/$",
271
- OrganisationFuzzyLookup.as_view(),
272
- name="organisation_fuzzy_lookup",
273
- ),
274
- url(
318
+ re_path(r"^teach/$", teach, name="teach"),
319
+ re_path(
275
320
  r"^teach/onboarding-organisation/$",
276
321
  organisation_manage,
277
322
  name="onboarding-organisation",
278
323
  ),
279
- url(
324
+ re_path(
280
325
  r"^teach/onboarding-classes",
281
326
  teacher_onboarding_create_class,
282
327
  name="onboarding-classes",
283
328
  ),
284
- url(
329
+ re_path(
285
330
  rf"^teach/onboarding-class/(?P<access_code>{ACCESS_CODE_REGEX})$",
286
331
  teacher_onboarding_edit_class,
287
332
  name="onboarding-class",
288
333
  ),
289
- url(
334
+ re_path(
290
335
  rf"^teach/onboarding-class/(?P<access_code>{ACCESS_CODE_REGEX})/print_reminder_cards/$",
291
336
  teacher_print_reminder_cards,
292
337
  name="teacher_print_reminder_cards",
293
338
  ),
294
- url(
339
+ re_path(
295
340
  rf"^teach/onboarding-class/(?P<access_code>{ACCESS_CODE_REGEX})/download_csv/$",
296
341
  teacher_download_csv,
297
342
  name="teacher_download_csv",
298
343
  ),
299
- url(r"^teach/invite", invite_teacher, name="invite_teacher"),
300
- url(r"^play/$", play_landing_page, name="play"),
301
- url(r"^play/details/$", SchoolStudentDashboard.as_view(), name="student_details"),
302
- url(
344
+ re_path(
345
+ r"^invited_teacher/(?P<token>[0-9a-f]+)/$",
346
+ invited_teacher,
347
+ name="invited_teacher",
348
+ ),
349
+ re_path(r"^play/$", play_landing_page, name="play"),
350
+ re_path(
351
+ r"^play/details/$",
352
+ SchoolStudentDashboard.as_view(),
353
+ name="student_details",
354
+ ),
355
+ re_path(
303
356
  r"^play/details/independent$",
304
357
  IndependentStudentDashboard.as_view(),
305
358
  name="independent_student_details",
306
359
  ),
307
- url(r"^play/account/$", student_edit_account, name="student_edit_account"),
308
- url(
360
+ re_path(r"^play/account/$", student_edit_account, name="student_edit_account"),
361
+ re_path(
309
362
  r"^play/account/independent/$",
310
363
  ratelimit(
311
- group=RATELIMIT_GROUP,
364
+ group=RATELIMIT_LOGIN_GROUP,
312
365
  key="post:name",
313
366
  method=RATELIMIT_METHOD,
314
- rate=RATELIMIT_RATE,
367
+ rate=RATELIMIT_LOGIN_RATE,
315
368
  block=True,
316
369
  is_teacher=False,
317
- )(IndependentStudentEditAccountView.as_view()),
370
+ )(independentStudentEditAccountView),
318
371
  name="independent_edit_account",
319
372
  ),
320
- url(
373
+ re_path(
321
374
  r"^play/account/school_student/$",
322
375
  SchoolStudentEditAccountView.as_view(),
323
376
  name="school_student_edit_account",
324
377
  ),
325
- url(r"^play/join/$", student_join_organisation, name="student_join_organisation"),
326
- url(r"^about", about, name="about"),
327
- url(r"^getinvolved", getinvolved, name="getinvolved"),
328
- url(r"^contribute", contribute, name="contribute"),
329
- url(
330
- r"^terms", TemplateView.as_view(template_name="portal/terms.html"), name="terms"
331
- ),
332
- url(r"^privacy-policy/$", privacy_policy, name="privacy_policy"),
333
- url(r"^teach/materials/$", materials, name="materials"),
334
- url(r"^teach/kurono_teaching_packs$", kurono_teaching_packs, name="kurono_packs"),
335
- url(
336
- r"^teach/resources/$", teacher_rapid_router_resources, name="teaching_resources"
337
- ),
338
- url(
339
- r"^teach/kurono_resources/$",
340
- teacher_kurono_resources,
341
- name="kurono_teaching_resources",
342
- ),
343
- url(r"^teach/dashboard/$", dashboard_manage, name="dashboard"),
344
- url(
378
+ re_path(
379
+ r"^play/join/$",
380
+ student_join_organisation,
381
+ name="student_join_organisation",
382
+ ),
383
+ re_path(r"^about", about, name="about"),
384
+ re_path(r"^getinvolved", getinvolved, name="getinvolved"),
385
+ re_path(r"^contribute", contribute, name="contribute"),
386
+ re_path(r"^terms", terms, name="terms"),
387
+ re_path(r"^privacy-notice/$", privacy_notice, name="privacy_notice"),
388
+ re_path(r"^privacy-policy/$", privacy_notice, name="privacy_policy"), # Keeping this to route from old URL
389
+ re_path(r"^teach/dashboard/$", dashboard_manage, name="dashboard"),
390
+ re_path(
345
391
  r"^teach/dashboard/kick/(?P<pk>[0-9]+)/$",
346
392
  organisation_kick,
347
393
  name="organisation_kick",
348
394
  ),
349
- url(
395
+ re_path(
350
396
  r"^teach/dashboard/toggle_admin/(?P<pk>[0-9]+)/$",
351
397
  organisation_toggle_admin,
352
398
  name="organisation_toggle_admin",
353
399
  ),
354
- url(
400
+ re_path(
355
401
  r"^teach/dashboard/disable_2FA/(?P<pk>[0-9]+)/$",
356
402
  teacher_disable_2FA,
357
403
  name="teacher_disable_2FA",
358
404
  ),
359
- url(
360
- r"^teach/dashboard/allow_join/(?P<pk>[0-9]+)/$",
361
- organisation_allow_join,
362
- name="organisation_allow_join",
363
- ),
364
- url(
365
- r"^teach/dashboard/deny_join/(?P<pk>[0-9]+)/$",
366
- organisation_deny_join,
367
- name="organisation_deny_join",
368
- ),
369
- url(
405
+ re_path(
370
406
  r"^teach/dashboard/school/leave/$",
371
407
  organisation_leave,
372
408
  name="organisation_leave",
373
409
  ),
374
- url(
410
+ re_path(
375
411
  r"^teach/dashboard/student/accept/(?P<pk>[0-9]+)/$",
376
412
  teacher_accept_student_request,
377
413
  name="teacher_accept_student_request",
378
414
  ),
379
- url(
415
+ re_path(
380
416
  r"^teach/dashboard/student/reject/(?P<pk>[0-9]+)/$",
381
417
  teacher_reject_student_request,
382
418
  name="teacher_reject_student_request",
383
419
  ),
384
- url(
420
+ re_path(
385
421
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})$",
386
422
  teacher_view_class,
387
423
  name="view_class",
388
424
  ),
389
- url(
425
+ re_path(
390
426
  rf"^teach/class/delete/(?P<access_code>{ACCESS_CODE_REGEX})$",
391
427
  teacher_delete_class,
392
428
  name="teacher_delete_class",
393
429
  ),
394
- url(
430
+ re_path(
395
431
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/delete/$",
396
432
  teacher_delete_students,
397
433
  name="teacher_delete_students",
398
434
  ),
399
- url(
435
+ re_path(
400
436
  rf"^teach/class/edit/(?P<access_code>{ACCESS_CODE_REGEX})$",
401
437
  teacher_edit_class,
402
438
  name="teacher_edit_class",
403
439
  ),
404
- url(
440
+ re_path(
405
441
  r"^teach/class/student/edit/(?P<pk>[0-9]+)/$",
406
442
  teacher_edit_student,
407
443
  name="teacher_edit_student",
408
444
  ),
409
- url(
445
+ re_path(
410
446
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/password_reset/$",
411
447
  teacher_class_password_reset,
412
448
  name="teacher_class_password_reset",
413
449
  ),
414
- url(
450
+ re_path(
415
451
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/dismiss/$",
416
452
  teacher_dismiss_students,
417
453
  name="teacher_dismiss_students",
418
454
  ),
419
- url(
455
+ re_path(
420
456
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/move/$",
421
457
  teacher_move_students,
422
458
  name="teacher_move_students",
423
459
  ),
424
- url(
460
+ re_path(
461
+ r"^teach/dashboard/resend_invite/(?P<token>[0-9a-f]+)/$",
462
+ resend_invite_teacher,
463
+ name="resend_invite_teacher",
464
+ ),
465
+ re_path(
466
+ r"^teach/dashboard/toggle_admin_invite/(?P<invite_id>[0-9]+)/$",
467
+ invite_toggle_admin,
468
+ name="invite_toggle_admin",
469
+ ),
470
+ re_path(
471
+ r"^teach/dashboard/delete_teacher_invite/(?P<token>[0-9a-f]+)$",
472
+ delete_teacher_invite,
473
+ name="delete_teacher_invite",
474
+ ),
475
+ re_path(
425
476
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/move/disambiguate/$",
426
477
  teacher_move_students_to_class,
427
478
  name="teacher_move_students_to_class",
428
479
  ),
429
- url(
480
+ re_path(r"^delete/account/$", delete_account, name="delete_account"),
481
+ re_path(
482
+ r"^schools/anonymise/(?P<start_id>\d+)/",
483
+ AnonymiseOrphanSchoolsView.as_view(),
484
+ name="anonymise_orphan_schools",
485
+ ),
486
+ re_path(
430
487
  r"^api/",
431
488
  include(
432
489
  [
433
- url(
490
+ re_path(
434
491
  r"^registered/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$",
435
492
  registered_users,
436
493
  name="registered-users",
437
494
  ),
438
- url(
495
+ re_path(
439
496
  r"^lastconnectedsince/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$",
440
497
  last_connected_since,
441
498
  name="last-connected-since",
442
499
  ),
443
- url(
500
+ re_path(
444
501
  r"^userspercountry/(?P<country>(AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW))/$",
445
502
  number_users_per_country,
446
503
  name="number_users_per_country",
@@ -448,4 +505,16 @@ urlpatterns = [
448
505
  ]
449
506
  ),
450
507
  ),
508
+ re_path(r"^codingClub/$", coding_club, name="codingClub"),
509
+ re_path(
510
+ r"^removeFakeAccounts/",
511
+ RemoveFakeAccounts.as_view(),
512
+ name="remove_fake_accounts",
513
+ ),
514
+ re_path(r"^celebrate/", ten_year_map_page, name="celebrate"),
515
+ re_path(
516
+ r"^maintenance/$",
517
+ TemplateView.as_view(template_name="maintenance.html"),
518
+ name="maintenance",
519
+ ),
451
520
  ]