summaryrefslogtreecommitdiff
path: root/yaksh/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'yaksh/models.py')
-rw-r--r--yaksh/models.py65
1 files changed, 49 insertions, 16 deletions
diff --git a/yaksh/models.py b/yaksh/models.py
index ceb763f..d792205 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -45,7 +45,8 @@ from django.template import Context, Template
from django.conf import settings
from django.forms.models import model_to_dict
from django.db.models import Count
-
+from django.db.models.signals import pre_delete
+from django.db.models.fields.files import FieldFile
# Local Imports
from yaksh.code_server import (
submit, get_result as get_result_from_code_server
@@ -54,6 +55,7 @@ from yaksh.settings import SERVER_POOL_PORT, SERVER_HOST_NAME
from .file_utils import extract_files, delete_files
from grades.models import GradingSystem
+
languages = (
("python", "Python"),
("bash", "Bash"),
@@ -272,6 +274,17 @@ def is_valid_time_format(time):
return status
+def file_cleanup(sender, instance, *args, **kwargs):
+ '''
+ Deletes the file(s) associated with a model instance. The model
+ is not saved after deletion of the file(s) since this is meant
+ to be used with the pre_delete signal.
+ '''
+ for field_name, _ in instance.__dict__.items():
+ field = getattr(instance, field_name)
+ if issubclass(field.__class__, FieldFile) and field.name:
+ field.delete(save=False)
+
###############################################################################
class CourseManager(models.Manager):
@@ -1424,11 +1437,10 @@ class Question(models.Model):
]
}
- def consolidate_answer_data(self, user_answer, user=None):
+ def consolidate_answer_data(self, user_answer, user=None, regrade=False):
question_data = {}
metadata = {}
test_case_data = []
-
test_cases = self.get_test_cases()
for test in test_cases:
@@ -1441,19 +1453,34 @@ class Question(models.Model):
metadata['partial_grading'] = self.partial_grading
files = FileUpload.objects.filter(question=self)
if files:
- metadata['file_paths'] = [(file.file.path, file.extract)
- for file in files]
- if self.type == "upload":
- assignment_files = AssignmentUpload.objects.filter(
- assignmentQuestion=self
- )
- if assignment_files:
- metadata['assign_files'] = [(file.assignmentFile.path, False)
- for file in assignment_files]
+ if settings.USE_AWS:
+ metadata['file_paths'] = [
+ (file.file.url, file.extract)
+ for file in files
+ ]
+ else:
+ metadata['file_paths'] = [
+ (self.get_file_url(file.file.url), file.extract)
+ for file in files
+ ]
+ if self.type == "upload" and regrade:
+ file = AssignmentUpload.objects.only(
+ "assignmentFile").filter(
+ assignmentQuestion_id=self.id, answer_paper__user_id=user.id
+ ).order_by("-id").first()
+ if file:
+ if settings.USE_AWS:
+ metadata['assign_files'] = [file.assignmentFile.url]
+ else:
+ metadata['assign_files'] = [
+ self.get_file_url(file.assignmentFile.url)
+ ]
question_data['metadata'] = metadata
-
return json.dumps(question_data)
+ def get_file_url(self, path):
+ return f'{settings.DOMAIN_HOST}{path}'
+
def dump_questions(self, question_ids, user):
questions = Question.objects.filter(id__in=question_ids,
user_id=user.id, active=True
@@ -1692,7 +1719,7 @@ class FileUpload(models.Model):
def get_filename(self):
return os.path.basename(self.file.name)
-
+pre_delete.connect(file_cleanup, sender=FileUpload)
###############################################################################
class Answer(models.Model):
"""Answers submitted by the users."""
@@ -2598,7 +2625,7 @@ class AnswerPaper(models.Model):
return (False, f'{msg} {question.type} answer submission error')
else:
answer = user_answer.answer
- json_data = question.consolidate_answer_data(answer) \
+ json_data = question.consolidate_answer_data(answer, self.user, True) \
if question.type == 'code' else None
result = self.validate_answer(answer, question,
json_data, user_answer.id,
@@ -2648,7 +2675,11 @@ class AssignmentUploadManager(models.Manager):
answer_paper__question_paper=qp,
answer_paper__course_id=course_id
)
- file_name = User.objects.get(id=user_id).get_full_name()
+ user_name = assignment_files.values_list(
+ "answer_paper__user__first_name",
+ "answer_paper__user__last_name"
+ )[0]
+ file_name = "_".join(user_name)
else:
assignment_files = AssignmentUpload.objects.filter(
answer_paper__question_paper=qp,
@@ -2675,6 +2706,8 @@ class AssignmentUpload(models.Model):
def __str__(self):
return f'Assignment File of the user {self.answer_paper.user}'
+pre_delete.connect(file_cleanup, sender=AssignmentUpload)
+
##############################################################################
class TestCase(models.Model):