Esempio n. 1
0
def list_exercise_submissions(request, exercise_id):
    """
    This view lists all submissions for a given exercise. The view can only be accessed
    by course staff, meaning the teachers and assistants of the course.
    
    @param exercise_id: the ID of the exercise which the submissions are for
    """
    exercise = get_object_or_404(BaseExercise, id=exercise_id)
    has_permission = exercise.get_course_instance().is_staff(
        request.user.get_profile())

    if not has_permission:
        return HttpResponseForbidden(
            "You are not allowed to access this view.")

    submissions = exercise.submissions.all()

    return render_to_response(
        "exercise/exercise_submissions.html",
        CourseContext(
            request,
            submissions=submissions,
            exercise=exercise,
            course_instance=exercise.course_module.course_instance,
        ))
Esempio n. 2
0
def add_or_edit_assignment(request, module_id):
    """
    This page can be used by teachers to add new 
    modules and edit existing ones.

    @param request: the Django HttpRequest object
    """
    course_module = CourseModule.objects.get(id=module_id)
    #course_books = []
    assignment = None
    #retrieve books
    book =  Books.objects.filter(courses=course_module.course_instance)[0]

    if Assignments.objects.filter(course_module=course_module).count()>0:
        assignment = get_object_or_404(Assignments, \
                                       course_module=course_module)
    if request.method == "POST":
        form = AssignmentForm(request.POST, instance=assignment)
        if form.is_valid():
            assignment = form.save()
            messages.success(request, \
                           _('The assignment module was saved successfully.'))
    else:
        if not assignment:
            assignment = Assignments(course_module = course_module, assignment_book = book)
        form = AssignmentForm(instance=assignment)
    return render_to_response("course/set_exercises.html",
                              CourseContext(request, course_instance = \
                                                course_module.course_instance,
                                                module=course_module,
                                                form=form,
                                                book_name = book.book_name
                                             ))
Esempio n. 3
0
def class_students(request, module_id):
    """
    View which aloow the instructor to edit student's information
    """
    course_module = CourseModule.objects.get(id=module_id)
    course_books = []
    course_books =  list(Books.objects.filter(courses = \
                                              course_module.course_instance))
    book = course_books[0]
    qs0 =  UserBook.objects.prefetch_related('user').filter(book = \
                                             book).order_by('user__username') 

    studentsFormSet = modelformset_factory(UserBook, form=StudentsForm, \
                                                                 extra=0)
    if request.method == "POST":
        formset = studentsFormSet(request.POST, queryset = qs0)
        if formset.is_valid():
            formset.save()
            messages.success(request, \
                     _('Students information were saved successfully.'))
    else:
        formset = studentsFormSet(queryset = qs0)
    return render_to_response("course/edit_students.html",
                              CourseContext(request, \
                              course_instance=course_module.course_instance,
                                                     module=course_module,
                                                     formset=formset
                                             ))
Esempio n. 4
0
def course_archive(request):
    """ 
    Displays a course archive of all courses in the system.
    """

    context = CourseContext(request)
    return render_to_response("course/archive.html", context)
Esempio n. 5
0
def add_or_edit_exercise(request, module_id, exercise_id=None):
    """ 
    This page can be used by teachers to add new exercises and edit existing ones.
    """
    module = get_object_or_404(CourseModule, id=module_id)
    course_instance = module.course_instance

    has_permission = course_instance.is_teacher(request.user.get_profile())

    if not has_permission:
        return HttpResponseForbidden(
            "You are not allowed to access this view.")

    if exercise_id != None:
        exercise = get_object_or_404(module.learning_objects,
                                     id=exercise_id).as_leaf_class()
    else:
        exercise = BaseExercise(course_module=module)

    if request.method == "POST":
        form = BaseExerciseForm(request.POST, instance=exercise)
        if form.is_valid():
            exercise = form.save()
            messages.success(request,
                             _('The exercise was saved successfully.'))
    else:
        form = BaseExerciseForm(instance=exercise)

    return render_to_response(
        "exercise/edit_exercise.html",
        CourseContext(request,
                      course_instance=course_instance,
                      exercise=exercise,
                      form=form))
Esempio n. 6
0
def delete_assignment(request, module_id):
    """
    This page can be used by teachers to delete existing assignments.

    @param request: the Django HttpRequest object
    """
    
    course_module = CourseModule.objects.get(id=module_id)
  
    assignment = None
    if Assignments.objects.filter(course_module = course_module).count()>0: 
        assignment = Assignments.objects.filter(course_module=course_module)[0]
    #retrieve books
    book =  Books.objects.filter(courses=course_module.course_instance)[0]

    #create redirection url that is the teachers' view
    next_url = "/course/%s/%s/teachers/" % ( \
                       course_module.course_instance.course.url, \
                       course_module.course_instance.url)

    if Assignments.objects.filter(course_module = course_module).count()>0:
        assignment = get_object_or_404(Assignments, course_module = \
                                                    course_module)

    if Assignments.objects.filter(assignment_book = book).count() == 1:
        messages.warning(request, \
                 _('There should be at least one assignment in the course.'))
        return HttpResponseRedirect(next_url)
    if request.method == "POST":
        form = DelAssignmentForm(request.POST, instance=assignment)
        if form.is_valid():
            assignment.delete()
            course_module.delete()
            messages.success(request, \
                         _('The assignment module was deleted successfully.'))
            return HttpResponseRedirect(next_url)
        else:
            if assignment is not None:
                assignment.delete()
            if course_module is not None:  
                course_module.delete()

            messages.success(request, \
                         _('The assignment module was deleted successfully.'))
            return HttpResponseRedirect(next_url)  
    else:
        if not assignment:
            assignment = Assignments(course_module = course_module)
        form = DelAssignmentForm(instance=assignment)


    return render_to_response("opendsa/edit_assignments.html",
                              CourseContext(request, course_instance = \
                                            course_module.course_instance, \
                                            module=course_module, \
                                            form=form, \
                                             ))
Esempio n. 7
0
def view_course(request, course_url):
    """ 
    Displays a page for the given course. The page consists of a list of
    course instances for the course. 
    
    @param request: the Django HttpRequest object
    @param course_url: the url value of a Course object 
    """

    course = get_object_or_404(Course, url=course_url)
    context = CourseContext(request, course=course)
    return render_to_response("course/view.html", context)
Esempio n. 8
0
def view_exercise(request, exercise_id):
    """ 
    Displays a particular exercise. If the exercise is requested with a HTTP POST request, 
    the view will try to submit the exercise to the exercise service. 
    
    @param request: HttpRequest from Django
    @param exercise_id: the id of the exercise model to display 
    """

    # Load the exercise as an instance of its leaf class
    exercise = get_object_or_404(BaseExercise, id=exercise_id).as_leaf_class()
    students = StudentGroup.get_students_from_request(request)
    submissions = exercise.get_submissions_for_student(
        request.user.get_profile())
    is_post = request.method == "POST"

    is_allowed, issues = exercise.is_submission_allowed(students)

    for error in issues:
        messages.warning(request, error)

    # FIXME: remove support for custom forms
    form = None

    if is_post and is_allowed:
        # This is a successful submission, so we handle submitting the form
        return _handle_submission(request, exercise, students, form,
                                  submissions)

    try:
        # Try retrieving the exercise page
        submission_url = exercise.get_submission_url_for_students(students)
        page = exercise.get_page(submission_url)

    except Exception as e:
        # Retrieving page failed, create an empty page and display an error
        # TODO: an error report should be sent or logged
        page = ExercisePage(exercise=exercise)
        messages.error(
            request,
            _('Connecting to the exercise service failed: %s.') % str(e))

    exercise_summary = ExerciseSummary(exercise, request.user)

    return render_to_response(
        "exercise/view_exercise.html",
        CourseContext(request,
                      exercise=exercise,
                      course_instance=exercise.course_module.course_instance,
                      page=page,
                      form=form,
                      submissions=submissions,
                      exercise_summary=exercise_summary))
Esempio n. 9
0
def submission_assessment(request, submission_id):
    """
    This view is used for assessing the given exercise submission. When assessing,
    the teacher or assistant may write verbal feedback and give a numeric grade for
    the submission.
    
    @param submission_id: the ID of the submission to assess
    """
    submission = get_object_or_404(Submission, id=submission_id)
    exercise = submission.exercise

    if exercise.allow_assistant_grading:
        # Both the teachers and assistants are allowed to assess
        has_permission = exercise.get_course_instance().is_staff(
            request.user.get_profile())
    else:
        # Only teacher is allowed to assess
        has_permission = exercise.get_course_instance().is_teacher(
            request.user.get_profile())

    if not has_permission:
        return HttpResponseForbidden(
            _("You are not allowed to access this view."))

    form = SubmissionReviewForm()
    if request.method == "POST":
        form = SubmissionReviewForm(request.POST)
        if form.is_valid():
            try:
                submission.set_points(form.cleaned_data["points"],
                                      exercise.max_points)
                submission.grader = request.user.get_profile()
                submission.feedback = form.cleaned_data["feedback"]
                submission.set_ready()
                submission.save()
                messages.success(request,
                                 _("The review was saved successfully."))
                return redirect(inspect_exercise_submission,
                                submission_id=submission.id)
            except:
                messages.error(
                    request,
                    _("Saving review failed. Check that the grade is within allowed boundaries."
                      ))

    return render_to_response(
        "exercise/submission_assessment.html",
        CourseContext(request,
                      course_instance=exercise.get_course_instance(),
                      exercise=exercise,
                      submission=submission,
                      form=form))
Esempio n. 10
0
def upload_accounts(request, module_id):
    """
     Views responsible of creating students accounts
     the instructor upload his course roaster
     An email is sent to each student 
    """

    course_module = CourseModule.objects.get(id=module_id)
    book =  Books.objects.filter(courses=course_module.course_instance)[0]

    form = None
    if request.method == 'POST':
        form = AccountsUploadForm(request.POST, request.FILES)
        #current_user = request.user
        if form.is_valid():
                account_created = 0
            #with open(request.FILES['classfile'], 'rb') as csvfile:
                csvfile = request.FILES['classfile']
                listreader = csv.reader(csvfile.read().splitlines())  #, delimiter=',', quotechar='|')
                for row in listreader:
                    username = row[0]
                    email = row[1]
                    password = id_generator()
                    if User.objects.filter(username=username).count()==0:
                        User.objects.create_user( username, email, password)
                        account_created = account_created + 1
                        #send notification email
                        subject = '[OpenDSA] account created'
                        message = 'Your OpenDSA account has been  created for the Book instance at %s.\n\n\n username: %s\n password:%s' %(book.book_url,username, password)
                        send_mail(subject, message, '*****@*****.**', [email], fail_silently=False)


                messages.success(request, \
                           _('%s account(s) created successfully.' %account_created))

    else:
        form = AccountsUploadForm()


    return render_to_response("opendsa/studentsupload.html",
                              CourseContext(request, course_instance = \
                                            course_module.course_instance, \
                                            module=course_module, \
                                            form=form, \
                                             ))
Esempio n. 11
0
def assistants_view(request, course_url, instance_url):
    """ 
    This is the special page for the assistants on the given course instance.
    
    @param request: the Django HttpRequest object
    @param course_url: the url value of a Course object
    @param instance_url: the url value of a CourseInstance object 
    """
    course_instance = _get_course_instance(course_url, instance_url)

    has_permission = course_instance.is_staff(request.user.get_profile())
    if not has_permission:
        return HttpResponseForbidden(
            _("You are not allowed to access this view."))

    return render_to_response(
        "course/assistants_view.html",
        CourseContext(request, course_instance=course_instance))
Esempio n. 12
0
def view_instance(request, course_url, instance_url):
    """ Renders a dashboard page for a course instance. A dashboard has a list
        of exercise rounds and exercises and plugins that may have been 
        installed on the course. Students also see a summary of their progress
        on the course dashboard.
        
        @param request: the Django HttpRequest object
        @param course_url: the url value of a Course object
        @param instance_url: the url value of a CourseInstance object """

    course_instance = _get_course_instance(course_url, instance_url)
    course_summary = CourseSummary(course_instance, request.user)
    course_instance.plugins.all()

    return render_to_response(
        "course/view_instance.html",
        CourseContext(request,
                      course_instance=course_instance,
                      course_summary=course_summary))
Esempio n. 13
0
def add_or_edit_module(request, course_url, instance_url, module_id=None):
    """ 
    This page can be used by teachers to add new modules and edit existing ones.
    
    @param request: the Django HttpRequest object
    @param course_url: the url value of a Course object
    @param instance_url: the url value of a CourseInstance object
    @param module_id: The id of the module to edit. If not given, a new module is created. 
    """
    course_instance = _get_course_instance(course_url, instance_url)
    has_permission = course_instance.is_teacher(request.user.get_profile())

    if not has_permission:
        return HttpResponseForbidden(
            "You are not allowed to access this view.")

    if module_id != None:
        module = get_object_or_404(CourseModule,
                                   id=module_id,
                                   course_instance=course_instance)
    else:
        module = CourseModule(course_instance=course_instance)

    if request.method == "POST":
        form = CourseModuleForm(request.POST, instance=module)
        if form.is_valid():
            module = form.save()
            messages.success(request,
                             _('The course module was saved successfully.'))
            next_url = "/course/%s/%s/teachers/" % (course_instance.course.url,
                                                    course_instance.url)
            return HttpResponseRedirect(next_url)
    else:
        form = CourseModuleForm(instance=module)

    return render_to_response(
        "course/edit_module.html",
        CourseContext(request,
                      course_instance=course_instance,
                      module=module,
                      form=form))
Esempio n. 14
0
def create_accounts(request, module_id):
    """
     Views responsible of creating students accounts
     An email is sent to the course teachers at 
     the end of the process
    """

    course_module = CourseModule.objects.get(id=module_id)

    form = None
    if request.method == 'POST':
        form = AccountsCreationForm(request.POST)
        current_user = request.user
        account_created = 0
        roster = 'username,password\n'
        if form.is_valid():
            for x in range(0, form.cleaned_data['account_number']):
                username = form.cleaned_data['account_prefix'] + str(x)
                password = id_generator()
                if User.objects.filter(username=username).count()==0:
                    User.objects.create_user( username, '', password)
                    account_created = account_created + 1
                    roster = roster + username + ',' + password + '\n'
            messages.success(request, \
                           _('%s account(s) created successfully. The roster has been emailed to %s.' %(account_created, current_user.email)))
            #send notification email
            subject = '[OpenDSA] Students accounts created'
            message = 'List of accounts created.\n\n\n\n' + roster
            send_mail(subject, message, '*****@*****.**', [current_user.email], fail_silently=False)

    else:
        form = AccountsCreationForm()


    return render_to_response("opendsa/studentsaccounts.html",
                              CourseContext(request, course_instance = \
                                            course_module.course_instance, \
                                            module=course_module, \
                                            form=form, \
                                             ))
Esempio n. 15
0
def view_instance_results(request, course_url, instance_url):
    """ 
    Renders a results page for a course instance. The results contain individual
    scores for each student on each exercise.
    
    @param request: the Django HttpRequest object
    @param course_url: the url value of a Course object
    @param instance_url: the url value of a CourseInstance object 
    """

    course_instance = _get_course_instance(course_url, instance_url)
    table = ResultTable(course_instance)

    table_html = loader.render_to_string("course/_results_table.html",
                                         {"result_table": table})

    return render_to_response(
        "course/view_results.html",
        CourseContext(request,
                      course_instance=course_instance,
                      result_table=table,
                      table_html=table_html))
Esempio n. 16
0
def view_submission(request, submission_id):
    # Find all submissions for this user
    submission = get_object_or_404(Submission, id=submission_id)
    exercise = submission.exercise
    submissions = exercise.get_submissions_for_student(
        request.user.get_profile())
    index = 1 + list(submissions).index(submission)

    # TODO: Check the user's permission to view this submission more elegantly
    assert submission.check_user_permission(request.user.get_profile())

    exercise_summary = ExerciseSummary(exercise, request.user)

    return render_to_response(
        "exercise/view_submission.html",
        CourseContext(request,
                      submission=submission,
                      exercise=submission.exercise,
                      course_instance=exercise.course_module.course_instance,
                      submissions=submissions,
                      submission_number=index,
                      exercise_summary=exercise_summary))
Esempio n. 17
0
def view_my_page(request, course_url, instance_url):
    """ 
    Renders a personalized page for a student on the course. The page is intended to show 
    how well the student is doing on the course and shortcuts to the latest submissions.
    
    @param request: the Django HttpRequest object
    @param course_url: the url value of a Course object
    @param instance_url: the url value of a CourseInstance object 
    """

    course_instance = _get_course_instance(course_url, instance_url)
    course_summary = CourseSummary(course_instance, request.user)
    submissions = request.user.get_profile().submissions.filter(
        exercise__course_module__course_instance=course_instance).order_by(
            "-id")

    return render_to_response(
        "course/view_my_page.html",
        CourseContext(request,
                      course_instance=course_instance,
                      course_summary=course_summary,
                      submissions=submissions))
Esempio n. 18
0
def inspect_exercise_submission(request, submission_id):
    """
    This is the view for course personnel for inspecting and manually assessing
    exercise submissions. To access this view, the user must be either an assistant
    or a teacher on the course where the exercise is held on.
    
    @param submission_id: the ID of the submission to be inspected
    """
    submission = get_object_or_404(Submission, id=submission_id)
    exercise = submission.exercise
    has_permission = exercise.get_course_instance().is_staff(
        request.user.get_profile())

    if not has_permission:
        return HttpResponseForbidden(
            "You are not allowed to access this view.")

    return render_to_response(
        "exercise/inspect_submission.html",
        CourseContext(request,
                      submission=submission,
                      exercise=exercise,
                      course_instance=exercise.get_course_instance()))
Esempio n. 19
0
        new_submission.delete()

        exercise_summary = ExerciseSummary(exercise, request.user)
        instance = exercise.course_module.course_instance

        # Add a message to the user's message queue
        messages.warning(
            request,
            _('The exercise could not be graded. Please check the page below for errors.'
              ))
        return render_to_response(
            "exercise/view_exercise.html",
            CourseContext(request,
                          exercise=exercise,
                          course_instance=instance,
                          page=response_page,
                          form=form,
                          submissions=submissions,
                          exercise_summary=exercise_summary))


@login_required
def view_submission(request, submission_id):
    # Find all submissions for this user
    submission = get_object_or_404(Submission, id=submission_id)
    exercise = submission.exercise
    submissions = exercise.get_submissions_for_student(
        request.user.get_profile())
    index = 1 + list(submissions).index(submission)

    # TODO: Check the user's permission to view this submission more elegantly