codeforlife-portal 8.0.1__tar.gz → 8.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codeforlife-portal might be problematic. Click here for more details.
- {codeforlife-portal-8.0.1/codeforlife_portal.egg-info → codeforlife-portal-8.0.3}/PKG-INFO +1 -1
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3/codeforlife_portal.egg-info}/PKG-INFO +1 -1
- codeforlife-portal-8.0.3/portal/__init__.py +1 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/teach.py +57 -152
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_edit_class.html +24 -9
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_class.py +244 -229
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/teacher/teach.py +20 -8
- codeforlife-portal-8.0.1/portal/__init__.py +0 -1
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/LICENSE.md +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/MANIFEST.in +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/README.md +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/codeforlife_portal.egg-info/SOURCES.txt +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/codeforlife_portal.egg-info/dependency_links.txt +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/codeforlife_portal.egg-info/not-zip-safe +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/codeforlife_portal.egg-info/requires.txt +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/codeforlife_portal.egg-info/top_level.txt +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/captcha.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/admin_access.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/basicauth.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/exceptionlogging.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/screentime_warning.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/security.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/middleware/session_timeout.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/static/apple-touch-icon-120x120.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/static/apple-touch-icon-152x152.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/static/apple-touch-icon-180x180.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/static/apple-touch-icon-76x76.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/static/apple-touch-icon.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/static/robots.txt +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/templates/deploy/csrf_failure.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/deploy/views.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/admin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/app_settings.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/backends.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/beta.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/context_processors.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/admin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/dotmailer.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/error_messages.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/invite_teacher.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/organisation.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/play.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/forms/registration.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/handlers.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/captcha.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/decorators.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/password.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/ratelimit.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/regexes.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/helpers/request_handlers.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0001_squashed_0041_new_news.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0042_school_country.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0043_auto_20150430_0952.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0044_auto_20150430_0959.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0045_auto_20150430_1446.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0046_auto_20150723_1101.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0047_remove_userprofile_avatar.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0048_plural_management_frontnews.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0049_refactor_emailverifications.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0050_refactor_emailverifications_2.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0051_add_missing_ev_records.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0052_refactor_emailverifications_3.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0053_refactor_teacher_student_1.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0054_pending_join_request_can_be_blank.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0055_add_preview_user.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0056_remove_preview_user.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0057_delete_frontpagenews.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0058_move_to_common_models.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0059_move_email_verifications_to_common.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0060_delete_guardian.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0061_make_portaladmin_teacher.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/0062_verify_portaladmin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/migrations/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/mixins/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/mixins/cron_mixin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/models.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/permissions/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/permissions/is_cron_request_from_google.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/pipeline_compilers/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/pipeline_compilers/libsass_compiler.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/fonts/bootstrap/glyphicons-halflings-regular.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/10_years_anniversary.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/10x_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/RR_logo_grass_background.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/RR_logo_green.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/RR_logo_simple.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/about_us_cfl.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/about_us_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/about_us_ocado.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/barefoot_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/bcs_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/clubs.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/coding_club_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/coding_club_python_pack.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/colorboxImages/border.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/colorboxImages/controls.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/colorboxImages/loading.gif +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/colorboxImages/loading_background.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/colorboxImages/overlay.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/confirmation_tick.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/cross.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/dee.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/facebook.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/favicon.ico +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/get_involved_hero.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/gitbook.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/gitbook_space.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/github.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/github_hero.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/gla_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/hamburger.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/help_and_support_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/home_educate.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/home_educate_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/home_learning_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/home_play.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/home_play_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/hope_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/howe_dell_1.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/howe_dell_2.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/howe_dell_3.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icl_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_controller.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_free.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_globe.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_piechart.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_step_by_step.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_tracking.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/icon_uk_flag.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/kirsty.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_cfl.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_cfl_powered.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_cfl_reminder_cards.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_cfl_white_landscape.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_ocado.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_ocado_group.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_ocado_group.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_ocado_group_white.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/logo_python_den.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/long_europe_map.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/mc_saatchi_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/nigel.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/ocado-swirl.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/oval_blue.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/oval_pink.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/oval_yellow.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/paper_plane.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/phil.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/polygon_blue.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/polygon_pink.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/polygon_yellow.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/pressure_cooker_logo.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/python_den.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/python_den_banner.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rapid_router.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rapid_router_landing_hero.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rapidrouter.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/resources_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/resources_montage.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/reuben.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rob.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rr_advanced.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rr_beginner.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/rr_intermediate.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/sadface.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/sharon_harrison.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/sian.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/teaching_resources_hero.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/ten_year_map_pin.svg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/thumbnail_educate_rapid_router.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/thumbnail_educate_resources.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/thumbnail_intro_c4l.jpg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/thumbnail_play_rapid_router.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/thumbnail_python_den.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/twitter.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/universities.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/img/wes.png +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/bootstrap.min.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/carouselCards.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/common.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/independentLogin.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/independentRegistration.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/join_create_game_toggle.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/jquery.placeholder.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/levelControl.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/lib/jquery-video-lightning.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/lib/jquery.colorbox.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/lib/jquery.easy-ticker.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/lib/jquery.min.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/lib/modernizr-build.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/lib/papaparse.min.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/organisation_manage.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/passwordStrength.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/play.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/resetPassword.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/riveted.min.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/school.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/sticky_subnav.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/studentLogin.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/teach_browser.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/teach_class.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/teacherEditStudent.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/teacherLogin.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/js/tenYearMap.js +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_alerts.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_badges.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_breadcrumbs.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_button-groups.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_buttons.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_carousel.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_close.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_code.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_component-animations.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_dropdowns.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_forms.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_glyphicons.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_grid.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_input-groups.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_jumbotron.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_labels.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_list-group.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_media.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_mixins.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_modals.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_navbar.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_navs.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_normalize.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_pager.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_pagination.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_panels.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_popovers.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_print.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_progress-bars.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_responsive-embed.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_responsive-utilities.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_scaffolding.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_tables.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_theme.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_thumbnails.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_tooltip.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_type.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_utilities.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_variables.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/_wells.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_alerts.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_background-variant.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_border-radius.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_breakpoints.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_buttons.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_center-block.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_clearfix.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_forms.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_gradients.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_grid-framework.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_grid.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_hide-text.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_image.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_labels.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_list-group.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_nav-divider.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_nav-vertical-align.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_opacity.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_pagination.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_panels.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_progress-bar.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_reset-filter.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_reset-text.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_resize.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_responsive-visibility.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_size.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_tab-focus.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_table-row.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_text-emphasis.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_text-overflow.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_text-truncate.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap/mixins/_vendor-prefixes.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_mixins/_all.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_mixins/_border-radius.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_mixins/_box-shadow.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_mixins/_hover.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_mixins/_nav-divider.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_partials/_dropdown.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_partials/_glyphicons.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_partials/_grid.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_partials/_variables.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_align.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_background.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_borders.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_clearfix.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_cursor.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_display.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_flex.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_float.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_position.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_screenreaders.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_sizing.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_spacing.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_text.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/bootstrap_utilities/_visibility.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/colorbox.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_all.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_animation.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_breakpoints.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_card_constants.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_colours.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_homepage_constants.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_levels.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_mixins.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/modules/_spacing.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_banners.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_base.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_buttons.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_carousel.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_footer.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_forms.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_grids.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_header.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_images.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_popup.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_progress-bars.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_subnavs.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_tables.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_text.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_ui-dialog.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/partials/_utils.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/sass/styles.scss +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/static/portal/video/code for life .pdf +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/about.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/coding_club.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/help_and_support.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/home_learning.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/materials.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/play.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/teach.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/teacher_resources.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/strings/ten_year_map.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/403.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/404.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/500.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/django_recaptcha/includes/js_v2_invisible.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/django_recaptcha/widget_v2_invisible.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/email.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/email.txt +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/about.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/base.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/base_no_userprofile.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/coding_club.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/contribute.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/dotmailer_consent_form.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/email_invitation_sent.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/email_style_template.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/email_verification_failed.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/email_verification_needed.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/form_shapes.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/getinvolved.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/home.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/home_learning.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/locked_out.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/locked_out_school_student.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/login/independent_student.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/login/student.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/login/student_class_code.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/login/teacher.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/mouseflow.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/banner.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/benefits.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/card_list.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/character_list.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/delete_popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/donate_popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/footer.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/header.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/headline.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/hero_card.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/info_popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/invite_admin_teacher.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/register_newsletter_tickbox.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/screentime_popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/service_unavailable_popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/session_popup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/teacher_non_dashboard_subnav.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/partials/teacher_non_dashboard_subnav_account.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/play/student_dashboard.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/play/student_edit_account.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/play/student_join_organisation.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/play.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/privacy_notice.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/register.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/reset_password.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/reset_password_confirm.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/reset_password_done.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/reset_password_email_sent.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/tag_manager/tag_manager_body.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/tag_manager/tag_manager_head.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/base_registering.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/class.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/dashboard.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/invited.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/onboarding_classes.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/onboarding_print.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/onboarding_school.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/onboarding_students.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_add_external_student.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_added_external_student.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_dismiss_students.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_edit_student.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_move_all_classes.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_move_students.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach/teacher_move_students_to_class.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/teach.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/ten_year_map.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/portal/terms.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/_base.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/_wizard_actions.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/_wizard_actions_enable_2fa.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/_wizard_actions_submit.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/_wizard_forms.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/_wizard_forms_token.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/backup_token.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/core/backup_tokens.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/core/login.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/core/setup.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/core/setup_complete.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/profile/disable.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/profile/profile.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templates/two_factor/setup_wizard_token.html +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/app_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/banner_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/benefits_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/card_list_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/future.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/headline_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/hero_card_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/templatetags/table_tags.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/base_test.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/conftest.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_make_portaladmin_teacher.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_preview_user_remove.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_preview_users.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_remove_front_page_news.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_remove_guardian.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_use_common_models.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/migrations/test_migration_verify_portaladmin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/admin/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/admin/admin_base_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/admin/admin_data_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/admin/admin_map_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/base_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/email_verification_needed_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/forbidden_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/game_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/home_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/independent_login_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/password_reset_form_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/password_reset_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/play/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/play/account_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/play/dashboard_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/play/join_school_or_club_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/play/play_base_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/play_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/resources_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/signup_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/student_login_class_code.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/student_login_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/add_independent_student_to_class_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/added_independent_student_to_class_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/class_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/dashboard_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/dismiss_students_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/edit_student_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/move_class_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/move_classes_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/move_students_disambiguate_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/move_students_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/onboarding_classes_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/onboarding_organisation_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/onboarding_student_list_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/onboarding_students_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teach/teach_base_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/pageObjects/portal/teacher_login_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/selenium_test_case.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/snapshots/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/snapshots/snap_test_partials.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_2FA.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_admin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_api.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_captcha_forms.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_emails.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_global_forms.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_helper_methods.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_independent_student.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_invite_teacher.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_middleware.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_organisation.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_partials.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_ratelimit.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_school_student.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_security.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_teacher.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_teacher_student.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/test_views.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/utils/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/utils/classes.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/tests/utils/messages.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/urls.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/about.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/admin.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/api.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/cron/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/cron/user.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/dotmailer.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/email.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/home.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/legal.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/login/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/login/independent_student.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/login/student.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/login/teacher.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/organisation.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/play_landing_page.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/registration.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/student/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/student/edit_account_details.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/student/play.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/teach.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/teacher/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/teacher/dashboard.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/two_factor/__init__.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/two_factor/core.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/two_factor/form.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/views/two_factor/profile.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/portal/wsgi.py +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/pyproject.toml +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/setup.cfg +0 -0
- {codeforlife-portal-8.0.1 → codeforlife-portal-8.0.3}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "8.0.3"
|
|
@@ -3,14 +3,14 @@ import re
|
|
|
3
3
|
from builtins import map, range, str
|
|
4
4
|
|
|
5
5
|
from common.helpers.emails import send_verification_email
|
|
6
|
-
from common.models import Student,
|
|
6
|
+
from common.models import Student, Teacher, UserSession, stripStudentName
|
|
7
7
|
from django import forms
|
|
8
8
|
from django.contrib.auth import authenticate
|
|
9
9
|
from django.contrib.auth.forms import AuthenticationForm
|
|
10
10
|
from django.contrib.auth.models import User
|
|
11
11
|
from django_recaptcha.fields import ReCaptchaField
|
|
12
12
|
from django_recaptcha.widgets import ReCaptchaV2Invisible
|
|
13
|
-
from game.models import Episode
|
|
13
|
+
from game.models import Episode, Worksheet
|
|
14
14
|
|
|
15
15
|
from portal.forms.error_messages import INVALID_LOGIN_MESSAGE
|
|
16
16
|
from portal.helpers.password import PasswordStrength, form_clean_password
|
|
@@ -18,46 +18,34 @@ from portal.helpers.ratelimit import clear_ratelimit_cache_for_user
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class InvitedTeacherForm(forms.Form):
|
|
21
|
-
prefix =
|
|
21
|
+
prefix = "teacher_signup"
|
|
22
22
|
|
|
23
23
|
def __init__(self, *args, **kwargs):
|
|
24
24
|
super().__init__(*args, **kwargs)
|
|
25
25
|
for field_name, field in self.fields.items():
|
|
26
|
-
field.widget.attrs[
|
|
26
|
+
field.widget.attrs["id"] = f"id_teacher_signup-{field_name}"
|
|
27
27
|
|
|
28
28
|
teacher_password = forms.CharField(
|
|
29
29
|
help_text="Enter a password",
|
|
30
|
-
widget=forms.PasswordInput(
|
|
31
|
-
attrs={"autocomplete": "off", "placeholder": "Password"}
|
|
32
|
-
),
|
|
30
|
+
widget=forms.PasswordInput(attrs={"autocomplete": "off", "placeholder": "Password"}),
|
|
33
31
|
)
|
|
34
32
|
teacher_confirm_password = forms.CharField(
|
|
35
33
|
help_text="Repeat password",
|
|
36
|
-
widget=forms.PasswordInput(
|
|
37
|
-
attrs={"autocomplete": "off", "placeholder": "Repeat password"}
|
|
38
|
-
),
|
|
34
|
+
widget=forms.PasswordInput(attrs={"autocomplete": "off", "placeholder": "Repeat password"}),
|
|
39
35
|
)
|
|
40
36
|
|
|
41
|
-
consent_ticked = forms.BooleanField(
|
|
42
|
-
|
|
43
|
-
)
|
|
44
|
-
newsletter_ticked = forms.BooleanField(
|
|
45
|
-
widget=forms.CheckboxInput(), initial=False, required=False
|
|
46
|
-
)
|
|
37
|
+
consent_ticked = forms.BooleanField(widget=forms.CheckboxInput(), initial=False, required=True)
|
|
38
|
+
newsletter_ticked = forms.BooleanField(widget=forms.CheckboxInput(), initial=False, required=False)
|
|
47
39
|
|
|
48
40
|
def clean_teacher_password(self):
|
|
49
|
-
return form_clean_password(
|
|
50
|
-
self, "teacher_password", PasswordStrength.TEACHER
|
|
51
|
-
)
|
|
41
|
+
return form_clean_password(self, "teacher_password", PasswordStrength.TEACHER)
|
|
52
42
|
|
|
53
43
|
def clean(self):
|
|
54
44
|
if any(self.errors):
|
|
55
45
|
return
|
|
56
46
|
|
|
57
47
|
password = self.cleaned_data.get("teacher_password", None)
|
|
58
|
-
confirm_password = self.cleaned_data.get(
|
|
59
|
-
"teacher_confirm_password", None
|
|
60
|
-
)
|
|
48
|
+
confirm_password = self.cleaned_data.get("teacher_confirm_password", None)
|
|
61
49
|
|
|
62
50
|
check_passwords(password, confirm_password)
|
|
63
51
|
|
|
@@ -68,22 +56,16 @@ class TeacherSignupForm(InvitedTeacherForm):
|
|
|
68
56
|
teacher_first_name = forms.CharField(
|
|
69
57
|
help_text="Enter your first name",
|
|
70
58
|
max_length=100,
|
|
71
|
-
widget=forms.TextInput(
|
|
72
|
-
attrs={"autocomplete": "off", "placeholder": "First name"}
|
|
73
|
-
),
|
|
59
|
+
widget=forms.TextInput(attrs={"autocomplete": "off", "placeholder": "First name"}),
|
|
74
60
|
)
|
|
75
61
|
teacher_last_name = forms.CharField(
|
|
76
62
|
help_text="Enter your last name",
|
|
77
63
|
max_length=100,
|
|
78
|
-
widget=forms.TextInput(
|
|
79
|
-
attrs={"autocomplete": "off", "placeholder": "Last name"}
|
|
80
|
-
),
|
|
64
|
+
widget=forms.TextInput(attrs={"autocomplete": "off", "placeholder": "Last name"}),
|
|
81
65
|
)
|
|
82
66
|
teacher_email = forms.EmailField(
|
|
83
67
|
help_text="Enter your email address",
|
|
84
|
-
widget=forms.EmailInput(
|
|
85
|
-
attrs={"autocomplete": "off", "placeholder": "Email address"}
|
|
86
|
-
),
|
|
68
|
+
widget=forms.EmailInput(attrs={"autocomplete": "off", "placeholder": "Email address"}),
|
|
87
69
|
)
|
|
88
70
|
|
|
89
71
|
captcha = ReCaptchaField(widget=ReCaptchaV2Invisible)
|
|
@@ -92,37 +74,27 @@ class TeacherSignupForm(InvitedTeacherForm):
|
|
|
92
74
|
class TeacherEditAccountForm(forms.Form):
|
|
93
75
|
first_name = forms.CharField(
|
|
94
76
|
max_length=100,
|
|
95
|
-
widget=forms.TextInput(
|
|
96
|
-
attrs={"placeholder": "First name", "class": "fName"}
|
|
97
|
-
),
|
|
77
|
+
widget=forms.TextInput(attrs={"placeholder": "First name", "class": "fName"}),
|
|
98
78
|
help_text="First name",
|
|
99
79
|
)
|
|
100
80
|
last_name = forms.CharField(
|
|
101
81
|
max_length=100,
|
|
102
|
-
widget=forms.TextInput(
|
|
103
|
-
attrs={"placeholder": "Last name", "class": "lName"}
|
|
104
|
-
),
|
|
82
|
+
widget=forms.TextInput(attrs={"placeholder": "Last name", "class": "lName"}),
|
|
105
83
|
help_text="Last name",
|
|
106
84
|
)
|
|
107
85
|
email = forms.EmailField(
|
|
108
86
|
required=False,
|
|
109
|
-
widget=forms.EmailInput(
|
|
110
|
-
attrs={"placeholder": "New email address (optional)"}
|
|
111
|
-
),
|
|
87
|
+
widget=forms.EmailInput(attrs={"placeholder": "New email address (optional)"}),
|
|
112
88
|
help_text="New email address (optional)",
|
|
113
89
|
)
|
|
114
90
|
password = forms.CharField(
|
|
115
91
|
required=False,
|
|
116
|
-
widget=forms.PasswordInput(
|
|
117
|
-
attrs={"placeholder": "New password (optional)"}
|
|
118
|
-
),
|
|
92
|
+
widget=forms.PasswordInput(attrs={"placeholder": "New password (optional)"}),
|
|
119
93
|
help_text="New password (optional)",
|
|
120
94
|
)
|
|
121
95
|
confirm_password = forms.CharField(
|
|
122
96
|
required=False,
|
|
123
|
-
widget=forms.PasswordInput(
|
|
124
|
-
attrs={"placeholder": "Confirm new password (optional)"}
|
|
125
|
-
),
|
|
97
|
+
widget=forms.PasswordInput(attrs={"placeholder": "Confirm new password (optional)"}),
|
|
126
98
|
help_text="Confirm new password (optional)",
|
|
127
99
|
)
|
|
128
100
|
current_password = forms.CharField(
|
|
@@ -149,9 +121,7 @@ class TeacherEditAccountForm(forms.Form):
|
|
|
149
121
|
|
|
150
122
|
return self.cleaned_data
|
|
151
123
|
|
|
152
|
-
def check_password_errors(
|
|
153
|
-
self, password, confirm_password, current_password
|
|
154
|
-
):
|
|
124
|
+
def check_password_errors(self, password, confirm_password, current_password):
|
|
155
125
|
check_passwords(password, confirm_password)
|
|
156
126
|
|
|
157
127
|
if not self.user.check_password(current_password):
|
|
@@ -160,15 +130,11 @@ class TeacherEditAccountForm(forms.Form):
|
|
|
160
130
|
|
|
161
131
|
class TeacherLoginForm(AuthenticationForm):
|
|
162
132
|
username = forms.EmailField(
|
|
163
|
-
widget=forms.EmailInput(
|
|
164
|
-
attrs={"autocomplete": "off", "placeholder": "Email address"}
|
|
165
|
-
),
|
|
133
|
+
widget=forms.EmailInput(attrs={"autocomplete": "off", "placeholder": "Email address"}),
|
|
166
134
|
help_text="Enter your email address",
|
|
167
135
|
)
|
|
168
136
|
password = forms.CharField(
|
|
169
|
-
widget=forms.PasswordInput(
|
|
170
|
-
attrs={"autocomplete": "off", "placeholder": "Password"}
|
|
171
|
-
),
|
|
137
|
+
widget=forms.PasswordInput(attrs={"autocomplete": "off", "placeholder": "Password"}),
|
|
172
138
|
help_text="Enter your password",
|
|
173
139
|
)
|
|
174
140
|
|
|
@@ -202,9 +168,7 @@ class TeacherLoginForm(AuthenticationForm):
|
|
|
202
168
|
users = User.objects.filter(email=email)
|
|
203
169
|
|
|
204
170
|
for result in users:
|
|
205
|
-
if hasattr(result, "userprofile") and hasattr(
|
|
206
|
-
result.userprofile, "teacher"
|
|
207
|
-
):
|
|
171
|
+
if hasattr(result, "userprofile") and hasattr(result.userprofile, "teacher"):
|
|
208
172
|
user = result
|
|
209
173
|
break
|
|
210
174
|
|
|
@@ -286,9 +250,7 @@ class ClassEditForm(forms.Form):
|
|
|
286
250
|
[
|
|
287
251
|
(
|
|
288
252
|
str(hours),
|
|
289
|
-
"Allow external requests to this class for the next "
|
|
290
|
-
+ str(hours)
|
|
291
|
-
+ " hours",
|
|
253
|
+
"Allow external requests to this class for the next " + str(hours) + " hours",
|
|
292
254
|
)
|
|
293
255
|
for hours in range(4, 28, 4)
|
|
294
256
|
]
|
|
@@ -297,9 +259,7 @@ class ClassEditForm(forms.Form):
|
|
|
297
259
|
[
|
|
298
260
|
(
|
|
299
261
|
str(days * 24),
|
|
300
|
-
"Allow external requests to this class for the next "
|
|
301
|
-
+ str(days)
|
|
302
|
-
+ " days",
|
|
262
|
+
"Allow external requests to this class for the next " + str(days) + " days",
|
|
303
263
|
)
|
|
304
264
|
for days in range(2, 5)
|
|
305
265
|
]
|
|
@@ -333,18 +293,22 @@ class ClassLevelControlForm(forms.Form):
|
|
|
333
293
|
def __init__(self, *args, **kwargs):
|
|
334
294
|
super(ClassLevelControlForm, self).__init__(*args, **kwargs)
|
|
335
295
|
|
|
336
|
-
episodes = Episode.objects.filter(pk__in=range(1,
|
|
296
|
+
episodes = Episode.objects.filter(pk__in=range(1, 25))
|
|
337
297
|
|
|
338
298
|
for episode in episodes:
|
|
339
|
-
|
|
340
|
-
|
|
299
|
+
choices = []
|
|
341
300
|
for level in episode.levels:
|
|
342
|
-
|
|
301
|
+
try:
|
|
302
|
+
choices.append((f"worksheet:{level.after_worksheet.id}", episode.name))
|
|
303
|
+
except Worksheet.DoesNotExist:
|
|
304
|
+
pass
|
|
305
|
+
choices.append((f"level:{level.id}", level.name))
|
|
343
306
|
|
|
344
|
-
|
|
307
|
+
for worksheet in episode.worksheets.filter(before_level__isnull=True):
|
|
308
|
+
choices.append((f"worksheet:{worksheet.id}", episode.name))
|
|
345
309
|
|
|
346
310
|
self.fields[episode.name] = forms.MultipleChoiceField(
|
|
347
|
-
choices=itertools.chain(
|
|
311
|
+
choices=itertools.chain(choices),
|
|
348
312
|
widget=forms.CheckboxSelectMultiple(),
|
|
349
313
|
required=False,
|
|
350
314
|
)
|
|
@@ -364,9 +328,7 @@ class ClassMoveForm(forms.Form):
|
|
|
364
328
|
teacher_choices.append(
|
|
365
329
|
(
|
|
366
330
|
teacher.id,
|
|
367
|
-
teacher.new_user.first_name
|
|
368
|
-
+ " "
|
|
369
|
-
+ teacher.new_user.last_name,
|
|
331
|
+
teacher.new_user.first_name + " " + teacher.new_user.last_name,
|
|
370
332
|
)
|
|
371
333
|
)
|
|
372
334
|
super(ClassMoveForm, self).__init__(*args, **kwargs)
|
|
@@ -389,24 +351,14 @@ class TeacherEditStudentForm(forms.Form):
|
|
|
389
351
|
name = stripStudentName(self.cleaned_data.get("name", ""))
|
|
390
352
|
|
|
391
353
|
if name == "":
|
|
392
|
-
raise forms.ValidationError(
|
|
393
|
-
"'"
|
|
394
|
-
+ self.cleaned_data.get("name", "")
|
|
395
|
-
+ "' is not a valid name"
|
|
396
|
-
)
|
|
354
|
+
raise forms.ValidationError("'" + self.cleaned_data.get("name", "") + "' is not a valid name")
|
|
397
355
|
|
|
398
356
|
if re.match(re.compile("^[\w -]+$"), name) is None:
|
|
399
|
-
raise forms.ValidationError(
|
|
400
|
-
"Names may only contain letters, numbers, dashes, underscores, and spaces."
|
|
401
|
-
)
|
|
357
|
+
raise forms.ValidationError("Names may only contain letters, numbers, dashes, underscores, and spaces.")
|
|
402
358
|
|
|
403
|
-
students = Student.objects.filter(
|
|
404
|
-
class_field=self.klass, new_user__first_name__iexact=name
|
|
405
|
-
)
|
|
359
|
+
students = Student.objects.filter(class_field=self.klass, new_user__first_name__iexact=name)
|
|
406
360
|
if students.exists() and students[0] != self.student:
|
|
407
|
-
raise forms.ValidationError(
|
|
408
|
-
"There is already a student called '" + name + "' in this class"
|
|
409
|
-
)
|
|
361
|
+
raise forms.ValidationError("There is already a student called '" + name + "' in this class")
|
|
410
362
|
|
|
411
363
|
return name
|
|
412
364
|
|
|
@@ -415,16 +367,12 @@ class TeacherSetStudentPass(forms.Form):
|
|
|
415
367
|
password = forms.CharField(
|
|
416
368
|
label="New password",
|
|
417
369
|
help_text="Enter new password",
|
|
418
|
-
widget=forms.PasswordInput(
|
|
419
|
-
attrs={"autocomplete": "off", "placeholder": "Enter new password"}
|
|
420
|
-
),
|
|
370
|
+
widget=forms.PasswordInput(attrs={"autocomplete": "off", "placeholder": "Enter new password"}),
|
|
421
371
|
)
|
|
422
372
|
confirm_password = forms.CharField(
|
|
423
373
|
label="Confirm new password",
|
|
424
374
|
help_text="Confirm new password",
|
|
425
|
-
widget=forms.PasswordInput(
|
|
426
|
-
attrs={"autocomplete": "off", "placeholder": "Confirm new password"}
|
|
427
|
-
),
|
|
375
|
+
widget=forms.PasswordInput(attrs={"autocomplete": "off", "placeholder": "Confirm new password"}),
|
|
428
376
|
)
|
|
429
377
|
|
|
430
378
|
def clean_password(self):
|
|
@@ -468,32 +416,19 @@ def validateStudentNames(klass, names):
|
|
|
468
416
|
|
|
469
417
|
def find_clashes(names, students, clashes_found, validationErrors):
|
|
470
418
|
for name in names:
|
|
471
|
-
if (
|
|
472
|
-
students.filter(new_user__first_name__iexact=name).exists()
|
|
473
|
-
and name not in clashes_found
|
|
474
|
-
):
|
|
419
|
+
if students.filter(new_user__first_name__iexact=name).exists() and name not in clashes_found:
|
|
475
420
|
validationErrors.append(
|
|
476
|
-
forms.ValidationError(
|
|
477
|
-
"There is already a student called '"
|
|
478
|
-
+ name
|
|
479
|
-
+ "' in this class"
|
|
480
|
-
)
|
|
421
|
+
forms.ValidationError("There is already a student called '" + name + "' in this class")
|
|
481
422
|
)
|
|
482
423
|
clashes_found.append(name)
|
|
483
424
|
|
|
484
425
|
|
|
485
426
|
def find_duplicates(names, lower_names, validationErrors):
|
|
486
427
|
duplicates_found = []
|
|
487
|
-
for duplicate in [
|
|
488
|
-
name for name in names if lower_names.count(name.lower()) > 1
|
|
489
|
-
]:
|
|
428
|
+
for duplicate in [name for name in names if lower_names.count(name.lower()) > 1]:
|
|
490
429
|
if duplicate not in duplicates_found:
|
|
491
430
|
validationErrors.append(
|
|
492
|
-
forms.ValidationError(
|
|
493
|
-
"You cannot add more than one student called '"
|
|
494
|
-
+ duplicate
|
|
495
|
-
+ "'"
|
|
496
|
-
)
|
|
431
|
+
forms.ValidationError("You cannot add more than one student called '" + duplicate + "'")
|
|
497
432
|
)
|
|
498
433
|
duplicates_found.append(duplicate)
|
|
499
434
|
|
|
@@ -512,9 +447,7 @@ def find_illegal_characters(names, validationErrors):
|
|
|
512
447
|
|
|
513
448
|
def check_passwords(password, confirm_password):
|
|
514
449
|
if password is not None and password != confirm_password:
|
|
515
|
-
raise forms.ValidationError(
|
|
516
|
-
"The password and the confirmation password do not match"
|
|
517
|
-
)
|
|
450
|
+
raise forms.ValidationError("The password and the confirmation password do not match")
|
|
518
451
|
|
|
519
452
|
|
|
520
453
|
class TeacherMoveStudentsDestinationForm(forms.Form):
|
|
@@ -539,9 +472,7 @@ class TeacherMoveStudentsDestinationForm(forms.Form):
|
|
|
539
472
|
+ klass.teacher.new_user.last_name,
|
|
540
473
|
)
|
|
541
474
|
)
|
|
542
|
-
super(TeacherMoveStudentsDestinationForm, self).__init__(
|
|
543
|
-
*args, **kwargs
|
|
544
|
-
)
|
|
475
|
+
super(TeacherMoveStudentsDestinationForm, self).__init__(*args, **kwargs)
|
|
545
476
|
self.fields["new_class"].choices = class_choices
|
|
546
477
|
|
|
547
478
|
|
|
@@ -558,28 +489,20 @@ class TeacherMoveStudentDisambiguationForm(forms.Form):
|
|
|
558
489
|
)
|
|
559
490
|
name = forms.CharField(
|
|
560
491
|
label="Name",
|
|
561
|
-
widget=forms.TextInput(
|
|
562
|
-
attrs={"placeholder": "Name", "style": "margin : 0px"}
|
|
563
|
-
),
|
|
492
|
+
widget=forms.TextInput(attrs={"placeholder": "Name", "style": "margin : 0px"}),
|
|
564
493
|
)
|
|
565
494
|
|
|
566
495
|
def clean_name(self):
|
|
567
496
|
name = stripStudentName(self.cleaned_data.get("name", ""))
|
|
568
497
|
if name == "":
|
|
569
|
-
raise forms.ValidationError(
|
|
570
|
-
"'"
|
|
571
|
-
+ self.cleaned_data.get("name", "")
|
|
572
|
-
+ "' is not a valid name"
|
|
573
|
-
)
|
|
498
|
+
raise forms.ValidationError("'" + self.cleaned_data.get("name", "") + "' is not a valid name")
|
|
574
499
|
return name
|
|
575
500
|
|
|
576
501
|
|
|
577
502
|
class BaseTeacherMoveStudentsDisambiguationFormSet(forms.BaseFormSet):
|
|
578
503
|
def __init__(self, destination, *args, **kwargs):
|
|
579
504
|
self.destination = destination
|
|
580
|
-
super(BaseTeacherMoveStudentsDisambiguationFormSet, self).__init__(
|
|
581
|
-
*args, **kwargs
|
|
582
|
-
)
|
|
505
|
+
super(BaseTeacherMoveStudentsDisambiguationFormSet, self).__init__(*args, **kwargs)
|
|
583
506
|
|
|
584
507
|
def clean(self):
|
|
585
508
|
if any(self.errors):
|
|
@@ -608,34 +531,24 @@ class TeacherDismissStudentsForm(forms.Form):
|
|
|
608
531
|
)
|
|
609
532
|
name = forms.CharField(
|
|
610
533
|
help_text="New student name",
|
|
611
|
-
widget=forms.TextInput(
|
|
612
|
-
attrs={"placeholder": "Enter new student name", "class": "m-0"}
|
|
613
|
-
),
|
|
534
|
+
widget=forms.TextInput(attrs={"placeholder": "Enter new student name", "class": "m-0"}),
|
|
614
535
|
)
|
|
615
536
|
email = forms.EmailField(
|
|
616
537
|
label="Email",
|
|
617
538
|
help_text="New email address",
|
|
618
|
-
widget=forms.EmailInput(
|
|
619
|
-
attrs={"placeholder": "Enter email address", "class": "m-0"}
|
|
620
|
-
),
|
|
539
|
+
widget=forms.EmailInput(attrs={"placeholder": "Enter email address", "class": "m-0"}),
|
|
621
540
|
)
|
|
622
541
|
confirm_email = forms.EmailField(
|
|
623
542
|
label="Confirm Email",
|
|
624
543
|
help_text="Confirm email address",
|
|
625
|
-
widget=forms.EmailInput(
|
|
626
|
-
attrs={"placeholder": "Confirm email address", "class": "m-0"}
|
|
627
|
-
),
|
|
544
|
+
widget=forms.EmailInput(attrs={"placeholder": "Confirm email address", "class": "m-0"}),
|
|
628
545
|
)
|
|
629
546
|
|
|
630
547
|
def clean_name(self):
|
|
631
548
|
name = stripStudentName(self.cleaned_data.get("name", ""))
|
|
632
549
|
|
|
633
550
|
if name == "":
|
|
634
|
-
raise forms.ValidationError(
|
|
635
|
-
"'"
|
|
636
|
-
+ self.cleaned_data.get("name", "")
|
|
637
|
-
+ "' is not a valid name"
|
|
638
|
-
)
|
|
551
|
+
raise forms.ValidationError("'" + self.cleaned_data.get("name", "") + "' is not a valid name")
|
|
639
552
|
|
|
640
553
|
return name
|
|
641
554
|
|
|
@@ -706,17 +619,9 @@ class TeacherAddExternalStudentForm(forms.Form):
|
|
|
706
619
|
name = stripStudentName(self.cleaned_data.get("name", ""))
|
|
707
620
|
|
|
708
621
|
if name == "":
|
|
709
|
-
raise forms.ValidationError(
|
|
710
|
-
"'"
|
|
711
|
-
+ self.cleaned_data.get("name", "")
|
|
712
|
-
+ "' is not a valid name"
|
|
713
|
-
)
|
|
622
|
+
raise forms.ValidationError("'" + self.cleaned_data.get("name", "") + "' is not a valid name")
|
|
714
623
|
|
|
715
|
-
if Student.objects.filter(
|
|
716
|
-
|
|
717
|
-
).exists():
|
|
718
|
-
raise forms.ValidationError(
|
|
719
|
-
"There is already a student called '" + name + "' in this class"
|
|
720
|
-
)
|
|
624
|
+
if Student.objects.filter(class_field=self.klass, new_user__first_name__iexact=name).exists():
|
|
625
|
+
raise forms.ValidationError("There is already a student called '" + name + "' in this class")
|
|
721
626
|
|
|
722
627
|
return name
|
|
@@ -13,9 +13,14 @@
|
|
|
13
13
|
// Uncheck the checkboxes that correspond to the already-locked levels
|
|
14
14
|
$(document).ready(function(){
|
|
15
15
|
const lockedLevelsIds = {{ locked_levels }};
|
|
16
|
+
const lockedWorksheetIds = {{ locked_worksheet_ids }};
|
|
16
17
|
|
|
17
18
|
lockedLevelsIds.forEach(function(lockedLevelId) {
|
|
18
|
-
const selector = `[value="
|
|
19
|
+
const selector = `[value="level:${lockedLevelId}"]`;
|
|
20
|
+
$(selector).click();
|
|
21
|
+
})
|
|
22
|
+
lockedWorksheetIds.forEach(function(lockedWorksheetId) {
|
|
23
|
+
const selector = `[value="worksheet:${lockedWorksheetId}"]`;
|
|
19
24
|
$(selector).click();
|
|
20
25
|
})
|
|
21
26
|
})
|
|
@@ -147,20 +152,21 @@
|
|
|
147
152
|
</label>
|
|
148
153
|
</div>
|
|
149
154
|
{% for episode in python_episodes %}
|
|
150
|
-
{% if episode.levels %}
|
|
151
155
|
<div class="panel">
|
|
152
156
|
<div class="panel-header bg--{{ episode.difficulty }}" id="episode-{{episode.id}}">
|
|
153
157
|
<div class="d-flex align-items-center justify-content-end" data-toggle="collapse"
|
|
154
158
|
data-target="#collapse-{{episode.id}}" aria-expanded="false"
|
|
155
159
|
aria-controls="collapse-{{episode.id}}" data-parent="#episodes">
|
|
156
160
|
<p class="episode-title flex-grow-1">{{episode.name}}</p>
|
|
157
|
-
{% if episode.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
{% if episode.last_level > 1009 %}
|
|
161
|
-
<span>Levels {{episode.first_level|stringformat:"i"|slice:"3:4"}}-{{episode.last_level|stringformat:"i"|slice:"2:4"}}</span>
|
|
161
|
+
{% if episode.levels %}
|
|
162
|
+
{% if episode.first_level > 1009 %}
|
|
163
|
+
<span>Levels {{episode.first_level|stringformat:"i"|slice:"2:4"}}-{{episode.last_level|stringformat:"i"|slice:"2:4"}}</span>
|
|
162
164
|
{% else %}
|
|
163
|
-
|
|
165
|
+
{% if episode.last_level > 1009 %}
|
|
166
|
+
<span>Levels {{episode.first_level|stringformat:"i"|slice:"3:4"}}-{{episode.last_level|stringformat:"i"|slice:"2:4"}}</span>
|
|
167
|
+
{% else %}
|
|
168
|
+
<span>Levels {{episode.first_level|stringformat:"i"|slice:"3:4"}}-{{episode.last_level|stringformat:"i"|slice:"3:4"}}</span>
|
|
169
|
+
{% endif %}
|
|
164
170
|
{% endif %}
|
|
165
171
|
{% endif %}
|
|
166
172
|
<div class="episode_range_text collapsed d-flex align-items-center justify-content-end"
|
|
@@ -177,12 +183,22 @@
|
|
|
177
183
|
<div class="panel-body d-flex justify-content-between">
|
|
178
184
|
<div class="d-flex flex-grow-1 flex-column justify-content-between">
|
|
179
185
|
{% for level in episode.levels %}
|
|
186
|
+
{% for worksheet in episode.worksheets %}
|
|
187
|
+
{% if worksheet.before_level == level.id %}
|
|
188
|
+
<p>{{episode.name}}</p>
|
|
189
|
+
{% endif %}
|
|
190
|
+
{% endfor %}
|
|
180
191
|
{% if level.name < 1010 %}
|
|
181
192
|
<p>{{level.name|stringformat:"i"|slice:"3:4"}}: {{level.title.strip | safe}}</p>
|
|
182
193
|
{% else %}
|
|
183
194
|
<p>{{level.name|stringformat:"i"|slice:"2:4"}}: {{level.title.strip | safe}}</p>
|
|
184
195
|
{% endif %}
|
|
185
196
|
{% endfor %}
|
|
197
|
+
{% for worksheet in episode.worksheets %}
|
|
198
|
+
{% if not worksheet.before_level %}
|
|
199
|
+
<p>{{episode.name}}{% if episode.worksheets|length > 1 %} pt. {{ forloop.counter }}{% endif %}</p>
|
|
200
|
+
{% endif %}
|
|
201
|
+
{% endfor %}
|
|
186
202
|
</div>
|
|
187
203
|
<div class="form__checkbox flex-column justify-content-between p-0">
|
|
188
204
|
{% for input in level_control_form|get_dict_item:episode.name %}
|
|
@@ -194,7 +210,6 @@
|
|
|
194
210
|
</div>
|
|
195
211
|
</div>
|
|
196
212
|
</div>
|
|
197
|
-
{% endif %}
|
|
198
213
|
{% endfor %}
|
|
199
214
|
</div>
|
|
200
215
|
|