def test_pl_state(self): self.assertIs(Answer.pl_state(self.pl, self.user), State.NOT_STARTED) Answer.objects.create(pl=self.pl, user=self.user, grade=10) self.assertEqual(Answer.pl_state(self.pl, self.user), State.PART_SUCC) self.assertEqual(Answer.activity_state(self.pltp, self.user), [(self.pltp.indexed_pl()[0].id, State.NOT_STARTED), (self.pltp.indexed_pl()[1].id, State.NOT_STARTED)]) Answer.objects.create(pl=self.pltp.indexed_pl()[0], user=self.user, grade=10) self.assertEqual(Answer.activity_state(self.pltp, self.user), [(self.pltp.indexed_pl()[0].id, State.PART_SUCC), (self.pltp.indexed_pl()[1].id, State.NOT_STARTED)])
def course_view(request, id): try: course = Course.objects.get(id=id) except: raise Http404("Course (id: " + str(id) + ") not found.") if not course.is_member( request.user) and not request.user.profile.is_admin(): logger.warning("User '" + request.user.username + "' denied to access course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas membre de cette classe.") if request.method == 'GET': if request.GET.get("action", None) == "toggle_activity": if not request.user in course.teacher.all(): logger.warning("User '" + request.user.username + "' denied to toggle course state'" + course.name + "'.") raise PermissionDenied( "Vous n'avez pas les droits nécessaires pour fermer/ouvrir cette activité." ) try: act = Activity.objects.get(id=request.GET.get("id", None)) act.open = not act.open act.save() logger.info("User '" + request.user.username + "' set activity '" + act.name + "' 'open' attribute to '" + str(act.open) + "' in '" + course.name + "'.") except: raise Http404("L'activité d'ID '" + str(request.GET.get("id", None)) + "' introuvable.") activity = list() for item in course.activity.all().order_by("id"): pl = [{ 'name': elem.json['title'], 'state': Answer.pl_state(elem, request.user) } for elem in item.pltp.pl.all()] len_pl = len(pl) if len(pl) else 1 activity.append({ 'name': item.name, 'pltp_sha1': item.pltp.sha1, 'title': item.pltp.json['title'], 'pl': pl, 'id': item.id, 'open': item.open, 'width': str(100 / len_pl), }) return render( request, 'classmanagement/course.html', { 'name': course.name, 'activity': activity, 'teacher': course.teacher.all(), 'instructor': True if request.user in course.teacher.all() else False, 'course_id': id, })
def get_context(self, request): pltp = PLTP.objects.get(sha1=self.dic['pltp_sha1__']) pl_list = list() for item in pltp.pl.all(): dic = self.intern_build() if 'pl_id__' in dic and item.id == dic['pl_id__']: answer = Answer.last_answer(item, request.user) if answer: dic['code'] = answer for key in [ 'text', 'texth', 'introduction', 'introductionh', "form", "title" ]: if key in dic: dic[key] = Template(dic[key]).render(Context(dic)) state = Answer.pl_state(item, request.user) pl_list.append({ 'id': item.id, 'state': state, 'title': item.json['title'], }) context = RequestContext(request) context.update(dic) context['pl_list__'] = pl_list return context
def teacher_dashboard(self, request, activity, session): """ This method is called when the dashboard of an activity is requested for a teacher. :return: A rendered template of the teacher dashboard """ student = list() for user in activity.student.all(): tp = list() for pl in activity.indexed_pl(): tp.append({ 'name': pl.json['title'], 'state': Answer.pl_state(pl, user) }) student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'question': tp, }) # Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'activity/activity_type/pltp/teacher_dashboard.html', { 'state': [i for i in State if i != State.ERROR], 'course_name': activity.parent.name, 'activity_name': activity.name, 'student': student, 'range_tp': range(len(activity.indexed_pl())), 'course_id': activity.parent.id, })
def __get_context(self, request, feedback=None, success=None): #Bootstrap class corresponding to every state. color = { Answer.SUCCEEDED: "1", Answer.FAILED: "2", Answer.STARTED: "3", Answer.NOT_STARTED: "4", } #Give the right state number for the css class according to user color blindness blindness = { PLUser.NONE: "", PLUser.DEUTERANOPIA: "-deuteranopia", PLUser.PROTANOPIA: "-protanopia", PLUser.TRITANOPIA: "-tritanopia", } pltp = PLTP.objects.get(sha1=self.dic['pltp_sha1']) pltp_json = json.loads(pltp.json) pl_list = list() for item in pltp.pl.all(): state = Answer.pl_state(item, request.user) is_pl = False if 'pl_sha1' in self.dic and item.sha1 == self.dic['pl_sha1']: if state != Answer.NOT_STARTED: self.dic['student_answer'] = Answer.objects.filter( user=request.user, pl=item).order_by('-date')[0].value is_pl = True content = json.loads(item.json) pl_list.append( (item, color[state] + blindness[request.user.pluser.color_blindness], content["title"])) context = RequestContext(request) dic = self.__build() context.update(dic) context['is_pl'] = is_pl context['pl_list'] = pl_list if 'custom_nav' in pltp_json: context['custom_nav'] = Template(pltp_json['custom_nav']) else: context['custom_nav'] = 'playexo/default_nav.html' if success: context['success'] = success if feedback: context['feedback'] = feedback return context
def activity_summary(request, id, name): try: course = Course.objects.get(id=id) except: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if not request.user.profile.is_admin() and ( not request.user in course.user.all() or not request.user.profile.have_role(Role.INSTRUCTOR)): logger.warning("User '" + request.user.username + "' denied to access summary of course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") activity = Activity.objects.get(name=name) student = list() for user in course.student.all(): tp = list() for pl in activity.pltp.pl.all(): tp.append({ 'name': pl.json['title'], 'state': Answer.pl_state(pl, user) }) student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'question': tp, }) #Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'classmanagement/activity_summary.html', { 'state': [ i for i in State if i not in [State.TEACHER_EXC, State.SANDBOX_EXC] ], 'course_name': course.name, 'activity_name': activity.name, 'student': student, 'range_tp': range(len(activity.pltp.pl.all())), 'course_id': id, })
def student_summary(request, course_id, student_id): try: course = Course.objects.get(id=course_id) except: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if not request.user.profile.is_admin() and ( not request.user in course.user.all() or not request.user.profile.have_role(Role.INSTRUCTOR)): logger.warning("User '" + request.user.username + "' denied to access summary of course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") student = User.objects.get(id=student_id) activities = course.activity.all().order_by("id") tp = list() for activity in activities: question = list() for pl in activity.pltp.pl.all(): state = Answer.pl_state(pl, student) question.append({ 'state': state, 'name': pl.json['title'], }) len_tp = len(question) if len(question) else 1 tp.append({ 'name': activity.pltp.json['title'], 'activity_name': activity.name, 'width': str(100 / len_tp), 'pl': question, }) return render( request, 'classmanagement/student_summary.html', { 'state': [ i for i in State if i not in [State.TEACHER_EXC, State.SANDBOX_EXC] ], 'course_name': course.name, 'student': student, 'activities': tp, 'course_id': course_id, })
def small(self, request, activity): """ This method can be called by any parent activity to display something from this activity. :return: A rendered template of the teacher dashboard """ pl = [{ 'name': activity.activity_data['title'], 'state': Answer.pl_state(elem, request.user) } for elem in activity.indexed_pl()] return get_template("activity/activity_type/pltp/small.html").render( { 'title': activity.activity_data['title'], 'pl': pl, 'id': activity.id, 'open': activity.open, 'instructor': request.user in activity.teacher.all() }, request)
def activity_summary(request, id, name): try: course = Course.objects.get(id=id) except: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if not request.user.pluser.is_admin() and ( not request.user in course.user.all() or not request.user.pluser.have_role(Role.INSTRUCTOR)): logger.warning("User '" + request.user.username + "' denied to access course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") activity = Activity.objects.get(name=name) student = list() for user in course.user.all(): tp = list() for pl in activity.pltp.pl.all(): tp.append({ 'name': json.loads(pl.json)['title'], 'state': STATE[Answer.pl_state(pl, user)] + BLINDNESS[request.user.pluser.color_blindness], }) student.append({ 'lastname': user.last_name, 'name': user.get_full_name(), 'id': user.id, 'question': tp, }) #Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'classmanagement/activity_summary.html', { 'course_name': course.name, 'activity_name': activity.name, 'student': student, 'range_tp': range(len(activity.pltp.pl.all())), 'course_id': id, })
def student_summary(request, course_id, student_id): try: course = Course.objects.get(id=course_id) except: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if not request.user.pluser.is_admin() and ( not request.user in course.user.all() or not request.user.pluser.have_role(Role.INSTRUCTOR)): logger.warning("User '" + request.user.username + "' denied to access course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") student = User.objects.get(id=student_id) activities = course.activity.all().order_by("id") tp = list() for activity in activities: question = list() for pl in activity.pltp.pl.all(): state = STATE[Answer.pl_state( pl, student)] + BLINDNESS[request.user.pluser.color_blindness] question.append({ 'state': state, 'name': json.loads(pl.json)['title'], }) len_tp = len(question) if len(question) else 1 tp.append({ 'name': json.loads(activity.pltp.json)['title'], 'activity_name': activity.name, 'width': str(100 / len_tp), 'pl': question, }) return render( request, 'classmanagement/student_summary.html', { 'course_name': course.name, 'student_name': student.get_full_name(), 'activities': tp, 'course_id': course_id, })
def student_summary(request, course_id, student_id): try: course = Course.objects.get(id=course_id) except Course.DoesNotExist: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if request.user not in course.teacher.all(): logger.warning("User '" + request.user.username + "' denied to access summary of course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") student = User.objects.get(id=student_id) activities = course.activity_set.all().order_by("id") tp = list() for activity in activities: question = list() for pl in activity.pltp.pl.all(): state = Answer.pl_state(pl, student) question.append({ 'state': state, 'name': pl.json['title'], }) len_tp = len(question) if len(question) else 1 tp.append({ 'name': activity.pltp.json['title'], 'activity_name': activity.name, 'id': activity.id, 'width': str(100 / len_tp), 'pl': question, }) return render( request, 'classmanagement/student_summary.html', { 'state': [i for i in State if i != State.ERROR], 'course_name': course.name, 'student': student, 'activities': tp, 'course_id': course_id, })
def activity_summary(request, pk, activity_pk): try: course = Course.objects.get(id=pk) except Course.DoesNotExist: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if request.user not in course.teacher.all(): logger.warning("User '" + request.user.username + "' denied to access summary of course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") activity = Activity.objects.get(pk=activity_pk) student = list() for user in course.student.all(): tp = list() for pl in activity.pltp.pl.all(): tp.append({ 'name': pl.json['title'], 'state': Answer.pl_state(pl, user) }) student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'question': tp, }) # Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'classmanagement/activity_summary.html', { 'state': [i for i in State if i != State.ERROR], 'course_name': course.name, 'activity_name': activity.name, 'student': student, 'range_tp': range(len(activity.pltp.pl.all())), 'course_id': pk, })
def student_summary(self, student_id, request, activity): try: student = User.objects.get(id=student_id) except User.DoesNotExist: return HttpResponseNotFound( "Cet étudiant ne fait pas partie de ce cours") if not activity.is_member(student): return HttpResponseNotFound( "Cet étudiant ne fait pas partie de ce cours") activities = activity.indexed_activities().filter(teacher=request.user) tp = list() for a in activities: question = list() for pl in a.indexed_pl(): state = Answer.pl_state(pl, student) question.append({ 'state': state, 'name': pl.json['title'], }) len_tp = len(question) if len(question) else 1 tp.append({ 'name': a.activity_data['title'], 'activity_name': a.name, 'id': a.id, 'width': str(100 / len_tp), 'pl': question, }) return render( request, 'activity/activity_type/course/student_summary.html', { 'state': [i for i in State if i != State.ERROR], 'course_name': activity.name, 'student': student, 'activities': tp, 'course_id': activity.id, })
def small(self, request, activity): """ This method can be called by any parent activity to display something from this activity. :return: A rendered template of the teacher dashboard """ pl = [{ 'name': activity.activity_data['title'], 'state': Answer.pl_state(elem, request.user) } for elem in activity.indexed_pl()] progr, quality = user_progression(request.user, activity) return get_template("activity/activity_type/pltp/small.html").render( { 'title': activity.activity_data['title'], 'pl': pl, 'id': activity.id, 'open': activity.open, 'instructor': request.user in activity.teacher.all(), 'nb_exos': len(pl), 'progr': graph_percent(progr), 'quality': graph_percent(quality), }, request)
def navigation(self, activity, session_activity, request): """This method is called to get a rendered template of the navigation of this activity""" session_exercise = session_activity.session_exercise() pl_list = [{ 'id': None, 'state': None, 'title': activity.activity_data['title'], }] for pl in activity.indexed_pl(): pl_list.append({ 'id': pl.id, 'state': Answer.pl_state(pl, session_activity.user), 'title': pl.json['title'], }) context = dict(session_exercise.context) context.update({ "pl_list__": pl_list, 'pl_id__': session_exercise.pl.id if session_exercise.pl else None }) return get_template( "activity/activity_type/pltp/navigation.html").render( context, request)
def test_pl_state(self): self.assertIs(Answer.pl_state(self.pl, self.user), State.NOT_STARTED) Answer.objects.create(pl=self.pl, user=self.user, grade=10) self.assertEqual(Answer.pl_state(self.pl, self.user), State.PART_SUCC)
def course_view(request, id): try: course = Course.objects.get(id=id) except: raise Http404( "Impossible d'accéder à la page, cette classe n'existe pas.") if not request.user in course.user.all( ) and not request.user.pluser.is_admin(): logger.warning("User '" + request.user.username + "' denied to access course'" + course.name + "'.") raise PermissionDenied( "Vous n'appartenez pas à cette classe et ne pouve donc y accéder.") if request.method == 'GET': if request.GET.get("action", None) == "toggle_activity": if not request.user.pluser.can_load(): logger.warning("User '" + request.user.username + "' denied to access course'" + course.name + "'.") raise PermissionDenied( "Vous n'avez pas les droits nécessaires pour fermer/ouvrir cette activité." ) try: act = Activity.objects.get(id=request.GET.get("id", None)) act.open = not act.open act.save() except: raise Http404("L'activité d'ID '" + str(request.GET.get("id", None)) + "' introuvable.") #Getting profs query = course.user.all() prof = list() for user in query: if user.pluser.have_role(Role.INSTRUCTOR): if not prof: prof.append("- " + user.get_full_name().title() + " (" + user.email + ")") else: prof.append("- " + user.get_full_name().title() + " (" + user.email + ")") #Getting activities activities = course.activity.all().order_by("id") activity = list() for item in activities: pl = list() for elem in item.pltp.pl.all(): pl.append({ 'name': elem.json['title'], 'state': STATE[Answer.pl_state(elem, request.user)] + BLINDNESS[request.user.pluser.color_blindness], }) len_pl = len(pl) if len(pl) else 1 activity.append({ 'name': item.name, 'pltp_sha1': item.pltp.sha1, 'title': item.pltp.json['title'], 'pl': pl, 'id': item.id, 'open': item.open, 'width': str(100 / len_pl), }) return render( request, 'classmanagement/course.html', { 'name': course.name, 'activity': activity, 'prof': prof, 'instructor': True if request.user.pluser.have_role(Role.INSTRUCTOR) else False, 'course_id': id, })