def get_exam_date_next_semester(course): """ Return a start date of an exam next semester. Looking for the latest course run that has just finished or is currently running, and uses its upgrade deadline as an even in time relative to which we can find an exam run this semester or next semester. Args: course (courses.models.Course): A course Returns: str: a string representation exam start date, example: Apr 5, 2021 """ current_course_run = (CourseRun.objects.filter( start_date__lte=now_in_utc(), course=course).order_by('-start_date').first()) three_months = datetime.timedelta(weeks=12) if current_course_run is None or current_course_run.upgrade_deadline is None: next_date = now_in_utc() + three_months else: next_date = current_course_run.upgrade_deadline + three_months exam_run = ExamRun.get_schedulable_in_future(course).filter( date_first_schedulable__gte=next_date).order_by( 'date_first_schedulable').first() return exam_run.date_last_eligible.strftime( '%b %-d, %Y') if exam_run else ""
def get_edx_exam_coupon_url(user, course): """ Find a successful exam authorization and return the coupon url for the exam Args: user (User): a user course (courses.models.Course): A course Returns: str: a url to the exam or empty string """ now = now_in_utc() schedulable_exam_runs = ExamRun.get_currently_schedulable(course) exam_auth = ExamAuthorization.objects.filter( user=user, course=course, status=ExamAuthorization.STATUS_SUCCESS, exam_run__in=schedulable_exam_runs).first() if exam_auth is None: return "" if exam_auth.exam_coupon is not None: return exam_auth.exam_coupon.coupon_url exam_coupon = ExamRunCoupon.objects.filter(expiration_date__gte=now.date(), is_taken=False, course=course).first() if exam_coupon is None: return "" exam_auth.exam_coupon = exam_coupon exam_auth.save() return exam_coupon.use_coupon()
def get_exam_register_end_date(course): """ Get a formatted string of dates during which the exam is schedulable """ schedulable_exam_run = ExamRun.get_currently_schedulable(course).first() if schedulable_exam_run is not None: return schedulable_exam_run.date_last_schedulable.strftime( "%B %-d, %I:%M %p %Z") return ""
def get_future_exam_runs(course): """ Return a list of first dates when exams can be scheduled Args: course (courses.models.Course): A course Returns: list(str): a list of dates when future exams become schedulable """ return (ExamRun.get_schedulable_in_future(course). order_by('date_first_schedulable').values_list('date_first_schedulable', flat=True))
def get_past_recent_exam_run(course): """ Return scheduling dates for a recent exam, example: 'Mar 7 - Mar 17, 2018' Args: course (courses.models.Course): A course Returns: str: a string representation of scheduling window for recent exam run """ exam = ExamRun.get_schedulable_in_past(course).order_by('-date_last_schedulable').first() return '{} - {}'.format( exam.date_first_schedulable.strftime('%b %-d'), exam.date_last_schedulable.strftime('%b %-d, %Y') ) if exam else ''
def handle(self, *args, **kwargs): # pylint: disable=unused-argument,too-many-locals csvfile = kwargs.get('csvfile') reader = csv.DictReader(csvfile.read().splitlines()) catalog_query = next(reader)['Catalog Query'] course_number = re.search(r"\+([A-Za-z0-9.]+)PEx", catalog_query).group(1) validated_urls = validate_urls(reader) try: course = Course.objects.get( course_number__startswith=course_number) except Course.DoesNotExist: raise CommandError( 'Could not find a course with number "{}"'.format( course_number)) except Course.MultipleObjectsReturned: raise CommandError( 'There are multiple courses with given number "{}"'.format( course_number)) exam_runs = ExamRun.get_currently_schedulable(course) if not exam_runs.exists(): raise CommandError( 'There are no eligible exam runs for course "{}"'.format( course.title)) exam_auths = ExamAuthorization.objects.filter( exam_run__in=exam_runs, status=ExamAuthorization.STATUS_SUCCESS, exam_coupon_url__isnull=True) auths_changed = 0 for exam_auth, url in zip(exam_auths, validated_urls): exam_auth.exam_coupon_url = url exam_auth.save() auths_changed += 1 result_messages = [ 'Total coupons: {}'.format(len(validated_urls)), 'Total exam authorizations that need coupon: {}'.format( exam_auths.count()), 'Authorizations changed: {}'.format(auths_changed) ] self.stdout.write(self.style.SUCCESS('\n'.join(result_messages)))
def authorize_user_for_schedulable_exam_runs(user, course_run): """ Authorizes a user for all schedulable ExamRuns for a CourseRun Args: user (django.contib.auth.models.User): the user to authorize course_run (courses.models.CourseRun): the course run to check """ # for each ExamRun for this course that is currently schedulable, attempt to authorize the user for exam_run in ExamRun.get_currently_schedulable(course_run.course): try: authorize_for_exam_run(user, course_run, exam_run) except ExamAuthorizationException: log.debug('Unable to authorize user: %s for exam on course_id: %s', user.username, course_run.course.id)
def get_current_exam_run_dates(course): """ Return eligibility dates for an exam this term, example: 'Mar 7 - Mar 17, 2018', i.e. the dates during which a learner can take the exam Args: course (courses.models.Course): A course Returns: str: a string representation of scheduling window for current exam run """ schedulable_exam_run = ExamRun.get_currently_schedulable(course).first() return '{} and {}'.format( schedulable_exam_run.date_first_eligible.strftime('%b %-d'), schedulable_exam_run.date_last_eligible.strftime( '%b %-d, %Y')) if schedulable_exam_run else ''
def authorize_user_for_schedulable_exam_runs(user, course_run): """ Authorizes a user for all schedulable ExamRuns for a CourseRun Args: user (django.contib.auth.models.User): the user to authorize course_run (courses.models.CourseRun): the course run to check """ mmtrack = get_mmtrack(user, course_run.course.program) # for each ExamRun for this course that is currently schedulable, attempt to authorize the user for exam_run in ExamRun.get_currently_schedulable(course_run.course): try: authorize_for_exam_run(mmtrack, course_run, exam_run) except ExamAuthorizationException: log.debug( 'Unable to authorize user: %s for exam on course_id: %s', user.username, course_run.course.id )