codeforlife-portal 8.0.0__py2.py3-none-any.whl → 8.0.2__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of codeforlife-portal might be problematic. Click here for more details.

@@ -1,4 +1,5 @@
1
1
  import re
2
+ import typing as t
2
3
  from datetime import timedelta
3
4
  from uuid import uuid4
4
5
 
@@ -7,6 +8,10 @@ from django.db import models
7
8
  from django.utils import timezone
8
9
  from django_countries.fields import CountryField
9
10
 
11
+ if t.TYPE_CHECKING:
12
+ from django.db.models import ManyToManyField
13
+ from game.models import Worksheet
14
+
10
15
 
11
16
  class UserProfile(models.Model):
12
17
  user = models.OneToOneField(User, on_delete=models.CASCADE)
@@ -43,9 +48,7 @@ class SchoolModelManager(models.Manager):
43
48
 
44
49
  class School(models.Model):
45
50
  name = models.CharField(max_length=200, unique=True)
46
- country = CountryField(
47
- blank_label="(select country)", null=True, blank=True
48
- )
51
+ country = CountryField(blank_label="(select country)", null=True, blank=True)
49
52
  # TODO: Create an Address model to house address details
50
53
  county = models.CharField(max_length=50, blank=True, null=True)
51
54
  creation_time = models.DateTimeField(default=timezone.now, null=True)
@@ -68,11 +71,7 @@ class School(models.Model):
68
71
 
69
72
  def admins(self):
70
73
  teachers = self.teacher_school.all()
71
- return (
72
- [teacher for teacher in teachers if teacher.is_admin]
73
- if teachers
74
- else None
75
- )
74
+ return [teacher for teacher in teachers if teacher.is_admin] if teachers else None
76
75
 
77
76
  def anonymise(self):
78
77
  self.name = uuid4().hex
@@ -130,10 +129,7 @@ class Teacher(models.Model):
130
129
  def teaches(self, userprofile):
131
130
  if hasattr(userprofile, "student"):
132
131
  student = userprofile.student
133
- return (
134
- not student.is_independent()
135
- and student.class_field.teacher == self
136
- )
132
+ return not student.is_independent() and student.class_field.teacher == self
137
133
 
138
134
  def has_school(self):
139
135
  return self.school is not (None or "")
@@ -165,14 +161,10 @@ class SchoolTeacherInvitation(models.Model):
165
161
  null=True,
166
162
  on_delete=models.SET_NULL,
167
163
  )
168
- invited_teacher_first_name = models.CharField(
169
- max_length=150
170
- ) # Same as User model
164
+ invited_teacher_first_name = models.CharField(max_length=150) # Same as User model
171
165
  # TODO: Make not nullable once data has been transferred
172
166
  _invited_teacher_first_name = models.BinaryField(null=True, blank=True)
173
- invited_teacher_last_name = models.CharField(
174
- max_length=150
175
- ) # Same as User model
167
+ invited_teacher_last_name = models.CharField(max_length=150) # Same as User model
176
168
  # TODO: Make not nullable once data has been transferred
177
169
  _invited_teacher_last_name = models.BinaryField(null=True, blank=True)
178
170
  # TODO: Switch to a CharField to be able to hold hashed value
@@ -222,10 +214,10 @@ class ClassModelManager(models.Manager):
222
214
 
223
215
 
224
216
  class Class(models.Model):
217
+ locked_worksheets: "ManyToManyField[Worksheet]"
218
+
225
219
  name = models.CharField(max_length=200)
226
- teacher = models.ForeignKey(
227
- Teacher, related_name="class_teacher", on_delete=models.CASCADE
228
- )
220
+ teacher = models.ForeignKey(Teacher, related_name="class_teacher", on_delete=models.CASCADE)
229
221
  access_code = models.CharField(max_length=5, null=True)
230
222
  classmates_data_viewable = models.BooleanField(default=False)
231
223
  always_accept_requests = models.BooleanField(default=False)
@@ -249,9 +241,7 @@ class Class(models.Model):
249
241
  def active_game(self):
250
242
  games = self.game_set.filter(game_class=self, is_archived=False)
251
243
  if len(games) >= 1:
252
- assert (
253
- len(games) == 1
254
- ) # there should NOT be more than one active game
244
+ assert len(games) == 1 # there should NOT be more than one active game
255
245
  return games[0]
256
246
  return None
257
247
 
@@ -261,13 +251,8 @@ class Class(models.Model):
261
251
 
262
252
  def get_requests_message(self):
263
253
  if self.always_accept_requests:
264
- external_requests_message = (
265
- "This class is currently set to always accept requests."
266
- )
267
- elif (
268
- self.accept_requests_until is not None
269
- and (self.accept_requests_until - timezone.now()) >= timedelta()
270
- ):
254
+ external_requests_message = "This class is currently set to always accept requests."
255
+ elif self.accept_requests_until is not None and (self.accept_requests_until - timezone.now()) >= timedelta():
271
256
  external_requests_message = (
272
257
  "This class is accepting external requests until "
273
258
  + self.accept_requests_until.strftime("%d-%m-%Y %H:%M")
@@ -275,9 +260,7 @@ class Class(models.Model):
275
260
  + timezone.get_current_timezone_name()
276
261
  )
277
262
  else:
278
- external_requests_message = (
279
- "This class is not currently accepting external requests."
280
- )
263
+ external_requests_message = "This class is not currently accepting external requests."
281
264
 
282
265
  return external_requests_message
283
266
 
@@ -299,9 +282,7 @@ class UserSession(models.Model):
299
282
  login_time = models.DateTimeField(default=timezone.now)
300
283
  school = models.ForeignKey(School, null=True, on_delete=models.SET_NULL)
301
284
  class_field = models.ForeignKey(Class, null=True, on_delete=models.SET_NULL)
302
- login_type = models.CharField(
303
- max_length=100, null=True
304
- ) # for student login
285
+ login_type = models.CharField(max_length=100, null=True) # for student login
305
286
 
306
287
  def __str__(self):
307
288
  return f"{self.user} login: {self.login_time} type: {self.login_type}"
@@ -330,9 +311,7 @@ class StudentModelManager(models.Manager):
330
311
  )
331
312
 
332
313
  def independentStudentFactory(self, name, email, password):
333
- user = User.objects.create_user(
334
- username=email, email=email, password=password, first_name=name
335
- )
314
+ user = User.objects.create_user(username=email, email=email, password=password, first_name=name)
336
315
 
337
316
  user_profile = UserProfile.objects.create(user=user)
338
317
 
@@ -391,9 +370,7 @@ class JoinReleaseStudent(models.Model):
391
370
  JOIN = "join"
392
371
  RELEASE = "release"
393
372
 
394
- student = models.ForeignKey(
395
- Student, related_name="student", on_delete=models.CASCADE
396
- )
373
+ student = models.ForeignKey(Student, related_name="student", on_delete=models.CASCADE)
397
374
  # either "release" or "join"
398
375
  action_type = models.CharField(max_length=64)
399
376
  action_time = models.DateTimeField(default=timezone.now)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codeforlife-portal
3
- Version: 8.0.0
3
+ Version: 8.0.2
4
4
  Classifier: Programming Language :: Python
5
5
  Classifier: Programming Language :: Python :: 3.12
6
6
  Classifier: Framework :: Django
@@ -6,7 +6,7 @@ cfl_common/common/apps.py,sha256=49UXZ3bSkFKvIEOL4zM7y1sAhccQJyRtsoOg5XVd_8Y,129
6
6
  cfl_common/common/context_processors.py,sha256=X0iuX5qu9kMWa7q8osE9CJ2LgM7pPOYQFGdjm8X3rk0,236
7
7
  cfl_common/common/csp_config.py,sha256=9ECOLnp60ENRFAYEEIoYOMhqQzLgfKA-wkWxeUBwDrQ,2824
8
8
  cfl_common/common/mail.py,sha256=pIRfUMVoJWxdv74UqToj_0_pTVTC51z6QlFVLI3QBOw,6874
9
- cfl_common/common/models.py,sha256=yAULJtzuF4loEt6mPrgZjwHGiQH6Hqm82etE7Sofvys,15989
9
+ cfl_common/common/models.py,sha256=bfmdqC8DPy4lq_XDvn0aWAJbNdjfaMkuXu0cHLOyWZI,15835
10
10
  cfl_common/common/permissions.py,sha256=gC6RQGZI2QDBbglx-xr_V4Hl2C2nf1V2_uPmEuoEcJo,2416
11
11
  cfl_common/common/utils.py,sha256=Nn2Npao9Uqad5Js_IdHwF-ow6wrPNpBLW4AO1LxoEBc,1727
12
12
  cfl_common/common/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -108,7 +108,7 @@ example_project/portal_test_settings.py,sha256=7Q7SdosA0Ba85qz-xkAe3EHyMPpSIQ61C
108
108
  example_project/settings.py,sha256=NjFhtDNLwdY5vhUAtqk9a9m3GRfcuWRVqIqnJ3u0o6E,5658
109
109
  example_project/urls.py,sha256=FUTzHPlUS1O5kqMHjL5V4L552N2ln7uTDXcw9wjKUto,422
110
110
  example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
111
- portal/__init__.py,sha256=SWqJTEDnx2fOon29wQowBCNjEkhyhMbbqVsSu4EpdWI,22
111
+ portal/__init__.py,sha256=hTIZ_8cc-ggqcFeOYQQKOHudFQCQNQlM4ZltuYIIjD4,22
112
112
  portal/admin.py,sha256=RKJizTF6dPJKmGPZw7nZUM0X8jkiTjgyKhLQxtvHJ0I,6148
113
113
  portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
114
114
  portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
@@ -126,7 +126,7 @@ portal/forms/invite_teacher.py,sha256=jkDNcCfkts4_lXRzhcI3xBam21Zn2yX9wMpMVhDtW1
126
126
  portal/forms/organisation.py,sha256=QcQyd7AiqBmvt4y8uQSQylguUbKOKqo2pjqWIkpWjDg,7433
127
127
  portal/forms/play.py,sha256=j_QYAKb4qyW0uy0VUUG49dmzDLINc3jR6ddK-djrbc4,11523
128
128
  portal/forms/registration.py,sha256=a-TuzikRc0Q-BAYs3rJ3Sz1wmQ1o_rTEtZmWdF7-xss,6008
129
- portal/forms/teach.py,sha256=VutOzDz3ATbL08cs09mcyfWDIX4NV1UQEJWs_OYEvUQ,22706
129
+ portal/forms/teach.py,sha256=wVwHP2odgMmEGGbbPQzak_1tqutcr1GWZcadvC1Bffg,21739
130
130
  portal/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
131
  portal/helpers/captcha.py,sha256=Amwg3HZ9eIh1LGYVYWYruk1ccNj6P3nYP_evufOY8BY,254
132
132
  portal/helpers/decorators.py,sha256=Bs6AVCvcgxfHLdJVWzTmZpxlYbJZXJh5e9AGRXf7cwo,3617
@@ -498,7 +498,7 @@ portal/templates/portal/teach/onboarding_students.html,sha256=09q658n7U7Vuzy_M_0
498
498
  portal/templates/portal/teach/teacher_add_external_student.html,sha256=Lrrh4W3EwxxXKe45kcqzf2BcPxYo_mLahGIQMNJjX9E,2453
499
499
  portal/templates/portal/teach/teacher_added_external_student.html,sha256=f18RhP5PCE13yjBTrQTCwPLZnkcZb0bDUZ_Z2Oh3D3I,1189
500
500
  portal/templates/portal/teach/teacher_dismiss_students.html,sha256=_5FvvtNjdYpZaM9lDzXrhhTjAD3NK_92kDYzh7xqowI,4283
501
- portal/templates/portal/teach/teacher_edit_class.html,sha256=TcACMixI-kd0OyUThS5EJ81O_E8j8SOTciccjfpIx5I,12254
501
+ portal/templates/portal/teach/teacher_edit_class.html,sha256=R25aFNJDDcMzrwQEFRR1EyAc_d6upNPBL1VyQES4ASg,13023
502
502
  portal/templates/portal/teach/teacher_edit_student.html,sha256=JNF8JyoZh0J-oKH4dz7SGSxR0t7J1lbTGLvjhNbk2Rw,3237
503
503
  portal/templates/portal/teach/teacher_move_all_classes.html,sha256=u9PNJHrKaIXd67vuwhgMmVXumgSnkKH4QKx1bd3O2VY,1780
504
504
  portal/templates/portal/teach/teacher_move_students.html,sha256=toBtjtpiCwvxo2FTJX5oZDzJ9batXdi7ty5AiCHnq4s,1591
@@ -534,7 +534,7 @@ portal/tests/test_2FA.py,sha256=0N4C9Ab3TvO9W__oQLCo-fLDH1Ho3CiGGsSg-2TiZUE,3597
534
534
  portal/tests/test_admin.py,sha256=AM2dgv8j9m4L-SDO-sMA9tQvQH9GwRBrlwRG9OgqtfI,1451
535
535
  portal/tests/test_api.py,sha256=Yo5s_nEGOoG35jA39yZ6nuDOUZvuCZ8o8o8XhZos61w,13819
536
536
  portal/tests/test_captcha_forms.py,sha256=Yn_VYO_6jbq6AeKeLcv-YFL1YwXZpU0C3y7SK8fRUm4,1033
537
- portal/tests/test_class.py,sha256=43g2HslNosbSuSnnMBzM6VWk4LaV0HXkWS3f8VKVRmw,15930
537
+ portal/tests/test_class.py,sha256=MfR8fRsi0XjqS5cbeV19y3Be2RVhOLUHsAy_mjm7P70,17644
538
538
  portal/tests/test_emails.py,sha256=pLr06j3uMBxP1raoZQWzUTBVFvsEDFtUh85J8OnqCwE,9238
539
539
  portal/tests/test_global_forms.py,sha256=A5JpAe4AYK-wpu0o1qU4THmeNv_wr7lhzaMbjz5czpY,1543
540
540
  portal/tests/test_helper_methods.py,sha256=-SQCDZm2XUtyXGEp0CHIb_SSC9CPD-XOSnpnY8QclHk,890
@@ -626,13 +626,13 @@ portal/views/student/edit_account_details.py,sha256=Ba-3D_zzKbX5N01NG5qqBS0ud10B
626
626
  portal/views/student/play.py,sha256=GMxk65bxWOe1Ds2kb6rvuOd1GoAtt5v_9AihLNXoUL0,8768
627
627
  portal/views/teacher/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
628
628
  portal/views/teacher/dashboard.py,sha256=pjzOOCz29d4VHukaCI5QhkDsu-RPvy7SXC9dDcPo50k,27422
629
- portal/views/teacher/teach.py,sha256=-9zzpNLR2oRkyBFXzXjL0_ew_Qpk27w7uca5rKNeCgE,35988
629
+ portal/views/teacher/teach.py,sha256=KDlQdHwU9YdoK_fikLpWO_qDk3ZlX1elYFiiWHBQm6I,36688
630
630
  portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
631
631
  portal/views/two_factor/core.py,sha256=Lk32z2SN2Pg0rRkK-N-LXMvXC1kKKsH3l692kiSDQ4E,964
632
632
  portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
633
633
  portal/views/two_factor/profile.py,sha256=SHSg_xHccE5PtD-OfuOkYhREYz_er4bj5ro1RjJ88Yw,393
634
- codeforlife_portal-8.0.0.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
635
- codeforlife_portal-8.0.0.dist-info/METADATA,sha256=oS_PmOPePrPiHlAe_ABue3QQe_ZslSp3b2AWeRLqPGc,3078
636
- codeforlife_portal-8.0.0.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
637
- codeforlife_portal-8.0.0.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
638
- codeforlife_portal-8.0.0.dist-info/RECORD,,
634
+ codeforlife_portal-8.0.2.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
635
+ codeforlife_portal-8.0.2.dist-info/METADATA,sha256=J59Su8ekITC171pvTLCred37bfPFxHSfexP5UOaGFq4,3078
636
+ codeforlife_portal-8.0.2.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
637
+ codeforlife_portal-8.0.2.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
638
+ codeforlife_portal-8.0.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.44.0)
2
+ Generator: bdist_wheel (0.45.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
portal/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "8.0.0"
1
+ __version__ = "8.0.2"