clone rapids app into longs
This commit is contained in:
Executable
+5
@@ -0,0 +1,5 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load static %}
|
||||
{% block extrahead %}
|
||||
<link rel="stylesheet" href="{% static 'css/admin.css' %}">
|
||||
{% endblock %}
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% for author in authors %}
|
||||
<p>Author: <a href="{% url 'rapids:author_detail' pk=author.pk %}">{{author.username}}</a>, </p>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}
|
||||
Rapids
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
{% block navigation %}
|
||||
Rapids:
|
||||
{% if request.user.is_authenticated %}
|
||||
<a href="{% url 'rapids:exam_list' %}">Exams</a> /
|
||||
<a href="{% url 'rapids:rapid_view' %}">Questions</a> /
|
||||
<a href="{% url 'rapids:rapid_create' %}" title="Create a new question">Create Question</a>
|
||||
{% endif %}
|
||||
{% comment %} </br>
|
||||
Questions by:
|
||||
<span id="authors-link"><a href="{% url 'rapids:author_list' %}">author</a></span> {% endcomment %}
|
||||
{% endblock %}
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
{{category}}:
|
||||
<ul>
|
||||
{% for rapid in rapids %}
|
||||
<li><a href="{% url 'rapids:rapid_detail' pk=rapid.pk %}">{{rapid}}
|
||||
[{{rapid.get_authors}}]</a></li>
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
<h2>Add new {{name}}</h2>
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="save btn btn-default">Save</button>
|
||||
</form>
|
||||
@@ -0,0 +1,79 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#flagged-button").click(function () {
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'rapids:flag_question' %}",
|
||||
data: {
|
||||
'pk': {{ question.pk }}
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
console.log(data.flagged);
|
||||
if(data.flagged) {
|
||||
$("#flagged-button").text("Flagged");
|
||||
$("#flagged-button").attr("class", "flagged");
|
||||
|
||||
} else {
|
||||
$("#flagged-button").text("Not Flagged");
|
||||
$("#flagged-button").attr("class", "not-flagged");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
$("#id_answer").keyup(function (event) {
|
||||
if(event.keyCode == 13) {
|
||||
$(".btn-default").click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<h1>Question {{question_details.current}} of {{question_details.total}}</h1>
|
||||
<p>{{ question.question_type.first }}</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="dicom-image" class="dicom-image" data-url="{{ question.image.url}}" data-annotations='{{question.image_annotations}}'>
|
||||
</div>
|
||||
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
{% if question_details.current > 1 %}
|
||||
<button type="submit" name="previous" class="btn btn-previous">Previous</button>
|
||||
{% endif %}
|
||||
{% if question_details.current >= question_details.total %}
|
||||
<button type="submit" name="save" class="save btn btn-default">Save</button>
|
||||
{% else %}
|
||||
<button type="submit" name="next" class="save btn btn-default">Next</button>
|
||||
{% endif %}
|
||||
<button id=flagged-button type="button"
|
||||
class={% if answer.flagged == True %}flagged{% else %}not-flagged{% endif %}>{% if answer.flagged == True %}Flagged{% else %}Not
|
||||
Flagged{% endif %}</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<div class=exam-navigation />
|
||||
<ul id=question-list>
|
||||
{% for question in questions %}
|
||||
<li><a class={% if question.pk in answered_questions %}answered{% else %}unanswered{% endif %}
|
||||
href="{% url 'rapids:exam_take' pk=exam.pk sk=forloop.counter0 %}">{{ forloop.counter }}{% if question.pk in flagged_questions %}!{% endif %}</a>
|
||||
</li>
|
||||
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,30 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Examinations</h1>
|
||||
<div class="rapids">
|
||||
Active exams:<br/>
|
||||
<ul>
|
||||
{% for exam in exams %}
|
||||
{% if exam.active %}
|
||||
<li>
|
||||
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">{{exam.name}}</a> <a href="{% url 'rapids:mark_overview' pk=exam.pk %}">(mark)</a> <a href="{% url 'rapids:exam_scores_cid' pk=exam.pk %}">(scores)</a> [Results are {% if not exam.publish_results %} not {% endif %}published]
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
Inactive exams:<br/>
|
||||
<ul>
|
||||
{% for exam in exams %}
|
||||
{% if not exam.active %}
|
||||
<li>
|
||||
<a href="{% url 'rapids:exam_overview' pk=exam.pk %}">{{exam.name}}</a> <a href="{% url 'rapids:mark_overview' pk=exam.pk %}">(mark)</a> <a href="{% url 'rapids:exam_scores_cid' pk=exam.pk %}">(scores)</a> [Results are {% if not exam.publish_results %} not {% endif %}published]
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,141 @@
|
||||
{% extends 'rapids/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% load thumbnail %}
|
||||
<div class="rapids">
|
||||
<a href="{% url 'admin:rapids_exam_change' exam.id %}" title="Edit the Exam using the admin interface">Admin Edit</a>
|
||||
<h1>Exam: {{ exam.name }}</h1>
|
||||
This exam has {{question_number}} questions. Time limit: {{exam.time_limit}} seconds.
|
||||
|
||||
<div class="parent-help" title="Click to enable / disable the exam">
|
||||
Exam active: <input type="checkbox" id="exam-active-switch" {% if exam.active %}checked{% endif %}> <span class="help-text">[When checked the exam will be available to take in the test system]</span>
|
||||
</div>
|
||||
<div class="parent-help" title="Click to enable / disable the exam results">
|
||||
Publish results: <input type="checkbox" id="exam-publish-results-switch" {% if exam.publish_results %}checked{% endif %}> <span class="help-text">[When checked the exam results will be available on this site]</span>
|
||||
</div>
|
||||
<p><a href="{% url 'rapids:mark_overview' pk=exam.pk %}"><button>Mark exam</button></a></p>
|
||||
|
||||
<ol id="full-question-list">
|
||||
{% for question in questions.all %}
|
||||
|
||||
<li>
|
||||
{% for image in question.GetImages %}
|
||||
<img src="{{ image|thumbnail_url:'exam-list' }}" alt="thumbail" />
|
||||
{% endfor %}
|
||||
{% if not question.normal %}
|
||||
<b>Abnormality:</b> {{ question.get_abnormalities }} <b>Region:</b> {{ question.get_regions }}
|
||||
<br />
|
||||
{{ question.GetPrimaryAnswer }}
|
||||
{% else %}
|
||||
<b>Normal</b>
|
||||
{% endif %}
|
||||
<br />
|
||||
Examination: {{ question.get_examinations }}, <a href="{% url 'rapids:exam_question_detail' pk=exam.pk sk=forloop.counter0 %}">View</a>, <a href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Mark</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
<a href="{% url 'rapids:exam_json' pk=exam.pk %}">JSON</a>
|
||||
<a href="{% url 'rapids:exam_json_recreate' pk=exam.pk %}">Refresh JSON cache</a>
|
||||
<button id='button-open-access'>Make questions open access</button>
|
||||
<button id='button-closed-access'>Make questions closed access</button>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
// send request to change the is_private state on customSwitches toggle
|
||||
$("#exam-active-switch").on("change", function () {
|
||||
$.ajax({
|
||||
url: "{% url 'rapids:exam_toggle_active' pk=exam.pk %}",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
active: this.checked // true if checked else false
|
||||
},
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
})
|
||||
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
|
||||
.done(function (data) {
|
||||
console.log(data);
|
||||
|
||||
if (data.status == "success") {
|
||||
toastr.info('Exam state changed.')
|
||||
}
|
||||
// show some message according to the response.
|
||||
// For eg. A message box showing that the status has been changed
|
||||
})
|
||||
.always(function () {
|
||||
console.log('[Done]');
|
||||
})
|
||||
})
|
||||
$("#exam-publish-results-switch").on("change", function () {
|
||||
$.ajax({
|
||||
url: "{% url 'rapids:exam_toggle_results_published' pk=exam.pk %}",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
publish_results: this.checked // true if checked else false
|
||||
},
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
})
|
||||
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
|
||||
.done(function (data) {
|
||||
console.log(data);
|
||||
|
||||
if (data.status == "success") {
|
||||
toastr.info('Publish results state changed.')
|
||||
}
|
||||
// show some message according to the response.
|
||||
// For eg. A message box showing that the status has been changed
|
||||
})
|
||||
.always(function () {
|
||||
console.log('[Done]');
|
||||
})
|
||||
})
|
||||
$("#button-open-access").click(function () {
|
||||
$.ajax({
|
||||
url: "{% url 'rapids:exam_json_edit' pk=exam.pk %}",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
set_open_access: true,
|
||||
},
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
})
|
||||
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
|
||||
.done(function (data) {
|
||||
console.log(data);
|
||||
|
||||
if (data.status == "success") {
|
||||
toastr.info('Question access state changed.')
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
console.log('[Done]');
|
||||
})
|
||||
})
|
||||
$("#button-closed-access").click(function () {
|
||||
$.ajax({
|
||||
url: "{% url 'rapids:exam_json_edit' pk=exam.pk %}",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
set_open_access: false,
|
||||
},
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
})
|
||||
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
|
||||
.done(function (data) {
|
||||
console.log(data);
|
||||
|
||||
if (data.status == "success") {
|
||||
toastr.info('Question access state changed.')
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
console.log('[Done]');
|
||||
})
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,65 @@
|
||||
{% extends 'rapids/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="rapids">
|
||||
<h2>{{ exam.name }}</h2>
|
||||
|
||||
{% if unmarked %}
|
||||
The following questions need marking
|
||||
{% for exam_index in unmarked %}
|
||||
<a href="{% url 'rapids:mark' exam.pk exam_index %}">{{ exam_index|add:1 }}</a>
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div id="stats-block">
|
||||
<h3>Stats</h3>
|
||||
Candidates: {{cids|length}}<br />
|
||||
Max score: {{max_score}}<br/>
|
||||
Mean: {{mean}}, Median {{median}}, Mode {{mode}}
|
||||
|
||||
<div id="stats-plot">{{plot|safe}}</div>
|
||||
</div>
|
||||
<div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Candidate ID</th>
|
||||
<th>Score</th>
|
||||
</tr>
|
||||
{% for user, value in user_answers_marks.items %}
|
||||
<tr>
|
||||
<td><a href="{% url 'cid_scores' user %}">{{user}}</a></td>
|
||||
<td>{{user_scores|get_item:user}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Answers as a table</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Candidate</th>
|
||||
{% for cid in cids %}
|
||||
<th>{{cid}}</th>
|
||||
{% endfor %}
|
||||
|
||||
</tr>
|
||||
{% for question in questions %}
|
||||
<tr>
|
||||
<td>Question {{forloop.counter}}</td>
|
||||
{% for ans, score in by_question|get_item:question %}
|
||||
<td class="user-answer-score-{{score}}" title="answer score: {{score}}">{{ans}}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td>Score:</td>
|
||||
{% for score in user_scores_list %}
|
||||
<td>{{score}}</td>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="rapids">
|
||||
<h2>Exam: {{ exam.name }}</h2>
|
||||
<h3>Candidate: {{ cid }}</h3>
|
||||
Answers:
|
||||
<ul>{% for ans, score, correct_answer in answers_and_marks %}
|
||||
<li class="user-answer-li">Question {{forloop.counter}} - Correct answer: <span class="correct-answer">{{ correct_answer }}</span></li>
|
||||
<span class="user-answer-score user-answer-score-{{score}}"><pre>{{ans}}</pre> ({{score}})</span>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<br /> Total mark: {{ total_score }} / {{max_score}}
|
||||
<div>
|
||||
<a href="{% url 'cid_scores' cid %}">Other exams</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block navigation %}
|
||||
{{block.super}}
|
||||
<br/>
|
||||
Exams: {{exam.name}}-> <a href="{% url 'rapids:exam_overview' pk=exam.pk %}">Overview</a> / <a href="{% url 'rapids:mark_overview' pk=exam.pk %}">Mark</a> / <a href="{% url 'rapids:exam_scores_cid' pk=exam.pk %}">Scores</a>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,11 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
{% for exam in exams %}
|
||||
<div class="rapids">
|
||||
<h1><a href="{% url 'rapids:exam_overview' pk=exam.pk %}">Exam: {{ exam.name }} </a></h1>
|
||||
{% if request.user.is_staff %}<a href="{% url 'rapids:mark' pk=exam.pk sk=0 %}">Mark answers</a>{% endif %}
|
||||
{% if request.user.is_staff %}<a href="{% url 'rapids:exam_scores_cid' pk=exam.pk %}">Scores</a>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
My Questions:
|
||||
<ul>
|
||||
{% for rapid in user_rapids %}
|
||||
<li{% if rapid.scrapped %} class='rapid-scrapped' {% endif %}><a
|
||||
href="{% url 'rapids:rapid_detail' pk=rapid.pk %}">{{rapid}}
|
||||
[{{rapid.get_authors}}]</a></li>
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
Other Questions:
|
||||
<ul>
|
||||
{% for rapid in other_rapids %}
|
||||
<li{% if rapid.scrapped %} class='rapid-scrapped' {% endif %}><a
|
||||
href="{% url 'rapids:rapid_detail' pk=rapid.pk %}">{{rapid}} [{{rapid.get_authors}}]</a></li>
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,67 @@
|
||||
{% extends 'rapids/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Marking question {{question_details.current}} of {{question_details.total}}</h2>
|
||||
<a href="{% url 'rapids:rapid_update' question.id %}" title="Edit the Question">Edit</a> <a
|
||||
href="{% url 'admin:rapids_rapid_change' question.id %}" title="Edit the Question using the admin interface">Admin
|
||||
Edit</a>
|
||||
{% if question.normal %}
|
||||
<h3>This question is normal</h3>
|
||||
Answers will be automatically marked.
|
||||
{% else %}
|
||||
<h3>This question is abnormal</h3>
|
||||
Answers marked as normal will be automatically marked.
|
||||
{% endif %}
|
||||
<div id="single-dicom-viewer" class="marking-dicom" data-images="{{question.GetImageUrls}}"
|
||||
data-annotations='{{question.image_annotations}}'>
|
||||
</div>
|
||||
<div class="marking">
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
{% if not question.normal %}
|
||||
Click each answer to toggle through marks awarded (as per colour)
|
||||
<div class="marking-list">
|
||||
Unmarked:
|
||||
<ul id="new-answer-list" class="answer-list">
|
||||
{% for answer in user_answers %}
|
||||
<li>
|
||||
<pre><span class="answer not-marked">{{ answer }}</span></pre>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
Marked:
|
||||
<ul id="marked-answer-list" class="answer-list">
|
||||
{% for answer in correct_answers %}
|
||||
<li>
|
||||
<pre><span class="answer correct">{{ answer }}</span></pre>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for answer in half_mark_answers %}
|
||||
<li>
|
||||
<pre><span class="answer half-correct">{{ answer }}</span></pre>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for answer in incorrect_answers %}
|
||||
<li>
|
||||
<pre><span class="answer incorrect">{{ answer }}</span></pre>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="answer-list key">Key: <span class="correct">2 Marks</span>, <span class="half-correct">1
|
||||
Mark</span>, <span class="incorrect">0 Marks</span></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if question_details.current > 1 %}
|
||||
<button type="submit" name="previous" class="save btn btn-default">Previous</button>
|
||||
{% endif %}
|
||||
<button type="submit" name="save" class="save btn btn-default">Save</button>
|
||||
{% if question_details.current >= question_details.total %}
|
||||
{% else %}
|
||||
<button type="submit" name="next" class="save btn btn-default">Next</button>
|
||||
<button type="submit" name="skip" class="save btn btn-default">Skip</button>
|
||||
{% endif %}
|
||||
<span class=hide>
|
||||
{{ form.as_p }}
|
||||
</span>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,20 @@
|
||||
{% extends 'rapids/exams.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="rapids">
|
||||
<h2>Marking exam: {{ exam.name }}</h2>
|
||||
You can start marking from a particular question by clicking on it below.
|
||||
|
||||
<div>
|
||||
<button class="show-all-button">Show all</button><button class="show-unmarked-button">Show unmarked</button>
|
||||
</div>
|
||||
<div id="stark-marking-button"><a href="{% url 'rapids:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
||||
|
||||
<ul id="question-mark-list">
|
||||
{% for question in questions.all %}
|
||||
<li data-markcount={{question.GetUnmarkedAnswerCount}}><a href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||
{{ question }}</a><br /> {{ question.GetUnmarkedAnswersString }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
{% extends "rapids/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Add Note</h2>
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
{% endblock %}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
{% if exam %}
|
||||
<div>
|
||||
|
||||
{% if previous > -1 %}
|
||||
<a href="{% url 'rapids:exam_question_detail' exam.id previous %}">Previous question</a>
|
||||
{% endif %}
|
||||
This question is part of exam: {{exam.name}} [{{pos}}/{{exam_length}}]
|
||||
{% if next %}
|
||||
<a href="{% url 'rapids:exam_question_detail' exam.id next %}">Next question</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<a href="{% url 'rapids:rapid_update' pk=question.pk %}" title="Edit the Rapid">Edit</a>
|
||||
<a href="{% url 'rapids:rapid_clone' pk=question.pk %}" title="Clone the Rapid (duplicate everything but the images)">Clone</a>
|
||||
<a href="{% url 'rapids:rapid_add_note' pk=question.pk %}"> Add Note</a>
|
||||
{% if request.user.is_superuser %}
|
||||
<a href="{% url 'admin:rapids_rapid_change' question.id %}" title="Edit the Rapid using the admin interface">Admin Edit</a>
|
||||
{% endif %}
|
||||
{% include 'rapids/rapid_display_block.html' %}
|
||||
{% endblock %}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<div class="rapid {% if question.scrapped %}rapid-scrapped{% endif %}">
|
||||
<div class="date">
|
||||
{{ question.created_date }}
|
||||
</div>
|
||||
|
||||
<p class="pre-whitespace"><b>Rapid:</b> {{ question }}</p>
|
||||
<p class="pre-whitespace"><b>Region:</b> {{ question.get_regions }}</p>
|
||||
<p class="pre-whitespace"><b>Examination:</b> {{ question.get_examinations }}</p>
|
||||
<p class="pre-whitespace"><b>Laterality:</b> {{ question.laterality }}</p>
|
||||
<p class="pre-whitespace"><b>Abnormality:</b> {{ question.get_abnormalities }}</p>
|
||||
<div class="pre-whitespace multi-image-block"><b>Images:</b>
|
||||
{% for image in question.images.all %}
|
||||
<span class="image-block">
|
||||
Image {{ forloop.counter }}{% if image.feedback_image %} [feedback image]{% endif %}:
|
||||
<div class="dicom-image rapid-img {% if image.feedback_image %}feedback-img{% endif %}" data-url="http://penracourses.org.uk{{ image.image.url}}"></div>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p class="pre-whitespace"><b>Feedback:</b> {{ question.feedback }}</p>
|
||||
<p><b>Author(s):</b> {% for author in question.author.all %} <a
|
||||
href="{% url 'rapids:author_detail' pk=author.pk %}">{{author}}</a>, {% endfor %}</p>
|
||||
<p><b>Checked by:</b> {% for verified in question.verified.all %} <a
|
||||
href="{% url 'rapids:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p>
|
||||
<p><b>Scrapped:</b> {{ question.scrapped }} <a href="{% url 'rapids:rapid_scrap' pk=question.pk %}">(toggle)</a>
|
||||
<p class="pre-whitespace"><b>Answers:</b> {{ question.GetMarkedAnswers }}</p>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
Notes:
|
||||
<ul>
|
||||
{% for note in question.rapid_notes.all %}
|
||||
<li>
|
||||
{{ note.created_on }} by {{ note.author }}: {{ note.note }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
Executable
+292
@@ -0,0 +1,292 @@
|
||||
{% extends "rapids/base.html" %}
|
||||
{% load static from static %}
|
||||
|
||||
{% block js %}
|
||||
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
|
||||
|
||||
<script type="text/javascript">
|
||||
function showEditPopup(url) {
|
||||
var win = window.open(url, "Edit",
|
||||
'height=500,width=800,resizable=yes,scrollbars=yes');
|
||||
return false;
|
||||
}
|
||||
function showAddPopup(triggeringLink) {
|
||||
var name = triggeringLink.id.replace(/^add_/, '');
|
||||
href = triggeringLink.href;
|
||||
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
|
||||
win.focus();
|
||||
return false;
|
||||
}
|
||||
function closePopup(win, newID, newRepr, id) {
|
||||
console.log(id)
|
||||
$(id + "_to").append('<option value=' + newID + ' title=' + newRepr + ' >' + newRepr + '</option>')
|
||||
win.close();
|
||||
}
|
||||
|
||||
document.addEventListener('drop', function (e) { e.preventDefault(); }, false);
|
||||
|
||||
function add_input_form() {
|
||||
var form_idx = $('#id_images-TOTAL_FORMS').val();
|
||||
$('#image_form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
|
||||
$('#id_images-TOTAL_FORMS').val(parseInt(form_idx) + 1);
|
||||
}
|
||||
|
||||
function add_answers_input_form() {
|
||||
var form_idx = $('#id_answers-TOTAL_FORMS').val();
|
||||
$('#answer_form_set').append($('#answer_empty_form').html().replace(/__prefix__/g, form_idx));
|
||||
$('#id_answers-TOTAL_FORMS').val(parseInt(form_idx) + 1);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#add_abnormality").appendTo($("label[for='id_abnormality']"));
|
||||
$("#add_examination").appendTo($("label[for='id_examination']"));
|
||||
$("#add_region").appendTo($("label[for='id_region']"));
|
||||
|
||||
dropContainer = document.getElementById("drop-container");
|
||||
|
||||
dropContainer.ondragover = function (evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
};
|
||||
|
||||
dropContainer.ondragenter = function (evt) {
|
||||
console.log("ENTER")
|
||||
console.log(evt)
|
||||
$(evt.target).addClass("drop-target-active")
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
};
|
||||
|
||||
dropContainer.ondragleave = function (evt) {
|
||||
console.log("ENTER")
|
||||
console.log(evt)
|
||||
$(evt.target).removeClass("drop-target-active")
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
};
|
||||
|
||||
dropContainer.ondrop = function (evt) {
|
||||
console.log("SHIT", evt);
|
||||
$(evt.target).removeClass("drop-target-active");
|
||||
|
||||
// Get all input elements
|
||||
inputs = $("#rapid-form input[type=file][id^=id_images-]");
|
||||
//fileInput = document.getElementById("id_images-0-image");
|
||||
|
||||
// Make sure we have enough input targets
|
||||
input_diff = (evt.dataTransfer.files.length - inputs.length)
|
||||
console.log("diff", input_diff)
|
||||
|
||||
if(input_diff > 0) {
|
||||
for(let j = 0; j < input_diff; j++) {
|
||||
add_input_form()
|
||||
}
|
||||
|
||||
// Need to make sure we include the new ones...
|
||||
inputs = $("#rapid-form input[type=file][id^=id_images-]");
|
||||
}
|
||||
|
||||
// Loop through each dropped file and try to assign to an
|
||||
// input element
|
||||
[...evt.dataTransfer.files].forEach((f) => {
|
||||
let dT = new DataTransfer();
|
||||
dT.clearData();
|
||||
dT.items.add(f);
|
||||
for(let i = 0; i < inputs.length; i++) {
|
||||
el = inputs.get(i)
|
||||
|
||||
if(el.files.length == 0) {
|
||||
el.files = dT.files;
|
||||
ocr(el)
|
||||
|
||||
if(evt.target.id == "feedback-drop-target") {
|
||||
arr = el.name.split("-");
|
||||
arr.splice(2, 1, "feedback_image");
|
||||
feedback_el_name = arr.join("-");
|
||||
|
||||
$(`[name=${feedback_el_name}]`).prop("checked", true);
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// // If you want to use some of the dropped files
|
||||
// const dT = new DataTransfer();
|
||||
// dT.items.add(evt.dataTransfer.files[0]);
|
||||
// dT.items.add(evt.dataTransfer.files[3]);
|
||||
// fileInput.files = dT.files;
|
||||
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
updateFileList();
|
||||
};
|
||||
|
||||
|
||||
$('#add_more_images').click(() => { add_input_form() });
|
||||
$('#add_more_answers').click(() => { add_answers_input_form() });
|
||||
|
||||
function updateFileList() {
|
||||
$("#drop-filenames").empty()
|
||||
$("#image_form_set input[type=file]").each((n, el) => {
|
||||
console.log(el);
|
||||
if(el.files.length > 0) {
|
||||
extra_class = " image-ident-loading";
|
||||
if($(el).hasClass("image-ident-warning")) {
|
||||
extra_class = " image-ident-warning"
|
||||
} else if($(el).hasClass("image-ident-ok")) {
|
||||
extra_class = " image-ident-ok"
|
||||
}
|
||||
$("#drop-filenames").append(
|
||||
`<span>${n}: ${el.files[0].name}</span><img class='uploading${extra_class}' data-input-id='${el.id}' src=${URL.createObjectURL(el.files[0])}>`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
$("input[type=file]").on('change', function () {
|
||||
$(this).removeClass("image-ident-warning");
|
||||
$(this).removeClass("image-ident-ok");
|
||||
updateFileList();
|
||||
console.log("input change1");
|
||||
console.log("input change", this);
|
||||
ocr(this);
|
||||
});
|
||||
|
||||
|
||||
|
||||
function ifNormal(){
|
||||
if (document.getElementById("id_normal").checked){
|
||||
$("#answer_form_set textarea").attr("required", false)
|
||||
} else {
|
||||
$("#answer_form_set textarea").attr("required", true)
|
||||
}
|
||||
}
|
||||
|
||||
$("#id_normal").change(() => ifNormal());
|
||||
|
||||
ifNormal();
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
function ocr(input) {
|
||||
// Tesseract.recognize(f, "eng",{ logger: m => console.log(m) }
|
||||
// ).then(({ data: { text } }) => {
|
||||
// console.log(text);
|
||||
// l = text.toLowerCase();
|
||||
// if (l.includes("accesion") || l.includes("number") || l.search(/(REF|RK9|RH8|RA9)\d+/g)) {
|
||||
// console.log("SHIT", this);
|
||||
// }
|
||||
// })
|
||||
|
||||
console.log('{% static "worker.min.js" %}');
|
||||
console.log('{{ STATIC_URL }}/tesseract-core.wasm.js %}');
|
||||
|
||||
const worker = Tesseract.createWorker({
|
||||
workerPath: '{% static "worker.min.js" %}',
|
||||
langPath: '{% static "" %}',
|
||||
//langPath: '{{ STATIC_URL }}',
|
||||
corePath: '{% static "tesseract-core.wasm.js" %}',
|
||||
});
|
||||
|
||||
const url = URL.createObjectURL(input.files[0]);
|
||||
let img = new Image;
|
||||
img.src = url;
|
||||
|
||||
img.onload = function () {
|
||||
|
||||
|
||||
width = img.width;
|
||||
|
||||
// const rectangle = { left: 0, top: 0, width: width, height: 10 }
|
||||
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
await worker.loadLanguage('eng');
|
||||
await worker.initialize('eng');
|
||||
// const { data: { text } } = await worker.recognize(input.files[0], { rectangle });
|
||||
const { data: { text } } = await worker.recognize(input.files[0]);
|
||||
//console.log(text);
|
||||
l = text.toLowerCase();
|
||||
$(`img[data-input-id='${input.id}'`).removeClass("image-ident-loading");
|
||||
console.log(l);
|
||||
if(l.includes("accesion") || l.includes("number") || l.search(/(ref|rk9|rh8|ra9|rbz)\d+/g) > -1) {
|
||||
console.log("SHIT", input);
|
||||
$(input).addClass("image-ident-warning");
|
||||
$(`img[data-input-id='${input.id}'`).addClass("image-ident-warning");
|
||||
} else {
|
||||
$(input).addClass("image-ident-ok");
|
||||
|
||||
}
|
||||
|
||||
await worker.terminate();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{{ form.media }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Submit Rapid</h2>
|
||||
<a href="{% url 'rapids:rapid_create_defaults' %}">Edit defaults</a>
|
||||
<form action="" method="post" enctype="multipart/form-data" id="rapid-form">
|
||||
{% csrf_token %}
|
||||
<a href="/rapids/abnormality/create" id="add_abnormality" class="add-popup"
|
||||
onclick="return showAddPopup(this);"><img src="{% static '/img/icon-addlink.svg' %}"></a>
|
||||
<a href="/rapids/examination/create" id="add_examination" class="add-popup"
|
||||
onclick="return showAddPopup(this);"><img src="{% static '/img/icon-addlink.svg' %}"></a>
|
||||
<a href="/rapids/region/create" id="add_region" class="add-popup" onclick="return showAddPopup(this);"><img
|
||||
src="{% static '/img/icon-addlink.svg' %}"></a>
|
||||
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<h3>Answers:</h3>
|
||||
<input type="button" value="Add More Answers" id="add_more_answers">
|
||||
<div id="answer_form_set">
|
||||
{% for form in answer_formset %}
|
||||
<ul class="no-error answer-formset">
|
||||
{{form.non_field_errors}}
|
||||
{{form.errors}}
|
||||
{{ form.as_ul }}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ answer_formset.management_form }}
|
||||
<h3>Images:</h3>
|
||||
<input type="button" value="Add More Images" id="add_more_images">
|
||||
<div id="drop-container" class="drop-target">Drop images here (or use the buttons below)<div
|
||||
id="feedback-drop-target">Feedback image?<br />drop those here</div>
|
||||
<div id="drop-filenames"></div>
|
||||
</div>
|
||||
<div id="image_form_set">
|
||||
{% for form in image_formset %}
|
||||
<ul class="no-error image-formset">
|
||||
{{form.non_field_errors}}
|
||||
{{form.errors}}
|
||||
{{ form.as_ul }}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ image_formset.management_form }}
|
||||
<input type="submit" class="submit-button" value="Submit" name="submit">
|
||||
<input type="submit" class="submit-button" value="Submit and Clone" name="submit-clone">
|
||||
</form>
|
||||
<div id="empty_form" style="display:none">
|
||||
<ul class='no_error image-formset'>
|
||||
{{ image_formset.empty_form.as_ul }}
|
||||
</ul>
|
||||
</div>
|
||||
<div id="answer_empty_form" style="display:none">
|
||||
<ul class='no_error answer-formset'>
|
||||
{{ answer_formset.empty_form.as_ul }}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{% extends "rapids/base.html" %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<h2>Defaults for creating new rapids</h2>
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="save btn btn-primary">Save</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
{% extends 'rapids/base.html' %}
|
||||
|
||||
{% load render_table from django_tables2 %}
|
||||
{% block css %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="view-filter-options">
|
||||
<h3>Filter Rapids</h3>
|
||||
<form action="" method="get">
|
||||
{{ filter.form }}
|
||||
<input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
{% render_table table %}
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user