Merge branch 'master' of ssh://git.xkjq.uk:30001/ross/rad

This commit is contained in:
Ross
2021-03-18 23:08:04 +00:00
9 changed files with 197 additions and 42 deletions
@@ -0,0 +1,18 @@
# Generated by Django 3.1.3 on 2021-03-09 15:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('anatomy', '0034_auto_20210215_1200'),
]
operations = [
migrations.AddField(
model_name='exam',
name='json_creation_time',
field=models.DateTimeField(blank=True, default=None, null=True),
),
]
+2
View File
@@ -64,6 +64,8 @@ class ExamBase(models.Model):
help_text="If the json cache needs updating", default=False
)
json_creation_time = models.DateTimeField(blank=True, default=None, null=True)
#time_limit = models.IntegerField(
# help_text="Exam time limit (in seconds). Default is 2100 secondse (35 minutes)",
# default=2100,
+45 -11
View File
@@ -32,6 +32,10 @@ from anatomy.models import AnatomyQuestion as AnatomyQuestion
from anatomy.models import Exam as AnatomyExam
from django.db.models import Case, When
from django.conf import settings
from datetime import datetime
import os
# Create your views here.
@@ -177,6 +181,8 @@ class ExamViews(View, LoginRequiredMixin):
exam.recreate_json = True
exam.save()
exam.get_exam_json()
return redirect("{}:exam_overview".format(self.app_name), pk=pk)
@method_decorator(login_required)
@@ -315,13 +321,25 @@ class ExamViews(View, LoginRequiredMixin):
for exam in exams:
if exam.active:
active_exams["exams"].append(
{
if exam.json_creation_time:
creation_time = exam.json_creation_time.isoformat()
else:
creation_time = "None"
obj = {
"name": exam.get_exam_name(),
"url": request.build_absolute_uri(exam.get_json_url()),
"type": self.question_type,
"eid": "{}/{}".format(self.question_type, exam.pk),
"json_creation_time": creation_time
}
)
if self.question_type == "long":
h = {}
for question in exam.exam_questions.all():
h[question.pk] = question.json_creation_time.isoformat()
obj["multi_question_json"] = h
active_exams["exams"].append( obj )
if json == False:
return active_exams["exams"]
@@ -356,24 +374,37 @@ class ExamViews(View, LoginRequiredMixin):
if not exam.active:
raise Http404("No available exam")
exam_json_cache = cache.get("{}_exam_json_{}".format(self.app_name, pk))
if exam_json_cache is not None and not exam.recreate_json:
exam_json_cache["cached"] = True
#exam_json_cache = cache.get("{}_exam_json_{}".format(self.app_name, pk))
path= "{0}{1}/exam/{2}.json".format(settings.MEDIA_ROOT, self.app_name, pk)
url= "{0}{1}/exam/{2}.json".format(settings.MEDIA_URL, self.app_name, pk)
if os.path.isfile(path) and not exam.recreate_json:
#exam_json_cache["cached"] = True
return redirect(url)
return JsonResponse(exam_json_cache)
exam_json = exam.get_exam_json()
time = datetime.now()
with open(path, "w+") as f:
exam_json = exam.get_exam_json()
exam_json["generated"] = time.isoformat()
f.write(json.dumps(exam_json))
exam.recreate_json = False
exam.json_creation_time = time
exam.save()
# We also try to clear the cache of any associated questions (longs)
# see exam_question_json
n = exam.exam_questions.count()
question_keys = ["{}_exam_json_{}_{}".format(self.app_name, pk, i) for i in range(1, n)]
cache.delete_many(question_keys)
#n = exam.exam_questions.count()
#question_keys = ["{}_exam_json_{}_{}".format(self.app_name, pk, i) for i in range(1, n)]
#cache.delete_many(question_keys)
cache.set("{}_exam_json_{}".format(self.app_name, pk), exam_json, 3600)
#cache.set("{}_exam_json_{}".format(self.app_name, pk), exam_json, 3600)
return JsonResponse(exam_json)
@@ -384,6 +415,9 @@ class ExamViews(View, LoginRequiredMixin):
if not exam.active:
raise Http404("No available exam")
return redirect("{}:question_json".format(self.app_name), pk=sk)
redirect()
question_json_cache = cache.get("{}_question_json_{}".format(self.app_name, sk))
if question_json_cache is not None and not question.recreate_json:
@@ -0,0 +1,23 @@
# Generated by Django 3.1.3 on 2021-03-09 15:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('longs', '0030_long_recreate_json'),
]
operations = [
migrations.AddField(
model_name='exam',
name='json_creation_time',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AddField(
model_name='long',
name='json_creation_time',
field=models.DateTimeField(blank=True, default=None, null=True),
),
]
+60 -24
View File
@@ -1,3 +1,4 @@
import json
from django.db.models.fields.files import ImageField
from django.db.models.fields.related import ForeignKey
from django.db import models
@@ -34,6 +35,7 @@ from easy_thumbnails.files import get_thumbnailer
from easy_thumbnails.exceptions import InvalidImageFormatError
import pydicom
import datetime
@@ -118,6 +120,10 @@ class Long(models.Model):
help_text="If the json cache needs updating", default=False
)
json_creation_time = models.DateTimeField(blank=True, default=None)
#question_file = models.FileField(upload_to=question_file_directory_path, blank=True, null=True)
def get_absolute_url(self):
return reverse("longs:question_detail", kwargs={"pk": self.pk})
@@ -164,35 +170,64 @@ class Long(models.Model):
return [ans for ans in answers if not ans.is_marked()]
def get_json(self, question_id):
# self == q?
q = get_object_or_404(Long, pk=question_id)
#exam_order.append(q.id)
path= "{0}longs/questions/{1}.json".format(settings.MEDIA_ROOT, question_id)
url= "{0}longs/questions/{1}.json".format(settings.MEDIA_URL, question_id)
# Loop through longimage associations
images = []
image_titles = []
for series in q.series.all():
#image_array = []
#for i in series.images.all():
# image_array.append(image_as_base64(i.image))
# #image_array.append(i.image.url)
image_array = [image_as_base64(i.image) for i in series.images.all()]
images.append(image_array)
image_titles.append(series.get_examination())
timestamp = datetime.datetime.now()
with open(path, "w+") as f:
exam_question = {
"title": q.history,
"images": images,
"image_titles": image_titles,
#"feedback_image": [],
#"annotations": [str(q.image_annotations)],
# We manually create the json for long questions to reducem memroy usade
f.write("""{{
"title": "{}",
"type": "long",
"cached": False,
}
"generated": "{}",
""".format(q.history, timestamp.isoformat())
)
return exam_question
f.write('"images" : [')
#images = []
image_titles = []
question_series = q.series.all()
# Loop through longimage associations
for i, series in enumerate(question_series):
#image_array = []
#for i in series.images.all():
# image_array.append(image_as_base64(i.image))
# #image_array.append(i.image.url)
# We are still limited by the size of a series (although this should not be too big or computers will crash...)
image_array = [image_as_base64(i.image) for i in series.images.all()]
#image_array = [i.image.url for i in series.images.all()]
f.write(json.dumps(image_array))
#images.append(url)
if i != len(question_series) - 1:
f.write(",")
image_titles.append(series.get_examination())
f.write("],")
f.write('"image_titles" : {} }}'.format(json.dumps(image_titles)))
self.json_creation_time = timestamp
self.save()
#exam_question = {
# "title": q.history,
# "images": images,
# "image_titles": image_titles,
# #"feedback_image": [],
# #"annotations": [str(q.image_annotations)],
# "type": "long",
# "cached": False,
#}
return url
@@ -482,6 +517,7 @@ class Exam(ExamBase):
#"feedback_image": [],
#"annotations": [str(q.image_annotations)],
"type": "long",
"images_json": True,
}
return exam_question
@@ -498,7 +534,7 @@ class Exam(ExamBase):
for q in questions:
exam_order.append(q.id)
exam_questions[q.id] = n
exam_questions[q.id] = q.json_creation_time.isoformat()
continue
@@ -538,7 +574,7 @@ class Exam(ExamBase):
"exam_mode": True,
"exam_order": exam_order,
"questions": exam_questions,
"question_requests": True,
"question_requests": exam_questions,
}
@@ -53,5 +53,8 @@
</ul>
</div>
<div>
JSON creation time: {{question.json_creation_time}} ({{question.json_creation_time|date:"c"}})
</div>
<a href="{% url 'longs:question_json' pk=question.pk %}">JSON</a>
<a href="{% url 'longs:question_json_recreate' pk=question.pk %}">Refresh JSON cache</a>
+10 -7
View File
@@ -47,6 +47,7 @@ import statistics
import plotly.express as px
from django.core.cache import cache
from django.conf import settings
from helpers.images import image_as_base64
@@ -63,6 +64,8 @@ from rest_framework import viewsets
from .serializers import ExamSerializer
import os
logger = logging.getLogger(__name__)
@@ -993,20 +996,18 @@ def question_json(request, pk):
#if not exam.active:
# raise Http404("No available exam")
question_json_cache = cache.get("{}_question_json_{}".format("longs", pk))
path= "{0}longs/questions/{1}.json".format(settings.MEDIA_ROOT, pk)
url= "{0}longs/questions/{1}.json".format(settings.MEDIA_URL, pk)
if question_json_cache is not None and not question.recreate_json:
question_json_cache["cached"] = True
return JsonResponse(question_json_cache)
if os.path.isfile(path) and not question.recreate_json:
return redirect(url)
question_json = question.get_json(pk)
cache.set("{}_question_json_{}".format("longs", pk), question_json, 3600)
question.recreate_json = False
question.save()
return JsonResponse(question_json)
return redirect(question_json)
@login_required
def question_json_recreate(request, pk):
@@ -1015,4 +1016,6 @@ def question_json_recreate(request, pk):
question.recreate_json = True
question.save()
question.get_json(pk)
return redirect("longs:question_detail", pk=pk)
@@ -0,0 +1,18 @@
# Generated by Django 3.1.3 on 2021-03-09 15:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('physics', '0003_auto_20201228_2235'),
]
operations = [
migrations.AddField(
model_name='exam',
name='json_creation_time',
field=models.DateTimeField(blank=True, default=None, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 3.1.3 on 2021-03-09 15:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rapids', '0019_auto_20210215_1203'),
]
operations = [
migrations.AddField(
model_name='exam',
name='json_creation_time',
field=models.DateTimeField(blank=True, default=None, null=True),
),
]