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, submitted_components = get_current_submission(student, activity, include_deleted=staff) if len(submitted_components) == 0: return NotFoundResponse(request) if submission and activity.due_date and activity.due_date < submission.created_at: late = submission.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 #cansubmit = False #messages.add_message(request, messages.INFO, "This is a group submission. You cannot submit since you aren't in a group.") 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": submission, "submitted_components":submitted_components, "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 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 = {} for c,s in submitted_components: d[c] = s and s.get_filename() 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 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 = data['form'].fields.keys()[0] data['form']._errors[field_name] = ErrorList([u"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=u"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(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 if activity.group and gm: messages.add_message(request, messages.INFO, "This is a group submission. You will submit on behalf of the group %s." % group.name) 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": submission, "submitted_components":submitted_components, "userid":userid, "late":late, "student":student, "group":group, "cansubmit":cansubmit, "is_staff":staff})
def test_group_change(self): """ Test changing group <-> individual on an activity. Should only be possible in some conditions. """ s, c = create_offering() # add some assignments and members due = datetime.datetime.now() + datetime.timedelta(days=1) due_date = str(due.date()) due_time = due.time().strftime("%H:%M:%S") a = NumericActivity(name="Assignment 1", short_name="A1", status="RLS", offering=c, position=2, max_grade=15, percent=10, due_date=due, group=False) a.save() p = Person.objects.get(userid="ggbaker") m = Member(person=p, offering=c, role="INST", added_reason="UNK") m.save() p = Person.objects.get(userid="0aaa0") m = Member(person=p, offering=c, role="STUD", added_reason="UNK") m.save() client = Client() client.login_user("ggbaker") url = reverse('grades.views.edit_activity', kwargs={'course_slug': c.slug, 'activity_slug': a.slug}) # for whatever reason, '0' is group and '1' is individual for the group value submit_dict = {'name': a.name, 'short_name': a.short_name, 'status': a.status, 'due_date_0': due_date, 'due_date_1': due_time, 'percent': a.percent, 'max_grade': a.max_grade, 'group': '1', 'extend_group': 'None'} # no change response = client.post(url, submit_dict) self.assertEquals(response.status_code, 302) # successful submit -> redirect self.assertEquals(NumericActivity.objects.get(id=a.id).group, False) # change indiv -> group submit_dict['group'] = '0' response = client.post(url, submit_dict) self.assertEquals(response.status_code, 302) self.assertEquals(NumericActivity.objects.get(id=a.id).group, True) # try with activity past due a.due_date = datetime.datetime.now() - datetime.timedelta(days=1) a.save() submit_dict['due_date_0'] = str(a.due_date.date()) submit_dict['group'] = '0' response = client.post(url, submit_dict) self.assertEquals(response.status_code, 200) # error on form -> 200 and back to form with error self.assertContains(response, "due date has passed") # try with a mark in the system a.due_date = datetime.datetime.now() + datetime.timedelta(days=1) a.save() submit_dict['due_date_0'] = str(a.due_date.date()) submit_dict['group'] = '0' g = NumericGrade(activity=a, member=m, value=2, flag="GRAD") g.save(entered_by='ggbaker') response = client.post(url, submit_dict) self.assertEquals(response.status_code, 200) self.assertContains(response, "grades have already been given") # try with a submission in the system g.flag = "NOGR" g.save(entered_by='ggbaker') s = StudentSubmission(activity=a, member=m) s.save() response = client.post(url, submit_dict) self.assertEquals(response.status_code, 200) self.assertContains(response, "submissions have already been made")
def test_group_change(self): """ Test changing group <-> individual on an activity. Should only be possible in some conditions. """ s, c = create_offering() # add some assignments and members due = datetime.datetime.now() + datetime.timedelta(days=1) due_date = str(due.date()) due_time = due.time().strftime("%H:%M:%S") a = NumericActivity(name="Assignment 1", short_name="A1", status="RLS", offering=c, position=2, max_grade=15, percent=10, due_date=due, group=False) a.save() p = Person.objects.get(userid="ggbaker") m = Member(person=p, offering=c, role="INST", added_reason="UNK") m.save() p = Person.objects.get(userid="0aaa0") m = Member(person=p, offering=c, role="STUD", added_reason="UNK") m.save() client = Client() client.login_user("ggbaker") url = reverse('offering:edit_activity', kwargs={ 'course_slug': c.slug, 'activity_slug': a.slug }) # for whatever reason, '0' is group and '1' is individual for the group value submit_dict = { 'name': a.name, 'short_name': a.short_name, 'status': a.status, 'due_date_0': due_date, 'due_date_1': due_time, 'percent': a.percent, 'max_grade': a.max_grade, 'group': '1', 'extend_group': 'None' } # no change response = client.post(url, submit_dict) self.assertEqual(response.status_code, 302) # successful submit -> redirect self.assertEqual(NumericActivity.objects.get(id=a.id).group, False) # change indiv -> group submit_dict['group'] = '0' response = client.post(url, submit_dict) self.assertEqual(response.status_code, 302) self.assertEqual(NumericActivity.objects.get(id=a.id).group, True) # try with activity past due a.due_date = datetime.datetime.now() - datetime.timedelta(days=1) a.save() submit_dict['due_date_0'] = str(a.due_date.date()) submit_dict['group'] = '0' response = client.post(url, submit_dict) self.assertEqual( response.status_code, 200) # error on form -> 200 and back to form with error self.assertContains(response, "due date has passed") # try with a mark in the system a.due_date = datetime.datetime.now() + datetime.timedelta(days=1) a.save() submit_dict['due_date_0'] = str(a.due_date.date()) submit_dict['group'] = '0' g = NumericGrade(activity=a, member=m, value=2, flag="GRAD") g.save(entered_by='ggbaker') response = client.post(url, submit_dict) self.assertEqual(response.status_code, 200) self.assertContains(response, "grades have already been given") # try with a submission in the system g.flag = "NOGR" g.save(entered_by='ggbaker') s = StudentSubmission(activity=a, member=m) s.save() response = client.post(url, submit_dict) self.assertEqual(response.status_code, 200) self.assertContains(response, "submissions have already been made")