Skip to content

Commit 3d818b2

Browse files
committed
Fixed academic group histories, tasks calculating student loads, added script to fix mis-imported loads.
1 parent 3e0a06f commit 3d818b2

28 files changed

Lines changed: 250 additions & 243 deletions

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ print-%:
105105
# PROJECT COMMANDS
106106
############################################################################################
107107

108-
data: site school unit task
108+
data: site school unit task assignment
109109

110110
site:
111111
uv run physics_workload/manage.py loaddata site info
@@ -139,6 +139,8 @@ superuser:
139139

140140
initialise:
141141
uv run physics_workload/manage.py initialise
142+
uv run physics_workload/manage.py calchistoric
143+
uv run physics_workload/manage.py fixtaskfirsttime
142144

143145
all: database data initialise
144146

README.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ It's not included in the repo as it contains personally identifiable data.
2121

2222
### File Server
2323

24-
If using this on a machine serving multiple sites,
25-
you'll need to add the configuration file to your existing Nginx setup.
24+
If using this on a machine serving multiple sites,
25+
you'll need to add the configuration file to your existing Nginx setup.
2626
Assign ownership of the directory to the `physics-workload-staff` group and add `nginx` to it:
27-
```bash
27+
28+
```bash
2829
$ sudo usermod -a -G physics-workload-staff nginx
2930
$ sudo chgrp -R voidorchestra-staff /var/www/physics-workload
3031
$ sudo chmod -R g+rw /var/www/physics-workload
@@ -33,26 +34,29 @@ $ sudo chmod -R g+rw /var/www/physics-workload
3334
Then, depending on your Linux distribution:
3435

3536
#### Debian/Ubuntu
37+
3638
Copy or link `nginx/physics-workload.conf` to your `/etc/nginx/sites-enabled/` directory, then restart Nginx:
39+
3740
```bash
3841
$ ln -s /var/www/physics-workload/nginx/physics-workload.conf /etc/nginx/sites-enabled/
3942
$ sudo systemctl reload nginx
4043
$ sudo systemctl restart nginx
4144
```
4245

4346
#### Fedora/RHEL
47+
4448
Copy `nginx/physics-workload.conf` file to your `/etc/nginx/conf.d` directory.
4549
Then, flag the log directory as a log directory under SELinux,
4650
and the output directory as as HTML content directory too:
47-
```bash
51+
52+
```bash
4853
$ sudo cp /var/www/voidorchestra/nginx/physics-workload.conf /etc/nginx/conf.d/
4954
$ sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/physics-workload/staticfiles(/.*)?"
5055
$ sudo restorecon -R -v /var/www/physics-workload/staticfiles
5156
$ sudo semanage fcontext -a -t httpd_log_t "/var/www/physics-workload/logs(/.*)?"
5257
$ sudo restorecon -R -v /var/www/physics-workload/logs/
5358
```
5459

55-
5660
## Running
5761

5862
The tool is run using `docker compose`. Generally, it's best to do this in a `screen` session.
@@ -65,26 +69,26 @@ sudo docker compose up web
6569

6670
### Initialising
6771

68-
If this is the first time the tool is being run, import the `.csv` data:
72+
If this is the first time the tool is being run, import the `.xlsx` data:
6973

7074
```bash
7175
sudo docker exec -it physics-workload-django /bin/bash
72-
make clean
73-
make data
76+
make all
7477
```
7578

7679
Then, log into the website to link your user account to the site.
7780
The command `python physics_workload/manage.py makestaff <account>` will then make the user associated with the 365 account `<account>` site staff;
78-
e.g.
81+
e.g.
82+
7983
```bash
8084
python physics_workload/manage.py makestaff swm1r18
8185
```
8286

8387
### Manual Tweaks
8488

8589
The output of `make data` should list the Tasks, Staff and Units that weren't able to be automatically imported.
86-
You should then get a file `failed_assignments.csv` out;
87-
this is the lines from the "Staff Tasks" sheet of the Excel file that failed to import.
90+
You should then get a file `failed_assignments.csv` out;
91+
this is the lines from the "Staff Tasks" sheet of the Excel file that failed to import.
8892

8993
## Updating
9094

@@ -97,8 +101,6 @@ sudo docker compose build --no-cache
97101
sudo docker compose up web
98102
```
99103

100-
101-
102104
# Extra
103105

104106
> [!NOTE]

physics_workload/app/forms/task.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ class Meta:
4747
title = "Details"
4848
fields = dict(
4949
academic_group__include=lambda task, **_: task.academic_group,
50-
load_calc__group="Calculated Load",
50+
load_calc=dict(group="Calculated Load", include=lambda task, **_: task.assignment_students != Task.AssignmentStudentsChoices.REQUIRED),
5151
load_calc_first=dict(
5252
group="Calculated Load",
53-
include=lambda task, **_: task.load_calc_first != task.load_calc,
53+
include=lambda task, **_: task.load_calc_first != task.load_calc
54+
and task.assignment_students != Task.AssignmentStudentsChoices.REQUIRED,
5455
),
5556
is_required=dict(
5657
group="Calculated Load",
@@ -84,17 +85,18 @@ class Meta:
8485
),
8586
load_function=dict(
8687
include=lambda task, **_: task.load_function,
88+
non_editable_input__template="app/choice_url.html",
8789
group="Calculation Details",
8890
after="exam_fraction",
8991
),
9092
students=dict(
91-
include=lambda task, **_: not task.assignment_students=="INVALID",
93+
include=lambda task, **_: task.assignment_students == Task.AssignmentStudentsChoices.OPTIONAL,
9294
group="Calculation Details",
9395
after="load_function",
9496
),
9597
assignment_students=dict(
9698
include=False,
97-
)
99+
),
98100
)
99101
editable = False
100102

@@ -216,9 +218,7 @@ class Meta:
216218
initial="Unit Lead",
217219
group="Basic",
218220
),
219-
assignment_students=Field.hardcoded(
220-
parsed_data="INVALID"
221-
),
221+
assignment_students=Field.hardcoded(parsed_data=Task.AssignmentStudentsChoices.INVALID),
222222
is_unique=dict(
223223
group="Basic",
224224
initial=True,
@@ -266,7 +266,9 @@ class Meta:
266266
load_fixed_first__group="Load",
267267
load_multiplier__group="Load",
268268
load_function__group="Calculation",
269-
assignment_students__group="Calculation",
269+
assignment_students=dict(
270+
group="Calculation",
271+
),
270272
students__group="Calculation",
271273
)
272274

physics_workload/app/forms/unit.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class Meta:
1818
auto__exclude = ["task_set"]
1919
fields__code__group = "Basics"
2020
fields__name__group = "Basics"
21-
fields__academic_group=dict(
22-
group = "Basics",
23-
non_editable_input__template = "app/choice_url.html",
21+
fields__academic_group = dict(
22+
group="Basics",
23+
non_editable_input__template="app/choice_url.html",
2424
include=lambda unit, **_: unit.academic_group,
2525
)
2626
fields__students__group = "Basics"

physics_workload/app/main_menu/__init__.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
from django.urls import reverse_lazy
1+
from django.urls import reverse, reverse_lazy
22
from django.views.generic import RedirectView
33
from iommi.main_menu import M, MainMenu
44

5-
from django.urls import reverse_lazy, reverse
6-
75
from app.main_menu.academic_group import academic_group_submenu
86
from app.main_menu.info import info_submenu
97
from app.main_menu.load_function import load_function_submenu
@@ -14,7 +12,6 @@
1412
from app.pages.basic import AboutPage, PrivacyPage
1513
from app.views import home_redirect
1614

17-
1815
main_menu = MainMenu(
1916
items=dict(
2017
index=M(
@@ -31,10 +28,7 @@
3128
render=False,
3229
view=PrivacyPage().as_view(),
3330
),
34-
about=M(
35-
render=False,
36-
view=AboutPage().as_view()
37-
),
31+
about=M(render=False, view=AboutPage().as_view()),
3832
staff=staff_submenu,
3933
module=unit_submenu,
4034
task=task_submenu,

physics_workload/app/main_menu/academic_group.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from iommi.main_menu import M
33
from iommi.path import register_path_decoding
44

5-
65
from app.models import AcademicGroup, Task
76
from app.pages.academic_group import (
87
AcademicGroupCreate,
@@ -15,7 +14,6 @@
1514
from app.pages.academic_group.history import AcademicGroupHistoryList
1615
from app.pages.task import TaskDelete, TaskDetail, TaskEdit
1716

18-
1917
# Decodes "<academic_group>" in paths to add academic_group to params
2018
register_path_decoding(academic_group=AcademicGroup)
2119

physics_workload/app/management/commands/calchistoric.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from django.conf import settings
88
from django.core.management.base import BaseCommand
99
from django.db.models import Sum
10+
1011
from app.models import AcademicGroup, Staff
1112

1213
logger: Logger = getLogger(__name__)
@@ -29,7 +30,7 @@ def handle(self, *args: Path, **options):
2930
date_2022: datetime = datetime(year=2022, month=9, day=20, hour=0, minute=0, second=0, tzinfo=ZoneInfo("GMT"))
3031
date_2023: datetime = datetime(year=2023, month=9, day=20, hour=0, minute=0, second=0, tzinfo=ZoneInfo("GMT"))
3132
date_2024: datetime = datetime(year=2024, month=9, day=20, hour=0, minute=0, second=0, tzinfo=ZoneInfo("GMT"))
32-
date_2025: datetime = datetime(year=2025, month=9, day=20, hour=0, minute=0, second=0, tzinfo=ZoneInfo("GMT"))
33+
# date_2025: datetime = datetime(year=2025, month=9, day=20, hour=0, minute=0, second=0, tzinfo=ZoneInfo("GMT"))
3334

3435
for academic_group in AcademicGroup.objects.all():
3536
for history in academic_group.history.all():
@@ -69,6 +70,4 @@ def handle(self, *args: Path, **options):
6970
# Stop tracking history changes.
7071
settings.SIMPLE_HISTORY_ENABLED = False
7172

72-
self.stdout.write(
73-
self.style.SUCCESS("Calculation finished.")
74-
)
73+
self.stdout.write(self.style.SUCCESS("Calculation finished."))

physics_workload/app/management/commands/calcloads.py

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from django.core.management.base import BaseCommand
2+
3+
from app.models import Task
4+
5+
6+
class Command(BaseCommand):
7+
"""
8+
Initialises the staff workloads in the database.
9+
"""
10+
11+
help = "Fixes imported tasks where the 'first time' value is not a bonus added, but the flat value."
12+
13+
def handle(self, *args, **options):
14+
fixed_loads: int = 0
15+
16+
for task in Task.objects.all():
17+
if task.load_fixed_first and task.load_fixed_first > task.load_fixed:
18+
task.load_fixed_first = task.load_fixed_first - task.load_fixed
19+
task.save()
20+
fixed_loads += 1
21+
22+
if task.is_lead or task.is_full_time or task.is_unique:
23+
task.assignment_students = Task.AssignmentStudentsChoices.INVALID
24+
25+
self.stdout.write(self.style.SUCCESS(f"Successfully fixed {fixed_loads} tasks."))

0 commit comments

Comments
 (0)