Add/change Course templates and add new org filter
- Author
- Maarten 'Vngngdn' Vangeneugden
- Date
- Nov. 29, 2017, 9:52 p.m.
- Hash
- d7edab6b52868f9bad6c0e38f9de4c97b4a6f482
- Parent
- 1f2fa3814594fb45c0f1e13535e977ccbcf3b38d
- Modified files
- courses/templates/courses/new_item.djhtml
- courses/views.py
- joeni/templatetags/__init__.py
- joeni/templatetags/joeni_org.py
courses/templates/courses/new_item.djhtml ¶
64 additions and 0 deletions.
View changes Hide changes
+ |
1 |
{% load static %} |
+ |
2 |
{% load i18n %} |
+ |
3 |
{% load humanize %} |
+ |
4 |
{% load crispy_forms_tags %} |
+ |
5 |
|
+ |
6 |
{% block title %} |
+ |
7 |
{{ course.name }} - {% trans "Course items"%} | ◀ Joeni /▶ |
+ |
8 |
{% endblock %} |
+ |
9 |
|
+ |
10 |
{% block main %} |
+ |
11 |
<h1>{% trans "Announcements" %}</h1> |
+ |
12 |
{% for announcement in announcements %} |
+ |
13 |
<label for="announcement-{{ forloop.counter0 }}">{{ announcement.title }}</label> |
+ |
14 |
<input type="checkbox" id="announcement-{{ forloop.counter0 }}"> |
+ |
15 |
{% crispy courses-announcement-form %} |
+ |
16 |
<a href="{% url 'courses-remove' type='announcement' id=announcement.id %}"> |
+ |
17 |
{% trans "Delete" %} |
+ |
18 |
</a> |
+ |
19 |
|
+ |
20 |
<hr /> |
+ |
21 |
{% endfor %} |
+ |
22 |
|
+ |
23 |
<h1>{% trans "Assignments" %}</h1> |
+ |
24 |
{% for assignment in assignments %} |
+ |
25 |
<label for="assignment-{{ forloop.counter0 }}">{{ assignment.title }}</label> |
+ |
26 |
<input type="checkbox" id="assignment-{{ forloop.counter0 }}"> |
+ |
27 |
{% crispy courses-assignment-form %} |
+ |
28 |
<a href="{% url 'courses-remove' type='assignment' id=assignment.id %}"> |
+ |
29 |
{% trans "Delete" %} |
+ |
30 |
</a> |
+ |
31 |
{% if assignment.digital_task %} |
+ |
32 |
<h2>{% trans "Uploads" %}</h2> |
+ |
33 |
{% for upload in uploads|dictsort:"student" %} |
+ |
34 |
{% if upload.assignment == assignment %} |
+ |
35 |
{% ifchanged upload.student %} |
+ |
36 |
<h3>{{ upload.student }}</h3> |
+ |
37 |
{% endifchanged %} |
+ |
38 |
{{ upload.upload_time|date:"SHORT_DATETIME_FORMAT" }} |
+ |
39 |
{% now as current_time %} |
+ |
40 |
{% if now > upload.upload_time %} |
+ |
41 |
<strong>{% trans "Overdue" %}</strong> |
+ |
42 |
{% endif %} |
+ |
43 |
<a href="{{ media }}{{ upload.file }}" download>{% trans "View submission" %}</a> |
+ |
44 |
{% if upload.comment %} |
+ |
45 |
<h4>{% trans "Additional comment" %}</h4> |
+ |
46 |
<p> |
+ |
47 |
{{ upload.comment }} |
+ |
48 |
</p> |
+ |
49 |
{% endif %} |
+ |
50 |
<hr /> |
+ |
51 |
{% endif %} |
+ |
52 |
{% empty %} |
+ |
53 |
{% trans "There are no submissions for this assignment yet." %} |
+ |
54 |
{% endfor %} |
+ |
55 |
{% endif %} |
+ |
56 |
{% endfor %} |
+ |
57 |
<h1>{% trans "Course items" %}</h1> |
+ |
58 |
{% for course-item in course-items|dictsort:"timestamp" %} |
+ |
59 |
{% crispy courses-course-item-form %} |
+ |
60 |
<a href="{% url 'courses-remove' type='course-item' id=course-item.id %}"> |
+ |
61 |
{% trans "Delete" %} |
+ |
62 |
</a> |
+ |
63 |
|
+ |
64 |
courses/views.py ¶
3 additions and 0 deletions.
View changes Hide changes
1 |
1 |
import datetime |
2 |
2 |
from django.core.urlresolvers import reverse # Why? |
3 |
3 |
from django.utils.translation import gettext as _ |
4 |
4 |
from .models import * |
5 |
5 |
import joeni.administration |
6 |
6 |
|
7 |
7 |
def current_academic_year(): |
8 |
8 |
""" Returns the current academic year. The year is determined as follows: |
9 |
9 |
- If today is before September 15 of the current year, the returned value |
10 |
10 |
is the current year - 1. |
11 |
11 |
- If today is after September 15 of the current year, but before January 1 |
12 |
12 |
of the next year, it returns the current year as is. |
13 |
13 |
""" |
14 |
14 |
today = datetime.datetime.now() |
15 |
15 |
switch = datetime.datetime.date(datetime.datetime.year, 9, 15) |
16 |
16 |
if today < switch: |
17 |
17 |
return today.year - 1 |
18 |
18 |
else: |
19 |
19 |
return today.year |
20 |
20 |
|
21 |
21 |
@login_required |
22 |
22 |
def index(request): |
23 |
23 |
""" Starting page regarding the courses. This serves two specific groups: |
24 |
24 |
- Students: Displays all courses that this student has in his/her curriculum |
25 |
25 |
for this academic year. Requires the curriculum to be accepted. |
26 |
26 |
- Staff: Displays all courses in which the staff member is part of the |
27 |
27 |
educating team, or is otherwise related to the course. |
28 |
28 |
Users who are not logged in will be sent to the login page. |
29 |
29 |
""" |
30 |
30 |
template = "courses/index.djhtml" |
31 |
31 |
courses = set() |
32 |
32 |
if request.user.is_student: |
33 |
33 |
curricula = administration.models.Curriculum.objects.filter(student=request.user) |
34 |
34 |
current_curriculum = curricula.filter(year__year=current_academic_year()) |
35 |
35 |
courses = current_curriculum.courses |
36 |
36 |
elif request.user.is_staff: |
37 |
37 |
courses += adminstration.models.Course.filter(course_team__contains=request.user) |
38 |
38 |
else: |
39 |
39 |
raise django.exceptions.FieldError("User "+request.user.number+" is neither staff nor student") |
40 |
40 |
|
41 |
41 |
context = { |
42 |
42 |
'courses': courses, |
43 |
43 |
} |
44 |
44 |
|
45 |
45 |
return render(request, template, context) |
46 |
46 |
|
47 |
47 |
@login_required |
48 |
48 |
def course(request, course_slug): |
49 |
49 |
template = "courses/course.djhtml" |
50 |
50 |
course = Course.objects.get(slug_name=course_slug) |
51 |
51 |
|
52 |
52 |
# Check if user can see this page |
53 |
53 |
if request.user.is_student: |
54 |
54 |
curricula = administration.models.Curriculum.objects.filter(student=request.user) |
55 |
55 |
current_curriculum = curricula.filter(year__year=current_academic_year()) |
56 |
56 |
if course not in current_curriculum.courses: |
57 |
57 |
""" I'm currently just redirecting to the index page, but maybe it's |
58 |
58 |
just as good to make an announcement that this course cannot be |
59 |
59 |
used by this user. """ |
60 |
60 |
return index(request) |
61 |
61 |
|
62 |
62 |
|
63 |
63 |
|
64 |
64 |
context = { |
65 |
65 |
'course': course, |
66 |
66 |
'announcements': Announcement.objects.filter(course=course), |
67 |
67 |
'assignments': Assignment.objects.filter(course=course), |
68 |
68 |
'course-items': CourseItem.objects.filter(course=course), |
69 |
69 |
'study-groups': StudyGroup.objects.filter(course=course), |
70 |
70 |
'uploads': Upload.objects.filter(course=course).filter(student=request.user) |
71 |
71 |
} |
72 |
72 |
|
73 |
73 |
return render(request, template, context) |
74 |
74 |
|
75 |
75 |
@login_required |
+ |
76 |
# put them in a decorator |
+ |
77 |
#@permission_required |
+ |
78 |
@login_required |
76 |
79 |
def new_item(request, course_slug): |
77 |
80 |
template = "courses/new_item.djhtml" |
78 |
81 |
course = Course.objects.get(slug_name=course_slug) |
79 |
82 |
|
80 |
83 |
if request.user.is_student or request.user not in course.course_team: |
81 |
84 |
# Students can't add new items. Redirect to index |
82 |
85 |
# Also redirect people who are not part of the course team |
83 |
86 |
redirect('courses-index') |
84 |
87 |
# Now able to assume user is allowed to add items to this course |
85 |
88 |
|
86 |
89 |
context = { |
87 |
90 |
'course': course, |
88 |
91 |
'announcements': Announcement.objects.filter(course=course), |
89 |
92 |
'assignments': Assignment.objects.filter(course=course), |
90 |
93 |
'course-items': CourseItem.objects.filter(course=course), |
91 |
94 |
'study-groups': StudyGroup.objects.filter(course=course), |
92 |
95 |
'uploads': Upload.objects.filter(course=course) |
93 |
96 |
} |
94 |
97 |
|
95 |
98 |
return render(request, template, context) |
96 |
99 |
|
97 |
100 |
@login_required |
98 |
101 |
def remove(request, type, id): |
99 |
102 |
pass |
100 |
103 |
joeni/templatetags/__init__.py ¶
0 additions and 0 deletions.
View changes Hide changes
joeni/templatetags/joeni_org.py ¶
10 additions and 0 deletions.
View changes Hide changes
+ |
1 |
from django.utils.safestring import mark_safe |
+ |
2 |
import subprocess # To call Pandoc |
+ |
3 |
|
+ |
4 |
register = template.Library() |
+ |
5 |
|
+ |
6 |
@register.filter |
+ |
7 |
def org(value): |
+ |
8 |
""" Takes an input, and transpiles it as org-mode syntax to HTML syntax. """ |
+ |
9 |
return mark_safe(subprocess.check_output(["pandoc", "--from=org", "--to=html", value])) |
+ |
10 |