Skip to content
views.py 43.1 KiB
Newer Older
        raise PermissionDenied(_("may not grant exceptions"))

    participation = get_object_or_404(Participation, id=participation_id)

    from course.content import get_flow_desc
    try:
        flow_desc = get_flow_desc(pctx.repo, pctx.course, flow_id,
                pctx.course_commit_sha)
    except ObjectDoesNotExist:
        raise http.Http404()

    session = FlowSession.objects.get(id=int(session_id))
    now_datetime = get_now_or_fake_time(pctx.request)
    from course.utils import (
            get_session_access_rule,
            get_session_grading_rule)
    access_rule = get_session_access_rule(
            session, participation.role, flow_desc, now_datetime)
    grading_rule = get_session_grading_rule(
            session, participation.role, flow_desc, now_datetime)

    request = pctx.request
    if request.method == "POST":
        form = ExceptionStage3Form(
                {}, flow_desc, session.access_rules_tag, request.POST)
        from course.constants import flow_rule_kind

        if form.is_valid():
            permissions = [
                    key
                    for key, _ in FLOW_PERMISSION_CHOICES
                    if form.cleaned_data[key]]

            from course.validation import (
                    validate_session_access_rule,
                    validate_session_grading_rule,
                    ValidationContext)
            from relate.utils import dict_to_struct
            vctx = ValidationContext(
                    repo=pctx.repo,
                    commit_sha=pctx.course_commit_sha)

            flow_desc = get_flow_desc(pctx.repo,
                    pctx.course,
                    flow_id, pctx.course_commit_sha)
            tags = None
            if hasattr(flow_desc, "rules"):
                tags = getattr(flow_desc.rules, "tags", None)

            # {{{ put together access rule

            new_access_rule = {"permissions": permissions}

            if (form.cleaned_data.get("restrict_to_same_tag")
                    and session.access_rules_tag is not None):
                new_access_rule["if_has_tag"] = session.access_rules_tag

            validate_session_access_rule(
                    vctx, ugettext("newly created exception"),
                    dict_to_struct(new_access_rule), tags)

            fre_access = FlowRuleException(
                flow_id=flow_id,
                participation=participation,
                expiration=form.cleaned_data["access_expires"],
                creator=pctx.request.user,
                comment=form.cleaned_data["comment"],
                kind=flow_rule_kind.access,
                rule=new_access_rule)
            new_access_rules_tag = form.cleaned_data.get("set_access_rules_tag")
            if new_access_rules_tag == NONE_SESSION_TAG:
                new_access_rules_tag = None

            if session.access_rules_tag != new_access_rules_tag:
                session.access_rules_tag = new_access_rules_tag
                session.save()

            # {{{ put together grading rule

            due = form.cleaned_data["due"]
            if form.cleaned_data["due_same_as_access_expiration"]:
                due = form.cleaned_data["access_expires"]

ifaint's avatar
ifaint committed
            descr = ugettext("Granted excecption")
            if form.cleaned_data["credit_percent"] is not None:
Dong Zhuang's avatar
Dong Zhuang committed
                descr += string_concat(" (%.1f%% ", ugettext('credit'), ")") \
                        % form.cleaned_data["credit_percent"]
Andreas Klöckner's avatar
Andreas Klöckner committed
            due_local_naive = due
            if due_local_naive is not None:
                from relate.utils import as_local_time
                due_local_naive = as_local_time(due_local_naive).replace(tzinfo=None)

            new_grading_rule = {
                "description": descr,
Andreas Klöckner's avatar
Andreas Klöckner committed
            if due_local_naive is not None:
                new_grading_rule["due"] = due_local_naive
                new_grading_rule["if_completed_before"] = due_local_naive

            if form.cleaned_data["credit_percent"] is not None:
                new_grading_rule["credit_percent"] = \
                        form.cleaned_data["credit_percent"]

            if (form.cleaned_data.get("restrict_to_same_tag")
                    and session.access_rules_tag is not None):
                new_grading_rule["if_has_tag"] = session.access_rules_tag

            if hasattr(grading_rule, "generates_grade"):
                new_grading_rule["generates_grade"] = \
                        grading_rule.generates_grade

ifaint's avatar
ifaint committed
            validate_session_grading_rule(vctx, ugettext("newly created exception"),
                    dict_to_struct(new_grading_rule), tags,
                    grading_rule.grade_identifier)
            fre_grading = FlowRuleException(
                flow_id=flow_id,
                participation=participation,
                creator=pctx.request.user,
                comment=form.cleaned_data["comment"],
                kind=flow_rule_kind.grading,
                rule=new_grading_rule)
            messages.add_message(pctx.request, messages.SUCCESS,
                    ugettext(
                        "Exception granted to '%(participation)s' "
                        "for '%(flow_id)s'.")
                    % {
                        'participation': participation,
                        'flow_id': flow_id})
            return redirect(
                    pctx.course.identifier)

    else:
        data = {
                "restrict_to_same_tag": session.access_rules_tag is not None,
                "credit_percent": grading_rule.credit_percent,
                #"due_same_as_access_expiration": True,
                "due": grading_rule.due,
        for perm in access_rule.permissions:
        form = ExceptionStage3Form(data, flow_desc, session.access_rules_tag)

    return render_course_page(pctx, "course/generic-course-form.html", {
        "form": form,
        "form_description": ugettext("Grant Exception"),
        "form_text": string_concat(
            "<div class='well'>",
            ugettext("Granting exception to '%(participation)s' "
            "for '%(flow_id)s' (session %(session)s)."),
            "</div>")
        % {
            'participation': participation,
            'flow_id': flow_id,
            'session': strify_session_for_exception(session)},
# {{{ ssh keypair

@login_required
def generate_ssh_keypair(request):
    if not request.user.is_staff:
        raise PermissionDenied(_("only staff may use this tool"))

    from paramiko import RSAKey
    key_class = RSAKey
    prv = key_class.generate(bits=2048)

    import six
    prv_bio = six.StringIO()
    prv.write_private_key(prv_bio)

    prv_bio_read = six.StringIO(prv_bio.getvalue())

    pub = key_class.from_private_key(prv_bio_read)

    pub_bio = six.StringIO()
    pub_bio.write("%s %s relate-course-key" % (pub.get_name(), pub.get_base64()))

    return render(request, "course/keypair.html", {
        "public_key": prv_bio.getvalue(),
        "private_key": pub_bio.getvalue(),
# {{{ celery task monitoring

def monitor_task(request, task_id):
    from celery.result import AsyncResult
    async_res = AsyncResult(task_id)

    progress_percent = None
    progress_statement = None

    if async_res.state == "PROGRESS":
        meta = async_res.info
        current = meta["current"]
        total = meta["total"]
        if total > 0:
            progress_percent = 100 * (current / total)
                _("%(current)d out of %(total)d items processed.")
                % {"current": current, "total": total})
    if async_res.state == "SUCCESS":
        if (isinstance(async_res.result, dict)
                and "message" in async_res.result):
            progress_statement = async_res.result["message"]

    traceback = None
    if request.user.is_staff and async_res.state == "FAILURE":
        traceback = async_res.traceback

    return render(request, "course/task-monitor.html", {
        "state": async_res.state,
        "progress_percent": progress_percent,
        "progress_statement": progress_statement,
        "traceback": traceback,
        })

# }}}


# {{{ edit course

class EditCourseForm(StyledModelForm):
    def __init__(self, *args, **kwargs):
        super(EditCourseForm, self).__init__(*args, **kwargs)
        self.fields["identifier"].disabled = True
        self.fields["active_git_commit_sha"].disabled = True

        self.helper.add_input(
                Submit("submit", _("Update")))

    class Meta:
        model = Course
        exclude = (
                "participants",
                )
        widgets = {
                "start_date": DateTimePicker(options={"format": "YYYY-MM-DD"}),
                "end_date": DateTimePicker(options={"format": "YYYY-MM-DD"})
                }


@course_view
def edit_course(pctx):
    if not pctx.has_permission(pperm.edit_course):
        raise PermissionDenied()

    request = pctx.request

    if request.method == 'POST':
        form = EditCourseForm(request.POST, instance=pctx.course)
        if form.is_valid():
            form.save()

    else:
        form = EditCourseForm(instance=pctx.course)

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

# }}}

# vim: foldmethod=marker