Commit 5a92a8a5 authored by Thom Wiggers's avatar Thom Wiggers 📐
Browse files

Merge branch...

Merge branch '629-generate-statistics-about-downloads-and-uploads-for-the-summaries-and-tests' into 'master'

Resolve "generate statistics about downloads and uploads for the summaries and tests"

Closes #629

See merge request !794
parents bd173277 5ec79bc1
"""
This module registers admin pages for the models
"""
import csv
from django.contrib import admin
from django.http import HttpResponse
from django.utils.translation import ugettext_lazy as _
from utils.translation import TranslatedModelAdmin
......@@ -22,11 +25,12 @@ class CourseAdmin(TranslatedModelAdmin):
@admin.register(models.Exam)
class ExamAdmin(TranslatedModelAdmin):
list_display = ('type', 'course', 'exam_date', 'uploader',
'accepted')
'accepted', 'download_count')
readonly_fields = ('download_count',)
list_filter = ('accepted', 'exam_date', 'type',)
search_fields = ('name', 'uploader__first_name', 'uploader__last_name',
'course__name_nl', 'course__name_en',)
actions = ['accept', 'reject']
actions = ['accept', 'reject', 'reset_download_count', 'download_csv']
def accept(self, request, queryset):
queryset.update(accepted=True)
......@@ -38,14 +42,38 @@ class ExamAdmin(TranslatedModelAdmin):
reject.short_description = _("Mark exams as rejected")
def reset_download_count(self, request, queryset):
queryset.update(download_count=0)
reset_download_count.short_description = _("Reset the marked exams "
"download count")
def download_csv(self, request, queryset):
opts = queryset.model._meta
response = HttpResponse(content_type='text/csv')
# force download.
response['Content-Disposition'] = 'attachment;filename=export.csv'
# the csv writer
writer = csv.writer(response)
field_names = [field.name for field in opts.fields]
# Write a first row with header information
writer.writerow(field_names)
# Write data rows
for obj in queryset:
writer.writerow([getattr(obj, field) for field in field_names])
return response
download_csv.short_description = _("Download marked as csv")
@admin.register(models.Summary)
class SummaryAdmin(TranslatedModelAdmin):
list_display = ('name', 'course', 'uploader', 'accepted')
list_display = ('name', 'course', 'uploader', 'accepted', 'download_count')
readonly_fields = ('download_count',)
list_filter = ('accepted',)
search_fields = ('name', 'uploader__first_name', 'uploader__last_name',
'course__name_nl', 'course__name_en',)
actions = ['accept', 'reject']
actions = ['accept', 'reject', 'reset_download_count', 'download_csv']
def accept(self, request, queryset):
queryset.update(accepted=True)
......@@ -56,3 +84,26 @@ class SummaryAdmin(TranslatedModelAdmin):
queryset.update(accepted=False)
reject.short_description = _("Mark summaries as rejected")
def reset_download_count(self, request, queryset):
queryset.update(download_count=0)
reset_download_count.short_description = _("Reset the marked summaries "
"download count")
def download_csv(self, request, queryset):
opts = queryset.model._meta
response = HttpResponse(content_type='text/csv')
# force download.
response['Content-Disposition'] = 'attachment;filename=export.csv'
# the csv writer
writer = csv.writer(response)
field_names = [field.name for field in opts.fields]
# Write a first row with header information
writer.writerow(field_names)
# Write data rows
for obj in queryset:
writer.writerow([getattr(obj, field) for field in field_names])
return response
download_csv.short_description = _("Download marked as csv")
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-02-12 14:06+0100\n"
"PO-Revision-Date: 2018-02-12 13:42+0100\n"
"POT-Creation-Date: 2018-05-16 20:01+0200\n"
"PO-Revision-Date: 2018-05-16 20:03+0200\n"
"Last-Translator: Sébastiaan Versteeg <se_bastiaan@outlook.com>\n"
"Language-Team: \n"
"Language: nl\n"
......@@ -16,24 +16,36 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.6\n"
"X-Generator: Poedit 1.8.7.1\n"
#: admin.py:34
#: admin.py:38
msgid "Mark exams as accepted"
msgstr "Markeer tentamens als geaccepteerd"
#: admin.py:39
#: admin.py:43
msgid "Mark exams as rejected"
msgstr "Markeer tentamens als afgekeurd"
#: admin.py:53
#: admin.py:48
msgid "Reset the marked exams download count"
msgstr "Reset download aantal van gemarkeerde tentamens"
#: admin.py:67 admin.py:111
msgid "Download marked as csv"
msgstr "Download gemarkeerde tentamens als csv"
#: admin.py:82
msgid "Mark summaries as accepted"
msgstr "Markeer samenvattingen als geaccepteerd"
#: admin.py:58
#: admin.py:87
msgid "Mark summaries as rejected"
msgstr "Markeer samenvattingen als afgekeurd"
#: admin.py:92
msgid "Reset the marked summaries download count"
msgstr "Reset download aantal van gemarkeerde samenvattingen"
#: apps.py:7
msgid "Education"
msgstr "Onderwijs"
......@@ -58,7 +70,7 @@ msgstr "EC"
msgid "period"
msgstr "periode"
#: models.py:77 models.py:132 models.py:180
#: models.py:77 models.py:132 models.py:186
msgid "course"
msgstr "vak"
......@@ -110,11 +122,11 @@ msgstr "type tentamen"
msgid "exam name"
msgstr "naam tentamen"
#: models.py:107 models.py:163
#: models.py:107 models.py:169
msgid "uploader"
msgstr "uploader"
#: models.py:116 models.py:185
#: models.py:116 models.py:191
msgid "accepted"
msgstr "geaccepteerd"
......@@ -122,32 +134,36 @@ msgstr "geaccepteerd"
msgid "exam date"
msgstr "tentamendatum"
#: models.py:126 models.py:191
#: models.py:126 models.py:197
msgid "Use the 'View on site' button to download the file for inspection."
msgstr ""
"Gebruik de ‘Toon op site’ knop om het bestand te downloaden voor controle."
#: models.py:151
#: models.py:137 models.py:202
msgid "amount of downloads"
msgstr "Hoeveelheid downloads"
#: models.py:157
msgid "exam"
msgstr "tentamen"
#: models.py:152
#: models.py:158
msgid "exams"
msgstr "tentamens"
#: models.py:158
#: models.py:164
msgid "summary name"
msgstr "naam samenvatting"
#: models.py:175
#: models.py:181
msgid "author"
msgstr "auteur"
#: models.py:203
#: models.py:215
msgid "summary"
msgstr "samenvatting"
#: models.py:204
#: models.py:216
msgid "summaries"
msgstr "samenvattingen"
......
# Generated by Django 2.0.5 on 2018-05-16 17:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('education', '0007_rename_answers_type'),
]
operations = [
migrations.AddField(
model_name='exam',
name='download_count',
field=models.IntegerField(default=0, verbose_name='amount of downloads'),
),
migrations.AddField(
model_name='summary',
name='download_count',
field=models.IntegerField(default=0, verbose_name='amount of downloads'),
),
]
......@@ -133,6 +133,12 @@ class Exam(models.Model, metaclass=ModelTranslateMeta):
on_delete=models.CASCADE,
)
download_count = models.IntegerField(
verbose_name=_('amount of downloads'),
default=0,
blank=False,
)
def __str__(self):
return "{} {} ({}, {}, {})".format(self.name.capitalize(),
self.type.capitalize(),
......@@ -192,6 +198,12 @@ class Summary(models.Model, metaclass=ModelTranslateMeta):
'the file for inspection.')
)
download_count = models.IntegerField(
verbose_name=_('amount of downloads'),
default=0,
blank=False,
)
def __str__(self):
return "{} ({}, {}, {})".format(self.name, self.course.name,
self.course.course_code, self.year)
......
......@@ -54,6 +54,10 @@ def student_participation(request):
@login_required
def exam(request, id):
exam = get_object_or_404(Exam, id=int(id))
exam.download_count += 1
exam.save()
ext = os.path.splitext(exam.file.path)[1]
filename = '{}-exam{}{}'.format(exam.course.name, exam.year, ext)
return sendfile(request, exam.file.path,
......@@ -63,6 +67,10 @@ def exam(request, id):
@login_required
def summary(request, id):
obj = get_object_or_404(Summary, id=int(id))
obj.download_count += 1
obj.save()
ext = os.path.splitext(obj.file.path)[1]
filename = '{}-summary{}{}'.format(obj.course.name, obj.year, ext)
return sendfile(request, obj.file.path,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment