Skip to content

Commit

Permalink
Merge pull request #101 from SELab-2/project-logic
Browse files Browse the repository at this point in the history
Project logic
  • Loading branch information
francisvaut authored Mar 13, 2024
2 parents b7cf8ed + 44516cf commit 4d7f6da
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 30 deletions.
13 changes: 13 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
PUID=1000
PGID=1000
TZ="Europe/Brussels"

DATADIR="./data"

BACKEND_DIR="./backend"

FRONTEND_DIR="./frontend"

REDIS_IP="192.168.90.10"
REDIS_PORT=6379
REDIS_PASSWORD="oqOsNX1PXGOX5soJtKkw"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.tool-versions
.env
.venv
data/*
data/nginx/ssl/*
data/postres*
Expand Down
2 changes: 1 addition & 1 deletion backend/.flake8
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Ignore unused imports
ignore = F401

max-line-length = 120
max-line-length = 125

max-complexity = 10

Expand Down
13 changes: 13 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.11.4

RUN apt update && apt install -y gettext libgettextpo-dev && pip install --upgrade pip

WORKDIR /code

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

COPY requirements.txt /code/
RUN pip install -r requirements.txt

COPY . /code/
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.2 on 2024-03-12 20:25

import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("api", "0005_alter_project_max_score"),
]

operations = [
migrations.AddField(
model_name="project",
name="locked_groups",
field=models.BooleanField(default=False),
),
]
12 changes: 12 additions & 0 deletions backend/api/migrations/0007_merge_20240313_0639.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated by Django 5.0.2 on 2024-03-13 06:39

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("api", "0006_project_locked_groups_alter_project_start_date_and_more"),
("api", "0006_project_score_visible_alter_project_start_date_and_more"),
]

operations = []
12 changes: 12 additions & 0 deletions backend/api/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class Project(models.Model):
# Project archived
archived = models.BooleanField(default=False)

# Locked groups
locked_groups = models.BooleanField(default=False)

start_date = models.DateTimeField(
# The default value is the current date and time
default=timezone.now,
Expand Down Expand Up @@ -84,6 +87,15 @@ def toggle_archived(self):
self.archived = not self.archived
self.save()

def is_groups_locked(self):
"""Returns True if participating groups are locked."""
return self.locked_groups

def toggle_groups_locked(self):
"""Toggles the locked state of the groups related to the project."""
self.locked_groups = not self.locked_groups
self.save()

def increase_deadline(self, days):
self.deadline = self.deadline + timedelta(days=days)
self.save()
8 changes: 8 additions & 0 deletions backend/api/serializers/group_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def validate(self, data):
group: Group = self.context["group"]
student: Student = data["student_id"]

# Make sure a student can't join if groups are locked
if group.project.is_groups_locked():
raise ValidationError(gettext("group.errors.locked"))

# Make sure the group is not already full
if group.is_full():
raise ValidationError(gettext("group.errors.full"))
Expand Down Expand Up @@ -90,4 +94,8 @@ def validate(self, data):
if not group.students.filter(id=student.id).exists():
raise ValidationError(gettext("group.errors.not_present"))

# Make sure a student can't leave if groups are locked
if group.project.is_groups_locked():
raise ValidationError(gettext("group.errors.locked"))

return data
30 changes: 29 additions & 1 deletion backend/api/serializers/project_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
from api.models.project import Project
from api.models.group import Group
from rest_framework.exceptions import ValidationError
from django.utils import timezone
from api.models.submission import Submission, SubmissionFile
from api.serializers.submission_serializer import SubmissionSerializer


class ProjectSerializer(serializers.ModelSerializer):
course = serializers.HyperlinkedRelatedField(
many=False, read_only=True, view_name="course-detail"
many=False,
view_name="course-detail",
read_only=True
)

structure_checks = serializers.HyperlinkedIdentityField(
Expand Down Expand Up @@ -46,10 +49,35 @@ class Meta:
"groups"
]

def validate(self, data):
if "course" in self.context:
data["course_id"] = self.context["course"].id
else:
raise ValidationError(gettext("project.errors.context"))

# Check if start date of the project is not in the past
if data["start_date"] < timezone.now().replace(hour=0, minute=0, second=0):
raise ValidationError(gettext("project.errors.start_date_in_past"))

# Check if deadline of the project is before the start date
if data["deadline"] < data["start_date"]:
raise ValidationError(gettext("project.errors.deadline_before_start_date"))

return data


class TeacherCreateGroupSerializer(serializers.Serializer):
number_groups = serializers.IntegerField(min_value=1)

def validate(self, data):
return data


class SubmissionStatusSerializer(serializers.Serializer):
non_empty_groups = serializers.IntegerField(read_only=True)
groups_submitted = serializers.IntegerField(read_only=True)
submissions_passed = serializers.IntegerField(read_only=True)


class SubmissionAddSerializer(SubmissionSerializer):
def validate(self, data):
Expand Down
Loading

0 comments on commit 4d7f6da

Please sign in to comment.