Skip to content

Commit

Permalink
Fix for uploading project files (#120)
Browse files Browse the repository at this point in the history
* files are now patchable uncluding the files

* fix for uploading a file that is not a zip that it doesn't get saved

* unsaved changes

* buzoghany requested changes

* linter

* added rollbacks

* extra rollback
  • Loading branch information
Gerwoud authored Mar 21, 2024
1 parent 8b4b093 commit 2d0574c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 20 deletions.
55 changes: 51 additions & 4 deletions backend/project/endpoints/projects/project_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@
for example /projects/1 if the project id of
the corresponding project is 1
"""
from os import getenv
import os
import zipfile
from urllib.parse import urljoin

from flask import request
from flask_restful import Resource

from project.db_in import db

from project.models.project import Project
from project.utils.query_agent import query_by_id_from_model, delete_by_id_from_model, \
patch_by_id_from_model
from project.utils.authentication import authorize_teacher_or_project_admin, \
authorize_teacher_of_project, authorize_project_visible

API_URL = getenv('API_HOST')
from project.endpoints.projects.endpoint_parser import parse_project_params

API_URL = os.getenv('API_HOST')
RESPONSE_URL = urljoin(API_URL, "projects")
UPLOAD_FOLDER = os.getenv('UPLOAD_URL')


class ProjectDetail(Resource):
"""
Expand Down Expand Up @@ -45,14 +52,54 @@ def patch(self, project_id):
Update method for updating a specific project
filtered by id of that specific project
"""
project_json = parse_project_params()

return patch_by_id_from_model(
output, status_code = patch_by_id_from_model(
Project,
"project_id",
project_id,
RESPONSE_URL,
request.json
project_json
)
if status_code != 200:
return output, status_code

if "assignment_file" in request.files:
file = request.files["assignment_file"]
filename = os.path.basename(file.filename)
project_upload_directory = os.path.join(f"{UPLOAD_FOLDER}", f"{project_id}")
os.makedirs(project_upload_directory, exist_ok=True)
try:
# remove the old file
try:
to_rem_files = os.listdir(project_upload_directory)
for to_rem_file in to_rem_files:
to_rem_file_path = os.path.join(project_upload_directory, to_rem_file)
if os.path.isfile(to_rem_file_path):
os.remove(to_rem_file_path)
except FileNotFoundError:
db.session.rollback()
return ({
"message": "Something went wrong deleting the old project files",
"url": f"{API_URL}/projects/{project_id}"
})

# removed all files now upload the new files
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:
upload_zip.extractall(project_upload_directory)
project_json["assignment_file"] = filename
except zipfile.BadZipfile:
db.session.rollback()
return ({
"message":
"Please provide a valid .zip file for updating the instructions",
"url": f"{API_URL}/projects/{project_id}"
},
400)

return output, status_code

@authorize_teacher_of_project
def delete(self, project_id):
Expand Down
38 changes: 22 additions & 16 deletions backend/project/endpoints/projects/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from flask import request, jsonify
from flask_restful import Resource

from project.db_in import db

from project.models.project import Project
from project.utils.query_agent import query_selected_from_model, create_model_instance
from project.utils.authentication import authorize_teacher
Expand All @@ -18,6 +20,7 @@
API_URL = os.getenv('API_HOST')
UPLOAD_FOLDER = os.getenv('UPLOAD_URL')


class ProjectsEndpoint(Resource):
"""
Class for projects endpoints
Expand Down Expand Up @@ -47,10 +50,12 @@ def post(self, teacher_id=None):
using flask_restfull parse lib
"""

file = request.files["assignment_file"]
project_json = parse_project_params()
filename = os.path.basename(file.filename)
project_json["assignment_file"] = filename
filename = 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 @@ -73,20 +78,21 @@ def post(self, teacher_id=None):
return new_project, status_code

project_upload_directory = os.path.join(f"{UPLOAD_FOLDER}", f"{new_project.project_id}")

os.makedirs(project_upload_directory, exist_ok=True)

file.save(os.path.join(project_upload_directory, filename))
try:
with zipfile.ZipFile(os.path.join(project_upload_directory, filename)) as upload_zip:
upload_zip.extractall(project_upload_directory)
except zipfile.BadZipfile:
return ({
"message": "Please provide a .zip file for uploading the instructions",
"url": f"{API_URL}/projects"
},
400)

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:
upload_zip.extractall(project_upload_directory)
except zipfile.BadZipfile:
os.remove(os.path.join(project_upload_directory, filename))
db.session.rollback()
return ({
"message": "Please provide a .zip file for uploading the instructions",
"url": f"{API_URL}/projects"
},
400)
return {
"message": "Project created succesfully",
"data": new_project,
Expand Down

0 comments on commit 2d0574c

Please sign in to comment.