Example #1
0
def handle_enrollment_request(course, user, status, roles, request=None):
    # type: (Course, Any, Text, List[Text], Optional[http.HttpRequest]) -> Participation  # noqa
    participations = Participation.objects.filter(course=course, user=user)

    assert participations.count() <= 1
    if participations.count() == 0:
        participation = Participation()
        participation.user = user
        participation.course = course
        participation.status = status
        participation.save()

        if roles is not None:
            participation.roles.set(roles)
    else:
        (participation, ) = participations
        participation.status = status
        participation.save()

    if status == participation_status.active:
        send_enrollment_decision(participation, True, request)
    elif status == participation_status.denied:
        send_enrollment_decision(participation, False, request)

    return participation
Example #2
0
def handle_enrollment_request(course, user, status, roles, request=None):
    # type: (Course, Any, Text, List[Text], Optional[http.HttpRequest]) -> Participation  # noqa
    participations = Participation.objects.filter(course=course, user=user)

    assert participations.count() <= 1
    if participations.count() == 0:
        participation = Participation()
        participation.user = user
        participation.course = course
        participation.status = status
        participation.save()

        if roles is not None:
            participation.roles.set(roles)
    else:
        (participation,) = participations
        participation.status = status
        participation.save()

    if status == participation_status.active:
        send_enrollment_decision(participation, True, request)
    elif status == participation_status.denied:
        send_enrollment_decision(participation, False, request)

    return participation
Example #3
0
    def enroll(status, role):
        participations = Participation.objects.filter(course=course, user=user)

        assert participations.count() <= 1
        if participations.count() == 0:
            participation = Participation()
            participation.user = user
            participation.course = course
            participation.role = role
            participation.status = status
            participation.save()
        else:
            (participation,) = participations
            participation.status = status
            participation.save()

        return participation
Example #4
0
def handle_enrollment_request(course, user, status, role, request=None):
    participations = Participation.objects.filter(course=course, user=user)

    assert participations.count() <= 1
    if participations.count() == 0:
        participation = Participation()
        participation.user = user
        participation.course = course
        participation.role = role
        participation.status = status
        participation.save()
    else:
        (participation,) = participations
        participation.status = status
        participation.save()

    if status == participation_status.active:
        send_enrollment_decision(participation, True, request)
    elif status == participation_status.denied:
        send_enrollment_decision(participation, False, request)
    else:
        return
Example #5
0
    def setUpTestData(cls):  # noqa
        super(CoursesTestMixinBase, cls).setUpTestData()
        cls.n_courses = 0
        for course_setup in cls.courses_setup_list:
            if "course" not in course_setup:
                continue

            cls.n_courses += 1
            course_identifier = course_setup["course"]["identifier"]
            cls.remove_exceptionally_undelete_course_repos(course_identifier)
            cls.create_course(**course_setup["course"])
            course = Course.objects.get(identifier=course_identifier)
            if "participations" in course_setup:
                for participation in course_setup["participations"]:
                    create_user_kwargs = participation.get("user")
                    if not create_user_kwargs:
                        continue
                    role_identifier = participation.get("role_identifier")
                    if not role_identifier:
                        continue
                    cls.create_participation(
                        course=course,
                        create_user_kwargs=create_user_kwargs,
                        role_identifier=role_identifier,
                        status=participation.get("status",
                                                 participation_status.active))

                    # Remove superuser from participation for further test
                    # such as impersonate in auth module
                    if role_identifier == "instructor":
                        try:
                            superuser_participation = (
                                Participation.objects.get(user=cls.superuser))
                            Participation.delete(superuser_participation)
                        except Participation.DoesNotExist:
                            pass
        cls.course_qset = Course.objects.all()
Example #6
0
    def do_quiz(cls, user, assign_role=None):
        # Login user first
        cls.c.logout()
        cls.c.login(
                    username=user.username,
                    password="******")

        # Enroll if not admin
        # Little hacky for not using enrollment view
        if assign_role:
            participation = Participation()
            participation.user = user
            participation.course = Course.objects.filter(
                                    identifier=cls.datas["course_identifier"])[0]
            participation.status = "active"
            participation.save()

            if assign_role == "student":
                role = ParticipationRole.objects.filter(id=3)[0]
            elif assign_role == "ta":
                role = ParticipationRole.objects.filter(id=2)[0]
            participation.roles.add(role)

        params = cls.datas.copy()
        del params["flow_session_id"]
        resp = cls.c.post(reverse("relate-view_start_flow", kwargs=params))

        # Yep, no regax!
        _, _, kwargs = resolve(resp.url)
        # Store flow_session_id
        cls.datas["flow_session_id"].append(int(kwargs["flow_session_id"]))

        # Let it raise error
        # Use pop() will not
        del kwargs["ordinal"]
        resp = cls.c.post(reverse("relate-finish_flow_session_view",
                                kwargs=kwargs), {'submit': ['']})
Example #7
0
def edit_participation(pctx, participation_id):
    # type: (CoursePageContext, int) -> http.HttpResponse
    if not pctx.has_permission(pperm.edit_participation):
        raise PermissionDenied()

    request = pctx.request

    num_participation_id = int(participation_id)

    if num_participation_id == -1:
        participation = Participation(course=pctx.course,
                                      status=participation_status.active)
        add_new = True
    else:
        participation = get_object_or_404(Participation,
                                          id=num_participation_id)
        add_new = False

    if participation.course.id != pctx.course.id:
        raise SuspiciousOperation(
            "may not edit participation in different course")

    if request.method == 'POST':
        form = EditParticipationForm(add_new,
                                     pctx,
                                     request.POST,
                                     instance=participation)
        reset_form = False

        try:
            if form.is_valid():
                if "submit" in request.POST:
                    form.save()

                    messages.add_message(request, messages.SUCCESS,
                                         _("Changes saved."))

                elif "approve" in request.POST:
                    send_enrollment_decision(participation, True, pctx.request)

                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.active
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                                         _("Successfully enrolled."))

                elif "deny" in request.POST:
                    send_enrollment_decision(participation, False,
                                             pctx.request)

                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.denied
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                                         _("Successfully denied."))

                elif "drop" in request.POST:
                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.dropped
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                                         _("Successfully dropped."))
        except IntegrityError as e:
            messages.add_message(
                request, messages.ERROR,
                _("A data integrity issue was detected when saving "
                  "this participation. Maybe a participation for "
                  "this user already exists? (%s)") % str(e))

        if reset_form:
            form = EditParticipationForm(add_new, pctx, instance=participation)
    else:
        form = EditParticipationForm(add_new, pctx, instance=participation)

    return render_course_page(pctx, "course/generic-course-form.html", {
        "form_description": _("Edit Participation"),
        "form": form
    })
Example #8
0
    def enroll(status, role):
        participations = Participation.objects.filter(course=course, user=user)

        assert participations.count() <= 1
        if participations.count() == 0:
            participation = Participation()
            participation.user = user
            participation.course = course
            participation.role = role
            participation.status = status
            participation.save()
        else:
            (participation, ) = participations
            participation.status = status
            participation.save()

        return participation
Example #9
0
def set_up_new_course(request):
    if not request.user.is_staff:
        raise PermissionDenied(_("only staff may create courses"))

    if request.method == "POST":
        form = CourseCreationForm(request.POST)

        if form.is_valid():
            new_course = form.save(commit=False)

            from course.content import get_course_repo_path
            repo_path = get_course_repo_path(new_course)

            try:
                import os
                os.makedirs(repo_path)

                repo = None

                try:
                    with transaction.atomic():
                        from dulwich.repo import Repo
                        repo = Repo.init(repo_path)

                        client, remote_path = \
                            get_dulwich_client_and_remote_path_from_course(
                                    new_course)

                        remote_refs = client.fetch(remote_path, repo)
                        transfer_remote_refs(repo, remote_refs)
                        new_sha = repo[b"HEAD"] = remote_refs[b"HEAD"]

                        vrepo = repo
                        if new_course.course_root_path:
                            from course.content import SubdirRepoWrapper
                            vrepo = SubdirRepoWrapper(
                                    vrepo, new_course.course_root_path)

                        from course.validation import validate_course_content
                        validate_course_content(
                                vrepo, new_course.course_file,
                                new_course.events_file, new_sha)

                        del repo
                        del vrepo

                        new_course.active_git_commit_sha = new_sha.decode()
                        new_course.save()

                        # {{{ set up a participation for the course creator

                        part = Participation()
                        part.user = request.user
                        part.course = new_course
                        part.role = participation_role.instructor
                        part.status = participation_status.active
                        part.save()

                        # }}}

                        messages.add_message(request, messages.INFO,
                                _("Course content validated, creation "
                                "succeeded."))
                except:
                    # Don't coalesce this handler with the one below. We only want
                    # to delete the directory if we created it. Trust me.

                    # Work around read-only files on Windows.
                    # https://docs.python.org/3.5/library/shutil.html#rmtree-example

                    import os
                    import stat
                    import shutil

                    # Make sure files opened for 'repo' above are actually closed.
                    if repo is not None:  # noqa
                        repo.close()  # noqa

                    def remove_readonly(func, path, _):  # noqa
                        "Clear the readonly bit and reattempt the removal"
                        os.chmod(path, stat.S_IWRITE)
                        func(path)

                    try:
                        shutil.rmtree(repo_path, onerror=remove_readonly)
                    except OSError:
                        messages.add_message(request, messages.WARNING,
                                ugettext("Failed to delete unused "
                                "repository directory '%s'.")
                                % repo_path)

                    raise

            except Exception as e:
                from traceback import print_exc
                print_exc()

                messages.add_message(request, messages.ERROR,
                        string_concat(
                            _("Course creation failed"),
                            ": %(err_type)s: %(err_str)s")
                        % {"err_type": type(e).__name__,
                            "err_str": str(e)})
            else:
                return redirect(
                        "relate-course_page",
                        new_course.identifier)

    else:
        form = CourseCreationForm()

    return render(request, "generic-form.html", {
        "form_description": _("Set up new course"),
        "form": form
        })
Example #10
0
def set_up_new_course(request):
    if not request.user.is_staff:
        raise PermissionDenied("only staff may create courses")

    if request.method == "POST":
        form = CourseCreationForm(request.POST)

        if form.is_valid():
            new_course = form.save(commit=False)

            from course.content import get_course_repo_path
            repo_path = get_course_repo_path(new_course)

            try:
                import os
                os.makedirs(repo_path)

                try:
                    with transaction.atomic():
                        from dulwich.repo import Repo
                        repo = Repo.init(repo_path)

                        client, remote_path = \
                            get_dulwich_client_and_remote_path_from_course(
                                    new_course)

                        remote_refs = client.fetch(remote_path, repo)
                        new_sha = repo["HEAD"] = remote_refs["HEAD"]

                        from course.validation import validate_course_content
                        validate_course_content(
                                repo, new_course.course_file,
                                new_course.events_file, new_sha)

                        new_course.valid = True
                        new_course.active_git_commit_sha = new_sha
                        new_course.save()

                        # {{{ set up a participation for the course creator

                        part = Participation()
                        part.user = request.user
                        part.course = new_course
                        part.role = participation_role.instructor
                        part.status = participation_status.active
                        part.save()

                        # }}}

                        messages.add_message(request, messages.INFO,
                                "Course content validated, creation succeeded. "
                                "You may want to view the events used "
                                "in the course content and create them. "
                                + '<a href="%s" class="btn btn-primary">'
                                'Check &raquo;</a>'
                                % reverse("course.calendar.check_events",
                                    args=(new_course.identifier,)))
                except:
                    # Don't coalesce this handler with the one below. We only want
                    # to delete the directory if we created it. Trust me.
                    import shutil
                    shutil.rmtree(repo_path)
                    raise

            except Exception as e:
                from traceback import print_exc
                print_exc()

                messages.add_message(request, messages.ERROR,
                        "Course creation failed: %s: %s" % (
                            type(e).__name__, str(e)))
            else:
                return redirect(
                        "course.views.course_page",
                        new_course.identifier)

    else:
        form = CourseCreationForm()

    return render(request, "generic-form.html", {
        "form_description": "Set up new course",
        "form": form
        })
Example #11
0
def set_up_new_course(request):
    # type: (http.HttpRequest) -> http.HttpResponse
    if request.method == "POST":
        form = CourseCreationForm(request.POST)

        if form.is_valid():
            new_course = form.save(commit=False)

            from course.content import get_course_repo_path
            repo_path = get_course_repo_path(new_course)

            try:
                import os
                os.makedirs(repo_path)

                repo = None

                try:
                    with transaction.atomic():
                        repo = Repo.init(repo_path)

                        client, remote_path = \
                            get_dulwich_client_and_remote_path_from_course(
                                    new_course)

                        remote_refs = client.fetch(remote_path, repo)
                        if remote_refs is None:
                            raise RuntimeError(
                                _("No refs found in remote repository"
                                  " (i.e. no master branch, no HEAD). "
                                  "This looks very much like a blank repository. "
                                  "Please create course.yml in the remote "
                                  "repository before creating your course."))

                        transfer_remote_refs(repo, remote_refs)
                        new_sha = repo[b"HEAD"] = remote_refs[b"HEAD"]

                        vrepo = repo
                        if new_course.course_root_path:
                            from course.content import SubdirRepoWrapper
                            vrepo = SubdirRepoWrapper(
                                vrepo, new_course.course_root_path)

                        from course.validation import validate_course_content
                        validate_course_content(  # type: ignore
                            vrepo, new_course.course_file,
                            new_course.events_file, new_sha)

                        del vrepo

                        new_course.active_git_commit_sha = new_sha.decode()
                        new_course.save()

                        # {{{ set up a participation for the course creator

                        part = Participation()
                        part.user = request.user
                        part.course = new_course
                        part.status = participation_status.active
                        part.save()

                        part.roles.set([
                            # created by signal handler for course creation
                            ParticipationRole.objects.get(
                                course=new_course, identifier="instructor")
                        ])

                        # }}}

                        messages.add_message(
                            request, messages.INFO,
                            _("Course content validated, creation "
                              "succeeded."))
                except:
                    # Don't coalesce this handler with the one below. We only want
                    # to delete the directory if we created it. Trust me.

                    # Work around read-only files on Windows.
                    # https://docs.python.org/3.5/library/shutil.html#rmtree-example

                    import os
                    import stat
                    import shutil

                    # Make sure files opened for 'repo' above are actually closed.
                    if repo is not None:  # noqa
                        repo.close()  # noqa

                    def remove_readonly(func, path, _):  # noqa
                        "Clear the readonly bit and reattempt the removal"
                        os.chmod(path, stat.S_IWRITE)
                        func(path)

                    try:
                        shutil.rmtree(repo_path, onerror=remove_readonly)
                    except OSError:
                        messages.add_message(
                            request, messages.WARNING,
                            ugettext("Failed to delete unused "
                                     "repository directory '%s'.") % repo_path)

                    raise

            except Exception as e:
                from traceback import print_exc
                print_exc()

                messages.add_message(
                    request, messages.ERROR,
                    string_concat(_("Course creation failed"),
                                  ": %(err_type)s: %(err_str)s") % {
                                      "err_type": type(e).__name__,
                                      "err_str": str(e)
                                  })
            else:
                return redirect("relate-course_page", new_course.identifier)

    else:
        form = CourseCreationForm()

    return render(request, "generic-form.html", {
        "form_description": _("Set up new course"),
        "form": form
    })
Example #12
0
def handle_enrollment_request(course, user, status, role, request=None):
    participations = Participation.objects.filter(course=course, user=user)

    assert participations.count() <= 1
    if participations.count() == 0:
        participation = Participation()
        participation.user = user
        participation.course = course
        participation.role = role
        participation.status = status
        participation.save()
    else:
        (participation, ) = participations
        participation.status = status
        participation.save()

    if status == participation_status.active:
        send_enrollment_decision(participation, True, request)
    elif status == participation_status.denied:
        send_enrollment_decision(participation, False, request)
    else:
        return
Example #13
0
def edit_participation(pctx, participation_id):
    # type: (CoursePageContext, int) -> http.HttpResponse
    if not pctx.has_permission(pperm.edit_participation):
        raise PermissionDenied()

    request = pctx.request

    num_participation_id = int(participation_id)

    if num_participation_id == -1:
        participation = Participation(
                course=pctx.course,
                status=participation_status.active)
        add_new = True
    else:
        participation = get_object_or_404(Participation, id=num_participation_id)
        add_new = False

    if participation.course.id != pctx.course.id:
        raise SuspiciousOperation("may not edit participation in different course")

    if request.method == 'POST':
        form = EditParticipationForm(
                add_new, pctx, request.POST, instance=participation)
        reset_form = False

        try:
            if form.is_valid():
                if "submit" in request.POST:
                    form.save()

                    messages.add_message(request, messages.SUCCESS,
                            _("Changes saved."))

                elif "approve" in request.POST:
                    send_enrollment_decision(participation, True, pctx.request)

                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.active
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                            _("Successfully enrolled."))

                elif "deny" in request.POST:
                    send_enrollment_decision(participation, False, pctx.request)

                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.denied
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                            _("Successfully denied."))

                elif "drop" in request.POST:
                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.dropped
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                            _("Successfully dropped."))
        except IntegrityError as e:
            messages.add_message(request, messages.ERROR,
                    _("A data integrity issue was detected when saving "
                        "this participation. Maybe a participation for "
                        "this user already exists? (%s)")
                    % str(e))

        if reset_form:
            form = EditParticipationForm(
                    add_new, pctx, instance=participation)
    else:
        form = EditParticipationForm(add_new, pctx, instance=participation)

    return render_course_page(pctx, "course/generic-course-form.html", {
        "form_description": _("Edit Participation"),
        "form": form
        })
Example #14
0
def set_up_new_course(request):
    if not request.user.is_staff:
        raise PermissionDenied("only staff may create courses")

    if request.method == "POST":
        form = CourseCreationForm(request.POST)

        if form.is_valid():
            new_course = form.save(commit=False)

            from course.content import get_course_repo_path
            repo_path = get_course_repo_path(new_course)

            try:
                import os
                os.makedirs(repo_path)

                try:
                    with transaction.atomic():
                        from dulwich.repo import Repo
                        repo = Repo.init(repo_path)

                        client, remote_path = \
                            get_dulwich_client_and_remote_path_from_course(
                                    new_course)

                        remote_refs = client.fetch(remote_path, repo)
                        new_sha = repo["HEAD"] = remote_refs["HEAD"]

                        from course.validation import validate_course_content
                        validate_course_content(
                                repo, new_course.course_file,
                                new_course.events_file, new_sha)

                        new_course.valid = True
                        new_course.active_git_commit_sha = new_sha
                        new_course.save()

                        # {{{ set up a participation for the course creator

                        part = Participation()
                        part.user = request.user
                        part.course = new_course
                        part.role = participation_role.instructor
                        part.status = participation_status.active
                        part.save()

                        # }}}

                        messages.add_message(request, messages.INFO,
                                "Course content validated, creation succeeded. "
                                "You may want to view the events used "
                                "in the course content and create them. "
                                + '<a href="%s" class="btn btn-primary">'
                                'Check &raquo;</a>'
                                % reverse("course.calendar.check_events",
                                    args=(new_course.identifier,)))
                except:
                    # Don't coalesce this handler with the one below. We only want
                    # to delete the directory if we created it. Trust me.
                    import shutil
                    shutil.rmtree(repo_path)
                    raise

            except Exception as e:
                from traceback import print_exc
                print_exc()

                messages.add_message(request, messages.ERROR,
                        "Course creation failed: %s: %s" % (
                            type(e).__name__, str(e)))
            else:
                return redirect(
                        "course.views.course_page",
                        new_course.identifier)

    else:
        form = CourseCreationForm()

    return render(request, "generic-form.html", {
        "form_description": "Set up new course",
        "form": form
        })
Example #15
0
def set_up_new_course(request):
    if not request.user.is_staff:
        raise PermissionDenied(_("only staff may create courses"))

    if request.method == "POST":
        form = CourseCreationForm(request.POST)

        if form.is_valid():
            new_course = form.save(commit=False)

            from course.content import get_course_repo_path
            repo_path = get_course_repo_path(new_course)

            try:
                import os
                os.makedirs(repo_path)

                try:
                    with transaction.atomic():
                        from dulwich.repo import Repo
                        repo = Repo.init(repo_path)

                        client, remote_path = \
                            get_dulwich_client_and_remote_path_from_course(
                                    new_course)

                        remote_refs = client.fetch(remote_path, repo)
                        new_sha = repo["HEAD"] = remote_refs["HEAD"]

                        vrepo = repo
                        if new_course.course_root_path:
                            from course.content import SubdirRepoWrapper
                            vrepo = SubdirRepoWrapper(
                                vrepo, new_course.course_root_path)

                        from course.validation import validate_course_content
                        validate_course_content(vrepo, new_course.course_file,
                                                new_course.events_file,
                                                new_sha)

                        del repo
                        del vrepo

                        new_course.valid = True
                        new_course.active_git_commit_sha = new_sha
                        new_course.save()

                        # {{{ set up a participation for the course creator

                        part = Participation()
                        part.user = request.user
                        part.course = new_course
                        part.role = participation_role.instructor
                        part.status = participation_status.active
                        part.save()

                        # }}}

                        messages.add_message(
                            request, messages.INFO,
                            _("Course content validated, creation "
                              "succeeded."))
                except:
                    # Don't coalesce this handler with the one below. We only want
                    # to delete the directory if we created it. Trust me.

                    # Work around read-only files on Windows.
                    # https://docs.python.org/3.5/library/shutil.html#rmtree-example

                    import os
                    import stat
                    import shutil

                    # Make sure files opened for 'repo' above are actually closed.
                    import gc
                    gc.collect()

                    def remove_readonly(func, path, _):  # noqa
                        "Clear the readonly bit and reattempt the removal"
                        os.chmod(path, stat.S_IWRITE)
                        func(path)

                    try:
                        shutil.rmtree(repo_path, onerror=remove_readonly)
                    except OSError:
                        messages.add_message(
                            request, messages.WARNING,
                            ugettext("Failed to delete unused "
                                     "repository directory '%s'.") % repo_path)

                    raise

            except Exception as e:
                from traceback import print_exc
                print_exc()

                messages.add_message(
                    request, messages.ERROR,
                    string_concat(_("Course creation failed"),
                                  ": %(err_type)s: %(err_str)s") % {
                                      "err_type": type(e).__name__,
                                      "err_str": str(e)
                                  })
            else:
                return redirect("relate-course_page", new_course.identifier)

    else:
        form = CourseCreationForm()

    return render(request, "generic-form.html", {
        "form_description": _("Set up new course"),
        "form": form
    })
Example #16
0
def edit_participation(pctx, participation_id):
    # type: (CoursePageContext, int) -> http.HttpResponse
    if not pctx.has_permission(pperm.edit_participation):
        raise PermissionDenied()

    request = pctx.request

    num_participation_id = int(participation_id)

    if num_participation_id == -1:
        participation = Participation(
                course=pctx.course,
                status=participation_status.active)
        add_new = True
    else:
        participation = get_object_or_404(Participation, id=num_participation_id)
        add_new = False

    if participation.course.id != pctx.course.id:
        raise SuspiciousOperation("may not edit participation in different course")

    if request.method == 'POST':
        form = None  # type: Optional[EditParticipationForm]

        if "submit" in request.POST:
            form = EditParticipationForm(
                    add_new, pctx, request.POST, instance=participation)

            if form.is_valid():  # type: ignore
                form.save()  # type: ignore
        elif "approve" in request.POST:

            send_enrollment_decision(participation, True, pctx.request)

            participation.status = participation_status.active
            participation.save()

            messages.add_message(request, messages.SUCCESS,
                    _("Successfully enrolled."))

        elif "deny" in request.POST:
            send_enrollment_decision(participation, False, pctx.request)

            participation.status = participation_status.denied
            participation.save()

            messages.add_message(request, messages.SUCCESS,
                    _("Successfully denied."))

        elif "drop" in request.POST:
            participation.status = participation_status.dropped
            participation.save()

            messages.add_message(request, messages.SUCCESS,
                    _("Successfully dropped."))

        if form is None:
            form = EditParticipationForm(add_new, pctx, instance=participation)

    else:
        form = EditParticipationForm(add_new, pctx, instance=participation)

    return render_course_page(pctx, "course/generic-course-form.html", {
        "form_description": _("Edit Participation"),
        "form": form
        })