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
@@ -1,38 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: codeforlife-portal
3
- Version: 5.32.2
4
- Summary: UNKNOWN
5
- Home-page: UNKNOWN
6
- License: UNKNOWN
7
- Platform: UNKNOWN
8
- Classifier: Programming Language :: Python
9
- Classifier: Programming Language :: Python :: 3.7
10
- Classifier: Framework :: Django
11
- License-File: LICENSE.md
12
- Requires-Dist: django (==2.2.26)
13
- Requires-Dist: django-countries (==6.1.3)
14
- Requires-Dist: djangorestframework (==3.12.2)
15
- Requires-Dist: django-pipeline (==1.6.14)
16
- Requires-Dist: django-recaptcha (==2.0.6)
17
- Requires-Dist: pyyaml (==5.4)
18
- Requires-Dist: rapid-router (>=1.0.0.post.dev1)
19
- Requires-Dist: aimmo
20
- Requires-Dist: reportlab (==3.6.1)
21
- Requires-Dist: django-formtools (==2.2)
22
- Requires-Dist: django-otp (==1.0.2)
23
- Requires-Dist: requests (==2.25.0)
24
- Requires-Dist: django-treebeard (==4.3.1)
25
- Requires-Dist: django-sekizai (==2.0.0)
26
- Requires-Dist: django-classy-tags (==2.0.0)
27
- Requires-Dist: sqlparse (==0.4.2)
28
- Requires-Dist: libsass (==0.20.1)
29
- Requires-Dist: phonenumbers (==8.12.12)
30
- Requires-Dist: more-itertools (==8.6.0)
31
- Requires-Dist: future (==0.18.2)
32
- Requires-Dist: cfl-common (==5.32.2)
33
- Requires-Dist: django-ratelimit (==3.0.1)
34
- Requires-Dist: django-preventconcurrentlogins (==0.8.2)
35
- Requires-Dist: django-csp (==3.7)
36
-
37
- UNKNOWN
38
-
deploy/permissions.py DELETED
@@ -1,2 +0,0 @@
1
- def is_authorised_to_view_aggregated_data(u):
2
- return hasattr(u, "userprofile") and u.userprofile.can_view_aggregated_data
example_project/manage.py DELETED
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env python
2
- import os
3
- import sys
4
-
5
- if __name__ == "__main__":
6
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
7
-
8
- from django.core.management import execute_from_command_line
9
-
10
- execute_from_command_line(sys.argv)
portal/autoconfig.py DELETED
@@ -1,140 +0,0 @@
1
- """Portal autoconfig"""
2
- import os
3
-
4
- from django_autoconfig.autoconfig import OrderingRelationship
5
-
6
- from .csp_config import CSP_CONFIG
7
-
8
- DEFAULT_SETTINGS = {
9
- "AUTOCONFIG_INDEX_VIEW": "home",
10
- "LANGUAGE_CODE": "en-gb",
11
- "SITE_ID": 1,
12
- "MEDIA_ROOT": os.path.join(
13
- os.path.join(os.path.dirname(__file__), "static"), "email_media/"
14
- ),
15
- }
16
-
17
- SETTINGS = {
18
- "AUTOCONFIG_DISABLED_APPS": [
19
- "django_otp",
20
- "django_otp.plugins.otp_static",
21
- "django_otp.plugins.otp_totp",
22
- ],
23
- "PIPELINE": {
24
- "COMPILERS": ("portal.pipeline_compilers.LibSassCompiler",),
25
- "STYLESHEETS": {
26
- "css": {
27
- "source_filenames": (
28
- "portal/sass/bootstrap.scss",
29
- "portal/sass/colorbox.scss",
30
- "portal/sass/styles.scss",
31
- ),
32
- "output_filename": "portal.css",
33
- },
34
- },
35
- "CSS_COMPRESSOR": None,
36
- "SASS_ARGUMENTS": "--quiet",
37
- },
38
- "STATICFILES_FINDERS": ["pipeline.finders.PipelineFinder"],
39
- "STATICFILES_STORAGE": "pipeline.storage.PipelineStorage",
40
- "INSTALLED_APPS": [
41
- "aimmo",
42
- "game",
43
- "pipeline",
44
- "portal",
45
- "common",
46
- "django.contrib.admin",
47
- "django.contrib.admindocs",
48
- "django.contrib.auth",
49
- "django.contrib.contenttypes",
50
- "django.contrib.sessions",
51
- "django.contrib.messages",
52
- "django.contrib.sites",
53
- "django.contrib.staticfiles",
54
- "rest_framework",
55
- "django_otp",
56
- "django_otp.plugins.otp_static",
57
- "django_otp.plugins.otp_totp",
58
- "sekizai", # for javascript and css management
59
- "treebeard",
60
- "two_factor",
61
- "preventconcurrentlogins",
62
- ],
63
- "LANGUAGES": [("en-gb", "English")],
64
- "MESSAGE_STORAGE": "django.contrib.messages.storage.session.SessionStorage",
65
- "MIDDLEWARE": [
66
- "deploy.middleware.admin_access.AdminAccessMiddleware",
67
- "django.contrib.sessions.middleware.SessionMiddleware",
68
- "django.middleware.locale.LocaleMiddleware",
69
- "django.middleware.common.CommonMiddleware",
70
- "django.middleware.csrf.CsrfViewMiddleware",
71
- "deploy.middleware.security.CustomSecurityMiddleware",
72
- "django.contrib.auth.middleware.AuthenticationMiddleware",
73
- "django.contrib.messages.middleware.MessageMiddleware",
74
- "django.middleware.clickjacking.XFrameOptionsMiddleware",
75
- "deploy.middleware.exceptionlogging.ExceptionLoggingMiddleware",
76
- "django_otp.middleware.OTPMiddleware",
77
- "preventconcurrentlogins.middleware.PreventConcurrentLoginsMiddleware",
78
- "csp.middleware.CSPMiddleware",
79
- ],
80
- "TEMPLATES": [
81
- {
82
- "BACKEND": "django.template.backends.django.DjangoTemplates",
83
- "APP_DIRS": True,
84
- "OPTIONS": {
85
- "context_processors": [
86
- "django.contrib.auth.context_processors.auth",
87
- "django.template.context_processors.request",
88
- "django.contrib.messages.context_processors.messages",
89
- "sekizai.context_processors.sekizai",
90
- "common.context_processors.module_name",
91
- "common.context_processors.cookie_management_enabled",
92
- "portal.context_processors.process_newsletter_form",
93
- ]
94
- },
95
- }
96
- ],
97
- "CODEFORLIFE_WEBSITE": "www.codeforlife.education",
98
- "CLOUD_STORAGE_PREFIX": "https://storage.googleapis.com/codeforlife-assets/",
99
- "LOGGING": {
100
- "version": 1,
101
- "disable_existing_loggers": False,
102
- "handlers": {"console": {"level": "DEBUG", "class": "logging.StreamHandler"}},
103
- "loggers": {"two_factor": {"handlers": ["console"], "level": "INFO"}},
104
- },
105
- "RAPID_ROUTER_EARLY_ACCESS_FUNCTION_NAME": "portal.beta.has_beta_access",
106
- "SECURE_CONTENT_TYPE_NOSNIFF": True,
107
- "SECURE_BROWSER_XSS_FILTER": True,
108
- "RECAPTCHA_DOMAIN": "www.recaptcha.net",
109
- "AUTHENTICATION_BACKENDS": [
110
- "django.contrib.auth.backends.ModelBackend",
111
- "portal.backends.StudentLoginBackend",
112
- ],
113
- "USE_TZ": True,
114
- "PASSWORD_RESET_TIMEOUT_DAYS": 1,
115
- }
116
-
117
- SETTINGS.update(CSP_CONFIG)
118
-
119
- RELATIONSHIPS = [
120
- OrderingRelationship(
121
- "MIDDLEWARE",
122
- "django_otp.middleware.OTPMiddleware",
123
- after=["django.contrib.auth.middleware.AuthenticationMiddleware"],
124
- add_missing=False,
125
- ),
126
- OrderingRelationship(
127
- "MIDDLEWARE",
128
- "preventconcurrentlogins.middleware.PreventConcurrentLoginsMiddleware",
129
- after=["django.contrib.auth.middleware.AuthenticationMiddleware"],
130
- add_missing=False,
131
- ),
132
- ]
133
-
134
- try:
135
- import django_pandasso
136
-
137
- SETTINGS["INSTALLED_APPS"].append("django_pandasso")
138
- SETTINGS["INSTALLED_APPS"].append("social.apps.django_app.default")
139
- except ImportError:
140
- pass
portal/csp_config.py DELETED
@@ -1,60 +0,0 @@
1
- """CSP config"""
2
-
3
- from common.app_settings import domain
4
-
5
- CSP_CONFIG = {
6
- "CSP_DEFAULT_SRC": ("'self'",),
7
- "CSP_CONNECT_SRC": (
8
- "'self'",
9
- "https://*.onetrust.com/",
10
- "https://euc-widget.freshworks.com/",
11
- "https://codeforlife.freshdesk.com/",
12
- "https://api.iconify.design/",
13
- "https://api.simplesvg.com/",
14
- "https://api.unisvg.com/",
15
- "https://www.google-analytics.com/",
16
- ),
17
- "CSP_FONT_SRC": (
18
- "'self'",
19
- "https://fonts.gstatic.com/",
20
- "https://fonts.googleapis.com/",
21
- ),
22
- "CSP_IMG_SRC": (
23
- "https://storage.googleapis.com/codeforlife-assets/images/",
24
- "https://cdn-ukwest.onetrust.com/",
25
- f"{domain()}/static/portal/img/",
26
- f"{domain()}/account/two_factor/qrcode/",
27
- "data:",
28
- ),
29
- "CSP_SCRIPT_SRC": (
30
- "'self'",
31
- "'unsafe-inline'",
32
- "https://*.onetrust.com/",
33
- "https://code.jquery.com/",
34
- "https://euc-widget.freshworks.com/",
35
- "https://cdn-ukwest.onetrust.com/",
36
- "https://code.iconify.design/2/2.0.3/iconify.min.js",
37
- "https://www.googletagmanager.com/gtm.js",
38
- "https://cdn.mouseflow.com/",
39
- "https://www.google-analytics.com/analytics.js",
40
- "https://www.recaptcha.net/",
41
- "https://www.google.com/recaptcha/",
42
- "https://www.gstatic.com/recaptcha/",
43
- f"{domain()}/static/portal/",
44
- f"{domain()}/static/common/",
45
- ),
46
- "CSP_STYLE_SRC": (
47
- "'self'",
48
- "'unsafe-inline'",
49
- "https://euc-widget.freshworks.com/",
50
- "https://cdn-ukwest.onetrust.com/",
51
- "https://fonts.googleapis.com/",
52
- f"{domain()}/static/portal/",
53
- ),
54
- "CSP_FRAME_SRC": (
55
- "https://storage.googleapis.com/",
56
- "https://www.youtube-nocookie.com/",
57
- "https://www.recaptcha.net/",
58
- "https://www.google.com/recaptcha/",
59
- ),
60
- }
portal/forms/add_game.py DELETED
@@ -1,33 +0,0 @@
1
- from aimmo.models import Game
2
- from common.models import Class
3
- from django.core.exceptions import ValidationError
4
- from django.db.models.query import QuerySet
5
- from django.forms import ModelChoiceField, ModelForm, Select
6
-
7
-
8
- class AddGameForm(ModelForm):
9
- def __init__(self, classes: QuerySet, *args, **kwargs):
10
- super(AddGameForm, self).__init__(*args, **kwargs)
11
- self.fields["game_class"].queryset = classes
12
-
13
- game_class = ModelChoiceField(
14
- queryset=None, widget=Select, label="Class", required=True
15
- )
16
-
17
- class Meta:
18
- model = Game
19
- fields = [
20
- "game_class",
21
- ]
22
-
23
- def clean(self):
24
- super(AddGameForm, self).clean()
25
- game_class: Class = self.cleaned_data.get("game_class")
26
-
27
- if not game_class:
28
- raise ValidationError("An invalid class was entered")
29
-
30
- if Game.objects.filter(game_class=game_class, is_archived=False).exists():
31
- raise ValidationError("An active game already exists for this class")
32
-
33
- return self.cleaned_data
@@ -1,121 +0,0 @@
1
- import requests
2
-
3
- try:
4
- from exceptions import Exception, ValueError
5
- except ImportError:
6
- pass
7
-
8
-
9
- class RequestException(Exception):
10
- pass
11
-
12
-
13
- class ApiException(Exception):
14
- pass
15
-
16
-
17
- def is_GB(component):
18
- return "country" in component["types"] and component["short_name"] == "GB"
19
-
20
-
21
- def extract_locality(components):
22
- town = None
23
- country = None
24
-
25
- for component in components:
26
- if "locality" in component["types"]:
27
- town = component["long_name"]
28
-
29
- if "postal_town" in component["types"]:
30
- town = component["long_name"]
31
-
32
- if "country" in component["types"]:
33
- country = component["short_name"]
34
-
35
- return town, country
36
-
37
-
38
- def extract_location_data(results):
39
- for result in results:
40
- town, country = extract_locality(result["address_components"])
41
- location = result["geometry"]["location"]
42
- return country, town, location["lat"], location["lng"]
43
-
44
- return None, None, None, None
45
-
46
-
47
- # Uses Google Maps API to lookup location data using postcode + country(ISO 3166-1 alpha-2)
48
- # By using country, it can return a more accurate location as the same postcode may exist in multiple countries
49
- # Coordinates of the country will be returned if postcode is invalid in that country
50
- def lookup_coord(postcode, country):
51
-
52
- payload = {"address": postcode, "components": "country:" + country}
53
-
54
- return get_location_from_api(payload)
55
-
56
-
57
- # Using the Google Map API, lookup country using postcode
58
- def lookup_country(postcode):
59
-
60
- payload = {"components": "postal_code:" + postcode}
61
-
62
- return get_location_from_api(payload)
63
-
64
-
65
- # Takes in payload as argument and use it when calling API
66
- # Catches any error and return an error message as first element in the tuple
67
- # Coordinates of GB is used if country is not specified, otherwise default to original country and 0 for coordinates
68
- # Return format is:
69
- # error, country, town, latitude, longitude
70
- def get_location_from_api(payload):
71
- # default location is UK and the coordinates of UK
72
- default_country = "GB"
73
- default_town = 0
74
- default_lat = 55.378051
75
- default_lng = -3.435973
76
-
77
- if "country" in payload.get("components"):
78
- default_country = payload.get("components", "GB").rpartition(":")[2]
79
- default_town = default_lat = default_lng = 0
80
-
81
- # Catch error when there is a problem connecting to external API
82
- try:
83
- res = requests.get(
84
- "https://maps.googleapis.com/maps/api/geocode/json", params=payload
85
- )
86
-
87
- # Make sure status_code is 200 before deserialising json
88
- if not res.status_code == requests.codes.ok:
89
- raise RequestException(res.reason)
90
-
91
- data = res.json()
92
-
93
- status = data.get("status", "No status")
94
- results = data.get("results", [])
95
-
96
- if not (status == "OK" and len(results) > 0):
97
- raise ApiException(status)
98
-
99
- country, town, lat, lng = extract_location_data(results)
100
-
101
- return (
102
- None,
103
- country or default_country,
104
- town or default_town,
105
- lat or default_lat,
106
- lng or default_lng,
107
- )
108
-
109
- except requests.exceptions.RequestException:
110
- error = "Connection error"
111
-
112
- except RequestException as e:
113
- error = "Request error: %s" % e
114
-
115
- except ValueError as e:
116
- error = "Value error: %s" % e
117
-
118
- except ApiException as e:
119
- error = "API error: %s" % e
120
-
121
- return error, default_country, default_town, default_lat, default_lng
Binary file
@@ -1 +0,0 @@
1
- <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 781.61 255.82"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:#fff;}</style><linearGradient id="linear-gradient" x1="390.81" x2="390.81" y2="255.82" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00cea7"/><stop offset="0.2" stop-color="#00c3ac"/><stop offset="0.68" stop-color="#00afb5"/><stop offset="1" stop-color="#00a8b8"/></linearGradient></defs><title>K_simple_logo_full_colour</title><path class="cls-1" d="M697.33.34A84.18,84.18,0,0,0,630.4,33.48,71.21,71.21,0,0,0,621,21.9C607,8,588,.41,567.25.41S527.48,8,513.54,21.9a72,72,0,0,0-9.45,11.59,84.09,84.09,0,0,0-115.1-18A35.89,35.89,0,0,0,359.73.41c-21.56,0-41.4,8-55.87,22.43-.52.53-1,1.07-1.52,1.61a37.13,37.13,0,0,0-65.33-8,9.77,9.77,0,0,1-16.12-.1A37.16,37.16,0,0,0,188.05.48a36.22,36.22,0,0,0-20.39,7.87A37.45,37.45,0,0,0,144.19,0a37,37,0,0,0-22.25,7.39L74.47,42.77V37.24A37.24,37.24,0,1,0,0,37.24V131.3A37.18,37.18,0,0,0,13.53,160a37,37,0,0,0-8.08,47.6,99.5,99.5,0,0,0,170.54,0A37,37,0,0,0,167.9,160a36.51,36.51,0,0,0,6-6.27A38.17,38.17,0,0,0,177,149c13.77,12.81,32.12,19.86,52,19.86,20.69,0,39.77-7.63,53.71-21.49.37-.37.73-.76,1.09-1.14a37.16,37.16,0,0,0,71.36-14.53V103.94a84.2,84.2,0,0,0,139.53,42.21,36.93,36.93,0,0,0,64.5,6.69,9.78,9.78,0,0,1,16.17,0,36.92,36.92,0,0,0,64.49-6.69A84.25,84.25,0,1,0,697.33.34Z"/><path class="cls-2" d="M284.47,37.56V91.85c0,34-24.37,56.71-55.49,56.71s-55.5-22.69-55.5-56.71V37.56a16.89,16.89,0,0,1,33.78,0V93.05c0,15.69,9.66,24.14,21.72,24.14s21.71-8.45,21.71-24.14V37.56a16.89,16.89,0,0,1,33.78,0Z"/><path class="cls-2" d="M375.42,36.36a15.66,15.66,0,0,1-15.69,15.69c-13.75,0-24.85,9.65-24.85,29.67v49.95a16.9,16.9,0,0,1-33.79,0V81.72c0-37.39,26.07-61,58.64-61A15.66,15.66,0,0,1,375.42,36.36Z"/><path class="cls-2" d="M622.74,77.39v54.29a16.89,16.89,0,0,1-33.77,0V76.19c0-15.69-9.65-24.14-21.72-24.14s-21.71,8.45-21.71,24.14v55.49a16.9,16.9,0,0,1-33.79,0V77.39c0-34,24.37-56.71,55.5-56.71S622.74,43.37,622.74,77.39Z"/><path class="cls-2" d="M761.28,84.62a64,64,0,1,1-63.95-63.95A63.95,63.95,0,0,1,761.28,84.62ZM697.33,52a32.58,32.58,0,1,0,32.58,32.58A32.58,32.58,0,0,0,697.33,52Z"/><path class="cls-2" d="M501.11,84.62a64,64,0,1,1-63.95-63.95A63.95,63.95,0,0,1,501.11,84.62ZM437.16,52a32.58,32.58,0,1,0,32.58,32.58A32.58,32.58,0,0,0,437.16,52Z"/><path class="cls-2" d="M37.24,148.21A16.91,16.91,0,0,1,20.33,131.3V37.24a16.91,16.91,0,1,1,33.81,0V131.3A16.91,16.91,0,0,1,37.24,148.21Z"/><path class="cls-2" d="M144.19,148.21A16.8,16.8,0,0,1,134,144.8L71.27,97.5a16.9,16.9,0,0,1,.08-27l62.74-46.77a16.91,16.91,0,1,1,20.22,27.1l-44.69,33.3,44.76,33.72a16.91,16.91,0,0,1-10.19,30.4Z"/><path class="cls-2" d="M90.72,235.49a78.54,78.54,0,0,1-67.85-38.37A16.76,16.76,0,0,1,51.6,179.85a45.65,45.65,0,0,0,78.24,0,16.76,16.76,0,1,1,28.72,17.27A78.52,78.52,0,0,1,90.72,235.49Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1330.02 596.66"><defs><style>.a{fill:#f2f2f2;}.b{fill:url(#a);}.c{fill:#fff;}</style><linearGradient id="a" x1="665.01" y1="510.52" x2="665.01" y2="287.55" gradientTransform="matrix(1, 0, 0, -1, 0, 724.17)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00cea7"/><stop offset="0.2" stop-color="#00c3ac"/><stop offset="0.68" stop-color="#00afb5"/><stop offset="1" stop-color="#00a8b8"/></linearGradient></defs><rect class="a" width="1330.02" height="596.66"/><path class="b" d="M932.17,214a73.34,73.34,0,0,0-58.33,28.88,62.06,62.06,0,0,0-8.2-10.09C853.44,220.62,836.88,214,818.8,214s-34.67,6.61-46.82,18.73a62.32,62.32,0,0,0-8.23,10.1,73.3,73.3,0,0,0-100.32-15.69A31.27,31.27,0,0,0,637.93,214c-18.8,0-36.09,7-48.7,19.55-.45.46-.87.93-1.32,1.4A32.36,32.36,0,0,0,531,228a8.53,8.53,0,0,1-11.86,2.14,8.44,8.44,0,0,1-2.19-2.23,32.39,32.39,0,0,0-28.63-13.83,31.57,31.57,0,0,0-17.77,6.86,32.64,32.64,0,0,0-20.45-7.28,32.29,32.29,0,0,0-19.4,6.44L389.3,250.93v-4.82A32.46,32.46,0,1,0,324.39,245v83a32.39,32.39,0,0,0,11.79,25,32.25,32.25,0,0,0-7,41.49,86.72,86.72,0,0,0,148.64,0,32.25,32.25,0,0,0-7-41.49,31.82,31.82,0,0,0,5.23-5.46,34.75,34.75,0,0,0,2.7-4.12c12,11.16,28,17.31,45.32,17.31,18,0,34.67-6.65,46.82-18.73l1-1a32.38,32.38,0,0,0,62.19-12.66v-24.2A73.39,73.39,0,0,0,755.55,341a32.19,32.19,0,0,0,56.22,5.83,8.52,8.52,0,0,1,14.09,0A32.17,32.17,0,0,0,882.07,341,73.43,73.43,0,1,0,932.17,214Z"/><path class="c" d="M572.33,246.39v47.32c0,29.63-21.24,49.42-48.36,49.42s-48.38-19.77-48.38-49.42V246.39a14.73,14.73,0,0,1,29.45,0v48.36c0,13.68,8.42,21,18.93,21s18.92-7.36,18.92-21V246.39a14.72,14.72,0,0,1,29.44,0Z"/><path class="c" d="M651.6,245.34A13.65,13.65,0,0,1,638,259h-.05c-12,0-21.66,8.41-21.66,25.86v43.53a14.73,14.73,0,0,1-29.45,0V284.88c0-32.59,22.72-53.17,51.11-53.17a13.65,13.65,0,0,1,13.67,13.62Z"/><path class="c" d="M867.16,281.1v47.32a14.72,14.72,0,0,1-29.43,0V280.06c0-13.68-8.41-21-18.93-21s-18.93,7.36-18.93,21v48.36a14.73,14.73,0,0,1-29.45,0V281.1c0-29.63,21.24-49.43,48.38-49.43S867.16,251.45,867.16,281.1Z"/><path class="c" d="M987.91,287.4a55.78,55.78,0,1,1-55.83-55.73h.09a55.74,55.74,0,0,1,55.74,55.73ZM932.17,259a28.4,28.4,0,1,0,28.4,28.4,28.41,28.41,0,0,0-28.4-28.4Z"/><path class="c" d="M761.15,287.4a55.78,55.78,0,1,1-55.83-55.73h.09a55.74,55.74,0,0,1,55.74,55.73ZM705.41,259a28.4,28.4,0,1,0,28.4,28.4h0A28.41,28.41,0,0,0,705.41,259Z"/><path class="c" d="M356.85,342.83a14.74,14.74,0,0,1-14.74-14.74h0v-82a14.74,14.74,0,0,1,29.47-.72q0,.36,0,.72v82A14.74,14.74,0,0,1,356.85,342.83Z"/><path class="c" d="M450.07,342.83a14.7,14.7,0,0,1-8.89-3l-54.67-41.23a14.73,14.73,0,0,1,.07-23.53l54.68-40.77a14.74,14.74,0,0,1,18.14,23.24l-.51.38-39,29,39,29.39a14.74,14.74,0,0,1-8.88,26.49Z"/><path class="c" d="M403.46,418.9a68.44,68.44,0,0,1-59.13-33.44,14.61,14.61,0,0,1,25-15.06,39.79,39.79,0,0,0,68.19,0,14.61,14.61,0,0,1,25.35,14.53c-.1.18-.21.35-.32.53A68.45,68.45,0,0,1,403.46,418.9Z"/></svg>
@@ -1 +0,0 @@
1
- <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 230.45 324.92"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:#fff;}</style><linearGradient id="linear-gradient" x1="107.38" y1="84.32" x2="127.22" y2="408.64" gradientTransform="translate(13.19 -90.72) rotate(3.5)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00cea7"/><stop offset="0.2" stop-color="#00c3ac"/><stop offset="0.68" stop-color="#00afb5"/><stop offset="1" stop-color="#00a8b8"/></linearGradient></defs><title>K_mark_full_colour</title><path class="cls-1" d="M220.9,195.26A47.28,47.28,0,0,0,211.62,129l-29.32-22.1L211.42,85.2A47.28,47.28,0,0,0,221.06,19,47.55,47.55,0,0,0,183.13,0a46.93,46.93,0,0,0-28.25,9.38L94.58,54.33v-7A47.29,47.29,0,0,0,0,47.29V166.77a47.24,47.24,0,0,0,17.19,36.45A47,47,0,0,0,6.92,263.67a126.37,126.37,0,0,0,216.6,0,47,47,0,0,0-10.27-60.45A47.3,47.3,0,0,0,220.9,195.26Z"/><path class="cls-2" d="M47.29,188.24a21.47,21.47,0,0,1-21.47-21.47V47.29a21.47,21.47,0,0,1,42.94,0V166.77A21.47,21.47,0,0,1,47.29,188.24Z"/><path class="cls-2" d="M183.13,188.24a21.4,21.4,0,0,1-12.92-4.33L90.52,123.84a21.47,21.47,0,0,1,.1-34.35l79.69-59.41A21.48,21.48,0,0,1,196,64.51L139.23,106.8l56.85,42.83a21.47,21.47,0,0,1-13,38.61Z"/><path class="cls-2" d="M115.22,299.1a99.75,99.75,0,0,1-86.17-48.74,21.29,21.29,0,0,1,36.49-21.94,58,58,0,0,0,99.36,0,21.29,21.29,0,0,1,36.49,21.94A99.75,99.75,0,0,1,115.22,299.1Z"/></svg>
Binary file
@@ -1,22 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg width="670px" height="670px" viewBox="0 0 670 670" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
- <!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
4
- <title>ocado-swirl</title>
5
- <desc>Created with Sketch.</desc>
6
- <defs>
7
- <polygon id="path-1" points="5.17780764e-14 0 670 0 670 670 0 670"></polygon>
8
- </defs>
9
- <g id="Play-landing-" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
10
- <g id="AIMMO-Prototype-landing---L-Desktops" transform="translate(-566.000000, -1829.000000)">
11
- <g id="Deliver-through-time-Copy" transform="translate(0.000000, 1829.000000)">
12
- <g id="ocado-swirl" transform="translate(566.000000, 0.000000)">
13
- <mask id="mask-2" fill="white">
14
- <use xlink:href="#path-1"></use>
15
- </mask>
16
- <g id="Clip-2"></g>
17
- <path d="M658.260758,254.973547 C674.312291,312.597644 673.719847,369.91571 657.606601,427.057142 C614.658514,579.343237 470.873555,679.663717 310.541302,669.260735 C156.532567,659.268533 27.1699201,539.8612 3.90825914,386.229804 C-28.5815422,171.653161 145.926171,-15.4115496 362.664044,1.00523855 C421.599894,5.46835385 477.814203,18.1573213 528.562804,49.3950207 C579.57677,80.7970316 617.72359,122.756066 631.654256,182.735982 C654.510668,281.150447 570.864961,412.905801 427.11703,374.563676 C370.388446,359.432627 332.965724,305.567159 334.165012,247.189282 C335.341672,189.838353 374.768007,138.897632 428.873791,125.00919 C446.291238,120.537859 463.73954,119.673169 479.651191,124.787369 C472.920367,137.546169 463.840338,149.321153 460.263045,162.576996 C450.370462,199.222602 471.498913,234.781698 507.712061,246.16028 C543.176426,257.304718 580.146586,238.480764 594.317932,201.288821 C605.61757,171.634676 600.09632,143.516844 583.246632,117.572034 C561.624478,84.2804387 528.931024,66.8942118 491.901208,55.983918 C363.661736,18.1983992 220.981439,115.8406 238.084149,280.285757 C249.902176,393.925751 356.017561,459.58058 441.267805,460.679414 C542.250732,461.981584 635.392002,386.601559 653.712515,287.460014 C655.697614,276.71814 656.767305,265.805792 658.260758,254.973547" id="Fill-1" fill="#F0F0F0" opacity="0.468353714" mask="url(#mask-2)"></path>
18
- </g>
19
- </g>
20
- </g>
21
- </g>
22
- </svg>
Binary file
@@ -1,106 +0,0 @@
1
- /* global showPopupConfirmation */
2
- /* global hidePopupConfirmation */
3
-
4
- function classesText(classes) {
5
- return classes
6
- .map(
7
- (name, index) =>
8
- `${
9
- index === 0
10
- ? ""
11
- : index === classes.length - 1
12
- ? " and "
13
- : ", "
14
- }<strong>${$("<div>").text(name).html()}</strong>`
15
- )
16
- .join("");
17
- }
18
-
19
- function clickDeleteGames() {
20
- let selectedGameIds = [];
21
- let selectedClasses = [];
22
- $("input[name='game_ids']:checked").each(function () {
23
- selectedGameIds.push($(this).val());
24
- selectedClasses.push($(this).data("className"));
25
- });
26
-
27
- if (!selectedGameIds.length) {
28
- return;
29
- }
30
-
31
- let title = "Delete class games";
32
- let text = `
33
- <div class='popup-text'>
34
- <p>Are you sure that you want to delete the game${
35
- selectedClasses.length > 1 ? "s" : ""
36
- } for ${classesText(selectedClasses)}?</p>
37
- <p>This action will delete any progress ${
38
- selectedClasses.length > 1 ? "those classes have" : "that class has"
39
- } made.</p>
40
- </div>`;
41
- let confirmHandler = "deleteGames()";
42
-
43
- showPopupConfirmation(title, text, confirmHandler);
44
- let popup = $(".popup-wrapper");
45
- popup.data("gameIds", selectedGameIds);
46
- }
47
-
48
- function deleteGames() {
49
- let gameIds = $("#popup").data("gameIds");
50
-
51
- $.ajax({
52
- url: "/kurono/api/games/delete_games/",
53
- type: "POST",
54
- data: { game_ids: gameIds },
55
- traditional: true,
56
- headers: {
57
- "X-CSRFToken": $("input[name=csrfmiddlewaretoken]").val(),
58
- },
59
- success: function (data) {
60
- hidePopupConfirmation();
61
- document.location.reload(true);
62
- },
63
- });
64
- }
65
-
66
- function changeWorksheetConfirmation(gameID, className, worksheetID) {
67
- let title = "Change Challenge";
68
- let text =
69
- "<div class='popup-text'><p>Please confirm that you would like to change the challenge for class: " +
70
- "<strong class='popup__class-name'></strong>. This will change the level for the students when they rejoin " +
71
- "the game.</p></div>";
72
- let confirmHandler = "changeWorksheet()";
73
-
74
- showPopupConfirmation(title, text, confirmHandler);
75
- let popup = $(".popup-wrapper");
76
- popup.data("gameId", gameID);
77
- popup.data("worksheetId", worksheetID);
78
- $(".popup__class-name").text(className);
79
- }
80
-
81
- function changeWorksheet() {
82
- let gameID = $("#popup").data("gameId");
83
- let worksheetID = $("#popup").data("worksheetId");
84
-
85
- $.ajax({
86
- url: "/kurono/api/games/" + gameID + "/",
87
- type: "PUT",
88
- data: { worksheet_id: worksheetID },
89
- success: function (data) {
90
- hidePopupConfirmation();
91
- document.location.reload(true);
92
- },
93
- });
94
- }
95
-
96
- $(document).ready(function () {
97
- // Handlers for the games checklist and select all checklist
98
- $('[id^="game_"]').on("click", () => {
99
- $("#gamesListToggle").prop("checked",
100
- $('[id^="game_"]:checked').length === $('[id^="game_"]').length);
101
- });
102
-
103
- $("#gamesListToggle").on("click", () => {
104
- $('[id^="game_"]').prop("checked", $("#gamesListToggle").is(":checked"));
105
- });
106
- });
@@ -1,14 +0,0 @@
1
- function deleteAllLocalStorageWorkspaces(){
2
- if(localStorage) {
3
- var query = /(python|blockly)Workspace(Xml){0,1}-([0-9]+)$/;
4
- var i;
5
- for (i in localStorage) {
6
- if (localStorage.hasOwnProperty(i)) {
7
- var matches = query.exec(i);
8
- if(matches){
9
- localStorage.removeItem(i);
10
- }
11
- }
12
- }
13
- }
14
- };
@@ -1,46 +0,0 @@
1
- // Here we want to send off an ajax request whenever the user types something
2
- // but we want it limited to some rate. This method of setting timeouts will
3
- // unfortunately introduce a delay but it was easy to implement and it ensures
4
- // that every character the user types is considered and the last one cannot
5
- // be missed off.
6
-
7
- var timeout_scheduled = false;
8
- function updateChosenOrgSelect() {
9
- if (!timeout_scheduled) {
10
- timeout_scheduled = true;
11
- update_timeout = setTimeout(function() {
12
- fuzzy_name = $('#' + FUZZY_NAME_FIELD_ID).val();
13
- $.getJSON(FUZZY_ORG_LOOKUP_URL, { fuzzy_name: fuzzy_name }, function(data) {
14
- select = document.getElementById(CHOSEN_ORG_FIELD_ID);
15
- select.options.length = 0;
16
-
17
- if (data.length > 0) {
18
- for (var i = 0; i < data.length; i++) {
19
- var d = data[i];
20
- select.options.add(new Option(d.name + ', ' + d.postcode + ', ' + d.admin_domain, d.id));
21
- }
22
- }
23
- else {
24
- select.options.add(new Option('Select school/club', ''));
25
- select.options[0].disabled = true;
26
- select.options[0].style.display = 'none';
27
- }
28
- });
29
- timeout_scheduled = false;
30
- }, 200);
31
- }
32
- }
33
-
34
- $(function() {
35
- fuzzy_name = $('#' + FUZZY_NAME_FIELD_ID);
36
- if (fuzzy_name.length > 0) { // Only do things if the elements exist!!
37
- fuzzy_name.on('keydown', updateChosenOrgSelect);
38
- fuzzy_name.on('paste', updateChosenOrgSelect);
39
- fuzzy_name.on('cut', updateChosenOrgSelect);
40
-
41
- select = document.getElementById(CHOSEN_ORG_FIELD_ID);
42
- select.options.add(new Option('Select school/club', ''));
43
- select.options[0].disabled = true;
44
- select.options[0].style.display = 'none';
45
- }
46
- });