Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Removed paths from db for projects and allowing multiple deadlines #185

Merged
merged 7 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions backend/db_construct.sql
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,19 @@ CREATE TABLE course_students (
PRIMARY KEY(course_id, uid)
);

CREATE TYPE deadline AS(
description TEXT,
deadline TIMESTAMP WITH TIME ZONE
);

CREATE TABLE projects (
project_id INT GENERATED ALWAYS AS IDENTITY,
title VARCHAR(50) NOT NULL,
description TEXT NOT NULL,
assignment_file VARCHAR(50),
deadline TIMESTAMP WITH TIME ZONE,
deadlines deadline[],
course_id INT NOT NULL,
visible_for_students BOOLEAN NOT NULL,
archived BOOLEAN NOT NULL,
test_path VARCHAR(50),
script_name VARCHAR(50),
regex_expressions VARCHAR(50)[],
PRIMARY KEY(project_id),
CONSTRAINT fk_course FOREIGN KEY(course_id) REFERENCES courses(course_id) ON DELETE CASCADE
Expand Down
20 changes: 15 additions & 5 deletions backend/project/endpoints/projects/endpoint_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Parser for the argument when posting or patching a project
"""

import json
from flask_restful import reqparse
from werkzeug.datastructures import FileStorage

Expand All @@ -14,7 +15,7 @@
help='Projects assignment file',
location="form"
)
parser.add_argument("deadline", type=str, help='Projects deadline', location="form")
parser.add_argument('deadlines', type=str, help='Projects deadlines', location="form")
parser.add_argument("course_id", type=str, help='Projects course_id', location="form")
parser.add_argument(
"visible_for_students",
Expand All @@ -23,8 +24,6 @@
location="form"
)
parser.add_argument("archived", type=bool, help='Projects', location="form")
parser.add_argument("test_path", type=str, help='Projects test path', location="form")
parser.add_argument("script_name", type=str, help='Projects test script path', location="form")
parser.add_argument(
"regex_expressions",
type=str,
Expand All @@ -39,9 +38,20 @@ def parse_project_params():
"""
args = parser.parse_args()
result_dict = {}

for key, value in args.items():
if value is not None:
result_dict[key] = value
if "deadlines" == key:
deadlines_parsed = json.loads(value)
new_deadlines = []
for deadline in deadlines_parsed:
new_deadlines.append(
(
deadline["description"],
deadline["deadline"]
)
)
result_dict[key] = new_deadlines
else:
result_dict[key] = value

return result_dict
2 changes: 1 addition & 1 deletion backend/project/endpoints/projects/project_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def patch(self, project_id):
zip_location = os.path.join(project_upload_directory, filename)
with zipfile.ZipFile(zip_location) as upload_zip:
upload_zip.extractall(project_upload_directory)
project_json["assignment_file"] = filename

except zipfile.BadZipfile:
db.session.rollback()
return ({
Expand Down
9 changes: 4 additions & 5 deletions backend/project/endpoints/projects/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get(self, teacher_id=None):
return query_selected_from_model(
Project,
response_url,
select_values=["project_id", "title", "description", "deadline"],
select_values=["project_id", "title", "description", "deadlines"],
url_mapper={"project_id": response_url},
filters=request.args
)
Expand All @@ -55,7 +55,6 @@ def post(self, teacher_id=None):
if "assignment_file" in request.files:
file = request.files["assignment_file"]
filename = os.path.basename(file.filename)
project_json["assignment_file"] = filename

# save the file that is given with the request
try:
Expand All @@ -81,9 +80,9 @@ def post(self, teacher_id=None):
os.makedirs(project_upload_directory, exist_ok=True)
if filename is not None:
try:
file.save(os.path.join(project_upload_directory, filename))
zip_location = os.path.join(project_upload_directory, filename)
with zipfile.ZipFile(zip_location) as upload_zip:
file_path = os.path.join(project_upload_directory, filename)
file.save(file_path)
with zipfile.ZipFile(file_path) as upload_zip:
upload_zip.extractall(project_upload_directory)
except zipfile.BadZipfile:
os.remove(os.path.join(project_upload_directory, filename))
Expand Down
16 changes: 12 additions & 4 deletions backend/project/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from dataclasses import dataclass
from sqlalchemy import ARRAY, Boolean, Column, DateTime, ForeignKey, Integer, String, Text
from sqlalchemy_utils import CompositeType
from project.db_in import db

@dataclass
Expand All @@ -23,11 +24,18 @@ class Project(db.Model): # pylint: disable=too-many-instance-attributes
project_id: int = Column(Integer, primary_key=True)
title: str = Column(String(50), nullable=False, unique=False)
description: str = Column(Text, nullable=False)
assignment_file: str = Column(String(50))
deadline: str = Column(DateTime(timezone=True))
deadlines: list = Column(ARRAY(
CompositeType(
"deadline",
[
Column("description", Text),
Column("deadline", DateTime(timezone=True))
]
),
dimensions=1
)
)
course_id: int = Column(Integer, ForeignKey("courses.course_id"), nullable=False)
visible_for_students: bool = Column(Boolean, nullable=False)
archived: bool = Column(Boolean, nullable=False)
test_path: str = Column(String(50))
script_name: str = Column(String(50))
regex_expressions: list[str] = Column(ARRAY(String(50)))
1 change: 1 addition & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ flask~=3.0.2
flask-cors
flask-restful
flask-sqlalchemy
sqlalchemy_utils
python-dotenv~=1.0.1
psycopg2-binary
pytest~=8.0.1
Expand Down
10 changes: 2 additions & 8 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,19 @@ def projects(session):
Project(
title="B+ Trees",
description="Implement B+ trees",
assignment_file="assignement.pdf",
deadline=datetime(2024,3,15,13,0,0),
deadlines=[("Deadline 1",datetime(2024,3,15,13,0,0))],
course_id=course_id_ad3,
visible_for_students=True,
archived=False,
test_path="/tests",
script_name="script.sh",
regex_expressions=["solution"]
),
Project(
title="Predicaten",
description="Predicaten project",
assignment_file="assignment.pdf",
deadline=datetime(2023,3,15,13,0,0),
deadlines=[("Deadline 1", datetime(2023,3,15,13,0,0))],
course_id=course_id_raf,
visible_for_students=False,
archived=True,
test_path="/tests",
script_name="script.sh",
regex_expressions=[".*"]
)
]
Expand Down
5 changes: 1 addition & 4 deletions backend/tests/endpoints/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,10 @@ def valid_project(valid_course_entry):
data = {
"title": "Project",
"description": "Test project",
"assignment_file": "testfile",
"deadline": "2024-02-25T12:00:00",
"deadlines": [{"deadline": "2024-02-25T12:00:00", "description": "Deadline 1"}],
"course_id": valid_course_entry.course_id,
"visible_for_students": True,
"archived": False,
"test_path": "tests",
"script_name": "script.sh",
"regex_expressions": ["*.pdf", "*.txt"]
}
return data
Expand Down
4 changes: 4 additions & 0 deletions backend/tests/endpoints/project_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""Tests for project endpoints."""

import json

def test_assignment_download(client, valid_project):
"""
Method for assignment download
"""

valid_project["deadlines"] = json.dumps(valid_project["deadlines"])
with open("tests/resources/testzip.zip", "rb") as zip_file:
valid_project["assignment_file"] = zip_file
# post the project
Expand Down Expand Up @@ -48,6 +51,7 @@ def test_getting_all_projects(client):
def test_post_project(client, valid_project):
"""Test posting a project to the database and testing if it's present"""

valid_project["deadlines"] = json.dumps(valid_project["deadlines"])
with open("tests/resources/testzip.zip", "rb") as zip_file:
valid_project["assignment_file"] = zip_file
# post the project
Expand Down
5 changes: 1 addition & 4 deletions backend/tests/models/project_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@ def test_create_project(self, session: Session):
project = Project(
title="Pigeonhole",
description="A new project",
assignment_file="assignment.pdf",
deadline=datetime(2024,12,31,23,59,59),
deadlines=[("Deadline 1", datetime(2024,12,31,23,59,59))],
course_id=course.course_id,
visible_for_students=True,
archived=False,
test_path="/test",
script_name="script",
regex_expressions=[r".*"]
)
session.add(project)
Expand Down