Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions interface/codeview.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,17 @@ def make_dict(submission_archive):
@register.filter
def get_item(dictionary, key):
return dictionary.get(key)


def table_maker(file):
return file.read().splitlines()


@register.filter
def with_path(things, path):
return things.filter(path=path)


@register.filter
def with_line(things, line):
return things.filter(line=line)
11 changes: 11 additions & 0 deletions interface/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django import forms
from django.conf import settings
from django.template.defaultfilters import filesizeformat
from .models import Comment


class UploadFileForm(forms.Form):
Expand All @@ -24,3 +25,13 @@ def clean_file(self):
class LoginForm(forms.Form):
username = forms.CharField(label="Username")
password = forms.CharField(label="Password", widget=forms.PasswordInput)


class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ("text",)

widgets = {
"text": forms.Textarea(attrs={"class": "form-control"}),
}
28 changes: 28 additions & 0 deletions interface/migrations/0023_comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.0.6 on 2020-09-07 17:48

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('interface', '0022_auto_20200709_2326'),
]

operations = [
migrations.CreateModel(
name='Comment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=256)),
('line', models.IntegerField(null=True)),
('text', models.TextField(blank=True, default='', max_length=4096)),
('created', models.DateTimeField(auto_now_add=True)),
('submission', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='comments', to='interface.Submission')),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
),
]
14 changes: 14 additions & 0 deletions interface/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,18 @@ def verify_jwt(self, message):
return decoded_message["data"] == str(self.id)


class Comment(models.Model):
path = models.CharField(max_length=256, blank=False)
line = models.IntegerField(null=True)
submission = models.ForeignKey(
Submission,
on_delete=models.PROTECT,
null=True,
related_name="comments",
)
user = models.ForeignKey(User, on_delete=models.PROTECT, null=True)
text = models.TextField(max_length=4096, default="", blank=True)
created = models.DateTimeField(auto_now_add=True)


pre_save.connect(signals.update_total_score, sender=Submission)
20 changes: 19 additions & 1 deletion interface/scoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,27 @@ def compute_review_score(submission):
return sum([decimal.Decimal(mark) for mark in marks])


def compute_comments_review(submission):
total_sum = 0
teaching_assistants = (
submission.assignment.course.teaching_assistants.all()
)
for comment in submission.comments.all():
if comment.user in teaching_assistants:
marks = re.findall(
r"^([+-]\d+\.*\d*):", comment.text, re.MULTILINE,
)
log.debug("Marks found: " + str(marks))
total_sum += sum([decimal.Decimal(mark) for mark in marks])

return total_sum


def calculate_total_score(submission):
score = submission.score if submission.score else 0
submission.review_score = compute_review_score(submission)
submission.review_score = compute_review_score(
submission
) + compute_comments_review(submission)

(penalties, holiday_start, holiday_finish) = get_penalty_info(submission)
timestamp = submission.timestamp or datetime.datetime.now()
Expand Down
102 changes: 98 additions & 4 deletions interface/templates/interface/code_view.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,112 @@
{% extends "interface/generics/base.html" %}

<script type="text/javascript">
$('.accordian-body').on('show.bs.collapse', function () {
$(this).closest("table")
.find(".collapse.in")
.not(this)
.collapse('toggle')
});
</script>
<style>
.hiddenRow {
padding: 0 !important;
}
</style>

{% block body_content %}

<div class="container-fluid">
<div class="row">
<div class="col-lg-3">
{% with dict=tree.items template="interface/tree_view.html" %}
{% include template %}
{% endwith %}
<div>
{% if user in sub.assignment.course.teaching_assistants.all %}
<p>
<button type="button" class="btn btn-primary btn-sm mr-1" data-toggle="modal" data-target="#review" data-id="{{ sub.id }}">Finish review</button>
</p>
{% endif %}
</div>
{% with dict=tree.items template="interface/tree_view.html" %}
{% include template %}
{% endwith %}
</div>
<div class="col-lg-9">
<pre> {{ file_content }} </pre>
<div>
{% if not file_exists %}
{{ file_content }}
{% else %}
<table class="table table-hover table-sm table-borderless" data-toggle="table" style="border-collapse: collapse;">
<thead>
<tr>
<th>
</th>
<th></th>
</tr>
</thead>
<tbody>
{% for line in file_content %}
<tr data-toggle="collapse" data-target="#demo_{{ forloop.counter }}" style="line-height: 1em;">
<td style="padding:0;height: 1px;"> {{ forloop.counter }} </td>
<td style="padding:0;height: 1px;">
{% with forloop.counter as index %}
{% if sub.comments|with_path:path|with_line:index %}
<div style="background-color: #FFCCCB;padding: 0;;white-space: pre;font-family: monospace;">{{ line }}</div>
{% else %}
<div style="padding: 0;white-space: pre;font-family: monospace;">{{ line }}</div>
{% endif %}
{% endwith %}
</td>
</tr>
<tr>
<td colspan="6" class="hiddenRow">
<div class="accordian-body collapse" id="demo_{{ forloop.counter }}">
<div class="tab-pane" id="add-comment">
{% with forloop.counter as index %}
{% for comment in path_comments %}
{% if comment.line == index %}
<div class="post-comment">
<p class="info">
Comment {{ forloop.counter }} by {{ comment.user }}
{{ comment.created }}
</p>
{{ comment.text|linebreaks }}
</div>
{% endif %}
{% empty %}
<p>There are no comments yet.</p>
{% endfor %}
{% endwith %}
{% if new_comment %}
<h2>Your comment has been added.</h2>
{% else %}
<form action="." method="post" class="form-horizontal" id="commentForm" role="form">
<div class="form-group">
<div class="col-sm-10">
{% csrf_token %}
{{ form.as_p }}
</div>
</div>
<input type="hidden" name="line" value="{{ forloop.counter }}">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<p><input class="btn btn-success btn-circle text-uppercase" type="submit" value="Add comment"></p>
</div>
</div>
</form>
{% endif %}
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
</div>
</div>
</div>

{% include "interface/generics/review_modal.html" %}

{% endblock %}
39 changes: 39 additions & 0 deletions interface/templates/interface/code_view_homepage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{% extends "interface/generics/base.html" %}

{% block body_content %}

<div class="container-fluid">
<div class="row">
<div class="col-lg-3">
{% with dict=tree.items template="interface/tree_view.html" %}
{% include template %}
{% endwith %}
</div>
<div class="col-lg-9">
<div class="row align-items-center">
<div class="col-lg-2"></div>
<div class="col-lg-9">
<pre>
/^--^\ /^--^\ /^--^\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 .       .
 |\_---_/|
/   o_o   \
|    U    |
\  ._I_.  /
 `-_____-'

\____/ \____/ \____/
/ \ / \ / \
| | | | | |
\__ __/ \__ __/ \__ __/
|^|^|^|^|^|^|^|^|^|^|^|^\ \^|^|^|^/ /^|^|^|^|^\ \^|^|^|^|^|^|^|^|^|^|^|^|
| | | | | | | | | | | | |\ \| | |/ /| | | | | | \ \ | | | | | | | | | | |
| | | | | | | | | | | | / / | | |\ \| | | | | |/ /| | | | | | | | | | | |
| | | | | | | | | | | | \/| | | | \/| | | | | |\/ | | | | | | | | | | | |
#########################################################################
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

</pre>
</div>
</div>
</div>
</div>
</div>
</div>


{% endblock %}
4 changes: 2 additions & 2 deletions interface/templates/interface/generics/review_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ <h5 class="modal-title" id="reviewLabel">Review submission {{ sub.pk }}</h5>
</div>

<div class="modal-body">
<form id="reviewForm" method="post" action="review">
<form id="reviewForm" method="post" action="{% url 'review' sub.pk %}">
{% csrf_token %}
<div class="form-group">
<label for="message-text" class="col-form-label">Review details:</label>
<textarea class="form-control" name='review-code' id="message-text">{{ submission_review_message }}</textarea>
<textarea class="form-control" name='review-code' id="message-text">{{ sub.review_message }}</textarea>
</div>
</form>
</div>
Expand Down
22 changes: 11 additions & 11 deletions interface/templates/interface/submission_result.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@ <h1>Submission {{ sub }} ({{ sub.state }})</h1>
</form>
{% endif %}

{% if user in sub.assignment.course.teaching_assistants.all%}
<p>
<button type="button" class="btn btn-primary btn-sm mr-1" data-toggle="modal" data-target="#review" data-id="{{ sub.id }}">Review</button>
</p>
{% endif %}

{% if user in sub.assignment.course.teaching_assistants.all %}
<form action="rerun">
{% csrf_token %}
<input formmethod="post" class="btn btn-primary btn-sm mr-1" type="submit" value="Rerun submission">
</form>
{% endif %}
{% endif %}

{% if user in sub.assignment.course.teaching_assistants.all %}
{% if user in sub.assignment.course.teaching_assistants.all %}
<form action="recompute">
{% csrf_token %}
<input formmethod="post" class="btn btn-primary btn-sm mr-1" type="submit" value="Recompute score">
</form>
{% endif %}
</div>
{% endif %}

{% if user == sub.user or user in sub.assignment.course.teaching_assistants.all %}
<form>
<button class="btn btn-primary btn-sm mr-1" formaction="{% url 'code_view_homepage' sub.pk %}">Start review</button>
</form>
{% endif %}
</div>

{% if sub.state == sub.STATE_DONE %}

Expand Down Expand Up @@ -79,6 +79,6 @@ <h2>Fortune teller</h2>

</div>

{% include "interface/generics/review_modal.html" %}


{% endblock %}
8 changes: 7 additions & 1 deletion interface/templates/interface/tree_view.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
<ul>
{% for key, value in dict %}
{% if '$path' in value and value.items %}
<a href="{% url 'code_view' pk value|get_item:'$path' %}">{{ key }}</a><br>
{% with value|get_item:'$path' as path %}
{% if sub.comments|with_path:path %}
<a href="{% url 'code_view' pk path %}" style="color:red;">{{ key }}</a><br>
{% else %}
<a href="{% url 'code_view' pk path %}">{{ key }}</a><br>
{% endif %}
{% endwith %}
{% else %}
{{ key }}
{% with dict=value.items template="interface/tree_view.html" %}
Expand Down
9 changes: 7 additions & 2 deletions interface/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
name="submission_result",
),
path("submission/<int:pk>/done", views.done),
path("submission/<int:pk>/review", views.review),
path("submission/<int:pk>/review/", views.review, name="review"),
path("submission/<int:pk>/download", views.download),
path("submission/<int:pk>/rerun", views.rerun_submission),
path("submission/<int:pk>/recompute", views.recompute_score),
Expand All @@ -43,8 +43,13 @@
),
path("mysubmissions/<username>", views.user_page, name="user_page"),
path(
"submission/<int:pk>/<path:filename>/",
"submission/<int:pk>/code/<path:filename>/",
views.code_view,
name="code_view",
),
path(
"submission/<int:pk>/code/",
views.code_view_homepage,
name="code_view_homepage",
),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Loading