示例#1
0
 def remove_container(self, container):
     try:
         self.client.remove_container(container.name)
         container.last_message = 'Container removed'
         container.last_message_at = now()
     except Exception as e:
         logger.warn("docker container not found by API -- %s" % e)
         container.last_message = str(e)
         container.last_message_at = now()
     logger.debug("Container removed %s" % container.name)
示例#2
0
 def remove_container(self, container):
     try:
         self.client.remove_container(container.name)
         container.last_message = 'Container removed'
         container.last_message_at = now()
     except Exception as e:
         logger.warn("docker container not found by API -- %s" % e)
         container.last_message = str(e)
         container.last_message_at = now()
     logger.debug("Container removed %s" % container.name)
示例#3
0
def vcrefresh(request, token_id, project_id):
    """Refresh users version control repository projects."""
    user = request.user
    logger.debug("user %s (project_id %s)" % (user, project_id))
    try:
        now_ = now()
        token = VCToken.objects.get(user = user, id = token_id)
        old_list = list(VCProject.objects.filter(token = token))
        cnt_new = 0
        cnt_del = 0
        for p_name in list_projects(token):
            try:
                p = VCProject.objects.get(token = token, project_name = p_name)
                p.last_seen = now_
                p.save()
                old_list.remove(p)
                logger.debug('still present: %s' % p_name)
            except VCProject.DoesNotExist:
                VCProject.objects.create(token = token, project_name = p_name)
                logger.debug('inserted present: %s' % p_name)
                cnt_new += 1
        while len(old_list):
            p = old_list.pop()
            p.remove()
            logger.debug('removed: %s' % p.project_name)
            cnt_del += 1
        if cnt_new:
            messages.info(request, "%d new project items found" % cnt_new)
        if cnt_del:
            messages.warning(request, "%d project items removed" % cnt_del)
        token.last_used = now_
        token.save()
    except VCToken.DoesNotExist:
        messages.error(requset, "System abuse")
    return redirect('project:conf_versioncontrol', project_id, 'project:list')
示例#4
0
 def iter_expired():
     timenow = now()
     for binding in UserAssignmentBinding.objects.filter(state = UserAssignmentBinding.ST_WORKINPROGRESS):
         if binding.expires_at is None:
             continue
         if timenow > binding.expires_at:
             yield binding
示例#5
0
 def refresh_container_state(self, container):
     docker_container_info = self.get_container(container)
     container_state = docker_container_info['State']
     logger.debug("Container state %s" % container_state)
     container.last_message = str(container_state)
     container.last_message_at = now()
     container.save()
示例#6
0
 def refresh_container_state(self, container):
     docker_container_info = self.get_container(container)
     container_state = docker_container_info['State']
     logger.debug("Container state %s" % container_state)
     container.last_message = str(container_state)
     container.last_message_at = now()
     container.save()
示例#7
0
def submitassignment(request, course_id):
    """Handle assignment submission"""
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id = course_id)
        assert len(list(UserCourseBinding.objects.filter(user = user, course = course, is_teacher = False))) == 1, "%s is not a student of course %s" % (user, course)
    except Exception as e:
        logger.error("Invalid request with course id %s and user %s -- %s" % (course_id, user, e))
        return redirect('indexpage')
    if request.method == 'GET':
        table_submit = T_SUBMIT_ASSIGNMENT(course.userassignmentbindings(user = user))
        RequestConfig(request).configure(table_submit)
        context_dict = {
            'course': course,
            't_submit': table_submit,
            'menu_teaching': 'active',
            'next_page': 'education:course',
        }
        return render(request, 'edu/assignment-submit.html', context = context_dict)
    elif request.method == 'POST':
        userassignmentbinding_ids = request.POST.getlist('userassignmentbinding_ids')
        for binding_id in userassignmentbinding_ids:
            try:
                binding = UserAssignmentBinding.objects.get(id = binding_id, user = user)
                binding.state = UserAssignmentBinding.ST_SUBMITTED
                binding.submitted_at = now()
                binding.save()
                assignment = binding.assignment
                coursecode = assignment.coursecode
                messages.info(request, '%s assignment is submitted for course %s (%s)' % (assignment.name, coursecode.course.name, coursecode.courseid))
            except Exception as e:
                logger.error(e)
                messages.error(request, 'Cannot fully submit assignment -- %s' % e)
    return redirect('education:courses')
示例#8
0
 def iter_expired():
     timenow = now()
     for binding in UserAssignmentBinding.objects.filter(
             state=UserAssignmentBinding.ST_WORKINPROGRESS):
         if binding.expires_at is None:
             continue
         if timenow > binding.expires_at:
             yield binding
示例#9
0
 def start_container(self, container):
     self.client.start(container.name)
     # we need to retrieve the container state after starting it
     docker_container_info = self.get_container(container)
     container_state = docker_container_info['State']
     logger.debug("Container state %s" % container_state)
     container.last_message = str(container_state)
     container.last_message_at = now()
     assert container_state == 'running', "Container failed to start: %s" % docker_container_info
示例#10
0
 def start_container(self, container):
     self.client.start(container.name)
     # we need to retrieve the container state after starting it
     docker_container_info = self.get_container(container)
     container_state = docker_container_info['State']
     logger.debug("Container state %s" % container_state)
     container.last_message = str(container_state)
     container.last_message_at = now()
     assert container_state == 'running', "Container failed to start: %s" % docker_container_info
示例#11
0
def snapshot_report(sender, instance, **kwargs):
    from kooplex.lib.filesystem import snapshot_report
    from kooplex.lib.proxy import addroute#, removeroute
    is_new = instance.id is None
    if not is_new:
        return
    instance.created_at = now()
    snapshot_report(instance)
    if instance.reporttype == Report.TP_STATIC:
        addroute(instance)
示例#12
0
def submitassignment(request, course_id):
    """Handle assignment submission"""
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id=course_id)
        assert len(
            list(
                UserCourseBinding.objects.filter(user=user,
                                                 course=course,
                                                 is_teacher=False))
        ) == 1, "%s is not a student of course %s" % (user, course)
    except Exception as e:
        logger.error("Invalid request with course id %s and user %s -- %s" %
                     (course_id, user, e))
        return redirect('indexpage')
    if request.method == 'GET':
        table_submit = T_SUBMIT_ASSIGNMENT(
            course.userassignmentbindings(user=user))
        RequestConfig(request).configure(table_submit)
        context_dict = {
            'course': course,
            't_submit': table_submit,
            'menu_teaching': 'active',
            'submenu': 'submit',
            'next_page': 'education:course',
        }
        return render(request,
                      'edu/assignment-student.html',
                      context=context_dict)
    elif request.method == 'POST':
        userassignmentbinding_ids = request.POST.getlist(
            'userassignmentbinding_ids')
        for binding_id in userassignmentbinding_ids:
            try:
                binding = UserAssignmentBinding.objects.get(id=binding_id,
                                                            user=user)
                binding.state = UserAssignmentBinding.ST_SUBMITTED
                binding.submitted_at = now()
                binding.save()
                assignment = binding.assignment
                coursecode = assignment.coursecode
                messages.info(
                    request, '%s assignment is submitted for course %s (%s)' %
                    (assignment.name, coursecode.course.name,
                     coursecode.courseid))
            except Exception as e:
                logger.error(e)
                messages.error(request,
                               'Cannot fully submit assignment -- %s' % e)
    return redirect('education:courses')
示例#13
0
def vc_refresh(request, token_id):
    """Refresh users version control repositories."""
    user = request.user
    logger.debug("user %s" % user)
    try:
        now_ = now()
        token = VCToken.objects.get(user=user, id=token_id)
        old_list = list(VCProject.objects.filter(token=token))
        cnt_new = 0
        cnt_del = 0
        for p_dict in list_projects(token):
            try:
                p = VCProject.objects.get(token=token, project_id=p_dict['id'])
                p.last_seen = now_
                p.save()
                old_list.remove(p)
                logger.debug(
                    'still present: {p[name]} of {p[owner_name]}'.format(
                        p=p_dict))
            except VCProject.DoesNotExist:
                VCProject.objects.create(
                    token=token,
                    project_id=p_dict['id'],
                    project_name=p_dict['name'],
                    project_description=p_dict['description'],
                    project_created_at=p_dict['created_at'],
                    project_updated_at=p_dict['updated_at'],
                    project_fullname=p_dict['full_name'],
                    project_owner=p_dict['owner_name'],
                    project_ssh_url=p_dict['ssh_url'])
                logger.debug(
                    'inserted present: {p[name]} of {p[owner_name]}'.format(
                        p=p_dict))
                cnt_new += 1
        while len(old_list):
            p = old_list.pop()
            p.delete()
            #logger.debug('removed: {p.project_name} of {p.project_owner}'.format(p = p))
            cnt_del += 1
        if cnt_new:
            messages.info(request, "%d new project items found" % cnt_new)
        if cnt_del:
            messages.warning(request, "%d project items removed" % cnt_del)
        token.last_used = now_
        token.save()
    except VCToken.DoesNotExist:
        messages.error(request, "System abuse")
    except Exception as e:
        messages.error(request, "System abuse -- %s" % e)
    return redirect('service:versioncontrol')
示例#14
0
def snapshot_report(sender, instance, **kwargs):
    from kooplex.lib.filesystem import snapshot_report, prepare_dashboardreport_withinitcell
    from kooplex.lib.proxy import addroute  #, removeroute
    is_new = instance.id is None
    if not is_new:
        return
    instance.created_at = now()
    snapshot_report(instance)
    if instance.reporttype == instance.TP_DYNAMIC:
        prepare_dashboardreport_withinitcell(instance)
    if instance.reporttype == Report.TP_STATIC:
        addroute(instance)
        if instance.password:
            add_report_nginx_api(instance)
    if instance.reporttype == Report.TP_BOKEH or instance.reporttype == Report.TP_SHINY:
        addroute(instance)
示例#15
0
def fs_refresh(request, token_id):
    """Refresh users file snchronization libraries."""
    user = request.user
    logger.debug("user %s" % user)
    try:
        now_ = now()
        token = FSToken.objects.get(user=user, id=token_id)
        old_list = list(FSLibrary.objects.filter(token=token))
        cnt_new = 0
        cnt_del = 0
        for r in list_libraries(token):
            try:
                l = FSLibrary.objects.get(token=token,
                                          library_name=r.name,
                                          library_id=r.id)
                l.last_seen = now_
                l.save()
                old_list.remove(l)
                logger.debug('still present: %s' % r.name)
            except FSLibrary.DoesNotExist:
                FSLibrary.objects.create(token=token,
                                         library_name=r.name,
                                         library_id=r.id)
                logger.debug('inserted present: %s' % r.name)
                cnt_new += 1
        while len(old_list):
            l = old_list.pop()
            l.delete()
            logger.debug('removed: %s' % l.library_name)
            cnt_del += 1
        if cnt_new:
            messages.info(request, "%d new libraries found" % cnt_new)
        if cnt_del:
            messages.warning(request, "%d libraries removed" % cnt_del)
        token.last_used = now_
        token.save()
    except FSToken.DoesNotExist:
        messages.error(request, "System abuse")
    except Exception as e:
        messages.error(request, "System abuse -- %s" % e)
    return redirect('service:filesync')
示例#16
0
 def do_activate(self):
     #FIXME: we may double check state and skip some bindings
     self.state = UserAssignmentBinding.ST_WORKINPROGRESS
     self.received_at = now()
     self.save()
     logger.info(self)
示例#17
0
def newassignment(request, course_id):
    """Renders assignment management form."""
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id=course_id)
        binding = UserCourseBinding.objects.get(user=user,
                                                course=course,
                                                is_teacher=True)
    except Course.DoesNotExist:
        logger.error("Missing course id %s and user %s" % (course_id, user))
        return redirect('education:teaching')
    except UserCourseBinding.DoesNotExist:
        logger.error("Missing course id %s and user %s" % (course_id, user))
        messages.error(
            request,
            'You are not allowed to create an assignment for %s' % (course))
        return redirect('education:teaching')
    if request.method == 'GET':
        context_dict = {
            'course': course,
            'f_assignment': FormAssignment(user=user, course=course),
            'menu_teaching': 'active',
            'submenu': 'new',
            'next_page': 'education:teaching',
        }
        return render(request,
                      'edu/assignment-teacher.html',
                      context=context_dict)
    elif request.method == 'POST':
        coursecode_ids = request.POST.getlist("coursecodes")
        name = request.POST.get("name").strip()
        description = request.POST.get("description").strip()
        folder = request.POST.get("folder")
        timenow = now()
        valid_from = translate_date(request.POST.get('valid_from')) or timenow
        expires_at = translate_date(request.POST.get('expires_at'))
        is_massassignment = bool(request.POST.get("is_massassignment"))
        can_studentsubmit = bool(request.POST.get("can_studentsubmit"))
        remove_collected = bool(request.POST.get("remove_collected"))
        try:
            assert valid_from >= timenow, "You try to shedule assignment behind time."
            assert len(name), "You need to provide a name"
            assert len(
                coursecode_ids), "You need to select at least one course code"
            extra = {}
            if expires_at:
                assert (expires_at - valid_from).total_seconds(
                ) >= 60, "Expiry is too close to handout. "
            for coursecodeid in coursecode_ids:
                coursecode = CourseCode.objects.get(id=coursecodeid)
                assert coursecode.course == course, "Course code mismatch"
                #UserCourseCodeBinding.objects.get(coursecode = coursecode, user = user, is_teacher = True)
                logger.debug("coursecode id %s" % coursecodeid)
                with transaction.atomic():
                    assignments = Assignment.objects.filter(
                        coursecode=coursecode,
                        name=name,
                        creator=user,
                        description=description,
                        folder=folder,
                        can_studentsubmit=can_studentsubmit,
                        remove_collected=remove_collected,
                        is_massassignment=is_massassignment,
                        expires_at=expires_at)
                    if len(assignments):
                        logger.warning(
                            'Prevented from duplicating assignments for course code %s'
                            % (coursecode))
                        messages.warning(
                            request,
                            'Maybe you double clicked on assignments.')
                        continue
                    Assignment.objects.create(
                        coursecode=coursecode,
                        name=name,
                        creator=user,
                        description=description,
                        folder=folder,
                        can_studentsubmit=can_studentsubmit,
                        remove_collected=remove_collected,
                        is_massassignment=is_massassignment,
                        valid_from=valid_from,
                        expires_at=expires_at)
                    logger.info('New assignments for course code %s' %
                                (coursecode))
                    messages.info(
                        request,
                        'New assignments for course code %s' % (coursecode))
        except Exception as e:
            logger.error(e)
            messages.error(request,
                           'Cannot fully register assignment -- %s' % e)
            return redirect('education:newassignment', course.id)
    return redirect('education:teaching')
示例#18
0
 def iter_valid():
     timenow = now()
     for binding in UserAssignmentBinding.objects.filter(state = UserAssignmentBinding.ST_QUEUED):
         if timenow > binding.valid_from:
             yield binding
示例#19
0
 def uptime(self):
     timenow = now()
     delta = timenow - self.launched_at
     return delta if self.is_running else -1
示例#20
0
def container_message_change(sender, instance, **kwargs):
    is_new = instance.id is None
    old_instance = Container() if is_new else Container.objects.get(id = instance.id)
    if old_instance.last_message != instance.last_message:
         logger.debug("msg of %s: %s" % (instance, instance.last_message))
         instance.last_message_at = now()
示例#21
0
 def state(self):
     timenow = now()
     if self.valid_from > timenow:
         return self.ST_SCHEDULED
     return self.ST_VALID if self.expires_at is None or self.expires_at >= timenow else self.ST_EXPIRED
示例#22
0
def feedbackassignment(request, course_id):
    """Mark assignments to correct"""
    from hub.models.assignment import ST_LOOKUP
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id = course_id)
        assert len(list(UserCourseBinding.objects.filter(user = user, course = course, is_teacher = True))) > 0, "%s is not a teacher of course %s" % (user, course)
    except Exception as e:
        logger.error("Invalid request with course id %s and user %s -- %s" % (course_id, user, e))
        return redirect('indexpage')
    if request.method == 'POST' and request.POST['button'] == 'search':
        s_name = request.POST.get('name')
        s_username = request.POST.get('username')
        s_assignment = request.POST.get('assignment')
        s_assignmentstate = request.POST.get('assignmentstate') if request.POST.get('assignmentstate') else None
        render_page = True
    elif request.method == 'GET':
        s_name = None
        s_username = None
        s_assignment = None
        s_assignmentstate = None
        render_page = True
    else:
        render_page = False
    if render_page:
        table_feedback = T_FEEDBACK_ASSIGNMENT(course.userassignmentbindings(s_assignment = s_assignment, s_name = s_name, s_username = s_username, s_assignmentstate = s_assignmentstate))
        RequestConfig(request).configure(table_feedback)
        context_dict = {
            'course': course,
            't_feedback': table_feedback,
            'search_name': s_name if s_name else '',
            'search_username': s_username if s_username else '',
            'search_assignment': s_assignment if s_assignment else '',
            'search_assignmentstate': s_assignmentstate if s_assignmentstate else '',
            'states': ST_LOOKUP,
            'menu_teaching': 'active',
            'submenu': 'feedback',
            'next_page': 'education:feedback',
        }
        return render(request, 'edu/assignments.html', context = context_dict)
    elif request.method == 'POST':
        for k, v in request.POST.items():
            try:
                task, binding_id = k.split('_')
                assert task == 'task'
                assert v in [ 'correct', 'ready', 'reassign' ]
                task = v
            except:
                continue
            try:
                binding = UserAssignmentBinding.objects.get(id = binding_id)
                #UserCourseCodeBinding.objects.get(user = user, coursecode = binding.assignment.coursecode, is_teacher = True)
                UserCourseBinding.objects.get(user = user, course = binding.assignment.coursecode.course, is_teacher = True)
                score = request.POST.get('score_%s' % binding_id)
                feedback_text = request.POST.get('feedback_text_%s' % binding_id)
                if task == 'correct':
                    binding.state = UserAssignmentBinding.ST_CORRECTING
                    binding.corrector = user
                elif task == 'ready':
                    binding.state = UserAssignmentBinding.ST_FEEDBACK
                    binding.corrected_at = now()
                    binding.score = float(score)
                    if feedback_text:
                        binding.feedback_text = feedback_text.strip()
                elif task == 'reassign': 
                    binding.state = UserAssignmentBinding.ST_WORKINPROGRESS
                    binding.corrected_at = now()
                binding.save()
                messages.info(request, '%s\'s assignment %s for course code %s is now %s' % (binding.user.username, binding.assignment.name, binding.assignment.coursecode.courseid, binding.assignment.state))
            except Exception as e:
                logger.error(e)
                messages.error(request, 'Cannot mark assignment corrected -- %s' % e)
        url_next = reverse('education:feedback', kwargs = {'course_id': course_id})
        pager = request.POST.get('pager')
        return redirect(url_next + "?%s" % pager) if pager else redirect('education:feedback', course_id)
    else:
        return redirect('education:teaching')
示例#23
0
def feedbackassignment(request, course_id):
    """Mark assignments to correct"""
    from hub.models.assignment import ST_LOOKUP
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    per_page = 20
    try:
        course = Course.objects.get(id=course_id)
        assert len(
            list(
                UserCourseBinding.objects.filter(
                    user=user, course=course, is_teacher=True))
        ) > 0, "%s is not a teacher of course %s" % (user, course)
    except Exception as e:
        logger.error("Invalid request with course id %s and user %s -- %s" %
                     (course_id, user, e))
        return redirect('indexpage')
    if request.method == 'POST' and request.POST['button'] == 'search':
        per_page = request.POST.get('per_page')
        s_name = request.POST.get('name')
        s_username = request.POST.get('username')
        s_assignment = request.POST.get('assignment')
        s_assignmentstate = request.POST.get(
            'assignmentstate') if request.POST.get('assignmentstate') else None
        render_page = True
    elif request.method == 'GET':
        s_name = None
        s_username = None
        s_assignment = None
        s_assignmentstate = None
        render_page = True
    else:
        render_page = False
    if render_page:
        table_feedback = T_FEEDBACK_ASSIGNMENT(
            course.userassignmentbindings(s_assignment=s_assignment,
                                          s_name=s_name,
                                          s_username=s_username,
                                          s_assignmentstate=s_assignmentstate))
        RequestConfig(request, paginate={
            'per_page': per_page
        }).configure(table_feedback)
        context_dict = {
            'course': course,
            't_feedback': table_feedback,
            'search_name': s_name if s_name else '',
            'search_username': s_username if s_username else '',
            'search_assignment': s_assignment if s_assignment else '',
            'search_assignmentstate':
            s_assignmentstate if s_assignmentstate else '',
            'states': ST_LOOKUP,
            'menu_teaching': 'active',
            'submenu': 'feedback',
            'per_page': per_page,
            'next_page': 'education:feedback',
        }
        return render(request,
                      'edu/assignment-teacher.html',
                      context=context_dict)
    elif request.method == 'POST':
        for k, v in request.POST.items():
            try:
                task, binding_id = k.split('_')
                assert task == 'task'
                assert v in ['correct', 'ready', 'reassign']
                task = v
            except:
                continue
            try:
                binding = UserAssignmentBinding.objects.get(id=binding_id)
                #UserCourseCodeBinding.objects.get(user = user, coursecode = binding.assignment.coursecode, is_teacher = True)
                UserCourseBinding.objects.get(
                    user=user,
                    course=binding.assignment.coursecode.course,
                    is_teacher=True)
                score = request.POST.get('score_%s' % binding_id)
                feedback_text = request.POST.get('feedback_text_%s' %
                                                 binding_id)
                if task == 'correct':
                    binding.state = UserAssignmentBinding.ST_CORRECTING
                    binding.corrector = user
                elif task == 'ready':
                    binding.state = UserAssignmentBinding.ST_FEEDBACK
                    binding.corrected_at = now()
                    binding.score = float(score)
                    if feedback_text:
                        binding.feedback_text = feedback_text.strip()
                elif task == 'reassign':
                    binding.state = UserAssignmentBinding.ST_WORKINPROGRESS
                    binding.corrected_at = now()
                binding.save()
                messages.info(
                    request,
                    '%s\'s assignment %s for course code %s is now %s' %
                    (binding.user.username, binding.assignment.name,
                     binding.assignment.coursecode.courseid,
                     binding.assignment.state))
            except Exception as e:
                logger.error(e)
                messages.error(request,
                               'Cannot mark assignment corrected -- %s' % e)
        url_next = reverse('education:feedback',
                           kwargs={'course_id': course_id})
        pager = request.POST.get('pager')
        return redirect(url_next + "?%s" % pager) if pager else redirect(
            'education:feedback', course_id)
    else:
        return redirect('education:teaching')
示例#24
0
 def do_activate(self):
     #FIXME: we may double check state and skip some bindings
     self.state = UserAssignmentBinding.ST_WORKINPROGRESS
     self.received_at = now()
     self.save()
     logger.info(self)
示例#25
0
 def iter_valid():
     timenow = now()
     for binding in UserAssignmentBinding.objects.filter(
             state=UserAssignmentBinding.ST_QUEUED):
         if timenow > binding.valid_from:
             yield binding
示例#26
0
 def do_collect(self):
     #FIXME: we may double check state and skip some bindings
     self.state = UserAssignmentBinding.ST_COLLECTED
     self.submitted_at = now()
     self.save()
     logger.info(self)
示例#27
0
def bindassignment(request, course_id):
    from django.contrib.auth.models import User
    """Bind assignment and user"""
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id=course_id)
        assert len(
            list(
                UserCourseBinding.objects.filter(
                    user=user, course=course, is_teacher=True))
        ) > 0, "%s is not a teacher of course %s" % (user, course)
    except Exception as e:
        logger.error("Invalid request with course id %s and user %s -- %s" %
                     (course_id, user, e))
        return redirect('indexpage')
    if request.method == 'GET':
        s_name = request.GET.get('name', '')
        s_username = request.GET.get('username', '')
        s_assignment = request.GET.get('assignment', '')
        table_bind = T_BIND_ASSIGNMENT(course.bindableassignments())
        RequestConfig(request).configure(table_bind)
        context_dict = {
            'course': course,
            't_bind': table_bind,
            'search_name': s_name,
            'search_username': s_username,
            'search_assignment': s_assignment,
            'menu_teaching': 'active',
            'submenu': 'bind',
            'next_page': 'education:teaching',
        }
        return render(request,
                      'edu/assignment-teacher.html',
                      context=context_dict)
    elif request.method == 'POST':
        thetime = now()
        oopses = 0
        done = 0
        for br in request.POST.getlist('binding_representation'):
            user_id, assignment_id = br.split('_')
            try:
                assignment = Assignment.objects.get(id=assignment_id)
                student = User.objects.get(id=user_id)
                assert student in assignment.list_students_bindable(
                ), "Cannot bind %s to %s" % (student, assignment)
                assert user.profile.is_coursecodeteacher(
                    assignment.coursecode
                ), "You are not a teacher of %s" % assignment.coursecode
            except Exception as e:
                raise
                logger.error("oops -- %s" % e)
                oopses += 1
                continue
            try:
                binding = UserAssignmentBinding.objects.get(
                    user=student, assignment=assignment)
                logger.error("Will not create a duplicate %s" % binding)
                messages.error(
                    request,
                    "Prevented from creating a duplicate assignment %s for student %s"
                    % (assignment.name, student))
            except UserAssignmentBinding.DoesNotExist:
                pass
            valid_from = translate_date(request.POST.get('valid_from_%s' % br))
            expires_at = translate_date(request.POST.get('expires_at_%s' % br))
            if valid_from and valid_from > thetime:
                UserAssignmentBinding.objects.create(
                    user=student,
                    assignment=assignment,
                    valid_from=valid_from,
                    expires_at=expires_at,
                    state=UserAssignmentBinding.ST_QUEUED)
            else:
                UserAssignmentBinding.objects.create(user=student,
                                                     assignment=assignment,
                                                     valid_from=valid_from,
                                                     expires_at=expires_at)
    #FIXME> expiry check in model init!
            messages.info(
                request, "Creating an assignment %s for student %s" %
                (assignment.name, student))
        url_next = reverse('education:bindassignment',
                           kwargs={'course_id': course_id})
        pager = request.POST.get('pager')
        logger.debug("next: %s %s" % (url_next, pager))
        return redirect(url_next + "?%s" % pager) if pager else redirect(
            'education:bindassignment', course_id)
    else:
        return redirect('education:teaching')
示例#28
0
def newassignment(request, course_id):
    """Renders assignment management form."""
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id = course_id)
        binding = UserCourseBinding.objects.get(user = user, course = course, is_teacher = True)
    except Course.DoesNotExist:
        logger.error("Missing course id %s and user %s" % (course_id, user))
        return redirect('education:teaching')
    except UserCourseBinding.DoesNotExist:
        logger.error("Missing course id %s and user %s" % (course_id, user))
        messages.error(request, 'You are not allowed to create an assignment for %s' % (course))
        return redirect('education:teaching')
    if request.method == 'GET':
        context_dict = {
            'course': course,
            'f_assignment': FormAssignment(user = user, course = course),
            'menu_teaching': 'active',
            'submenu': 'new',
            'next_page': 'education:teaching',
        }
        return render(request, 'edu/assignments.html', context = context_dict)
    elif request.method == 'POST':
        coursecode_ids = request.POST.getlist("coursecodes")
        name = request.POST.get("name").strip()
        description = request.POST.get("description").strip()
        folder = request.POST.get("folder")
        timenow = now()
        valid_from = translate_date(request.POST.get('valid_from')) or timenow
        expires_at = translate_date(request.POST.get('expires_at'))
        is_massassignment = bool(request.POST.get("is_massassignment"))
        can_studentsubmit = bool(request.POST.get("can_studentsubmit"))
        remove_collected = bool(request.POST.get("remove_collected"))
        try:
            assert valid_from >= timenow, "You try to chedule assignment behind time."
            assert len(name), "You need to provide a name"
            assert len(coursecode_ids), "You need to select at least one course code"
            extra = {}
            if expires_at:
                assert (expires_at - valid_from).total_seconds() >= 60, "Expiry is too close to handout. "
            for coursecodeid in coursecode_ids:
                coursecode = CourseCode.objects.get(id = coursecodeid)
                assert coursecode.course == course, "Course code mismatch"
                #UserCourseCodeBinding.objects.get(coursecode = coursecode, user = user, is_teacher = True)
                logger.debug("coursecode id %s" % coursecodeid)
                with transaction.atomic():
                    assignments = Assignment.objects.filter(
                        coursecode = coursecode, 
                        name = name, 
                        creator = user, 
                        description = description, 
                        folder = folder, 
                        can_studentsubmit = can_studentsubmit, 
                        remove_collected = remove_collected,
                        is_massassignment = is_massassignment, 
                        expires_at = expires_at
                        )
                    if len(assignments):
                        logger.warning('Prevented from duplicating assignments for course code %s' % (coursecode))
                        messages.warning(request, 'Maybe you double clicked on assignments.')
                        continue
                    Assignment.objects.create(
                        coursecode = coursecode, 
                        name = name, 
                        creator = user, 
                        description = description, 
                        folder = folder, 
                        can_studentsubmit = can_studentsubmit, 
                        remove_collected = remove_collected,
                        is_massassignment = is_massassignment, 
                        valid_from = valid_from,
                        expires_at = expires_at
                    )
                    logger.info('New assignments for course code %s' % (coursecode))
                    messages.info(request, 'New assignments for course code %s' % (coursecode))
        except Exception as e:
            logger.error(e)
            messages.error(request, 'Cannot fully register assignment -- %s' % e)
            return redirect('education:newassignment', course.id)
    return redirect('education:teaching')
示例#29
0
 def state(self):
     timenow = now()
     if self.valid_from > timenow:
         return self.ST_SCHEDULED
     return self.ST_VALID if self.expires_at is None or self.expires_at >= timenow else self.ST_EXPIRED
示例#30
0
 def do_collect(self):
     #FIXME: we may double check state and skip some bindings
     self.state = UserAssignmentBinding.ST_COLLECTED
     self.submitted_at = now()
     self.save()
     logger.info(self)
示例#31
0
def bindassignment(request, course_id):
    from django.contrib.auth.models import User
    """Bind assignment and user"""
    user = request.user
    logger.debug("user %s, method: %s" % (user, request.method))
    try:
        course = Course.objects.get(id = course_id)
        assert len(list(UserCourseBinding.objects.filter(user = user, course = course, is_teacher = True))) > 0, "%s is not a teacher of course %s" % (user, course)
    except Exception as e:
        logger.error("Invalid request with course id %s and user %s -- %s" % (course_id, user, e))
        return redirect('indexpage')
    if request.method == 'GET':
        s_name = request.GET.get('name', '')
        s_username = request.GET.get('username', '')
        s_assignment = request.GET.get('assignment', '')
        table_bind = T_BIND_ASSIGNMENT(course.bindableassignments())
        RequestConfig(request).configure(table_bind)
        context_dict = {
            'course': course,
            't_bind': table_bind,
            'search_name': s_name,
            'search_username': s_username,
            'search_assignment': s_assignment,
            'menu_teaching': 'active',
            'submenu': 'bind',
            'next_page': 'education:teaching', 
        }
        return render(request, 'edu/assignments.html', context = context_dict)
    elif request.method == 'POST':
        thetime = now()
        oopses = 0
        done = 0
        for br in request.POST.getlist('binding_representation'):
            user_id, assignment_id = br.split('_')
            try:
                assignment = Assignment.objects.get(id = assignment_id)
                student = User.objects.get(id = user_id)
                assert student in assignment.list_students_bindable(), "Cannot bind %s to %s" % (student, assignment)
                assert user.profile.is_coursecodeteacher(assignment.coursecode), "You are not a teacher of %s" % assignment.coursecode
            except Exception as e:
                raise
                logger.error("oops -- %s" % e)
                oopses += 1
                continue
            try:
                binding = UserAssignmentBinding.objects.get(user = student, assignment = assignment)
                logger.error("Will not create a duplicate %s" % binding)
                messages.error(request, "Prevented from creating a duplicate assignment %s for student %s" % (assignment.name, student))
            except UserAssignmentBinding.DoesNotExist:
                pass
            valid_from = translate_date(request.POST.get('valid_from_%s' % br))
            expires_at = translate_date(request.POST.get('expires_at_%s' % br))
            if valid_from and valid_from > thetime:
                UserAssignmentBinding.objects.create(user = student, assignment = assignment, valid_from = valid_from, expires_at = expires_at, state = UserAssignmentBinding.ST_QUEUED)
            else:
                UserAssignmentBinding.objects.create(user = student, assignment = assignment, valid_from = valid_from, expires_at = expires_at)
    #FIXME> expiry check in model init!
            messages.info(request, "Creating an assignment %s for student %s" % (assignment.name, student))
        url_next = reverse('education:bindassignment', kwargs = {'course_id': course_id})
        pager = request.POST.get('pager')
        logger.debug("next: %s %s" % (url_next, pager)) 
        return redirect(url_next + "?%s" % pager) if pager else redirect('education:bindassignment', course_id)
    else:
        return redirect('education:teaching')