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()
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()
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 })
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})