codeforlife-portal 5.32.2__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 (393) 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.32.2.dist-info → codeforlife_portal-8.9.9.dist-info}/RECORD +341 -238
  92. {codeforlife_portal-5.32.2.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.32.2.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 +31 -0
  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 +10 -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 -73
  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 +138 -15
  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 +237 -164
  319. portal/views/admin.py +0 -332
  320. portal/views/api.py +82 -68
  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/__init__.py +0 -0
  338. portal/views/two_factor/core.py +28 -0
  339. portal/views/two_factor/form.py +7 -0
  340. portal/views/two_factor/profile.py +11 -0
  341. codeforlife_portal-5.32.2.dist-info/LICENSE.md +0 -577
  342. codeforlife_portal-5.32.2.dist-info/METADATA +0 -38
  343. deploy/permissions.py +0 -2
  344. example_project/manage.py +0 -10
  345. portal/autoconfig.py +0 -140
  346. portal/csp_config.py +0 -60
  347. portal/forms/add_game.py +0 -33
  348. portal/helpers/location.py +0 -121
  349. portal/static/portal/img/kurono_hero.jpg +0 -0
  350. portal/static/portal/img/kurono_landing_hero.png +0 -0
  351. portal/static/portal/img/kurono_logo.svg +0 -1
  352. portal/static/portal/img/kurono_logo_grey_background.svg +0 -1
  353. portal/static/portal/img/kurono_logo_mark.svg +0 -1
  354. portal/static/portal/img/kurono_resources_hero.jpg +0 -0
  355. portal/static/portal/img/kurono_story.png +0 -0
  356. portal/static/portal/img/ocado-swirl.svg +0 -22
  357. portal/static/portal/img/thumbnail_educate_kurono.png +0 -0
  358. portal/static/portal/img/thumbnail_educate_resources_and_progress_tracking.png +0 -0
  359. portal/static/portal/img/thumbnail_kurono_resources.png +0 -0
  360. portal/static/portal/img/thumbnail_play_kurono.png +0 -0
  361. portal/static/portal/img/x_close_video.png +0 -0
  362. portal/static/portal/js/aimmoGame.js +0 -106
  363. portal/static/portal/js/deleteWorkspaces.js +0 -14
  364. portal/static/portal/js/fuzzySchoolLookup.js +0 -46
  365. portal/static/portal/js/lib/jquery-3.5.1.min.js +0 -2
  366. portal/static/portal/js/lib/jquery-ui-1.12.1.min.js +0 -13
  367. portal/static/portal/sass/partials/_videos.scss +0 -10
  368. portal/static/portal/video/aimmo_play_now_background_video.mp4 +0 -0
  369. portal/strings/student_aimmo_dashboard.py +0 -6
  370. portal/templates/portal/admin/aggregated_data.html +0 -35
  371. portal/templates/portal/admin/map.html +0 -70
  372. portal/templates/portal/mouseflow.html +0 -9
  373. portal/templates/portal/partials/aimmo_games_table.html +0 -83
  374. portal/templates/portal/partials/register_over_required_age_tickbox.html +0 -9
  375. portal/templates/portal/play/independent_student_dashboard.html +0 -64
  376. portal/templates/portal/play/student_aimmo_dashboard.html +0 -63
  377. portal/templates/portal/privacy_policy.html +0 -483
  378. portal/templates/portal/reset_password_email.html +0 -9
  379. portal/templates/portal/teach/invite.html +0 -25
  380. portal/templates/portal/teach/teacher_aimmo_dashboard.html +0 -95
  381. portal/templates/portal/teach/teacher_resources.html +0 -68
  382. portal/templatetags/character_list_tags.py +0 -16
  383. portal/tests/pageObjects/portal/kurono_teacher_dashboard_page.py +0 -49
  384. portal/tests/pageObjects/portal/student_password_reset_form_page.py +0 -23
  385. portal/tests/pageObjects/portal/teach/onboarding_revoke_request_page.py +0 -20
  386. portal/tests/pageObjects/portal/teacher_password_reset_form_page.py +0 -23
  387. portal/tests/test_aimmo_dashboards.py +0 -172
  388. portal/tests/test_location.py +0 -217
  389. portal/tests/utils/aimmo_games.py +0 -30
  390. portal/views/aimmo/dashboard.py +0 -119
  391. portal/views/privacy_policy.py +0 -9
  392. portal/views/teacher/teacher_resources.py +0 -42
  393. {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
@@ -12,87 +11,85 @@ from two_factor.views import (
12
11
  QRGeneratorView,
13
12
  SetupCompleteView,
14
13
  )
15
- from portal.two_factor.core import CustomSetupView
16
- from portal.two_factor.profile import CustomDisableView
17
14
 
18
15
  from portal.helpers.decorators import ratelimit
19
16
  from portal.helpers.ratelimit import (
20
- RATELIMIT_GROUP,
17
+ RATELIMIT_LOGIN_GROUP,
18
+ RATELIMIT_LOGIN_RATE,
19
+ RATELIMIT_LOGIN_RATE_SCHOOL_STUDENT,
21
20
  RATELIMIT_METHOD,
22
- RATELIMIT_RATE,
21
+ school_student_key,
23
22
  )
24
- from portal.helpers.regexes import ACCESS_CODE_REGEX
25
- from portal.views.about import about, getinvolved, contribute
26
- from portal.views.admin import (
27
- AdminChangePasswordDoneView,
28
- AdminChangePasswordView,
29
- aggregated_data,
30
- schools_map,
31
- )
32
- 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
33
27
  from portal.views.api import (
28
+ AnonymiseOrphanSchoolsView,
34
29
  InactiveUsersView,
35
- DuplicateIndyStudentsView,
30
+ RemoveFakeAccounts,
36
31
  last_connected_since,
37
32
  number_users_per_country,
38
33
  registered_users,
39
34
  )
40
35
  from portal.views.dotmailer import dotmailer_consent_form, process_newsletter_form
41
- from portal.views.email import send_new_users_report, verify_email
36
+ from portal.views.email import verify_email
42
37
  from portal.views.home import (
38
+ coding_club,
43
39
  home,
44
40
  home_learning,
45
41
  logout_view,
46
42
  register_view,
43
+ reset_screentime_warning,
44
+ ten_year_map_page,
47
45
  )
46
+ from portal.views.legal import privacy_notice, terms
48
47
  from portal.views.login import old_login_form_redirect
49
48
  from portal.views.login.independent_student import IndependentStudentLoginView
50
49
  from portal.views.login.student import (
51
- StudentLoginView,
52
50
  StudentClassCodeView,
51
+ StudentLoginView,
53
52
  student_direct_login,
54
53
  )
55
54
  from portal.views.login.teacher import TeacherLoginView
56
- from portal.views.organisation import (
57
- OrganisationFuzzyLookup,
58
- organisation_leave,
59
- organisation_manage,
60
- )
55
+ from portal.views.organisation import organisation_leave, organisation_manage
61
56
  from portal.views.play_landing_page import play_landing_page
62
- from portal.views.privacy_policy import privacy_policy
63
57
  from portal.views.registration import (
58
+ delete_account,
64
59
  password_reset_check_and_confirm,
65
60
  password_reset_done,
66
61
  student_password_reset,
67
62
  teacher_password_reset,
68
63
  )
69
64
  from portal.views.student.edit_account_details import (
70
- IndependentStudentEditAccountView,
71
65
  SchoolStudentEditAccountView,
66
+ independentStudentEditAccountView,
72
67
  student_edit_account,
73
68
  )
74
69
  from portal.views.student.play import (
75
- SchoolStudentDashboard,
76
70
  IndependentStudentDashboard,
71
+ SchoolStudentDashboard,
77
72
  student_join_organisation,
78
73
  )
79
74
  from portal.views.teach import teach
80
75
  from portal.views.teacher.dashboard import (
81
76
  dashboard_manage,
82
- organisation_allow_join,
83
- organisation_deny_join,
77
+ delete_teacher_invite,
78
+ invite_toggle_admin,
79
+ invited_teacher,
84
80
  organisation_kick,
85
81
  organisation_toggle_admin,
82
+ resend_invite_teacher,
86
83
  teacher_accept_student_request,
87
84
  teacher_disable_2FA,
88
85
  teacher_reject_student_request,
89
86
  )
90
87
  from portal.views.teacher.teach import (
91
- invite_teacher,
92
88
  teacher_class_password_reset,
93
89
  teacher_delete_class,
94
90
  teacher_delete_students,
95
91
  teacher_dismiss_students,
92
+ teacher_download_csv,
96
93
  teacher_edit_class,
97
94
  teacher_edit_student,
98
95
  teacher_move_students,
@@ -100,37 +97,32 @@ from portal.views.teacher.teach import (
100
97
  teacher_onboarding_create_class,
101
98
  teacher_onboarding_edit_class,
102
99
  teacher_print_reminder_cards,
103
- teacher_download_csv,
104
100
  teacher_view_class,
105
101
  )
106
- from portal.views.teacher.teacher_resources import (
107
- teacher_kurono_resources,
108
- teacher_rapid_router_resources,
109
- kurono_teaching_packs,
110
- materials,
111
- )
102
+ from portal.views.two_factor.core import CustomSetupView
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,304 +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(r"^indycleanup/", DuplicateIndyStudentsView.as_view(), name="indy_cleanup"),
176
- url(
197
+ re_path(r"^users/inactive/", InactiveUsersView.as_view(), name="inactive_users"),
198
+ re_path(
177
199
  r"^locked_out/$",
178
200
  TemplateView.as_view(template_name="portal/locked_out.html"),
179
201
  name="locked_out",
180
202
  ),
181
- url(r"^", include((two_factor_patterns, "two_factor"), namespace="two_factor")),
182
- url(r"^i18n/", include("django.conf.urls.i18n")),
183
- url(r"^jsi18n/$", JavaScriptCatalog.as_view(), js_info_dict),
184
- url(r"^(?P<levelName>[A-Z0-9]+)/$", play_default_level, name="play_default_level"),
185
- url(r"^$", home, name="home"),
186
- url(r"^home-learning", home_learning, name="home-learning"),
187
- url(r"^register_form", register_view, name="register"),
188
- 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(
189
218
  r"^login/teacher/$",
190
219
  # The ratelimit decorator checks how often a POST request is performed on that view.
191
220
  # It checks against the username value specifically. If the number of requests
192
221
  # exceeds the specified rate, then the user will be blocked (if block = True).
193
222
  ratelimit(
194
- group=RATELIMIT_GROUP,
223
+ group=RATELIMIT_LOGIN_GROUP,
195
224
  key="post:auth-username",
196
225
  method=RATELIMIT_METHOD,
197
- rate=RATELIMIT_RATE,
226
+ rate=RATELIMIT_LOGIN_RATE,
198
227
  block=True,
199
228
  )(TeacherLoginView.as_view()),
200
229
  name="teacher_login",
201
230
  ),
202
- url(
231
+ re_path(
203
232
  rf"^login/student/(?P<access_code>{ACCESS_CODE_REGEX})/(?:(?P<login_type>classform)/)?$",
204
- 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()),
205
241
  name="student_login",
206
242
  ),
207
- url(
243
+ re_path(
208
244
  r"^login/student/$",
209
245
  StudentClassCodeView.as_view(),
210
246
  name="student_login_access_code",
211
247
  ),
212
- url(
248
+ re_path(
213
249
  r"^u/(?P<user_id>[0-9]+)/(?P<login_id>[a-z0-9]+)/$",
214
250
  student_direct_login,
215
251
  name="student_direct_login",
216
252
  ),
217
- url(
253
+ re_path(
218
254
  r"^login/independent/$",
219
255
  ratelimit(
220
- group=RATELIMIT_GROUP,
256
+ group=RATELIMIT_LOGIN_GROUP,
221
257
  key="post:username",
222
258
  method=RATELIMIT_METHOD,
223
- rate=RATELIMIT_RATE,
259
+ rate=RATELIMIT_LOGIN_RATE,
224
260
  block=True,
225
261
  is_teacher=False,
226
262
  )(IndependentStudentLoginView.as_view()),
227
263
  name="independent_student_login",
228
264
  ),
229
- url(r"^login_form", old_login_form_redirect, name="old_login_form"),
230
- url(r"^logout/$", logout_view, name="logout_view"),
231
- url(r"^news_signup/$", process_newsletter_form, name="process_newsletter_form"),
232
- url(r"^consent_form/$", dotmailer_consent_form, name="consent_form"),
233
- 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(
234
274
  r"^verify_email/$",
235
275
  TemplateView.as_view(template_name="portal/email_verification_needed.html"),
236
276
  name="email_verification",
237
277
  ),
238
- url(r"^verify_email/(?P<token>[0-9a-f]+)/$", verify_email, name="verify_email"),
239
- url(
278
+ re_path(
279
+ rf"^verify_email/(?P<token>{JWT_REGEX})/$",
280
+ verify_email,
281
+ name="verify_email",
282
+ ),
283
+ re_path(
240
284
  r"^user/password/reset/student/$",
241
285
  student_password_reset,
242
286
  name="student_password_reset",
243
287
  ),
244
- url(
288
+ re_path(
245
289
  r"^user/password/reset/teacher/$",
246
290
  teacher_password_reset,
247
291
  name="teacher_password_reset",
248
292
  ),
249
- url(
293
+ re_path(
250
294
  r"^user/password/reset/done/$",
251
295
  password_reset_done,
252
296
  name="reset_password_email_sent",
253
297
  ),
254
- url(
298
+ re_path(
255
299
  r"^user/password/reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$",
256
300
  password_reset_check_and_confirm,
257
301
  name="password_reset_check_and_confirm",
258
302
  ),
259
- 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(
260
314
  r"^teacher/password/reset/complete/$",
261
315
  TemplateView.as_view(template_name="portal/reset_password_done.html"),
262
316
  name="password_reset_complete",
263
317
  ),
264
- url(r"^teach/$", teach, name="teach"),
265
- url(
266
- r"^teach/fuzzy_lookup/$",
267
- OrganisationFuzzyLookup.as_view(),
268
- name="organisation_fuzzy_lookup",
269
- ),
270
- url(
318
+ re_path(r"^teach/$", teach, name="teach"),
319
+ re_path(
271
320
  r"^teach/onboarding-organisation/$",
272
321
  organisation_manage,
273
322
  name="onboarding-organisation",
274
323
  ),
275
- url(
324
+ re_path(
276
325
  r"^teach/onboarding-classes",
277
326
  teacher_onboarding_create_class,
278
327
  name="onboarding-classes",
279
328
  ),
280
- url(
329
+ re_path(
281
330
  rf"^teach/onboarding-class/(?P<access_code>{ACCESS_CODE_REGEX})$",
282
331
  teacher_onboarding_edit_class,
283
332
  name="onboarding-class",
284
333
  ),
285
- url(
334
+ re_path(
286
335
  rf"^teach/onboarding-class/(?P<access_code>{ACCESS_CODE_REGEX})/print_reminder_cards/$",
287
336
  teacher_print_reminder_cards,
288
337
  name="teacher_print_reminder_cards",
289
338
  ),
290
- url(
339
+ re_path(
291
340
  rf"^teach/onboarding-class/(?P<access_code>{ACCESS_CODE_REGEX})/download_csv/$",
292
341
  teacher_download_csv,
293
342
  name="teacher_download_csv",
294
343
  ),
295
- url(r"^teach/invite", invite_teacher, name="invite_teacher"),
296
- url(r"^play/$", play_landing_page, name="play"),
297
- url(r"^play/details/$", SchoolStudentDashboard.as_view(), name="student_details"),
298
- 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(
299
356
  r"^play/details/independent$",
300
357
  IndependentStudentDashboard.as_view(),
301
358
  name="independent_student_details",
302
359
  ),
303
- url(r"^play/account/$", student_edit_account, name="student_edit_account"),
304
- url(
360
+ re_path(r"^play/account/$", student_edit_account, name="student_edit_account"),
361
+ re_path(
305
362
  r"^play/account/independent/$",
306
363
  ratelimit(
307
- group=RATELIMIT_GROUP,
364
+ group=RATELIMIT_LOGIN_GROUP,
308
365
  key="post:name",
309
366
  method=RATELIMIT_METHOD,
310
- rate=RATELIMIT_RATE,
367
+ rate=RATELIMIT_LOGIN_RATE,
311
368
  block=True,
312
369
  is_teacher=False,
313
- )(IndependentStudentEditAccountView.as_view()),
370
+ )(independentStudentEditAccountView),
314
371
  name="independent_edit_account",
315
372
  ),
316
- url(
373
+ re_path(
317
374
  r"^play/account/school_student/$",
318
375
  SchoolStudentEditAccountView.as_view(),
319
376
  name="school_student_edit_account",
320
377
  ),
321
- url(r"^play/join/$", student_join_organisation, name="student_join_organisation"),
322
- url(r"^about", about, name="about"),
323
- url(r"^getinvolved", getinvolved, name="getinvolved"),
324
- url(r"^contribute", contribute, name="contribute"),
325
- url(
326
- r"^terms", TemplateView.as_view(template_name="portal/terms.html"), name="terms"
327
- ),
328
- url(r"^privacy-policy/$", privacy_policy, name="privacy_policy"),
329
- url(r"^teach/materials/$", materials, name="materials"),
330
- url(r"^teach/kurono_teaching_packs$", kurono_teaching_packs, name="kurono_packs"),
331
- url(
332
- r"^teach/resources/$", teacher_rapid_router_resources, name="teaching_resources"
333
- ),
334
- url(
335
- r"^teach/kurono_resources/$",
336
- teacher_kurono_resources,
337
- name="kurono_teaching_resources",
338
- ),
339
- url(r"^teach/dashboard/$", dashboard_manage, name="dashboard"),
340
- 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(
341
391
  r"^teach/dashboard/kick/(?P<pk>[0-9]+)/$",
342
392
  organisation_kick,
343
393
  name="organisation_kick",
344
394
  ),
345
- url(
395
+ re_path(
346
396
  r"^teach/dashboard/toggle_admin/(?P<pk>[0-9]+)/$",
347
397
  organisation_toggle_admin,
348
398
  name="organisation_toggle_admin",
349
399
  ),
350
- url(
400
+ re_path(
351
401
  r"^teach/dashboard/disable_2FA/(?P<pk>[0-9]+)/$",
352
402
  teacher_disable_2FA,
353
403
  name="teacher_disable_2FA",
354
404
  ),
355
- url(
356
- r"^teach/dashboard/allow_join/(?P<pk>[0-9]+)/$",
357
- organisation_allow_join,
358
- name="organisation_allow_join",
359
- ),
360
- url(
361
- r"^teach/dashboard/deny_join/(?P<pk>[0-9]+)/$",
362
- organisation_deny_join,
363
- name="organisation_deny_join",
364
- ),
365
- url(
405
+ re_path(
366
406
  r"^teach/dashboard/school/leave/$",
367
407
  organisation_leave,
368
408
  name="organisation_leave",
369
409
  ),
370
- url(
410
+ re_path(
371
411
  r"^teach/dashboard/student/accept/(?P<pk>[0-9]+)/$",
372
412
  teacher_accept_student_request,
373
413
  name="teacher_accept_student_request",
374
414
  ),
375
- url(
415
+ re_path(
376
416
  r"^teach/dashboard/student/reject/(?P<pk>[0-9]+)/$",
377
417
  teacher_reject_student_request,
378
418
  name="teacher_reject_student_request",
379
419
  ),
380
- url(
420
+ re_path(
381
421
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})$",
382
422
  teacher_view_class,
383
423
  name="view_class",
384
424
  ),
385
- url(
425
+ re_path(
386
426
  rf"^teach/class/delete/(?P<access_code>{ACCESS_CODE_REGEX})$",
387
427
  teacher_delete_class,
388
428
  name="teacher_delete_class",
389
429
  ),
390
- url(
430
+ re_path(
391
431
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/delete/$",
392
432
  teacher_delete_students,
393
433
  name="teacher_delete_students",
394
434
  ),
395
- url(
435
+ re_path(
396
436
  rf"^teach/class/edit/(?P<access_code>{ACCESS_CODE_REGEX})$",
397
437
  teacher_edit_class,
398
438
  name="teacher_edit_class",
399
439
  ),
400
- url(
440
+ re_path(
401
441
  r"^teach/class/student/edit/(?P<pk>[0-9]+)/$",
402
442
  teacher_edit_student,
403
443
  name="teacher_edit_student",
404
444
  ),
405
- url(
445
+ re_path(
406
446
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/password_reset/$",
407
447
  teacher_class_password_reset,
408
448
  name="teacher_class_password_reset",
409
449
  ),
410
- url(
450
+ re_path(
411
451
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/dismiss/$",
412
452
  teacher_dismiss_students,
413
453
  name="teacher_dismiss_students",
414
454
  ),
415
- url(
455
+ re_path(
416
456
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/move/$",
417
457
  teacher_move_students,
418
458
  name="teacher_move_students",
419
459
  ),
420
- 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(
421
476
  rf"^teach/class/(?P<access_code>{ACCESS_CODE_REGEX})/students/move/disambiguate/$",
422
477
  teacher_move_students_to_class,
423
478
  name="teacher_move_students_to_class",
424
479
  ),
425
- 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(
426
487
  r"^api/",
427
488
  include(
428
489
  [
429
- url(
490
+ re_path(
430
491
  r"^registered/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$",
431
492
  registered_users,
432
493
  name="registered-users",
433
494
  ),
434
- url(
495
+ re_path(
435
496
  r"^lastconnectedsince/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$",
436
497
  last_connected_since,
437
498
  name="last-connected-since",
438
499
  ),
439
- url(
500
+ re_path(
440
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))/$",
441
502
  number_users_per_country,
442
503
  name="number_users_per_country",
@@ -444,4 +505,16 @@ urlpatterns = [
444
505
  ]
445
506
  ),
446
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
+ ),
447
520
  ]