예제 #1
0
def download_file(request,
                  course_slug,
                  activity_slug,
                  component_slug=None,
                  submission_id=None,
                  userid=None):
    course = get_object_or_404(CourseOffering, slug=course_slug)
    activity = get_object_or_404(course.activity_set,
                                 slug=activity_slug,
                                 deleted=False)
    staff = False
    if is_course_staff_by_slug(request, course_slug):
        staff = True

    # find the appropriate submission object
    if submission_id:
        # explicit request: get that one.
        try:
            submission_info = SubmissionInfo.from_submission_id(submission_id)
        except ValueError:
            return NotFoundResponse(request)
    elif userid:
        # userid specified: get their most recent submission
        student = get_object_or_404(Person, find_userid_or_emplid(userid))
        submission_info = SubmissionInfo(student=student,
                                         activity=activity,
                                         include_deleted=staff)
    else:
        return NotFoundResponse(request)

    if not submission_info.have_submitted(
    ) or submission_info.activity != activity:
        return NotFoundResponse(request)

    if not submission_info.accessible_by(request):
        return ForbiddenResponse(request)

    # create the result
    if component_slug:
        # download single component if specified
        submission_info.get_most_recent_components()
        submitted_components = [
            subcomp
            for comp, subcomp in submission_info.components_and_submitted()
            if subcomp and comp.slug == component_slug
        ]
        if not submitted_components:
            return NotFoundResponse(request)

        submitted_component = submitted_components[0]
        return submitted_component.download_response(
            slug=submission_info.submissions[0].file_slug())
    else:
        # no component specified: give back the full ZIP file.
        return submission_info.generate_student_zip()
예제 #2
0
파일: views.py 프로젝트: sfu-fas/coursys
def download_file(request, course_slug, activity_slug, component_slug=None, submission_id=None, userid=None):
    course = get_object_or_404(CourseOffering, slug=course_slug)
    activity = get_object_or_404(course.activity_set, slug = activity_slug, deleted=False)
    staff = False
    if is_course_staff_by_slug(request, course_slug):
        staff = True

    # find the appropriate submission object
    if submission_id:
        # explicit request: get that one.
        try:
            submission_info = SubmissionInfo.from_submission_id(submission_id)
        except ValueError:
            return NotFoundResponse(request)
    elif userid:
        # userid specified: get their most recent submission
        student = get_object_or_404(Person, find_userid_or_emplid(userid))
        submission_info = SubmissionInfo(student=student, activity=activity, include_deleted=staff)
    else:
        return NotFoundResponse(request)

    if not submission_info.have_submitted() or submission_info.activity != activity:
        return NotFoundResponse(request)

    if not submission_info.accessible_by(request):
        return ForbiddenResponse(request)

    # create the result
    if component_slug:
        # download single component if specified
        submission_info.get_most_recent_components()
        submitted_components = [subcomp for comp, subcomp in submission_info.components_and_submitted() if subcomp and comp.slug == component_slug]
        if not submitted_components:
            return NotFoundResponse(request)

        submitted_component = submitted_components[0]
        return submitted_component.download_response(slug=submission_info.submissions[0].file_slug())
    else:
        # no component specified: give back the full ZIP file.
        return submission_info.generate_student_zip()
예제 #3
0
def _show_components_student(request,
                             course_slug,
                             activity_slug,
                             userid=None,
                             template="dashboard_student.html",
                             staff=False):
    """
    Show all the component submission history of this activity
    """
    if userid == None:
        userid = request.user.username
    course = get_object_or_404(CourseOffering, slug=course_slug)
    activity = get_object_or_404(course.activity_set,
                                 slug=activity_slug,
                                 deleted=False)
    student = get_object_or_404(Person, find_userid_or_emplid(userid))
    cansubmit = True
    submission_configured = SubmissionComponent.objects.filter(
        activity_id=activity.id).exists()
    if not submission_configured:
        return NotFoundResponse(request)

    submission_info = SubmissionInfo(student=student, activity=activity)
    submission_info.get_most_recent_components()
    if activity.multisubmit():
        submission_info.get_all_components()

    any_submissions = bool(submission_info.submissions)

    if submission_info.submissions and activity.due_date and activity.due_date < submission_info.latest(
    ).created_at:
        late = submission_info.latest().created_at - activity.due_date
    else:
        late = 0

    if activity.group:
        gm = GroupMember.objects.filter(student__person=student,
                                        activity=activity,
                                        confirmed=True)
        if gm:
            group = gm[0].group
            member = gm[0].student
        else:
            group = None

    else:
        group = None

    # activity should be submitable
    cansubmit = cansubmit and activity.submitable()

    if not cansubmit:
        messages.add_message(request, messages.ERROR,
                             "This activity is not submittable.")
        return render(
            request, "submission/" + template, {
                "course": course,
                "activity": activity,
                "submission_info": submission_info,
                'any_submissions': any_submissions,
                "userid": userid,
                "late": late,
                "student": student,
                "group": group,
                "cansubmit": cansubmit
            })

    # get all components of activity
    component_list = select_all_components(activity)
    component_list.sort()
    component_form_list = []

    if request.method == 'POST':
        component_form_list = make_form_from_list(component_list,
                                                  request=request)
        submitted_comp = [
        ]  # list all components which has content submitted in the POST
        not_submitted_comp = [
        ]  #list allcomponents which has no content submitted in the POST
        if not activity.group:
            new_sub = StudentSubmission(
            )  # the submission foreign key for newly submitted components
            new_sub.member = get_object_or_404(
                Member,
                offering__slug=course_slug,
                person__userid=request.user.username)
        elif gm:
            new_sub = GroupSubmission()
            new_sub.group = group
            new_sub.creator = member
        else:
            messages.add_message(
                request, messages.ERROR,
                "This is a group submission. You cannot submit since you aren't in a group."
            )
            return ForbiddenResponse(request)
        new_sub.activity = activity

        # begin validating uploaded data
        submitted_comp = []
        not_submitted_comp = []
        # validate forms one by one
        for data in component_form_list:
            component = data['comp']
            form = data['form']
            if form.is_valid():
                sub = form.save(commit=False)
                sub.component = component
                submitted_comp.append(sub)
            else:
                # hack to replace the "required" message to something more appropriate
                for k, v in list(form.errors.items()):
                    for i, e in enumerate(v):
                        if e == "This field is required.":
                            v[i] = "Nothing submitted."

                not_submitted_comp.append(component)
        # check duplicate filenames here
        all_ok = False
        while not all_ok:
            all_ok = True
            d = {}
            if not activity.multisubmit():
                # single-submit logic: don't want to overrite filenames from earlier submissions that are still in-play
                for c, s in submission_info.components_and_submitted():
                    d[c] = s and s.get_filename()
            # filenames from this submission
            for s in submitted_comp:
                d[s.component] = s.get_filename()
            # a list holding all file names
            file_name_list = [
                a[1] for a in list(d.items()) if a[1] is not None
            ]
            to_be_removed = []
            for (i, s) in enumerate(submitted_comp):
                if file_name_list.count(s.get_filename()) > 1:
                    all_ok = False
                    to_be_removed.append(i)
                    not_submitted_comp.append(s.component)
                    #HACK: modify the 'errors' field in the form
                    for data in component_form_list:
                        if s.component == data['comp']:
                            # assume we have only one field for submission form
                            field_name = list(data['form'].fields.keys())[0]
                            data['form']._errors[field_name] = ErrorList([
                                "This file has the same name as another file in your submission."
                            ])
            # remove those has errors in submitted_comp
            to_be_removed.reverse()
            for t in to_be_removed:
                submitted_comp.pop(t)
        # all okay now
        # end validating, begin saving
        if len(submitted_comp) > 0:
            new_sub.save()
        for sub in submitted_comp:
            sub.submission = new_sub
            sub.save()
            #LOG EVENT#
            if activity.group:
                group_str = " as a member of group %s" % new_sub.group.name
            else:
                group_str = ""
            l = LogEntry(userid=request.user.username,
                         description="submitted for %s %s%s" %
                         (activity, sub.component.title, group_str),
                         related_object=sub)
            l.save()

        if len(not_submitted_comp) == 0:
            messages.add_message(request, messages.SUCCESS,
                                 "Your submission was successful.")
            return HttpResponseRedirect(
                reverse('offering:submission:show_components',
                        args=[course_slug, activity_slug]))

        return render(
            request, "submission/submission_error.html", {
                "course": course,
                "activity": activity,
                "component_list": component_form_list,
                "submitted_comp": submitted_comp,
                "not_submitted_comp": not_submitted_comp
            })
    else:  #not POST
        component_form_list = make_form_from_list(component_list)
        return render(
            request, "submission/" + template, {
                'component_form_list': component_form_list,
                "course": course,
                "activity": activity,
                "submission_info": submission_info,
                "userid": userid,
                "late": late,
                "student": student,
                "group": group,
                "cansubmit": cansubmit,
                "is_staff": staff,
                'any_submissions': any_submissions
            })
예제 #4
0
파일: views.py 프로젝트: sfu-fas/coursys
def _show_components_student(request, course_slug, activity_slug, userid=None, template="dashboard_student.html", staff=False):
    """
    Show all the component submission history of this activity
    """
    if userid == None:
        userid = request.user.username
    course = get_object_or_404(CourseOffering, slug=course_slug)
    activity = get_object_or_404(course.activity_set,slug=activity_slug, deleted=False)
    student = get_object_or_404(Person, find_userid_or_emplid(userid))
    cansubmit = True
    submission_configured = SubmissionComponent.objects.filter(activity_id=activity.id).exists()
    if not submission_configured:
        return NotFoundResponse(request)

    submission_info = SubmissionInfo(student=student, activity=activity)
    submission_info.get_most_recent_components()
    if activity.multisubmit():
        submission_info.get_all_components()

    any_submissions = bool(submission_info.submissions)

    if submission_info.submissions and activity.due_date and activity.due_date < submission_info.latest().created_at:
        late = submission_info.latest().created_at - activity.due_date
    else:
        late = 0
    
    if activity.group:
        gm = GroupMember.objects.filter(student__person=student, activity=activity, confirmed=True)
        if gm:
            group = gm[0].group
            member = gm[0].student
        else:
            group = None

    else:
        group = None

    # activity should be submitable
    cansubmit = cansubmit and activity.submitable()

    if not cansubmit:
        messages.add_message(request, messages.ERROR, "This activity is not submittable.")
        return render(request, "submission/" + template,
        {"course":course, "activity":activity, "submission_info": submission_info, 'any_submissions': any_submissions,
         "userid":userid, "late":late, "student":student, "group":group, "cansubmit":cansubmit})

    # get all components of activity
    component_list = select_all_components(activity)
    component_list.sort()
    component_form_list=[]

    if request.method == 'POST':
        component_form_list = make_form_from_list(component_list, request=request)
        submitted_comp = []    # list all components which has content submitted in the POST
        not_submitted_comp = [] #list allcomponents which has no content submitted in the POST
        if not activity.group:
            new_sub = StudentSubmission()   # the submission foreign key for newly submitted components
            new_sub.member = get_object_or_404(Member, offering__slug=course_slug, person__userid=request.user.username)
        elif gm:
            new_sub = GroupSubmission()
            new_sub.group = group
            new_sub.creator = member
        else:
            messages.add_message(request, messages.ERROR, "This is a group submission. You cannot submit since you aren't in a group.")
            return ForbiddenResponse(request)
        new_sub.activity = activity

        # begin validating uploaded data
        submitted_comp = []
        not_submitted_comp = []
        # validate forms one by one
        for data in component_form_list:
            component = data['comp']
            form = data['form']
            if form.is_valid():
                sub = form.save(commit=False)
                sub.component = component
                submitted_comp.append(sub)
            else:
                # hack to replace the "required" message to something more appropriate
                for k,v in list(form.errors.items()):
                    for i,e in enumerate(v):
                        if e == "This field is required.":
                            v[i] = "Nothing submitted."

                not_submitted_comp.append(component)
        # check duplicate filenames here
        all_ok = False
        while not all_ok:
            all_ok = True
            d = {}
            if not activity.multisubmit():
                # single-submit logic: don't want to overrite filenames from earlier submissions that are still in-play
                for c,s in submission_info.components_and_submitted():
                    d[c] = s and s.get_filename()
            # filenames from this submission
            for s in submitted_comp:
                d[s.component] = s.get_filename()
            # a list holding all file names
            file_name_list = [a[1] for a in list(d.items()) if a[1] is not None]
            to_be_removed = []
            for (i, s) in enumerate(submitted_comp):
                if file_name_list.count(s.get_filename()) > 1:
                    all_ok = False
                    to_be_removed.append(i)
                    not_submitted_comp.append(s.component)
                    #HACK: modify the 'errors' field in the form
                    for data in component_form_list:
                        if s.component == data['comp']:
                            # assume we have only one field for submission form
                            field_name = list(data['form'].fields.keys())[0]
                            data['form']._errors[field_name] = ErrorList(["This file has the same name as another file in your submission."])
            # remove those has errors in submitted_comp
            to_be_removed.reverse()
            for t in to_be_removed:
                submitted_comp.pop(t)
        # all okay now
        # end validating, begin saving
        if len(submitted_comp) > 0:
            new_sub.save()    
        for sub in submitted_comp:
            sub.submission = new_sub
            sub.save()
            #LOG EVENT#
            if activity.group:
                group_str = " as a member of group %s" % new_sub.group.name
            else:
                group_str = ""
            l = LogEntry(userid=request.user.username,
                  description="submitted for %s %s%s" % (activity, sub.component.title, group_str),
                  related_object=sub)
            l.save()

        if len(not_submitted_comp) == 0:
            messages.add_message(request, messages.SUCCESS, "Your submission was successful.")
            return HttpResponseRedirect(reverse('offering:submission:show_components', args=[course_slug, activity_slug]))

        return render(request, "submission/submission_error.html",
            {"course":course, "activity":activity, "component_list":component_form_list,
            "submitted_comp":submitted_comp, "not_submitted_comp":not_submitted_comp})
    else: #not POST
        component_form_list = make_form_from_list(component_list)
        return render(request, "submission/" + template,
        {'component_form_list': component_form_list, "course": course, "activity": activity, "submission_info": submission_info,
         "userid":userid, "late":late, "student":student, "group":group,
         "cansubmit":cansubmit, "is_staff":staff, 'any_submissions': any_submissions})