basic rapid integration testing
This commit is contained in:
+60
-26
@@ -48,6 +48,20 @@ import hashlib
|
||||
import pydicom
|
||||
import pydicom.errors
|
||||
|
||||
from typing import List, TypedDict, Required, NotRequired
|
||||
|
||||
|
||||
class QuestionData(TypedDict):
|
||||
images: Required[list[str]]
|
||||
annotations: Required[List[str]]
|
||||
type: Required[str]
|
||||
history: NotRequired[str]
|
||||
normal: Required[bool]
|
||||
answers: NotRequired[List[str]]
|
||||
feedback: NotRequired[str]
|
||||
feedback_images: NotRequired[List[str]]
|
||||
|
||||
|
||||
image_storage = FileSystemStorage(
|
||||
# Physical file location ROOT
|
||||
location="{0}".format(settings.MEDIA_ROOT),
|
||||
@@ -136,6 +150,15 @@ class Answer(models.Model):
|
||||
|
||||
|
||||
class Rapid(models.Model):
|
||||
"""
|
||||
Django model that defines a rapid question.
|
||||
|
||||
Images are help by a seperate model: RapidImage
|
||||
which has a foreign key to this model
|
||||
|
||||
|
||||
"""
|
||||
|
||||
question = models.TextField(null=True, blank=True)
|
||||
history = models.TextField(null=True, blank=True)
|
||||
feedback = models.TextField(null=True, blank=True)
|
||||
@@ -293,7 +316,7 @@ class Rapid(models.Model):
|
||||
exams = ", ".join(e)
|
||||
return exams
|
||||
|
||||
def get_unmarked_user_answer_string(self, exam_pk=None):
|
||||
def get_unmarked_user_answer_string(self, exam_pk: int=None):
|
||||
unmarked_answers = self.get_unmarked_user_answers(exam_pk)
|
||||
|
||||
if not unmarked_answers:
|
||||
@@ -304,7 +327,7 @@ class Rapid(models.Model):
|
||||
)
|
||||
)
|
||||
|
||||
def get_unmarked_user_answers(self, exam_pk=None, marker=None):
|
||||
def get_unmarked_user_answers(self, exam_pk: int|None=None, marker=None):
|
||||
# If normal no answers to mark (they will be automarked)
|
||||
if self.normal:
|
||||
return []
|
||||
@@ -446,8 +469,6 @@ class Rapid(models.Model):
|
||||
answers.append("{} {}".format(a.name, laterality))
|
||||
answers.append("{}".format(a.name))
|
||||
|
||||
|
||||
|
||||
compare_answers = self.get_compare_answers()
|
||||
|
||||
new_answers = [
|
||||
@@ -456,24 +477,30 @@ class Rapid(models.Model):
|
||||
|
||||
return new_answers
|
||||
|
||||
def get_question_json(self, based=True, feedback=False):
|
||||
"""Returns json"""
|
||||
def get_question_json(
|
||||
self, based: bool = True, feedback: bool = False, answers: bool = True, history: bool = False, annotations: bool = False
|
||||
) -> QuestionData:
|
||||
"""Returns a json representation of the question"""
|
||||
|
||||
# Loop through rapidimage associations
|
||||
images = []
|
||||
annotations = []
|
||||
feedback_images = []
|
||||
for i in self.images.all():
|
||||
annotations.append(i.image_annotations)
|
||||
# TODO: add anotations
|
||||
|
||||
if i.feedback_image == True:
|
||||
if based:
|
||||
feedback_images.append(image_as_base64(i.image))
|
||||
else:
|
||||
feedback_images.append(
|
||||
"{}/{}".format(settings.REMOTE_URL, i.image.url)
|
||||
)
|
||||
# feedback_images.append("{}/{}".format(settings.REMOTE_URL, i.image.url))
|
||||
if feedback:
|
||||
annotations.append(i.image_annotations)
|
||||
if based:
|
||||
feedback_images.append(image_as_base64(i.image))
|
||||
else:
|
||||
feedback_images.append(
|
||||
"{}/{}".format(settings.REMOTE_URL, i.image.url)
|
||||
)
|
||||
# feedback_images.append("{}/{}".format(settings.REMOTE_URL, i.image.url))
|
||||
else:
|
||||
annotations.append(i.image_annotations)
|
||||
if based:
|
||||
images.append(image_as_base64(i.image))
|
||||
else:
|
||||
@@ -482,16 +509,21 @@ class Rapid(models.Model):
|
||||
json = {
|
||||
"images": images,
|
||||
# "feedback_image": [],
|
||||
"annotations": annotations,
|
||||
"type": "rapid",
|
||||
}
|
||||
|
||||
json["history"] = self.history
|
||||
json["normal"] = self.normal
|
||||
json["feedback_images"] = feedback_images
|
||||
json["answers"] = list(self.get_correct_unstripped_answers())
|
||||
if annotations:
|
||||
json["annotations"] = self.annotations
|
||||
|
||||
if history:
|
||||
json["history"] = self.history
|
||||
|
||||
if answers:
|
||||
json["normal"] = self.normal
|
||||
json["answers"] = list(self.get_correct_unstripped_answers())
|
||||
|
||||
if feedback:
|
||||
json["feedback_images"] = feedback_images
|
||||
json["feedback"] = self.feedback
|
||||
|
||||
return json
|
||||
@@ -537,8 +569,6 @@ class RapidImage(models.Model):
|
||||
|
||||
is_dicom = models.BooleanField(default=False)
|
||||
|
||||
|
||||
|
||||
def image_tag(self):
|
||||
if self.image:
|
||||
return mark_safe(
|
||||
@@ -580,8 +610,12 @@ class RapidImage(models.Model):
|
||||
|
||||
self.is_dicom = True
|
||||
except pydicom.errors.InvalidDicomError:
|
||||
self.image.file.open()
|
||||
hash = hashlib.md5(self.image.read()).hexdigest()
|
||||
try: # This is horrible (but needed for current unit tests)
|
||||
# (we use a temporary file that breaks here)
|
||||
self.image.file.open()
|
||||
hash = hashlib.md5(self.image.read()).hexdigest()
|
||||
except AttributeError:
|
||||
return
|
||||
|
||||
self.image_md5_hash = hash
|
||||
super().save(*args, **kwargs) # Call the "real" save() method.
|
||||
@@ -633,15 +667,14 @@ class Exam(ExamBase):
|
||||
CidUserGroup,
|
||||
blank=True,
|
||||
help_text="These groups define which candidates are able to be added to the exams/collection.",
|
||||
related_name="rapid_cid_user_groups"
|
||||
|
||||
related_name="rapid_cid_user_groups",
|
||||
)
|
||||
|
||||
user_user_groups = models.ManyToManyField(
|
||||
UserUserGroup,
|
||||
blank=True,
|
||||
help_text="These groups define which candidates are able to be added to the exams/collection.",
|
||||
related_name="rapid_user_user_groups"
|
||||
related_name="rapid_user_user_groups",
|
||||
)
|
||||
|
||||
exam_user_status = GenericRelation(ExamUserStatus)
|
||||
@@ -667,6 +700,7 @@ class Exam(ExamBase):
|
||||
|
||||
exam_order = []
|
||||
|
||||
q: Rapid
|
||||
for q in questions:
|
||||
exam_order.append(q.id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user