pronto-helpdesk 1.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. accounts/__init__.py +0 -0
  2. accounts/admin.py +107 -0
  3. accounts/apps.py +6 -0
  4. accounts/migrations/0001_initial.py +113 -0
  5. accounts/migrations/0002_alter_user_options_alter_user_email_and_more.py +49 -0
  6. accounts/migrations/0003_user_matricola_degree_programme.py +53 -0
  7. accounts/migrations/0004_studentprofile.py +71 -0
  8. accounts/migrations/0005_copy_student_data.py +54 -0
  9. accounts/migrations/0006_remove_user_matricola_degree_programme.py +24 -0
  10. accounts/migrations/0007_require_user_names.py +55 -0
  11. accounts/migrations/0008_activate_accounts.py +55 -0
  12. accounts/migrations/__init__.py +0 -0
  13. accounts/models.py +141 -0
  14. accounts/serializers.py +171 -0
  15. accounts/urls.py +10 -0
  16. accounts/views.py +47 -0
  17. booking/__init__.py +0 -0
  18. booking/admin.py +28 -0
  19. booking/apps.py +6 -0
  20. booking/migrations/0001_initial.py +203 -0
  21. booking/migrations/0002_shift.py +64 -0
  22. booking/migrations/0003_appointment_suggested_faq.py +26 -0
  23. booking/migrations/0004_move_office_to_offices.py +43 -0
  24. booking/migrations/__init__.py +0 -0
  25. booking/models.py +148 -0
  26. booking/notifications.py +128 -0
  27. booking/serializers.py +101 -0
  28. booking/services.py +264 -0
  29. booking/templates/booking/email/booked_employee.it.txt +15 -0
  30. booking/templates/booking/email/booked_student.en.txt +12 -0
  31. booking/templates/booking/email/booked_student.it.txt +12 -0
  32. booking/templates/booking/email/cancelled_employee.it.txt +11 -0
  33. booking/templates/booking/email/cancelled_student.en.txt +12 -0
  34. booking/templates/booking/email/cancelled_student.it.txt +12 -0
  35. booking/urls.py +35 -0
  36. booking/views.py +201 -0
  37. faq/__init__.py +0 -0
  38. faq/admin.py +52 -0
  39. faq/anonymisation.py +140 -0
  40. faq/apps.py +9 -0
  41. faq/management/__init__.py +0 -0
  42. faq/management/commands/__init__.py +0 -0
  43. faq/management/commands/import_faqs.py +193 -0
  44. faq/management/commands/rebuild_faq_index.py +21 -0
  45. faq/matching.py +138 -0
  46. faq/migrations/0001_initial.py +77 -0
  47. faq/migrations/0002_inquiry.py +89 -0
  48. faq/migrations/0003_faq_office_inquiry_office.py +81 -0
  49. faq/migrations/0004_link_office.py +44 -0
  50. faq/migrations/0005_remove_faq_office_code_remove_inquiry_office_code.py +58 -0
  51. faq/migrations/0006_faq_question_text.py +22 -0
  52. faq/migrations/0007_inquiry_matched_by.py +35 -0
  53. faq/migrations/0008_inquiry_office_optional.py +27 -0
  54. faq/migrations/__init__.py +0 -0
  55. faq/models.py +116 -0
  56. faq/serializers.py +82 -0
  57. faq/services.py +38 -0
  58. faq/signals.py +37 -0
  59. faq/urls.py +14 -0
  60. faq/vector_index.py +119 -0
  61. faq/views.py +78 -0
  62. offices/__init__.py +0 -0
  63. offices/admin.py +16 -0
  64. offices/apps.py +6 -0
  65. offices/management/__init__.py +0 -0
  66. offices/management/commands/__init__.py +0 -0
  67. offices/management/commands/seed_offices.py +26 -0
  68. offices/migrations/0001_initial.py +90 -0
  69. offices/migrations/0002_rename_office_table.py +44 -0
  70. offices/migrations/__init__.py +0 -0
  71. offices/models.py +35 -0
  72. offices/seed.py +34 -0
  73. pronto/__init__.py +0 -0
  74. pronto/asgi.py +16 -0
  75. pronto/enums.py +35 -0
  76. pronto/i18n.py +50 -0
  77. pronto/permissions.py +23 -0
  78. pronto/settings.py +251 -0
  79. pronto/urls.py +11 -0
  80. pronto/wsgi.py +16 -0
  81. pronto_helpdesk-1.0.2.dist-info/METADATA +166 -0
  82. pronto_helpdesk-1.0.2.dist-info/RECORD +84 -0
  83. pronto_helpdesk-1.0.2.dist-info/WHEEL +4 -0
  84. pronto_helpdesk-1.0.2.dist-info/licenses/LICENSE +201 -0
accounts/__init__.py ADDED
File without changes
accounts/admin.py ADDED
@@ -0,0 +1,107 @@
1
+ from django.contrib import admin
2
+ from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
3
+ from django.contrib.auth.forms import AdminUserCreationForm
4
+ from django.core.exceptions import ValidationError
5
+ from django.forms.models import BaseInlineFormSet
6
+
7
+ from pronto.enums import Role
8
+
9
+ from .models import StudentProfile, User
10
+
11
+
12
+ class UserCreationFormWithoutUsername(AdminUserCreationForm):
13
+ """Django's admin creation form, with email as the credential."""
14
+
15
+ class Meta(AdminUserCreationForm.Meta):
16
+ model = User
17
+ fields = (
18
+ "email",
19
+ "role",
20
+ "first_name",
21
+ "last_name",
22
+ )
23
+
24
+
25
+ class StudentProfileFormSet(BaseInlineFormSet):
26
+ """Requires a profile for a student and refuses one to anybody else."""
27
+
28
+ def clean(self):
29
+ super().clean()
30
+ kept = [
31
+ form
32
+ for form in self.forms
33
+ if form.cleaned_data and not form.cleaned_data.get("DELETE")
34
+ ]
35
+ if self.instance.role == Role.STUDENT and not kept:
36
+ raise ValidationError("A student needs a matricola and a degree programme.")
37
+ if self.instance.role != Role.STUDENT and kept:
38
+ raise ValidationError("Only students have a student profile.")
39
+
40
+
41
+ class StudentProfileInline(admin.StackedInline):
42
+ """The student data, edited on the user's page."""
43
+
44
+ model = StudentProfile
45
+ formset = StudentProfileFormSet
46
+
47
+ def get_extra(self, request, obj=None, **kwargs):
48
+ if obj is not None and obj.role != Role.STUDENT:
49
+ return 0
50
+ return 1
51
+
52
+
53
+ @admin.register(User)
54
+ class UserAdmin(DjangoUserAdmin):
55
+ """Django's UserAdmin without ``username``."""
56
+
57
+ add_form = UserCreationFormWithoutUsername
58
+ inlines = [StudentProfileInline]
59
+
60
+ list_display = ["email", "last_name", "first_name", "role", "is_active", "is_staff"]
61
+ list_filter = ["role", "is_active", "is_staff"]
62
+ search_fields = [
63
+ "email",
64
+ "last_name",
65
+ "first_name",
66
+ "student_profile__matricola",
67
+ ]
68
+ ordering = ["email"]
69
+
70
+ fieldsets = [
71
+ (None, {"fields": ("email", "password")}),
72
+ (
73
+ "Anagrafica",
74
+ {"fields": ("first_name", "last_name")},
75
+ ),
76
+ (
77
+ "Ruolo e permessi",
78
+ {
79
+ "fields": (
80
+ "role",
81
+ "is_active",
82
+ "is_staff",
83
+ "is_superuser",
84
+ "groups",
85
+ "user_permissions",
86
+ )
87
+ },
88
+ ),
89
+ ("Date", {"fields": ("last_login", "date_joined")}),
90
+ ]
91
+ add_fieldsets = [
92
+ (
93
+ None,
94
+ {
95
+ "classes": ("wide",),
96
+ "fields": (
97
+ "email",
98
+ "role",
99
+ "first_name",
100
+ "last_name",
101
+ "usable_password",
102
+ "password1",
103
+ "password2",
104
+ ),
105
+ },
106
+ ),
107
+ ]
accounts/apps.py ADDED
@@ -0,0 +1,6 @@
1
+ from django.apps import AppConfig
2
+
3
+
4
+ class AccountsConfig(AppConfig):
5
+ default_auto_field = "django.db.models.BigAutoField"
6
+ name = "accounts"
@@ -0,0 +1,113 @@
1
+ # Generated by Django 5.2.16 on 2026-09-03 09:38
2
+
3
+ import django.utils.timezone
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ initial = True
9
+
10
+ dependencies = [
11
+ ("auth", "0012_alter_user_first_name_max_length"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.CreateModel(
16
+ name="User",
17
+ fields=[
18
+ (
19
+ "id",
20
+ models.BigAutoField(
21
+ auto_created=True,
22
+ primary_key=True,
23
+ serialize=False,
24
+ verbose_name="ID",
25
+ ),
26
+ ),
27
+ ("password", models.CharField(max_length=128, verbose_name="password")),
28
+ (
29
+ "last_login",
30
+ models.DateTimeField(
31
+ blank=True, null=True, verbose_name="last login"
32
+ ),
33
+ ),
34
+ (
35
+ "is_superuser",
36
+ models.BooleanField(
37
+ default=False,
38
+ help_text="Designates that this user has all permissions without explicitly assigning them.",
39
+ verbose_name="superuser status",
40
+ ),
41
+ ),
42
+ (
43
+ "first_name",
44
+ models.CharField(
45
+ blank=True, max_length=150, verbose_name="first name"
46
+ ),
47
+ ),
48
+ (
49
+ "last_name",
50
+ models.CharField(
51
+ blank=True, max_length=150, verbose_name="last name"
52
+ ),
53
+ ),
54
+ (
55
+ "is_staff",
56
+ models.BooleanField(
57
+ default=False,
58
+ help_text="Designates whether the user can log into this admin site.",
59
+ verbose_name="staff status",
60
+ ),
61
+ ),
62
+ (
63
+ "is_active",
64
+ models.BooleanField(
65
+ default=True,
66
+ help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
67
+ verbose_name="active",
68
+ ),
69
+ ),
70
+ (
71
+ "date_joined",
72
+ models.DateTimeField(
73
+ default=django.utils.timezone.now, verbose_name="date joined"
74
+ ),
75
+ ),
76
+ ("email", models.EmailField(max_length=254, unique=True)),
77
+ (
78
+ "role",
79
+ models.CharField(
80
+ choices=[("STUDENT", "Student"), ("EMPLOYEE", "Employee")],
81
+ max_length=8,
82
+ ),
83
+ ),
84
+ (
85
+ "groups",
86
+ models.ManyToManyField(
87
+ blank=True,
88
+ help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
89
+ related_name="user_set",
90
+ related_query_name="user",
91
+ to="auth.group",
92
+ verbose_name="groups",
93
+ ),
94
+ ),
95
+ (
96
+ "user_permissions",
97
+ models.ManyToManyField(
98
+ blank=True,
99
+ help_text="Specific permissions for this user.",
100
+ related_name="user_set",
101
+ related_query_name="user",
102
+ to="auth.permission",
103
+ verbose_name="user permissions",
104
+ ),
105
+ ),
106
+ ],
107
+ options={
108
+ "verbose_name": "user",
109
+ "verbose_name_plural": "users",
110
+ "abstract": False,
111
+ },
112
+ ),
113
+ ]
@@ -0,0 +1,49 @@
1
+ # Generated by Django 5.2.16 on 2026-09-10 09:10
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("accounts", "0001_initial"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterModelOptions(
13
+ name="user",
14
+ options={"verbose_name": "utente", "verbose_name_plural": "utenti"},
15
+ ),
16
+ migrations.AlterField(
17
+ model_name="user",
18
+ name="email",
19
+ field=models.EmailField(
20
+ help_text="Indirizzo istituzionale, usato anche come credenziale di accesso.",
21
+ max_length=254,
22
+ unique=True,
23
+ verbose_name="indirizzo email",
24
+ ),
25
+ ),
26
+ migrations.AlterField(
27
+ model_name="user",
28
+ name="is_active",
29
+ field=models.BooleanField(
30
+ default=False,
31
+ help_text="Diventa vero quando l'utente apre il link di verifica ricevuto per email.",
32
+ verbose_name="attivo",
33
+ ),
34
+ ),
35
+ migrations.AlterField(
36
+ model_name="user",
37
+ name="role",
38
+ field=models.CharField(
39
+ choices=[
40
+ ("STUDENT", "Studente"),
41
+ ("EMPLOYEE", "Dipendente"),
42
+ ("ADMIN", "Amministratore"),
43
+ ],
44
+ help_text="Derivato dal dominio dell'indirizzo email in fase di registrazione.",
45
+ max_length=16,
46
+ verbose_name="ruolo",
47
+ ),
48
+ ),
49
+ ]
@@ -0,0 +1,53 @@
1
+ # Generated by Django 5.2.16 on 2026-09-28 23:06
2
+
3
+ import django.core.validators
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("accounts", "0002_alter_user_options_alter_user_email_and_more"),
10
+ ("auth", "0012_alter_user_first_name_max_length"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AddField(
15
+ model_name="user",
16
+ name="degree_programme",
17
+ field=models.CharField(
18
+ blank=True,
19
+ default="",
20
+ help_text="Solo per gli studenti: il corso di laurea a cui sono iscritti.",
21
+ max_length=200,
22
+ verbose_name="corso di studi",
23
+ ),
24
+ ),
25
+ migrations.AddField(
26
+ model_name="user",
27
+ name="matricola",
28
+ field=models.CharField(
29
+ blank=True,
30
+ default="",
31
+ error_messages={
32
+ "unique": "A student with this matricola is already registered."
33
+ },
34
+ help_text="Solo per gli studenti: il numero di matricola Unibo, da 6 a 10 cifre.",
35
+ max_length=10,
36
+ validators=[
37
+ django.core.validators.RegexValidator(
38
+ "^[0-9]{6,10}$", "A matricola is a number of 6 to 10 digits."
39
+ )
40
+ ],
41
+ verbose_name="matricola",
42
+ ),
43
+ ),
44
+ migrations.AddConstraint(
45
+ model_name="user",
46
+ constraint=models.UniqueConstraint(
47
+ condition=models.Q(("matricola", ""), _negated=True),
48
+ fields=("matricola",),
49
+ name="unique_matricola",
50
+ violation_error_message="A student with this matricola is already registered.",
51
+ ),
52
+ ),
53
+ ]
@@ -0,0 +1,71 @@
1
+ # Generated by Django 5.2.16 on 2026-10-01 13:44
2
+
3
+ import django.core.validators
4
+ import django.db.models.deletion
5
+ from django.conf import settings
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+ dependencies = [
11
+ ("accounts", "0003_user_matricola_degree_programme"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.CreateModel(
16
+ name="StudentProfile",
17
+ fields=[
18
+ (
19
+ "user",
20
+ models.OneToOneField(
21
+ on_delete=django.db.models.deletion.CASCADE,
22
+ primary_key=True,
23
+ related_name="student_profile",
24
+ serialize=False,
25
+ to=settings.AUTH_USER_MODEL,
26
+ verbose_name="utente",
27
+ ),
28
+ ),
29
+ (
30
+ "matricola",
31
+ models.CharField(
32
+ error_messages={
33
+ "unique": "A student with this matricola is already registered."
34
+ },
35
+ help_text="Il numero di matricola Unibo, da 6 a 10 cifre.",
36
+ max_length=10,
37
+ unique=True,
38
+ validators=[
39
+ django.core.validators.RegexValidator(
40
+ "^[0-9]{6,10}$",
41
+ "A matricola is a number of 6 to 10 digits.",
42
+ )
43
+ ],
44
+ verbose_name="matricola",
45
+ ),
46
+ ),
47
+ (
48
+ "degree_programme",
49
+ models.CharField(
50
+ help_text="Il corso di laurea a cui lo studente è iscritto.",
51
+ max_length=200,
52
+ verbose_name="corso di studi",
53
+ ),
54
+ ),
55
+ ],
56
+ options={
57
+ "verbose_name": "profilo studente",
58
+ "verbose_name_plural": "profili studenti",
59
+ "constraints": [
60
+ models.CheckConstraint(
61
+ condition=models.Q(("matricola", ""), _negated=True),
62
+ name="student_profile_matricola_not_empty",
63
+ ),
64
+ models.CheckConstraint(
65
+ condition=models.Q(("degree_programme", ""), _negated=True),
66
+ name="student_profile_degree_programme_not_empty",
67
+ ),
68
+ ],
69
+ },
70
+ ),
71
+ ]
@@ -0,0 +1,54 @@
1
+ # Moves each student's matricola and degree programme to a student profile.
2
+ # Data a profile cannot hold stops the migration. A separate migration because
3
+ # PostgreSQL cannot alter a table in the transaction that wrote rows to it.
4
+
5
+ from django.db import migrations
6
+
7
+ from pronto.enums import Role
8
+
9
+
10
+ def copy_to_profiles(apps, schema_editor):
11
+ User = apps.get_model("accounts", "User")
12
+ StudentProfile = apps.get_model("accounts", "StudentProfile")
13
+ profiles = []
14
+ invalid = []
15
+ for user in User.objects.order_by("pk"):
16
+ given = [
17
+ bool(value.strip()) for value in (user.matricola, user.degree_programme)
18
+ ]
19
+ if user.role == Role.STUDENT and all(given):
20
+ profiles.append(
21
+ StudentProfile(
22
+ user=user,
23
+ matricola=user.matricola,
24
+ degree_programme=user.degree_programme,
25
+ )
26
+ )
27
+ elif user.role == Role.STUDENT or any(given):
28
+ invalid.append(user.email)
29
+ if invalid:
30
+ raise RuntimeError(
31
+ "These users' matricola and degree programme do not match their "
32
+ f"role (both required of a student, refused from anyone else): "
33
+ f"{', '.join(invalid)}. Correct them, then migrate again."
34
+ )
35
+ StudentProfile.objects.bulk_create(profiles)
36
+
37
+
38
+ def copy_to_users(apps, schema_editor):
39
+ User = apps.get_model("accounts", "User")
40
+ StudentProfile = apps.get_model("accounts", "StudentProfile")
41
+ for profile in StudentProfile.objects.all():
42
+ User.objects.filter(pk=profile.pk).update(
43
+ matricola=profile.matricola, degree_programme=profile.degree_programme
44
+ )
45
+
46
+
47
+ class Migration(migrations.Migration):
48
+ dependencies = [
49
+ ("accounts", "0004_studentprofile"),
50
+ ]
51
+
52
+ operations = [
53
+ migrations.RunPython(copy_to_profiles, copy_to_users),
54
+ ]
@@ -0,0 +1,24 @@
1
+ # Generated by Django 5.2.16 on 2026-10-01 13:44
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("accounts", "0005_copy_student_data"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.RemoveConstraint(
13
+ model_name="user",
14
+ name="unique_matricola",
15
+ ),
16
+ migrations.RemoveField(
17
+ model_name="user",
18
+ name="degree_programme",
19
+ ),
20
+ migrations.RemoveField(
21
+ model_name="user",
22
+ name="matricola",
23
+ ),
24
+ ]
@@ -0,0 +1,55 @@
1
+ # Generated by Django 5.2.16 on 2026-10-01 13:51
2
+ #
3
+ # Every user needs a first and a last name, admins included, and the database
4
+ # refuses an empty one. Users without them stop the migration first, with a
5
+ # list of who they are: names cannot be made up, and the constraint's own
6
+ # error would not say whom it is about.
7
+
8
+ from django.db import migrations, models
9
+ from django.db.models import Q
10
+
11
+
12
+ def check_names(apps, schema_editor):
13
+ User = apps.get_model("accounts", "User")
14
+ unnamed = User.objects.filter(Q(first_name="") | Q(last_name="")).order_by("pk")
15
+ if unnamed.exists():
16
+ emails = ", ".join(unnamed.values_list("email", flat=True))
17
+ raise RuntimeError(
18
+ f"These users have no first or last name: {emails}. Give them one, "
19
+ "then migrate again."
20
+ )
21
+
22
+
23
+ class Migration(migrations.Migration):
24
+ dependencies = [
25
+ ("accounts", "0006_remove_user_matricola_degree_programme"),
26
+ ("auth", "0012_alter_user_first_name_max_length"),
27
+ ]
28
+
29
+ operations = [
30
+ migrations.RunPython(check_names, migrations.RunPython.noop),
31
+ migrations.AlterField(
32
+ model_name="user",
33
+ name="first_name",
34
+ field=models.CharField(max_length=150, verbose_name="first name"),
35
+ ),
36
+ migrations.AlterField(
37
+ model_name="user",
38
+ name="last_name",
39
+ field=models.CharField(max_length=150, verbose_name="last name"),
40
+ ),
41
+ migrations.AddConstraint(
42
+ model_name="user",
43
+ constraint=models.CheckConstraint(
44
+ condition=models.Q(("first_name", ""), _negated=True),
45
+ name="user_first_name_not_empty",
46
+ ),
47
+ ),
48
+ migrations.AddConstraint(
49
+ model_name="user",
50
+ constraint=models.CheckConstraint(
51
+ condition=models.Q(("last_name", ""), _negated=True),
52
+ name="user_last_name_not_empty",
53
+ ),
54
+ ),
55
+ ]
@@ -0,0 +1,55 @@
1
+ # Generated by Django 5.2.16 on 2026-10-06 15:55
2
+ """Accounts are active from registration on: e-mail verification is gone.
3
+
4
+ New users get ``is_active=True`` by default. The users who registered while
5
+ verification existed and never opened their link are still inactive, and with
6
+ the link gone nothing would ever activate them: this migration does.
7
+
8
+ Which rows: inactive users who have never logged in (``last_login IS NULL``).
9
+ An account could only log in once verified, so an inactive one with a login
10
+ was deactivated afterwards, by an admin, and stays inactive. The trade-off: an
11
+ account an admin deactivated before it ever logged in looks exactly like an
12
+ unverified one, and is activated too. So is one that only logged in before
13
+ token logins were recorded, and was deactivated later: the login endpoint has
14
+ set ``last_login`` since 1 October 2026, and left it NULL before. Nothing in
15
+ the table tells these apart. When this migration was written, the inactive users on the hosted database
16
+ were all unverified registrations; an admin who has deactivated someone since
17
+ should check the user list in the admin after migrating.
18
+
19
+ Going back changes no data. Which users this migration activated is not
20
+ recorded, and deactivating every user who has never logged in would also lock
21
+ out those registered, active, after it ran. Reverting the code restores
22
+ verification for new registrations only.
23
+
24
+ The schema change is the default and the help text alone: Django keeps field
25
+ defaults in Python, so the ``AlterField`` runs no SQL.
26
+ """
27
+
28
+ from django.db import migrations, models
29
+
30
+
31
+ def activate_unverified(apps, schema_editor):
32
+ User = apps.get_model("accounts", "User")
33
+ User.objects.filter(is_active=False, last_login__isnull=True).update(is_active=True)
34
+
35
+
36
+ class Migration(migrations.Migration):
37
+ dependencies = [
38
+ ("accounts", "0007_require_user_names"),
39
+ ]
40
+
41
+ operations = [
42
+ migrations.AlterField(
43
+ model_name="user",
44
+ name="is_active",
45
+ field=models.BooleanField(
46
+ default=True,
47
+ help_text=(
48
+ "Toglilo per impedire all'utente di accedere, invece di "
49
+ "eliminarne l'account."
50
+ ),
51
+ verbose_name="attivo",
52
+ ),
53
+ ),
54
+ migrations.RunPython(activate_unverified, migrations.RunPython.noop),
55
+ ]
File without changes