Newer
Older
@course_view
@transaction.atomic
def grant_exception_stage_3(pctx, participation_id, flow_id, session_id):
Andreas Klöckner
committed
# type: (CoursePageContext, int, Text, int) -> http.HttpResponse
if not pctx.has_permission(pperm.grant_exception):
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, flow_desc, now_datetime)
grading_rule = get_session_grading_rule(session, 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
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,
fre_access.save()
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()
due = form.cleaned_data["due"]
if form.cleaned_data["due_same_as_access_expiration"]:
due = form.cleaned_data["access_expires"]
if form.cleaned_data["credit_percent"] is not None:
descr += string_concat(" (%.1f%% ", ugettext('credit'), ")") \
% form.cleaned_data["credit_percent"]
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)
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
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,
messages.add_message(pctx.request, messages.SUCCESS,
ugettext(
"Exception granted to '%(participation)s' "
% {
'participation': participation,
'flow_id': flow_id})
"relate-grant_exception",
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_read = six.StringIO(prv_bio.getvalue())
pub = key_class.from_private_key(prv_bio_read)
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)
progress_statement = (
_("%(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,
})
# }}}
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
# {{{ 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
})
# }}}