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 test_activity_summary(self): self.assertEqual( Answer.activity_summary(self.pltp, self.user)[State.NOT_STARTED], ['100.0', '2']) Answer.objects.create(pl=self.pltp.indexed_pl()[0], user=self.user, grade=10) self.assertEqual( Answer.activity_summary(self.pltp, self.user)[State.PART_SUCC], ['50.0', '1'])
def test_pl_state(self): self.assertEqual(Answer.pltp_state(self.pltp, self.user), [(self.pltp.pl.all()[0].id, State.NOT_STARTED), (self.pltp.pl.all()[1].id, State.NOT_STARTED)]) Answer.objects.create(pl=self.pltp.pl.all()[0], user=self.user, grade=10) self.assertEqual(Answer.pltp_state(self.pltp, self.user), [(self.pltp.pl.all()[0].id, State.PART_SUCC), (self.pltp.pl.all()[1].id, State.NOT_STARTED)])
def activity_ajax(request): exercise = request.session.get('exercise', None) if not exercise: return HttpResponse("No exercise found in the session", status=409) exercise = PLInstance(exercise) status = json.loads(request.body.decode()) if status['requested_action'] == 'save': feedback_type = "info" feedback = "Réponse enregistré avec succès" Answer(value=status['inputs']['answer'], user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id__']), seed=exercise.dic['seed'], grade=-1).save() return HttpResponse(json.dumps({ 'feedback_type': feedback_type, 'feedback': feedback }), content_type='application/json') elif status['requested_action'] == 'submit': # Validate success, feedback = exercise.evaluate(status['inputs']) if 'answer' in status['inputs']: value = status['inputs']['answer'] else: value = "" if success == None: feedback_type = "info" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id__']), seed=exercise.dic['seed'], grade=-1).save() elif success: feedback_type = "success" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id__']), seed=exercise.dic['seed'], grade=100).save() else: feedback_type = "fail" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id__']), seed=exercise.dic['seed'], grade=0).save() return HttpResponse(json.dumps({ 'feedback_type': feedback_type, 'feedback': feedback }), content_type='application/json') return HttpResponseBadRequest("Missing action in status")
def ajax(request, exercise): status = json.loads(request.body.decode()) if status['requested_action'] == 'submit': # Validate success, feedback = exercise.evaluate(status['inputs']) if 'answer' in status['inputs']: value = status['inputs']['answer'] else: value = "" if success == None: feedback_type = "info" Answer(value=value, user=request.user, pl=PL.objects.get(sha1=exercise.dic['pl_sha1']), seed=exercise.dic['seed'], state=Answer.STARTED).save() elif success: feedback_type = "success" Answer(value=value, user=request.user, pl=PL.objects.get(sha1=exercise.dic['pl_sha1']), seed=exercise.dic['seed'], state=Answer.SUCCEEDED).save() else: feedback_type = "fail" Answer(value=value, user=request.user, pl=PL.objects.get(sha1=exercise.dic['pl_sha1']), seed=exercise.dic['seed'], state=Answer.FAILED).save() return HttpResponse(json.dumps({ 'feedback_type': feedback_type, 'feedback': feedback }), content_type='application/json') elif status['requested_action'] == 'save': # Save if 'answer' in status['inputs']: value = status['inputs']['answer'] else: value = "" Answer(value=value, user=request.user, pl=PL.objects.get(sha1=exercise.dic['pl_sha1']), seed=exercise.dic['seed'], state=Answer.STARTED).save() return HttpResponse(json.dumps({ 'feedback_type': "info", 'feedback': "Votre réponse à bien été enregistrée." }), content_type='application/json') return None # Not an AJAX request
def activity_receiver(request): activity_id = request.session.get("current_activity", None) if activity_id == None: return HttpResponse("No activity found in the session", status=409) if request.method == "POST": # Received ajax request return activity_ajax(request) if request.session.get("testing", False): activity = get_object_or_404(ActivityTest, id=activity_id) else: activity = get_object_or_404(Activity, id=activity_id) current_pl = request.session.get("current_pl", None) current_pl = None if current_pl == None else PL.objects.get(id=current_pl) exercise = ActivityInstance(request, activity, current_pl) if request.method == 'GET' and request.GET.get("action", None): action = request.GET.get("action", None) if action == "pl": request.session["current_pl"] = request.GET.get("pl_id", None) elif action == "pltp": request.session["current_pl"] = None elif current_pl and action == "reset": value = "" if 'code' not in exercise.dic else exercise.dic["code"] Answer(value=value, user=request.user, pl=current_pl, seed=exercise.dic['seed'], grade=-1).save() elif current_pl and action == "next": for current, next in zip(activity.pltp.pl.all(), list(activity.pltp.pl.all())[1:] + [None]): if current_pl.id == current.id: request.session[ "current_pl"] = None if next == None else next.id break else: request.session["current_pl"] = None request.method return redirect(reverse(activity_receiver)) request.session['exercise'] = exercise.dic if current_pl: Answer(value='', user=request.user, pl=PL.objects.get(id=current_pl.id), seed=exercise.dic['seed'], grade=-1).save() return HttpResponse(exercise.render(request))
def evaluate(self, exercise, request): """ Return the evaluation of the user's answer in the form of a tuple: - 'success'/'fail'/'info': The user succeeded / The user failed / Save or An error occured - Feedback Return None, None if the request doesn't contain any AJAX request. Calling this function will also save the user's answer in the database. """ status = json.loads(request.body.decode()) if status['requested_action'] == 'submit': # Validate success, feedback = exercise.evaluate(status['inputs']) if 'answer' in status['inputs']: value = status['inputs']['answer'] else: value = "" if success == None: feedback_type = "info" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id']), seed=exercise.dic['seed'], state=-1).save() elif success: feedback_type = "success" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id']), seed=exercise.dic['seed'], state=100).save() else: feedback_type = "fail" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id']), seed=exercise.dic['seed'], state=0).save() return feedback_type, feedback elif status['requested_action'] == 'save': # Save if 'answer' in status['inputs']: value = status['inputs']['answer'] else: value = "" Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id']), seed=exercise.dic['seed'], state=-1).save() return 'info', "Votre réponse à bien été enregistrée." return None, None # Not an AJAX 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) 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 user_progression(user, activity): """Return a tuple of two integers `(progression, quality)` where `progression` is the percent of work done and `quality` is the mean of grades over graded exercices. All views using this utilitary function should check the requesting user is allowed to access data. `progression` : percent of graded exercices plus 10% of percent of only built exercices by the `user`. `quality` : average grade obtained by `user` over graded exercices. Quality is zero if no exercice has been graded. """ pl = activity.pl.all() nb_pl_touched = 0 nb_pl_graded = 0 sum_grades = 0 for i in pl: answer = Answer.highest_grade(i, user) if answer is not None: nb_pl_touched += 1 if answer.grade is not None: nb_pl_graded += 1 sum_grades += answer.grade progr = (100 * nb_pl_graded + 10 * (nb_pl_touched - nb_pl_graded)) / len(pl) if pl else 0 average = sum_grades / nb_pl_graded if nb_pl_graded else 0 return (progr, average)
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 notes(self, activity, request): user = request.user users = activity.student.all() pl = activity.pl.all() if not user or user not in activity.teacher.all(): return HttpResponseForbidden("Not authorized") csv = "username,firstname,lastname,email," + ''.join( [str(i + 1) + ": " + p.name + "," for i, p in enumerate(pl)]) + "total\n" for u in users: grades = [] for i in pl: answer = Answer.highest_grade(i, u) grades.append(0 if answer is None else max(answer.grade, 0) if answer.grade is not None else 0) csv += ("%s,%s,%s,%s," % (u.username, u.first_name, u.last_name, u.email) + ''.join([str(i) + "," for i in grades]) + str(sum(grades)) + "\n") response = HttpResponse(csv, content_type="text/csv") response['Content-Disposition'] = 'attachment;filename=notes.csv' return response
def test_user_course_summary(self): course = Course.objects.create(name="test", label="test") course.student.add(self.user) Activity.objects.create(name="test", pltp=self.pltp, course=course) self.assertEqual( Answer.user_course_summary(course, self.user)[State.NOT_STARTED], ['100.0', '2'])
def reset_pl(self, exercise, request): """ Reset the PL to the default code """ value = "" if 'code' not in exercise.dic else exercise.dic["code"] Answer(value=value, user=request.user, pl=PL.objects.get(id=exercise.dic['pl_id']), seed=exercise.dic['seed'], state=-1).save()
def course_summary(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.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.") activities = course.activity.all().order_by("id") student = list() for user in course.student.all(): tp = list() for activity in activities: summary = Answer.pltp_summary(activity.pltp, user) tp.append({ 'state': [{ 'percent': summary[i][0], 'count': summary[i][1], 'class': i.template } for i in summary], 'name': activity.pltp.json['title'], 'activity_name': activity.name, }) student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'activities': tp, }) #Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'classmanagement/course_summary.html', { 'state': [ i for i in State if i not in [State.TEACHER_EXC, State.SANDBOX_EXC] ], 'name': course.name, 'student': student, 'range_tp': range(len(activities)), 'course_id': id, })
def test_course_state(self): course = Activity.objects.create(name="test", activity_data={"label": "test"}, activity_type="course") course.student.add(self.user) Activity.objects.create(name="test", activity_type="pltp", parent=course) self.assertEqual( Answer.course_state(course)[0]['user_id'], self.user.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_view(request, activity_id): activity = get_object_or_404(Activity, id=activity_id) session, _ = SessionActivity.objects.get_or_create(user=request.user, activity=activity) if request.method == 'GET': action = request.GET.get("action") if action == "pl": pl_id = request.GET.get("pl_id") if not pl_id or not pl_id.isdigit(): return HttpResponseBadRequest( "Missing/invalid parameter 'pl_id'") session.current_pl = get_object_or_404(PL, id=pl_id) session.save() elif action == "pltp": session.current_pl = None session.save() elif session.current_pl and action == "reset": Answer.objects.create(user=request.user, pl=session.current_pl) elif session.current_pl and action == "reroll": exercise = session.exercise() exercise.built = False exercise.seed = None exercise.save() elif session.current_pl and action == "next": pls = activity.pltp.pl.all() for previous, next in zip(pls, list(pls[1:]) + [None]): if previous == session.current_pl: session.current_pl = next session.save() break else: session.current_pl = None session.save() if action: # Remove get arguments from URL return redirect(reverse("playexo:activity", args=[activity_id])) if session.current_pl: last = Answer.last(session.current_pl, request.user) Answer.objects.create(user=request.user, pl=session.current_pl, answers=last.answers if last else {}) return render(request, 'playexo/exercise.html', session.exercise().get_context(request))
def index(request): course = list() for item in request.user.course_set.all(): summary = Answer.user_course_summary(item, request.user) completion = [{'name': "", 'count': summary[key][1], 'class': key.template} for key in summary] course.append({ 'id': item.id, 'name': item.name, 'completion': completion, 'nb_square': sum([int(summary[key][1]) for key in summary]) }) return render(request, 'classmanagement/index.html', {'course': course})
def course_summary(request, 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.info("User '" + request.user.username + "' denied to access summary of course'" + course.name + "'.") raise PermissionDenied("Vous n'êtes pas professeur de cette classe.") activities = course.activity_set.all().order_by("id") student = list() for user in course.student.all(): tp = list() for activity in activities: summary = Answer.pltp_summary(activity.pltp, user) tp.append({ 'state': [{ 'percent': summary[i][0], 'count': summary[i][1], 'class': i.template } for i in summary], 'name': activity.pltp.json['title'], 'activity_name': activity.name, 'id': activity.id, }) student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'activities': tp, }) # Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'classmanagement/course_summary.html', { 'state': [i for i in State if i != State.ERROR], 'name': course.name, 'student': student, 'range_tp': range(len(activities)), 'course_id': pk, })
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 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 """ exos = [] for pl in activity.indexed_pl(): exos.append({'name': pl.json['title'], 'sum_grades': 0}) for state in list(State)[0:-1]: exos[-1][state] = 0 student = list() for user in activity.student.all(): tp = list() for count, pl in enumerate(activity.indexed_pl()): ans_grade = Answer.highest_grade(pl, user) state = State.by_grade(ans_grade.grade if ans_grade else ...) tp.append({'name': pl.json['title'], 'state': state}) if state != State.ERROR: exos[count][state] += 1 if ans_grade and ans_grade.grade is not None: exos[count]['sum_grades'] += ans_grade.grade student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'question': tp, }) for exo in exos: exo['mean'] = exo['sum_grades'] / len(student) if student else 0 exo.pop('sum_grades') # 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, 'exos': exos, })
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': 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 course_summary(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.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.") activities = course.activity.all().order_by("id") student = list() for user in course.user.all(): tp = list() for activity in activities: tp.append({ 'state': Answer.pltp_summary(activity.pltp, user), 'name': json.loads(activity.pltp.json)['title'], 'activity_name': activity.name, }) student.append({ 'lastname': user.last_name, 'name': user.get_full_name(), 'id': user.id, 'activities': tp, }) #Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'classmanagement/course_summary.html', { 'name': course.name, 'student': student, 'range_tp': range(len(activities)), 'course_id': 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 template(self, request, activity, session): if not activity.open: return self.end(activity, session) if request.method == 'GET': action = request.GET.get("action") if action == "pl": pl_id = request.GET.get("pl_id") if not pl_id or not pl_id.isdigit(): return HttpResponseBadRequest( "Missing/invalid parameter 'pl_id'") session.current_pl = get_object_or_404(PL, id=pl_id) session.save() elif action == "home": session.current_pl = None session.save() elif session.current_pl and action == "reset": Answer.objects.create(user=request.user, pl=session.current_pl) elif session.current_pl and action == "reroll": exercise = session.session_exercise() exercise.built = False exercise.seed = None exercise.save() if action: # Remove get arguments from URL return redirect(reverse("activity:play", args=[activity.id])) if session.current_pl: last = Answer.last(session.current_pl, request.user) Answer.objects.create(user=request.user, pl=session.current_pl, answers=last.answers if last else {}) return render(request, 'activity/activity_type/pltp/exercise.html', self.get_context(activity, session, request))
def __init__(self, request, activity, pl=None): self.dic = { 'activity_name__': activity.name, 'activity_id__': activity.id, 'pltp_name__': activity.pltp.name, 'pltp_title__': activity.pltp.json["title"], 'pltp_sha1__': activity.pltp.sha1, } if pl: seed = Answer.last_seed(pl, request.user) if 'oneshot' in pl.json or not seed: seed = time.time() self.dic.update({ 'pl_id__': pl.id, 'pl_name__': pl.name, 'seed': float(seed), }) self.dic.update(pl.json) else: self.dic.update(activity.pltp.json)