def test_groups(self): group = StudentGroup(course_instance=self.current_course_instance) group.save() group.members.add(self.user.userprofile,self.grader.userprofile) self.assertEqual(StudentGroup.get_exact(self.current_course_instance, [self.user.userprofile,self.grader.userprofile]), group) self.assertEqual(StudentGroup.get_exact(self.current_course_instance, [self.user.userprofile,self.superuser.userprofile]), None)
def get_group(self): if self.submission_count > 0: s = self.submissions[0] if s.submitters.count() > 0: return StudentGroup.get_exact(self.exercise.course_instance, s.submitters.all()) return None
def get_group(self): if self.submission_count > 0: s = self.submissions[0] if s.submitters.count() > 0: return StudentGroup.get_exact( self.exercise.course_instance, s.submitters.all() ) return None
def _check_submission_allowed(self, profile, request=None): students = [profile] warnings = [] # Let course module settings decide submissionable state. #if self.course_instance.ending_time < timezone.now(): # warnings.append(_('The course is archived. Exercises are offline.')) # return False, warnings, students # Check enrollment requirements. enrollment = self.course_instance.get_enrollment_for(profile.user) if self.status in ( LearningObject.STATUS.ENROLLMENT, LearningObject.STATUS.ENROLLMENT_EXTERNAL, ): if not self.course_instance.is_enrollment_open(): return (self.SUBMIT_STATUS.CANNOT_ENROLL, [_('The enrollment is not open.')], students) if not self.course_instance.is_enrollable(profile.user): return (self.SUBMIT_STATUS.CANNOT_ENROLL, [_('You cannot enroll in the course.')], students) elif not enrollment: if self.course_instance.is_course_staff(profile.user): return (self.SUBMIT_STATUS.ALLOWED, [_('Staff can submit exercises without enrolling.')], students) return (self.SUBMIT_STATUS.NOT_ENROLLED, [_('You must enroll in the course to submit exercises.')], students) # Support group id from post or currently selected group. group = None group_id = request.POST.get("_aplus_group") if request else None if not group_id is None: try: gid = int(group_id) if gid > 0: group = profile.groups.filter( course_instance=self.course_instance, id=gid).first() except ValueError: pass elif enrollment and enrollment.selected_group: group = enrollment.selected_group # Check groups cannot be changed after submitting. submission = self.get_submissions_for_student(profile).first() if submission: if self._detect_group_changes(profile, group, submission): msg = _("Group can only change between different exercises.") warning = _('You have previously submitted this ' 'exercise {with_group}. {msg}') if submission.submitters.count() == 1: warning = warning.format(with_group=_('alone'), msg=msg) else: collaborators = StudentGroup.format_collaborator_names( submission.submitters.all(), profile) with_group = _('with {}').format(collaborators) warning = warning.format(with_group=with_group, msg=msg) warnings.append(warning) return self.SUBMIT_STATUS.INVALID_GROUP, warnings, students elif self._detect_submissions(profile, group): warnings.append(_('{collaborators} already submitted to this exercise in a different group.').format( collaborators=group.collaborator_names(profile))) return self.SUBMIT_STATUS.INVALID_GROUP, warnings, students # Get submitters. if group: students = list(group.members.all()) # Check group size. if not (self.min_group_size <= len(students) <= self.max_group_size): if self.max_group_size == self.min_group_size: size = "{:d}".format(self.min_group_size) else: size = "{:d}-{:d}".format(self.min_group_size, self.max_group_size) warnings.append( _("This exercise must be submitted in groups of {size} students.") .format(size=size)) if self.status in (self.STATUS.ENROLLMENT, self.STATUS.ENROLLMENT_EXTERNAL): access_ok, access_warnings = True, [] else: access_ok, access_warnings = self.one_has_access(students) is_staff = all(self.course_instance.is_course_staff(p.user) for p in students) ok = (access_ok and len(warnings) == 0) or is_staff all_warnings = warnings + access_warnings if not ok: if len(all_warnings) == 0: all_warnings.append(_( 'Cannot submit exercise due to unknown reason. If you ' 'think this is an error, please contact course staff.')) return self.SUBMIT_STATUS.INVALID, all_warnings, students submit_limit_ok, submit_limit_warnings = self.one_has_submissions(students) if not submit_limit_ok and not is_staff: # access_warnings are not needed here return (self.SUBMIT_STATUS.AMOUNT_EXCEEDED, submit_limit_warnings, students) return self.SUBMIT_STATUS.ALLOWED, all_warnings + submit_limit_warnings, students
def _check_submission_allowed(self, profile, request=None): students = [profile] warnings = [] # Let course module settings decide submissionable state. #if self.course_instance.ending_time < timezone.now(): # warnings.append(_('The course is archived. Exercises are offline.')) # return False, warnings, students # Check enrollment requirements. enrollment = self.course_instance.get_enrollment_for(profile.user) if self.status in ( LearningObject.STATUS.ENROLLMENT, LearningObject.STATUS.ENROLLMENT_EXTERNAL, ): if not self.course_instance.is_enrollable(profile.user): return (self.SUBMIT_STATUS.CANNOT_ENROLL, [_('You cannot enroll in the course.')], students) elif not enrollment: # TODO Provide button to enroll, should there be option to auto-enroll if self.course_instance.is_course_staff(profile.user): return (self.SUBMIT_STATUS.ALLOWED, [_('Staff can submit exercises without enrolling.')], students) return (self.SUBMIT_STATUS.NOT_ENROLLED, [_('You must enroll at course home to submit exercises.')], students) # Support group id from post or currently selected group. group = None group_id = request.POST.get("_aplus_group") if request else None if not group_id is None: try: gid = int(group_id) if gid > 0: group = profile.groups.filter( course_instance=self.course_instance, id=gid).first() except ValueError: pass elif enrollment and enrollment.selected_group: group = enrollment.selected_group # Check groups cannot be changed after submitting. submissions = list(self.get_submissions_for_student(profile)) if len(submissions) > 0: s = submissions[0] if self._detect_group_changes(profile, group, s): msg = _("Group can only change between different exercises.") warning = _('You have previously submitted this ' 'exercise {with_group}. {msg}') if s.submitters.count() == 1: warning = warning.format(with_group=_('alone'), msg=msg) else: collaborators = StudentGroup.format_collaborator_names( s.submitters.all(), profile) with_group = _('with {}').format(collaborators) warning = warning.format(with_group=with_group, msg=msg) warnings.append(warning) return self.SUBMIT_STATUS.INVALID_GROUP, warnings, students elif self._detect_submissions(profile, group): warnings.append(_('{collaborators} already submitted to this exercise in a different group.').format( collaborators=group.collaborator_names(profile))) return self.SUBMIT_STATUS.INVALID_GROUP, warnings, students # Get submitters. if group: students = list(group.members.all()) # Check group size. if not (self.min_group_size <= len(students) <= self.max_group_size): if self.max_group_size == self.min_group_size: size = "{:d}".format(self.min_group_size) else: size = "{:d}-{:d}".format(self.min_group_size, self.max_group_size) warnings.append( _("This exercise must be submitted in groups of {size} students.") .format(size=size)) access_ok,access_warnings = self.one_has_access(students) if not self.one_has_submissions(students): if self.course_module.late_submissions_allowed: access_warnings.append(_('You have used the allowed amount of submissions for this exercise. You may still submit unofficially to receive feedback.')) return (self.SUBMIT_STATUS.ALLOWED, warnings + access_warnings, students) warnings.append(_('You have used the allowed amount of submissions for this exercise.')) return (self.SUBMIT_STATUS.AMOUNT_EXCEEDED, warnings + access_warnings, students) ok = ( (access_ok and len(warnings) == 0) or all(self.course_instance.is_course_staff(p.user) for p in students) ) all_warnings = warnings + access_warnings if not ok: if len(all_warnings) == 0: all_warnings.append(_( 'Cannot submit exercise due to unknown reason. If you ' 'think this is an error, please contact course staff.')) return self.SUBMIT_STATUS.INVALID, all_warnings, students return self.SUBMIT_STATUS.ALLOWED, all_warnings, students
def modify_default_courses(): from course.models import Course, CourseInstance, Enrollment, StudentGroup # The container has already created the default database, but we # modify some settings of the course instance here. course = Course.objects.get(url="def", ) instance = CourseInstance.objects.get( course=course, url="current", ) #instance.head_urls = # "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_CHTML-full&delayStartupUntil=onload" #instance.view_content_to = CourseInstance.VIEW_ACCESS.ENROLLED #instance.view_content_to = CourseInstance.VIEW_ACCESS.PUBLIC #if not instance.description: # instance.description = '<p><b>TESTing</b> course instance description.</p><p>Hello course!</p>' #instance.save() from django.contrib.auth.models import User teacher = User.objects.get(username="******") course2, created = Course.objects.get_or_create( name="Test course 2", code='testcourse2', url='testcourse2', ) if created: course2.teachers.set([teacher.userprofile]) course2.save() now = timezone.now() try: instance2 = CourseInstance.objects.get( course=course2, instance_name="Test instance", url='test', ) instance2.starting_time = now instance2.ending_time = now + timedelta(days=365) instance2.save() except CourseInstance.DoesNotExist: instance2 = CourseInstance.objects.create( course=course2, instance_name="Test instance", url='test', starting_time=now, ending_time=now + timedelta(days=365), ) # enroll students for i in range(2, 100): user = User.objects.get(username="******" + str(i)) Enrollment.objects.get_or_create(course_instance=instance, user_profile=user.userprofile) # student groups for i in range(2, 90, 3): group = StudentGroup(course_instance=instance) group.save() member1 = User.objects.get(username="******" + str(i)) member2 = User.objects.get(username="******" + str(i + 1)) group.members.add(member1.userprofile, member2.userprofile) # UserTags create_user_tags(instance) ########################################################### # add submissions for testing from course.models import CourseModule from exercise.exercise_models import BaseExercise, LearningObject from exercise.submission_models import Submission time.sleep( 4 ) # let the database initialize the course (JSON import from the mooc-grader) student1 = User.objects.get(username='******', ) # module from the aplus-manual course course_module = CourseModule.objects.get( url='m01_introduction', course_instance=instance, ) exercise = BaseExercise.objects.get( course_module=course_module, url='m01_introduction_07_questionnaires_questionnaire_demo', #order=1, ) for i in range(300): new_submission = Submission.objects.create(exercise=exercise, #submission_data={}, ) new_submission.submitters.set([student1.userprofile]) if random.random() > 0.3: # randomly grade some submissions new_submission.set_points(random.randint(0, 50), 50) new_submission.set_ready() new_submission.save()