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_models(self): """ Test the backend for groups """ s, c = create_offering() a = NumericActivity(name="Assignment 1", short_name="A1", status="URLS", offering=c, position=3, max_grade=20, group=True) a.save() a1 = a a = NumericActivity(name="Assignment 2", short_name="A2", status="URLS", offering=c, position=6, max_grade=20, group=True) a.save() a2 = a userid1 = "0aaa4" userid2 = "0aaa0" userid3 = "0aaa1" userid4 = "0aaa2" for u in [userid1, userid2, userid3, userid4]: p = Person.objects.get(userid=u) m = Member(person=p, offering=c, role="STUD", credits=3, career="UGRD", added_reason="UNK") m.save() # basics m = Member.objects.get(person__userid=userid1, offering=c) g = Group(name="Test Group", manager=m, courseoffering=c) g.save() self.assertEqual(g.slug, 'g-test-group') gm = GroupMember(group=g, student=m, confirmed=True, activity=a1) gm.save() m = Member.objects.get(person__userid=userid2, offering=c) gm = GroupMember(group=g, student=m, confirmed=True, activity=a1) gm.save() gs = Group.objects.filter(courseoffering=c) self.assertEqual(len(gs), 1) g = gs[0] self.assertEqual( set([gm.student.person.userid for gm in g.groupmember_set.all()]), set([userid1, userid2])) # check uniqueness of activity + member m = Member.objects.get(person__userid=userid3, offering=c) g2 = Group(name="Other Group", manager=m, courseoffering=c) g2.save() gm = GroupMember(group=g2, student=m, confirmed=True, activity=a1) gm.save() gm = GroupMember(group=g, student=m, confirmed=True, activity=a1) # south doesn't seem to create the constraints in SQLite for testing #self.assertRaises(IntegrityError, gm.save) # uniqueness of group name g3 = Group(name="Other Group", manager=m, courseoffering=c) # south doesn't seem to create the constraints in SQLite for testing #self.assertRaises(IntegrityError, g3.save) # finding all activities this group covers members = GroupMember.objects.filter(group=g) all_act = all_activities(members) self.assertEqual(set(a.slug for a in all_act), set([a1.slug])) # add a member for assignment 2 and check again gm = GroupMember(group=g, student=m, confirmed=True, activity=a2) gm.save() members = GroupMember.objects.filter(group=g) all_act = all_activities(members) self.assertEqual(set(a.slug for a in all_act), set([a1.slug, a2.slug])) # check student-editable tests # test dates m = Member.objects.get(offering=c, person__userid="0aaa0") gm = GroupMember.objects.get(group=g, student=m, activity=a1) a1.due_date = datetime.datetime.now() - datetime.timedelta( days=1) # yesterday a1.save() self.assertTrue("passed" in gm.student_editable("0aaa0")) a1.due_date = datetime.datetime.now() + datetime.timedelta( days=1) # tomorrow a1.save() gm = GroupMember.objects.get(group=g, student=m, activity=a1) self.assertEqual(gm.student_editable("0aaa0"), '') # not member for this activity self.assertTrue("not a member" in gm.student_editable("0aaa1")) # already graded gr = NumericGrade(activity=a1, member=m, value=1, flag="GRAD") gr.save(entered_by='ggbaker') self.assertTrue("grade" in gm.student_editable("0aaa0")) gr.flag = "NOGR" gr.save(entered_by='ggbaker') self.assertEqual(gm.student_editable("0aaa0"), '') # submission made s = GroupSubmission(group=g, creator=m, activity=a1) s.save() self.assertTrue("submission" in gm.student_editable("0aaa0"))
def test_group_models(self): """ Test the backend for groups """ s, c = create_offering() a = NumericActivity(name="Assignment 1", short_name="A1", status="URLS", offering=c, position=3, max_grade=20, group=True) a.save() a1 = a a = NumericActivity(name="Assignment 2", short_name="A2", status="URLS", offering=c, position=6, max_grade=20, group=True) a.save() a2 = a userid1 = "0aaa4" userid2 = "0aaa0" userid3 = "0aaa1" userid4 = "0aaa2" for u in [userid1, userid2, userid3, userid4]: p = Person.objects.get(userid=u) m = Member(person=p, offering=c, role="STUD", credits=3, career="UGRD", added_reason="UNK") m.save() # basics m = Member.objects.get(person__userid=userid1, offering=c) g = Group(name="Test Group", manager=m, courseoffering=c) g.save() self.assertEqual(g.slug, 'g-test-group') gm = GroupMember(group=g, student=m, confirmed=True, activity=a1) gm.save() m = Member.objects.get(person__userid=userid2, offering=c) gm = GroupMember(group=g, student=m, confirmed=True, activity=a1) gm.save() gs = Group.objects.filter(courseoffering=c) self.assertEqual(len(gs), 1) g = gs[0] self.assertEqual(set([gm.student.person.userid for gm in g.groupmember_set.all()]), set([userid1,userid2])) # check uniqueness of activity + member m = Member.objects.get(person__userid=userid3, offering=c) g2 = Group(name="Other Group", manager=m, courseoffering=c) g2.save() gm = GroupMember(group=g2, student=m, confirmed=True, activity=a1) gm.save() gm = GroupMember(group=g, student=m, confirmed=True, activity=a1) # south doesn't seem to create the constraints in SQLite for testing #self.assertRaises(IntegrityError, gm.save) # uniqueness of group name g3 = Group(name="Other Group", manager=m, courseoffering=c) # south doesn't seem to create the constraints in SQLite for testing #self.assertRaises(IntegrityError, g3.save) # finding all activities this group covers members = GroupMember.objects.filter(group=g) all_act = all_activities(members) self.assertEqual(set(a.slug for a in all_act), set([a1.slug])) # add a member for assignment 2 and check again gm = GroupMember(group=g, student=m, confirmed=True, activity=a2) gm.save() members = GroupMember.objects.filter(group=g) all_act = all_activities(members) self.assertEqual(set(a.slug for a in all_act), set([a1.slug, a2.slug])) # check student-editable tests # test dates m = Member.objects.get(offering=c, person__userid="0aaa0") gm = GroupMember.objects.get(group=g, student=m, activity=a1) a1.due_date = datetime.datetime.now() - datetime.timedelta(days=1) # yesterday a1.save() self.assertTrue("passed" in gm.student_editable("0aaa0")) a1.due_date = datetime.datetime.now() + datetime.timedelta(days=1) # tomorrow a1.save() gm = GroupMember.objects.get(group=g, student=m, activity=a1) self.assertEqual(gm.student_editable("0aaa0"), '') # not member for this activity self.assertTrue("not a member" in gm.student_editable("0aaa1")) # already graded gr = NumericGrade(activity=a1, member=m, value=1, flag="GRAD") gr.save(entered_by='ggbaker') self.assertTrue("grade" in gm.student_editable("0aaa0")) gr.flag="NOGR" gr.save(entered_by='ggbaker') self.assertEqual(gm.student_editable("0aaa0"), '') # submission made s = GroupSubmission(group=g, creator=m, activity=a1) s.save() self.assertTrue("submission" in gm.student_editable("0aaa0"))