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)