icp/src/courses/views.py

183 lines
6.1 KiB
Python

from __future__ import print_function
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django import template
from django.template.defaultfilters import stringfilter
# Class Based Views (CBV)
from django.views.generic import View
from django.views.generic import ListView
from .models import Course
from .models import Section
from .models import Slide
from .models import UserCourse
from .models import UserSolution
import sys
import json
class ListCourseView(ListView):
model = Course
###############################################################################
def index(request):
data = {}
return render(request, 'courses/index.html')
###############################################################################
def course(request, cid):
course = get_object_or_404(Course, pk=cid)
first_section = course.sections.first()
first_slide = first_section.slides.first()
if request.user.is_authenticated:
try:
# when the user is merely opening the course, jump the last active section (better: last incomplete?)
user_course = UserCourse.objects.get(course=course, user=request.user)
return HttpResponseRedirect(reverse('courses:slide', args=(course.id, user_course.progress_section.id, user_course.progress_slide.id)))
except UserCourse.DoesNotExist:
# usfrom django import template
# also redirect to course beginning
user_course = UserCourse.objects.create(course=course, user=request.user, progress_section=first_section, progress_slide=first_slide)
return HttpResponseRedirect(reverse('courses:slide', args=(course.id, first_section.id, first_slide.id)))
else:
return HttpResponseRedirect(reverse('courses:slide', args=(course.id, first_section.id, first_slide.id)))
data = {'course': course}
return render(request, 'courses/course.html', data)
###############################################################################
def section(request, cid, seid):
course = get_object_or_404(Course, pk=cid)
section = get_object_or_404(Section, pk=seid)
first_slide = section.slides.first()
if request.user.is_authenticated:
try:
user_course = UserCourse.objects.get(course=course, user=request.user)
if section.id == user_course.progress_section.id:
# only redirect if progress was made in this sections
return HttpResponseRedirect(reverse('courses:slide', args=(course.id, user_course.progress_section.id, user_course.progress_slide.id)))
else:
# otherwise switch to first slide in section
first_slide = section.slides.first()
return HttpResponseRedirect(reverse('courses:slide', args=(course.id, section.id, first_slide.id)))
except UserCourse.DoesNotExist:
# TODO how are direct visitors handled?
pass
else:
return HttpResponseRedirect(reverse('courses:slide', args=(course.id, section.id, first_slide.id)))
data = {'course': course}
return render(request, 'courses/course.html', data)
###############################################################################
def slide(request, cid, seid, slid):
""" The slide view serves the smallest servable unit of material to the
user. In principle a single slide is meant to provide
"""
course = get_object_or_404(Course, pk=cid)
section = get_object_or_404(Section, pk=seid)
slide = get_object_or_404(Slide, pk=slid)
if request.user.is_authenticated:
try:
user_course = UserCourse.objects.get(course=course, user=request.user)
# simply update last user_course action
user_course.progress_section = section
user_course.progress_slide = slide
user_course.save()
except UserCourse.DoesNotExist:
# TODO Should direct visitors get a special treatment?
pass
user_solution = None
if request.user.is_authenticated:
try:
user_solution = UserSolution.objects.get(slide=slide, user=request.user)
except UserSolution.DoesNotExist:
# TODO Should direct visitors get a special treatment?
pass
print(user_solution, file=sys.stderr)
result = request
print(result, file=sys.stderr)
print(dir(result), file=sys.stderr)
# determine next slide, as necessary for the navigation
next_slide = {'course': course, 'section': None, 'slide': None}
matched_slide = False
slides = section.slides.all()
for s in slides:
if matched_slide:
next_slide['slide'] = s
next_slide['section'] = section
break;
if slide.id == s.id:
matched_slide = True
# looks like the slide was the last for this section find next section
if next_slide['slide'] == None:
matched_section = False
sections = course.sections.all()
for sec in sections:
if matched_section:
next_slide['slide'] = sec.slides.first()
next_slide['section'] = sec
break;
if section.id == sec.id:
matched_section = True
try:
slide_data = json.loads(slide.data)
except:
slide_data = "Exception!"
try:
user_solution_data = json.loads(user_solution.data)
except:
user_solution_data = "Exception!"
data = {'course': course, 'section': section, 'slide': slide, 'next_slide': next_slide, 'slide_data': slide_data, 'user_solution_data': user_solution_data}
# return render(request, 'courses/course.html', data)
try:
template_path = 'generated_exercises/%s/template.html' % (slide.slide_type)
print(template_path, file=sys.stderr)
template.loader.get_template(template_path)
return render(request, template_path, data)
except template.TemplateDoesNotExist:
return render(request, 'courses/course.html', data)