Exemplo n.º 1
0
def reset_course_deadlines(request):
    course_key = request.data.get('course_key', None)

    # If body doesnt contain 'course_key', return 400 to client.
    if not course_key:
        raise ParseError(_("'course_key' is required."))

    # If body contains params other than 'course_key', return 400 to client.
    if len(request.data) > 1:
        raise ParseError(_("Only 'course_key' is expected."))

    try:
        reset_self_paced_schedule(request.user, course_key)

        key = CourseKey.from_string(course_key)
        if course_home_mfe_dates_tab_is_active(key):
            body_link = get_microfrontend_url(course_key=course_key, view_name='dates')
        else:
            body_link = '{}{}'.format(settings.LMS_ROOT_URL, reverse('dates', args=[six.text_type(course_key)]))

        return Response({
            'body': format_html('<a href="{}">{}</a>', body_link, _('View all dates')),
            'header': format_html(
                '<div>{}</div>', _('Your due dates have been successfully shifted to help you stay on track.')
            ),
            'message': _('Deadlines successfully reset.'),
        })
    except Exception:
        raise UnableToResetDeadlines
Exemplo n.º 2
0
def reset_course_deadlines(request):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course
    """
    from lms.urls import RENDER_XBLOCK_NAME
    from openedx.features.course_experience.urls import COURSE_HOME_VIEW_NAME

    detail_id_dict = ast.literal_eval(
        request.POST.get('reset_deadlines_redirect_url_id_dict'))
    redirect_url = request.POST.get('reset_deadlines_redirect_url_base',
                                    COURSE_HOME_VIEW_NAME)
    course_key = CourseKey.from_string(detail_id_dict['course_id'])
    masquerade_details, masquerade_user = setup_masquerade(
        request, course_key, has_access(request.user, 'staff', course_key))
    if masquerade_details and masquerade_details.role == 'student' and masquerade_details.user_name and (
            redirect_url == COURSE_HOME_VIEW_NAME):
        # Masquerading as a specific student, so reset that student's schedule
        user = masquerade_user
    else:
        user = request.user
    reset_self_paced_schedule(user, course_key)
    if redirect_url == RENDER_XBLOCK_NAME:
        detail_id_dict.pop('course_id')
    return redirect(reverse(redirect_url, kwargs=detail_id_dict))
Exemplo n.º 3
0
def reset_schedule_on_mode_change(sender, user, course_key, mode, **kwargs):  # pylint: disable=unused-argument
    """
    When a CourseEnrollment's mode is changed, reset the user's schedule if self-paced.
    """
    # If switching to audit, reset to when the user got access to course. This is for the case where a user
    # upgrades to verified (resetting their date), then later refunds the order and goes back to audit. We want
    # to make sure that audit users go back to their normal audit schedule access.
    use_availability_date = mode in CourseMode.AUDIT_MODES
    reset_self_paced_schedule(user, course_key, use_availability_date=use_availability_date)
Exemplo n.º 4
0
    def test_safe_without_schedule(self):
        """ Just ensure that we don't raise exceptions or create any schedules """
        self.create_schedule()
        self.schedule.delete()

        reset_self_paced_schedule(self.user, self.course.id, use_availability_date=False)
        reset_self_paced_schedule(self.user, self.course.id, use_availability_date=True)

        self.assertEqual(Schedule.objects.count(), 0)
Exemplo n.º 5
0
    def test_reset_to_start_date(self, offset, expected_offset):
        self.create_schedule(offset=offset)
        expected_start = self.course.start + datetime.timedelta(days=expected_offset)

        with self.assertNumQueries(3):
            reset_self_paced_schedule(self.user, self.course.id, use_availability_date=True)

        self.schedule.refresh_from_db()
        self.assertEqual(self.schedule.start_date.replace(microsecond=0), expected_start.replace(microsecond=0))
Exemplo n.º 6
0
    def test_reset_to_now(self):
        self.create_schedule()
        original_start = self.schedule.start_date

        with self.assertNumQueries(3):
            reset_self_paced_schedule(self.user, self.course.id, use_availability_date=False)

        self.schedule.refresh_from_db()
        self.assertGreater(self.schedule.start_date, original_start)
Exemplo n.º 7
0
    def test_reset_before_course_starts(self, use_enrollment_date):
        self.create_schedule(
            enrollment_offset=-5,
            course_start_offset=5)  # starts in 5 days, enrollment is now

        reset_self_paced_schedule(self.user,
                                  self.course.id,
                                  use_enrollment_date=use_enrollment_date)

        self.schedule.refresh_from_db()
        assert self.schedule.start_date == self.enrollment.course.start
Exemplo n.º 8
0
    def test_reset_to_now(self):
        self.create_schedule()
        original_start = self.schedule.start_date

        with self.assertNumQueries(3):
            reset_self_paced_schedule(self.user,
                                      self.course.id,
                                      use_enrollment_date=False)

        self.schedule.refresh_from_db()
        assert self.schedule.start_date > original_start
Exemplo n.º 9
0
    def test_safe_without_schedule(self):
        """ Just ensure that we don't raise exceptions or create any schedules """
        self.create_schedule()
        self.schedule.delete()

        reset_self_paced_schedule(self.user,
                                  self.course.id,
                                  use_enrollment_date=False)
        reset_self_paced_schedule(self.user,
                                  self.course.id,
                                  use_enrollment_date=True)

        assert Schedule.objects.count() == 0
Exemplo n.º 10
0
def reset_course_deadlines(request):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course

    IMPORTANT NOTE: If updates are happening to the logic here, ALSO UPDATE the `reset_course_deadlines`
    function in common/djangoapps/util/views.py as well.
    """
    course_key = request.data.get('course_key', None)

    # If body doesnt contain 'course_key', return 400 to client.
    if not course_key:
        raise ParseError(_("'course_key' is required."))

    # If body contains params other than 'course_key', return 400 to client.
    if len(request.data) > 1:
        raise ParseError(_("Only 'course_key' is expected."))

    try:
        course_key = CourseKey.from_string(course_key)
        _course_masquerade, user = setup_masquerade(
            request, course_key, has_access(request.user, 'staff', course_key))

        missed_deadlines, missed_gated_content = dates_banner_should_display(
            course_key, user)
        if missed_deadlines and not missed_gated_content:
            reset_self_paced_schedule(user, course_key)

        if course_home_mfe_dates_tab_is_active(course_key):
            body_link = get_microfrontend_url(course_key=str(course_key),
                                              view_name='dates')
        else:
            body_link = '{}{}'.format(settings.LMS_ROOT_URL,
                                      reverse('dates', args=[str(course_key)]))

        return Response({
            'body':
            format_html('<a href="{}">{}</a>', body_link, _('View all dates')),
            'header':
            _('Your due dates have been successfully shifted to help you stay on track.'
              ),
            'link':
            body_link,
            'link_text':
            _('View all dates'),
            'message':
            _('Deadlines successfully reset.'),
        })
    except Exception as e:
        log.exception(e)
        raise UnableToResetDeadlines
Exemplo n.º 11
0
def reset_course_deadlines(request):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course
    """
    course_key = CourseKey.from_string(request.POST.get('course_id'))
    _course_masquerade, user = setup_masquerade(
        request, course_key, has_access(request.user, 'staff', course_key))

    missed_deadlines, missed_gated_content = dates_banner_should_display(
        course_key, user)
    if missed_deadlines and not missed_gated_content:
        reset_self_paced_schedule(user, course_key)

    referrer = request.META.get('HTTP_REFERER')
    return redirect(referrer) if referrer else HttpResponse()
Exemplo n.º 12
0
def reset_course_deadlines(request):
    course_key = request.data.get('course_key', None)

    # If body doesnt contain 'course_key', return 400 to client.
    if not course_key:
        raise ParseError("'course_key' is required.")

    # If body contains params other than 'course_key', return 400 to client.
    if len(request.data) > 1:
        raise ParseError("Only 'course_key' is expected.")

    try:
        reset_self_paced_schedule(request.user, course_key)
        return Response({'message': 'Deadlines successfully reset.'})
    except Exception:
        raise UnableToResetDeadlines
Exemplo n.º 13
0
def reset_course_deadlines(request, course_id):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course
    """
    course_key = CourseKey.from_string(course_id)
    masquerade_details, masquerade_user = setup_masquerade(
        request, course_key, has_access(request.user, 'staff', course_key))
    if masquerade_details and masquerade_details.role == 'student' and masquerade_details.user_name:
        # Masquerading as a specific student, so reset that student's schedule
        user = masquerade_user
    else:
        user = request.user
    reset_self_paced_schedule(user, course_key)
    return redirect(
        reverse('openedx.course_experience.course_home',
                args=[six.text_type(course_key)]))
Exemplo n.º 14
0
def reset_course_deadlines(request):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course

    IMPORTANT NOTE: If updates are happening to the logic here, ALSO UPDATE the `reset_course_deadlines`
    function in openedx/features/course_experience/api/v1/views.py as well.
    """
    course_key = CourseKey.from_string(request.POST.get('course_id'))
    _course_masquerade, user = setup_masquerade(
        request, course_key, has_access(request.user, 'staff', course_key))

    missed_deadlines, missed_gated_content = dates_banner_should_display(
        course_key, user)
    if missed_deadlines and not missed_gated_content:
        reset_self_paced_schedule(user, course_key)

    referrer = request.META.get('HTTP_REFERER')
    return redirect(referrer) if referrer else HttpResponse()
Exemplo n.º 15
0
def reset_course_deadlines(request):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course

    IMPORTANT NOTE: If updates are happening to the logic here, ALSO UPDATE the `reset_course_deadlines`
    function in openedx/features/course_experience/api/v1/views.py as well.
    """
    course_key = CourseKey.from_string(request.POST.get('course_id'))
    _course_masquerade, user = setup_masquerade(
        request, course_key, has_access(request.user, 'staff', course_key))

    # We ignore the missed_deadlines because this endpoint could be used for
    # learners who have remaining attempts on a problem and reset their due dates in order to
    # submit additional attempts. This can apply for 'completed' (submitted) content that would
    # not be marked as past_due
    _missed_deadlines, missed_gated_content = dates_banner_should_display(
        course_key, user)
    if not missed_gated_content:
        reset_self_paced_schedule(user, course_key)

    referrer = request.META.get('HTTP_REFERER')
    return redirect(referrer) if referrer else HttpResponse()
Exemplo n.º 16
0
def reset_course_deadlines(request):
    """
    Set the start_date of a schedule to today, which in turn will adjust due dates for
    sequentials belonging to a self paced course

    Request Parameters:
        course_key: course key
        research_event_data: any data that should be included in the research tracking event
            Example: sending the location of where the reset deadlines banner (i.e. outline-tab)

    IMPORTANT NOTE: If updates are happening to the logic here, ALSO UPDATE the `reset_course_deadlines`
    function in common/djangoapps/util/views.py as well.
    """
    course_key = request.data.get('course_key', None)
    research_event_data = request.data.get('research_event_data', {})

    # If body doesnt contain 'course_key', return 400 to client.
    if not course_key:
        raise ParseError(_("'course_key' is required."))

    try:
        course_key = CourseKey.from_string(course_key)
        course_masquerade, user = setup_masquerade(
            request, course_key, has_access(request.user, 'staff', course_key))

        # We ignore the missed_deadlines because this endpoint is used in the Learning MFE for
        # learners who have remaining attempts on a problem and reset their due dates in order to
        # submit additional attempts. This can apply for 'completed' (submitted) content that would
        # not be marked as past_due
        _missed_deadlines, missed_gated_content = dates_banner_should_display(
            course_key, user)
        if not missed_gated_content:
            reset_self_paced_schedule(user, course_key)

            course_overview = course_detail(request, user.username, course_key)
            # For context here, research_event_data should already contain `location` indicating
            # the page/location dates were reset from and could also contain `block_id` if reset
            # within courseware.
            research_event_data.update({
                'courserun_key':
                str(course_key),
                'is_masquerading':
                is_masquerading(user, course_key, course_masquerade),
                'is_staff':
                has_access(user, 'staff', course_key).has_access,
                'org_key':
                course_overview.display_org_with_default,
                'user_id':
                user.id,
            })
            tracker.emit('edx.ui.lms.reset_deadlines.clicked',
                         research_event_data)

        if course_home_legacy_is_active(course_key):
            body_link = '{}{}'.format(settings.LMS_ROOT_URL,
                                      reverse('dates', args=[str(course_key)]))
        else:
            body_link = get_learning_mfe_home_url(course_key=str(course_key),
                                                  view_name='dates')

        return Response({
            'body':
            format_html('<a href="{}">{}</a>', body_link, _('View all dates')),
            'header':
            _('Your due dates have been successfully shifted to help you stay on track.'
              ),
            'link':
            body_link,
            'link_text':
            _('View all dates'),
            'message':
            _('Deadlines successfully reset.'),
        })
    except Exception as reset_deadlines_exception:
        log.exception('Error occurred while trying to reset deadlines!')
        raise UnableToResetDeadlines from reset_deadlines_exception