diff --git a/homecoming/apps/announcements/forms.py b/homecoming/apps/announcements/forms.py index cd16acb..6f1845d 100644 --- a/homecoming/apps/announcements/forms.py +++ b/homecoming/apps/announcements/forms.py @@ -26,9 +26,9 @@ def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) if not user.has_management_permission: - self.fields["class_group"].queryset = self.fields["class_group"].queryset.filter( - id=user.class_group.id - ) + self.fields["class_group"].queryset = self.fields[ + "class_group" + ].queryset.filter(id=user.class_group.id) def clean(self): cleaned_data = self.cleaned_data diff --git a/homecoming/apps/announcements/migrations/0001_initial.py b/homecoming/apps/announcements/migrations/0001_initial.py index f1271ca..3c8d13a 100644 --- a/homecoming/apps/announcements/migrations/0001_initial.py +++ b/homecoming/apps/announcements/migrations/0001_initial.py @@ -9,22 +9,37 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('authentication', '0004_user_is_hoco_admin'), + ("authentication", "0004_user_is_hoco_admin"), ] operations = [ migrations.CreateModel( - name='Announcement', + name="Announcement", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=128)), - ('description', models.TextField(max_length=48000)), - ('start_time', models.DateTimeField()), - ('end_time', models.DateTimeField()), - ('class_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='announcements', to='authentication.classgroup')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=128)), + ("description", models.TextField(max_length=48000)), + ("start_time", models.DateTimeField()), + ("end_time", models.DateTimeField()), + ( + "class_group", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="announcements", + to="authentication.classgroup", + ), + ), ], options={ - 'ordering': ('start_time',), + "ordering": ("start_time",), }, ), ] diff --git a/homecoming/apps/announcements/urls.py b/homecoming/apps/announcements/urls.py index e4f12a4..1ff4e95 100644 --- a/homecoming/apps/announcements/urls.py +++ b/homecoming/apps/announcements/urls.py @@ -7,7 +7,11 @@ urlpatterns = [ path("create/", views.create_announcement_view, name="create_announcement_page"), - path("edit//", views.edit_announcement_view, name="edit_announcement"), + path( + "edit//", + views.edit_announcement_view, + name="edit_announcement", + ), path( "delete/", management_or_class_group_admin_only(views.DeleteAnnouncementView.as_view()), diff --git a/homecoming/apps/announcements/views.py b/homecoming/apps/announcements/views.py index 010d79c..54670e3 100644 --- a/homecoming/apps/announcements/views.py +++ b/homecoming/apps/announcements/views.py @@ -2,14 +2,12 @@ from django import http from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.http import HttpRequest, HttpResponse, JsonResponse -from django.shortcuts import redirect, render, get_object_or_404 +from django.http import HttpRequest, HttpResponse +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse, reverse_lazy from django.views.generic.edit import DeleteView -from ..auth.decorators import management_only, management_or_class_group_admin_only -from ..scores.models import ScoreBoard +from ..auth.decorators import management_or_class_group_admin_only from .forms import AnnouncementForm from .models import Announcement @@ -83,7 +81,9 @@ def edit_announcement_view(request: HttpRequest, announcement_id: int) -> HttpRe raise http.Http404 if request.method == "POST": - form = AnnouncementForm(data=request.POST, instance=announcement, user=request.user) + form = AnnouncementForm( + data=request.POST, instance=announcement, user=request.user + ) if form.is_valid(): form.save() messages.info(request, "Announcement edited!") @@ -92,7 +92,9 @@ def edit_announcement_view(request: HttpRequest, announcement_id: int) -> HttpRe form = AnnouncementForm(instance=announcement, user=request.user) return render( - request, "announcements/announcement_form.html", {"form": form, "id": announcement_id} + request, + "announcements/announcement_form.html", + {"form": form, "id": announcement_id}, ) diff --git a/homecoming/apps/auth/admin.py b/homecoming/apps/auth/admin.py index fc18dfd..c02dcde 100644 --- a/homecoming/apps/auth/admin.py +++ b/homecoming/apps/auth/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import User, ClassGroup +from .models import ClassGroup, User admin.site.register(User) admin.site.register(ClassGroup) diff --git a/homecoming/apps/auth/decorators.py b/homecoming/apps/auth/decorators.py index bf9bb4e..6994a60 100644 --- a/homecoming/apps/auth/decorators.py +++ b/homecoming/apps/auth/decorators.py @@ -5,5 +5,6 @@ ) management_or_class_group_admin_only = user_passes_test( - lambda u: u.is_authenticated and (u.has_management_permission or u.is_class_group_admin) + lambda u: u.is_authenticated + and (u.has_management_permission or u.is_class_group_admin) ) diff --git a/homecoming/apps/auth/forms.py b/homecoming/apps/auth/forms.py index caaf204..3696692 100644 --- a/homecoming/apps/auth/forms.py +++ b/homecoming/apps/auth/forms.py @@ -1,7 +1,6 @@ import bleach from django import forms -from django.core.exceptions import ValidationError from .models import ClassGroup diff --git a/homecoming/apps/auth/migrations/0003_auto_20230901_1648.py b/homecoming/apps/auth/migrations/0003_auto_20230901_1648.py index b4fcc02..5ca90af 100644 --- a/homecoming/apps/auth/migrations/0003_auto_20230901_1648.py +++ b/homecoming/apps/auth/migrations/0003_auto_20230901_1648.py @@ -6,22 +6,30 @@ class Migration(migrations.Migration): dependencies = [ - ('authentication', '0002_auto_20201107_1851'), + ("authentication", "0002_auto_20201107_1851"), ] operations = [ migrations.CreateModel( - name='ClassGroup', + name="ClassGroup", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=128)), - ('username_prefix', models.CharField(max_length=4)), - ('message', models.TextField(blank=True, max_length=48000, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=128)), + ("username_prefix", models.CharField(max_length=4)), + ("message", models.TextField(blank=True, max_length=48000, null=True)), ], ), migrations.AddField( - model_name='user', - name='is_class_group_admin', + model_name="user", + name="is_class_group_admin", field=models.BooleanField(default=False), ), ] diff --git a/homecoming/apps/auth/migrations/0004_user_is_hoco_admin.py b/homecoming/apps/auth/migrations/0004_user_is_hoco_admin.py index 9ecd3e8..5ae192a 100644 --- a/homecoming/apps/auth/migrations/0004_user_is_hoco_admin.py +++ b/homecoming/apps/auth/migrations/0004_user_is_hoco_admin.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('authentication', '0003_auto_20230901_1648'), + ("authentication", "0003_auto_20230901_1648"), ] operations = [ migrations.AddField( - model_name='user', - name='is_hoco_admin', + model_name="user", + name="is_hoco_admin", field=models.BooleanField(default=False), ), ] diff --git a/homecoming/apps/auth/models.py b/homecoming/apps/auth/models.py index 4f19ddd..48d0be4 100644 --- a/homecoming/apps/auth/models.py +++ b/homecoming/apps/auth/models.py @@ -20,7 +20,9 @@ def class_group(self): @property def has_management_permission(self) -> bool: - return self.is_hoco_admin or self.is_teacher or self.is_staff or self.is_superuser + return ( + self.is_hoco_admin or self.is_teacher or self.is_staff or self.is_superuser + ) @property def short_name(self): @@ -40,8 +42,6 @@ class ClassGroup(models.Model): message = models.TextField(max_length=48000, blank=True, null=True) def has_user(self, user: User) -> bool: - if self.username_prefix == "_": - return True return user.username.startswith(self.username_prefix) def __str__(self): diff --git a/homecoming/apps/auth/views.py b/homecoming/apps/auth/views.py index 9c9efdc..f7de1dd 100644 --- a/homecoming/apps/auth/views.py +++ b/homecoming/apps/auth/views.py @@ -1,14 +1,12 @@ from django import http from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.http import HttpRequest, HttpResponse, JsonResponse -from django.shortcuts import redirect, render, get_object_or_404 -from django.urls import reverse, reverse_lazy -from django.views.generic.edit import DeleteView +from django.http import HttpRequest, HttpResponse +from django.shortcuts import get_object_or_404, redirect, render +from django.urls import reverse from .decorators import management_or_class_group_admin_only -from .models import ClassGroup from .forms import ClassGroupForm +from .models import ClassGroup def login(request: HttpRequest) -> HttpResponse: @@ -35,4 +33,6 @@ def edit_class_group_view(request: HttpRequest, class_group_id: int) -> HttpResp else: form = ClassGroupForm(instance=class_group) - return render(request, "auth/class_group_form.html", {"form": form, "id": class_group_id}) + return render( + request, "auth/class_group_form.html", {"form": form, "id": class_group_id} + ) diff --git a/homecoming/apps/base/views.py b/homecoming/apps/base/views.py index 901ce52..605304c 100644 --- a/homecoming/apps/base/views.py +++ b/homecoming/apps/base/views.py @@ -1,5 +1,3 @@ -import datetime - from django.contrib import messages from django.contrib.auth.decorators import login_required from django.db.models import Sum @@ -8,9 +6,9 @@ from django.urls import reverse from django.utils import timezone +from ..announcements.models import Announcement from ..auth.decorators import management_only from ..auth.models import ClassGroup -from ..announcements.models import Announcement from ..events.models import Event from ..scores.models import ScoreBoard @@ -18,9 +16,15 @@ @login_required def index_view(request: HttpRequest) -> HttpResponse: # Combine class group announcements and global announcements - all_announcements = request.user.class_group.announcements.all() | Announcement.objects.filter( - class_group__username_prefix="_" - ) + if request.user.class_group: + all_announcements = ( + request.user.class_group.announcements.all() + | Announcement.objects.filter(class_group__username_prefix="_") + ) + else: + all_announcements = Announcement.objects.filter( + class_group__username_prefix="_" + ) announcements = ( all_announcements.filter(end_time__gte=timezone.now()) .filter(start_time__lte=timezone.now()) @@ -38,8 +42,12 @@ def index_view(request: HttpRequest) -> HttpResponse: "sophomore_total": ScoreBoard.objects.aggregate(Sum("sophomore_score"))[ "sophomore_score__sum" ], - "junior_total": ScoreBoard.objects.aggregate(Sum("junior_score"))["junior_score__sum"], - "senior_total": ScoreBoard.objects.aggregate(Sum("senior_score"))["senior_score__sum"], + "junior_total": ScoreBoard.objects.aggregate(Sum("junior_score"))[ + "junior_score__sum" + ], + "senior_total": ScoreBoard.objects.aggregate(Sum("senior_score"))[ + "senior_score__sum" + ], } if ClassGroup.objects.filter(username_prefix="_").exists(): @@ -59,8 +67,12 @@ def api_view(request: HttpRequest) -> JsonResponse: "sophomore_total": ScoreBoard.objects.aggregate(Sum("sophomore_score"))[ "sophomore_score__sum" ], - "junior_total": ScoreBoard.objects.aggregate(Sum("junior_score"))["junior_score__sum"], - "senior_total": ScoreBoard.objects.aggregate(Sum("senior_score"))["senior_score__sum"], + "junior_total": ScoreBoard.objects.aggregate(Sum("junior_score"))[ + "junior_score__sum" + ], + "senior_total": ScoreBoard.objects.aggregate(Sum("senior_score"))[ + "senior_score__sum" + ], } resp = JsonResponse(context) resp["Access-Control-Allow-Origin"] = "*" diff --git a/homecoming/apps/scores/migrations/0003_scoreboard_staff_score.py b/homecoming/apps/scores/migrations/0003_scoreboard_staff_score.py index 4c6265b..660bb30 100644 --- a/homecoming/apps/scores/migrations/0003_scoreboard_staff_score.py +++ b/homecoming/apps/scores/migrations/0003_scoreboard_staff_score.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('scores', '0002_auto_20200715_2206'), + ("scores", "0002_auto_20200715_2206"), ] operations = [ migrations.AddField( - model_name='scoreboard', - name='staff_score', + model_name="scoreboard", + name="staff_score", field=models.IntegerField(default=0), ), ] diff --git a/homecoming/apps/scores/migrations/0004_remove_scoreboard_staff_score.py b/homecoming/apps/scores/migrations/0004_remove_scoreboard_staff_score.py index 93330ef..464abaa 100644 --- a/homecoming/apps/scores/migrations/0004_remove_scoreboard_staff_score.py +++ b/homecoming/apps/scores/migrations/0004_remove_scoreboard_staff_score.py @@ -6,12 +6,12 @@ class Migration(migrations.Migration): dependencies = [ - ('scores', '0003_scoreboard_staff_score'), + ("scores", "0003_scoreboard_staff_score"), ] operations = [ migrations.RemoveField( - model_name='scoreboard', - name='staff_score', + model_name="scoreboard", + name="staff_score", ), ] diff --git a/homecoming/settings/__init__.py b/homecoming/settings/__init__.py index 7968766..42d04bc 100644 --- a/homecoming/settings/__init__.py +++ b/homecoming/settings/__init__.py @@ -67,7 +67,9 @@ } AUTH_PASSWORD_VALIDATORS = [ - {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, diff --git a/homecoming/templates/base/home.html b/homecoming/templates/base/home.html index 5b5eacc..bf9a2b3 100644 --- a/homecoming/templates/base/home.html +++ b/homecoming/templates/base/home.html @@ -108,14 +108,14 @@

Scoreboard

- {% if class_group %} + {% if class_group or global_group %}

Class Announcements

{% if global_group %}

- {% if user|has_management_permissions or user.is_class_group_admin %} + {% if user|has_management_permissions %} {{ global_group.name }} {% else %} {{ global_group.name }} @@ -127,25 +127,27 @@

{% endif %} -
-
-

- {% if user|has_management_permissions or user.is_class_group_admin %} - {{ class_group.name }} - {% else %} - {{ class_group.name }} - {% endif %} -

-
-
- {{ class_group.message|safe }} + {% if class_group %} +
+
+

+ {% if user|has_management_permissions or user.is_class_group_admin %} + {{ class_group.name }} + {% else %} + {{ class_group.name }} + {% endif %} +

+
+
+ {{ class_group.message|safe }} +
-
+ {% endif %} {% for announcement in announcements %}

- {% if user|has_management_permissions or user.is_class_group_admin %} + {% if user|has_management_permissions or user.is_class_group_admin and announcement.class_group.username_prefix != "_" %} {{ announcement.name }} {% else %} {{ announcement.name }} diff --git a/homecoming/urls.py b/homecoming/urls.py index 1aedf12..41fd3a0 100644 --- a/homecoming/urls.py +++ b/homecoming/urls.py @@ -5,7 +5,8 @@ path("admin/", admin.site.urls), path("oauth/", include("social_django.urls", namespace="social")), path( - "announcements/", include("homecoming.apps.announcements.urls", namespace="announcements") + "announcements/", + include("homecoming.apps.announcements.urls", namespace="announcements"), ), path("", include("homecoming.apps.auth.urls", namespace="auth")), path("", include("homecoming.apps.base.urls", namespace="base")),