Example #1
0
 def is_past_due(self):
     """
     Is it now past this problem's due date, including grace period?
     """
     due_date = self.due  # pylint: disable=no-member
     if self.graceperiod is not None and due_date:  # pylint: disable=no-member
         close_date = due_date + self.graceperiod  # pylint: disable=no-member
     else:
         close_date = due_date
     return close_date is not None and datetime.datetime.now(
         UTC()) > close_date
Example #2
0
def _can_enroll_courselike(user, courselike):
    """
    Ascertain if the user can enroll in the given courselike object.

    Arguments:
        user (User): The user attempting to enroll.
        courselike (CourseDescriptor or CourseOverview): The object representing the
            course in which the user is trying to enroll.

    Returns:
        AccessResponse, indicating whether the user can enroll.
    """
    enrollment_domain = courselike.enrollment_domain
    # Courselike objects (e.g., course descriptors and CourseOverviews) have an attribute named `id`
    # which actually points to a CourseKey. Sigh.
    course_key = courselike.id

    # If using a registration method to restrict enrollment (e.g., Shibboleth)
    if settings.FEATURES.get(
            'RESTRICT_ENROLL_BY_REG_METHOD') and enrollment_domain:
        if user is not None and user.is_authenticated() and \
                ExternalAuthMap.objects.filter(user=user, external_domain=enrollment_domain):
            debug("Allow: external_auth of " + enrollment_domain)
            reg_method_ok = True
        else:
            reg_method_ok = False
    else:
        reg_method_ok = True

    # If the user appears in CourseEnrollmentAllowed paired with the given course key,
    # they may enroll. Note that as dictated by the legacy database schema, the filter
    # call includes a `course_id` kwarg which requires a CourseKey.
    if user is not None and user.is_authenticated():
        if CourseEnrollmentAllowed.objects.filter(email=user.email,
                                                  course_id=course_key):
            return ACCESS_GRANTED

    if _has_staff_access_to_descriptor(user, courselike, course_key):
        return ACCESS_GRANTED

    if courselike.invitation_only:
        debug("Deny: invitation only")
        return ACCESS_DENIED

    now = datetime.now(UTC())
    enrollment_start = courselike.enrollment_start or datetime.min.replace(
        tzinfo=pytz.UTC)
    enrollment_end = courselike.enrollment_end or datetime.max.replace(
        tzinfo=pytz.UTC)
    if reg_method_ok and enrollment_start < now < enrollment_end:
        debug("Allow: in enrollment period")
        return ACCESS_GRANTED

    return ACCESS_DENIED
Example #3
0
 def test_ccx_due_caching(self):
     """verify that caching the due property works to limit queries"""
     expected = datetime.now(UTC())
     self.set_ccx_override('due', expected)
     with check_mongo_calls(1):
         # these statements are used entirely to demonstrate the
         # instance-level caching of these values on CCX objects. The
         # check_mongo_calls context is the point here.
         self.ccx.due  # pylint: disable=pointless-statement, no-member
     with check_mongo_calls(0):
         self.ccx.due  # pylint: disable=pointless-statement, no-member
    def test_receiver_on_course_deleted(self, store):
        self._create_course(store=store,
                            start=datetime(2010, 1, 1, tzinfo=UTC()),
                            end=datetime(2020, 1, 1, tzinfo=UTC()))
        module = self.get_module_for_user(self.user, self.course, self.problem)
        module.system.publish(module, 'progress', {})

        progress = StudentProgress.objects.all()
        self.assertEqual(len(progress), 1)

        history = StudentProgressHistory.objects.all()
        self.assertEqual(len(history), 1)

        course_deleted.send(sender=None, course_key=self.course.id)

        progress = StudentProgress.objects.all()
        self.assertEqual(len(progress), 0)

        history = StudentProgressHistory.objects.all()
        self.assertEqual(len(history), 0)
Example #5
0
 def verify_current_content_visibility(cls, due, hide_after_due):
     """
     Returns whether the content visibility policy passes
     for the given due date and hide_after_due values and
     the current date-time.
     """
     return (
         not due or
         not hide_after_due or
         datetime.now(UTC()) < due
     )
Example #6
0
 def test_lti20_request_handler_grade_past_due(self):
     """
     Test that we get a 404 when accept_grades_past_due is False and it is past due
     """
     self.setup_system_xmodule_mocks_for_lti20_request_test()
     self.xmodule.due = datetime.datetime.now(UTC())
     self.xmodule.accept_grades_past_due = False
     mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
     response = self.xmodule.lti_2_0_result_rest_handler(
         mock_request, "user/abcd")
     self.assertEqual(response.status_code, 404)
Example #7
0
def enrollment_has_ended(course):
    """
    Returns True if the current time is after the specified course end date.
    Returns False if there is no end date specified.
    """

    now = datetime.now(UTC())

    if course.enrollment_end is None:
        return False

    return now > course.enrollment_end
Example #8
0
    def can_enroll():
        """
        First check if restriction of enrollment by login method is enabled, both
            globally and by the course.
        If it is, then the user must pass the criterion set by the course, e.g. that ExternalAuthMap
            was set by 'shib:https://idp.stanford.edu/", in addition to requirements below.
        Rest of requirements:
        (CourseEnrollmentAllowed always overrides)
          or
        (staff can always enroll)
          or
        Enrollment can only happen in the course enrollment period, if one exists, and
        course is not invitation only.
        """

        # if using registration method to restrict (say shibboleth)
        if settings.FEATURES.get(
                'RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
            if user is not None and user.is_authenticated() and \
                    ExternalAuthMap.objects.filter(user=user, external_domain=course.enrollment_domain):
                debug("Allow: external_auth of " + course.enrollment_domain)
                reg_method_ok = True
            else:
                reg_method_ok = False
        else:
            reg_method_ok = True  # if not using this access check, it's always OK.

        now = datetime.now(UTC())
        start = course.enrollment_start or datetime.min.replace(
            tzinfo=pytz.UTC)
        end = course.enrollment_end or datetime.max.replace(tzinfo=pytz.UTC)

        # if user is in CourseEnrollmentAllowed with right course key then can also enroll
        # (note that course.id actually points to a CourseKey)
        # (the filter call uses course_id= since that's the legacy database schema)
        # (sorry that it's confusing :( )
        if user is not None and user.is_authenticated(
        ) and CourseEnrollmentAllowed:
            if CourseEnrollmentAllowed.objects.filter(email=user.email,
                                                      course_id=course.id):
                return True

        if _has_staff_access_to_descriptor(user, course, course.id):
            return True

        # Invitation_only doesn't apply to CourseEnrollmentAllowed or has_staff_access_access
        if course.invitation_only:
            debug("Deny: invitation only")
            return False

        if reg_method_ok and start < now < end:
            debug("Allow: in enrollment period")
            return True
Example #9
0
    def course_descriptor_no_inheritance_check(self, descriptor):
        """
        Verifies that a default value of None (for due) does not get marked as inherited.
        """
        self.assertEqual(descriptor.due, None)

        # Check that the child does not inherit a value for due
        child = descriptor.get_children()[0]
        self.assertEqual(child.due, None)

        # Check that the child hasn't started yet
        self.assertLessEqual(datetime.datetime.now(UTC()), child.start)
    def test_not_yet_started_course(self):
        self._create_course(start=datetime(3000, 1, 1, tzinfo=UTC()),
                            end=datetime(3000, 1, 1, tzinfo=UTC()))

        module = self.get_module_for_user(self.user, self.course, self.problem)
        grade_dict = {'value': 0.75, 'max_value': 1, 'user_id': self.user.id}
        module.system.publish(module, 'grade', grade_dict)

        gradebook = StudentGradebook.objects.get(user=self.user,
                                                 course_id=self.course.id)
        self.assertEqual(gradebook.grade, 0.01)
        self.assertEqual(gradebook.proforma_grade, 0.75)
        self.assertIn(json.dumps(self.problem_progress_summary),
                      gradebook.progress_summary)
        self.assertIn(json.dumps(self.problem_grade_summary),
                      gradebook.grade_summary)
        self.assertEquals(json.loads(gradebook.grading_policy),
                          self.grading_policy)

        module = self.get_module_for_user(self.user, self.course,
                                          self.problem2)
        grade_dict = {'value': 0.95, 'max_value': 1, 'user_id': self.user.id}
        module.system.publish(module, 'grade', grade_dict)

        gradebook = StudentGradebook.objects.get(user=self.user,
                                                 course_id=self.course.id)
        self.assertEqual(gradebook.grade, 0.03)
        self.assertEqual(gradebook.proforma_grade, 0.8500000000000001)
        self.assertIn(json.dumps(self.problem2_progress_summary),
                      gradebook.progress_summary)
        self.assertIn(json.dumps(self.problem2_grade_summary),
                      gradebook.grade_summary)
        self.assertEquals(json.loads(gradebook.grading_policy),
                          self.grading_policy)

        gradebook = StudentGradebook.objects.all()
        self.assertEqual(len(gradebook), 1)

        history = StudentGradebookHistory.objects.all()
        self.assertEqual(len(history), 2)
Example #11
0
    def test_ccx_start_is_correct(self):
        """verify that the start datetime for a ccx is correctly retrieved

        Note that after setting the start field override microseconds are
        truncated, so we can't do a direct comparison between before and after.
        For this reason we test the difference between and make sure it is less
        than one second.
        """
        expected = datetime.now(UTC())
        self.set_ccx_override('start', expected)
        actual = self.ccx.start  # pylint: disable=no-member
        diff = expected - actual
        self.assertTrue(abs(diff.total_seconds()) < 1)
Example #12
0
def get_months():
    # получаем значение текущего месяца
    utc = pytz.utc if pytz else UTC()
    if settings.USE_TZ:
        current = datetime.utcnow().replace(tzinfo=utc)
    else:
        current = datetime.now()
    date1 = next_month(current)
    date2 = next_month(date1)
    date3 = next_month(date2)
    return {
        'months': [current, date1, date2, date3],
    }
Example #13
0
    def within_enrollment_period():
        """
        Just a time boundary check, handles if start or stop were set to None
        """
        now = datetime.now(UTC())
        start = courselike.enrollment_start
        if start is not None:
            start = start.replace(tzinfo=pytz.UTC)
        end = courselike.enrollment_end
        if end is not None:
            end = end.replace(tzinfo=pytz.UTC)

        return (start is None or now > start) and (end is None or now < end)
Example #14
0
    def _assert_valid_gradebook_on_course(self, course):
        """
        Asserts user has a valid grade book
        """
        time_first_attempted = datetime.now(UTC()).isoformat()
        module = self.get_module_for_user(self.user, course,
                                          course.homework_assignment)
        grade_dict = {'value': 0.5, 'max_value': 1, 'user_id': self.user.id}
        with freeze_time(time_first_attempted):
            module.system.publish(module, 'grade', grade_dict)

        gradebook = StudentGradebook.objects.get(user=self.user,
                                                 course_id=course.id)
        self.assertEqual(gradebook.grade, 0.25)
        self.assertEqual(gradebook.proforma_grade, 0.5)

        self.assertIn(
            json.dumps(
                self._get_homework_summary(course,
                                           attempted=time_first_attempted)),
            gradebook.progress_summary)
        self.assertIn(json.dumps(self._get_homework_grade_summary()),
                      gradebook.grade_summary)
        self.assertEquals(json.loads(gradebook.grading_policy),
                          course.grading_policy)

        module = self.get_module_for_user(self.user, course,
                                          course.midterm_assignment)
        grade_dict = {'value': 1, 'max_value': 1, 'user_id': self.user.id}
        with freeze_time(time_first_attempted):
            module.system.publish(module, 'grade', grade_dict)

        gradebook = StudentGradebook.objects.get(user=self.user,
                                                 course_id=course.id)
        self.assertEqual(gradebook.grade, 0.75)
        self.assertEqual(gradebook.proforma_grade, 0.75)
        self.assertIn(
            json.dumps(
                self._get_midterm_summary(course,
                                          attempted=time_first_attempted)),
            gradebook.progress_summary)
        self.assertIn(json.dumps(self._get_midterm_grade_summary()),
                      gradebook.grade_summary)
        self.assertEquals(json.loads(gradebook.grading_policy),
                          course.grading_policy)

        gradebook = StudentGradebook.objects.all()
        self.assertEqual(len(gradebook), 1)

        history = StudentGradebookHistory.objects.all()
        self.assertEqual(len(history), 2)
Example #15
0
def course_info(request, course_id):
    """
    Display the course's info.html, or 404 if there is no such course.

    Assumes the course_id is in a valid format.
    """

    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)

    with modulestore().bulk_operations(course_key):
        course = get_course_with_access(request.user, 'load', course_key)

        # check to see if there is a required survey that must be taken before
        # the user can access the course.
        if request.user.is_authenticated() and survey.utils.must_answer_survey(course, request.user):
            return redirect(reverse('course_survey', args=[unicode(course.id)]))

        staff_access = has_access(request.user, 'staff', course)
        masquerade = setup_masquerade(request, course_key, staff_access)  # allow staff to masquerade on the info page
        reverifications = fetch_reverify_banner_info(request, course_key)
        studio_url = get_studio_url(course, 'course_info')

        # link to where the student should go to enroll in the course:
        # about page if there is not marketing site, SITE_NAME if there is
        url_to_enroll = reverse(course_about, args=[course_id])
        if settings.FEATURES.get('ENABLE_MKTG_SITE'):
            url_to_enroll = marketing_link('COURSES')

        show_enroll_banner = request.user.is_authenticated() and not CourseEnrollment.is_enrolled(request.user, course.id)

        context = {
            'request': request,
            'course_id': course_key.to_deprecated_string(),
            'cache': None,
            'course': course,
            'staff_access': staff_access,
            'masquerade': masquerade,
            'studio_url': studio_url,
            'reverifications': reverifications,
            'show_enroll_banner': show_enroll_banner,
            'url_to_enroll': url_to_enroll,
        }

        now = datetime.now(UTC())
        effective_start = _adjust_start_date_for_beta_testers(request.user, course, course_key)
        if staff_access and now < effective_start:
            # Disable student view button if user is staff and
            # course is not yet visible to students.
            context['disable_student_access'] = True

        return render_to_response('courseware/info.html', context)
Example #16
0
    def forum_posts_allowed(self):
        try:
            blackout_periods = [(parse_time(start), parse_time(end))
                                for start, end in self.discussion_blackouts]
            now = datetime.now(UTC())
            for start, end in blackout_periods:
                if start <= now <= end:
                    return False
        except:
            log.exception(
                "Error parsing discussion_blackouts for course {0}".format(
                    self.id))

        return True
Example #17
0
    def test_ooc_encoder(self):
        """
        Test the encoder out of its original constrained purpose to see if it functions for general use
        """
        details = {
            'number': 1,
            'string': 'string',
            'datetime': datetime.datetime.now(UTC())
        }
        jsondetails = json.dumps(details, cls=CourseSettingsEncoder)
        jsondetails = json.loads(jsondetails)

        self.assertEquals(1, jsondetails['number'])
        self.assertEqual(jsondetails['string'], 'string')
Example #18
0
    def test_closed_course_staff(self):
        """
        Users marked as course staff should be able to submit grade events to a closed course
        """
        course = self.setup_course_with_grading(
            start=datetime(2010, 1, 1, tzinfo=UTC()),
            end=datetime(2011, 1, 1, tzinfo=UTC()),
        )
        self.user = StaffFactory(course_key=course.id)
        module = self.get_module_for_user(self.user, course,
                                          course.homework_assignment)
        grade_dict = {'value': 0.5, 'max_value': 1, 'user_id': self.user.id}
        module.system.publish(module, 'grade', grade_dict)

        with self.assertRaises(StudentGradebook.DoesNotExist):
            __ = StudentGradebook.objects.get(user=self.user,
                                              course_id=course.id)

        gradebook = StudentGradebook.objects.all()
        self.assertEqual(len(gradebook), 0)

        history = StudentGradebookHistory.objects.all()
        self.assertEqual(len(history), 0)
Example #19
0
 def test_update_and_fetch(self):
     jsondetails = CourseDetails.fetch(self.course_locator)
     jsondetails.syllabus = "<a href='foo'>bar</a>"
     # encode - decode to convert date fields and other data which changes form
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).syllabus,
         jsondetails.syllabus, "After set syllabus")
     jsondetails.short_description = "Short Description"
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).short_description,
         jsondetails.short_description, "After set short_description")
     jsondetails.overview = "Overview"
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).overview,
         jsondetails.overview, "After set overview")
     jsondetails.intro_video = "intro_video"
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).intro_video,
         jsondetails.intro_video, "After set intro_video")
     jsondetails.effort = "effort"
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).effort,
         jsondetails.effort, "After set effort")
     jsondetails.start_date = datetime.datetime(2010,
                                                10,
                                                1,
                                                0,
                                                tzinfo=UTC())
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).start_date,
         jsondetails.start_date)
     jsondetails.course_image_name = "an_image.jpg"
     self.assertEqual(
         CourseDetails.update_from_json(self.course_locator,
                                        jsondetails.__dict__,
                                        self.user).course_image_name,
         jsondetails.course_image_name)
    def test_save_completion_with_course_not_started(self, store):
        """
        Save a CourseModuleCompletion with the feature flag, but the course has not yet started
        """
        self._create_course(store=store, start=datetime(3000, 1, 1, tzinfo=UTC()))

        module = self.get_module_for_user(self.user, self.course, self.problem4)
        module.system.publish(module, 'progress', {})

        entry = CourseModuleCompletion.objects.get(
            user=self.user.id,
            course_id=self.course.id,
            content_id=self.problem4.location
        )
        self.assertIsNotNone(entry)
Example #21
0
    def __init__(self, *args, **kwargs):
        """
        Expects the same arguments as XModuleDescriptor.__init__
        """
        super(CourseDescriptor, self).__init__(*args, **kwargs)

        if self.wiki_slug is None:
            self.wiki_slug = self.location.course

        msg = None
        if self.start is None:
            msg = "Course loaded without a valid start date. id = %s" % self.id
            self.start = datetime.now(UTC())
            log.critical(msg)
            self.system.error_tracker(msg)

        # NOTE: relies on the modulestore to call set_grading_policy() right after
        # init.  (Modulestore is in charge of figuring out where to load the policy from)

        # NOTE (THK): This is a last-minute addition for Fall 2012 launch to dynamically
        #   disable the syllabus content for courses that do not provide a syllabus
        self.syllabus_present = self.system.resources_fs.exists(
            path('syllabus'))
        self._grading_policy = {}

        self.set_grading_policy(self.grading_policy)
        if self.discussion_topics == {}:
            self.discussion_topics = {
                'General': {
                    'id': self.location.html_id()
                }
            }

        self.test_center_exams = []
        test_center_info = self.testcenter_info
        if test_center_info is not None:
            for exam_name in test_center_info:
                try:
                    exam_info = test_center_info[exam_name]
                    self.test_center_exams.append(
                        self.TestCenterExam(self.id, exam_name, exam_info))
                except Exception as err:
                    # If we can't parse the test center exam info, don't break
                    # the rest of the courseware.
                    msg = 'Error %s: Unable to load test-center exam info for exam "%s" of course "%s"' % (
                        err, exam_name, self.id)
                    log.error(msg)
                    continue
Example #22
0
def travels(requst):
    # получаем значение текущего месяца
    utc = pytz.utc if pytz else UTC()
    if settings.USE_TZ:
        current = datetime.utcnow().replace(tzinfo=utc)
    else:
        current = datetime.now()
    date1 = next_month(current)
    date2 = next_month(date1)
    date3 = next_month(date2)
    date4 = next_month(date3)
    date5 = next_month(date4)
    monts1 = [date3, date4, date5]
    return {
        'months': [current, date1, date2],
        'months1': monts1
    }
    def render_to_fragment(self, request, course_id, user_access, **kwargs):
        """
        Renders a course message fragment for the specified course.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key)

        # Get time until the start date, if already started, or no start date, value will be zero or negative
        now = datetime.now(UTC())
        already_started = course.start and now > course.start
        days_until_start_string = "started" if already_started else format_timedelta(
            course.start - now, locale=to_locale(get_language()))
        course_start_data = {
            'course_start_date':
            format_date(course.start, locale=to_locale(get_language())),
            'already_started':
            already_started,
            'days_until_start_string':
            days_until_start_string
        }

        # Register the course home messages to be loaded on the page
        _register_course_home_messages(request, course_id, user_access,
                                       course_start_data)

        # Grab the relevant messages
        course_home_messages = list(CourseHomeMessages.user_messages(request))

        # Pass in the url used to set a course goal
        goal_api_url = reverse('course_goals_api:v0:course_goal-list',
                               request=request)

        # Grab the logo
        image_src = "course_experience/images/home_message_author.png"

        context = {
            'course_home_messages': course_home_messages,
            'goal_api_url': goal_api_url,
            'image_src': image_src,
            'course_id': course_id,
            'username': request.user.username,
        }

        html = render_to_string(
            'course_experience/course-messages-fragment.html', context)
        return Fragment(html)
Example #24
0
    def setUp(self):
        super(MasqueradeTestCase, self).setUp()

        # By default, tests run with DISABLE_START_DATES=True. To test that masquerading as a student is
        # working properly, we must use start dates and set a start date in the past (otherwise the access
        # checks exist prematurely).
        self.course = CourseFactory.create(
            number='masquerade-test', metadata={'start': datetime.now(UTC())})
        # Creates info page and puts random data in it for specific student info page test
        self.info_page = ItemFactory.create(
            category="course_info",
            parent_location=self.course.location,
            data="OOGIE BLOOGIE",
            display_name="updates")
        self.chapter = ItemFactory.create(
            parent_location=self.course.location,
            category="chapter",
            display_name="Test Section",
        )
        self.sequential_display_name = "Test Masquerade Subsection"
        self.sequential = ItemFactory.create(
            parent_location=self.chapter.location,
            category="sequential",
            display_name=self.sequential_display_name,
        )
        self.vertical = ItemFactory.create(
            parent_location=self.sequential.location,
            category="vertical",
            display_name="Test Unit",
        )
        problem_xml = OptionResponseXMLFactory().build_xml(
            question_text='The correct answer is Correct',
            num_inputs=2,
            weight=2,
            options=['Correct', 'Incorrect'],
            correct_option='Correct')
        self.problem_display_name = "TestMasqueradeProblem"
        self.problem = ItemFactory.create(
            parent_location=self.vertical.location,
            category='problem',
            data=problem_xml,
            display_name=self.problem_display_name)
        self.test_user = self.create_user()
        self.login(self.test_user.email, 'test')
        self.enroll(self.course, True)
Example #25
0
    def can_enroll():
        """
        First check if restriction of enrollment by login method is enabled, both
            globally and by the course.
        If it is, then the user must pass the criterion set by the course, e.g. that ExternalAuthMap
            was set by 'shib:https://idp.stanford.edu/", in addition to requirements below.
        Rest of requirements:
        Enrollment can only happen in the course enrollment period, if one exists.
            or

        (CourseEnrollmentAllowed always overrides)
        (staff can always enroll)
        """

        if user is not None and user.groups.filter(name=CVN_REGISTERED_GROUP_NAME).count() == 0:
            return False


        # if using registration method to restrict (say shibboleth)
        if settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
            if user is not None and user.is_authenticated() and \
                ExternalAuthMap.objects.filter(user=user, external_domain=course.enrollment_domain):
                debug("Allow: external_auth of " + course.enrollment_domain)
                reg_method_ok = True
            else:
                reg_method_ok = False
        else:
            reg_method_ok = True #if not using this access check, it's always OK.

        now = datetime.now(UTC())
        start = course.enrollment_start
        end = course.enrollment_end

        if reg_method_ok and (start is None or now > start) and (end is None or now < end):
            # in enrollment period, so any user is allowed to enroll.
            debug("Allow: in enrollment period")
            return True

        # if user is in CourseEnrollmentAllowed with right course_id then can also enroll
        if user is not None and user.is_authenticated() and CourseEnrollmentAllowed:
            if CourseEnrollmentAllowed.objects.filter(email=user.email, course_id=course.id):
                return True

        # otherwise, need staff access
        return _has_staff_access_to_descriptor(user, course)
Example #26
0
def formatT(value):
    '''
    提交时间与现在时间的差
    :param value: 数据
    :return: 格式化后的时间
    '''
    value = value.replace(tzinfo=UTC())
    nowtime = datetime.datetime.today().replace(tzinfo=LocalTimezone())
    temp = (nowtime - value).days
    if temp >= 1:
        t = value
    else:
        t = (nowtime - value).seconds
        if t <= 3600:
            t = ('{} 分钟以前'.format(t // 60))
        else:
            t = ('{} 小时以前'.format(t // 3600))
    return t
Example #27
0
def check_start_date(user, days_early_for_beta, start, course_key):
    """
    Verifies whether the given user is allowed access given the
    start date and the Beta offset for the given course.

    Returns:
        AccessResponse: Either ACCESS_GRANTED or StartDateError.
    """
    start_dates_disabled = settings.FEATURES['DISABLE_START_DATES']
    if start_dates_disabled and not is_masquerading_as_student(user, course_key):
        return ACCESS_GRANTED
    else:
        now = datetime.now(UTC())
        effective_start = adjust_start_date(user, days_early_for_beta, start, course_key)
        if start is None or now > effective_start or in_preview_mode():
            return ACCESS_GRANTED

        return StartDateError(start)
    def test_save_completion_staff_ended(self, store):
        """
        Save a CourseModuleCompletion with the feature flag on a course that has not yet started
        but Staff should be able to write
        """
        self._create_course(store=store, end=datetime(1999, 1, 1, tzinfo=UTC()))

        self.user = StaffFactory(course_key=self.course.id)

        module = self.get_module_for_user(self.user, self.course, self.problem4)
        module.system.publish(module, 'progress', {})

        with self.assertRaises(CourseModuleCompletion.DoesNotExist):
            CourseModuleCompletion.objects.get(
                user=self.user.id,
                course_id=self.course.id,
                content_id=self.problem4.location
            )
    def test_save_completion_admin_not_started(self, store):
        """
        Save a CourseModuleCompletion with the feature flag on a course that has not yet started
        but Admins should be able to write
        """
        self._create_course(store=store, start=datetime(3000, 1, 1, tzinfo=UTC()))

        self.user = AdminFactory()

        module = self.get_module_for_user(self.user, self.course, self.problem4)
        module.system.publish(module, 'progress', {})

        completion_fetch = CourseModuleCompletion.objects.get(
            user=self.user.id,
            course_id=self.course.id,
            content_id=self.problem4.location
        )
        self.assertIsNotNone(completion_fetch)
Example #30
0
def _filter_unstarted_categories(category_map, course):
    """
    Returns a subset of categories from the provided map which have not yet met the start date
    Includes information about category children, subcategories (different), and entries
    """
    now = datetime.now(UTC())

    result_map = {}

    unfiltered_queue = [category_map]
    filtered_queue = [result_map]

    while unfiltered_queue:

        unfiltered_map = unfiltered_queue.pop()
        filtered_map = filtered_queue.pop()

        filtered_map["children"] = []
        filtered_map["entries"] = {}
        filtered_map["subcategories"] = {}

        for child in unfiltered_map["children"]:
            if child in unfiltered_map["entries"]:
                if course.self_paced or unfiltered_map["entries"][child][
                        "start_date"] <= now:
                    filtered_map["children"].append(child)
                    filtered_map["entries"][child] = {}
                    for key in unfiltered_map["entries"][child]:
                        if key != "start_date":
                            filtered_map["entries"][child][
                                key] = unfiltered_map["entries"][child][key]
                else:
                    log.debug(u"Filtering out:%s with start_date: %s", child,
                              unfiltered_map["entries"][child]["start_date"])
            else:
                if course.self_paced or unfiltered_map["subcategories"][child][
                        "start_date"] < now:
                    filtered_map["children"].append(child)
                    filtered_map["subcategories"][child] = {}
                    unfiltered_queue.append(
                        unfiltered_map["subcategories"][child])
                    filtered_queue.append(filtered_map["subcategories"][child])

    return result_map