Skip to content
Snippets Groups Projects
Commit 36f06771 authored by Jan Maximilian Michal's avatar Jan Maximilian Michal
Browse files

added empty submissions

parent e905d57c
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,8 @@ TODO ...@@ -12,6 +12,8 @@ TODO
- provide one time passwords for student accounts - provide one time passwords for student accounts
- use postgresql - use postgresql
- fix seen - fix seen
- csv export
- ilias import
- versioning for feedback - versioning for feedback
- implement better capabilities for the reviewer (optional) - implement better capabilities for the reviewer (optional)
......
...@@ -59,7 +59,7 @@ class Submission(models.Model): ...@@ -59,7 +59,7 @@ class Submission(models.Model):
SubmissionType, SubmissionType,
related_name='submissions' related_name='submissions'
) )
text = models.TextField() text = models.TextField(blank=True)
pre_corrections = models.TextField(blank=True) pre_corrections = models.TextField(blank=True)
final_feedback = models.OneToOneField('Feedback', null=True, blank=True) final_feedback = models.OneToOneField('Feedback', null=True, blank=True)
student = models.ForeignKey(Student) student = models.ForeignKey(Student)
...@@ -193,6 +193,7 @@ class Feedback(models.Model): ...@@ -193,6 +193,7 @@ class Feedback(models.Model):
self.final = True self.final = True
self.of_reviewer = user self.of_reviewer = user
self.of_submission.final_feedback = self self.of_submission.final_feedback = self
self.of_submission.save()
self.save() self.save()
def unfinalize_feedback(self): def unfinalize_feedback(self):
......
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
.CodeMirror { pre {
border: 1px solid #eee; width: 100%;
height: auto; white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
white-space: -pre-wrap; /* Opera */
white-space: -o-pre-wrap; /* Opera */
white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) http://www.w3.org/TR/css3-text/#white-space */
word-wrap: break-word; /* IE 5.5+ */
} }
.card-block{ .card-block{
...@@ -17,3 +21,7 @@ ...@@ -17,3 +21,7 @@
height: 500px; height: 500px;
width: auto; width: auto;
} }
.nopadding-right {
padding-right: 0 !important;
}
.CodeMirror-dialog {
position: absolute;
left: 0; right: 0;
background: inherit;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: inherit;
}
.CodeMirror-dialog-top {
border-bottom: 1px solid #eee;
top: 0;
}
.CodeMirror-dialog-bottom {
border-top: 1px solid #eee;
bottom: 0;
}
.CodeMirror-dialog input {
border: none;
outline: none;
background: transparent;
width: 20em;
color: inherit;
font-family: monospace;
}
.CodeMirror-dialog button {
font-size: 70%;
}
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
{# CSS includes #} {# CSS includes #}
<link rel="stylesheet" href="{% static 'lib/css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/custom.css' %}"> <link rel="stylesheet" href="{% static 'lib/css/custom.css' %}">
<link rel="stylesheet" href="{% static 'lib/css/dialog.css' %}">
{# Importing stuff for ACE editor #} {# Importing stuff for ACE editor #}
<script src="{% static 'lib/ace/ace.js' %}"></script> <script src="{% static 'lib/ace/ace.js' %}"></script>
...@@ -28,7 +27,7 @@ ...@@ -28,7 +27,7 @@
</head> </head>
{# Navbar contaning: Brand - Title - Page Title <---> (Username - Logout || Login form) #} {# Navbar contaning: Brand - Title - Page Title <---> (Username - Logout || Login form) #}
<nav class="navbar navbar-toggleable-md navbar-light bg-faded"> <nav class="navbar navbar-toggleable navbar-light bg-faded">
<a class="navbar-brand" href="{% url 'start' %}"> <a class="navbar-brand" href="{% url 'start' %}">
<img src="{% static 'res/brand.png' %}" width="30" height="30" class="d-inline-block align-top" alt=""> <img src="{% static 'res/brand.png' %}" width="30" height="30" class="d-inline-block align-top" alt="">
Grady Grady
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<a data-toggle="collapse" href="#collapse{{unique}}"> <a data-toggle="collapse" href="#collapse{{unique}}">
<h5 class="card-header">{{ header }}</h5> <h5 class="card-header">{{ header }}</h5>
</a> </a>
<div id="collapse{{unique}}" class="collapse hide" role="tabpanel"> <div id="collapse{{unique}}" class="collapse {{expanded}}" role="tabpanel">
<div class="card-block m-2"> <div class="card-block m-2">
{{ content }} {{ content }}
</div> </div>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
{% block body_block %} {% block body_block %}
<div class="row"> <div class="row">
<div class="col my-2"> <div class="col my-2 nopadding-right">
<div class="card mb-2"> <div class="card mb-2">
<h4 class="card-header">{{feedback.of_submission.type.name}}</h4> <h4 class="card-header">{{feedback.of_submission.type.name}}</h4>
...@@ -17,10 +17,10 @@ ...@@ -17,10 +17,10 @@
</div> </div>
</div> </div>
{% include "core/feedback_card.html" with unique="1" header="Description" content=feedback.of_submission.type.task_description expanded="false" %} {% include "core/feedback_card.html" with unique="4" header="Custom Feedback" content=feedback.of_submission.pre_corrections expanded="show" %}
{% include "core/feedback_card.html" with unique="2" header="Solution" content=feedback.of_submission.type.possible_solution expanded="false" %} {% include "core/feedback_card.html" with unique="1" header="Description" content=feedback.of_submission.type.task_description expanded="hide" %}
{% include "core/feedback_card.html" with unique="3" header="Correction Guideline" content=feedback.of_submission.type.correction_guideline expanded="false" %} {% include "core/feedback_card.html" with unique="2" header="Solution" content=feedback.of_submission.type.possible_solution expanded="hide" %}
{% include "core/feedback_card.html" with unique="4" header="Custom Feedback" content=feedback.of_submission.pre_corrections expanded="false" %} {% include "core/feedback_card.html" with unique="3" header="Correction Guideline" content=feedback.of_submission.type.correction_guideline expanded="hide" %}
<div class="my-2"> <div class="my-2">
<button type="button" id="collapseAllOpen" class="btn btn-secondary">Open All</button> <button type="button" id="collapseAllOpen" class="btn btn-secondary">Open All</button>
...@@ -68,7 +68,6 @@ ...@@ -68,7 +68,6 @@
</form> </form>
{# This is where all the messages pop up #} {# This is where all the messages pop up #}
{% include "core/message_box.html" %} {% include "core/message_box.html" %}
{# This is where all the messages pop up #}
</div> </div>
</div> </div>
......
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
<tbody> <tbody>
{% for submission in submission_list %} {% for submission in submission_list %}
<tr class="align-middle"> <tr class="align-middle">
<td class="align-middle">{% if submission.seen %} <td class="align-middle">
<span class="badge badge-success">Seen</span> {% if submission.seen %}
<span class="badge badge-success">Seen</span>
{% endif %}</td> {% endif %}</td>
<td class="align-middle">{{ submission.type }}</td> <td class="align-middle">{{ submission.type }}</td>
<td class="align-middle"> <td class="align-middle">
......
...@@ -16,7 +16,7 @@ class SubmissionView(DetailView): ...@@ -16,7 +16,7 @@ class SubmissionView(DetailView):
def get_object(self): def get_object(self):
obj = Submission.objects.get(slug=self.kwargs['slug']) obj = Submission.objects.get(slug=self.kwargs['slug'])
if obj.final_feedback: if obj.final_feedback is not None:
obj.seen = True obj.seen = True
obj.save() obj.save()
return obj return obj
...@@ -12,7 +12,7 @@ django.setup() ...@@ -12,7 +12,7 @@ django.setup()
from django.contrib.auth.models import Group, User from django.contrib.auth.models import Group, User
from core.models import Student, Submission, SubmissionType from core.models import Student, Submission, SubmissionType, Feedback
def add_submission_type(name, def add_submission_type(name,
...@@ -52,6 +52,30 @@ def add_submission(type, text, student, pre="Vorgabe"): ...@@ -52,6 +52,30 @@ def add_submission(type, text, student, pre="Vorgabe"):
return sub return sub
def add_empty_feedback(submission):
auto_correct, _ = User.objects.get_or_create(username='auto_correct')
feedback = Feedback()
feedback.text = "--- You have not submitted any code for this task ---"
feedback.final = True
feedback.empty = False
feedback.of_submission = submission
feedback.of_tutor = auto_correct
feedback.save()
print(f"- Created empty Feedback for Submission {submission}")
return feedback
def add_empty_submission(type, student):
sub = Submission()
sub.type = type
sub.student = student
sub.save()
sub.feedback = add_empty_feedback(sub)
sub.save()
print(f"- Created empty Submission of Type {sub.type}")
return sub
def add_student(name): def add_student(name):
student_group = Group.objects.get(name='Students') student_group = Group.objects.get(name='Students')
student_user = add_user(name, student_group) student_user = add_user(name, student_group)
...@@ -166,6 +190,8 @@ class PopulateDatabase: ...@@ -166,6 +190,8 @@ class PopulateDatabase:
for s, code in submissions.items(): for s, code in submissions.items():
if code: if code:
add_submission(type_dict[s], code, student) add_submission(type_dict[s], code, student)
else:
add_empty_submission(type_dict[s], student)
# Start execution here! # Start execution here!
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment