cfl-common 5.3.0__py3-none-any.whl → 8.9.15__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.
- cfl_common-8.9.15.dist-info/METADATA +47 -0
- cfl_common-8.9.15.dist-info/RECORD +99 -0
- {cfl_common-5.3.0.dist-info → cfl_common-8.9.15.dist-info}/WHEEL +1 -1
- common/app_settings.py +35 -5
- common/csp_config.py +85 -0
- common/fixtures/aimmo_characters.json +30 -30
- common/fixtures/aimmo_characters2.json +1 -1
- common/fixtures/aimmo_characters3.json +35 -0
- common/helpers/data_migration_loader.py +3 -4
- common/helpers/emails.py +228 -108
- common/helpers/generators.py +1 -1
- common/helpers/organisation.py +10 -0
- common/mail.py +201 -0
- common/migrations/0002_emailverification.py +1 -3
- common/migrations/0005_add_worksheets.py +2 -13
- common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +2 -14
- common/migrations/0008_unlock_worksheet_3.py +1 -6
- common/migrations/0011_student_login_id.py +3 -3
- common/migrations/0012_usersession.py +39 -0
- common/migrations/0013_class_school.py +42 -0
- common/migrations/0014_login_type.py +29 -0
- common/migrations/0015_dailyactivity.py +31 -0
- common/migrations/0016_joinreleasestudent.py +42 -0
- common/migrations/0017_copy_email_to_username.py +18 -0
- common/migrations/0018_update_aimmo_character_image_path.py +15 -0
- common/migrations/0019_aimmocharacter_alt.py +16 -0
- common/migrations/0020_class_is_active_and_null_access_code.py +23 -0
- common/migrations/0021_school_is_active.py +28 -0
- common/migrations/0022_school_cleanup.py +29 -0
- common/migrations/0023_userprofile_aimmo_badges.py +22 -0
- common/migrations/0024_teacher_invited_by.py +25 -0
- common/migrations/0025_schoolteacherinvitation.py +47 -0
- common/migrations/0026_teacher_remove_join_request.py +22 -0
- common/migrations/0027_class_created_by.py +25 -0
- common/migrations/0028_coding_club_downloads.py +23 -0
- common/migrations/0029_dynamicelement.py +22 -0
- common/migrations/0030_add_maintenance_banner.py +25 -0
- common/migrations/0031_improve_admin_panel.py +56 -0
- common/migrations/0032_dailyactivity_level_control_submits.py +18 -0
- common/migrations/0033_password_reset_tracking_fields.py +23 -0
- common/migrations/0034_dailyactivity_daily_school_student_lockout_reset.py +18 -0
- common/migrations/0035_rename_lockout_fields.py +27 -0
- common/migrations/0036_rename_awaiting_email_verification_userprofile_is_verified.py +17 -0
- common/migrations/0037_migrate_email_verification.py +21 -0
- common/migrations/0038_delete_emailverification.py +16 -0
- common/migrations/0039_copy_email_to_username.py +18 -0
- common/migrations/0040_school_county.py +18 -0
- common/migrations/0041_populate_gb_counties.py +27 -0
- common/migrations/0042_totalactivity.py +25 -0
- common/migrations/0043_add_total_activity.py +30 -0
- common/migrations/0044_update_activity_models.py +33 -0
- common/migrations/0045_otp.py +23 -0
- common/migrations/0046_alter_school_country.py +19 -0
- common/migrations/0047_delete_school_postcode.py +16 -0
- common/migrations/0048_unique_school_names.py +42 -0
- common/migrations/0049_anonymise_orphan_users.py +29 -0
- common/migrations/0050_anonymise_orphan_schools.py +30 -0
- common/migrations/0051_verify_returning_users.py +26 -0
- common/migrations/0052_add_cse_fields.py +68 -0
- common/migrations/0053_clean_class_data.py +24 -0
- common/migrations/0054_delete_aimmo_models.py +20 -0
- common/migrations/0055_alter_schoolteacherinvitation_token.py +18 -0
- common/migrations/0056_set_non_school_teachers_as_non_admins.py +25 -0
- common/migrations/0057_teacher_teacher__is_admin.py +19 -0
- common/migrations/0058_userprofile_google_refresh_token_and_more.py +24 -0
- common/models.py +347 -63
- common/permissions.py +20 -8
- common/static/common/img/RR_logo.svg +336 -0
- common/static/common/img/brain.svg +1 -0
- common/templates/common/onetrust_cookies_consent_notice.html +6 -6
- common/tests/test_migration_anonymise_orphan_schools.py +30 -0
- common/tests/test_migration_anonymise_orphan_users.py +30 -0
- common/tests/test_migration_blocked_time.py +3 -11
- common/tests/test_migration_remove_teacher_title.py +1 -3
- common/tests/test_migration_unique_school_names.py +33 -0
- common/tests/test_migration_verify_returning_users.py +59 -0
- common/tests/test_models.py +49 -43
- common/tests/utils/classes.py +1 -3
- common/tests/utils/email.py +11 -49
- common/tests/utils/organisation.py +10 -14
- common/tests/utils/student.py +14 -67
- common/tests/utils/teacher.py +16 -38
- common/tests/utils/user.py +1 -3
- cfl_common-5.3.0.dist-info/METADATA +0 -20
- cfl_common-5.3.0.dist-info/RECORD +0 -48
- common/email_messages.py +0 -218
- common/fixtures/unlock_worksheet3.json +0 -20
- common/fixtures/worksheets.json +0 -98
- common/fixtures/worksheets2.json +0 -110
- common/tests/test_migration_aimmo_characters.py +0 -31
- common/tests/test_migration_worksheets.py +0 -49
- {cfl_common-5.3.0.dist-info → cfl_common-8.9.15.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 3.2.16 on 2022-12-09 13:27
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0031_improve_admin_panel"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="level_control_submits",
|
|
16
|
+
field=models.PositiveBigIntegerField(default=0),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Generated by Django 3.2.16 on 2023-01-17 10:41
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0032_dailyactivity_level_control_submits"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="daily_indy_lockout_reset",
|
|
16
|
+
field=models.PositiveIntegerField(default=0),
|
|
17
|
+
),
|
|
18
|
+
migrations.AddField(
|
|
19
|
+
model_name="dailyactivity",
|
|
20
|
+
name="daily_teacher_lockout_reset",
|
|
21
|
+
field=models.PositiveIntegerField(default=0),
|
|
22
|
+
),
|
|
23
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 3.2.16 on 2023-01-24 15:26
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0033_password_reset_tracking_fields"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="daily_school_student_lockout_reset",
|
|
16
|
+
field=models.PositiveIntegerField(default=0),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Generated by Django 3.2.16 on 2023-01-27 03:17
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("common", "0034_dailyactivity_daily_school_student_lockout_reset"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.RenameField(
|
|
13
|
+
model_name="dailyactivity",
|
|
14
|
+
old_name="daily_indy_lockout_reset",
|
|
15
|
+
new_name="indy_lockout_resets",
|
|
16
|
+
),
|
|
17
|
+
migrations.RenameField(
|
|
18
|
+
model_name="dailyactivity",
|
|
19
|
+
old_name="daily_school_student_lockout_reset",
|
|
20
|
+
new_name="school_student_lockout_resets",
|
|
21
|
+
),
|
|
22
|
+
migrations.RenameField(
|
|
23
|
+
model_name="dailyactivity",
|
|
24
|
+
old_name="daily_teacher_lockout_reset",
|
|
25
|
+
new_name="teacher_lockout_resets",
|
|
26
|
+
),
|
|
27
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Generated by Django 3.2.18 on 2023-04-11 14:31
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("common", "0035_rename_lockout_fields"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.RenameField(
|
|
13
|
+
model_name="userprofile",
|
|
14
|
+
old_name="awaiting_email_verification",
|
|
15
|
+
new_name="is_verified",
|
|
16
|
+
),
|
|
17
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from django.db import migrations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Migration(migrations.Migration):
|
|
5
|
+
dependencies = [
|
|
6
|
+
("common", "0036_rename_awaiting_email_verification_userprofile_is_verified"),
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
def forwards(apps, schema_editor):
|
|
10
|
+
"""Finds the users of verified Email Verification objects and sets their `is_verified` to True"""
|
|
11
|
+
UserProfile = apps.get_model("common", "UserProfile")
|
|
12
|
+
db_alias = schema_editor.connection.alias
|
|
13
|
+
UserProfile.objects.using(db_alias).filter(user__email_verifications__verified=True).update(is_verified=True)
|
|
14
|
+
|
|
15
|
+
def backwards(apps, schema_editor):
|
|
16
|
+
"""Finds the users of verified Email Verification objects and sets their `is_verified` to False"""
|
|
17
|
+
UserProfile = apps.get_model("common", "UserProfile")
|
|
18
|
+
db_alias = schema_editor.connection.alias
|
|
19
|
+
UserProfile.objects.using(db_alias).filter(user__email_verifications__verified=True).update(is_verified=False)
|
|
20
|
+
|
|
21
|
+
operations = [migrations.RunPython(forwards, reverse_code=backwards)]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Generated by Django 3.2.18 on 2023-04-13 18:41
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0037_migrate_email_verification"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.DeleteModel(
|
|
14
|
+
name="EmailVerification",
|
|
15
|
+
),
|
|
16
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 3.2.18 on 2023-04-13 18:41
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
from django.db.models import F
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def copy_email_to_username(apps, schema):
|
|
8
|
+
User = apps.get_model("auth", "User")
|
|
9
|
+
User.objects.exclude(email="").exclude(email__isnull=True).exclude(email=F("username")).update(username=F("email"))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Migration(migrations.Migration):
|
|
13
|
+
|
|
14
|
+
dependencies = [
|
|
15
|
+
("common", "0038_delete_emailverification"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
operations = [migrations.RunPython(code=copy_email_to_username, reverse_code=migrations.RunPython.noop)]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-08-04 14:35
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0039_copy_email_to_username"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="school",
|
|
15
|
+
name="county",
|
|
16
|
+
field=models.CharField(blank=True, max_length=50, null=True),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import pgeocode
|
|
2
|
+
from django.db import migrations
|
|
3
|
+
|
|
4
|
+
from ..helpers.organisation import sanitise_uk_postcode
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0040_school_county"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
def forwards(apps, schema_editor):
|
|
13
|
+
"""Populate the county field for schools in GB"""
|
|
14
|
+
School = apps.get_model("common", "School")
|
|
15
|
+
gb_schools = School.objects.filter(country="GB")
|
|
16
|
+
nomi = pgeocode.Nominatim("GB")
|
|
17
|
+
|
|
18
|
+
for school in gb_schools:
|
|
19
|
+
if school.postcode.replace(" ", "") == "":
|
|
20
|
+
school.county = "nan"
|
|
21
|
+
school.save()
|
|
22
|
+
else:
|
|
23
|
+
county = nomi.query_postal_code(sanitise_uk_postcode(school.postcode)).county_name
|
|
24
|
+
school.county = county
|
|
25
|
+
school.save()
|
|
26
|
+
|
|
27
|
+
operations = [migrations.RunPython(forwards, reverse_code=migrations.RunPython.noop)]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-09-07 01:56
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0041_populate_gb_counties"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.CreateModel(
|
|
14
|
+
name="TotalActivity",
|
|
15
|
+
fields=[
|
|
16
|
+
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
17
|
+
("teacher_registrations", models.PositiveIntegerField(default=0)),
|
|
18
|
+
("student_registrations", models.PositiveIntegerField(default=0)),
|
|
19
|
+
("independent_registrations", models.PositiveIntegerField(default=0)),
|
|
20
|
+
],
|
|
21
|
+
options={
|
|
22
|
+
"verbose_name_plural": "Total activity",
|
|
23
|
+
},
|
|
24
|
+
),
|
|
25
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from django.db import migrations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def add_total_activity(apps, schema_editor):
|
|
5
|
+
"""
|
|
6
|
+
This creates the only TotalActivity entry that we need to record total activity.
|
|
7
|
+
Initialises it with the total number of registrations at the time of the migration.
|
|
8
|
+
"""
|
|
9
|
+
TotalActivity = apps.get_model("common", "TotalActivity")
|
|
10
|
+
Teacher = apps.get_model("common", "Teacher")
|
|
11
|
+
Student = apps.get_model("common", "Student")
|
|
12
|
+
TotalActivity.objects.create(
|
|
13
|
+
teacher_registrations=Teacher.objects.all().count(),
|
|
14
|
+
student_registrations=Student.objects.filter(class_field__isnull=False).count(),
|
|
15
|
+
independent_registrations=Student.objects.filter(class_field__isnull=True).count(),
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def remove_total_activity(apps, schema_editor):
|
|
20
|
+
TotalActivity = apps.get_model("common", "TotalActivity")
|
|
21
|
+
TotalActivity.objects.get(id=1).delete()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Migration(migrations.Migration):
|
|
25
|
+
|
|
26
|
+
dependencies = [
|
|
27
|
+
("common", "0042_totalactivity"),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
operations = [migrations.RunPython(add_total_activity, remove_total_activity)]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-09-14 16:26
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0043_add_total_activity"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="anonymised_unverified_independents",
|
|
16
|
+
field=models.PositiveIntegerField(default=0),
|
|
17
|
+
),
|
|
18
|
+
migrations.AddField(
|
|
19
|
+
model_name="dailyactivity",
|
|
20
|
+
name="anonymised_unverified_teachers",
|
|
21
|
+
field=models.PositiveIntegerField(default=0),
|
|
22
|
+
),
|
|
23
|
+
migrations.AddField(
|
|
24
|
+
model_name="totalactivity",
|
|
25
|
+
name="anonymised_unverified_independents",
|
|
26
|
+
field=models.PositiveIntegerField(default=0),
|
|
27
|
+
),
|
|
28
|
+
migrations.AddField(
|
|
29
|
+
model_name="totalactivity",
|
|
30
|
+
name="anonymised_unverified_teachers",
|
|
31
|
+
field=models.PositiveIntegerField(default=0),
|
|
32
|
+
),
|
|
33
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-09-27 13:36
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("common", "0044_update_activity_models"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="userprofile",
|
|
15
|
+
name="last_otp_for_time",
|
|
16
|
+
field=models.DateTimeField(blank=True, null=True),
|
|
17
|
+
),
|
|
18
|
+
migrations.AddField(
|
|
19
|
+
model_name="userprofile",
|
|
20
|
+
name="otp_secret",
|
|
21
|
+
field=models.CharField(blank=True, max_length=40, null=True),
|
|
22
|
+
),
|
|
23
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-11-06 16:04
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
import django_countries.fields
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("common", "0045_otp"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name="school",
|
|
16
|
+
name="country",
|
|
17
|
+
field=django_countries.fields.CountryField(blank=True, max_length=2, null=True),
|
|
18
|
+
),
|
|
19
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-11-06 18:56
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("common", "0046_alter_school_country"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.RemoveField(
|
|
13
|
+
model_name="school",
|
|
14
|
+
name="postcode",
|
|
15
|
+
),
|
|
16
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated by Django 3.2.20 on 2023-11-06 18:56
|
|
2
|
+
|
|
3
|
+
from django.apps.registry import Apps
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def unique_school_names(apps: Apps, *args):
|
|
8
|
+
School = apps.get_model("common", "School")
|
|
9
|
+
|
|
10
|
+
def get_school_name(school_name: str, school_name_number: int):
|
|
11
|
+
return f"{school_name} {school_name_number}"
|
|
12
|
+
|
|
13
|
+
school_values = School.objects.values("name").annotate(name_count=models.Count("name")).filter(name_count__gt=1)
|
|
14
|
+
for school_value in school_values:
|
|
15
|
+
school_name = school_value["name"]
|
|
16
|
+
school_name_number = 1
|
|
17
|
+
|
|
18
|
+
schools = list(School.objects.filter(name=school_name).order_by("id"))
|
|
19
|
+
for index in range(1, len(schools)):
|
|
20
|
+
school = schools[index]
|
|
21
|
+
|
|
22
|
+
school.name = get_school_name(school_name, school_name_number)
|
|
23
|
+
while School.objects.filter(name=school.name).exists():
|
|
24
|
+
school_name_number += 1
|
|
25
|
+
school.name = get_school_name(school_name, school_name_number)
|
|
26
|
+
|
|
27
|
+
school.save()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Migration(migrations.Migration):
|
|
31
|
+
dependencies = [
|
|
32
|
+
("common", "0047_delete_school_postcode"),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
operations = [
|
|
36
|
+
migrations.RunPython(code=unique_school_names, reverse_code=migrations.RunPython.noop),
|
|
37
|
+
migrations.AlterField(
|
|
38
|
+
model_name="school",
|
|
39
|
+
name="name",
|
|
40
|
+
field=models.CharField(max_length=200, unique=True),
|
|
41
|
+
),
|
|
42
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from django.apps.registry import Apps
|
|
2
|
+
from django.db import migrations
|
|
3
|
+
|
|
4
|
+
from portal.views.api import __anonymise_user
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def anonymise_orphan_users(apps: Apps, *args):
|
|
8
|
+
"""
|
|
9
|
+
Users should never exist without a user-type linked to them. Anonymise all
|
|
10
|
+
instances of User objects without a Teacher or Student instance.
|
|
11
|
+
"""
|
|
12
|
+
User = apps.get_model("auth", "User")
|
|
13
|
+
|
|
14
|
+
active_orphan_users = User.objects.filter(
|
|
15
|
+
new_teacher__isnull=True, new_student__isnull=True, is_active=True
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
for active_orphan_user in active_orphan_users:
|
|
19
|
+
__anonymise_user(active_orphan_user)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Migration(migrations.Migration):
|
|
23
|
+
dependencies = [("common", "0048_unique_school_names")]
|
|
24
|
+
|
|
25
|
+
operations = [
|
|
26
|
+
migrations.RunPython(
|
|
27
|
+
code=anonymise_orphan_users, reverse_code=migrations.RunPython.noop
|
|
28
|
+
),
|
|
29
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from uuid import uuid4
|
|
2
|
+
|
|
3
|
+
from django.apps.registry import Apps
|
|
4
|
+
from django.db import migrations
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def anonymise_orphan_schools(apps: Apps, *args):
|
|
8
|
+
"""
|
|
9
|
+
Schools without any teachers or students should be anonymised (inactive).
|
|
10
|
+
Mark all active orphan schools as inactive.
|
|
11
|
+
"""
|
|
12
|
+
School = apps.get_model("common", "School")
|
|
13
|
+
|
|
14
|
+
active_orphan_schools = School.objects.filter(teacher_school__isnull=True)
|
|
15
|
+
|
|
16
|
+
for active_orphan_school in active_orphan_schools:
|
|
17
|
+
active_orphan_school.name = uuid4().hex
|
|
18
|
+
active_orphan_school.is_active = False
|
|
19
|
+
active_orphan_school.save()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Migration(migrations.Migration):
|
|
23
|
+
dependencies = [("common", "0049_anonymise_orphan_users")]
|
|
24
|
+
|
|
25
|
+
operations = [
|
|
26
|
+
migrations.RunPython(
|
|
27
|
+
code=anonymise_orphan_schools,
|
|
28
|
+
reverse_code=migrations.RunPython.noop,
|
|
29
|
+
),
|
|
30
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from django.apps.registry import Apps
|
|
2
|
+
from django.db import migrations
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def verify_returning_users(apps: Apps, *args):
|
|
6
|
+
"""
|
|
7
|
+
Users cannot be unverified after having logged in at least once. Grab all
|
|
8
|
+
instances of unverified UserProfile where the User has logged in and mark it
|
|
9
|
+
as verified.
|
|
10
|
+
"""
|
|
11
|
+
UserProfile = apps.get_model("common", "UserProfile")
|
|
12
|
+
|
|
13
|
+
UserProfile.objects.filter(
|
|
14
|
+
user__last_login__isnull=False, is_verified=False
|
|
15
|
+
).update(is_verified=True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Migration(migrations.Migration):
|
|
19
|
+
dependencies = [("common", "0050_anonymise_orphan_schools")]
|
|
20
|
+
|
|
21
|
+
operations = [
|
|
22
|
+
migrations.RunPython(
|
|
23
|
+
code=verify_returning_users,
|
|
24
|
+
reverse_code=migrations.RunPython.noop,
|
|
25
|
+
),
|
|
26
|
+
]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Generated by Django 3.2.25 on 2024-05-22 11:30
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('common', '0051_verify_returning_users'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name='schoolteacherinvitation',
|
|
15
|
+
name='_invited_teacher_email',
|
|
16
|
+
field=models.BinaryField(blank=True, null=True),
|
|
17
|
+
),
|
|
18
|
+
migrations.AddField(
|
|
19
|
+
model_name='schoolteacherinvitation',
|
|
20
|
+
name='_invited_teacher_first_name',
|
|
21
|
+
field=models.BinaryField(blank=True, null=True),
|
|
22
|
+
),
|
|
23
|
+
migrations.AddField(
|
|
24
|
+
model_name='schoolteacherinvitation',
|
|
25
|
+
name='_invited_teacher_last_name',
|
|
26
|
+
field=models.BinaryField(blank=True, null=True),
|
|
27
|
+
),
|
|
28
|
+
migrations.AddField(
|
|
29
|
+
model_name='userprofile',
|
|
30
|
+
name='_email',
|
|
31
|
+
field=models.BinaryField(blank=True, null=True),
|
|
32
|
+
),
|
|
33
|
+
migrations.AddField(
|
|
34
|
+
model_name='userprofile',
|
|
35
|
+
name='_first_name',
|
|
36
|
+
field=models.BinaryField(blank=True, null=True),
|
|
37
|
+
),
|
|
38
|
+
migrations.AddField(
|
|
39
|
+
model_name='userprofile',
|
|
40
|
+
name='_last_name',
|
|
41
|
+
field=models.BinaryField(blank=True, null=True),
|
|
42
|
+
),
|
|
43
|
+
migrations.AddField(
|
|
44
|
+
model_name='userprofile',
|
|
45
|
+
name='_username',
|
|
46
|
+
field=models.BinaryField(blank=True, null=True),
|
|
47
|
+
),
|
|
48
|
+
migrations.AddField(
|
|
49
|
+
model_name='userprofile',
|
|
50
|
+
name='email',
|
|
51
|
+
field=models.CharField(blank=True, max_length=200, null=True),
|
|
52
|
+
),
|
|
53
|
+
migrations.AddField(
|
|
54
|
+
model_name='userprofile',
|
|
55
|
+
name='first_name',
|
|
56
|
+
field=models.CharField(blank=True, max_length=200, null=True),
|
|
57
|
+
),
|
|
58
|
+
migrations.AddField(
|
|
59
|
+
model_name='userprofile',
|
|
60
|
+
name='last_name',
|
|
61
|
+
field=models.CharField(blank=True, max_length=200, null=True),
|
|
62
|
+
),
|
|
63
|
+
migrations.AddField(
|
|
64
|
+
model_name='userprofile',
|
|
65
|
+
name='username',
|
|
66
|
+
field=models.CharField(blank=True, max_length=200, null=True),
|
|
67
|
+
),
|
|
68
|
+
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from django.apps.registry import Apps
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
def clean_early_class_data(apps: Apps, *args):
|
|
7
|
+
Class = apps.get_model("common", "Class")
|
|
8
|
+
|
|
9
|
+
Class.objects.filter(
|
|
10
|
+
creation_time__date__lt = date(2021, 10, 15)
|
|
11
|
+
).update(creation_time = None)
|
|
12
|
+
|
|
13
|
+
class Migration(migrations.Migration):
|
|
14
|
+
|
|
15
|
+
dependencies = [
|
|
16
|
+
("common", "0052_add_cse_fields")
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
operations = [
|
|
20
|
+
migrations.RunPython(
|
|
21
|
+
code=clean_early_class_data,
|
|
22
|
+
reverse_code=migrations.RunPython.noop,
|
|
23
|
+
),
|
|
24
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Generated by Django 3.2.25 on 2024-07-31 00:13
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('common', '0053_clean_class_data'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.DeleteModel(
|
|
14
|
+
name='AimmoCharacter',
|
|
15
|
+
),
|
|
16
|
+
migrations.RemoveField(
|
|
17
|
+
model_name='userprofile',
|
|
18
|
+
name='aimmo_badges',
|
|
19
|
+
),
|
|
20
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 3.2.25 on 2024-09-27 16:04
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('common', '0054_delete_aimmo_models'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='schoolteacherinvitation',
|
|
15
|
+
name='token',
|
|
16
|
+
field=models.CharField(max_length=88),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from django.apps.registry import Apps
|
|
2
|
+
from django.db import migrations
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def set_non_school_teachers_as_non_admins(apps: Apps, *args):
|
|
6
|
+
Teacher = apps.get_model("common", "Teacher")
|
|
7
|
+
|
|
8
|
+
Teacher.objects.filter(
|
|
9
|
+
is_admin=True,
|
|
10
|
+
school__isnull=True,
|
|
11
|
+
).update(is_admin=False)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Migration(migrations.Migration):
|
|
15
|
+
|
|
16
|
+
dependencies = [
|
|
17
|
+
("common", "0055_alter_schoolteacherinvitation_token"),
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
operations = [
|
|
21
|
+
migrations.RunPython(
|
|
22
|
+
code=set_non_school_teachers_as_non_admins,
|
|
23
|
+
reverse_code=migrations.RunPython.noop,
|
|
24
|
+
),
|
|
25
|
+
]
|